/**
  * Executes this task
  *
  * @param \TYPO3\Deploy\Domain\Model\Node $node
  * @param \TYPO3\Deploy\Domain\Model\Application $application
  * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment
  * @param array $options
  * @return void
  */
 public function execute(Node $node, Application $application, Deployment $deployment, array $options = array())
 {
     $targetReleasePath = $deployment->getApplicationReleasePath($application);
     $username = $node->getOption('username');
     $hostname = $node->getHostname();
     $configurationPath = $this->getDeploymentConfigurationPath() . '/Configuration/' . $deployment->getName() . '/';
     $encryptedConfiguration = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($configurationPath, 'yaml.encrypted');
     if (count($encryptedConfiguration) > 0) {
         throw new \Exception('You have sealed configuration files, please open the configuration for "' . $deployment->getName() . '"', 1317229449);
     }
     $configurations = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($configurationPath, 'yaml');
     $commands = array();
     foreach ($configurations as $configuration) {
         $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration));
         $commands[] = "scp {$configuration} {$username}@{$hostname}:{$targetReleasePath}/Configuration/{$targetConfigurationPath}/";
     }
     $localhost = new Node('localhost');
     $localhost->setHostname('localhost');
     $this->shell->executeOrSimulate($commands, $localhost, $deployment);
 }
예제 #2
0
 /**
  * Recursively publishes static resources located in the specified directory.
  * These resources are typically public package resources provided by the active packages.
  *
  * @param string $sourcePath The full path to the source directory which should be published (includes sub directories)
  * @param string $relativeTargetPath Path relative to the target's root where resources should be published to.
  * @return boolean TRUE if publication succeeded or FALSE if the resources could not be published
  */
 public function publishStaticResources($sourcePath, $relativeTargetPath)
 {
     if (!is_dir($sourcePath)) {
         return FALSE;
     }
     $sourcePath = rtrim(\TYPO3\FLOW3\Utility\Files::getUnixStylePath($this->realpath($sourcePath)), '/');
     $targetPath = rtrim(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->resourcesPublishingPath, 'Static', $relativeTargetPath)), '/');
     if ($this->settings['resource']['publishing']['fileSystem']['mirrorMode'] === 'link') {
         if (\TYPO3\FLOW3\Utility\Files::is_link($targetPath) && rtrim(\TYPO3\FLOW3\Utility\Files::getUnixStylePath($this->realpath($targetPath)), '/') === $sourcePath) {
             return TRUE;
         } elseif (is_dir($targetPath)) {
             \TYPO3\FLOW3\Utility\Files::removeDirectoryRecursively($targetPath);
         } elseif (is_link($targetPath)) {
             unlink($targetPath);
         } else {
             \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively(dirname($targetPath));
         }
         symlink($sourcePath, $targetPath);
     } else {
         foreach (\TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($sourcePath) as $sourcePathAndFilename) {
             if (substr(strtolower($sourcePathAndFilename), -4, 4) === '.php') {
                 continue;
             }
             $targetPathAndFilename = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($targetPath, str_replace($sourcePath, '', $sourcePathAndFilename)));
             if (!file_exists($targetPathAndFilename) || filemtime($sourcePathAndFilename) > filemtime($targetPathAndFilename)) {
                 $this->mirrorFile($sourcePathAndFilename, $targetPathAndFilename, TRUE);
             }
         }
     }
     return TRUE;
 }
예제 #3
0
파일: Manager.php 프로젝트: nxpthx/FLOW3
 /**
  * Look for code migration files in the given package path and register them
  * for further action.
  *
  * @param string $packagePath
  * @return void
  */
 protected function registerMigrationFiles($packagePath)
 {
     $packagePath = rtrim($packagePath, '/');
     $packageKey = substr($packagePath, strrpos($packagePath, '/') + 1);
     $migrationsDirectory = Files::concatenatePaths(array($packagePath, 'Migrations/Code'));
     if (!is_dir($migrationsDirectory)) {
         return;
     }
     $migrationFilenames = Files::readDirectoryRecursively($migrationsDirectory, '.php');
     foreach ($migrationFilenames as $filenameAndPath) {
         require_once $filenameAndPath;
         $baseFilename = basename($filenameAndPath, '.php');
         $version = substr($baseFilename, 7);
         $classname = 'TYPO3\\FLOW3\\Core\\Migrations\\' . $baseFilename;
         $this->migrations[$version] = new $classname($this, $packageKey);
     }
     ksort($this->migrations);
 }
예제 #4
0
파일: PhpSession.php 프로젝트: nxpthx/FLOW3
 /**
  * Destroys (file) data from all active PHP sessions.
  *
  * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap
  * @return integer The number of session files which have been removed
  */
 public static function destroyAll(Bootstrap $bootstrap)
 {
     $settings = $bootstrap->getObjectManager()->get('TYPO3\\FLOW3\\Configuration\\ConfigurationManager')->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'TYPO3.FLOW3');
     if (empty($settings['session']['PhpSession']['savePath'])) {
         $sessionsPath = Files::concatenatePaths(array($bootstrap->getObjectManager()->get('TYPO3\\FLOW3\\Utility\\Environment')->getPathToTemporaryDirectory(), 'Sessions'));
     } else {
         $sessionsPath = $settings['session']['PhpSession']['savePath'];
     }
     if (is_dir($sessionsPath)) {
         $filenames = Files::readDirectoryRecursively($sessionsPath);
         if (count($filenames) > 0) {
             Files::emptyDirectoryRecursively($sessionsPath);
         }
         return count($filenames);
     } else {
         return 0;
     }
 }
 /**
  * Validate the given configuration
  *
  * ./flow3 configuration:validate --type Settings --path TYPO3.FLOW3.persistence
  *
  * The schemas are searched in the path "Resources/Private/Schema" of all
  * active Packages. The schema-filenames must match the pattern
  * __type__.__path__.schema.yaml. The type and/or the path can also be
  * expressed as subdirectories of Resources/Private/Schema. So
  * Settings/TYPO3/FLOW3.persistence.schema.yaml will match the same pathes
  * like Settings.TYPO3.FLOW3.persistence.schema.yaml or
  * Settings/TYPO3.FLOW3/persistence.schema.yaml
  *
  * @param string $type Configuration type to validate
  * @param string $path path to the subconfiguration separated by "." like "TYPO3.FLOW3"
  * @return void
  */
 public function validateCommand($type = NULL, $path = NULL)
 {
     $availableConfigurationTypes = $this->configurationManager->getAvailableConfigurationTypes();
     if (in_array($type, $availableConfigurationTypes) === FALSE) {
         if ($type !== NULL) {
             $this->outputLine('<b>Configuration type "%s" was not found!</b>', array($type));
             $this->outputLine();
         }
         $this->outputLine('<b>Available configuration types:</b>');
         foreach ($availableConfigurationTypes as $availableConfigurationType) {
             $this->outputLine('  ' . $availableConfigurationType);
         }
         $this->outputLine();
         $this->outputLine('Hint: <b>%s configuration:validate --type <configurationType></b>', array($this->getFlow3InvocationString()));
         $this->outputLine('      validates the configuration of the specified type.');
         return;
     }
     $configuration = $this->configurationManager->getConfiguration($type);
     $this->outputLine('<b>Validating configuration for type: "' . $type . '"' . ($path !== NULL ? ' and path: "' . $path . '"' : '') . '</b>');
     // find schema files for the given type and path
     $schemaFileInfos = array();
     $activePackages = $this->packageManager->getActivePackages();
     foreach ($activePackages as $package) {
         $packageKey = $package->getPackageKey();
         $packageSchemaPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($package->getResourcesPath(), 'Private/Schema'));
         if (is_dir($packageSchemaPath)) {
             $packageSchemaFiles = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($packageSchemaPath, '.schema.yaml');
             foreach ($packageSchemaFiles as $schemaFile) {
                 $schemaName = substr($schemaFile, strlen($packageSchemaPath) + 1, -strlen('.schema.yaml'));
                 $schemaNameParts = explode('.', str_replace('/', '.', $schemaName), 2);
                 $schemaType = $schemaNameParts[0];
                 $schemaPath = isset($schemaNameParts[1]) ? $schemaNameParts[1] : NULL;
                 if ($schemaType === $type && ($path === NULL || strpos($schemaPath, $path) === 0)) {
                     $schemaFileInfos[] = array('file' => $schemaFile, 'name' => $schemaName, 'path' => $schemaPath, 'packageKey' => $packageKey);
                 }
             }
         }
     }
     $this->outputLine();
     if (count($schemaFileInfos) > 0) {
         $this->outputLine('%s schema files were found:', array(count($schemaFileInfos)));
         $result = new \TYPO3\FLOW3\Error\Result();
         foreach ($schemaFileInfos as $schemaFileInfo) {
             if ($schemaFileInfo['path'] !== NULL) {
                 $data = \TYPO3\FLOW3\Utility\Arrays::getValueByPath($configuration, $schemaFileInfo['path']);
             } else {
                 $data = $configuration;
             }
             if (empty($data)) {
                 $result->forProperty($schemaFileInfo['path'])->addError(new \TYPO3\FLOW3\Error\Error('configuration in path ' . $schemaFileInfo['path'] . ' is empty'));
                 $this->outputLine(' - package: "' . $schemaFileInfo['packageKey'] . '" schema: "' . $schemaFileInfo['name'] . '" -> <b>configuration is empty</b>');
             } else {
                 $parsedSchema = \Symfony\Component\Yaml\Yaml::parse($schemaFileInfo['file']);
                 $schemaResult = $this->schemaValidator->validate($data, $parsedSchema);
                 if ($schemaResult->hasErrors()) {
                     $this->outputLine(' - package:"' . $schemaFileInfo['packageKey'] . '" schema:"' . $schemaFileInfo['name'] . '" -> <b>' . count($schemaResult->getFlattenedErrors()) . ' errors</b>');
                 } else {
                     $this->outputLine(' - package:"' . $schemaFileInfo['packageKey'] . '" schema:"' . $schemaFileInfo['name'] . '" -> <b>is valid</b>');
                 }
                 if ($schemaFileInfo['path'] !== NULL) {
                     $result->forProperty($schemaFileInfo['path'])->merge($schemaResult);
                 } else {
                     $result->merge($schemaResult);
                 }
             }
         }
     } else {
         $this->outputLine('No matching schema-files were found!');
         return;
     }
     $this->outputLine();
     if ($result->hasErrors()) {
         $errors = $result->getFlattenedErrors();
         $this->outputLine('<b>%s errors were found:</b>', array(count($errors)));
         foreach ($errors as $path => $pathErrors) {
             foreach ($pathErrors as $error) {
                 $this->outputLine(' - %s -> %s', array($path, $error->render()));
             }
         }
     } else {
         $this->outputLine('<b>The configuration is valid!</b>');
     }
 }
예제 #6
0
 /**
  * Applies all registered searchAndReplace and searchAndReplaceRegex operations.
  *
  * @return void
  */
 protected function applySearchAndReplaceOperations()
 {
     $allPathsAndFilenames = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($this->packageData['path'], NULL, TRUE);
     foreach ($this->operations['searchAndReplace'] as $operation) {
         foreach ($allPathsAndFilenames as $pathAndFilename) {
             $pathInfo = pathinfo($pathAndFilename);
             if (!isset($pathInfo['filename'])) {
                 continue;
             }
             if (strpos($pathAndFilename, 'Migrations/Code') !== FALSE) {
                 continue;
             }
             if ($operation[2] !== array()) {
                 if (!isset($pathInfo['extension']) || !in_array($pathInfo['extension'], $operation[2], TRUE)) {
                     continue;
                 }
             }
             Tools::searchAndReplace($operation[0], $operation[1], $pathAndFilename);
         }
     }
 }
 /**
  * Open encrypted configuration with the local key
  *
  * Like the seal command, this can be restricted to a specific deployment. If a passphrase
  * was used to encrypt the local private key, it must be specified as the passphrase
  * argument to open the configuration files.
  *
  * @param string $passphrase Passphrase to decrypt the local key (if encrypted)
  * @param string $deploymentName Optional deployment name to selectively decrypt the configuration
  * @return void
  * @see typo3.deploy:encrypt:seal
  * @author Christopher Hlubek <*****@*****.**>
  */
 public function openCommand($passphrase = NULL, $deploymentName = '')
 {
     $keyPair = $this->readKeyPair($this->getDeploymentConfigurationPath() . '/Keys/Local.key');
     try {
         $keyPair = $this->encryptionService->openKeyPair($keyPair, $passphrase);
     } catch (\TYPO3\Deploy\Encryption\InvalidPassphraseException $exception) {
         $this->outputLine('Local key is encrypted with passphrase. Wrong or no passphrase given.');
         $this->quit(1);
     }
     $configurations = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($this->getDeploymentConfigurationPath() . '/Configuration/' . $deploymentName, 'yaml.encrypted');
     foreach ($configurations as $configuration) {
         $crypted = file_get_contents($configuration);
         $data = $this->encryptionService->decryptData($crypted, $keyPair->getPrivateKey());
         $targetFilename = substr($configuration, 0, -strlen('.encrypted'));
         file_put_contents($targetFilename, $data);
         unlink($configuration);
         $this->outputLine('Opened ' . $targetFilename);
     }
 }
예제 #8
0
 /**
  * Detects changes of the files and directories to be monitored and emits signals
  * accordingly.
  *
  * @return void
  * @api
  */
 public function detectChanges()
 {
     $changedDirectories = array();
     $changedFiles = $this->detectChangedFiles($this->monitoredFiles);
     foreach ($this->monitoredDirectories as $path) {
         if (!isset($this->directoriesAndFiles[$path])) {
             $this->directoriesAndFiles[$path] = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($path);
             $this->directoriesChanged = TRUE;
             $changedDirectories[$path] = \TYPO3\FLOW3\Monitor\ChangeDetectionStrategy\ChangeDetectionStrategyInterface::STATUS_CREATED;
         }
     }
     foreach ($this->directoriesAndFiles as $path => $pathAndFilenames) {
         if (!is_dir($path)) {
             unset($this->directoriesAndFiles[$path]);
             $this->directoriesChanged = TRUE;
             $changedDirectories[$path] = \TYPO3\FLOW3\Monitor\ChangeDetectionStrategy\ChangeDetectionStrategyInterface::STATUS_DELETED;
         } else {
             $currentSubDirectoriesAndFiles = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($path);
             if ($currentSubDirectoriesAndFiles != $pathAndFilenames) {
                 $pathAndFilenames = array_unique(array_merge($currentSubDirectoriesAndFiles, $pathAndFilenames));
             }
             $changedFiles = array_merge($changedFiles, $this->detectChangedFiles($pathAndFilenames));
         }
     }
     if (count($changedFiles) > 0) {
         $this->emitFilesHaveChanged($this->identifier, $changedFiles);
     }
     if (count($changedDirectories) > 0) {
         $this->emitDirectoriesHaveChanged($this->identifier, $changedDirectories);
     }
     if (count($changedFiles) > 0 || count($changedDirectories) > 0) {
         $this->systemLogger->log(sprintf('File Monitor "%s" detected %s changed files and %s changed directories.', $this->identifier, count($changedFiles), count($changedDirectories)), LOG_INFO);
     }
 }
 /**
  * Imports the specified bundle into the configured "importRootNodePath".
  *
  * @param string $bundle
  * @return void
  */
 protected function importBundle($bundle)
 {
     $this->outputLine('Importing bundle "%s"', array($bundle));
     $renderedDocumentationRootPath = rtrim($this->bundleConfiguration['renderedDocumentationRootPath'], '/');
     $contentContext = new \TYPO3\TYPO3\Domain\Service\ContentContext('live');
     $contentContext->setInvisibleContentShown(TRUE);
     $siteNode = $contentContext->getCurrentSiteNode();
     $importRootNode = $siteNode->getNode($this->bundleConfiguration['importRootNodePath']);
     if ($importRootNode === NULL) {
         $this->output('ImportRootNode "%s" does not exist!', array($this->bundleConfiguration['importRootNodePath']));
         $this->quit(1);
     }
     if (!is_dir($renderedDocumentationRootPath)) {
         $this->outputLine('The folder "%s" does not exist. Did you render the documentation?', array($renderedDocumentationRootPath));
         $this->quit(1);
     }
     $unorderedJsonFileNames = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($renderedDocumentationRootPath, '.fjson');
     if ($unorderedJsonFileNames === array()) {
         $this->outputLine('The folder "%s" contains no fjson files. Did you render the documentation?', array($renderedDocumentationRootPath));
         $this->quit(1);
     }
     $orderedNodePaths = array();
     foreach ($unorderedJsonFileNames as $jsonPathAndFileName) {
         if (basename($jsonPathAndFileName) === 'Index.fjson') {
             $chapterRelativeNodePath = substr($jsonPathAndFileName, strlen($renderedDocumentationRootPath), -12) . '/';
             #				$orderedNodePaths[] = $this->normalizeNodePath(substr($chapterRelativeNodePath, 0, -1));
             $indexArray = json_decode(file_get_contents($jsonPathAndFileName), TRUE);
             foreach (explode(chr(10), $indexArray['body']) as $tocHtmlLine) {
                 preg_match('!^\\<li class="toctree-l1"\\>\\<a class="reference internal" href="\\.\\./([a-zA-Z0-9]+)/.*$!', $tocHtmlLine, $matches);
                 if ($matches !== array()) {
                     $orderedNodePaths[] = $this->normalizeNodePath($chapterRelativeNodePath . $matches[1]);
                 }
             }
         }
     }
     foreach ($unorderedJsonFileNames as $jsonPathAndFileName) {
         $data = json_decode(file_get_contents($jsonPathAndFileName));
         if (!isset($data->body)) {
             continue;
         }
         $relativeNodePath = substr($jsonPathAndFileName, strlen($renderedDocumentationRootPath) + 1, -6);
         $relativeNodePath = $this->normalizeNodePath($relativeNodePath);
         $segments = explode('/', $relativeNodePath);
         $pageNode = $importRootNode;
         while ($segment = array_shift($segments)) {
             $nodeName = preg_replace('/[^a-z0-9\\-]/', '', $segment);
             $subPageNode = $pageNode->getNode($nodeName);
             if ($subPageNode === NULL) {
                 $this->outputLine('Creating page node "%s"', array($relativeNodePath));
                 $subPageNode = $pageNode->createNode($nodeName, 'TYPO3.TYPO3:Page');
                 if (!$subPageNode->hasProperty('title')) {
                     $subPageNode->setProperty('title', $nodeName);
                 }
             }
             $pageNode = $subPageNode;
         }
         $sectionNode = $pageNode->getNode('main');
         if ($sectionNode === NULL) {
             $this->outputLine('Creating section node "%s"', array($relativeNodePath . '/main'));
             $sectionNode = $pageNode->createNode('main', 'TYPO3.TYPO3:Section');
         }
         $textNode = $sectionNode->getNode('text1');
         if ($textNode === NULL) {
             $this->outputLine('Creating text node "%s"', array($relativeNodePath . '/main/text1'));
             $textNode = $sectionNode->createNode('text1', 'TYPO3.TYPO3:Text');
         }
         $pageNode->setProperty('title', $data->title);
         $this->outputLine('Setting page title of page "%s" to "%s"', array($relativeNodePath, $data->title));
         $bodyText = $this->prepareBodyText($data->body, $relativeNodePath);
         $textNode->setProperty('text', $bodyText);
     }
     $importRootNodePath = $importRootNode->getPath();
     $currentParentNodePath = '';
     foreach ($orderedNodePaths as $nodePath) {
         $node = $importRootNode->getNode($importRootNodePath . $nodePath);
         if ($node !== NULL) {
             if ($node->getParent()->getPath() !== $currentParentNodePath) {
                 $currentParentNodePath = $node->getParent()->getPath();
                 $previousNode = NULL;
             }
             if ($previousNode !== NULL) {
                 $this->outputLine('Moved node %s', array($node->getPath()));
                 $this->outputLine('after node %s', array($previousNode->getPath()));
                 $node->moveAfter($previousNode);
             } else {
                 // FIXME: Node->isFirst() or Node->moveFirst() would be needed here
             }
             $previousNode = $node;
         } else {
             $this->outputLine('Node %s does not exist.', array($importRootNodePath . $nodePath));
         }
     }
     $this->siteRepository->update($contentContext->getCurrentSite());
 }