/** * @test */ public function setDateTimeAllowsForMockingTheCurrentTime() { $simulatedCurrentTime = new \DateTime(); date_add($simulatedCurrentTime, new \DateInterval('P1D')); $context = $this->contextFactory->create(array('currentDateTime' => $simulatedCurrentTime)); $this->assertEquals($simulatedCurrentTime, $context->getCurrentDateTime()); }
/** * @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'); }
/** * @param string $nodeIdentifier * @return NodeInterface */ protected function getNodeByIdentifier($nodeIdentifier) { $context = $this->contextFactory->create(); $node = null; $this->securityContext->withoutAuthorizationChecks(function () use($nodeIdentifier, $context, &$node) { $node = $context->getNodeByIdentifier($nodeIdentifier); }); $context->getFirstLevelNodeCache()->setByIdentifier($nodeIdentifier, null); return $node; }
/** * Creates missing child nodes for the given node. * * @param NodeInterface $node * @return void */ public function createChildNodes(NodeInterface $node) { $nodeType = $node->getNodeType(); foreach ($nodeType->getAutoCreatedChildNodes() as $childNodeName => $childNodeType) { try { $node->createNode($childNodeName, $childNodeType); } catch (NodeExistsException $exception) { // If you have a node that has been marked as removed, but is needed again // the old node is recovered $childNodePath = NodePaths::addNodePathSegment($node->getPath(), $childNodeName); $contextProperties = $node->getContext()->getProperties(); $contextProperties['removedContentShown'] = true; $context = $this->contextFactory->create($contextProperties); $childNode = $context->getNode($childNodePath); if ($childNode->isRemoved()) { $childNode->setRemoved(false); } } } }
/** * @param string $workspaceName * @param array $dimensions * @param integer $limit * @param callable $callback * @return integer */ protected function indexWorkspaceWithDimensions($workspaceName, array $dimensions = [], $limit = null, callable $callback = null) { $context = $this->contextFactory->create(['workspaceName' => $workspaceName, 'dimensions' => $dimensions]); $rootNode = $context->getRootNode(); $indexedNodes = 0; $traverseNodes = function (NodeInterface $currentNode, &$indexedNodes) use($limit, &$indexedNodes, &$traverseNodes) { if ($limit !== null && $indexedNodes > $limit) { return; } $this->nodeIndexingManager->indexNode($currentNode); $indexedNodes++; array_map(function (NodeInterface $childNode) use($traverseNodes, &$indexedNodes) { $traverseNodes($childNode, $indexedNodes); }, $currentNode->getChildNodes()); }; $traverseNodes($rootNode, $indexedNodes); if ($callback !== null) { $callback($workspaceName, $indexedNodes, $dimensions); } return $indexedNodes; }
/** * @param string $workspaceName * @param array $dimensions * @return void */ protected function indexWorkspaceWithDimensions($workspaceName, array $dimensions = array()) { $context = $this->contextFactory->create(array('workspaceName' => $workspaceName, 'dimensions' => $dimensions)); $rootNode = $context->getRootNode(); $this->traverseNodes($rootNode); if ($dimensions === array()) { $this->outputLine('Workspace "' . $workspaceName . '" without dimensions done. (Indexed ' . $this->indexedNodes . ' nodes)'); } else { $this->outputLine('Workspace "' . $workspaceName . '" and dimensions "' . json_encode($dimensions) . '" done. (Indexed ' . $this->indexedNodes . ' nodes)'); } $this->countedIndexedNodes = $this->countedIndexedNodes + $this->indexedNodes; $this->indexedNodes = 0; }
/** * index this node, and add it to the current bulk request. * * @param NodeInterface $node * @param string $targetWorkspaceName In case this is triggered during publishing, a workspace name will be passed in * @return void * @throws \TYPO3\TYPO3CR\Search\Exception\IndexingException */ public function indexNode(NodeInterface $node, $targetWorkspaceName = null) { $indexer = function (NodeInterface $node, $targetWorkspaceName = null) { $contextPath = $node->getContextPath(); if ($this->settings['indexAllWorkspaces'] === false) { // we are only supposed to index the live workspace. // We need to check the workspace at two occasions; checking the // $targetWorkspaceName and the workspace name of the node's context as fallback if ($targetWorkspaceName !== null && $targetWorkspaceName !== 'live') { return; } if ($targetWorkspaceName === null && $node->getContext()->getWorkspaceName() !== 'live') { return; } } if ($targetWorkspaceName !== null) { $contextPath = str_replace($node->getContext()->getWorkspace()->getName(), $targetWorkspaceName, $contextPath); } $contextPathHash = sha1($contextPath); $nodeType = $node->getNodeType(); $mappingType = $this->getIndex()->findType(NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($nodeType)); // Remove document with the same contextPathHash but different NodeType, required after NodeType change $this->logger->log(sprintf('NodeIndexer: Removing node %s from index (if node type changed from %s). ID: %s', $contextPath, $node->getNodeType()->getName(), $contextPathHash), LOG_DEBUG, null, 'ElasticSearch (CR)'); $this->getIndex()->request('DELETE', '/_query', [], json_encode(['query' => ['bool' => ['must' => ['ids' => ['values' => [$contextPathHash]]], 'must_not' => ['term' => ['_type' => NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($node->getNodeType()->getName())]]]]])); if ($node->isRemoved()) { // TODO: handle deletion from the fulltext index as well $mappingType->deleteDocumentById($contextPathHash); $this->logger->log(sprintf('NodeIndexer: Removed node %s from index (node flagged as removed). ID: %s', $contextPath, $contextPathHash), LOG_DEBUG, null, 'ElasticSearch (CR)'); return; } $logger = $this->logger; $fulltextIndexOfNode = []; $nodePropertiesToBeStoredInIndex = $this->extractPropertiesAndFulltext($node, $fulltextIndexOfNode, function ($propertyName) use($logger, $contextPathHash) { $logger->log(sprintf('NodeIndexer (%s) - Property "%s" not indexed because no configuration found.', $contextPathHash, $propertyName), LOG_DEBUG, null, 'ElasticSearch (CR)'); }); $document = new ElasticSearchDocument($mappingType, $nodePropertiesToBeStoredInIndex, $contextPathHash); $documentData = $document->getData(); if ($targetWorkspaceName !== null) { $documentData['__workspace'] = $targetWorkspaceName; } $dimensionCombinations = $node->getContext()->getDimensions(); if (is_array($dimensionCombinations)) { $documentData['__dimensionCombinations'] = $dimensionCombinations; $documentData['__dimensionCombinationHash'] = md5(json_encode($dimensionCombinations)); } if ($this->isFulltextEnabled($node)) { if ($this->isFulltextRoot($node)) { // for fulltext root documents, we need to preserve the "__fulltext" field. That's why we use the // "update" API instead of the "index" API, with a custom script internally; as we // shall not delete the "__fulltext" part of the document if it has any. $this->currentBulkRequest[] = [['update' => ['_type' => $document->getType()->getName(), '_id' => $document->getId()]], ['script' => ' fulltext = (ctx._source.containsKey("__fulltext") ? ctx._source.__fulltext : new LinkedHashMap()); fulltextParts = (ctx._source.containsKey("__fulltextParts") ? ctx._source.__fulltextParts : new LinkedHashMap()); ctx._source = newData; ctx._source.__fulltext = fulltext; ctx._source.__fulltextParts = fulltextParts ', 'params' => ['newData' => $documentData], 'upsert' => $documentData, 'lang' => 'groovy']]; } else { // non-fulltext-root documents can be indexed as-they-are $this->currentBulkRequest[] = [['index' => ['_type' => $document->getType()->getName(), '_id' => $document->getId()]], $documentData]; } $this->updateFulltext($node, $fulltextIndexOfNode, $targetWorkspaceName); } $this->logger->log(sprintf('NodeIndexer: Added / updated node %s. ID: %s Context: %s', $contextPath, $contextPathHash, json_encode($node->getContext()->getProperties())), LOG_DEBUG, null, 'ElasticSearch (CR)'); }; $dimensionCombinations = $this->contentDimensionCombinator->getAllAllowedCombinations(); $workspaceName = $targetWorkspaceName ?: 'live'; $nodeIdentifier = $node->getIdentifier(); if ($dimensionCombinations !== []) { foreach ($dimensionCombinations as $combination) { $context = $this->contextFactory->create(['workspaceName' => $workspaceName, 'dimensions' => $combination]); $node = $context->getNodeByIdentifier($nodeIdentifier); if ($node !== null) { $indexer($node, $targetWorkspaceName); } } } else { $context = $this->contextFactory->create(['workspaceName' => $workspaceName]); $node = $context->getNodeByIdentifier($nodeIdentifier); if ($node !== null) { $indexer($node, $targetWorkspaceName); } } }
/** * Returns the form post values * * @param string $path Absolute path of the node * @return void */ public function listFormPostsAction($path) { $context = $this->contextFactory->create(array('workspaceName' => 'live')); $formNode = $this->nodeDataRepository->findOneByPath($path, $context->getWorkspace()); $this->view->assignMultiple(array('formIdentifier' => $formNode->getProperty('formIdentifier'), 'formPosts' => $this->nodeDataRepository->findByParentAndNodeTypeRecursively($formNode->getParentPath(), 'Lelesys.Plugin.ContactForm:FormPost', $context->getWorkspace()))); }