Example #1
0
 /**
  * Set the routes configuration for the Neos setup and configures the routing component
  * to skip initialisation, which would overwrite the specific settings again.
  *
  * @param ComponentContext $componentContext
  * @return void
  */
 public function handle(ComponentContext $componentContext)
 {
     $configurationSource = $this->objectManager->get(\Neos\Flow\Configuration\Source\YamlSource::class);
     $routesConfiguration = $configurationSource->load($this->packageManager->getPackage('Neos.Setup')->getConfigurationPath() . ConfigurationManager::CONFIGURATION_TYPE_ROUTES);
     $this->router->setRoutesConfiguration($routesConfiguration);
     $componentContext->setParameter(\Neos\Flow\Mvc\Routing\RoutingComponent::class, 'skipRouterInitialization', true);
 }
 public function initializeObject($reason)
 {
     if ($reason === ObjectManagerInterface::INITIALIZATIONCAUSE_RECREATED) {
         return;
     }
     /** @var Package $package */
     foreach ($this->packageManager->getActivePackages() as $package) {
         foreach ($package->getNamespaces() as $namespace) {
             $this->addNamespace(strtolower($package->getPackageKey()), $namespace . '\\ViewHelpers');
         }
     }
 }
 /**
  * Kickstart a new site package
  *
  * This command generates a new site package with basic TypoScript and Sites.xml
  *
  * @param string $packageKey The packageKey for your site
  * @param string $siteName The siteName of your site
  * @return string
  */
 public function siteCommand($packageKey, $siteName)
 {
     if (!$this->packageManager->isPackageKeyValid($packageKey)) {
         $this->outputLine('Package key "%s" is not valid. Only UpperCamelCase in the format "Vendor.PackageKey", please!', array($packageKey));
         $this->quit(1);
     }
     if ($this->packageManager->isPackageAvailable($packageKey)) {
         $this->outputLine('Package "%s" already exists.', array($packageKey));
         $this->quit(1);
     }
     $generatedFiles = $this->generatorService->generateSitePackage($packageKey, $siteName);
     $this->outputLine(implode(PHP_EOL, $generatedFiles));
 }
 /**
  * Fetches the site with the given name and exports it into XML in the given package.
  *
  * @param array<Site> $sites
  * @param boolean $tidy Whether to export formatted XML
  * @param string $packageKey Package key where the export output should be saved to
  * @param string $nodeTypeFilter Filter the node type of the nodes, allows complex expressions (e.g. "Neos.Neos:Page", "!Neos.Neos:Page,Neos.Neos:Text")
  * @return void
  * @throws NeosException
  */
 public function exportToPackage(array $sites, $tidy = false, $packageKey, $nodeTypeFilter = null)
 {
     if (!$this->packageManager->isPackageActive($packageKey)) {
         throw new NeosException(sprintf('Error: Package "%s" is not active.', $packageKey), 1404375719);
     }
     $contentPathAndFilename = sprintf('resource://%s/Private/Content/Sites.xml', $packageKey);
     $this->resourcesPath = Files::concatenatePaths(array(dirname($contentPathAndFilename), 'Resources'));
     Files::createDirectoryRecursively($this->resourcesPath);
     $this->xmlWriter = new \XMLWriter();
     $this->xmlWriter->openUri($contentPathAndFilename);
     $this->xmlWriter->setIndent($tidy);
     $this->exportSites($sites, $nodeTypeFilter);
     $this->xmlWriter->flush();
 }
Example #5
0
 /**
  * Index action
  *
  * @return void
  */
 public function indexAction()
 {
     $this->view->assign('flowPathRoot', realpath(FLOW_PATH_ROOT));
     $this->view->assign('flowPathWeb', realpath(FLOW_PATH_WEB));
     $this->view->assign('isMyPackageActive', $this->packageManager->isPackageActive('MyCompany.MyPackage'));
     $baseUri = $this->request->getHttpRequest()->getBaseUri();
     $this->view->assign('baseUri', $baseUri);
     $this->view->assign('isWindows', DIRECTORY_SEPARATOR !== '/');
     $flowPackage = $this->packageManager->getPackage('Neos.Flow');
     $version = $flowPackage->getInstalledVersion();
     $this->view->assign('version', $version);
     $activePackages = $this->packageManager->getActivePackages();
     $this->view->assign('activePackages', $activePackages);
     $this->view->assign('notDevelopmentContext', !$this->objectManager->getContext()->isDevelopment());
 }
 /**
  * Flush all caches
  *
  * The flush command flushes all caches (including code caches) which have been
  * registered with Flow's Cache Manager. It also removes any session data.
  *
  * If fatal errors caused by a package prevent the compile time bootstrap
  * from running, the removal of any temporary data can be forced by specifying
  * the option <b>--force</b>.
  *
  * This command does not remove the precompiled data provided by frozen
  * packages unless the <b>--force</b> option is used.
  *
  * @param boolean $force Force flushing of any temporary data
  * @return void
  * @see neos.flow:cache:warmup
  * @see neos.flow:package:freeze
  * @see neos.flow:package:refreeze
  */
 public function flushCommand($force = false)
 {
     // Internal note: the $force option is evaluated early in the Flow
     // bootstrap in order to reliably flush the temporary data before any
     // other code can cause fatal errors.
     $this->cacheManager->flushCaches();
     $this->outputLine('Flushed all caches for "' . $this->bootstrap->getContext() . '" context.');
     if ($this->lockManager->isSiteLocked()) {
         $this->lockManager->unlockSite();
     }
     $frozenPackages = [];
     foreach (array_keys($this->packageManager->getActivePackages()) as $packageKey) {
         if ($this->packageManager->isPackageFrozen($packageKey)) {
             $frozenPackages[] = $packageKey;
         }
     }
     if ($frozenPackages !== []) {
         $this->outputFormatted(PHP_EOL . 'Please note that the following package' . (count($frozenPackages) === 1 ? ' is' : 's are') . ' currently frozen: ' . PHP_EOL);
         $this->outputFormatted(implode(PHP_EOL, $frozenPackages) . PHP_EOL, [], 2);
         $message = 'As code and configuration changes in these packages are not detected, the application may respond ';
         $message .= 'unexpectedly if modifications were done anyway or the remaining code relies on these changes.' . PHP_EOL . PHP_EOL;
         $message .= 'You may call <b>package:refreeze all</b> in order to refresh frozen packages or use the <b>--force</b> ';
         $message .= 'option of this <b>cache:flush</b> command to flush caches if Flow becomes unresponsive.' . PHP_EOL;
         $this->outputFormatted($message, [$frozenPackages]);
     }
     $this->sendAndExit(0);
 }
 /**
  * Return the json array for a given locale, sourceCatalog, xliffPath and package.
  * The json will be cached.
  *
  * @param Locale $locale The locale
  * @return Result
  * @throws Exception
  */
 public function getCachedJson(Locale $locale)
 {
     $cacheIdentifier = md5($locale);
     if ($this->xliffToJsonTranslationsCache->has($cacheIdentifier)) {
         $json = $this->xliffToJsonTranslationsCache->get($cacheIdentifier);
     } else {
         $labels = [];
         $localeChain = $this->localizationService->getLocaleChain($locale);
         foreach ($this->packagesRegisteredForAutoInclusion as $packageKey => $sourcesToBeIncluded) {
             if (!is_array($sourcesToBeIncluded)) {
                 continue;
             }
             $translationBasePath = Files::concatenatePaths([$this->packageManager->getPackage($packageKey)->getResourcesPath(), $this->xliffBasePath]);
             // We merge labels in the chain from the worst choice to best choice
             foreach (array_reverse($localeChain) as $allowedLocale) {
                 $localeSourcePath = Files::getNormalizedPath(Files::concatenatePaths([$translationBasePath, $allowedLocale]));
                 foreach ($sourcesToBeIncluded as $sourceName) {
                     foreach (glob($localeSourcePath . $sourceName . '.xlf') as $xliffPathAndFilename) {
                         $xliffPathInfo = pathinfo($xliffPathAndFilename);
                         $sourceName = str_replace($localeSourcePath, '', $xliffPathInfo['dirname'] . '/' . $xliffPathInfo['filename']);
                         $labels = Arrays::arrayMergeRecursiveOverrule($labels, $this->parseXliffToArray($xliffPathAndFilename, $packageKey, $sourceName));
                     }
                 }
             }
         }
         $json = json_encode($labels);
         $this->xliffToJsonTranslationsCache->set($cacheIdentifier, $json);
     }
     return $json;
 }
 /**
  * Checks the syntax of the given $packageKey and quits with an error message if it's not valid
  *
  * @param string $packageKey
  * @return void
  */
 protected function validatePackageKey($packageKey)
 {
     if (!$this->packageManager->isPackageKeyValid($packageKey)) {
         $this->outputLine('Package key "%s" is not valid. Only UpperCamelCase with alphanumeric characters in the format <VendorName>.<PackageKey>, please!', array($packageKey));
         exit(1);
     }
 }
 /**
  * Generate a documentation skeleton for the package key
  *
  * @param string $packageKey The package key
  * @return array An array of generated filenames
  */
 public function generateDocumentation($packageKey)
 {
     $documentationPath = Files::concatenatePaths([$this->packageManager->getPackage($packageKey)->getPackagePath(), 'Documentation']);
     $contextVariables = array();
     $contextVariables['packageKey'] = $packageKey;
     $templatePathAndFilename = 'resource://Neos.Kickstarter/Private/Generator/Documentation/conf.py';
     $fileContent = $this->renderTemplate($templatePathAndFilename, $contextVariables);
     $targetPathAndFilename = $documentationPath . '/conf.py';
     $this->generateFile($targetPathAndFilename, $fileContent);
     $templatePathAndFilename = 'resource://Neos.Kickstarter/Private/Generator/Documentation/Makefile';
     $fileContent = file_get_contents($templatePathAndFilename);
     $targetPathAndFilename = $documentationPath . '/Makefile';
     $this->generateFile($targetPathAndFilename, $fileContent);
     $templatePathAndFilename = 'resource://Neos.Kickstarter/Private/Generator/Documentation/index.rst';
     $fileContent = $this->renderTemplate($templatePathAndFilename, $contextVariables);
     $targetPathAndFilename = $documentationPath . '/index.rst';
     $this->generateFile($targetPathAndFilename, $fileContent);
     $targetPathAndFilename = $documentationPath . '/_build/.gitignore';
     $this->generateFile($targetPathAndFilename, '*' . chr(10) . '!.gitignore' . chr(10));
     $targetPathAndFilename = $documentationPath . '/_static/.gitignore';
     $this->generateFile($targetPathAndFilename, '*' . chr(10) . '!.gitignore' . chr(10));
     $targetPathAndFilename = $documentationPath . '/_templates/.gitignore';
     $this->generateFile($targetPathAndFilename, '*' . chr(10) . '!.gitignore' . chr(10));
     return $this->generatedFiles;
 }
 /**
  * Import sites content
  *
  * This command allows for importing one or more sites or partial content from an XML source. The format must
  * be identical to that produced by the export command.
  *
  * If a filename is specified, this command expects the corresponding file to contain the XML structure. The
  * filename php://stdin can be used to read from standard input.
  *
  * If a package key is specified, this command expects a Sites.xml file to be located in the private resources
  * directory of the given package (Resources/Private/Content/Sites.xml).
  *
  * @param string $packageKey Package key specifying the package containing the sites content
  * @param string $filename relative path and filename to the XML file containing the sites content
  * @return void
  */
 public function importCommand($packageKey = null, $filename = null)
 {
     $exceedingArguments = $this->request->getExceedingArguments();
     if (isset($exceedingArguments[0]) && $packageKey === null && $filename === null) {
         if (file_exists($exceedingArguments[0])) {
             $filename = $exceedingArguments[0];
         } elseif ($this->packageManager->isPackageAvailable($exceedingArguments[0])) {
             $packageKey = $exceedingArguments[0];
         }
     }
     if ($packageKey === null && $filename === null) {
         $this->outputLine('You have to specify either "--package-key" or "--filename"');
         $this->quit(1);
     }
     $site = null;
     if ($filename !== null) {
         try {
             $site = $this->siteImportService->importFromFile($filename);
         } catch (\Exception $exception) {
             $this->systemLogger->logException($exception);
             $this->outputLine('<error>During the import of the file "%s" an exception occurred: %s, see log for further information.</error>', array($filename, $exception->getMessage()));
             $this->quit(1);
         }
     } else {
         try {
             $site = $this->siteImportService->importFromPackage($packageKey);
         } catch (\Exception $exception) {
             $this->systemLogger->logException($exception);
             $this->outputLine('<error>During the import of the "Sites.xml" from the package "%s" an exception occurred: %s, see log for further information.</error>', array($packageKey, $exception->getMessage()));
             $this->quit(1);
         }
     }
     $this->outputLine('Import of site "%s" finished.', array($site->getName()));
 }
 /**
  * Generate additional folders for site packages.
  *
  * @param string $packageKey
  */
 protected function generateAdditionalFolders($packageKey)
 {
     $resourcesPath = $this->packageManager->getPackage($packageKey)->getResourcesPath();
     $publicResourcesPath = Files::concatenatePaths(array($resourcesPath, 'Public'));
     foreach (array('Images', 'JavaScript', 'Styles') as $publicResourceFolder) {
         Files::createDirectoryRecursively(Files::concatenatePaths(array($publicResourcesPath, $publicResourceFolder)));
     }
 }
 /**
  * @param string $packageKey
  * @return string|null
  */
 protected function getPackagePrivateResourcesPath($packageKey)
 {
     if (!$this->packageManager->isPackageActive($packageKey)) {
         return null;
     }
     $packageResourcesPath = $this->packageManager->getPackage($packageKey)->getResourcesPath();
     return Files::concatenatePaths([$packageResourcesPath, 'Private']);
 }
Example #13
0
 /**
  * @param PaletteInterface $proxy
  * @param $profilePath
  * @return \Imagine\Image\Profile
  */
 protected function createAndSetProfileOnProxy(PaletteInterface $proxy, $profilePath)
 {
     if (substr($profilePath, 0, 11) !== 'resource://') {
         $profilePath = $this->packageManager->getPackage('imagine.imagine')->getPackagePath() . 'lib/Imagine/resources/' . $profilePath;
     }
     $profile = Profile::fromPath($profilePath);
     ObjectAccess::setProperty($proxy, 'profile', $profile, TRUE);
     return $profile;
 }
 /**
  * Rescan package availability and recreates the PackageStates configuration.
  */
 public function rescanCommand()
 {
     $packageStates = $this->packageManager->rescanPackages();
     $this->outputLine('The following packages are registered and will be loaded in this order:');
     $this->outputLine('');
     foreach ($packageStates['packages'] as $composerName => $packageState) {
         $this->outputLine($composerName);
     }
     $this->outputLine('');
     $this->outputLine('Package rescan successful.');
 }
 /**
  * @param string $packageKey
  * @return Error|Message
  */
 protected function freezePackage($packageKey)
 {
     try {
         $this->packageManager->freezePackage($packageKey);
         $message = new Message('Package %s has been frozen', 1343231689, array($packageKey));
     } catch (\LogicException $exception) {
         $message = new Error($exception->getMessage(), 1343231690);
     } catch (UnknownPackageException $exception) {
         $message = new Error($exception->getMessage(), 1343231691);
     }
     return $message;
 }
 /**
  * If site packages already exist and are active, we will deactivate them in order to prevent
  * interactions with the newly created or imported package (like Content Dimensions being used).
  *
  * @param string $activePackageKey Package key of one package which should stay active
  * @return array deactivated site packages
  */
 protected function deactivateAllOtherSitePackages($activePackageKey)
 {
     $sitePackagesToDeactivate = $this->packageManager->getFilteredPackages('active', null, 'neos-site');
     $deactivatedSitePackages = array();
     foreach (array_keys($sitePackagesToDeactivate) as $packageKey) {
         if ($packageKey !== $activePackageKey) {
             $this->packageManager->deactivatePackage($packageKey);
             $deactivatedSitePackages[] = $packageKey;
         }
     }
     return $deactivatedSitePackages;
 }
 /**
  * @test
  */
 public function openResolves40CharacterLongPackageKeysUsingThePackageManager()
 {
     $packageKey = 'Some.PackageKey.Containing.40.Characters';
     mkdir('vfs://Foo/Some/');
     file_put_contents('vfs://Foo/Some/Path', 'fixture');
     $this->mockPackageManager->expects($this->once())->method('isPackageAvailable')->with($packageKey)->will($this->returnValue(true));
     $mockPackage = $this->createMock(PackageInterface::class);
     $mockPackage->expects($this->any())->method('getResourcesPath')->will($this->returnValue('vfs://Foo'));
     $this->mockPackageManager->expects($this->once())->method('getPackage')->with($packageKey)->will($this->returnValue($mockPackage));
     $openedPathAndFilename = '';
     $this->assertTrue($this->resourceStreamWrapper->open('resource://' . $packageKey . '/Some/Path', 'r', 0, $openedPathAndFilename));
     $this->assertSame($openedPathAndFilename, 'vfs://Foo/Some/Path');
 }
 /**
  * Returns the absolute paths of public resources directories of all active packages.
  * This method is used directly by the FileSystemSymlinkTarget.
  *
  * @return array<string>
  */
 public function getPublicResourcePaths()
 {
     $paths = [];
     $packages = $this->packageManager->getActivePackages();
     foreach ($packages as $packageKey => $package) {
         /** @var PackageInterface $package */
         $publicResourcesPath = Files::concatenatePaths([$package->getResourcesPath(), 'Public']);
         if (is_dir($publicResourcesPath)) {
             $paths[$packageKey] = $publicResourcesPath;
         }
     }
     return $paths;
 }
 /**
  * @return void
  */
 protected function displayHelpIndex()
 {
     $context = $this->bootstrap->getContext();
     $applicationPackage = $this->packageManager->getPackage($this->applicationPackageKey);
     $this->outputLine('<b>%s %s ("%s" context)</b>', [$applicationPackage->getComposerManifest('description'), $applicationPackage->getInstalledVersion() ?: 'dev', $context]);
     $this->outputLine('<i>usage: %s <command identifier></i>', [$this->getFlowInvocationString()]);
     $this->outputLine();
     $this->outputLine('The following commands are currently available:');
     $this->displayShortHelpForCommands($this->commandManager->getAvailableCommands());
     $this->outputLine('* = compile time command');
     $this->outputLine();
     $this->outputLine('See "%s help <commandidentifier>" for more information about a specific command.', [$this->getFlowInvocationString()]);
     $this->outputLine();
 }
 /**
  * If Site Packages already exist and are active, we will deactivate them in order to prevent
  * interactions with the newly created or imported package (like Content Dimensions being used).
  *
  * @param string $packageKey
  * @return array
  */
 protected function deactivateOtherSitePackages($packageKey)
 {
     $sitePackagesToDeactivate = $this->packageManager->getFilteredPackages('active', null, 'neos-site');
     $deactivatedSitePackages = array();
     foreach ($sitePackagesToDeactivate as $sitePackageToDeactivate) {
         if ($sitePackageToDeactivate->getPackageKey() !== $packageKey) {
             $this->packageManager->deactivatePackage($sitePackageToDeactivate->getPackageKey());
             $deactivatedSitePackages[] = $sitePackageToDeactivate->getPackageKey();
         }
     }
     if (count($deactivatedSitePackages) >= 1) {
         $this->flashMessageContainer->addMessage(new Message(sprintf('The existing Site Packages "%s" were deactivated, in order to prevent interactions with the newly created package "%s".', implode(', ', $deactivatedSitePackages), $packageKey)));
     }
 }
 /**
  * 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 \Neos\Error\Messages\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 = [];
     $activePackages = $this->packageManager->getActivePackages();
     foreach ($activePackages as $package) {
         $packageKey = $package->getPackageKey();
         $packageSchemaPath = Files::concatenatePaths([$package->getResourcesPath(), 'Private/Schema']);
         if (is_dir($packageSchemaPath)) {
             foreach (Files::getRecursiveDirectoryGenerator($packageSchemaPath, '.schema.yaml') 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[] = ['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 = Arrays::getValueByPath($configuration, $schemaFileInfo['path']);
         } else {
             $data = $configuration;
         }
         if (empty($data)) {
             $result->addNotice(new Notice('No configuration found, skipping schema "%s".', 1364985445, [substr($schemaFileInfo['file'], strlen(FLOW_PATH_ROOT))]));
         } else {
             $parsedSchema = 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;
 }
Example #22
0
 /**
  * Generate a new migration
  *
  * If $diffAgainstCurrent is TRUE (the default), it generates a migration file
  * with the diff between current DB structure and the found mapping metadata.
  *
  * Otherwise an empty migration skeleton is generated.
  *
  * Only includes tables/sequences matching the $filterExpression regexp when
  * diffing models and existing schema. Include delimiters in the expression!
  * The use of
  *
  *  --filter-expression '/^acme_com/'
  *
  * would only create a migration touching tables starting with "acme_com".
  *
  * Note: A filter-expression will overrule any filter configured through the
  * Neos.Flow.persistence.doctrine.migrations.ignoredTables setting
  *
  * @param boolean $diffAgainstCurrent Whether to base the migration on the current schema structure
  * @param string $filterExpression Only include tables/sequences matching the filter expression regexp
  * @return void
  * @see neos.flow:doctrine:migrate
  * @see neos.flow:doctrine:migrationstatus
  * @see neos.flow:doctrine:migrationexecute
  * @see neos.flow:doctrine:migrationversion
  */
 public function migrationGenerateCommand($diffAgainstCurrent = true, $filterExpression = null)
 {
     // "driver" is used only for Doctrine, thus we (mis-)use it here
     // additionally, when no host is set, skip this step, assuming no DB is needed
     if (!$this->isDatabaseConfigured()) {
         $this->outputLine('Doctrine migration generation has been SKIPPED, the driver and host backend options are not set in /Configuration/Settings.yaml.');
         $this->quit(1);
     }
     // use default filter expression from settings
     if ($filterExpression === null) {
         $ignoredTables = array_keys(array_filter($this->settings['doctrine']['migrations']['ignoredTables']));
         if ($ignoredTables !== array()) {
             $filterExpression = sprintf('/^(?!%s$).*$/xs', implode('$|', $ignoredTables));
         }
     }
     list($status, $migrationClassPathAndFilename) = $this->doctrineService->generateMigration($diffAgainstCurrent, $filterExpression);
     $this->outputLine('<info>%s</info>', [$status]);
     $this->outputLine();
     if ($migrationClassPathAndFilename) {
         $choices = ['Don\'t Move'];
         $packages = [null];
         /** @var Package $package */
         foreach ($this->packageManager->getAvailablePackages() as $package) {
             $type = $package->getComposerManifest('type');
             if ($type === null || strpos($type, 'typo3-') !== 0 && strpos($type, 'neos-') !== 0) {
                 continue;
             }
             $choices[] = $package->getPackageKey();
             $packages[] = $package;
         }
         $selectedPackageIndex = (int) $this->output->select('Do you want to move the migration to one of these packages?', $choices, 0);
         $this->outputLine();
         if ($selectedPackageIndex !== 0) {
             /** @var Package $selectedPackage */
             $selectedPackage = $packages[$selectedPackageIndex];
             $targetPathAndFilename = Files::concatenatePaths([$selectedPackage->getPackagePath(), 'Migrations', $this->doctrineService->getDatabasePlatformName(), basename($migrationClassPathAndFilename)]);
             Files::createDirectoryRecursively(dirname($targetPathAndFilename));
             rename($migrationClassPathAndFilename, $targetPathAndFilename);
             $this->outputLine('The migration was moved to: <comment>%s</comment>', [substr($targetPathAndFilename, strlen(FLOW_PATH_PACKAGES))]);
             $this->outputLine();
             $this->outputLine('Next Steps:');
         } else {
             $this->outputLine('Next Steps:');
             $this->outputLine(sprintf('- Move <comment>%s</comment> to YourPackage/<comment>Migrations/%s/</comment>', $migrationClassPathAndFilename, $this->doctrineService->getDatabasePlatformName()));
         }
         $this->outputLine('- Review and adjust the generated migration.');
         $this->outputLine('- (optional) execute the migration using <comment>%s doctrine:migrate</comment>', [$this->getFlowInvocationString()]);
     }
 }
 /**
  * @param string $driver
  * @return array Not supported image format
  */
 protected function findUnsupportedImageFormats($driver)
 {
     $this->imagineFactory->injectSettings(array('driver' => ucfirst($driver)));
     $imagine = $this->imagineFactory->create();
     $unsupportedFormats = array();
     foreach (array('jpg', 'gif', 'png') as $imageFormat) {
         $imagePath = Files::concatenatePaths(array($this->packageManager->getPackage('Neos.Neos')->getResourcesPath(), 'Private/Installer/TestImages/Test.' . $imageFormat));
         try {
             $imagine->open($imagePath);
         } catch (\Exception $exception) {
             $unsupportedFormats[] = sprintf('"%s"', $imageFormat);
         }
     }
     return $unsupportedFormats;
 }
 /**
  * Finds all Locale objects representing locales available in the
  * Flow installation. This is done by scanning all Private and Public
  * resource files of all active packages, in order to find localized files.
  *
  * Localized files have a locale identifier added before their extension
  * (or at the end of filename, if no extension exists). For example, a
  * localized file for foobar.png, can be foobar.en.png, fobar.en_GB.png, etc.
  *
  * Just one localized resource file causes the corresponding locale to be
  * regarded as available (installed, supported).
  *
  * Note: result of this method invocation is cached
  *
  * @return void
  */
 protected function generateAvailableLocalesCollectionByScanningFilesystem()
 {
     $whitelistPaths = array_keys(array_filter((array) $this->settings['scan']['includePaths']));
     if ($whitelistPaths === []) {
         return;
     }
     $blacklistPattern = $this->getScanBlacklistPattern();
     /** @var PackageInterface $activePackage */
     foreach ($this->packageManager->getActivePackages() as $activePackage) {
         $packageResourcesPath = Files::getNormalizedPath($activePackage->getResourcesPath());
         if (!is_dir($packageResourcesPath)) {
             continue;
         }
         $directories = [];
         foreach ($whitelistPaths as $path) {
             $scanPath = Files::concatenatePaths(array($packageResourcesPath, $path));
             if (is_dir($scanPath)) {
                 array_push($directories, Files::getNormalizedPath($scanPath));
             }
         }
         while ($directories !== []) {
             $currentDirectory = array_pop($directories);
             $relativeDirectory = '/' . str_replace($packageResourcesPath, '', $currentDirectory);
             if ($blacklistPattern !== '' && preg_match($blacklistPattern, $relativeDirectory) === 1) {
                 continue;
             }
             if ($handle = opendir($currentDirectory)) {
                 while (false !== ($filename = readdir($handle))) {
                     if ($filename[0] === '.') {
                         continue;
                     }
                     $pathAndFilename = Files::concatenatePaths([$currentDirectory, $filename]);
                     if (is_dir($pathAndFilename)) {
                         array_push($directories, Files::getNormalizedPath($pathAndFilename));
                     } else {
                         $localeIdentifier = Utility::extractLocaleTagFromFilename($filename);
                         if ($localeIdentifier !== false) {
                             $this->localeCollection->addLocale(new Locale($localeIdentifier));
                         }
                     }
                 }
                 closedir($handle);
             }
         }
     }
 }
 /**
  * Tries to find out a package key which the Version belongs to. If no
  * package could be found, an empty string is returned.
  *
  * @param Version $version
  * @return string
  */
 protected function getPackageKeyFromMigrationVersion(Version $version)
 {
     $sortedAvailablePackages = $this->packageManager->getAvailablePackages();
     usort($sortedAvailablePackages, function (PackageInterface $packageOne, PackageInterface $packageTwo) {
         return strlen($packageTwo->getPackagePath()) - strlen($packageOne->getPackagePath());
     });
     $reflectedClass = new \ReflectionClass($version->getMigration());
     $classPathAndFilename = Files::getUnixStylePath($reflectedClass->getFileName());
     /** @var $package PackageInterface */
     foreach ($sortedAvailablePackages as $package) {
         $packagePath = Files::getUnixStylePath($package->getPackagePath());
         if (strpos($classPathAndFilename, $packagePath) === 0) {
             return $package->getPackageKey();
         }
     }
     return '';
 }
 /**
  * Replace resource on an asset. Takes variants and redirect handling into account.
  *
  * @param AssetInterface $asset
  * @param PersistentResource $resource
  * @param array $options
  * @return void
  */
 public function replaceAssetResource(AssetInterface $asset, PersistentResource $resource, array $options = [])
 {
     $originalAssetResource = $asset->getResource();
     $asset->setResource($resource);
     if (isset($options['keepOriginalFilename']) && (bool) $options['keepOriginalFilename'] === true) {
         $asset->getResource()->setFilename($originalAssetResource->getFilename());
     }
     $uriMapping = [];
     $redirectHandlerEnabled = isset($options['generateRedirects']) && (bool) $options['generateRedirects'] === true && $this->packageManager->isPackageAvailable('Neos.RedirectHandler');
     if ($redirectHandlerEnabled) {
         $uriMapping[$this->resourceManager->getPublicPersistentResourceUri($originalAssetResource)] = $this->resourceManager->getPublicPersistentResourceUri($asset->getResource());
     }
     if (method_exists($asset, 'getVariants')) {
         $variants = $asset->getVariants();
         /** @var AssetVariantInterface $variant */
         foreach ($variants as $variant) {
             $originalVariantResource = $variant->getResource();
             $variant->refresh();
             if (method_exists($variant, 'getAdjustments')) {
                 foreach ($variant->getAdjustments() as $adjustment) {
                     if (method_exists($adjustment, 'refit')) {
                         $adjustment->refit($asset);
                     }
                 }
             }
             if ($redirectHandlerEnabled) {
                 $uriMapping[$this->resourceManager->getPublicPersistentResourceUri($originalVariantResource)] = $this->resourceManager->getPublicPersistentResourceUri($variant->getResource());
             }
             $this->getRepository($variant)->update($variant);
         }
     }
     if ($redirectHandlerEnabled) {
         /** @var \Neos\RedirectHandler\Storage\RedirectStorageInterface $redirectStorage */
         $redirectStorage = $this->objectManager->get(\Neos\RedirectHandler\Storage\RedirectStorageInterface::class);
         foreach ($uriMapping as $originalUri => $newUri) {
             $existingRedirect = $redirectStorage->getOneBySourceUriPathAndHost($originalUri);
             if ($existingRedirect === null) {
                 $redirectStorage->addRedirect($originalUri, $newUri, 301);
             }
         }
     }
     $this->getRepository($asset)->update($asset);
     $this->emitAssetResourceReplaced($asset);
 }
 /**
  * Imports one or multiple sites from the XML file at $pathAndFilename
  *
  * @param string $pathAndFilename
  * @return Site The imported site
  * @throws UnknownPackageException|InvalidPackageStateException|NeosException
  */
 public function importFromFile($pathAndFilename)
 {
     /** @var Site $importedSite */
     $site = null;
     $xmlReader = new \XMLReader();
     $xmlReader->open($pathAndFilename, null, LIBXML_PARSEHUGE);
     if ($this->workspaceRepository->findOneByName('live') === null) {
         $this->workspaceRepository->add(new Workspace('live'));
         $this->persistenceManager->persistAll();
     }
     while ($xmlReader->read()) {
         if ($xmlReader->nodeType != \XMLReader::ELEMENT || $xmlReader->name !== 'site') {
             continue;
         }
         $site = $this->getSiteByNodeName($xmlReader->getAttribute('siteNodeName'));
         $site->setName($xmlReader->getAttribute('name'));
         $site->setState((int) $xmlReader->getAttribute('state'));
         $siteResourcesPackageKey = $xmlReader->getAttribute('siteResourcesPackageKey');
         if (!$this->packageManager->isPackageAvailable($siteResourcesPackageKey)) {
             throw new UnknownPackageException(sprintf('Package "%s" specified in the XML as site resources package does not exist.', $siteResourcesPackageKey), 1303891443);
         }
         if (!$this->packageManager->isPackageActive($siteResourcesPackageKey)) {
             throw new InvalidPackageStateException(sprintf('Package "%s" specified in the XML as site resources package is not active.', $siteResourcesPackageKey), 1303898135);
         }
         $site->setSiteResourcesPackageKey($siteResourcesPackageKey);
         $rootNode = $this->contextFactory->create()->getRootNode();
         // We fetch the workspace to be sure it's known to the persistence manager and persist all
         // so the workspace and site node are persisted before we import any nodes to it.
         $rootNode->getContext()->getWorkspace();
         $this->persistenceManager->persistAll();
         $sitesNode = $rootNode->getNode(SiteService::SITES_ROOT_PATH);
         if ($sitesNode === null) {
             $sitesNode = $rootNode->createNode(NodePaths::getNodeNameFromPath(SiteService::SITES_ROOT_PATH));
         }
         $this->nodeImportService->import($xmlReader, $sitesNode->getPath(), dirname($pathAndFilename) . '/Resources');
     }
     if ($site === null) {
         throw new NeosException(sprintf('The XML file did not contain a valid site node.'), 1418999522);
     }
     $this->emitSiteImported($site);
     return $site;
 }
 /**
  * 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 \InvalidArgumentException|ResourceException
  */
 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 = Functions::parse_url($requestedPath);
     if (!is_array($uriParts) || !isset($uriParts['host'])) {
         return false;
     }
     if (preg_match('/^[0-9a-f]{40}$/i', $uriParts['host']) === 1) {
         $resource = $this->resourceManager->getResourceBySha1($uriParts['host']);
         return $this->resourceManager->getStreamByResource($resource);
     }
     if (!$this->packageManager->isPackageAvailable($uriParts['host'])) {
         throw new ResourceException(sprintf('Invalid resource URI "%s": Package "%s" is not available.', $requestedPath, $uriParts['host']), 1309269952);
     }
     $package = $this->packageManager->getPackage($uriParts['host']);
     $resourceUri = Files::concatenatePaths([$package->getResourcesPath(), $uriParts['path']]);
     if ($checkForExistence === false || file_exists($resourceUri)) {
         return $resourceUri;
     }
     return false;
 }
Example #29
0
 /**
  * Clean up resource registry
  *
  * This command checks the resource registry (that is the database tables) for orphaned resource objects which don't
  * seem to have any corresponding data anymore (for example: the file in Data/Persistent/Resources has been deleted
  * without removing the related PersistentResource object).
  *
  * If the Neos.Media package is active, this command will also detect any assets referring to broken resources
  * and will remove the respective Asset object from the database when the broken resource is removed.
  *
  * This command will ask you interactively what to do before deleting anything.
  *
  * @return void
  */
 public function cleanCommand()
 {
     $this->outputLine('Checking if resource data exists for all known resource objects ...');
     $this->outputLine();
     $mediaPackagePresent = $this->packageManager->isPackageActive('Neos.Media');
     $resourcesCount = $this->resourceRepository->countAll();
     $this->output->progressStart($resourcesCount);
     $brokenResources = [];
     $relatedAssets = new \SplObjectStorage();
     $relatedThumbnails = new \SplObjectStorage();
     $iterator = $this->resourceRepository->findAllIterator();
     foreach ($this->resourceRepository->iterate($iterator, function ($iteration) {
         $this->clearState($iteration);
     }) as $resource) {
         $this->output->progressAdvance(1);
         /* @var PersistentResource $resource */
         $stream = $resource->getStream();
         if (!is_resource($stream)) {
             $brokenResources[] = $resource->getSha1();
         }
     }
     $this->output->progressFinish();
     $this->outputLine();
     if ($mediaPackagePresent && count($brokenResources) > 0) {
         /* @var AssetRepository $assetRepository */
         $assetRepository = $this->objectManager->get(AssetRepository::class);
         /* @var ThumbnailRepository $thumbnailRepository */
         $thumbnailRepository = $this->objectManager->get(ThumbnailRepository::class);
         foreach ($brokenResources as $key => $resourceSha1) {
             $resource = $this->resourceRepository->findOneBySha1($resourceSha1);
             $brokenResources[$key] = $resource;
             $assets = $assetRepository->findByResource($resource);
             if ($assets !== null) {
                 $relatedAssets[$resource] = $assets;
             }
             $thumbnails = $thumbnailRepository->findByResource($resource);
             if ($assets !== null) {
                 $relatedThumbnails[$resource] = $thumbnails;
             }
         }
     }
     if (count($brokenResources) > 0) {
         $this->outputLine('<b>Found %s broken resource(s):</b>', [count($brokenResources)]);
         $this->outputLine();
         foreach ($brokenResources as $resource) {
             $this->outputLine('%s (%s) from "%s" collection', [$resource->getFilename(), $resource->getSha1(), $resource->getCollectionName()]);
             if (isset($relatedAssets[$resource])) {
                 foreach ($relatedAssets[$resource] as $asset) {
                     $this->outputLine(' -> %s (%s)', [get_class($asset), $asset->getIdentifier()]);
                 }
             }
         }
         $response = null;
         while (!in_array($response, ['y', 'n', 'c'])) {
             $response = $this->output->ask('<comment>Do you want to remove all broken resource objects and related assets from the database? (y/n/c) </comment>');
         }
         switch ($response) {
             case 'y':
                 $brokenAssetCounter = 0;
                 $brokenThumbnailCounter = 0;
                 foreach ($brokenResources as $sha1 => $resource) {
                     $this->outputLine('- delete %s (%s) from "%s" collection', [$resource->getFilename(), $resource->getSha1(), $resource->getCollectionName()]);
                     $resource->disableLifecycleEvents();
                     $this->resourceRepository->remove($resource);
                     if (isset($relatedAssets[$resource])) {
                         foreach ($relatedAssets[$resource] as $asset) {
                             $assetRepository->remove($asset);
                             $brokenAssetCounter++;
                         }
                     }
                     if (isset($relatedThumbnails[$resource])) {
                         foreach ($relatedThumbnails[$resource] as $thumbnail) {
                             $thumbnailRepository->remove($thumbnail);
                             $brokenThumbnailCounter++;
                         }
                     }
                     $this->persistenceManager->persistAll();
                 }
                 $brokenResourcesCounter = count($brokenResources);
                 if ($brokenResourcesCounter > 0) {
                     $this->outputLine('Removed %s resource object(s) from the database.', [$brokenResourcesCounter]);
                 }
                 if ($brokenAssetCounter > 0) {
                     $this->outputLine('Removed %s asset object(s) from the database.', [$brokenAssetCounter]);
                 }
                 if ($brokenThumbnailCounter > 0) {
                     $this->outputLine('Removed %s thumbnail object(s) from the database.', [$brokenThumbnailCounter]);
                 }
                 break;
             case 'n':
                 $this->outputLine('Did not delete any resource objects.');
                 break;
             case 'c':
                 $this->outputLine('Stopping. Did not delete any resource objects.');
                 $this->quit(0);
                 break;
         }
     }
 }
Example #30
0
 /**
  * Prepares an array with TypoScript paths to auto include before the Site TypoScript.
  *
  * @return array
  */
 protected function prepareAutoIncludeTypoScript()
 {
     $autoIncludeTypoScript = array();
     foreach (array_keys($this->packageManager->getActivePackages()) as $packageKey) {
         if (isset($this->autoIncludeConfiguration[$packageKey]) && $this->autoIncludeConfiguration[$packageKey] === true) {
             $autoIncludeTypoScriptFile = sprintf($this->autoIncludeTypoScriptPattern, $packageKey);
             if (is_file($autoIncludeTypoScriptFile)) {
                 $autoIncludeTypoScript[] = $autoIncludeTypoScriptFile;
             } else {
                 // If there is no Root.fusion found in the default path pattern or the legacy path pattern
                 // use the default path pattern so an exception will show the correct path pattern and not a
                 // legacy path pattern
                 $legacyAutoIncludeTypoScriptFile = sprintf($this->legacyAutoIncludeTypoScriptPattern, $packageKey);
                 if (is_file($legacyAutoIncludeTypoScriptFile)) {
                     $autoIncludeTypoScript[] = $legacyAutoIncludeTypoScriptFile;
                 } else {
                     $autoIncludeTypoScript[] = $autoIncludeTypoScriptFile;
                 }
             }
         }
     }
     return $autoIncludeTypoScript;
 }