/** * Logs exceptional results of the NodeService's getNodeByContextNodePath() method which is called by FrontendNodeRoutePartHandler::matchValue() * * @FLOW3\AfterThrowing("method(TYPO3\TYPO3\Service\NodeService->getNodeByContextNodePath())") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point * @return void */ public function logFailedMatch(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $relativeContextNodePath = $joinPoint->getMethodArgument('relativeContextNodePath'); $exception = $joinPoint->getException(); if ($exception !== NULL) { $this->systemLogger->log(sprintf('%s failed to retrieve a node for path "%s" with message: %s', $joinPoint->getClassName(), $relativeContextNodePath, $exception->getMessage()), LOG_INFO); } }
/** * Before advice for all methods annotated with "@FLOW3\Session(autoStart=true)". * Those methods will trigger a session initialization if a session does not exist * yet. * * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point * @return void * @fixme The pointcut expression below does not consider the options of the session annotation – needs adjustments in the AOP framework * @FLOW3\Before("methodAnnotatedWith(TYPO3\FLOW3\Annotations\Session)") */ public function initializeSession(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { if ($this->session->isStarted() === TRUE) { return; } $objectName = $this->objectManager->getObjectNameByClassName(get_class($joinPoint->getProxy())); $methodName = $joinPoint->getMethodName(); $this->systemLogger->log(sprintf('Session initialization triggered by %s->%s.', $objectName, $methodName), LOG_DEBUG); $this->session->start(); }
/** * Logs calls of renewId() * * @FLOW3\Around("within(TYPO3\FLOW3\Session\SessionInterface) && method(.*->renewId())") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current joinpoint * @return mixed The result of the target method if it has not been intercepted */ public function logRenewId(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $session = $joinPoint->getProxy(); $newId = $joinPoint->getAdviceChain()->proceed($joinPoint); if ($session->isStarted()) { $oldId = $session->getId(); $this->systemLogger->log(sprintf('Changed session id from %s to %s', $oldId, $newId), LOG_DEBUG); } return $newId; }
/** * Checks if the specified method matches against the method name * expression. * * Returns TRUE if method name, visibility and arguments constraints match and the target * method is not final. * * @param string $className Ignored in this pointcut filter * @param string $methodName Name of the method to match against * @param string $methodDeclaringClassName Name of the class the method was originally declared in * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection. * @return boolean TRUE if the class matches, otherwise FALSE * @throws \TYPO3\FLOW3\Aop\Exception */ public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier) { $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName); if ($matchResult === FALSE) { throw new \TYPO3\FLOW3\Aop\Exception('Error in regular expression', 1168876915); } elseif ($matchResult !== 1) { return FALSE; } switch ($this->methodVisibility) { case 'public': if (!($methodDeclaringClassName !== NULL && $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName))) { return FALSE; } break; case 'protected': if (!($methodDeclaringClassName !== NULL && $this->reflectionService->isMethodProtected($methodDeclaringClassName, $methodName))) { return FALSE; } break; } if ($methodDeclaringClassName !== NULL && $this->reflectionService->isMethodFinal($methodDeclaringClassName, $methodName)) { return FALSE; } $methodArguments = $methodDeclaringClassName === NULL ? array() : $this->reflectionService->getMethodParameters($methodDeclaringClassName, $methodName); foreach (array_keys($this->methodArgumentConstraints) as $argumentName) { $objectAccess = explode('.', $argumentName, 2); $argumentName = $objectAccess[0]; if (!array_key_exists($argumentName, $methodArguments)) { $this->systemLogger->log('The argument "' . $argumentName . '" declared in pointcut does not exist in method ' . $methodDeclaringClassName . '->' . $methodName, LOG_NOTICE); return FALSE; } } return TRUE; }
/** * Detects changes of the files and directories to be monitored and emits signals * accordingly. * * @return void * @api */ public function detectChanges() { $changedDirectories = array(); $changedFiles = $this->detectChangedFiles($this->monitoredFiles); foreach ($this->monitoredDirectories as $path) { if (!isset($this->directoriesAndFiles[$path])) { $this->directoriesAndFiles[$path] = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($path); $this->directoriesChanged = TRUE; $changedDirectories[$path] = \TYPO3\FLOW3\Monitor\ChangeDetectionStrategy\ChangeDetectionStrategyInterface::STATUS_CREATED; } } foreach ($this->directoriesAndFiles as $path => $pathAndFilenames) { if (!is_dir($path)) { unset($this->directoriesAndFiles[$path]); $this->directoriesChanged = TRUE; $changedDirectories[$path] = \TYPO3\FLOW3\Monitor\ChangeDetectionStrategy\ChangeDetectionStrategyInterface::STATUS_DELETED; } else { $currentSubDirectoriesAndFiles = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($path); if ($currentSubDirectoriesAndFiles != $pathAndFilenames) { $pathAndFilenames = array_unique(array_merge($currentSubDirectoriesAndFiles, $pathAndFilenames)); } $changedFiles = array_merge($changedFiles, $this->detectChangedFiles($pathAndFilenames)); } } if (count($changedFiles) > 0) { $this->emitFilesHaveChanged($this->identifier, $changedFiles); } if (count($changedDirectories) > 0) { $this->emitDirectoriesHaveChanged($this->identifier, $changedDirectories); } if (count($changedFiles) > 0 || count($changedDirectories) > 0) { $this->systemLogger->log(sprintf('File Monitor "%s" detected %s changed files and %s changed directories.', $this->identifier, count($changedFiles), count($changedDirectories)), LOG_INFO); } }
/** * Unlocks the site if this request has locked it. * * @return void * @api */ public function unlockSite() { if ($this->siteLocked === TRUE) { if (file_exists($this->lockPathAndFilename)) { unlink($this->lockPathAndFilename); } else { $this->systemLogger->log('Site is locked but no lockfile could be found.', LOG_WARNING); } $this->siteLocked = FALSE; $this->systemLogger->log('Unlocked site.', LOG_NOTICE); } }
/** * Builds the corresponding uri (excluding protocol and host) by iterating * through all configured routes and calling their respective resolves() * method. If no matching route is found, an empty string is returned. * Note: calls of this message are cached by RouterCachingAspect * * @param array $routeValues Key/value pairs to be resolved. E.g. array('@package' => 'MyPackage', '@controller' => 'MyController'); * @return string * @throws \TYPO3\FLOW3\Mvc\Exception\NoMatchingRouteException */ public function resolve(array $routeValues) { $this->lastResolvedRoute = NULL; $this->createRoutesFromConfiguration(); foreach ($this->routes as $route) { if ($route->resolves($routeValues)) { $this->lastResolvedRoute = $route; return $route->getMatchingUri(); } } $this->systemLogger->log('Router resolve(): Could not resolve a route for building an URI for the given route values.', LOG_WARNING, $routeValues); throw new \TYPO3\FLOW3\Mvc\Exception\NoMatchingRouteException('Could not resolve a route and its corresponding URI for the given parameters. This may be due to referring to a not existing package / controller / action while building a link or URI. Refer to log and check the backtrace for more details.', 1301610453); }
/** * Called after a functional test in FLOW3, dumps everything in the database. * * @return void */ public function tearDown() { // "driver" is used only for Doctrine, thus we (mis-)use it here // additionally, when no path is set, skip this step, assuming no DB is needed if ($this->settings['backendOptions']['driver'] !== NULL && $this->settings['backendOptions']['path'] !== NULL) { $this->entityManager->clear(); $schemaTool = new \Doctrine\ORM\Tools\SchemaTool($this->entityManager); $schemaTool->dropDatabase(); $this->systemLogger->log('Doctrine 2 schema destroyed.', LOG_NOTICE); } else { $this->systemLogger->log('Doctrine 2 destroy skipped, driver and path backend options not set!', LOG_NOTICE); } }
/** * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods. * * @param array &$objectConfigurations * @return void * @throws \TYPO3\FLOW3\Object\Exception if an injected property is private */ protected function autowireProperties(array &$objectConfigurations) { foreach ($objectConfigurations as $objectConfiguration) { $className = $objectConfiguration->getClassName(); $properties = $objectConfiguration->getProperties(); foreach (get_class_methods($className) as $methodName) { if (substr($methodName, 0, 6) === 'inject') { $propertyName = strtolower(substr($methodName, 6, 1)) . substr($methodName, 7); $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, 'TYPO3\\FLOW3\\Annotations\\Autowiring'); if ($autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE) { continue; } if ($methodName === 'injectSettings') { $packageKey = $objectConfiguration->getPackageKey(); if ($packageKey !== NULL) { $properties[$propertyName] = new ConfigurationProperty($propertyName, $packageKey, ConfigurationProperty::PROPERTY_TYPES_SETTING); } } else { if (array_key_exists($propertyName, $properties)) { continue; } $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName); if (count($methodParameters) !== 1) { $this->systemLogger->log(sprintf('Could not autowire property %s because %s() expects %s instead of exactly 1 parameter.', "{$className}::{$propertyName}", $methodName, count($methodParameters) ?: 'none'), LOG_DEBUG); continue; } $methodParameter = array_pop($methodParameters); if ($methodParameter['class'] === NULL) { $this->systemLogger->log(sprintf('Could not autowire property %s because the method parameter in %s() contained no class type hint.', "{$className}::{$propertyName}", $methodName), LOG_DEBUG); continue; } $properties[$propertyName] = new ConfigurationProperty($propertyName, $methodParameter['class'], ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } } foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, 'TYPO3\\FLOW3\\Annotations\\Inject') as $propertyName) { if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) { $exceptionMessage = 'The property "' . $propertyName . '" in class "' . $className . '" must not be private when annotated for injection.'; throw new \TYPO3\FLOW3\Object\Exception($exceptionMessage, 1328109641); } if (!array_key_exists($propertyName, $properties)) { $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\'); $properties[$propertyName] = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } $objectConfiguration->setProperties($properties); } }
/** * Analyzes the Object Configuration provided by the compiler and builds the necessary PHP code for the proxy classes * to realize dependency injection. * * @return void */ public function build() { $this->objectConfigurations = $this->objectManager->getObjectConfigurations(); foreach ($this->objectConfigurations as $objectName => $objectConfiguration) { $className = $objectConfiguration->getClassName(); if ($this->compiler->hasCacheEntryForClass($className) === TRUE) { continue; } if ($objectName !== $className || $this->reflectionService->isClassAbstract($className) || $this->reflectionService->isClassFinal($className)) { continue; } $proxyClass = $this->compiler->getProxyClass($className); if ($proxyClass === FALSE) { continue; } $this->systemLogger->log('Building DI proxy for "' . $className . '".', LOG_DEBUG); $constructorPreCode = ''; $constructorPostCode = ''; $constructorPreCode .= $this->buildSetInstanceCode($objectConfiguration); $constructorPreCode .= $this->buildConstructorInjectionCode($objectConfiguration); $wakeupMethod = $proxyClass->getMethod('__wakeup'); $wakeupMethod->addPreParentCallCode($this->buildSetInstanceCode($objectConfiguration)); $wakeupMethod->addPreParentCallCode($this->buildSetRelatedEntitiesCode()); $wakeupMethod->addPostParentCallCode($this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\FLOW3\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_RECREATED)); $wakeupMethod->addPostParentCallCode($this->buildLifecycleShutdownCode($objectConfiguration)); $sleepMethod = $proxyClass->getMethod('__sleep'); $sleepMethod->addPostParentCallCode($this->buildSerializeRelatedEntitiesCode($objectConfiguration)); $searchForEntitiesAndStoreIdentifierArrayMethod = $proxyClass->getMethod('searchForEntitiesAndStoreIdentifierArray'); $searchForEntitiesAndStoreIdentifierArrayMethod->setMethodParametersCode('$path, $propertyValue, $originalPropertyName'); $searchForEntitiesAndStoreIdentifierArrayMethod->overrideMethodVisibility('private'); $searchForEntitiesAndStoreIdentifierArrayMethod->addPreParentCallCode($this->buildSearchForEntitiesAndStoreIdentifierArrayCode()); $injectPropertiesCode = $this->buildPropertyInjectionCode($objectConfiguration); if ($injectPropertiesCode !== '') { $proxyClass->getMethod('FLOW3_Proxy_injectProperties')->addPreParentCallCode($injectPropertiesCode); $proxyClass->getMethod('FLOW3_Proxy_injectProperties')->overrideMethodVisibility('private'); $wakeupMethod->addPreParentCallCode("\t\t\$this->FLOW3_Proxy_injectProperties();\n"); $constructorPostCode .= ' if (\'' . $className . '\' === get_class($this)) {' . "\n"; $constructorPostCode .= ' $this->FLOW3_Proxy_injectProperties();' . "\n"; $constructorPostCode .= ' }' . "\n"; } $constructorPostCode .= $this->buildLifecycleInitializationCode($objectConfiguration, \TYPO3\FLOW3\Object\ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED); $constructorPostCode .= $this->buildLifecycleShutdownCode($objectConfiguration); $constructor = $proxyClass->getConstructor(); $constructor->addPreParentCallCode($constructorPreCode); $constructor->addPostParentCallCode($constructorPostCode); } }
/** * Returns translated label ("target" tag in XLIFF) for the id given. * Id is compared with "id" attribute of "trans-unit" tag (see XLIFF * specification for details). * * @param string $transUnitId The "id" attribute of "trans-unit" tag in XLIFF * @param integer $pluralFormIndex Index of plural form to use (starts with 0) * @return mixed Translated label or FALSE on failure */ public function getTargetByTransUnitId($transUnitId, $pluralFormIndex = 0) { if (!isset($this->xmlParsedData['translationUnits'][$transUnitId])) { $this->systemLogger->log('No trans-unit element with the id "' . $transUnitId . '" was found in ' . $this->sourcePath . '. Either this translation has been removed or the id in the code or template referring to the translation is wrong.', LOG_WARNING); return FALSE; } if (!isset($this->xmlParsedData['translationUnits'][$transUnitId][$pluralFormIndex])) { $this->systemLogger->log('The plural form index "' . $pluralFormIndex . '" for the trans-unit element with the id "' . $transUnitId . '" in ' . $this->sourcePath . ' is not available.', LOG_WARNING); return FALSE; } if ($this->xmlParsedData['translationUnits'][$transUnitId][$pluralFormIndex]['target']) { return $this->xmlParsedData['translationUnits'][$transUnitId][$pluralFormIndex]['target']; } elseif ($this->locale->getLanguage() === $this->xmlParsedData['sourceLocale']->getLanguage()) { return $this->xmlParsedData['translationUnits'][$transUnitId][$pluralFormIndex]['source'] ?: FALSE; } else { $this->systemLogger->log('The target translation was empty and the source translation language (' . $this->xmlParsedData['sourceLocale']->getLanguage() . ') does not match the current locale (' . $this->locale->getLanguage() . ') for the trans-unit element with the id "' . $transUnitId . '" in ' . $this->sourcePath, LOG_WARNING); return FALSE; } }
/** * Builds proxy class code which weaves advices into the respective target classes. * * The object configurations provided by the Compiler are searched for possible aspect * annotations. If an aspect class is found, the poincut expressions are parsed and * a new aspect with one or more advisors is added to the aspect registry of the AOP framework. * Finally all advices are woven into their target classes by generating proxy classes. * * In general, the command typo3.flow3:core:compile is responsible for compilation * and calls this method to do so. * * In order to distinguish between an emerged / changed possible target class and * a class which has been matched previously but just didn't have to be proxied, * the latter are kept track of by an "unproxiedClass-*" cache entry. * * @return void */ public function build() { $allAvailableClassNamesByPackage = $this->objectManager->getRegisteredClassNames(); $possibleTargetClassNames = $this->getProxyableClasses($allAvailableClassNamesByPackage); $actualAspectClassNames = $this->reflectionService->getClassNamesByAnnotation('TYPO3\\FLOW3\\Annotations\\Aspect'); sort($possibleTargetClassNames); sort($actualAspectClassNames); $this->aspectContainers = $this->buildAspectContainers($actualAspectClassNames); $rebuildEverything = FALSE; if ($this->objectConfigurationCache->has('allAspectClassesUpToDate') === FALSE) { $rebuildEverything = TRUE; $this->systemLogger->log('Aspects have been modified, therefore rebuilding all target classes.', LOG_INFO); $this->objectConfigurationCache->set('allAspectClassesUpToDate', TRUE); } $possibleTargetClassNameIndex = new ClassNameIndex(); $possibleTargetClassNameIndex->setClassNames($possibleTargetClassNames); $targetClassNameCandidates = new ClassNameIndex(); foreach ($this->aspectContainers as $aspectContainer) { $targetClassNameCandidates->applyUnion($aspectContainer->reduceTargetClassNames($possibleTargetClassNameIndex)); } $targetClassNameCandidates->sort(); foreach ($targetClassNameCandidates->getClassNames() as $targetClassName) { $isUnproxied = $this->objectConfigurationCache->has('unproxiedClass-' . str_replace('\\', '_', $targetClassName)); $hasCacheEntry = $this->compiler->hasCacheEntryForClass($targetClassName) || $isUnproxied; if ($rebuildEverything === TRUE || $hasCacheEntry === FALSE) { $proxyBuildResult = $this->buildProxyClass($targetClassName, $this->aspectContainers); if ($proxyBuildResult !== FALSE) { if ($isUnproxied) { $this->objectConfigurationCache->remove('unproxiedClass-' . str_replace('\\', '_', $targetClassName)); } $this->systemLogger->log(sprintf('Built AOP proxy for class "%s".', $targetClassName), LOG_DEBUG); } else { $this->objectConfigurationCache->set('unproxiedClass-' . str_replace('\\', '_', $targetClassName), TRUE); } } } }
/** * Converts the given string or array to a ResourcePointer object. * * If the input format is an array, this method assumes the resource to be a * fresh file upload and imports the temporary upload file through the * resource manager. * * @param array $source The upload info (expected keys: error, name, tmp_name) * @param string $targetType * @param array $convertedChildProperties * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration * @return \TYPO3\FLOW3\Resource\Resource|TYPO3\FLOW3\Error\Error if the input format is not supported or could not be converted for other reasons */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL) { if (!isset($source['error']) || $source['error'] === \UPLOAD_ERR_NO_FILE) { if (isset($source['submittedFile']) && isset($source['submittedFile']['filename']) && isset($source['submittedFile']['resourcePointer'])) { $resourcePointer = $this->persistenceManager->getObjectByIdentifier($source['submittedFile']['resourcePointer'], 'TYPO3\\FLOW3\\Resource\\ResourcePointer'); if ($resourcePointer) { $resource = new Resource(); $resource->setFilename($source['submittedFile']['filename']); $resource->setResourcePointer($resourcePointer); return $resource; } } return NULL; } if ($source['error'] !== \UPLOAD_ERR_OK) { switch ($source['error']) { case \UPLOAD_ERR_INI_SIZE: case \UPLOAD_ERR_FORM_SIZE: case \UPLOAD_ERR_PARTIAL: return new \TYPO3\FLOW3\Error\Error(\TYPO3\FLOW3\Utility\Files::getUploadErrorMessage($source['error']), 1264440823); default: $this->systemLogger->log(sprintf('A server error occurred while converting an uploaded resource: "%s"', \TYPO3\FLOW3\Utility\Files::getUploadErrorMessage($source['error'])), LOG_ERR); return new \TYPO3\FLOW3\Error\Error('An error occurred while uploading. Please try again or contact the administrator if the problem remains', 1340193849); } } if (isset($this->convertedResources[$source['tmp_name']])) { return $this->convertedResources[$source['tmp_name']]; } $resource = $this->resourceManager->importUploadedResource($source); if ($resource === FALSE) { return new \TYPO3\FLOW3\Error\Error('The resource manager could not create a Resource instance.', 1264517906); } else { $this->convertedResources[$source['tmp_name']] = $resource; return $resource; } }
/** * Flushes entries tagged with class names if their class source files have changed. * Also flushes AOP proxy caches if a policy was modified. * * This method is used as a slot for a signal sent by the system file monitor * defined in the bootstrap scripts. * * Note: Policy configuration handling is implemented here as well as other parts * of FLOW3 (like the security framework) are not fully initialized at the * time needed. * * @param string $fileMonitorIdentifier Identifier of the File Monitor * @param array $changedFiles A list of full paths to changed files * @return void */ public function flushSystemCachesByChangedFiles($fileMonitorIdentifier, array $changedFiles) { $modifiedClassNamesWithUnderscores = array(); $objectClassesCache = $this->getCache('FLOW3_Object_Classes'); $objectConfigurationCache = $this->getCache('FLOW3_Object_Configuration'); switch ($fileMonitorIdentifier) { case 'FLOW3_ClassFiles': $modifiedAspectClassNamesWithUnderscores = array(); foreach ($changedFiles as $pathAndFilename => $status) { $pathAndFilename = str_replace(FLOW3_PATH_PACKAGES, '', $pathAndFilename); $matches = array(); if (preg_match('/[^\\/]+\\/(.+)\\/(Classes|Tests)\\/(.+)\\.php/', $pathAndFilename, $matches) === 1) { $classNameWithUnderscores = str_replace('/', '_', $matches[1] . '_' . ($matches[2] === 'Tests' ? 'Tests_' : '') . $matches[3]); $classNameWithUnderscores = str_replace('.', '_', $classNameWithUnderscores); $modifiedClassNamesWithUnderscores[$classNameWithUnderscores] = TRUE; // If an aspect was modified, the whole code cache needs to be flushed, so keep track of them: if (substr($classNameWithUnderscores, -6, 6) === 'Aspect') { $modifiedAspectClassNamesWithUnderscores[$classNameWithUnderscores] = TRUE; } // As long as no modified aspect was found, we are optimistic that only part of the cache needs to be flushed: if (count($modifiedAspectClassNamesWithUnderscores) === 0) { $objectClassesCache->remove($classNameWithUnderscores); } } } $flushDoctrineProxyCache = FALSE; if (count($modifiedClassNamesWithUnderscores) > 0) { $reflectionStatusCache = $this->getCache('FLOW3_Reflection_Status'); foreach (array_keys($modifiedClassNamesWithUnderscores) as $classNameWithUnderscores) { $reflectionStatusCache->remove($classNameWithUnderscores); if ($flushDoctrineProxyCache === FALSE && preg_match('/_Domain_Model_(.+)/', $classNameWithUnderscores) === 1) { $flushDoctrineProxyCache = TRUE; } } $objectConfigurationCache->remove('allCompiledCodeUpToDate'); } if (count($modifiedAspectClassNamesWithUnderscores) > 0) { $this->systemLogger->log('Aspect classes have been modified, flushing the whole proxy classes cache.', LOG_INFO); $objectClassesCache->flush(); } if ($flushDoctrineProxyCache === TRUE) { $this->systemLogger->log('Domain model changes have been detected, triggering Doctrine 2 proxy rebuilding.', LOG_INFO); $objectConfigurationCache->remove('doctrineProxyCodeUpToDate'); } break; case 'FLOW3_ConfigurationFiles': $policyChangeDetected = FALSE; $routesChangeDetected = FALSE; foreach (array_keys($changedFiles) as $pathAndFilename) { $filename = basename($pathAndFilename); if (!in_array($filename, array('Policy.yaml', 'Routes.yaml'))) { continue; } if ($policyChangeDetected === FALSE && basename($pathAndFilename) === 'Policy.yaml') { $this->systemLogger->log('The security policies have changed, flushing the policy cache.', LOG_INFO); $this->getCache('FLOW3_Security_Policy')->flush(); $policyChangeDetected = TRUE; } elseif ($routesChangeDetected === FALSE && basename($pathAndFilename) === 'Routes.yaml') { $this->systemLogger->log('A Routes.yaml file has been changed, flushing the routing cache.', LOG_INFO); $this->getCache('FLOW3_Mvc_Routing_FindMatchResults')->flush(); $this->getCache('FLOW3_Mvc_Routing_Resolve')->flush(); $routesChangeDetected = TRUE; } } $this->systemLogger->log('The configuration has changed, triggering an AOP proxy class rebuild.', LOG_INFO); $objectConfigurationCache->remove('allAspectClassesUpToDate'); $objectConfigurationCache->remove('allCompiledCodeUpToDate'); $objectClassesCache->flush(); break; case 'FLOW3_TranslationFiles': foreach ($changedFiles as $pathAndFilename => $status) { $matches = array(); if (preg_match('/\\/Translations\\/.+\\.xlf/', $pathAndFilename, $matches) === 1) { $this->systemLogger->log('The localization files have changed, thus flushing the I18n XML model cache.', LOG_INFO); $this->getCache('FLOW3_I18n_XmlModelCache')->flush(); break; } } break; } }
/** * Writes the given message along with the additional information into the log. * * @param string $message The message to log * @param integer $severity An integer value, one of the LOG_* constants * @param mixed $additionalData A variable containing more information about the event to be logged * @return void */ protected function log($message, $severity = LOG_INFO, $additionalData = NULL) { if (is_object($this->systemLogger)) { $this->systemLogger->log($message, $severity, $additionalData); } }