/** * 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); } }
/** * @return NodeInterface */ public function getCurrentUserNode() { try { return $this->profileService->getCurrentPartyProfile(); } catch (\Exception $exception) { $this->systemLogger->log('Profile node could not be fetched: ' . $exception->getMessage(), LOG_CRIT); } }
/** * 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())); } }
private function processReceiverGroup(ReceiverGroup $receiverGroup, $language = NULL) { $cacheFileName = $receiverGroup->getCacheFileName($language); $jqProcess = escapeshellarg('cat ' . escapeshellcmd($receiverGroup->getReceiverSource()->getSourceFileName()) . ' | jq -c ' . escapeshellarg($this->convertFilterIntoJqExpression($receiverGroup->getFilter($language))) . ' > ' . escapeshellcmd($cacheFileName) . ' ; wc -l < ' . escapeshellcmd($cacheFileName) . ' > ' . escapeshellcmd($cacheFileName . '.lines')); $finalProcess = 'nohup /bin/bash -c ' . $jqProcess . ' &'; $this->systemLogger->log('Starting process: ' . $finalProcess); $proc = new Process($finalProcess); $proc->start(); }
/** * 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 \TYPO3\Flow\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 * @Flow\Before("methodAnnotatedWith(TYPO3\Flow\Annotations\Session)") */ public function initializeSession(\TYPO3\Flow\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(); }
/** * Create a new site from a site template * * This command uses a site template located in a sitePackage to create a new site with a new subdomain. * * @param string $sitePackage Package key of the Site containing the template under Templates/Content/Sites.xml * @param string $siteName The sitename * @param string $baseDomain The base domain name e.g. site.com => will be used like $siteName.site.com * @return void */ public function newSiteCommand($sitePackage, $siteName, $baseDomain) { try { $site = $this->siteService->importSiteFromTemplate($sitePackage, $siteName, $baseDomain); $this->outputLine('Created a new site "%s"', array($site->getName())); } catch (\Exception $e) { $this->systemLogger->logException($e); $this->outputLine('An error occured during site creation, check error log for details'); } }
/** * 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' => $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; }
/** * 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); } } } }
/** * @param string $event * @param string $person * * @return void */ public function removeAttendeeAction($event, $person = '') { try { $context = $this->contextFactory->create([]); $person = $this->getPersonProfile($person, $context); $event = $context->getNodeByIdentifier($event); $this->eventService->removeAttendeeFromEvent($event, $person); } catch (\Exception $exception) { $this->systemLogger->log($exception->getMessage(), LOG_ALERT); } $this->addFlashMessage('Je bent afgemeld'); $this->redirectToUri('/agenda'); }
/** * @return void */ public function pingAction() { $this->systemLogger->log("FOO" . $this->apiKey); $apiKey = $this->request->getHttpRequest()->getHeader('X-Api-Key'); $this->systemLogger->log($apiKey); if ($apiKey === $this->apiKey) { $this->response->setStatus(204); $this->response->send(); } else { $this->response->setStatus(403, 'Invalid Authentication'); $this->response->send(); } return false; }
/** * @param string $value * @throws Exception * @throws \TYPO3\Flow\Resource\Exception * @throws \TYPO3\Flow\Utility\Exception */ protected function initializeValue($value) { if (!is_array($value)) { throw new Exception('Value must be an array, with source URI (sourceUri) and filename (filename)', 1425981082); } if (!isset($value['sourceUri'])) { throw new Exception('Missing source URI', 1425981083); } $sourceUri = trim($value['sourceUri']); if (!isset($value['filename'])) { throw new Exception('Missing filename URI', 1425981084); } $filename = trim($value['filename']); $overrideFilename = isset($value['overrideFilename']) ? trim($value['overrideFilename']) : $filename; if (!isset($this->options['downloadDirectory'])) { throw new Exception('Missing download directory data type option', 1425981085); } Files::createDirectoryRecursively($this->options['downloadDirectory']); $temporaryFileAndPathname = trim($this->options['downloadDirectory'] . $filename); $this->download($sourceUri, $temporaryFileAndPathname); $sha1Hash = sha1_file($temporaryFileAndPathname); # Try to add file extenstion if missing if (!$this->downloadCache->has($sha1Hash)) { $fileExtension = pathinfo($temporaryFileAndPathname, PATHINFO_EXTENSION); if (trim($fileExtension) === '') { $mimeTypeGuesser = new MimeTypeGuesser(); $mimeType = $mimeTypeGuesser->guess($temporaryFileAndPathname); $this->logger->log(sprintf('Try to guess mime type for "%s" (%s), result: %s', $sourceUri, $filename, $mimeType), LOG_DEBUG); $fileExtension = MediaTypes::getFilenameExtensionFromMediaType($mimeType); if ($fileExtension !== '') { $oldTemporaryDestination = $temporaryFileAndPathname; $temporaryDestination = $temporaryFileAndPathname . '.' . $fileExtension; copy($oldTemporaryDestination, $temporaryDestination); $this->logger->log(sprintf('Rename "%s" to "%s"', $oldTemporaryDestination, $temporaryDestination), LOG_DEBUG); } } } $resource = $this->resourceManager->getResourceBySha1($sha1Hash); if ($resource === NULL) { $resource = $this->resourceManager->importResource($temporaryFileAndPathname); if ($filename !== $overrideFilename) { $resource->setFilename($overrideFilename); } } $this->temporaryFileAndPathname = $temporaryFileAndPathname; $this->downloadCache->set($sha1Hash, ['sha1Hash' => $sha1Hash, 'filename' => $filename, 'sourceUri' => $sourceUri, 'temporaryFileAndPathname' => $temporaryFileAndPathname]); $this->value = $resource; }
/** * @Flow\Around("setting(Ttree.Embedly.logApiRequest) && within(Ttree\Embedly\Embedly) && method(public .*->(oembed|preview|objectify|extract|services)())") * @param JoinPointInterface $joinPoint The current join point * @return mixed */ public function getResponseFromCache(JoinPointInterface $joinPoint) { $proxy = $joinPoint->getProxy(); $key = ObjectAccess::getProperty($proxy, 'key'); $params = $joinPoint->getMethodArgument('params'); $cacheKey = md5($joinPoint->getClassName() . $joinPoint->getMethodName() . $key . json_encode($params)); if ($this->responseCache->has($cacheKey)) { $this->systemLogger->log(sprintf(' cache hit Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG); return $this->responseCache->get($cacheKey); } else { $this->systemLogger->log(sprintf(' cache miss Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG); } $response = $joinPoint->getAdviceChain()->proceed($joinPoint); $this->responseCache->set($cacheKey, $response); return $response; }
/** * 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 = array(); $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('TYPO3.Media is configured to simulate the deprecated Neos 1.2 behaviour. Please check the setting "TYPO3.Media.behaviourFlag".', LOG_DEBUG); } }
/** * Renumbers the indexes of all nodes directly below the node specified by the * given path. * * Note that renumbering must happen in-memory and can't be optimized by a clever * query executed directly by the database because sorting indexes of new or * modified nodes need to be considered. * * @param string $parentPath Path to the parent node * @return void * @throws Exception\NodeException */ protected function renumberIndexesInLevel($parentPath) { $this->systemLogger->log(sprintf('Renumbering nodes in level below %s.', $parentPath), LOG_INFO); /** @var \Doctrine\ORM\Query $query */ $query = $this->entityManager->createQuery('SELECT n FROM TYPO3\\TYPO3CR\\Domain\\Model\\NodeData n WHERE n.parentPathHash = :parentPathHash ORDER BY n.index ASC'); $query->setParameter('parentPathHash', md5($parentPath)); $nodesOnLevel = array(); /** @var $node NodeData */ foreach ($query->getResult() as $node) { $nodesOnLevel[$node->getIndex()] = $node; } /** @var $node NodeData */ foreach ($this->addedNodes as $node) { if ($node->getParentPath() === $parentPath) { $index = $node->getIndex(); if (isset($nodesOnLevel[$index])) { throw new Exception\NodeException(sprintf('Index conflict for nodes %s and %s: both have index %s', $nodesOnLevel[$index]->getPath(), $node->getPath(), $index), 1317140401); } $nodesOnLevel[$index] = $node; } } // We need to sort the nodes now, to take unpersisted node orderings into account. // This fixes bug #34291 ksort($nodesOnLevel); $newIndex = 100; foreach ($nodesOnLevel as $node) { if ($newIndex > self::INDEX_MAXIMUM) { throw new Exception\NodeException(sprintf('Reached maximum node index of %s while setting index of node %s.', $newIndex, $node->getPath()), 1317140402); } $node->setIndex($newIndex); $newIndex += 100; } }
/** * @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 TYPO3.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)); }
/** * 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 \TYPO3\Flow\Configuration\Exception\InvalidConfigurationTypeException */ protected function applyClassFilterConfiguration($classNames, $filterConfiguration, $includeOrExclude = 'include') { if (!in_array($includeOrExclude, array('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 "TYPO3.Flow.object.' . $includeOrExclude . 'Classes" was either excluded or is not loaded.', LOG_DEBUG); continue; } if (!is_array($filterExpressions)) { throw new \TYPO3\Flow\Configuration\Exception\InvalidConfigurationTypeException('The value given for setting "TYPO3.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] = array(); 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] === array()) { unset($classNames[$packageKey]); } } return $classNames; }
/** * Defines template if configured for provider. * * @param string $providerName * * @return bool TRUE if some configuration found, FALSE if no configuration defined for given provider. */ private function definePrettyPreRedirectTemplate($providerName) { $prettyPreRedirectPage = $this->configurationManager->getConfiguration(\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'TYPO3.Flow.security.authentication.providers.' . $providerName . '.providerOptions.Miscellaneous.prettyPreRedirectPage'); if (empty($prettyPreRedirectPage)) { return false; } $log = ''; if (isset($prettyPreRedirectPage['layoutRootPath']) && method_exists($this->view, 'setLayoutRootPath')) { $this->view->setLayoutRootPath($prettyPreRedirectPage['layoutRootPath']); } elseif (isset($prettyPreRedirectPage['layoutRootPath']) && !method_exists($this->view, 'setLayoutRootPath')) { $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setLayoutRootPath().', $providerName); } if (isset($prettyPreRedirectPage['partialRootPath']) && method_exists($this->view, 'setPartialRootPath')) { $this->view->setPartialRootPath($prettyPreRedirectPage['partialRootPath']); } elseif (isset($prettyPreRedirectPage['partialRootPath']) && !method_exists($this->view, 'setPartialRootPath')) { $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setPartialRootPath().', $providerName); } if (isset($prettyPreRedirectPage['templatePathAndFilename']) && method_exists($this->view, 'setTemplatePathAndFilename')) { $this->view->setTemplatePathAndFilename($prettyPreRedirectPage['templatePathAndFilename']); } elseif (isset($prettyPreRedirectPage['templatePathAndFilename']) && !method_exists($this->view, 'setTemplatePathAndFilename')) { $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setTemplatePathAndFilename().', $providerName); } if (!empty($log)) { $this->systemLogger->log($log, LOG_ERR); } $this->view->assignMultiple($prettyPreRedirectPage); return true; }
/** * 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, array('TYPO3\\Flow\\Persistence\\Doctrine\\CountWalker')); $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()); } }
/** * Iterates over all existing sessions and removes their data if the inactivity * timeout was reached. * * @param boolean $maximumSessionsToRemove How many sessions to remove per run * @return integer The number of outdated entries removed * @api */ public function collectGarbage($maximumSessionsToRemove = 0) { if ($this->inactivityTimeout === 0) { return 0; } if ($this->metaDataCache->has('_garbage-collection-running')) { return false; } $sessionRemovalCount = 0; $this->metaDataCache->set('_garbage-collection-running', true, array(), 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 ($maximumSessionsToRemove > 0 && $sessionRemovalCount >= $maximumSessionsToRemove) { break; } } $this->metaDataCache->remove('_garbage-collection-running'); return $sessionRemovalCount; }
/** * Create a new site. * * @param string $site Site to import * @param string $packageKey Package Name to create * @param string $siteName Site Name to create * @Flow\Validate(argumentName="$packageKey", type="\TYPO3\Neos\Validation\Validator\PackageKeyValidator") * @return void */ public function createSiteAction($site, $packageKey = '', $siteName = '') { if ($packageKey !== '' && $this->packageManager->isPackageActive('TYPO3.Neos.Kickstarter')) { if ($this->packageManager->isPackageAvailable($packageKey)) { $this->addFlashMessage('The package key "%s" already exists.', 'Invalid package key', Message::SEVERITY_ERROR, array(htmlspecialchars($packageKey)), 1412372021); $this->redirect('index'); } $generatorService = $this->objectManager->get('TYPO3\\Neos\\Kickstarter\\Service\\GeneratorService'); $generatorService->generateSitePackage($packageKey, $siteName); } else { $packageKey = $site; } $deactivatedSitePackages = $this->deactivateAllOtherSitePackages($packageKey); if (count($deactivatedSitePackages) > 0) { $this->flashMessageContainer->addMessage(new Message(sprintf('The existing Site Packages "%s" were deactivated, in order to prevent interactions with the newly created package "%s".', htmlspecialchars(implode(', ', $deactivatedSitePackages)), htmlspecialchars($packageKey)))); } $this->packageManager->activatePackage($packageKey); if ($packageKey !== '') { try { $this->siteImportService->importFromPackage($packageKey); $this->addFlashMessage('The site has been created.', '', null, array(), 1412372266); } catch (\Exception $exception) { $this->systemLogger->logException($exception); $this->addFlashMessage('Error: During the import of the "Sites.xml" from the package "%s" an exception occurred: %s', 'Import error', Message::SEVERITY_ERROR, array(htmlspecialchars($packageKey), htmlspecialchars($exception->getMessage())), 1412372375); } } else { $this->addFlashMessage('No site selected for import and no package name provided.', 'No site selected', Message::SEVERITY_ERROR, array(), 1412372554); $this->redirect('newSite'); } $this->unsetLastVisitedNodeAndRedirect('index'); }
/** * 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 !== array() || $this->annotationValueConstraints === array()) { $matches = $designatedAnnotations !== array(); } 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 \TYPO3\Flow\Aop\Exception */ public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier) { $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName); if ($matchResult === false) { throw new \TYPO3\Flow\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; }
/** * 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.', 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.', array($packageKey, $exception->getMessage())); $this->quit(1); } } $this->outputLine('Import of site "%s" finished.', array($site->getName())); }
/** * @param \TYPO3\Form\Core\Model\FinisherContext $finisherContext * @return void * @throws \TYPO3\Setup\Exception */ public function importSite(\TYPO3\Form\Core\Model\FinisherContext $finisherContext) { $formValues = $finisherContext->getFormRuntime()->getFormState()->getFormValues(); if (isset($formValues['prune']) && intval($formValues['prune']) === 1) { $this->nodeDataRepository->removeAll(); $this->workspaceRepository->removeAll(); $this->domainRepository->removeAll(); $this->siteRepository->removeAll(); $this->persistenceManager->persistAll(); } if (!empty($formValues['packageKey'])) { if ($this->packageManager->isPackageAvailable($formValues['packageKey'])) { throw new \TYPO3\Setup\Exception(sprintf('The package key "%s" already exists.', $formValues['packageKey']), 1346759486); } $packageKey = $formValues['packageKey']; $siteName = $formValues['siteName']; $generatorService = $this->objectManager->get('TYPO3\\Neos\\Kickstarter\\Service\\GeneratorService'); $generatorService->generateSitePackage($packageKey, $siteName); } elseif (!empty($formValues['site'])) { $packageKey = $formValues['site']; } $this->deactivateOtherSitePackages($packageKey); $this->packageManager->activatePackage($packageKey); if (!empty($packageKey)) { try { $contentContext = $this->contextFactory->create(array('workspaceName' => 'live')); $this->siteImportService->importFromPackage($packageKey, $contentContext); } catch (\Exception $exception) { $finisherContext->cancel(); $this->systemLogger->logException($exception); throw new SetupException(sprintf('Error: During the import of the "Sites.xml" from the package "%s" an exception occurred: %s', $packageKey, $exception->getMessage()), 1351000864); } } }
/** * Deletes the given Resource from the Resource Repository and, if the storage data is no longer used in another * Resource object, also deletes the data from the storage. * * This method will also remove the Resource object from the (internal) ResourceRepository. * * @param Resource $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(Resource $resource, $unpublishResource = TRUE) { $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 Resource 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 Resource 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 Resource object.', $resource->getFilename(), $resource->getSha1()), LOG_DEBUG); } } $resource->setDeleted(); $this->resourceRepository->remove($resource); return TRUE; }
/** * Send a new notification that a comment has been created * * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $commentNode The comment node * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $postNode The post node * @return void */ public function sendNewCommentNotification(NodeInterface $commentNode, NodeInterface $postNode) { if ($this->settings['notifications']['to']['email'] === '') { return; } if (!class_exists('TYPO3\\SwiftMailer\\Message')) { $this->systemLogger->logException(new \TYPO3\Flow\Exception('The package "TYPO3.SwiftMailer" is required to send notifications!', 1359473932)); return; } try { $mail = new Message(); $mail->setFrom(array($commentNode->getProperty('emailAddress') => $commentNode->getProperty('author')))->setTo(array($this->settings['notifications']['to']['email'] => $this->settings['notifications']['to']['name']))->setSubject('New comment on blog post "' . $postNode->getProperty('title') . '"' . ($commentNode->getProperty('spam') ? ' (SPAM)' : ''))->setBody($commentNode->getProperty('text'))->send(); } catch (\Exception $e) { $this->systemLogger->logException($e); } }
/** * Handles the given exception * * @param \Exception $exception The exception object * @return void */ public function handleException(\Exception $exception) { // Ignore if the error is suppressed by using the shut-up operator @ if (error_reporting() === 0) { return; } if (is_object($this->systemLogger)) { $this->systemLogger->logException($exception); } switch (PHP_SAPI) { case 'cli': $this->echoExceptionCli($exception); break; default: $this->echoExceptionWeb($exception); } }
/** * 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); }