/**
  * 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;
 }
 /**
  * Provides an XML comment containing the exception
  *
  * @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->logException($exception);
     if (isset($referenceCode)) {
         return sprintf('<!-- Exception while rendering %s: %s (%s) -->', $this->formatScriptPath($typoScriptPath, ''), htmlspecialchars($exception->getMessage()), $referenceCode);
     } else {
         return sprintf('<!-- Exception while rendering %s: %s -->', $this->formatScriptPath($typoScriptPath, ''), htmlspecialchars($exception->getMessage()));
     }
 }
 /**
  * @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);
     }
 }
 /**
  * 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();
 }
 /**
  * Renders the exception in HTML for display
  *
  * @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)
 {
     $messageArray = array('header' => 'An exception was thrown while Neos tried to render your page', 'content' => htmlspecialchars($exception->getMessage()), 'stacktrace' => $this->formatTypoScriptPath($typoScriptPath), 'referenceCode' => $this->formatErrorCodeMessage($referenceCode));
     $messageBody = sprintf('<p class="neos-message-content">%s</p>' . '<p class="neos-message-stacktrace"><code>%s</code></p>', $messageArray['content'], $messageArray['stacktrace']);
     if ($referenceCode) {
         $messageBody = sprintf('%s<p class="neos-reference-code">%s</p>', $messageBody, $messageArray['referenceCode']);
     }
     $message = sprintf('<div class="neos-message-header"><div class="neos-message-icon"><i class="icon-warning-sign"></i></div><h1>%s</h1></div>' . '<div class="neos-message-wrapper">%s</div>', $messageArray['header'], $messageBody);
     $this->systemLogger->logException($exception);
     return $message;
 }
 /**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * 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 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;
 }
 /**
  * @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));
 }
 /**
  * Handles the given exception
  *
  * @param object $exception The exception object - can be \Exception, or some type of \Throwable in PHP 7
  * @return void
  */
 public function handleException($exception)
 {
     // Ignore if the error is suppressed by using the shut-up operator @
     if (error_reporting() === 0) {
         return;
     }
     $this->renderingOptions = $this->resolveCustomRenderingOptions($exception);
     if (is_object($this->systemLogger) && isset($this->renderingOptions['logException']) && $this->renderingOptions['logException']) {
         if ($exception instanceof \Throwable) {
             if ($this->systemLogger instanceof ThrowableLoggerInterface) {
                 $this->systemLogger->logThrowable($exception);
             } else {
                 // Convert \Throwable to \Exception for non-supporting logger implementations
                 $this->systemLogger->logException(new \Exception($exception->getMessage(), $exception->getCode()));
             }
         } elseif ($exception instanceof \Exception) {
             $this->systemLogger->logException($exception);
         }
     }
     switch (PHP_SAPI) {
         case 'cli':
             $this->echoExceptionCli($exception);
             break;
         default:
             $this->echoExceptionWeb($exception);
     }
 }
 /**
  * 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);
     }
 }
 /**
  * Returns the query result count
  *
  * @return integer The query result count
  * @throws Exception\DatabaseConnectionException
  * @api
  */
 public function count()
 {
     try {
         $originalQuery = $this->queryBuilder->getQuery();
         $dqlQuery = clone $originalQuery;
         $dqlQuery->setParameters($originalQuery->getParameters());
         $dqlQuery->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_TREE_WALKERS, [CountWalker::class]);
         $offset = $dqlQuery->getFirstResult();
         $limit = $dqlQuery->getMaxResults();
         if ($offset !== null) {
             $dqlQuery->setFirstResult(null);
         }
         $numberOfResults = (int) $dqlQuery->getSingleScalarResult();
         if ($offset !== null) {
             $numberOfResults = max(0, $numberOfResults - $offset);
         }
         if ($limit !== null) {
             $numberOfResults = min($numberOfResults, $limit);
         }
         return $numberOfResults;
     } catch (\Doctrine\ORM\ORMException $ormException) {
         $this->systemLogger->logException($ormException);
         return 0;
     } catch (\PDOException $pdoException) {
         throw new Exception\DatabaseConnectionException($pdoException->getMessage(), $pdoException->getCode());
     }
 }
 /**
  * Import sites content
  *
  * This command allows for importing one or more sites or partial content from an XML source. The format must
  * be identical to that produced by the export command.
  *
  * If a filename is specified, this command expects the corresponding file to contain the XML structure. The
  * filename php://stdin can be used to read from standard input.
  *
  * If a package key is specified, this command expects a Sites.xml file to be located in the private resources
  * directory of the given package (Resources/Private/Content/Sites.xml).
  *
  * @param string $packageKey Package key specifying the package containing the sites content
  * @param string $filename relative path and filename to the XML file containing the sites content
  * @return void
  */
 public function importCommand($packageKey = null, $filename = null)
 {
     $exceedingArguments = $this->request->getExceedingArguments();
     if (isset($exceedingArguments[0]) && $packageKey === null && $filename === null) {
         if (file_exists($exceedingArguments[0])) {
             $filename = $exceedingArguments[0];
         } elseif ($this->packageManager->isPackageAvailable($exceedingArguments[0])) {
             $packageKey = $exceedingArguments[0];
         }
     }
     if ($packageKey === null && $filename === null) {
         $this->outputLine('You have to specify either "--package-key" or "--filename"');
         $this->quit(1);
     }
     $site = null;
     if ($filename !== null) {
         try {
             $site = $this->siteImportService->importFromFile($filename);
         } catch (\Exception $exception) {
             $this->systemLogger->logException($exception);
             $this->outputLine('<error>During the import of the file "%s" an exception occurred: %s, see log for further information.</error>', array($filename, $exception->getMessage()));
             $this->quit(1);
         }
     } else {
         try {
             $site = $this->siteImportService->importFromPackage($packageKey);
         } catch (\Exception $exception) {
             $this->systemLogger->logException($exception);
             $this->outputLine('<error>During the import of the "Sites.xml" from the package "%s" an exception occurred: %s, see log for further information.</error>', array($packageKey, $exception->getMessage()));
             $this->quit(1);
         }
     }
     $this->outputLine('Import of site "%s" finished.', array($site->getName()));
 }
Beispiel #16
0
 /**
  * Output an error message and log the exception.
  *
  * @param \Exception $exception
  * @return void
  */
 protected function handleException(\Exception $exception)
 {
     $this->outputLine('<error>%s</error>', [$exception->getMessage()]);
     $this->outputLine();
     $this->outputLine('The exception details have been logged to the Flow system log.');
     $this->systemLogger->logException($exception);
     $this->quit(1);
 }
 /**
  * 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;
 }
Beispiel #18
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;
         }
     }
 }
 /**
  * Get a single property reduced to a simple type (no objects) representation
  *
  * @param NodeInterface $node
  * @param string $propertyName
  * @return mixed
  */
 public function getProperty(NodeInterface $node, $propertyName)
 {
     if ($propertyName[0] === '_') {
         $propertyValue = ObjectAccess::getProperty($node, ltrim($propertyName, '_'));
     } else {
         $propertyValue = $node->getProperty($propertyName);
     }
     $dataType = $node->getNodeType()->getPropertyType($propertyName);
     try {
         $convertedValue = $this->convertValue($propertyValue, $dataType);
     } catch (PropertyException $exception) {
         $this->systemLogger->logException($exception);
         $convertedValue = null;
     }
     if ($convertedValue === null) {
         $convertedValue = $this->getDefaultValueForProperty($node->getNodeType(), $propertyName);
     }
     return $convertedValue;
 }
 /**
  * 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);
     }
 }
 /**
  * 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);
             }
         }
     }
 }
 /**
  * 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();
 }
 /**
  * @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);
         }
     }
 }
 /**
  * Returns a thumbnail of the given asset
  *
  * If the maximum width / height is not specified or exceeds the original asset's dimensions, the width / height of
  * the original asset is used.
  *
  * @param AssetInterface $asset The asset to render a thumbnail for
  * @param ThumbnailConfiguration $configuration
  * @return ImageInterface
  * @throws \Exception
  */
 public function getThumbnail(AssetInterface $asset, ThumbnailConfiguration $configuration)
 {
     // Calculates the dimensions of the thumbnail to be generated and returns the thumbnail image if the new
     // dimensions differ from the specified image dimensions, otherwise the original image is returned.
     if ($asset instanceof ImageInterface) {
         if ($asset->getWidth() === null && $asset->getHeight() === null) {
             return $asset;
         }
         $maximumWidth = $configuration->getMaximumWidth() > $asset->getWidth() ? $asset->getWidth() : $configuration->getMaximumWidth();
         $maximumHeight = $configuration->getMaximumHeight() > $asset->getHeight() ? $asset->getHeight() : $configuration->getMaximumHeight();
         if ($configuration->isUpScalingAllowed() === false && $maximumWidth === $asset->getWidth() && $maximumHeight === $asset->getHeight()) {
             return $asset;
         }
     }
     $assetIdentifier = $this->persistenceManager->getIdentifierByObject($asset);
     $configurationHash = $configuration->getHash();
     if (!isset($this->thumbnailCache[$assetIdentifier])) {
         $this->thumbnailCache[$assetIdentifier] = [];
     }
     if (isset($this->thumbnailCache[$assetIdentifier][$configurationHash])) {
         $thumbnail = $this->thumbnailCache[$assetIdentifier][$configurationHash];
     } else {
         $thumbnail = $this->thumbnailRepository->findOneByAssetAndThumbnailConfiguration($asset, $configuration);
         $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
     }
     $async = $configuration->isAsync();
     if ($thumbnail === null) {
         try {
             $thumbnail = new Thumbnail($asset, $configuration, $async);
             $this->emitThumbnailCreated($thumbnail);
             // If the thumbnail strategy failed to generate a valid thumbnail
             if ($async === false && $thumbnail->getResource() === null && $thumbnail->getStaticResource() === null) {
                 $this->thumbnailRepository->remove($thumbnail);
                 return null;
             }
             if (!$this->persistenceManager->isNewObject($asset)) {
                 $this->thumbnailRepository->add($thumbnail);
             }
             $asset->addThumbnail($thumbnail);
             // Allow thumbnails to be persisted even if this is a "safe" HTTP request:
             $this->persistenceManager->whiteListObject($thumbnail);
             $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
         } catch (NoThumbnailAvailableException $exception) {
             $this->systemLogger->logException($exception);
             return null;
         }
         $this->persistenceManager->whiteListObject($thumbnail);
         $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
     } elseif ($thumbnail->getResource() === null && $async === false) {
         $this->refreshThumbnail($thumbnail);
     }
     return $thumbnail;
 }
 /**
  * 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);
     }
 }
 /**
  * @param string $resourcePath
  * @return string
  */
 protected function getStaticResourceWebBaseUri($resourcePath)
 {
     $localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath);
     $matches = array();
     try {
         if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) {
             $packageKey = $matches[1];
             $path = $matches[2];
             return $this->resourceManager->getPublicPackageResourceUri($packageKey, $path);
         }
     } catch (\Exception $exception) {
         $this->systemLogger->logException($exception);
     }
     return '';
 }
Beispiel #28
0
 /**
  * Finally evaluate the TypoScript path
  *
  * As PHP does not like throwing an exception here, we render any exception using the configured TypoScript exception
  * handler and will also catch and log any exceptions resulting from that as a last resort.
  *
  * @return string
  */
 public function __toString()
 {
     try {
         return (string) $this->objectAccess();
     } catch (\Exception $exceptionHandlerException) {
         try {
             // Throwing an exception in __toString causes a fatal error, so if that happens we catch them and use the context dependent exception handler instead.
             $contextDependentExceptionHandler = new ContextDependentHandler();
             $contextDependentExceptionHandler->setRuntime($this->fusionRuntime);
             return $contextDependentExceptionHandler->handleRenderingException($this->path, $exception);
         } catch (\Exception $contextDepndentExceptionHandlerException) {
             $this->systemLogger->logException($contextDepndentExceptionHandlerException, array('path' => $this->path));
             return sprintf('<!-- Exception while rendering exception in %s: %s (%s) -->', $this->path, $contextDepndentExceptionHandlerException->getMessage(), $contextDepndentExceptionHandlerException instanceof Exception ? 'see reference code ' . $contextDepndentExceptionHandlerException->getReferenceCode() . ' in log' : $contextDepndentExceptionHandlerException->getCode());
         }
     }
 }
 /**
  * Render the Uri.
  *
  * @return string The rendered URI or NULL if no URI could be resolved for the given node
  * @throws NeosException
  */
 public function evaluate()
 {
     $baseNode = null;
     $baseNodeName = $this->getBaseNodeName() ?: 'documentNode';
     $currentContext = $this->tsRuntime->getCurrentContext();
     if (isset($currentContext[$baseNodeName])) {
         $baseNode = $currentContext[$baseNodeName];
     } else {
         throw new NeosException(sprintf('Could not find a node instance in TypoScript context with name "%s" and no node instance was given to the node argument. Set a node instance in the TypoScript context or pass a node object to resolve the URI.', $baseNodeName), 1373100400);
     }
     try {
         return $this->linkingService->createNodeUri($this->tsRuntime->getControllerContext(), $this->getNode(), $baseNode, $this->getFormat(), $this->isAbsolute(), $this->getAdditionalParams(), $this->getSection(), $this->getAddQueryString(), $this->getArgumentsToBeExcludedFromQueryString());
     } catch (NeosException $exception) {
         $this->systemLogger->logException($exception);
         return '';
     }
 }
 /**
  * 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;
 }