/** * Constructs this cache factory * * @param ApplicationContext $context The current Flow context * @param Environment $environment * @Flow\Autowiring(enabled=false) */ public function __construct(ApplicationContext $context, Environment $environment) { $this->context = $context; $this->environment = $environment; $environmentConfiguration = new EnvironmentConfiguration(FLOW_PATH_ROOT . '~' . (string) $environment->getContext(), $environment->getPathToTemporaryDirectory(), PHP_MAXPATHLEN); parent::__construct($environmentConfiguration); }
public function setUp() { $this->mockDirectory = vfsStream::setup('WritableFileSystemStorageTest'); $this->writableFileSystemStorage = $this->getAccessibleMock(WritableFileSystemStorage::class, null, ['testStorage', ['path' => 'vfs://WritableFileSystemStorageTest/']]); $this->mockEnvironment = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock(); $this->mockEnvironment->expects($this->any())->method('getPathToTemporaryDirectory')->will($this->returnValue('vfs://WritableFileSystemStorageTest/')); $this->inject($this->writableFileSystemStorage, 'environment', $this->mockEnvironment); }
/** * @Flow\Around("method(Neos\Neos\Domain\Repository\DomainRepository->findOneByActiveRequest())") * @param JoinPointInterface $joinPoint The current join point * @return mixed */ public function cacheDomainForActiveRequest(JoinPointInterface $joinPoint) { if ($this->domainForActiveRequest === false || $this->environment->getContext()->isTesting()) { $domain = $joinPoint->getAdviceChain()->proceed($joinPoint); $this->domainForActiveRequest = $domain; } return $this->domainForActiveRequest; }
/** * @test */ public function getMaximumPathLengthReturnsCorrectValue() { $environment = new Environment(new ApplicationContext('Testing')); $expectedValue = PHP_MAXPATHLEN; if ((int) $expectedValue <= 0) { $this->fail('The PHP Constant PHP_MAXPATHLEN is not available on your system! Please file a PHP bug report.'); } $this->assertEquals($expectedValue, $environment->getMaximumPathLength()); }
/** * Creates the mocked filesystem used in the tests */ public function setUp() { vfsStream::setup('Foo'); $this->mockEnvironment = $this->createMock(Utility\Environment::class); $this->mockEnvironment->expects($this->any())->method('getPathToTemporaryDirectory')->will($this->returnValue('vfs://Foo/')); $this->mockEnvironment->expects($this->any())->method('getMaximumPathLength')->will($this->returnValue(1024)); $this->mockEnvironment->expects($this->any())->method('getContext')->will($this->returnValue(new ApplicationContext('Testing'))); $this->mockCacheManager = $this->getMockBuilder(CacheManager::class)->setMethods(['registerCache', 'isCachePersistent'])->disableOriginalConstructor()->getMock(); $this->mockCacheManager->expects($this->any())->method('isCachePersistent')->will($this->returnValue(false)); $this->mockEnvironmentConfiguration = $this->getMockBuilder(EnvironmentConfiguration::class)->setConstructorArgs([__DIR__ . '~Testing', 'vfs://Foo/', 255])->getMock(); }
/** * Handle an exception depending on the context with an HTML message or XML comment * * @param array $typoScriptPath path causing the exception * @param \Exception $exception exception to handle * @param integer $referenceCode * @return string */ protected function handle($typoScriptPath, \Exception $exception, $referenceCode) { $context = $this->environment->getContext(); if ($context->isDevelopment()) { $handler = new HtmlMessageHandler(); } else { $handler = new XmlCommentHandler(); } $handler->setRuntime($this->getRuntime()); return $handler->handleRenderingException($typoScriptPath, $exception); }
public function setUp() { vfsStream::setup('Foo'); $this->cacheManager = new CacheManager(); $this->mockEnvironment = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock(); $this->mockEnvironment->expects($this->any())->method('getPathToTemporaryDirectory')->will($this->returnValue('vfs://Foo/')); $this->cacheManager->injectEnvironment($this->mockEnvironment); $this->mockSystemLogger = $this->createMock(SystemLoggerInterface::class); $this->cacheManager->injectSystemLogger($this->mockSystemLogger); $this->mockConfigurationManager = $this->getMockBuilder(ConfigurationManager::class)->disableOriginalConstructor()->getMock(); $this->cacheManager->injectConfigurationManager($this->mockConfigurationManager); }
/** * Explicitly compile proxy classes * * The compile command triggers the proxy class compilation. * Although a compilation run is triggered automatically by Flow, there might * be cases in a production context where a manual compile run is needed. * * @Flow\Internal * @param boolean $force If set, classes will be compiled even though the cache says that everything is up to date. * @return void */ public function compileCommand($force = false) { /** @var VariableFrontend $objectConfigurationCache */ $objectConfigurationCache = $this->cacheManager->getCache('Flow_Object_Configuration'); if ($force === false) { if ($objectConfigurationCache->has('allCompiledCodeUpToDate')) { return; } } /** @var PhpFrontend $classesCache */ $classesCache = $this->cacheManager->getCache('Flow_Object_Classes'); $this->proxyClassCompiler->injectClassesCache($classesCache); $this->aopProxyClassBuilder->injectObjectConfigurationCache($objectConfigurationCache); $this->aopProxyClassBuilder->build(); $this->dependencyInjectionProxyClassBuilder->build(); $classCount = $this->proxyClassCompiler->compile(); $dataTemporaryPath = $this->environment->getPathToTemporaryDirectory(); Files::createDirectoryRecursively($dataTemporaryPath); file_put_contents($dataTemporaryPath . 'AvailableProxyClasses.php', $this->proxyClassCompiler->getStoredProxyClassMap()); $objectConfigurationCache->set('allCompiledCodeUpToDate', true); $classesCacheBackend = $classesCache->getBackend(); if ($this->bootstrap->getContext()->isProduction() && $classesCacheBackend instanceof FreezableBackendInterface) { /** @var FreezableBackendInterface $backend */ $backend = $classesCache->getBackend(); $backend->freeze(); } $this->emitFinishedCompilationRun($classCount); }
/** * Compiles the Doctrine proxy class code using the Doctrine ProxyFactory. * * @return void */ public function compileProxies() { Files::emptyDirectoryRecursively(Files::concatenatePaths([$this->environment->getPathToTemporaryDirectory(), 'Doctrine/Proxies'])); /** @var \Doctrine\ORM\Proxy\ProxyFactory $proxyFactory */ $proxyFactory = $this->entityManager->getProxyFactory(); $proxyFactory->generateProxyClasses($this->entityManager->getMetadataFactory()->getAllMetadata()); }
/** * renders the exception to nice html content element to display, edit, remove, ... * * @param string $typoScriptPath - path causing the exception * @param \Exception $exception - exception to handle * @param integer $referenceCode - might be unset * @return string */ protected function handle($typoScriptPath, \Exception $exception, $referenceCode) { $handler = new ContextDependentHandler(); $handler->setRuntime($this->runtime); $output = $handler->handleRenderingException($typoScriptPath, $exception); $currentContext = $this->getRuntime()->getCurrentContext(); if (isset($currentContext['node'])) { /** @var NodeInterface $node */ $node = $currentContext['node']; $applicationContext = $this->environment->getContext(); if ($applicationContext->isProduction() && $this->privilegeManager->isPrivilegeTargetGranted('Neos.Neos:Backend.GeneralAccess') && $node->getContext()->getWorkspaceName() !== 'live') { $output = '<div class="neos-rendering-exception"><div class="neos-rendering-exception-title">Failed to render element' . $output . '</div></div>'; } return $this->contentElementWrappingService->wrapContentObject($node, $output, $typoScriptPath); } return $output; }
/** * Flushes all registered caches * * @param boolean $flushPersistentCaches If set to TRUE, even those caches which are flagged as "persistent" will be flushed * @return void * @api */ public function flushCaches($flushPersistentCaches = false) { $this->createAllCaches(); /** @var FrontendInterface $cache */ foreach ($this->caches as $identifier => $cache) { if (!$flushPersistentCaches && $this->isCachePersistent($identifier)) { continue; } $cache->flush(); } $this->configurationManager->flushConfigurationCache(); $dataTemporaryPath = $this->environment->getPathToTemporaryDirectory(); Files::unlink($dataTemporaryPath . 'AvailableProxyClasses.php'); }
/** * Builds the URI * * @param array $arguments optional URI arguments. Will be merged with $this->arguments with precedence to $arguments * @return string The URI * @api */ public function build(array $arguments = []) { $arguments = Arrays::arrayMergeRecursiveOverrule($this->arguments, $arguments); $arguments = $this->mergeArgumentsWithRequestArguments($arguments); $uri = $this->router->resolve($arguments); $this->lastArguments = $arguments; if (!$this->environment->isRewriteEnabled()) { $uri = 'index.php/' . $uri; } $httpRequest = $this->request->getHttpRequest(); if ($this->createAbsoluteUri === true) { $uri = $httpRequest->getBaseUri() . $uri; } elseif (!$this->createRelativePaths) { $uri = $httpRequest->getScriptRequestPath() . $uri; } if ($this->section !== '') { $uri .= '#' . $this->section; } return $uri; }
/** * Prepare an uploaded file to be imported as resource object. Will check the validity of the file, * move it outside of upload folder if open_basedir is enabled and check the filename. * * @param array $uploadInfo * @return array Array of string with the two keys "filepath" (the path to get the filecontent from) and "filename" the filename of the originally uploaded file. * @throws Exception */ protected function prepareUploadedFileForImport(array $uploadInfo) { $openBasedirEnabled = (bool) ini_get('open_basedir'); $temporaryTargetPathAndFilename = $uploadInfo['tmp_name']; $pathInfo = UnicodeFunctions::pathinfo($uploadInfo['name']); if (!is_uploaded_file($temporaryTargetPathAndFilename)) { throw new Exception('The given upload file "' . strip_tags($pathInfo['basename']) . '" was not uploaded through PHP. As it could pose a security risk it cannot be imported.', 1422461503); } if (isset($pathInfo['extension']) && array_key_exists(strtolower($pathInfo['extension']), $this->settings['resource']['uploadExtensionBlacklist']) && $this->settings['resource']['uploadExtensionBlacklist'][strtolower($pathInfo['extension'])] === true) { throw new Exception('The extension of the given upload file "' . strip_tags($pathInfo['basename']) . '" is blacklisted. As it could pose a security risk it cannot be imported.', 1447148472); } if ($openBasedirEnabled === true) { // Move uploaded file to a readable folder before trying to read sha1 value of file $newTemporaryTargetPathAndFilename = $this->environment->getPathToTemporaryDirectory() . 'ResourceUpload.' . uniqid() . '.tmp'; if (move_uploaded_file($temporaryTargetPathAndFilename, $newTemporaryTargetPathAndFilename) === false) { throw new Exception(sprintf('The uploaded file "%s" could not be moved to the temporary location "%s".', $temporaryTargetPathAndFilename, $newTemporaryTargetPathAndFilename), 1375199056); } $temporaryTargetPathAndFilename = $newTemporaryTargetPathAndFilename; } if (!is_file($temporaryTargetPathAndFilename)) { throw new Exception(sprintf('The temporary file "%s" of the file upload does not exist (anymore).', $temporaryTargetPathAndFilename), 1375198998); } return ['filepath' => $temporaryTargetPathAndFilename, 'filename' => $pathInfo['basename']]; }
/** * Injects the Environment object * * @param Environment $environment * @return void */ public function injectEnvironment(Environment $environment) { $this->environment = $environment; $this->environmentConfiguration = $this->createEnvironmentConfiguration($environment->getContext(), $environment->getPathToTemporaryDirectory()); }
/** * Returns the path to a local file representing this resource for use with read-only file operations such as reading or copying. * * Note that you must not store or publish file paths returned from this method as they will change with every request. * * @return string Absolute path and filename pointing to the temporary local copy of this resource * @throws Exception * @api */ public function createTemporaryLocalCopy() { if ($this->temporaryLocalCopyPathAndFilename === null) { $temporaryPathAndFilename = $this->environment->getPathToTemporaryDirectory() . 'ResourceFiles/'; try { Utility\Files::createDirectoryRecursively($temporaryPathAndFilename); } catch (Utility\Exception $e) { throw new ResourceException(sprintf('Could not create the temporary directory %s while trying to create a temporary local copy of resource %s (%s).', $temporaryPathAndFilename, $this->sha1, $this->filename), 1416221864); } $temporaryPathAndFilename .= $this->getCacheEntryIdentifier(); $temporaryPathAndFilename .= '-' . microtime(true); if (function_exists('posix_getpid')) { $temporaryPathAndFilename .= '-' . str_pad(posix_getpid(), 10); } else { $temporaryPathAndFilename .= '-' . (string) getmypid(); } $temporaryPathAndFilename = trim($temporaryPathAndFilename); $temporaryFileHandle = fopen($temporaryPathAndFilename, 'w'); if ($temporaryFileHandle === false) { throw new ResourceException(sprintf('Could not create the temporary file %s while trying to create a temporary local copy of resource %s (%s).', $temporaryPathAndFilename, $this->sha1, $this->filename), 1416221864); } $resourceStream = $this->getStream(); if ($resourceStream === false) { throw new ResourceException(sprintf('Could not open stream for resource %s ("%s") from collection "%s" while trying to create a temporary local copy.', $this->sha1, $this->filename, $this->collectionName), 1416221863); } stream_copy_to_stream($resourceStream, $temporaryFileHandle); fclose($resourceStream); fclose($temporaryFileHandle); $this->temporaryLocalCopyPathAndFilename = $temporaryPathAndFilename; } return $this->temporaryLocalCopyPathAndFilename; }
/** * @return boolean */ protected function hasFrozenCacheInProduction() { return $this->environment->getContext()->isProduction() && $this->reflectionDataRuntimeCache->getBackend()->isFrozen(); }
/** * @param PersistentResource $originalResource * @param array $adjustments * @return array resource, width, height as keys * @throws ImageFileException * @throws InvalidConfigurationException * @throws Exception */ public function processImage(PersistentResource $originalResource, array $adjustments) { $additionalOptions = array(); $adjustmentsApplied = false; // TODO: Special handling for SVG should be refactored at a later point. if ($originalResource->getMediaType() === 'image/svg+xml') { $originalResourceStream = $originalResource->getStream(); $resource = $this->resourceManager->importResource($originalResourceStream, $originalResource->getCollectionName()); fclose($originalResourceStream); $resource->setFilename($originalResource->getFilename()); return ['width' => null, 'height' => null, 'resource' => $resource]; } $resourceUri = $originalResource->createTemporaryLocalCopy(); $resultingFileExtension = $originalResource->getFileExtension(); $transformedImageTemporaryPathAndFilename = $this->environment->getPathToTemporaryDirectory() . uniqid('ProcessedImage-') . '.' . $resultingFileExtension; if (!file_exists($resourceUri)) { throw new ImageFileException(sprintf('An error occurred while transforming an image: the resource data of the original image does not exist (%s, %s).', $originalResource->getSha1(), $resourceUri), 1374848224); } $imagineImage = $this->imagineService->open($resourceUri); $convertCMYKToRGB = $this->getOptionsMergedWithDefaults()['convertCMYKToRGB']; if ($convertCMYKToRGB && $imagineImage->palette() instanceof CMYK) { $imagineImage->usePalette(new RGB()); } if ($this->imagineService instanceof Imagine && $originalResource->getFileExtension() === 'gif' && $this->isAnimatedGif(file_get_contents($resourceUri)) === true) { $imagineImage->layers()->coalesce(); $layers = $imagineImage->layers(); $newLayers = array(); foreach ($layers as $index => $imagineFrame) { $imagineFrame = $this->applyAdjustments($imagineFrame, $adjustments, $adjustmentsApplied); $newLayers[] = $imagineFrame; } $imagineImage = array_shift($newLayers); $layers = $imagineImage->layers(); foreach ($newLayers as $imagineFrame) { $layers->add($imagineFrame); } $additionalOptions['animated'] = true; } else { $imagineImage = $this->applyAdjustments($imagineImage, $adjustments, $adjustmentsApplied); } if ($adjustmentsApplied === true) { $imagineImage->save($transformedImageTemporaryPathAndFilename, $this->getOptionsMergedWithDefaults($additionalOptions)); $imageSize = $imagineImage->getSize(); // TODO: In the future the collectionName of the new resource should be configurable. $resource = $this->resourceManager->importResource($transformedImageTemporaryPathAndFilename, $originalResource->getCollectionName()); if ($resource === false) { throw new ImageFileException('An error occurred while importing a generated image file as a resource.', 1413562208); } unlink($transformedImageTemporaryPathAndFilename); $pathInfo = UnicodeFunctions::pathinfo($originalResource->getFilename()); $resource->setFilename(sprintf('%s-%ux%u.%s', $pathInfo['filename'], $imageSize->getWidth(), $imageSize->getHeight(), $pathInfo['extension'])); } else { $originalResourceStream = $originalResource->getStream(); $resource = $this->resourceManager->importResource($originalResourceStream, $originalResource->getCollectionName()); fclose($originalResourceStream); $resource->setFilename($originalResource->getFilename()); $imageSize = $this->getImageSize($originalResource); $imageSize = new Box($imageSize['width'], $imageSize['height']); } $this->imageSizeCache->set($resource->getCacheEntryIdentifier(), array('width' => $imageSize->getWidth(), 'height' => $imageSize->getHeight())); $result = array('width' => $imageSize->getWidth(), 'height' => $imageSize->getHeight(), 'resource' => $resource); return $result; }
/** * Initializes the Configuration Manager, the Flow settings and the Environment service * * @param Bootstrap $bootstrap * @return void * @throws FlowException */ public static function initializeConfiguration(Bootstrap $bootstrap) { $context = $bootstrap->getContext(); $environment = new Environment($context); $environment->setTemporaryDirectoryBase(FLOW_PATH_TEMPORARY_BASE); $bootstrap->setEarlyInstance(Environment::class, $environment); $packageManager = $bootstrap->getEarlyInstance(PackageManagerInterface::class); $configurationManager = new ConfigurationManager($context); $configurationManager->setTemporaryDirectoryPath($environment->getPathToTemporaryDirectory()); $configurationManager->injectConfigurationSource(new YamlSource()); $configurationManager->setPackages($packageManager->getActivePackages()); $configurationManager->loadConfigurationCache(); $settings = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow'); $lockManager = new LockManager($settings['utility']['lockStrategyClassName'], ['lockDirectory' => Files::concatenatePaths([$environment->getPathToTemporaryDirectory(), 'Lock'])]); Lock::setLockManager($lockManager); $packageManager->injectSettings($settings); $bootstrap->getSignalSlotDispatcher()->dispatch(ConfigurationManager::class, 'configurationManagerReady', [$configurationManager]); $bootstrap->setEarlyInstance(ConfigurationManager::class, $configurationManager); }
/** * Factory method which creates an EntityManager. * * @return EntityManager * @throws InvalidConfigurationException */ public function create() { $config = new Configuration(); $config->setClassMetadataFactoryName(Mapping\ClassMetadataFactory::class); $this->applySecondLevelCacheSettingsToConfiguration($this->settings['doctrine']['secondLevelCache'], $config); $cache = new CacheAdapter(); // must use ObjectManager in compile phase... $cache->setCache($this->objectManager->get(CacheManager::class)->getCache('Flow_Persistence_Doctrine')); $config->setMetadataCacheImpl($cache); $config->setQueryCacheImpl($cache); $resultCache = new CacheAdapter(); // must use ObjectManager in compile phase... $resultCache->setCache($this->objectManager->get(CacheManager::class)->getCache('Flow_Persistence_Doctrine_Results')); $config->setResultCacheImpl($resultCache); if (is_string($this->settings['doctrine']['sqlLogger']) && class_exists($this->settings['doctrine']['sqlLogger'])) { $configuredSqlLogger = $this->settings['doctrine']['sqlLogger']; $sqlLoggerInstance = new $configuredSqlLogger(); if ($sqlLoggerInstance instanceof SQLLogger) { $config->setSQLLogger($sqlLoggerInstance); } else { throw new InvalidConfigurationException(sprintf('Neos.Flow.persistence.doctrine.sqlLogger must point to a \\Doctrine\\DBAL\\Logging\\SQLLogger implementation, %s given.', get_class($sqlLoggerInstance)), 1426150388); } } $eventManager = $this->buildEventManager(); $flowAnnotationDriver = $this->objectManager->get(FlowAnnotationDriver::class); $config->setMetadataDriverImpl($flowAnnotationDriver); $proxyDirectory = Files::concatenatePaths([$this->environment->getPathToTemporaryDirectory(), 'Doctrine/Proxies']); Files::createDirectoryRecursively($proxyDirectory); $config->setProxyDir($proxyDirectory); $config->setProxyNamespace('Neos\\Flow\\Persistence\\Doctrine\\Proxies'); $config->setAutoGenerateProxyClasses(false); // Set default host to 127.0.0.1 if there is no host configured but a dbname if (empty($this->settings['backendOptions']['host']) && !empty($this->settings['backendOptions']['dbname'])) { $this->settings['backendOptions']['host'] = '127.0.0.1'; } // The following code tries to connect first, if that succeeds, all is well. If not, the platform is fetched directly from the // driver - without version checks to the database server (to which no connection can be made) - and is added to the config // which is then used to create a new connection. This connection will then return the platform directly, without trying to // detect the version it runs on, which fails if no connection can be made. But the platform is used even if no connection can // be made, which was no problem with Doctrine DBAL 2.3. And then came version-aware drivers and platforms... $connection = DriverManager::getConnection($this->settings['backendOptions'], $config, $eventManager); try { $connection->connect(); } catch (ConnectionException $exception) { $settings = $this->settings['backendOptions']; $settings['platform'] = $connection->getDriver()->getDatabasePlatform(); $connection = DriverManager::getConnection($settings, $config, $eventManager); } $entityManager = EntityManager::create($connection, $config, $eventManager); $flowAnnotationDriver->setEntityManager($entityManager); if (isset($this->settings['doctrine']['dbal']['mappingTypes']) && is_array($this->settings['doctrine']['dbal']['mappingTypes'])) { foreach ($this->settings['doctrine']['dbal']['mappingTypes'] as $typeName => $typeConfiguration) { Type::addType($typeName, $typeConfiguration['className']); $entityManager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping($typeConfiguration['dbType'], $typeName); } } if (isset($this->settings['doctrine']['filters']) && is_array($this->settings['doctrine']['filters'])) { foreach ($this->settings['doctrine']['filters'] as $filterName => $filterClass) { $config->addFilter($filterName, $filterClass); $entityManager->getFilters()->enable($filterName); } } if (isset($this->settings['doctrine']['dql']) && is_array($this->settings['doctrine']['dql'])) { $this->applyDqlSettingsToConfiguration($this->settings['doctrine']['dql'], $config); } return $entityManager; }
/** * Initializes the Configuration Manager, the Flow settings and the Environment service * * @param Bootstrap $bootstrap * @return void * @throws FlowException */ public static function initializeConfiguration(Bootstrap $bootstrap) { $context = $bootstrap->getContext(); $packageManager = $bootstrap->getEarlyInstance(PackageManagerInterface::class); $configurationManager = new ConfigurationManager($context); $configurationManager->injectConfigurationSource(new YamlSource()); $configurationManager->loadConfigurationCache(); $configurationManager->setPackages($packageManager->getActivePackages()); $settings = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow'); $environment = new Environment($context); if (isset($settings['utility']['environment']['temporaryDirectoryBase'])) { $defaultTemporaryDirectoryBase = FLOW_PATH_DATA . '/Temporary'; if (FLOW_PATH_TEMPORARY_BASE !== $defaultTemporaryDirectoryBase) { throw new FlowException(sprintf('It seems like the PHP default temporary base path has been changed from "%s" to "%s" via the FLOW_PATH_TEMPORARY_BASE environment variable. If that variable is present, the Neos.Flow.utility.environment.temporaryDirectoryBase setting must not be specified!', $defaultTemporaryDirectoryBase, FLOW_PATH_TEMPORARY_BASE), 1447707261); } $environment->setTemporaryDirectoryBase($settings['utility']['environment']['temporaryDirectoryBase']); } else { $environment->setTemporaryDirectoryBase(FLOW_PATH_TEMPORARY_BASE); } $configurationManager->setTemporaryDirectoryPath($environment->getPathToTemporaryDirectory()); $lockManager = new LockManager($settings['utility']['lockStrategyClassName'], ['lockDirectory' => Files::concatenatePaths([$environment->getPathToTemporaryDirectory(), 'Lock'])]); Lock::setLockManager($lockManager); $packageManager->injectSettings($settings); $bootstrap->getSignalSlotDispatcher()->dispatch(ConfigurationManager::class, 'configurationManagerReady', [$configurationManager]); $bootstrap->setEarlyInstance(ConfigurationManager::class, $configurationManager); $bootstrap->setEarlyInstance(Environment::class, $environment); }