/** * @return void */ protected function displayHelpIndex() { $context = $this->bootstrap->getContext(); $this->outputLine('<b>FLOW3 %s ("%s" context)</b>', array($this->packageManager->getPackage('TYPO3.FLOW3')->getPackageMetaData()->getVersion(), $context)); $this->outputLine('<i>usage: %s <command identifier></i>', array($this->getFlow3InvocationString())); $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.', array($this->getFlow3InvocationString())); $this->outputLine(); }
/** * Loads the states of available packages from the PackageStates.php file. * The result is stored in $this->packageStatesConfiguration. * * @return void */ protected function loadPackageStates() { $this->packageStatesConfiguration = file_exists($this->packageStatesPathAndFilename) ? include $this->packageStatesPathAndFilename : array(); if (!isset($this->packageStatesConfiguration['version']) || $this->packageStatesConfiguration['version'] < 2) { if (is_dir(FLOW3_PATH_PACKAGES . '.Shortcuts')) { Files::removeDirectoryRecursively(FLOW3_PATH_PACKAGES . '.Shortcuts'); } $this->packageStatesConfiguration = array(); } if ($this->packageStatesConfiguration === array() || !$this->bootstrap->getContext()->isProduction()) { $this->scanAvailablePackages(); } else { $this->registerPackages(); } }
/** * Launch sub process * * @return array The new sub process and its STDIN, STDOUT, STDERR pipes – or FALSE if an error occurred. * @throws \RuntimeException */ protected function launchSubProcess() { $systemCommand = 'FLOW3_ROOTPATH=' . FLOW3_PATH_ROOT . ' ' . 'FLOW3_CONTEXT=' . $this->bootstrap->getContext() . ' ' . PHP_BINDIR . '/php -c ' . php_ini_loaded_file() . ' ' . FLOW3_PATH_FLOW3 . 'Scripts/flow3.php' . ' --start-slave'; $descriptorSpecification = array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'a')); $subProcess = proc_open($systemCommand, $descriptorSpecification, $pipes); if (!is_resource($subProcess)) { throw new \RuntimeException('Could not execute sub process.'); } $read = array($pipes[1]); $write = null; $except = null; $readTimeout = 30; stream_select($read, $write, $except, $readTimeout); $subProcessStatus = proc_get_status($subProcess); return $subProcessStatus['running'] === TRUE ? array($subProcess, $pipes) : FALSE; }
/** * Refreeze a package * * Refreezes a currently frozen package: all precompiled information is removed * and file monitoring will consider the package exactly once, on the next * request. After that request, the package remains frozen again, just with the * updated data. * * By specifying <b>all</b> as a package key, all currently frozen packages are * refrozen (the default). * * @param string $packageKey Key of the package to refreeze, or 'all' * @return void * @see typo3.flow3:package:freeze * @see typo3.flow3:cache:flush */ public function refreezeCommand($packageKey = 'all') { if (!$this->bootstrap->getContext()->isDevelopment()) { $this->outputLine('Package freezing is only supported in Development context.'); $this->quit(3); } $packagesToRefreeze = array(); if ($packageKey === 'all') { foreach (array_keys($this->packageManager->getAvailablePackages()) as $packageKey) { if ($this->packageManager->isPackageFrozen($packageKey)) { $packagesToRefreeze[] = $packageKey; } } if ($packagesToRefreeze === array()) { $this->outputLine('Nothing to do, no packages were frozen.'); $this->quit(0); } } else { if ($packageKey === NULL) { $this->outputLine('You must specify a package to refreeze.'); $this->quit(1); } if (!$this->packageManager->isPackageAvailable($packageKey)) { $this->outputLine('Package "%s" is not available.', array($packageKey)); $this->quit(2); } if (!$this->packageManager->isPackageFrozen($packageKey)) { $this->outputLine('Package "%s" was not frozen.', array($packageKey)); $this->quit(0); } $packagesToRefreeze = array($packageKey); } foreach ($packagesToRefreeze as $packageKey) { $this->packageManager->refreezePackage($packageKey); $this->outputLine('Refroze package "%s".', array($packageKey)); } Scripts::executeCommand('typo3.flow3:cache:flush', $this->settings, FALSE); $this->sendAndExit(0); }
/** * Invokes custom PHP code directly after the package manager has been initialized. * * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) { $bootstrap->registerRequestHandler(new \TYPO3\FLOW3\Cli\SlaveRequestHandler($bootstrap)); $bootstrap->registerRequestHandler(new \TYPO3\FLOW3\Cli\CommandRequestHandler($bootstrap)); $bootstrap->registerRequestHandler(new \TYPO3\FLOW3\Http\RequestHandler($bootstrap)); if ($bootstrap->getContext()->isTesting()) { $bootstrap->getEarlyInstance('TYPO3\\FLOW3\\Core\\ClassLoader')->setConsiderTestsNamespace(TRUE); $bootstrap->registerRequestHandler(new \TYPO3\FLOW3\Tests\FunctionalTestRequestHandler($bootstrap)); } $bootstrap->registerCompiletimeCommand('typo3.flow3:core:*'); $bootstrap->registerCompiletimeCommand('typo3.flow3:cache:flush'); $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect('TYPO3\\FLOW3\\Mvc\\Dispatcher', 'afterControllerInvocation', 'TYPO3\\FLOW3\\Persistence\\PersistenceManagerInterface', 'persistAll'); $dispatcher->connect('TYPO3\\FLOW3\\Cli\\SlaveRequestHandler', 'dispatchedCommandLineSlaveRequest', 'TYPO3\\FLOW3\\Persistence\\PersistenceManagerInterface', 'persistAll'); $dispatcher->connect('TYPO3\\FLOW3\\Core\\Bootstrap', 'bootstrapShuttingDown', 'TYPO3\\FLOW3\\Configuration\\ConfigurationManager', 'shutdown'); $dispatcher->connect('TYPO3\\FLOW3\\Core\\Bootstrap', 'bootstrapShuttingDown', 'TYPO3\\FLOW3\\Object\\ObjectManagerInterface', 'shutdown'); $dispatcher->connect('TYPO3\\FLOW3\\Core\\Bootstrap', 'bootstrapShuttingDown', 'TYPO3\\FLOW3\\Reflection\\ReflectionService', 'saveToCache'); $dispatcher->connect('TYPO3\\FLOW3\\Command\\CoreCommandController', 'finishedCompilationRun', 'TYPO3\\FLOW3\\Security\\Policy\\PolicyService', 'savePolicyCache'); $dispatcher->connect('TYPO3\\FLOW3\\Security\\Authentication\\AuthenticationProviderManager', 'authenticatedToken', 'TYPO3\\FLOW3\\Session\\SessionInterface', 'renewId'); $dispatcher->connect('TYPO3\\FLOW3\\Security\\Authentication\\AuthenticationProviderManager', 'loggedOut', 'TYPO3\\FLOW3\\Session\\SessionInterface', 'destroy'); $dispatcher->connect('TYPO3\\FLOW3\\Monitor\\FileMonitor', 'filesHaveChanged', 'TYPO3\\FLOW3\\Cache\\CacheManager', 'flushSystemCachesByChangedFiles'); $dispatcher->connect('TYPO3\\FLOW3\\Tests\\FunctionalTestCase', 'functionalTestTearDown', 'TYPO3\\FLOW3\\Mvc\\Routing\\Aspect\\RouterCachingAspect', 'flushCaches'); }
/** * Flush all caches * * The flush command flushes all caches (including code caches) which have been * registered with FLOW3'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 typo3.flow3:cache:warmup * @see typo3.flow3:package:freeze * @see typo3.flow3:package:refreeze */ public function flushCommand($force = FALSE) { // Internal note: the $force option is evaluated early in the FLOW3 // bootstrap in order to reliably flush the temporary data before any // other code can cause fatal errors. $currentSessionImplementation = $this->objectManager->getClassNameByObjectName('TYPO3\\FLOW3\\Session\\SessionInterface'); $result = $currentSessionImplementation::destroyAll($this->bootstrap); if ($result === NULL) { $sessionDestroyMessage = ' and removed all potentially existing session data.'; } elseif ($result > 0) { $sessionDestroyMessage = sprintf(' and removed data of %s.', $result === 1 ? 'the one existing session' : 'the ' . $result . ' existing sessions'); } else { $sessionDestroyMessage = '.'; } $this->cacheManager->flushCaches(); $this->outputLine('Flushed all caches for "' . $this->bootstrap->getContext() . '" context' . $sessionDestroyMessage); if ($this->lockManager->isSiteLocked()) { $this->lockManager->unlockSite(); } $frozenPackages = array(); foreach (array_keys($this->packageManager->getActivePackages()) as $packageKey) { if ($this->packageManager->isPackageFrozen($packageKey)) { $frozenPackages[] = $packageKey; } } if ($frozenPackages !== array()) { $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, array(), 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 FLOW3 becomes unresponsive.' . PHP_EOL; $this->outputFormatted($message, array($frozenPackages)); } $this->sendAndExit(0); }
/** * @return string */ public function render() { return implode("\n", array('window.T3Configuration = {};', 'window.T3Configuration.Schema = ' . json_encode($this->contentTypeManager->getFullConfiguration()) . ';', 'window.T3Configuration.UserInterface = ' . json_encode($this->settings['userInterface']) . ';', 'window.T3Configuration.phoenixShouldCacheSchema = ' . json_encode($this->bootstrap->getContext()->isProduction()) . ';', 'window.T3Configuration.enableAloha = ' . json_encode($this->settings['enableAloha']) . ';', 'window.T3Configuration.contentTypeGroups = ' . json_encode($this->settings['contentTypeGroups']) . ';')); }
/** * This request handler can handle CLI requests. * * @return boolean If the request is a CLI request, TRUE otherwise FALSE */ public function canHandleRequest() { return PHP_SAPI === 'cli' && $this->bootstrap->getContext()->isTesting(); }
/** * Initializes this service. * * This method must be run only after all dependencies have been injected. * * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap * @return void */ public function initialize(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) { $this->context = $bootstrap->getContext(); if ($this->context->isProduction() && $this->reflectionDataRuntimeCache->getBackend()->isFrozen()) { $this->classReflectionData = $this->reflectionDataRuntimeCache->get('__classNames'); $this->annotatedClasses = $this->reflectionDataRuntimeCache->get('__annotatedClasses'); $this->loadFromClassSchemaRuntimeCache = TRUE; } else { $this->loadClassReflectionCompiletimeCache(); } $this->annotationReader = new \Doctrine\Common\Annotations\AnnotationReader(); foreach ($this->settings['reflection']['ignoredTags'] as $tag) { \Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredName($tag); } \Doctrine\Common\Annotations\AnnotationRegistry::registerLoader(array($this->classLoader, 'loadClass')); }
/** * Initializes the runtime Object Manager * * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap * @return void */ public static function initializeObjectManager(Bootstrap $bootstrap) { $configurationManager = $bootstrap->getEarlyInstance('TYPO3\\FLOW3\\Configuration\\ConfigurationManager'); $objectConfigurationCache = $bootstrap->getEarlyInstance('TYPO3\\FLOW3\\Cache\\CacheManager')->getCache('FLOW3_Object_Configuration'); $objectManager = new \TYPO3\FLOW3\Object\ObjectManager($bootstrap->getContext()); Bootstrap::$staticObjectManager = $objectManager; $objectManager->injectAllSettings($configurationManager->getConfiguration(\TYPO3\FLOW3\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS)); $objectManager->setObjects($objectConfigurationCache->get('objects')); foreach ($bootstrap->getEarlyInstances() as $objectName => $instance) { $objectManager->setInstance($objectName, $instance); } $objectManager->get('TYPO3\\FLOW3\\SignalSlot\\Dispatcher')->injectObjectManager($objectManager); \TYPO3\FLOW3\Error\Debugger::injectObjectManager($objectManager); $bootstrap->setEarlyInstance('TYPO3\\FLOW3\\Object\\ObjectManagerInterface', $objectManager); }