/** * @test */ public function getPathToTemporaryDirectoryReturnsAnExistingPath() { $environment = new \TYPO3\FLOW3\Utility\Environment(new ApplicationContext('Testing')); $environment->setTemporaryDirectoryBase(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array(sys_get_temp_dir(), 'FLOW3EnvironmentTest'))); $path = $environment->getPathToTemporaryDirectory(); $this->assertTrue(file_exists($path), 'The temporary path does not exist.'); }
/** * @test */ public function modelIsReturnedCorrectlyForLocaleImplicatingChaining() { $localeImplementingChaining = new \TYPO3\FLOW3\I18n\Locale('de_DE'); $cldrModel = $this->cldrRepository->getModelForLocale($localeImplementingChaining); $this->assertAttributeContains(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->cldrBasePath, 'main/root.xml')), 'sourcePaths', $cldrModel); $this->assertAttributeContains(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->cldrBasePath, 'main/de_DE.xml')), 'sourcePaths', $cldrModel); $this->assertAttributeContains(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->cldrBasePath, 'main/de.xml')), 'sourcePaths', $cldrModel); }
/** * Loads all files in $sourcePath, transforms and stores them in $targetPath * * @param string $sourcePath Absolute path of the source file directory * @param string $targetPath Absolute path of the target file directory * @return void * @author Bastian Waidelich <*****@*****.**> */ public function processFiles($sourcePath, $targetPath) { $this->setSourcePath($sourcePath); $this->setTargetPath($targetPath); if ($this->emptyTargetPath) { \TYPO3\FLOW3\Utility\Files::emptyDirectoryRecursively($this->targetPath); } $this->findSourceFilenames(); $codeProcessor = $this->objectManager->get($this->codeProcessorClassName); $codeProcessor->setExtensionKey($this->extensionKey); $unusedReplacePairs = $this->replacePairs; foreach ($this->sourceFilenames as $sourceFilename) { $classCode = \TYPO3\FLOW3\Utility\Files::getFileContents($sourceFilename); $relativeFilePath = substr($sourceFilename, strlen($this->sourcePath) + 1); if (!$this->shouldFileBeProcessed($relativeFilePath)) { continue; } $targetFilename = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->targetPath, $relativeFilePath)); $targetFilename = $this->renameTargetFilename($targetFilename); \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively(dirname($targetFilename)); $codeProcessor->setClassCode($classCode); $fileSpecificReplacePairs = array(); $unusedFileSpecificReplacePairs = array(); if (isset($this->fileSpecificReplacePairs[$relativeFilePath]) && is_array($this->fileSpecificReplacePairs[$relativeFilePath])) { $fileSpecificReplacePairs = $this->fileSpecificReplacePairs[$relativeFilePath]; $unusedFileSpecificReplacePairs = $fileSpecificReplacePairs; } file_put_contents($targetFilename, $codeProcessor->processCode($this->replacePairs, $fileSpecificReplacePairs, $unusedReplacePairs, $unusedFileSpecificReplacePairs)); if (count($unusedFileSpecificReplacePairs)) { /*\TYPO3\FLOW3\var_dump( $unusedFileSpecificReplacePairs, 'Unused file specific replace pairs' );*/ //echo '--- Unused file specific replace pairs: ' . $relativeFilePath . chr(10); //var_dump($unusedFileSpecificReplacePairs); } } // Additional classes if (count($unusedReplacePairs)) { /*\TYPO3\FLOW3\var_dump( $unusedReplacePairs, 'Unused replace pairs' );*/ //echo '--- Unused replace pairs: ' . chr(10); //var_dump($unusedReplacePairs); } }
/** * Read the package metadata for the given package from the * Package.xml file contained in the package * * @param \TYPO3\FLOW3\Package\PackageInterface $package The package to read metadata for * @return \TYPO3\FLOW3\Package\MetaData A package meta data instance with the data from the package's Package.xml file. */ public static function readPackageMetaData(\TYPO3\FLOW3\Package\PackageInterface $package) { $packageInfoPath = $package->getMetaPath(); $meta = new \TYPO3\FLOW3\Package\MetaData($package->getPackageKey()); $xml = simplexml_load_file(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($packageInfoPath, 'Package.xml'))); if ($xml === FALSE) { $meta->setDescription('[Package.xml could not be read.]'); } else { $meta->setVersion((string) $xml->version); $meta->setTitle((string) $xml->title); $meta->setDescription((string) $xml->description); self::readCategories($xml, $meta); self::readParties($xml, $meta); self::readConstraints($xml, $meta); } return $meta; }
/** * Will return an array with all available packages. * * The data for each entry will be an array with the key, full path to * the package (index 'path') and a category (the packages subfolder, * index 'category'). The array is indexed by package key. * * @param string $packagesPath * @return array */ public static function getPackagesData($packagesPath) { $packagesData = array(); $packagesDirectoryIterator = new \DirectoryIterator($packagesPath); foreach ($packagesDirectoryIterator as $categoryFileInfo) { $category = $categoryFileInfo->getFilename(); if (!$categoryFileInfo->isDir() || $category[0] === '.') { continue; } $categoryDirectoryIterator = new \DirectoryIterator($categoryFileInfo->getPathname()); foreach ($categoryDirectoryIterator as $packageFileInfo) { $packageKey = $packageFileInfo->getFilename(); if (!$packageFileInfo->isDir() || $packageKey[0] === '.') { continue; } if (!file_exists(Files::concatenatePaths(array($packageFileInfo->getPathname(), 'Classes/Package.php')))) { continue; } $packagesData[$packageKey] = array('packageKey' => $packageKey, 'category' => $category, 'path' => $packageFileInfo->getPathname()); } } return $packagesData; }
/** * Creates a resource (file) from the given binary content as a persistent resource. * On a successful creation this method returns a Resource object representing the * newly created persistent resource. * * @param mixed $content The binary content of the file * @param string $filename * @return \TYPO3\FLOW3\Resource\Resource A resource object representing the created resource or FALSE if an error occurred. * @api */ public function createResourceFromContent($content, $filename) { $pathInfo = pathinfo($filename); if (!isset($pathInfo['extension']) || substr(strtolower($pathInfo['extension']), -3, 3) === 'php') { return FALSE; } $hash = sha1($content); $finalTargetPathAndFilename = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->persistentResourcesStorageBaseUri, $hash)); if (!file_exists($finalTargetPathAndFilename)) { file_put_contents($finalTargetPathAndFilename, $content); $this->fixFilePermissions($finalTargetPathAndFilename); } $resource = $this->createResourceFromHashAndFilename($hash, $pathInfo['basename']); $this->attachImportedResource($resource); return $resource; }
/** * Returns absolute paths to CLDR files connected in hierarchy * * For given locale, many CLDR files have to be merged in order to get full * set of CLDR data. For example, for 'en_GB' locale, files 'root', 'en', * and 'en_GB' should be merged. * * @param \TYPO3\FLOW3\I18n\Locale $locale A locale * @param string $directoryPath Relative path to existing CLDR directory which contains one file per locale (see 'main' directory in CLDR for example) * @return array<string> Absolute paths to CLDR files in hierarchy */ protected function findLocaleChain(\TYPO3\FLOW3\I18n\Locale $locale, $directoryPath) { $filesInHierarchy = array(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($directoryPath, (string) $locale . '.xml'))); $localeIdentifier = (string) $locale; while ($localeIdentifier = substr($localeIdentifier, 0, (int) strrpos($localeIdentifier, '_'))) { $possibleFilename = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($directoryPath, $localeIdentifier . '.xml')); if (file_exists($possibleFilename)) { array_unshift($filesInHierarchy, $possibleFilename); } } array_unshift($filesInHierarchy, \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($directoryPath, 'root.xml'))); return $filesInHierarchy; }
/** * Returns a XliffModel instance representing desired XLIFF file. * * Will return existing instance if a model for given $sourceName was already * requested before. Returns FALSE when $sourceName doesn't point to existing * file. * * @param string $packageKey Key of the package containing the source file * @param string $sourceName Relative path to existing CLDR file * @param \TYPO3\FLOW3\I18n\Locale $locale Locale object * @return \TYPO3\FLOW3\I18n\Xliff\XliffModel New or existing instance * @throws \TYPO3\FLOW3\I18n\Exception */ protected function getModel($packageKey, $sourceName, \TYPO3\FLOW3\I18n\Locale $locale) { $sourcePath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array('resource://' . $packageKey, $this->xliffBasePath)); list($sourcePath, $foundLocale) = $this->localizationService->getXliffFilenameAndPath($sourcePath, $sourceName, $locale); if ($sourcePath === FALSE) { throw new \TYPO3\FLOW3\I18n\Exception('No XLIFF file is available for ' . $packageKey . '::' . $sourceName . '::' . $locale . ' in the locale chain.', 1334759591); } if (isset($this->models[$sourcePath])) { return $this->models[$sourcePath]; } return $this->models[$sourcePath] = new \TYPO3\FLOW3\I18n\Xliff\XliffModel($sourcePath, $foundLocale); }
/** * Replaces images (<img src="Foo.png">) by persistent resources (<img src="_Resources/....">) * * @param string $bodyText * @return string the text with replaced image tags */ protected function replaceImages($bodyText) { $self = $this; $configuration = $this->bundleConfiguration; $resourceManager = $this->resourceManager; $resourcePublisher = $this->resourcePublisher; $bodyText = preg_replace_callback('/(<img .*?src=")([^"]*)(".*?\\/>)/', function ($matches) use($self, $configuration, $resourceManager, $resourcePublisher) { $imageRootPath = isset($configuration['imageRootPath']) ? $configuration['imageRootPath'] : \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($configuration['renderedDocumentationRootPath'], '_images')); $imagePathAndFilename = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($imageRootPath, basename($matches[2]))); $imageResource = $resourceManager->importResource($imagePathAndFilename); $image = new \TYPO3\Media\Domain\Model\Image($imageResource); if ($image->getWidth() > $configuration['imageMaxWidth'] || $image->getHeight() > $configuration['imageMaxHeight']) { $image = $image->getThumbnail($configuration['imageMaxWidth'], $configuration['imageMaxHeight']); } $imageUri = '_Resources/' . $resourcePublisher->publishPersistentResource($image->getResource()); if ($image->getWidth() > $configuration['thumbnailMaxWidth'] || $image->getHeight() > $configuration['thumbnailMaxHeight']) { $thumbnail = $image->getThumbnail(710, 800); $thumbnailUri = '_Resources/' . $resourcePublisher->getPersistentResourceWebUri($thumbnail->getResource()); return sprintf('<a href="%s" class="lightbox">%s%s" style="width: %dpx" /></a>', $imageUri, $matches[1], $thumbnailUri, $thumbnail->getWidth()); } else { return sprintf('%s%s" style="width: %dpx" />', $matches[1], $imageUri, $image->getWidth()); } }, $bodyText); return $bodyText; }
/** * Returns the path to the existing localized version of file given. * * Searching is done for the current locale if no $locale parameter is * provided. The search is done according to the configured fallback * rule. * * If parameter $strict is provided, searching is done only for the * provided / current locale (without searching of files localized for * more generic locales). * * If no localized version of file is found, $filepath is returned without * any change. * * @param string $path Base directory to the translation files * @param string $sourceName name of the translation source * @param \TYPO3\FLOW3\I18n\Locale $locale Desired locale of XLIFF file * @return array Path to the localized file (or $filename when no localized file was found) and the matched locale * @see Configuration::setFallbackRule() * @api */ public function getXliffFilenameAndPath($path, $sourceName, Locale $locale = NULL) { if ($locale === NULL) { $locale = $this->configuration->getCurrentLocale(); } foreach ($this->getLocaleChain($locale) as $localeIdentifier => $locale) { $possibleXliffFilename = Files::concatenatePaths(array($path, $localeIdentifier, $sourceName . '.xlf')); if (file_exists($possibleXliffFilename)) { return array($possibleXliffFilename, $locale); } } return array(FALSE, $locale); }
/** * Parse TypoScript * @param string $additionalTypoScriptFile * @return \TYPO3\TypoScript\Core\Runtime */ protected function parseTypoScript($additionalTypoScriptFile = NULL) { $typoScript = file_get_contents(__DIR__ . '/Fixtures/PredefinedTypoScript.ts2'); $typoScript .= chr(10) . chr(10) . file_get_contents(__DIR__ . '/Fixtures/BaseTypoScript.ts2'); $fixtureDirectory = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array(__DIR__, 'Fixtures')); if ($additionalTypoScriptFile !== NULL) { $typoScript .= chr(10) . chr(10) . file_get_contents(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($fixtureDirectory, $additionalTypoScriptFile))); } $typoScript = str_replace('FIXTURE_DIRECTORY', $fixtureDirectory, $typoScript); $parser = new \TYPO3\TypoScript\Core\Parser(); $typoScriptConfiguration = $parser->parse($typoScript); $httpRequest = \TYPO3\FLOW3\Http\Request::create(new \TYPO3\FLOW3\Http\Uri('http://foo.bar/bazfoo')); $request = $httpRequest->createActionRequest(); $response = new \TYPO3\FLOW3\Http\Response(); $controllerContext = new \TYPO3\FLOW3\Mvc\Controller\ControllerContext($request, $response, $this->getMock('TYPO3\\FLOW3\\Mvc\\Controller\\Arguments', array(), array(), '', FALSE), $this->getMock('TYPO3\\FLOW3\\Mvc\\Routing\\UriBuilder'), $this->getMock('TYPO3\\FLOW3\\Mvc\\FlashMessageContainer')); return new \TYPO3\TypoScript\Core\Runtime($typoScriptConfiguration, $controllerContext); }
/** * Determines the path to the precompiled reflection data. * * @return string */ protected function getPrecompiledReflectionStoragePath() { return Files::concatenatePaths(array($this->environment->getPathToTemporaryDirectory(), 'PrecompiledReflectionData/')) . '/'; }
/** * Requires and registers all packages which were defined in packageStatesConfiguration * * @return void * @throws \TYPO3\FLOW3\Package\Exception\CorruptPackageException */ protected function registerPackages() { foreach ($this->packageStatesConfiguration['packages'] as $packageKey => $stateConfiguration) { $packageClassPathAndFilename = Files::concatenatePaths(array($this->packagesBasePath, $stateConfiguration['packagePath'], 'Classes/Package.php')); if (!file_exists($packageClassPathAndFilename)) { $shortFilename = substr($packageClassPathAndFilename, strlen($this->packagesBasePath)) . 'Classes/Package.php'; throw new \TYPO3\FLOW3\Package\Exception\CorruptPackageException(sprintf('Missing package class in package "%s". Please create a file "%s" and extend Package.', $packageKey, $shortFilename), 1300782486); } require_once $packageClassPathAndFilename; $packageClassName = str_replace('.', '\\', $packageKey) . '\\Package'; if (!class_exists($packageClassName)) { throw new \TYPO3\FLOW3\Package\Exception\CorruptPackageException(sprintf('The package "%s" does not contain a valid package class. Check if the file "%s" really contains a class called "%s".', $packageKey, $packageClassPathAndFilename, $packageClassName), 1327587091); } $packagePath = Files::concatenatePaths(array($this->packagesBasePath, $stateConfiguration['packagePath'])) . '/'; $this->packages[$packageKey] = new $packageClassName($packageKey, $packagePath, $stateConfiguration['classesPath']); if (!$this->packages[$packageKey] instanceof PackageInterface) { throw new \TYPO3\FLOW3\Package\Exception\CorruptPackageException(sprintf('The package class %s in package "%s" does not implement PackageInterface.', $packageClassName, $packageKey), 1300782487); } $this->packageKeys[strtolower($packageKey)] = $packageKey; if ($stateConfiguration['state'] === 'active') { $this->activePackages[$packageKey] = $this->packages[$packageKey]; } } }
/** * 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>'); } }
/** * @param \Doctrine\DBAL\Migrations\Configuration\Configuration $configuration * @param string $up * @param string $down * @return string * @throws \RuntimeException */ protected function writeMigrationClassToFile(\Doctrine\DBAL\Migrations\Configuration\Configuration $configuration, $up, $down) { $namespace = $configuration->getMigrationsNamespace(); $className = 'Version' . date('YmdHis'); $up = $up === NULL ? '' : "\n\t\t" . implode("\n\t\t", explode("\n", $up)); $down = $down === NULL ? '' : "\n\t\t" . implode("\n\t\t", explode("\n", $down)); $path = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($configuration->getMigrationsDirectory(), $className . '.php')); try { \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively(dirname($path)); } catch (\TYPO3\FLOW3\Utility\Exception $exception) { throw new \RuntimeException(sprintf('Migration target directory "%s" does not exist.', dirname($path)), 1303298536, $exception); } $code = <<<EOT <?php namespace {$namespace}; use Doctrine\\DBAL\\Migrations\\AbstractMigration, \tDoctrine\\DBAL\\Schema\\Schema; /** * Auto-generated Migration: Please modify to your need! */ class {$className} extends AbstractMigration { \t/** \t * @param Schema \$schema \t * @return void \t */ \tpublic function up(Schema \$schema) { \t\t\t// this up() migration is autogenerated, please modify it to your needs{$up} \t} \t/** \t * @param Schema \$schema \t * @return void \t */ \tpublic function down(Schema \$schema) { \t\t\t// this down() migration is autogenerated, please modify it to your needs{$down} \t} } ?> EOT; file_put_contents($path, $code); return $path; }
/** * 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; } }
/** * @param \TYPO3\Form\Core\Model\FinisherContext $finisherContext * @return void * @throws \TYPO3\Setup\Exception */ public function importSite(\TYPO3\Form\Core\Model\FinisherContext $finisherContext) { $formValues = $finisherContext->getFormRuntime()->getFormState()->getFormValues(); if (isset($formValues['prune']) && intval($formValues['prune']) === 1) { $this->nodeRepository->removeAll(); $this->workspaceRepository->removeAll(); $this->domainRepository->removeAll(); $this->siteRepository->removeAll(); $this->persistenceManager->persistAll(); } if (!empty($formValues['packageKey'])) { if ($this->packageManager->isPackageAvailable($formValues['packageKey'])) { throw new \TYPO3\Setup\Exception(sprintf('The package key "%s" already exists.', $formValues['packageKey']), 1346759486); } $packageKey = $formValues['packageKey']; $siteName = $formValues['packageKey']; $this->packageManager->createPackage($packageKey, NULL, Files::getUnixStylePath(Files::concatenatePaths(array(FLOW3_PATH_PACKAGES, 'Sites')))); $this->generatorService->generateSitesXml($packageKey, $siteName); $this->generatorService->generateSitesTypoScript($packageKey, $siteName); $this->generatorService->generateSitesTemplate($packageKey, $siteName); $this->packageManager->activatePackage($packageKey); } else { $packageKey = $formValues['site']; } if ($packageKey !== '') { try { $contentContext = new \TYPO3\TYPO3\Domain\Service\ContentContext('live'); $this->nodeRepository->setContext($contentContext); $this->siteImportService->importFromPackage($packageKey); } catch (\Exception $exception) { $finisherContext->cancel(); $this->flashMessageContainer->addMessage(new \TYPO3\FLOW3\Error\Error(sprintf('Error: During the import of the "Sites.xml" from the package "%s" an exception occurred: %s', $packageKey, $exception->getMessage()))); } } }
/** * 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); }
/** * Returns the publish path and filename to be used to publish the specified persistent resource * * @FLOW3\Around("method(TYPO3\FLOW3\Resource\Publishing\FileSystemPublishingTarget->buildPersistentResourcePublishPathAndFilename()) && setting(TYPO3.FLOW3.security.enable)") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point * @return mixed Result of the target method */ public function rewritePersistentResourcePublishPathAndFilenameForPrivateResources(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $resource = $joinPoint->getMethodArgument('resource'); $configuration = $resource->getPublishingConfiguration(); $returnFilename = $joinPoint->getMethodArgument('returnFilename'); if ($configuration === NULL || $configuration instanceof \TYPO3\FLOW3\Security\Authorization\Resource\SecurityPublishingConfiguration === FALSE) { return $joinPoint->getAdviceChain()->proceed($joinPoint); } $publishingPath = FALSE; $allowedRoles = $configuration->getAllowedRoles(); if (count(array_intersect($allowedRoles, $this->securityContext->getRoles())) > 0) { $publishingPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($joinPoint->getProxy()->getResourcesPublishingPath(), 'Persistent/', $this->session->getID())) . '/'; $filename = $resource->getResourcePointer()->getHash() . '.' . $resource->getFileExtension(); \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively($publishingPath); $this->accessRestrictionPublisher->publishAccessRestrictionsForPath($publishingPath); if ($this->settings['resource']['publishing']['fileSystem']['mirrorMode'] === 'link') { foreach ($allowedRoles as $role) { $roleDirectory = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->environment->getPathToTemporaryDirectory(), 'PrivateResourcePublishing/', $role)); \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively($roleDirectory); if (file_exists($publishingPath . $role)) { if (\TYPO3\FLOW3\Utility\Files::is_link(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $role))) && realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $role))) === $roleDirectory) { continue; } unlink($publishingPath . $role); symlink($roleDirectory, \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $role))); } else { symlink($roleDirectory, \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $role))); } } $publishingPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $allowedRoles[0])) . '/'; } if ($returnFilename === TRUE) { $publishingPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($publishingPath, $filename)); } } return $publishingPath; }
/** * Helper function to get the base path for key storage. * * @return string */ protected function getPath() { return Files::concatenatePaths(array(FLOW3_PATH_DATA, 'Persistent', 'FileBasedSimpleKeyService')); }
/** * Factory method which creates an EntityManager. * * @return \Doctrine\ORM\EntityManager */ public function create() { $config = new \Doctrine\ORM\Configuration(); $config->setClassMetadataFactoryName('TYPO3\\FLOW3\\Persistence\\Doctrine\\Mapping\\ClassMetadataFactory'); if (class_exists($this->settings['doctrine']['cacheImplementation'])) { // safeguard against apc being disabled in CLI... if ($this->settings['doctrine']['cacheImplementation'] !== 'Doctrine\\Common\\Cache\\ApcCache' || function_exists('apc_fetch')) { $cache = new $this->settings['doctrine']['cacheImplementation'](); $config->setMetadataCacheImpl($cache); $config->setQueryCacheImpl($cache); } } if (class_exists($this->settings['doctrine']['sqlLogger'])) { $config->setSQLLogger(new $this->settings['doctrine']['sqlLogger']()); } // must use ObjectManager in compile phase... $flow3AnnotationDriver = $this->objectManager->get('TYPO3\\FLOW3\\Persistence\\Doctrine\\Mapping\\Driver\\Flow3AnnotationDriver'); $config->setMetadataDriverImpl($flow3AnnotationDriver); $proxyDirectory = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->environment->getPathToTemporaryDirectory(), 'Doctrine/Proxies')); \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively($proxyDirectory); $config->setProxyDir($proxyDirectory); $config->setProxyNamespace('TYPO3\\FLOW3\\Persistence\\Doctrine\\Proxies'); $config->setAutoGenerateProxyClasses(FALSE); $entityManager = \Doctrine\ORM\EntityManager::create($this->settings['backendOptions'], $config); $flow3AnnotationDriver->setEntityManager($entityManager); return $entityManager; }
/** * @test */ public function inLinkModeRewritePersistentResourcePublishPathAndFilenameForPrivateResourcesCreatesRoleDirectoriesForEachAllowedRoleAndSymlinksThemIntoTheCurrentSessionDirectory() { $settings = array('resource' => array('publishing' => array('fileSystem' => array('mirrorMode' => 'link')))); $allowedRoles = array(new Role('Role2'), new Role('Role3')); $mockPublishingConfiguration = $this->getMock('TYPO3\\FLOW3\\Security\\Authorization\\Resource\\SecurityPublishingConfiguration', array(), array(), '', FALSE); $mockPublishingConfiguration->expects($this->once())->method('getAllowedRoles')->will($this->returnValue($allowedRoles)); $actualRoles = array(new Role('Role1'), new Role('Role2'), new Role('Role3')); $mockEnvironment = $this->getMock('TYPO3\\FLOW3\\Utility\\Environment', array(), array(), '', FALSE); $mockEnvironment->expects($this->any())->method('getPathToTemporaryDirectory')->will($this->returnValue($this->temporaryDirectoryPath)); $mockSecurityContext = $this->getMock('TYPO3\\FLOW3\\Security\\Context', array(), array(), '', FALSE); $mockSecurityContext->expects($this->once())->method('getRoles')->will($this->returnValue($actualRoles)); $mockPublishingTargetProxy = $this->getMock('TYPO3\\FLOW3\\Resource\\Publishing\\FileSystemPublishingTarget', array(), array(), '', FALSE); $mockPublishingTargetProxy->expects($this->once())->method('getResourcesPublishingPath')->will($this->returnValue($this->publishPath)); $mockResourcePointer = $this->getMock('TYPO3\\FLOW3\\Resource\\ResourcePointer', array(), array(), '', FALSE); $mockResourcePointer->expects($this->once())->method('getHash')->will($this->returnValue('ResourceHash')); $mockResource = $this->getMock('TYPO3\\FLOW3\\Resource\\Resource', array(), array(), '', FALSE); $mockResource->expects($this->once())->method('getPublishingConfiguration')->will($this->returnValue($mockPublishingConfiguration)); $mockResource->expects($this->once())->method('getResourcePointer')->will($this->returnValue($mockResourcePointer)); $mockResource->expects($this->once())->method('getFileExtension')->will($this->returnValue('ResourceFileExtension')); $mockJoinPoint = $this->getMock('TYPO3\\FLOW3\\Aop\\JoinPointInterface', array(), array(), '', FALSE); $mockJoinPoint->expects($this->at(0))->method('getMethodArgument')->with('resource')->will($this->returnValue($mockResource)); $mockJoinPoint->expects($this->at(1))->method('getMethodArgument')->with('returnFilename')->will($this->returnValue(FALSE)); $mockJoinPoint->expects($this->once())->method('getProxy')->will($this->returnValue($mockPublishingTargetProxy)); $mockSession = $this->getMock('TYPO3\\FLOW3\\Session\\SessionInterface', array(), array(), '', FALSE); $mockSession->expects($this->once())->method('getID')->will($this->returnValue('TheCurrentSessionId')); $mockAccessRestrictionPublisher = $this->getMock('\\TYPO3\\FLOW3\\Security\\Authorization\\Resource\\AccessRestrictionPublisherInterface', array(), array(), '', FALSE); $publishingAspect = $this->getAccessibleMock('TYPO3\\FLOW3\\Security\\Aspect\\PrivateResourcesPublishingAspect', array('dummy'), array(), '', FALSE); $publishingAspect->_set('securityContext', $mockSecurityContext); $publishingAspect->_set('session', $mockSession); $publishingAspect->_set('environment', $mockEnvironment); $publishingAspect->_set('settings', $settings); $publishingAspect->_set('accessRestrictionPublisher', $mockAccessRestrictionPublisher); $publishingAspect->_call('rewritePersistentResourcePublishPathAndFilenameForPrivateResources', $mockJoinPoint); $this->assertFileExists($this->temporaryDirectoryPath . '/PrivateResourcePublishing/Role2/'); $this->assertFileExists($this->temporaryDirectoryPath . '/PrivateResourcePublishing/Role3/'); $this->assertFileExists($this->publishPath . '/Persistent/TheCurrentSessionId/Role2'); $this->assertFileExists($this->publishPath . '/Persistent/TheCurrentSessionId/Role3'); $role2PrivateResourcePath = realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->temporaryDirectoryPath, 'PrivateResourcePublishing/Role2'))); $role2SymlinkedPath = realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->publishPath, 'Persistent/TheCurrentSessionId/Role2'))); $this->assertEquals($role2PrivateResourcePath, $role2SymlinkedPath); $role3PrivateResourcePath = realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->temporaryDirectoryPath, 'PrivateResourcePublishing/Role3'))); $role3SymlinkedPath = realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($this->publishPath, 'Persistent/TheCurrentSessionId/Role3'))); $this->assertEquals($role3PrivateResourcePath, $role3SymlinkedPath); }
/** * @test */ public function publishStaticResourcesLinksTheSpecifiedDirectoryIfMirrorModeIsLink() { $sourcePath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array(realpath(sys_get_temp_dir()), 'FLOW3FileSystemPublishingTargetTestSource')); $targetRootPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array(realpath(sys_get_temp_dir()), 'FLOW3FileSystemPublishingTargetTestTarget')); $targetPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($targetRootPath, '_Resources')); mkdir($sourcePath); \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively($targetPath); $settings = array('resource' => array('publishing' => array('fileSystem' => array('mirrorMode' => 'link')))); $publishingTarget = $this->getAccessibleMock('TYPO3\\FLOW3\\Resource\\Publishing\\FileSystemPublishingTarget', array('mirrorFile')); $publishingTarget->_set('settings', $settings); $publishingTarget->_set('resourcesPublishingPath', $targetPath); $publishingTarget->expects($this->never())->method('mirrorFile'); $this->assertTrue($publishingTarget->publishStaticResources($sourcePath, 'Bar')); $this->assertTrue(\TYPO3\FLOW3\Utility\Files::is_link(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($targetPath, 'Static/Bar')))); \TYPO3\FLOW3\Utility\Files::removeDirectoryRecursively($targetRootPath); \TYPO3\FLOW3\Utility\Files::removeDirectoryRecursively($sourcePath); }
/** * 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; }
/** * @test */ public function unlinkProperlyRemovesSymlinksPointingToDirectories() { $targetPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array(dirname(tempnam($this->temporaryDirectory, '')), 'FLOW3FilesTestDirectory')); if (!is_dir($targetPath)) { \TYPO3\FLOW3\Utility\Files::createDirectoryRecursively($targetPath); } $linkPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array(dirname(tempnam($this->temporaryDirectory, '')), 'FLOW3FilesTestDirectoryLink')); if (is_dir($linkPath)) { \TYPO3\FLOW3\Utility\Files::removeDirectoryRecursively($linkPath); } symlink($targetPath, $linkPath); $this->assertTrue(\TYPO3\FLOW3\Utility\Files::unlink($linkPath)); $this->assertTrue(file_exists($targetPath)); $this->assertFalse(file_exists($linkPath)); }
/** * Defines various path constants used by FLOW3 and if no root path or web root was * specified by an environment variable, exits with a respective error message. * * @return void */ protected function defineConstants() { if (defined('FLOW3_SAPITYPE')) { return; } define('FLOW3_SAPITYPE', PHP_SAPI === 'cli' ? 'CLI' : 'Web'); if (!defined('FLOW3_PATH_FLOW3')) { define('FLOW3_PATH_FLOW3', str_replace('//', '/', str_replace('\\', '/', __DIR__ . '/../../'))); } if (!defined('FLOW3_PATH_ROOT')) { $rootPath = isset($_SERVER['FLOW3_ROOTPATH']) ? $_SERVER['FLOW3_ROOTPATH'] : FALSE; if ($rootPath === FALSE && isset($_SERVER['REDIRECT_FLOW3_ROOTPATH'])) { $rootPath = $_SERVER['REDIRECT_FLOW3_ROOTPATH']; } if (FLOW3_SAPITYPE === 'CLI' && $rootPath === FALSE) { $rootPath = getcwd(); if (realpath(__DIR__) !== realpath($rootPath . '/Packages/Framework/TYPO3.FLOW3/Classes/Core')) { echo 'FLOW3: Invalid root path. (Error #1301225173)' . PHP_EOL . 'You must start FLOW3 from the root directory or set the environment variable FLOW3_ROOTPATH correctly.' . PHP_EOL; exit(1); } } if ($rootPath !== FALSE) { $rootPath = \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath($rootPath)) . '/'; $testPath = \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath(\TYPO3\FLOW3\Utility\Files::concatenatePaths(array($rootPath, 'Packages/Framework/TYPO3.FLOW3')))) . '/'; $expectedPath = \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath(FLOW3_PATH_FLOW3)) . '/'; if ($testPath !== $expectedPath) { echo 'FLOW3: Invalid root path. (Error #1248964375)' . PHP_EOL . '"' . $testPath . '" does not lead to' . PHP_EOL . '"' . $expectedPath . '"' . PHP_EOL; exit(1); } define('FLOW3_PATH_ROOT', $rootPath); unset($rootPath); unset($testPath); } } if (FLOW3_SAPITYPE === 'CLI') { if (!defined('FLOW3_PATH_ROOT')) { echo 'FLOW3: No root path defined in environment variable FLOW3_ROOTPATH (Error #1248964376)' . PHP_EOL; exit(1); } if (!defined('FLOW3_PATH_WEB')) { if (isset($_SERVER['FLOW3_WEBPATH']) && is_dir($_SERVER['FLOW3_WEBPATH'])) { define('FLOW3_PATH_WEB', \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath($_SERVER['FLOW3_WEBPATH'])) . '/'); } else { define('FLOW3_PATH_WEB', FLOW3_PATH_ROOT . 'Web/'); } } } else { if (!defined('FLOW3_PATH_ROOT')) { define('FLOW3_PATH_ROOT', \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath(dirname($_SERVER['SCRIPT_FILENAME']) . '/../')) . '/'); } define('FLOW3_PATH_WEB', \TYPO3\FLOW3\Utility\Files::getUnixStylePath(realpath(dirname($_SERVER['SCRIPT_FILENAME']))) . '/'); } define('FLOW3_PATH_CONFIGURATION', FLOW3_PATH_ROOT . 'Configuration/'); define('FLOW3_PATH_DATA', FLOW3_PATH_ROOT . 'Data/'); define('FLOW3_PATH_PACKAGES', FLOW3_PATH_ROOT . 'Packages/'); define('FLOW3_VERSION_BRANCH', '1.2'); }
/** * Evaluates the absolute path and filename of the resource file specified * by the given path. * * @param string $requestedPath * @param boolean $checkForExistence Whether a (non-hash) path should be checked for existence before being returned * @return mixed The full path and filename or FALSE if the file doesn't exist * @throws \TYPO3\FLOW3\Resource\Exception * @throws \InvalidArgumentException */ protected function evaluateResourcePath($requestedPath, $checkForExistence = TRUE) { if (substr($requestedPath, 0, strlen(self::SCHEME)) !== self::SCHEME) { throw new \InvalidArgumentException('The ' . __CLASS__ . ' only supports the \'' . self::SCHEME . '\' scheme.', 1256052544); } $uriParts = parse_url($requestedPath); if (!is_array($uriParts) || !isset($uriParts['host'])) { return FALSE; } if (strlen($uriParts['host']) === 40) { $resourcePath = $this->resourceManager->getPersistentResourcesStorageBaseUri() . $uriParts['host']; if ($checkForExistence === FALSE || file_exists($resourcePath)) { return $resourcePath; } else { return FALSE; } } if (!$this->packageManager->isPackageAvailable($uriParts['host'])) { throw new \TYPO3\FLOW3\Resource\Exception(sprintf('Invalid resource URI "%s": Package "%s" is not available.', $requestedPath, $uriParts['host']), 1309269952); } $package = $this->packageManager->getPackage($uriParts['host']); $resourcePath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($package->getResourcesPath(), $uriParts['path'])); if ($checkForExistence === FALSE || file_exists($resourcePath)) { return $resourcePath; } return FALSE; }