/** * Executes this task * * @param \TYPO3\Surf\Domain\Model\Node $node * @param \TYPO3\Surf\Domain\Model\Application $application * @param \TYPO3\Surf\Domain\Model\Deployment $deployment * @param array $options * @throws \TYPO3\Surf\Exception\InvalidConfigurationException * @return void */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $options['username'] = isset($options['username']) ? $options['username'] . '@' : ''; $targetReleasePath = $deployment->getApplicationReleasePath($application); $configurationPath = $deployment->getDeploymentConfigurationPath() . '/'; if (!is_dir($configurationPath)) { return; } $configurations = \TYPO3\Flow\Utility\Files::readDirectoryRecursively($configurationPath); $commands = array(); foreach ($configurations as $configuration) { $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration)); if ($node->isLocalhost()) { $commands[] = "mkdir -p '{$targetReleasePath}/Configuration/{$targetConfigurationPath}/'"; $commands[] = "cp {$configuration} {$targetReleasePath}/Configuration/{$targetConfigurationPath}/"; } else { $username = $options['username']; $hostname = $node->getHostname(); $port = $node->hasOption('port') ? '-P ' . escapeshellarg($node->getOption('port')) : ''; $commands[] = "ssh {$port} {$username}{$hostname} 'mkdir -p {$targetReleasePath}/Configuration/{$targetConfigurationPath}/'"; $commands[] = "scp {$port} {$configuration} {$username}{$hostname}:{$targetReleasePath}/Configuration/{$targetConfigurationPath}/"; } } $localhost = new Node('localhost'); $localhost->setHostname('localhost'); $this->shell->executeOrSimulate($commands, $localhost, $deployment); }
/** * Executes this task * * @param \TYPO3\Surf\Domain\Model\Node $node * @param \TYPO3\Surf\Domain\Model\Application $application * @param \TYPO3\Surf\Domain\Model\Deployment $deployment * @param array $options * @throws \TYPO3\Surf\Exception\TaskExecutionException * @throws \TYPO3\Surf\Exception\InvalidConfigurationException */ public function execute(Node $node, Application $application, Deployment $deployment, array $options = array()) { $configurationFileExtension = isset($options['configurationFileExtension']) ? $options['configurationFileExtension'] : 'yaml'; $targetReleasePath = $deployment->getApplicationReleasePath($application); $configurationPath = $deployment->getDeploymentConfigurationPath(); if (!is_dir($configurationPath)) { return; } $commands = array(); $configurationFiles = Files::readDirectoryRecursively($configurationPath, $configurationFileExtension); foreach ($configurationFiles as $configuration) { $targetConfigurationPath = dirname(str_replace($configurationPath, '', $configuration)); $escapedSourcePath = escapeshellarg($configuration); $escapedTargetPath = escapeshellarg(Files::concatenatePaths(array($targetReleasePath, 'Configuration', $targetConfigurationPath)) . '/'); if ($node->isLocalhost()) { $commands[] = 'mkdir -p ' . $escapedTargetPath; $commands[] = 'cp ' . $escapedSourcePath . ' ' . $escapedTargetPath; } else { $username = isset($options['username']) ? $options['username'] . '@' : ''; $hostname = $node->getHostname(); $sshPort = isset($options['port']) ? '-p ' . escapeshellarg($options['port']) . ' ' : ''; $scpPort = isset($options['port']) ? '-P ' . escapeshellarg($options['port']) . ' ' : ''; $createDirectoryCommand = '"mkdir -p ' . $escapedTargetPath . '"'; $commands[] = "ssh {$sshPort}{$username}{$hostname} {$createDirectoryCommand}"; $commands[] = "scp {$scpPort}{$escapedSourcePath} {$username}{$hostname}:\"{$escapedTargetPath}\""; } } $localhost = new Node('localhost'); $localhost->setHostname('localhost'); $this->shell->executeOrSimulate($commands, $localhost, $deployment); }
/** * Add a warning for each HTML file that uses one of the f:uri.* or the f:format.json ViewHelpers * * @param string $packagePath * @return void */ protected function addWarningsForAffectedViewHelpers($packagePath) { $foundAffectedViewHelpers = array(); $allPathsAndFilenames = Files::readDirectoryRecursively($packagePath, NULL, TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { $pathInfo = pathinfo($pathAndFilename); if (!isset($pathInfo['filename']) || $pathInfo['extension'] !== 'html') { continue; } $fileContents = file_get_contents($pathAndFilename); preg_match_all('/f\\:(uri\\.[\\w]+|format\\.json)/', $fileContents, $matches, PREG_SET_ORDER); foreach ($matches as $match) { $viewHelperName = $match[1]; if (!isset($foundAffectedViewHelpers[$viewHelperName])) { $foundAffectedViewHelpers[$viewHelperName] = array(); } $truncatedPathAndFilename = substr($pathAndFilename, strlen($packagePath) + 1); if (!in_array($truncatedPathAndFilename, $foundAffectedViewHelpers[$viewHelperName])) { $foundAffectedViewHelpers[$viewHelperName][] = $truncatedPathAndFilename; } } } foreach ($foundAffectedViewHelpers as $viewHelperName => $filePathsAndNames) { $this->showWarning(sprintf('The behavior of the "%s" ViewHelper has been changed to produce escaped output.' . chr(10) . 'This package makes use of this ViewHelper in the following files:' . chr(10) . '- %s' . chr(10) . 'See upgrading instructions for further details.' . chr(10), $viewHelperName, implode(chr(10) . '- ', $filePathsAndNames))); } }
/** * @internal param $gatlingRoot * @return array */ protected function buildAvailableSimulations() { $simulationFilesPaths = Files::readDirectoryRecursively($this->gatlingRoot, '.scala'); $simulations = array(); foreach ($simulationFilesPaths as $simulationFilePath) { $simulations[] = $this->buildSimulation($simulationFilePath); } return $simulations; }
/** * @return void */ public function up() { $affectedFiles = array(); $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], NULL, TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { if (substr($pathAndFilename, -13) !== 'Converter.php') { continue; } $fileContents = file_get_contents($pathAndFilename); if (preg_match('/public\\s+function\\s+canConvertFrom\\s*\\(/', $fileContents) === 1) { $affectedFiles[] = substr($pathAndFilename, strlen($this->targetPackageData['path']) + 1); } } if ($affectedFiles !== array()) { $this->showWarning('Following TypeConverters implement the canConvertFrom() method. The element type of the $targetType argument is no longer cut off, so it might be "array<Some/Element/Type>" instead of just "array" for example. Make sure that this is not an issue or add' . PHP_EOL . ' $targetType = TypeHandling::truncateElementType($targetType);' . PHP_EOL . 'to the beginning of this method body if you\'re not sure:' . PHP_EOL . PHP_EOL . '* ' . implode(PHP_EOL . '* ', $affectedFiles)); } }
public function up() { $affectedFiles = array(); $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], NULL, TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { if (substr($pathAndFilename, -14) !== 'ViewHelper.php') { continue; } $fileContents = file_get_contents($pathAndFilename); if (preg_match('/\\$this->reflectionService/', $fileContents) === 1) { $affectedFiles[] = substr($pathAndFilename, strlen($this->targetPackageData['path']) + 1); } } if ($affectedFiles !== array()) { $this->showWarning('Following ViewHelpers might use a removed ReflectionService dependency from AbstractViewHelper, please inject a ReflectionService instance yourself:' . PHP_EOL . PHP_EOL . '* ' . implode(PHP_EOL . '* ', $affectedFiles)); } }
/** * Return all Objects stored in this storage filtered by the given directory / filename pattern * * @param string $pattern A glob compatible directory / filename pattern * @return array<\TYPO3\Flow\Resource\Storage\Object> */ public function getObjectsByPathPattern($pattern) { $objects = array(); $directories = array(); if (strpos($pattern, '/') !== FALSE) { list($packageKeyPattern, $directoryPattern) = explode('/', $pattern, 2); } else { $packageKeyPattern = $pattern; $directoryPattern = '*'; } // $packageKeyPattern can be used in a future implementation to filter by package key $packages = $this->packageManager->getActivePackages(); foreach ($packages as $packageKey => $package) { /** @var PackageInterface $package */ if ($directoryPattern === '*') { $directories[$packageKey][] = $package->getPackagePath(); } else { $directories[$packageKey] = glob($package->getPackagePath() . $directoryPattern, GLOB_ONLYDIR); } } foreach ($directories as $packageKey => $packageDirectories) { foreach ($packageDirectories as $directoryPath) { foreach (Files::readDirectoryRecursively($directoryPath) as $resourcePathAndFilename) { $pathInfo = UnicodeFunctions::pathinfo($resourcePathAndFilename); $object = new Object(); $object->setFilename($pathInfo['basename']); $object->setSha1(sha1_file($resourcePathAndFilename)); $object->setMd5(md5_file($resourcePathAndFilename)); $object->setFileSize(filesize($resourcePathAndFilename)); if (isset($pathInfo['dirname'])) { list(, $path) = explode('/', str_replace($packages[$packageKey]->getResourcesPath(), '', $pathInfo['dirname']), 2); $object->setRelativePublicationPath($packageKey . '/' . $path . '/'); } $object->setStream(function () use($resourcePathAndFilename) { return fopen($resourcePathAndFilename, 'r'); }); $objects[] = $object; } } } return $objects; }
/** * @param array $paths * @param string $templateNamePrefix * @param string $suffix * @return string */ public function render(array $paths, $templateNamePrefix = NULL, $suffix = '.hbs') { foreach ($paths as $path) { $templates = \TYPO3\Flow\Utility\Files::readDirectoryRecursively($path, $suffix); foreach ($templates as $template) { if (substr($template, 0, strlen($path) + 10) === $path . '/Resources') { $templateName = str_replace(array($path . '/Resources/', $suffix), '', $template); $this->handlebarTemplates[$this->getPrefixedResourceTemplateName($templateName, $templateNamePrefix)] = $template; } elseif (substr($template, 0, strlen($path) + 9) === $path . '/Partials') { $templateName = str_replace(array($path . '/Partials/', $suffix), '', $template); $this->handlebarTemplates['_' . $this->getPrefixedResourceTemplateName($templateName, $templateNamePrefix)] = $template; } else { $templateName = str_replace(array($path . '/', $suffix, '/'), array('', '', '_'), $template); $this->handlebarTemplates[$this->getPrefixedTemplateName($templateName, $templateNamePrefix)] = $template; } } } foreach ($this->handlebarTemplates as $templateName => $template) { $handlebarView = new \TYPO3\Fluid\View\StandaloneView(); $handlebarView->setFormat('html'); $handlebarView->setTemplateSource(\TYPO3\Flow\Utility\Files::getFileContents($template)); $assignHelpers = \TYPO3\Flow\Reflection\ObjectAccess::getPropertyPath($this->settings, 'handlebar.view.assignHelpers.' . $templateName); if (is_array($assignHelpers)) { foreach ($assignHelpers as $variable => $helper) { if (!isset($helper['class']) || !isset($helper['method'])) { continue; } $helperInstance = $this->objectManager->get($helper['class']); $value = call_user_func_array(array($helperInstance, $helper['method']), isset($helper['arguments']) ? $helper['arguments'] : array()); $handlebarView->assign($variable, $value); } } $this->handlebarTemplates[$templateName] = sprintf('<script type="text/x-handlebars" data-template-name="%s">%s</script>', $templateName, $handlebarView->render()); } return implode('', $this->handlebarTemplates); }
/** * Apply the given processor to the raw results of loading the given configuration * type for the package from YAML. If multiple files exist (context configuration) * all are processed independently. * * @param string $configurationType One of ConfigurationManager::CONFIGURATION_TYPE_* * @param \Closure $processor * @param boolean $saveResult * @return void */ protected function processConfiguration($configurationType, \Closure $processor, $saveResult = false) { if (is_dir($this->targetPackageData['path'] . '/Configuration') === false) { return; } $yamlPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'] . '/Configuration', 'yaml', true); $configurationPathsAndFilenames = array_filter($yamlPathsAndFilenames, function ($pathAndFileName) use($configurationType) { if (strpos(basename($pathAndFileName, '.yaml'), $configurationType) === 0) { return true; } else { return false; } }); $yamlSource = new YamlSource(); foreach ($configurationPathsAndFilenames as $pathAndFilename) { $originalConfiguration = $configuration = $yamlSource->load(substr($pathAndFilename, 0, -5)); $processor($configuration); if ($saveResult === true && $configuration !== $originalConfiguration) { $yamlSource->save(substr($pathAndFilename, 0, -5), $configuration); } } }
/** * 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\\Flow\\Core\\Migrations\\' . $baseFilename; $this->migrations[$version] = new $classname($this, $packageKey); } ksort($this->migrations); }
/** * 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\Flow\Utility\Files::getUnixStylePath($this->realpath($sourcePath)), '/'); $targetPath = rtrim(\TYPO3\Flow\Utility\Files::concatenatePaths(array($this->resourcesPublishingPath, 'Static', $relativeTargetPath)), '/'); if ($this->settings['resource']['publishing']['fileSystem']['mirrorMode'] === 'link') { if (\TYPO3\Flow\Utility\Files::is_link($targetPath) && rtrim(\TYPO3\Flow\Utility\Files::getUnixStylePath($this->realpath($targetPath)), '/') === $sourcePath) { return TRUE; } elseif (is_dir($targetPath)) { \TYPO3\Flow\Utility\Files::removeDirectoryRecursively($targetPath); } elseif (is_link($targetPath)) { unlink($targetPath); } else { \TYPO3\Flow\Utility\Files::createDirectoryRecursively(dirname($targetPath)); } symlink($sourcePath, $targetPath); } else { foreach (\TYPO3\Flow\Utility\Files::readDirectoryRecursively($sourcePath) as $sourcePathAndFilename) { if (substr(strtolower($sourcePathAndFilename), -4, 4) === '.php') { continue; } $targetPathAndFilename = \TYPO3\Flow\Utility\Files::concatenatePaths(array($targetPath, str_replace($sourcePath, '', $sourcePathAndFilename))); if (!file_exists($targetPathAndFilename) || filemtime($sourcePathAndFilename) > filemtime($targetPathAndFilename)) { $this->mirrorFile($sourcePathAndFilename, $targetPathAndFilename, TRUE); } } } return TRUE; }
/** * Read a monitored directory recursively, taking into account filename patterns * * @param string $path The path of a monitored directory * @return array An array of filenames with full path */ protected function readMonitoredDirectoryRecursively($path) { $filenames = \TYPO3\Flow\Utility\Files::readDirectoryRecursively($path); $filenamePattern = isset($this->monitoredDirectories[$path]) ? $this->monitoredDirectories[$path] : NULL; if ($filenamePattern !== NULL) { $filenames = array_filter($filenames, function ($pathAndFilename) use($filenamePattern) { return preg_match('|' . $filenamePattern . '|', basename($pathAndFilename)) === 1; }); } return $filenames; }
/** * Looks for composer.json in the given path and returns a path or NULL. * * @param string $packagePath * @return array */ protected function findComposerManifestPaths($packagePath) { $manifestPaths = array(); if (file_exists($packagePath . '/composer.json')) { $manifestPaths[] = $packagePath . '/'; } else { $jsonPathsAndFilenames = Files::readDirectoryRecursively($packagePath, '.json'); asort($jsonPathsAndFilenames); while (list($unusedKey, $jsonPathAndFilename) = each($jsonPathsAndFilenames)) { if (basename($jsonPathAndFilename) === 'composer.json') { $manifestPath = dirname($jsonPathAndFilename) . '/'; $manifestPaths[] = $manifestPath; $isNotSubPathOfManifestPath = function ($otherPath) use($manifestPath) { return strpos($otherPath, $manifestPath) !== 0; }; $jsonPathsAndFilenames = array_filter($jsonPathsAndFilenames, $isNotSubPathOfManifestPath); } } } return $manifestPaths; }
/** * Reads all Policy.yaml files below Packages, extracts the roles and prepends * them with the package key "guessed" from the path. * * @return array */ protected function loadRolesFromPolicyFiles() { $roles = array(); $yamlPathsAndFilenames = Files::readDirectoryRecursively(__DIR__ . '/../../../../../Packages', 'yaml', true); $configurationPathsAndFilenames = array_filter($yamlPathsAndFilenames, function ($pathAndFileName) { if (basename($pathAndFileName) === 'Policy.yaml') { return true; } else { return false; } }); $yamlSource = new \TYPO3\Flow\Configuration\Source\YamlSource(); foreach ($configurationPathsAndFilenames as $pathAndFilename) { if (preg_match('%Packages/.+/([^/]+)/Configuration/(?:Development|Production|Policy).+%', $pathAndFilename, $matches) === 0) { continue; } $packageKey = $matches[1]; $configuration = $yamlSource->load(substr($pathAndFilename, 0, -5)); if (isset($configuration['roles']) && is_array($configuration['roles'])) { foreach ($configuration['roles'] as $roleIdentifier => $parentRoles) { $roles[$packageKey . ':' . $roleIdentifier] = true; } } } return array_keys($roles); }
/** * Validate a single configuration type * * @param string $configurationType the configuration typr to validate * @param string $path configuration path to validate, or NULL. * @param array $loadedSchemaFiles will be filled with a list of loaded schema files * @return \TYPO3\Flow\Error\Result * @throws Exception\SchemaValidationException */ protected function validateSingleType($configurationType, $path, &$loadedSchemaFiles) { $availableConfigurationTypes = $this->configurationManager->getAvailableConfigurationTypes(); if (in_array($configurationType, $availableConfigurationTypes) === FALSE) { throw new Exception\SchemaValidationException('The configuration type "' . $configurationType . '" was not found. Only the following configuration types are supported: "' . implode('", "', $availableConfigurationTypes) . '"', 1364984886); } $configuration = $this->configurationManager->getConfiguration($configurationType); // find schema files for the given type and path $schemaFileInfos = array(); $activePackages = $this->packageManager->getActivePackages(); foreach ($activePackages as $package) { $packageKey = $package->getPackageKey(); $packageSchemaPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($package->getResourcesPath(), 'Private/Schema')); if (is_dir($packageSchemaPath)) { $packageSchemaFiles = \TYPO3\Flow\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 === $configurationType && ($path === NULL || strpos($schemaPath, $path) === 0)) { $schemaFileInfos[] = array('file' => $schemaFile, 'name' => $schemaName, 'path' => $schemaPath, 'packageKey' => $packageKey); } } } } if (count($schemaFileInfos) === 0) { throw new Exception\SchemaValidationException('No schema files found for configuration type "' . $configurationType . '"' . ($path !== NULL ? ' and path "' . $path . '".' : '.'), 1364985056); } $result = new Result(); foreach ($schemaFileInfos as $schemaFileInfo) { $loadedSchemaFiles[] = $schemaFileInfo['file']; if ($schemaFileInfo['path'] !== NULL) { $data = \TYPO3\Flow\Utility\Arrays::getValueByPath($configuration, $schemaFileInfo['path']); } else { $data = $configuration; } if (empty($data)) { $result->addNotice(new Notice('No configuration found, skipping schema "%s".', 1364985445, array(substr($schemaFileInfo['file'], strlen(FLOW_PATH_ROOT))))); } else { $parsedSchema = \Symfony\Component\Yaml\Yaml::parse($schemaFileInfo['file']); $validationResultForSingleSchema = $this->schemaValidator->validate($data, $parsedSchema); if ($schemaFileInfo['path'] !== NULL) { $result->forProperty($schemaFileInfo['path'])->merge($validationResultForSingleSchema); } else { $result->merge($validationResultForSingleSchema); } } } return $result; }
/** * @return mixed * @throws \TYPO3\Flow\Utility\Exception */ public static function getRandomMeme() { $folder = FLOW_PATH_PACKAGES . 'Application/WMDB.Forger/Resources/Public/images/memes/'; $listOfFiles = \TYPO3\Flow\Utility\Files::readDirectoryRecursively($folder); return basename($listOfFiles[rand(0, count($listOfFiles) - 1)]); }
/** * 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) { /** @noinspection PhpIncludeInspection */ require_once $filenameAndPath; $baseFilename = basename($filenameAndPath, '.php'); $className = '\\TYPO3\\Flow\\Core\\Migrations\\' . $baseFilename; /** @var AbstractMigration $migration */ $migration = new $className($this, $packageKey); $this->migrations[$migration->getVersionNumber()] = $migration; } }
/** * Applies all registered moveFile operations. * * @return void */ protected function applyFileOperations() { $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], NULL, TRUE); foreach ($this->operations['moveFile'] as $operation) { $oldPath = Files::concatenatePaths(array($this->targetPackageData['path'] . '/' . $operation[0])); $newPath = Files::concatenatePaths(array($this->targetPackageData['path'] . '/' . $operation[1])); if (substr($oldPath, -1) === '*') { $oldPath = substr($oldPath, 0, -1); if (!file_exists($oldPath)) { continue; } if (!file_exists($newPath)) { Files::createDirectoryRecursively($newPath); } if (!is_dir($newPath)) { continue; } foreach ($allPathsAndFilenames as $pathAndFilename) { if (substr_compare($pathAndFilename, $oldPath, 0, strlen($oldPath)) === 0) { $relativePathAndFilename = substr($pathAndFilename, strlen($oldPath)); if (!is_dir(dirname(Files::concatenatePaths(array($newPath, $relativePathAndFilename))))) { Files::createDirectoryRecursively(dirname(Files::concatenatePaths(array($newPath, $relativePathAndFilename)))); } Git::move($pathAndFilename, Files::concatenatePaths(array($newPath, $relativePathAndFilename))); } } } else { $oldPath = Files::concatenatePaths(array($this->targetPackageData['path'] . '/' . $operation[0])); $newPath = Files::concatenatePaths(array($this->targetPackageData['path'] . '/' . $operation[1])); Git::move($oldPath, $newPath); } } foreach ($this->operations['deleteFile'] as $operation) { $filename = Files::concatenatePaths(array($this->targetPackageData['path'] . '/' . $operation[0])); if (file_exists($filename)) { Git::remove($filename); } } }
/** * Imports the specified bundle into the configured "importRootNodePath". * * @param string $bundle * @return void */ protected function importBundle($bundle) { $nodeTypes = array('page' => $this->nodeTypeManager->getNodeType($this->bundleConfiguration['nodeTypes']['page']), 'section' => $this->nodeTypeManager->getNodeType($this->bundleConfiguration['nodeTypes']['section']), 'text' => $this->nodeTypeManager->getNodeType($this->bundleConfiguration['nodeTypes']['text'])); $this->outputLine('Importing bundle "%s"', array($bundle)); $renderedDocumentationRootPath = rtrim($this->bundleConfiguration['renderedDocumentationRootPath'], '/'); $importRootNode = $this->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 = 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) . '/'; $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)); /** @var NodeInterface $subPageNode */ $subPageNode = $pageNode->createNode($nodeName, $nodeTypes['page']); if (!$subPageNode->hasProperty('title')) { $subPageNode->setProperty('title', $nodeName); } } else { $subPageNode->setNodeType($nodeTypes['page']); } $pageNode = $subPageNode; } $sectionNode = $pageNode->getNode('main'); if ($sectionNode === NULL) { $this->outputLine('Creating section node "%s"', array($relativeNodePath . '/main')); $sectionNode = $pageNode->createNode('main', $nodeTypes['section']); } else { $sectionNode->setNodeType($nodeTypes['section']); } $textNode = $sectionNode->getNode('text1'); if ($textNode === NULL) { $this->outputLine('Creating text node "%s"', array($relativeNodePath . '/main/text1')); $textNode = $sectionNode->createNode('text1', $nodeTypes['text']); } else { $textNode->setNodeType($nodeTypes['text']); } $pageNode->setProperty('title', htmlspecialchars_decode($data->title)); $this->outputLine('Setting page title of page "%s" to "%s"', array($relativeNodePath, $data->title)); $bodyText = $this->prepareBodyText($data->body, $relativeNodePath); $textNode->setProperty('title', ''); $textNode->setProperty('text', $bodyText); } $importRootNodePath = $importRootNode->getPath(); $currentParentNodePath = ''; /** @var NodeInterface $previousNode */ $previousNode = NULL; 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($this->currentSite); }
/** * Load TypoScript from the directories specified by $this->getOption('typoScriptPathPatterns') * * @return void */ protected function loadTypoScript() { $mergedTypoScriptCode = ''; $typoScriptPathPatterns = $this->getOption('typoScriptPathPatterns'); ksort($typoScriptPathPatterns); foreach ($typoScriptPathPatterns as $typoScriptPathPattern) { $typoScriptPathPattern = str_replace('@package', $this->getPackageKey(), $typoScriptPathPattern); $filePaths = Files::readDirectoryRecursively($typoScriptPathPattern, '.ts2'); sort($filePaths); foreach ($filePaths as $filePath) { $mergedTypoScriptCode .= PHP_EOL . file_get_contents($filePath) . PHP_EOL; } } $this->parsedTypoScript = $this->typoScriptParser->parse($mergedTypoScriptCode); }
/** * @param string $jobIdentifier */ public function downloadCenterAction($jobIdentifier) { /** @var DocumentJobTrait $jobConfiguration */ $jobConfiguration = $this->jobConfigurationRepository->findOneByIdentifier($jobIdentifier); if ($jobConfiguration->getShowFileBrowser() !== true) { $this->addFlashMessage(sprintf('The current job (%s) does not implement "DocumentJobTrait"', $jobIdentifier), '', Message::SEVERITY_ERROR); $this->redirect('index'); } $files = Files::readDirectoryRecursively($jobConfiguration->getDocumentAbsolutePath()); $files = array_map(function ($file) { return ['path' => $file, 'creationDate' => \DateTime::createFromFormat('s', filemtime($file)), 'filesize' => filesize($file), 'name' => basename($file)]; }, $files); usort($files, function ($a, $b) { return strnatcmp($a['name'], $b['name']); }); $this->view->assignMultiple(['files' => $files, 'jobConfiguration' => $jobConfiguration]); }