/**
  * Checks the cache for the route path given in the Request and returns the result
  *
  * @param Request $httpRequest
  * @return array|boolean the cached route values or FALSE if no cache entry was found
  */
 public function getCachedMatchResults(Request $httpRequest)
 {
     $cachedResult = $this->routeCache->get($this->buildRouteCacheIdentifier($httpRequest));
     if ($cachedResult !== false) {
         $this->systemLogger->log(sprintf('Router route(): A cached Route with the cache identifier "%s" matched the path "%s".', $this->buildRouteCacheIdentifier($httpRequest), $httpRequest->getRelativePath()), LOG_DEBUG);
     }
     return $cachedResult;
 }
 /**
  * Before advice for all methods annotated with "@Flow\Session(autoStart=true)".
  * Those methods will trigger a session initialization if a session does not exist
  * yet.
  *
  * @param 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
  * @Flow\Before("methodAnnotatedWith(Neos\Flow\Annotations\Session)")
  */
 public function initializeSession(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();
 }
 /**
  * @param array $redirects
  * @return void
  * @throws Exception
  */
 public function emitRedirectCreated(array $redirects)
 {
     foreach ($redirects as $redirect) {
         if (!$redirect instanceof RedirectInterface) {
             throw new Exception('Redirect should implement RedirectInterface', 1460139669);
         }
         $this->_redirectService->emitRedirectCreated($redirect);
         $this->_logger->log(sprintf('Redirect from %s %s -> %s (%d) added', $redirect->getHost(), $redirect->getSourceUriPath(), $redirect->getTargetUriPath(), $redirect->getStatusCode()), LOG_DEBUG);
     }
 }
 /**
  * Iterates over all existing sessions and removes their data if the inactivity
  * timeout was reached.
  *
  * @return integer The number of outdated entries removed
  * @api
  */
 public function collectGarbage()
 {
     if ($this->inactivityTimeout === 0) {
         return 0;
     }
     if ($this->metaDataCache->has('_garbage-collection-running')) {
         return false;
     }
     $sessionRemovalCount = 0;
     $this->metaDataCache->set('_garbage-collection-running', true, [], 120);
     foreach ($this->metaDataCache->getIterator() as $sessionIdentifier => $sessionInfo) {
         if ($sessionIdentifier === '_garbage-collection-running') {
             continue;
         }
         $lastActivitySecondsAgo = $this->now - $sessionInfo['lastActivityTimestamp'];
         if ($lastActivitySecondsAgo > $this->inactivityTimeout) {
             if ($sessionInfo['storageIdentifier'] === null) {
                 $this->systemLogger->log('SESSION INFO INVALID: ' . $sessionIdentifier, LOG_WARNING, $sessionInfo);
             } else {
                 $this->storageCache->flushByTag($sessionInfo['storageIdentifier']);
                 $sessionRemovalCount++;
             }
             $this->metaDataCache->remove($sessionIdentifier);
         }
         if ($sessionRemovalCount >= $this->garbageCollectionMaximumPerRun) {
             break;
         }
     }
     $this->metaDataCache->remove('_garbage-collection-running');
     return $sessionRemovalCount;
 }
 /**
  * Detects changes of the files and directories to be monitored and emits signals
  * accordingly.
  *
  * @return void
  * @api
  */
 public function detectChanges()
 {
     if ($this->changedFiles === null || $this->changedPaths === null) {
         $this->loadDetectedDirectoriesAndFiles();
         $changesDetected = false;
         $this->changedPaths = $this->changedFiles = [];
         $this->changedFiles = $this->detectChangedFiles($this->monitoredFiles);
         foreach ($this->monitoredDirectories as $path => $filenamePattern) {
             $changesDetected = $this->detectChangesOnPath($path, $filenamePattern) ? true : $changesDetected;
         }
         if ($changesDetected) {
             $this->saveDetectedDirectoriesAndFiles();
         }
         $this->directoriesAndFiles = null;
     }
     $changedFileCount = count($this->changedFiles);
     $changedPathCount = count($this->changedPaths);
     if ($changedFileCount > 0) {
         $this->emitFilesHaveChanged($this->identifier, $this->changedFiles);
     }
     if ($changedPathCount > 0) {
         $this->emitDirectoriesHaveChanged($this->identifier, $this->changedPaths);
     }
     if ($changedFileCount > 0 || $changedPathCount) {
         $this->systemLogger->log(sprintf('File Monitor "%s" detected %s changed files and %s changed directories.', $this->identifier, $changedFileCount, $changedPathCount), LOG_INFO);
     }
 }
 /**
  * Log a deprecation message once
  *
  * @return void
  */
 protected function logDeprecation()
 {
     if (!static::$loggedDeprecation) {
         static::$loggedDeprecation = true;
         $this->logger->log('Neos.Media is configured to simulate the deprecated Neos 1.2 behaviour. Please check the setting "Neos.Media.behaviourFlag".', LOG_DEBUG);
     }
 }
 /**
  * Checks if the specified method matches with the method annotation filter pattern
  *
  * @param string $className Name of the class to check against - not used here
  * @param string $methodName Name of the method
  * @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 - not used here
  * @return boolean TRUE if the class matches, otherwise FALSE
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     if ($methodDeclaringClassName === null || !method_exists($methodDeclaringClassName, $methodName)) {
         return false;
     }
     $designatedAnnotations = $this->reflectionService->getMethodAnnotations($methodDeclaringClassName, $methodName, $this->annotation);
     if ($designatedAnnotations !== [] || $this->annotationValueConstraints === []) {
         $matches = $designatedAnnotations !== [];
     } else {
         // It makes no sense to check property values for an annotation that is used multiple times, we shortcut and check the value against the first annotation found.
         $firstFoundAnnotation = $designatedAnnotations;
         $annotationProperties = $this->reflectionService->getClassPropertyNames($this->annotation);
         foreach ($this->annotationValueConstraints as $propertyName => $expectedValue) {
             if (!array_key_exists($propertyName, $annotationProperties)) {
                 $this->systemLogger->log('The property "' . $propertyName . '" declared in pointcut does not exist in annotation ' . $this->annotation, LOG_NOTICE);
                 return false;
             }
             if ($firstFoundAnnotation->{$propertyName} === $expectedValue) {
                 $matches = true;
             } else {
                 return false;
             }
         }
     }
     return $matches;
 }
 /**
  * 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 Exception
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName);
     if ($matchResult === false) {
         throw new 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 ? [] : $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;
 }
 /**
  * Filters the classnames available for object management by filter expressions that either include or exclude classes.
  *
  * @param array $classNames All classnames per package
  * @param array $filterConfiguration The filter configuration to apply
  * @param string $includeOrExclude if this is an "include" or "exclude" filter
  * @return array the remaining class
  * @throws InvalidConfigurationTypeException
  */
 protected function applyClassFilterConfiguration($classNames, $filterConfiguration, $includeOrExclude = 'include')
 {
     if (!in_array($includeOrExclude, ['include', 'exclude'])) {
         throw new \InvalidArgumentException('The argument $includeOrExclude must be one of "include" or "exclude", the given value was not allowed.', 1423726253);
     }
     foreach ($filterConfiguration as $packageKey => $filterExpressions) {
         if (!array_key_exists($packageKey, $classNames)) {
             $this->systemLogger->log('The package "' . $packageKey . '" specified in the setting "Neos.Flow.object.' . $includeOrExclude . 'Classes" was either excluded or is not loaded.', LOG_DEBUG);
             continue;
         }
         if (!is_array($filterExpressions)) {
             throw new InvalidConfigurationTypeException('The value given for setting "Neos.Flow.object.' . $includeOrExclude . 'Classes.\'' . $packageKey . '\'" is  invalid. It should be an array of expressions. Check the syntax in the YAML file.', 1422357272);
         }
         $classesForPackageUnderInspection = $classNames[$packageKey];
         $classNames[$packageKey] = [];
         foreach ($filterExpressions as $filterExpression) {
             $classesForPackageUnderInspection = array_filter($classesForPackageUnderInspection, function ($className) use($filterExpression, $includeOrExclude) {
                 $match = preg_match('/' . $filterExpression . '/', $className);
                 return $includeOrExclude === 'include' ? $match === 1 : $match !== 1;
             });
             if ($includeOrExclude === 'include') {
                 $classNames[$packageKey] = array_merge($classNames[$packageKey], $classesForPackageUnderInspection);
                 $classesForPackageUnderInspection = $classNames[$packageKey];
             } else {
                 $classNames[$packageKey] = $classesForPackageUnderInspection;
             }
         }
         if ($classNames[$packageKey] === []) {
             unset($classNames[$packageKey]);
         }
     }
     return $classNames;
 }
 /**
  * @param array $nodes
  */
 public function assignNodes(array $nodes)
 {
     $data = array();
     foreach ($nodes as $node) {
         if ($node->getPath() !== '/') {
             $q = new FlowQuery(array($node));
             $closestDocumentNode = $q->closest('[instanceof Neos.Neos:Document]')->get(0);
             if ($closestDocumentNode !== null) {
                 $data[] = array('nodeContextPath' => $node->getContextPath(), 'documentNodeContextPath' => $closestDocumentNode->getContextPath());
             } else {
                 $this->systemLogger->log('You have a node that is no longer connected to a parent. Path: ' . $node->getPath() . ' (Identifier: ' . $node->getIdentifier() . ')');
             }
         }
     }
     $this->assign('value', array('data' => $data, 'success' => true));
 }
 /**
  * Matches a \Neos\Flow\Mvc\RequestInterface against the configured CSRF pattern rules and
  * searches for invalid csrf tokens. If this returns TRUE, the request is invalid!
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws AuthenticationRequiredException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest || $request->getHttpRequest()->isMethodSafe()) {
         $this->systemLogger->log('CSRF: No token required, safe request', LOG_DEBUG);
         return false;
     }
     if ($this->authenticationManager->isAuthenticated() === false) {
         $this->systemLogger->log('CSRF: No token required, not authenticated', LOG_DEBUG);
         return false;
     }
     if ($this->securityContext->areAuthorizationChecksDisabled() === true) {
         $this->systemLogger->log('CSRF: No token required, authorization checks are disabled', LOG_DEBUG);
         return false;
     }
     $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName());
     $actionMethodName = $request->getControllerActionName() . 'Action';
     if (!$this->hasPolicyEntryForMethod($controllerClassName, $actionMethodName)) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is not restricted by a policy.', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     if ($this->reflectionService->isMethodTaggedWith($controllerClassName, $actionMethodName, 'skipcsrfprotection')) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is tagged with a "skipcsrfprotection" annotation', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     $httpRequest = $request->getHttpRequest();
     if ($httpRequest->hasHeader('X-Flow-Csrftoken')) {
         $csrfToken = $httpRequest->getHeader('X-Flow-Csrftoken');
     } else {
         $internalArguments = $request->getMainRequest()->getInternalArguments();
         $csrfToken = isset($internalArguments['__csrfToken']) ? $internalArguments['__csrfToken'] : null;
     }
     if (empty($csrfToken)) {
         $this->systemLogger->log(sprintf('CSRF: token was empty but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     if (!$this->securityContext->hasCsrfProtectionTokens()) {
         throw new AuthenticationRequiredException(sprintf('CSRF: No CSRF tokens in security context, possible session timeout. A valid token is required for %s::%s()', $controllerClassName, $actionMethodName), 1317309673);
     }
     if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === false) {
         $this->systemLogger->log(sprintf('CSRF: token was invalid but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     $this->systemLogger->log(sprintf('CSRF: Successfully verified token for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
     return false;
 }
Esempio n. 12
0
 /**
  * Flushes I18n caches if translation files have changed
  *
  * @param array $changedFiles A list of full paths to changed files
  * @return void
  * @see flushSystemCachesByChangedFiles()
  */
 protected function flushTranslationCachesByChangedFiles(array $changedFiles)
 {
     foreach ($changedFiles as $pathAndFilename => $status) {
         if (preg_match('/\\/Translations\\/.+\\.xlf/', $pathAndFilename) === 1) {
             $this->systemLogger->log('The localization files have changed, thus flushing the I18n XML model cache.', LOG_INFO);
             $this->getCache('Flow_I18n_XmlModelCache')->flush();
             break;
         }
     }
 }
 /**
  * Flush caches according to the previously registered node changes.
  *
  * @return void
  */
 public function shutdownObject()
 {
     if ($this->tagsToFlush !== array()) {
         foreach ($this->tagsToFlush as $tag => $logMessage) {
             $affectedEntries = $this->contentCache->flushByTag($tag);
             if ($affectedEntries > 0) {
                 $this->systemLogger->log(sprintf('Content cache: Removed %s entries %s', $affectedEntries, $logMessage), LOG_DEBUG);
             }
         }
     }
 }
Esempio n. 14
0
 /**
  * Refreshes this asset after the Resource or any other parameters affecting thumbnails have been modified
  *
  * @return void
  */
 public function refresh()
 {
     $assetClassType = str_replace('Neos\\Media\\Domain\\Model\\', '', get_class($this));
     $this->systemLogger->log(sprintf('%s: refresh() called, clearing all thumbnails. Filename: %s. PersistentResource SHA1: %s', $assetClassType, $this->getResource()->getFilename(), $this->getResource()->getSha1()), LOG_DEBUG);
     // whitelist objects so they can be deleted (even during safe requests)
     $this->persistenceManager->whitelistObject($this);
     foreach ($this->thumbnails as $thumbnail) {
         $this->persistenceManager->whitelistObject($thumbnail);
     }
     $this->thumbnails->clear();
 }
 /**
  * Logs calls of collectGarbage()
  *
  * @Flow\AfterReturning("within(Neos\Flow\Session\SessionInterface) && method(.*->collectGarbage())")
  * @param JoinPointInterface $joinPoint The current joinpoint
  * @return void
  */
 public function logCollectGarbage(JoinPointInterface $joinPoint)
 {
     $sessionRemovalCount = $joinPoint->getResult();
     if ($sessionRemovalCount > 0) {
         $this->systemLogger->log(sprintf('%s: Triggered garbage collection and removed %s expired sessions.', $this->getClassName($joinPoint), $sessionRemovalCount), LOG_INFO);
     } elseif ($sessionRemovalCount === 0) {
         $this->systemLogger->log(sprintf('%s: Triggered garbage collection but no sessions needed to be removed.', $this->getClassName($joinPoint)), LOG_INFO);
     } elseif ($sessionRemovalCount === false) {
         $this->systemLogger->log(sprintf('%s: Ommitting garbage collection because another process is already running. Consider lowering the GC propability if these messages appear a lot.', $this->getClassName($joinPoint)), LOG_WARNING);
     }
 }
 /**
  * @param callable $callback a callback function to process every notification
  * @return void
  * @api
  */
 public function flush(callable $callback = null)
 {
     foreach ($this->messages as $message) {
         /** @var Message $message */
         $this->messages->detach($message);
         $this->systemLogger->log('ResourcePublishingMessage: ' . $message->getMessage(), $message->getSeverity());
         if ($callback !== null) {
             $callback($message);
         }
     }
 }
 /**
  * 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 ($className === '' || $this->compiler->hasCacheEntryForClass($className) === true) {
             continue;
         }
         if ($objectName !== $className || $this->reflectionService->isClassAbstract($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);
         $setRelatedEntitiesCode = '';
         if (!$this->reflectionService->hasMethod($className, '__sleep')) {
             $proxyClass->addTraits(['\\' . ObjectSerializationTrait::class]);
             $sleepMethod = $proxyClass->getMethod('__sleep');
             $sleepMethod->addPostParentCallCode($this->buildSerializeRelatedEntitiesCode($objectConfiguration));
             $setRelatedEntitiesCode = "\n        " . '$this->Flow_setRelatedEntities();' . "\n";
         }
         $wakeupMethod = $proxyClass->getMethod('__wakeup');
         $wakeupMethod->addPreParentCallCode($this->buildSetInstanceCode($objectConfiguration));
         $wakeupMethod->addPreParentCallCode($setRelatedEntitiesCode);
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleInitializationCode($objectConfiguration, ObjectManagerInterface::INITIALIZATIONCAUSE_RECREATED));
         $wakeupMethod->addPostParentCallCode($this->buildLifecycleShutdownCode($objectConfiguration));
         $injectPropertiesCode = $this->buildPropertyInjectionCode($objectConfiguration);
         if ($injectPropertiesCode !== '') {
             $proxyClass->addTraits(['\\' . PropertyInjectionTrait::class]);
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->addPreParentCallCode($injectPropertiesCode);
             $proxyClass->getMethod('Flow_Proxy_injectProperties')->overrideMethodVisibility('private');
             $wakeupMethod->addPreParentCallCode("        \$this->Flow_Proxy_injectProperties();\n");
             $constructorPostCode .= '        if (\'' . $className . '\' === get_class($this)) {' . "\n";
             $constructorPostCode .= '            $this->Flow_Proxy_injectProperties();' . "\n";
             $constructorPostCode .= '        }' . "\n";
         }
         $constructorPostCode .= $this->buildLifecycleInitializationCode($objectConfiguration, ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED);
         $constructorPostCode .= $this->buildLifecycleShutdownCode($objectConfiguration);
         $constructor = $proxyClass->getConstructor();
         $constructor->addPreParentCallCode($constructorPreCode);
         $constructor->addPostParentCallCode($constructorPostCode);
         if ($this->objectManager->getContext()->isProduction()) {
             $this->compileStaticMethods($className, $proxyClass);
         }
     }
 }
 /**
  * Called after a functional test in Flow, 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 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);
     }
 }
Esempio n. 19
0
 /**
  * Returns the current workspace.
  *
  * @param boolean $createWorkspaceIfNecessary DEPRECATED: If enabled, creates a workspace with the configured name if it doesn't exist already. This option is DEPRECATED, create workspace explicitly instead.
  * @return Workspace The workspace or NULL
  * @api
  */
 public function getWorkspace($createWorkspaceIfNecessary = true)
 {
     if ($this->workspace !== null) {
         return $this->workspace;
     }
     $this->workspace = $this->workspaceRepository->findByIdentifier($this->workspaceName);
     if ($this->workspace === null && $createWorkspaceIfNecessary) {
         $liveWorkspace = $this->workspaceRepository->findByIdentifier('live');
         $this->workspace = new Workspace($this->workspaceName, $liveWorkspace);
         $this->workspaceRepository->add($this->workspace);
         $this->systemLogger->log(sprintf('Notice: %s::getWorkspace() implicitly created the new workspace "%s". This behaviour is discouraged and will be removed in future versions. Make sure to create workspaces explicitly by adding a new workspace to the Workspace Repository.', __CLASS__, $this->workspaceName), LOG_NOTICE);
     }
     if ($this->workspace !== null) {
         $this->validateWorkspace($this->workspace);
     }
     return $this->workspace;
 }
 /**
  * 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 pointcut 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 neos.flow: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(Flow\Aspect::class);
     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();
     $treatedSubClasses = new ClassNameIndex();
     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) {
                 // In case the proxy was not build because there was nothing adviced,
                 // it might be an advice in the parent and so we need to try to treat this class.
                 $treatedSubClasses = $this->addBuildMethodsAndAdvicesCodeToClass($targetClassName, $treatedSubClasses);
             }
             $treatedSubClasses = $this->proxySubClassesOfClassToEnsureAdvices($targetClassName, $targetClassNameCandidates, $treatedSubClasses);
             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);
             }
         }
     }
 }
 /**
  * Call the render() method and handle errors.
  *
  * @return string the rendered ViewHelper
  * @throws Exception
  */
 protected function callRenderMethod()
 {
     $renderMethodParameters = [];
     foreach ($this->argumentDefinitions as $argumentName => $argumentDefinition) {
         if ($argumentDefinition instanceof ArgumentDefinition && $argumentDefinition->isMethodParameter()) {
             $renderMethodParameters[$argumentName] = $this->arguments[$argumentName];
         }
     }
     try {
         return call_user_func_array([$this, 'render'], $renderMethodParameters);
     } catch (Exception $exception) {
         if ($this->objectManager->getContext()->isProduction()) {
             $this->systemLogger->log('A Fluid ViewHelper Exception was captured: ' . $exception->getMessage() . ' (' . $exception->getCode() . ')', LOG_ERR, ['exception' => $exception]);
             return '';
         } else {
             throw $exception;
         }
     }
 }
Esempio n. 22
0
 /**
  * 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 NoMatchingRouteException
  */
 public function resolve(array $routeValues)
 {
     $cachedResolvedUriPath = $this->routerCachingService->getCachedResolvedUriPath($routeValues);
     if ($cachedResolvedUriPath !== false) {
         return $cachedResolvedUriPath;
     }
     $this->lastResolvedRoute = null;
     $this->createRoutesFromConfiguration();
     /** @var $route Route */
     foreach ($this->routes as $route) {
         if ($route->resolves($routeValues)) {
             $this->lastResolvedRoute = $route;
             $resolvedUriPath = $route->getResolvedUriPath();
             if ($resolvedUriPath !== null) {
                 $this->routerCachingService->storeResolvedUriPath($resolvedUriPath, $routeValues);
             }
             return $resolvedUriPath;
         }
     }
     $this->systemLogger->log('Router resolve(): Could not resolve a route for building an URI for the given route values.', LOG_WARNING, $routeValues);
     throw new 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);
 }
 /**
  * Make room in the sortindex-index space of a given path in preparation to inserting a node.
  * All indices that are greater or equal to the given referenceIndex are incremented by 100
  *
  * @param string $parentPath
  * @param integer $referenceIndex
  * @throws Exception\NodeException
  */
 protected function openIndexSpace($parentPath, $referenceIndex)
 {
     $this->systemLogger->log(sprintf('Opening sortindex space after index %s at path %s.', $referenceIndex, $parentPath), LOG_INFO);
     /** @var Query $query */
     $query = $this->entityManager->createQuery('SELECT n.Persistence_Object_Identifier identifier, n.index, n.path FROM Neos\\ContentRepository\\Domain\\Model\\NodeData n WHERE n.parentPathHash = :parentPathHash ORDER BY n.index ASC');
     $query->setParameter('parentPathHash', md5($parentPath));
     $nodesOnLevel = [];
     /** @var $node NodeData */
     foreach ($query->getArrayResult() as $node) {
         $nodesOnLevel[] = ['identifier' => $node['identifier'], 'path' => $node['path'], 'index' => $node['index']];
     }
     /** @var $node NodeData */
     foreach ($this->addedNodes as $node) {
         if ($node->getParentPath() === $parentPath) {
             $nodesOnLevel[] = ['addedNode' => $node, 'path' => $node->getPath(), 'index' => $node->getIndex()];
         }
     }
     $query = $this->entityManager->createQuery('UPDATE Neos\\ContentRepository\\Domain\\Model\\NodeData n SET n.index = :index WHERE n.Persistence_Object_Identifier = :identifier');
     foreach ($nodesOnLevel as $node) {
         if ($node['index'] < $referenceIndex) {
             continue;
         }
         $newIndex = $node['index'] + 100;
         if ($newIndex > self::INDEX_MAXIMUM) {
             throw new Exception\NodeException(sprintf('Reached maximum node index of %s while setting index of node %s.', $newIndex, $node['path']), 1317140402);
         }
         if (isset($node['addedNode'])) {
             $node['addedNode']->setIndex($newIndex);
         } else {
             if ($entity = $this->entityManager->getUnitOfWork()->tryGetById($node['identifier'], NodeData::class)) {
                 $entity->setIndex($newIndex);
             }
             $query->setParameter('index', $newIndex);
             $query->setParameter('identifier', $node['identifier']);
             $query->execute();
         }
     }
 }
 /**
  * Matches a frontend URI pointing to a node (for example a page).
  *
  * This function tries to find a matching node by the given request path. If one was found, its
  * absolute context node path is set in $this->value and true is returned.
  *
  * Note that this matcher does not check if access to the resolved workspace or node is allowed because at the point
  * in time the route part handler is invoked, the security framework is not yet fully initialized.
  *
  * @param string $requestPath The request path (without leading "/", relative to the current Site Node)
  * @return boolean true if the $requestPath could be matched, otherwise false
  * @throws \Exception
  * @throws Exception\NoHomepageException if no node could be found on the homepage (empty $requestPath)
  */
 protected function matchValue($requestPath)
 {
     try {
         /** @var NodeInterface $node */
         $node = null;
         // Build context explicitly without authorization checks because the security context isn't available yet
         // anyway and any Entity Privilege targeted on Workspace would fail at this point:
         $this->securityContext->withoutAuthorizationChecks(function () use(&$node, $requestPath) {
             $node = $this->convertRequestPathToNode($requestPath);
         });
     } catch (Exception $exception) {
         $this->systemLogger->log('FrontendNodeRoutePartHandler matchValue(): ' . $exception->getMessage(), LOG_DEBUG);
         if ($requestPath === '') {
             throw new Exception\NoHomepageException('Homepage could not be loaded. Probably you haven\'t imported a site yet', 1346950755, $exception);
         }
         return false;
     }
     if ($this->onlyMatchSiteNodes() && $node !== $node->getContext()->getCurrentSiteNode()) {
         return false;
     }
     $this->value = $node->getContextPath();
     return true;
 }
 /**
  * Deletes the given PersistentResource from the ResourceRepository and, if the storage data is no longer used in another
  * PersistentResource object, also deletes the data from the storage.
  *
  * This method will also remove the PersistentResource object from the (internal) ResourceRepository.
  *
  * @param PersistentResource $resource The resource to delete
  * @param boolean $unpublishResource If the resource should be unpublished before deleting it from the storage
  * @return boolean true if the resource was deleted, otherwise FALSE
  * @api
  */
 public function deleteResource(PersistentResource $resource, $unpublishResource = true)
 {
     $this->initialize();
     $collectionName = $resource->getCollectionName();
     $result = $this->resourceRepository->findBySha1($resource->getSha1());
     if (count($result) > 1) {
         $this->systemLogger->log(sprintf('Not removing storage data of resource %s (%s) because it is still in use by %s other PersistentResource object(s).', $resource->getFilename(), $resource->getSha1(), count($result) - 1), LOG_DEBUG);
     } else {
         if (!isset($this->collections[$collectionName])) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s) because it refers to the unknown collection "%s".', $resource->getFilename(), $resource->getSha1(), $collectionName), LOG_WARNING);
             return false;
         }
         $storage = $this->collections[$collectionName]->getStorage();
         if (!$storage instanceof WritableStorageInterface) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s) because it its collection "%s" is read-only.', $resource->getFilename(), $resource->getSha1(), $collectionName), LOG_WARNING);
             return false;
         }
         try {
             $storage->deleteResource($resource);
         } catch (\Exception $exception) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s): %s.', $resource->getFilename(), $resource->getSha1(), $exception->getMessage()), LOG_WARNING);
             return false;
         }
         if ($unpublishResource) {
             /** @var TargetInterface $target */
             $target = $this->collections[$collectionName]->getTarget();
             $target->unpublishResource($resource);
             $this->systemLogger->log(sprintf('Removed storage data and unpublished resource %s (%s) because it not used by any other PersistentResource object.', $resource->getFilename(), $resource->getSha1()), LOG_DEBUG);
         } else {
             $this->systemLogger->log(sprintf('Removed storage data of resource %s (%s) because it not used by any other PersistentResource object.', $resource->getFilename(), $resource->getSha1()), LOG_DEBUG);
         }
     }
     $resource->setDeleted();
     $this->resourceRepository->remove($resource);
     return true;
 }
Esempio n. 26
0
 /**
  * "Send" the given Message. This transport will add it to a stored collection of sent messages
  * for testing purposes and log the message to the system logger.
  *
  * @param \Swift_Mime_Message $message The message to send
  * @param array &$failedRecipients Failed recipients
  * @return integer
  */
 public function send(\Swift_Mime_Message $message, &$failedRecipients = null)
 {
     self::$deliveredMessages[] = $message;
     $this->systemLogger->log('Sent email to ' . $this->buildStringFromEmailAndNameArray($message->getTo()), LOG_DEBUG, array('message' => $message->toString()));
     return count((array) $message->getTo()) + count((array) $message->getCc()) + count((array) $message->getBcc());
 }
 /**
  * Returns an empty string
  *
  * @param string $typoScriptPath path causing the exception
  * @param \Exception $exception exception to handle
  * @param integer $referenceCode
  * @return string
  */
 protected function handle($typoScriptPath, \Exception $exception, $referenceCode)
 {
     $this->systemLogger->log('Absorbed Exception: ' . $exception->getMessage(), LOG_DEBUG, array('typoScriptPath' => $typoScriptPath, 'referenceCode' => $referenceCode), 'Neos.Fusion', \Neos\Fusion\Core\ExceptionHandlers\AbsorbingHandler::class);
     return '';
 }
Esempio n. 28
0
 /**
  * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods.
  *
  * @param array &$objectConfigurations
  * @return void
  * @throws ObjectException if an injected property is private
  */
 protected function autowireProperties(array &$objectConfigurations)
 {
     /** @var Configuration $objectConfiguration */
     foreach ($objectConfigurations as $objectConfiguration) {
         $className = $objectConfiguration->getClassName();
         $properties = $objectConfiguration->getProperties();
         if ($className === '') {
             continue;
         }
         $classMethodNames = get_class_methods($className);
         if (!is_array($classMethodNames)) {
             if (!class_exists($className)) {
                 throw new UnknownClassException(sprintf('The class "%s" defined in the object configuration for object "%s", defined in package: %s, does not exist.', $className, $objectConfiguration->getObjectName(), $objectConfiguration->getPackageKey()), 1352371371);
             } else {
                 throw new UnknownClassException(sprintf('Could not autowire properties of class "%s" because names of methods contained in that class could not be retrieved using get_class_methods().', $className), 1352386418);
             }
         }
         foreach ($classMethodNames as $methodName) {
             if (isset($methodName[6]) && strpos($methodName, 'inject') === 0 && $methodName[6] === strtoupper($methodName[6])) {
                 $propertyName = lcfirst(substr($methodName, 6));
                 $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, Flow\Autowiring::class);
                 if ($autowiringAnnotation !== null && $autowiringAnnotation->enabled === false) {
                     continue;
                 }
                 if ($methodName === 'injectSettings') {
                     $packageKey = $objectConfiguration->getPackageKey();
                     if ($packageKey !== null) {
                         $properties[$propertyName] = new ConfigurationProperty($propertyName, ['type' => ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'path' => $packageKey], ConfigurationProperty::PROPERTY_TYPES_CONFIGURATION);
                     }
                 } 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, Inject::class) as $propertyName) {
             if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) {
                 throw new ObjectException(sprintf('The property "%%s" in class "%s" must not be private when annotated for injection.', $propertyName, $className), 1328109641);
             }
             if (!array_key_exists($propertyName, $properties)) {
                 /** @var Inject $injectAnnotation */
                 $injectAnnotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, Inject::class);
                 $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\');
                 $configurationProperty = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT, null, $injectAnnotation->lazy);
                 $properties[$propertyName] = $configurationProperty;
             }
         }
         foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, InjectConfiguration::class) as $propertyName) {
             if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) {
                 throw new ObjectException(sprintf('The property "%s" in class "%s" must not be private when annotated for configuration injection.', $propertyName, $className), 1416765599);
             }
             if (array_key_exists($propertyName, $properties)) {
                 continue;
             }
             /** @var InjectConfiguration $injectConfigurationAnnotation */
             $injectConfigurationAnnotation = $this->reflectionService->getPropertyAnnotation($className, $propertyName, InjectConfiguration::class);
             if ($injectConfigurationAnnotation->type === ConfigurationManager::CONFIGURATION_TYPE_SETTINGS) {
                 $packageKey = $injectConfigurationAnnotation->package !== null ? $injectConfigurationAnnotation->package : $objectConfiguration->getPackageKey();
                 $configurationPath = rtrim($packageKey . '.' . $injectConfigurationAnnotation->path, '.');
             } else {
                 if ($injectConfigurationAnnotation->package !== null) {
                     throw new ObjectException(sprintf('The InjectConfiguration annotation for property "%s" in class "%s" specifies a "package" key for configuration type "%s", but this is only supported for injection of "Settings".', $propertyName, $className, $injectConfigurationAnnotation->type), 1420811958);
                 }
                 $configurationPath = $injectConfigurationAnnotation->path;
             }
             $properties[$propertyName] = new ConfigurationProperty($propertyName, ['type' => $injectConfigurationAnnotation->type, 'path' => $configurationPath], ConfigurationProperty::PROPERTY_TYPES_CONFIGURATION);
         }
         $objectConfiguration->setProperties($properties);
     }
 }
 /**
  * Publishes the given source stream to this target, with the given relative path.
  *
  * @param resource $sourceStream Stream of the source to publish
  * @param string $relativeTargetPathAndFilename relative path and filename in the target directory
  * @return void
  * @throws TargetException
  */
 protected function publishFile($sourceStream, $relativeTargetPathAndFilename)
 {
     $pathInfo = UnicodeFunctions::pathinfo($relativeTargetPathAndFilename);
     if (isset($pathInfo['extension']) && array_key_exists(strtolower($pathInfo['extension']), $this->extensionBlacklist) && $this->extensionBlacklist[strtolower($pathInfo['extension'])] === true) {
         throw new TargetException(sprintf('Could not publish "%s" into resource publishing target "%s" because the filename extension "%s" is blacklisted.', $sourceStream, $this->name, strtolower($pathInfo['extension'])), 1447148472);
     }
     $targetPathAndFilename = $this->path . $relativeTargetPathAndFilename;
     if (@fstat($sourceStream) === false) {
         throw new TargetException(sprintf('Could not publish "%s" into resource publishing target "%s" because the source file is not accessible (file stat failed).', $sourceStream, $this->name), 1375258499);
     }
     if (!file_exists(dirname($targetPathAndFilename))) {
         Files::createDirectoryRecursively(dirname($targetPathAndFilename));
     }
     if (!is_writable(dirname($targetPathAndFilename))) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the target file "%s" is not writable.', $sourceStream, $this->name, $targetPathAndFilename), 1428917322, isset($exception) ? $exception : null);
     }
     try {
         $targetFileHandle = fopen($targetPathAndFilename, 'w');
         $result = stream_copy_to_stream($sourceStream, $targetFileHandle);
         fclose($targetFileHandle);
     } catch (\Exception $exception) {
         $result = false;
     }
     if ($result === false) {
         throw new TargetException(sprintf('Could not publish "%s" into resource publishing target "%s" because the source file could not be copied to the target location.', $sourceStream, $this->name), 1375258399, isset($exception) ? $exception : null);
     }
     $this->systemLogger->log(sprintf('FileSystemTarget: Published file. (target: %s, file: %s)', $this->name, $relativeTargetPathAndFilename), LOG_DEBUG);
 }
Esempio n. 30
0
 /**
  * Returns a string containing all validation errors separated by PHP_EOL.
  *
  * @return string
  */
 protected function getFlattenedValidationErrorMessage()
 {
     $outputMessage = 'Validation failed while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL;
     $logMessage = $outputMessage;
     foreach ($this->arguments->getValidationResults()->getFlattenedErrors() as $propertyPath => $errors) {
         foreach ($errors as $error) {
             $logMessage .= 'Error for ' . $propertyPath . ':  ' . $error->render() . PHP_EOL;
         }
     }
     $this->systemLogger->log($logMessage, LOG_ERR);
     return $outputMessage;
 }