/** * Emits a signal when package states have been changed (e.g. when a package was created or activated) * * The advice is not proxyable, so the signal is dispatched manually here. * * @return void * @Flow\Signal */ protected function emitPackageStatesUpdated() { if ($this->dispatcher === null) { $this->dispatcher = $this->bootstrap->getEarlyInstance(Dispatcher::class); } $this->dispatcher->dispatch(PackageManager::class, 'packageStatesUpdated'); }
/** * Adds an HTTP header to the Response which indicates that the application is powered by Flow. * * @param Response $response * @return void */ protected function addPoweredByHeader(Response $response) { if ($this->settings['http']['applicationToken'] === 'Off') { return; } $applicationIsFlow = $this->settings['core']['applicationPackageKey'] === 'TYPO3.Flow'; if ($this->settings['http']['applicationToken'] === 'ApplicationName') { if ($applicationIsFlow) { $response->getHeaders()->set('X-Flow-Powered', 'Flow'); } else { $response->getHeaders()->set('X-Flow-Powered', 'Flow ' . $this->settings['core']['applicationName']); } return; } /** @var Package $applicationPackage */ /** @var Package $flowPackage */ $flowPackage = $this->bootstrap->getEarlyInstance('TYPO3\\Flow\\Package\\PackageManagerInterface')->getPackage('TYPO3.Flow'); $applicationPackage = $this->bootstrap->getEarlyInstance('TYPO3\\Flow\\Package\\PackageManagerInterface')->getPackage($this->settings['core']['applicationPackageKey']); if ($this->settings['http']['applicationToken'] === 'MajorVersion') { $flowVersion = $this->renderMajorVersion($flowPackage->getInstalledVersion()); $applicationVersion = $this->renderMajorVersion($applicationPackage->getInstalledVersion()); } else { $flowVersion = $this->renderMinorVersion($flowPackage->getInstalledVersion()); $applicationVersion = $this->renderMinorVersion($applicationPackage->getInstalledVersion()); } if ($applicationIsFlow) { $response->getHeaders()->set('X-Flow-Powered', 'Flow/' . ($flowVersion ?: 'dev')); } else { $response->getHeaders()->set('X-Flow-Powered', 'Flow/' . ($flowVersion ?: 'dev') . ' ' . $this->settings['core']['applicationName'] . '/' . ($applicationVersion ?: 'dev')); } }
/** * Display a message. As we cannot rely on any Flow requirements being fulfilled here, * we have to statically include the CSS styles at this point, and have to in-line the TYPO3 logo. * * @param array<\TYPO3\Flow\Error\Message> $messages Array of messages (at least one message must be passed) * @param string $extraHeaderHtml extra HTML code to include at the end of the head tag * @return void This method never returns. */ public function showMessages(array $messages, $extraHeaderHtml = '') { if ($messages === array()) { throw new \InvalidArgumentException('No messages given for rendering', 1416914970); } /** @var \TYPO3\Flow\Package\PackageManagerInterface $packageManager */ $packageManager = $this->bootstrap->getEarlyInstance('TYPO3\\Flow\\Package\\PackageManagerInterface'); $css = ''; if ($packageManager->isPackageAvailable('TYPO3.Twitter.Bootstrap')) { $css .= file_get_contents($packageManager->getPackage('TYPO3.Twitter.Bootstrap')->getResourcesPath() . 'Public/3/css/bootstrap.min.css'); $css = str_replace('url(../', 'url(/_Resources/Static/Packages/TYPO3.Twitter.Bootstrap/3.0/', $css); } if ($packageManager->isPackageAvailable('TYPO3.Setup')) { $css .= file_get_contents($packageManager->getPackage('TYPO3.Setup')->getResourcesPath() . 'Public/Styles/Setup.css'); $css = str_replace('url(\'../', 'url(\'/_Resources/Static/Packages/TYPO3.Setup/', $css); } echo '<html>'; echo '<head>'; echo '<title>Setup message</title>'; echo '<style type="text/css">'; echo $css; echo '</style>'; echo $extraHeaderHtml; echo '</head>'; echo '<body>'; $renderedMessages = $this->renderMessages($messages); $lastMessage = end($messages); echo sprintf(' <div class="logo"></div> <div class="well"> <div class="container"> <ul class="breadcrumb"> <li><a class="active">Setup</a></li> </ul> <h3>%s</h3> <div class="t3-module-container indented"> %s </div> </div> </div> ', $lastMessage->getTitle(), $renderedMessages); echo '</body></html>'; exit(0); }
/** * Helper method to create a FileMonitor instance during boot sequence as injections have to be done manually. * * @param string $identifier * @param Bootstrap $bootstrap * @return FileMonitor */ public static function createFileMonitorAtBoot($identifier, Bootstrap $bootstrap) { $fileMonitorCache = $bootstrap->getEarlyInstance('TYPO3\\Flow\\Cache\\CacheManager')->getCache('Flow_Monitor'); // The change detector needs to be instantiated and registered manually because // it has a complex dependency (cache) but still needs to be a singleton. $fileChangeDetector = new \TYPO3\Flow\Monitor\ChangeDetectionStrategy\ModificationTimeStrategy(); $fileChangeDetector->injectCache($fileMonitorCache); $bootstrap->getObjectManager()->registerShutdownObject($fileChangeDetector, 'shutdownObject'); $fileMonitor = new FileMonitor($identifier); $fileMonitor->injectCache($fileMonitorCache); $fileMonitor->injectChangeDetectionStrategy($fileChangeDetector); $fileMonitor->injectSignalDispatcher($bootstrap->getEarlyInstance('TYPO3\\Flow\\SignalSlot\\Dispatcher')); $fileMonitor->injectSystemLogger($bootstrap->getEarlyInstance('TYPO3\\Flow\\Log\\SystemLoggerInterface')); $fileMonitor->initializeObject(); return $fileMonitor; }
/** * Invokes custom PHP code directly after the package manager has been initialized. * * @param Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(Bootstrap $bootstrap) { if (!file_exists(FLOW_PATH_DATA . 'Logs')) { Files::createDirectoryRecursively(FLOW_PATH_DATA . 'Logs'); } $monologFactory = LoggerFactory::getInstance(); $bootstrap->setEarlyInstance(LoggerFactory::class, $monologFactory); $dispatcher = $bootstrap->getSignalSlotDispatcher(); $dispatcher->connect('TYPO3\\Flow\\Core\\Booting\\Sequence', 'afterInvokeStep', function ($step) use($bootstrap, $dispatcher) { if ($step->getIdentifier() === 'typo3.flow:configuration') { /** @var ConfigurationManager $configurationManager */ $configurationManager = $bootstrap->getEarlyInstance(ConfigurationManager::class); $monologFactory = LoggerFactory::getInstance(); $loggerConfigurations = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Flowpack.Monolog'); $monologFactory->injectConfiguration($loggerConfigurations); } }); }
/** * Sets up xhprof, some directories, the profiler and wires signals to slots. * * @param Bootstrap $bootstrap * @return void */ public function boot(Bootstrap $bootstrap) { if (($samplingRate = getenv('PHPPROFILER_SAMPLINGRATE')) !== FALSE) { $currentSampleValue = mt_rand() / mt_getrandmax(); if ($currentSampleValue > (double) $samplingRate) { return; } } $profiler = Profiler::getInstance(); $profiler->setConfigurationProvider(function () use($bootstrap) { $settings = $bootstrap->getEarlyInstance('TYPO3\\Flow\\Configuration\\ConfigurationManager')->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Sandstorm.PhpProfiler'); if (!file_exists($settings['plumber']['profilePath'])) { Files::createDirectoryRecursively($settings['plumber']['profilePath']); } return $settings; }); $run = $profiler->start(); $run->setOption('Context', (string) $bootstrap->getContext()); $dispatcher = $bootstrap->getSignalSlotDispatcher(); $this->connectToSignals($dispatcher, $profiler, $run, $bootstrap); $this->connectToNeosSignals($dispatcher, $profiler, $run, $bootstrap); }
/** * @param Bootstrap $bootstrap The current bootstrap * @return void */ public function boot(Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); $flushConfigurationCache = function () use($bootstrap) { $cacheManager = $bootstrap->getEarlyInstance('TYPO3\\Flow\\Cache\\CacheManager'); $cacheManager->getCache('TYPO3_Neos_Configuration_Version')->flush(); }; $flushXliffServiceCache = function () use($bootstrap) { $cacheManager = $bootstrap->getEarlyInstance('TYPO3\\Flow\\Cache\\CacheManager'); $cacheManager->getCache('TYPO3_Neos_XliffToJsonTranslations')->flush(); }; $dispatcher->connect('TYPO3\\Flow\\Monitor\\FileMonitor', 'filesHaveChanged', function ($fileMonitorIdentifier, array $changedFiles) use($flushConfigurationCache, $flushXliffServiceCache) { switch ($fileMonitorIdentifier) { case 'TYPO3CR_NodeTypesConfiguration': case 'Flow_ConfigurationFiles': $flushConfigurationCache(); break; case 'Flow_TranslationFiles': $flushConfigurationCache(); $flushXliffServiceCache(); } }); $dispatcher->connect('TYPO3\\Neos\\Domain\\Model\\Site', 'siteChanged', $flushConfigurationCache); $dispatcher->connect('TYPO3\\Neos\\Domain\\Model\\Site', 'siteChanged', 'TYPO3\\Flow\\Mvc\\Routing\\RouterCachingService', 'flushCaches'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeUpdated', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeAdded', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeRemoved', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'beforeNodeMove', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeAdded', NodeUriPathSegmentGenerator::class, '::setUniqueUriPathSegment'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodePropertyChanged', Service\ImageVariantGarbageCollector::class, 'removeUnusedImageVariant'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodePropertyChanged', function (NodeInterface $node, $propertyName) use($bootstrap) { if ($propertyName === 'uriPathSegment') { NodeUriPathSegmentGenerator::setUniqueUriPathSegment($node); $bootstrap->getObjectManager()->get('TYPO3\\Neos\\Routing\\Cache\\RouteCacheFlusher')->registerNodeChange($node); } }); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodePathChanged', function (NodeInterface $node, $oldPath, $newPath, $recursion) { if (!$recursion) { NodeUriPathSegmentGenerator::setUniqueUriPathSegment($node); } }); $dispatcher->connect('TYPO3\\Neos\\Service\\PublishingService', 'nodePublished', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\Neos\\Service\\PublishingService', 'nodeDiscarded', 'TYPO3\\Neos\\TypoScript\\Cache\\ContentCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodePathChanged', 'TYPO3\\Neos\\Routing\\Cache\\RouteCacheFlusher', 'registerNodePathChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeRemoved', 'TYPO3\\Neos\\Routing\\Cache\\RouteCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\Neos\\Service\\PublishingService', 'nodePublished', 'TYPO3\\Neos\\Routing\\Cache\\RouteCacheFlusher', 'registerNodeChange'); $dispatcher->connect('TYPO3\\Neos\\Service\\PublishingService', 'nodePublished', function ($node, $targetWorkspace) use($bootstrap) { $cacheManager = $bootstrap->getObjectManager()->get(CacheManager::class); if ($cacheManager->hasCache('Flow_Persistence_Doctrine')) { $cacheManager->getCache('Flow_Persistence_Doctrine')->flush(); } }); $dispatcher->connect('TYPO3\\Flow\\Persistence\\Doctrine\\PersistenceManager', 'allObjectsPersisted', 'TYPO3\\Neos\\Routing\\Cache\\RouteCacheFlusher', 'commit'); $dispatcher->connect('TYPO3\\Neos\\Domain\\Service\\SiteService', 'sitePruned', 'TYPO3\\TypoScript\\Core\\Cache\\ContentCache', 'flush'); $dispatcher->connect('TYPO3\\Neos\\Domain\\Service\\SiteService', 'sitePruned', 'TYPO3\\Flow\\Mvc\\Routing\\RouterCachingService', 'flushCaches'); $dispatcher->connect('TYPO3\\Neos\\Domain\\Service\\SiteImportService', 'siteImported', 'TYPO3\\TypoScript\\Core\\Cache\\ContentCache', 'flush'); $dispatcher->connect('TYPO3\\Neos\\Domain\\Service\\SiteImportService', 'siteImported', 'TYPO3\\Flow\\Mvc\\Routing\\RouterCachingService', 'flushCaches'); // Eventlog $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'beforeNodeCreate', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeNodeCreate'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'afterNodeCreate', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'afterNodeCreate'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeUpdated', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'nodeUpdated'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodeRemoved', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'nodeRemoved'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'beforeNodePropertyChange', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeNodePropertyChange'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'nodePropertyChanged', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'nodePropertyChanged'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'beforeNodeCopy', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeNodeCopy'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'afterNodeCopy', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'afterNodeCopy'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'beforeNodeMove', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeNodeMove'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Node', 'afterNodeMove', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'afterNodeMove'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Service\\Context', 'beforeAdoptNode', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeAdoptNode'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Service\\Context', 'afterAdoptNode', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'afterAdoptNode'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Workspace', 'beforeNodePublishing', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'beforeNodePublishing'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Model\\Workspace', 'afterNodePublishing', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'afterNodePublishing'); $dispatcher->connect('TYPO3\\Flow\\Persistence\\Doctrine\\PersistenceManager', 'allObjectsPersisted', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'updateEventsAfterPublish'); $dispatcher->connect('TYPO3\\TYPO3CR\\Domain\\Repository\\NodeDataRepository', 'repositoryObjectsPersisted', 'TYPO3\\Neos\\EventLog\\Integrations\\TYPO3CRIntegrationService', 'updateEventsAfterPublish'); }
/** * Initialize the resource management component, setting up stream wrappers, * publishing the public resources of all found packages, ... * * @param Bootstrap $bootstrap * @return void */ public static function initializeResources(Bootstrap $bootstrap) { $packageManager = $bootstrap->getEarlyInstance('TYPO3\\Flow\\Package\\PackageManagerInterface'); $resourceManager = $bootstrap->getObjectManager()->get('TYPO3\\Flow\\Resource\\ResourceManager'); $resourceManager->initialize(); $resourceManager->publishPublicPackageResources($packageManager->getActivePackages()); }
/** * Update Doctrine 2 proxy classes * * This is not simply bound to the finishedCompilationRun signal because it * needs the advised proxy classes to run. When that signal is fired, they * have been written, but not loaded. * * @param Bootstrap $bootstrap * @return void */ protected static function compileDoctrineProxies(Bootstrap $bootstrap) { $cacheManager = $bootstrap->getEarlyInstance(\TYPO3\Flow\Cache\CacheManager::class); $objectConfigurationCache = $cacheManager->getCache('Flow_Object_Configuration'); $coreCache = $cacheManager->getCache('Flow_Core'); $systemLogger = $bootstrap->getEarlyInstance(\TYPO3\Flow\Log\SystemLoggerInterface::class); $configurationManager = $bootstrap->getEarlyInstance(\TYPO3\Flow\Configuration\ConfigurationManager::class); $settings = $configurationManager->getConfiguration(\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'TYPO3.Flow'); if ($objectConfigurationCache->has('doctrineProxyCodeUpToDate') === false && $coreCache->has('doctrineSetupRunning') === false) { $coreCache->set('doctrineSetupRunning', 'White Russian', array(), 60); $systemLogger->log('Compiling Doctrine proxies', LOG_DEBUG); self::executeCommand('typo3.flow:doctrine:compileproxies', $settings); $coreCache->remove('doctrineSetupRunning'); $objectConfigurationCache->set('doctrineProxyCodeUpToDate', true); } }
<?php /* * This file configures dynamic return type support for factory methods in PhpStorm */ namespace PHPSTORM_META; $STATIC_METHOD_TYPES = [\TYPO3\Flow\Object\ObjectManagerInterface::get('') => ['' == '@'], \TYPO3\Flow\Core\Bootstrap::getEarlyInstance('') => ['' == '@']];