Skip to content

Commit 644e1e0

Browse files
author
Robert Lemke
committed
Merge pull request #16 from Flowpack/search-api-adjustments
[!!!][TASK] Adjust to search API changes in TYPO3CR
2 parents 76ec2e2 + 4a7521d commit 644e1e0

5 files changed

Lines changed: 83 additions & 74 deletions

File tree

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Command/NodeIndexCommandController.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ class NodeIndexCommandController extends CommandController {
4040
*/
4141
protected $nodeDataRepository;
4242

43+
/**
44+
* @Flow\Inject
45+
* @var \TYPO3\TYPO3CR\Domain\Factory\NodeFactory
46+
*/
47+
protected $nodeFactory;
48+
49+
/**
50+
* @Flow\Inject
51+
* @var \TYPO3\TYPO3CR\Domain\Service\ContextFactory
52+
*/
53+
protected $contextFactory;
54+
4355
/**
4456
* @Flow\Inject
4557
* @var NodeTypeMappingBuilder
@@ -51,8 +63,6 @@ class NodeIndexCommandController extends CommandController {
5163
*/
5264
protected $logger;
5365

54-
55-
5666
/**
5767
* Show the mapping which would be sent to the ElasticSearch server
5868
*
@@ -61,7 +71,7 @@ class NodeIndexCommandController extends CommandController {
6171
public function showMappingCommand() {
6272
$nodeTypeMappingCollection = $this->nodeTypeMappingBuilder->buildMappingInformation($this->nodeIndexer->getIndex());
6373
foreach ($nodeTypeMappingCollection as $mapping) {
64-
/** @var Mapping $mapping */
74+
/** @var \Flowpack\ElasticSearch\Domain\Model\Mapping $mapping */
6575
$this->output(\Symfony\Component\Yaml\Yaml::dump($mapping->asArray(), 5, 2));
6676
$this->outputLine();
6777
}
@@ -106,7 +116,7 @@ public function buildCommand($limit = NULL, $update = FALSE) {
106116

107117
$nodeTypeMappingCollection = $this->nodeTypeMappingBuilder->buildMappingInformation($this->nodeIndexer->getIndex());
108118
foreach ($nodeTypeMappingCollection as $mapping) {
109-
/** @var Mapping $mapping */
119+
/** @var \Flowpack\ElasticSearch\Domain\Model\Mapping $mapping */
110120
$mapping->apply();
111121
}
112122
$this->logger->log('Updated Mapping.', LOG_INFO);
@@ -116,11 +126,19 @@ public function buildCommand($limit = NULL, $update = FALSE) {
116126

117127
$count = 0;
118128
foreach ($this->nodeDataRepository->findAll() as $nodeData) {
129+
/** @var \TYPO3\TYPO3CR\Domain\Model\NodeData $nodeData */
130+
$context = $this->contextFactory->create(array(
131+
'workspaceName' => $nodeData->getWorkspace()->getName(),
132+
'invisibleContentShown' => TRUE,
133+
'removedContentShown' => TRUE,
134+
'inaccessibleContentShown' => TRUE
135+
));
136+
$node = $this->nodeFactory->createFromNodeData($nodeData, $context);
119137
if ($limit !== NULL && $count > $limit) {
120138
break;
121139
}
122-
$this->nodeIndexingManager->indexNode($nodeData);
123-
$this->logger->log(sprintf(' %s: %s', $nodeData->getWorkspace()->getName(), $nodeData->getPath()), LOG_DEBUG);
140+
$this->nodeIndexingManager->indexNode($node);
141+
$this->logger->log(sprintf(' %s', $node->getContextPath()), LOG_DEBUG);
124142
$count ++;
125143
}
126144

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Indexer/NodeIndexer.php

Lines changed: 44 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Flowpack\ElasticSearch\Domain\Model\Document as ElasticSearchDocument;
1818
use Flowpack\ElasticSearch\Domain\Model\Index;
1919
use TYPO3\Flow\Annotations as Flow;
20-
use TYPO3\TYPO3CR\Domain\Model\NodeData;
20+
use TYPO3\TYPO3CR\Domain\Model\Node;
2121
use TYPO3\TYPO3CR\Domain\Service\NodeTypeManager;
2222

2323
/*
@@ -162,53 +162,53 @@ public function getIndex() {
162162
/**
163163
* index this node, and add it to the current bulk request.
164164
*
165-
* @param NodeData $nodeData
165+
* @param Node $node
166166
* @throws \Exception
167167
* @return void
168168
*/
169-
public function indexNode(NodeData $nodeData) {
170-
$persistenceObjectIdentifier = $this->persistenceManager->getIdentifierByObject($nodeData);
171-
$nodeType = $nodeData->getNodeType();
169+
public function indexNode(Node $node) {
170+
$identifier = sha1($node->getContextPath());
171+
$nodeType = $node->getNodeType();
172172

173173
$mappingType = $this->getIndex()->findType(NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($nodeType));
174174

175-
if ($nodeData->isRemoved()) {
175+
if ($node->isRemoved()) {
176176
// TODO: handle deletion from the fulltext index as well
177-
$mappingType->deleteDocumentById($persistenceObjectIdentifier);
178-
$this->logger->log(sprintf('NodeIndexer: Removed node %s from index (node flagged as removed). Persistence ID: %s', $nodeData->getContextPath(), $persistenceObjectIdentifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
177+
$mappingType->deleteDocumentById($identifier);
178+
$this->logger->log(sprintf('NodeIndexer: Removed node %s from index (node flagged as removed). Persistence ID: %s', $node->getContextPath(), $identifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
179179

180180
return;
181181
}
182182

183183
$nodePropertiesToBeStoredInElasticSearchIndex = array();
184184
$fulltextIndexOfNode = array();
185-
$fulltextIndexingEnabledForNode = $this->isFulltextEnabled($nodeData);
185+
$fulltextIndexingEnabledForNode = $this->isFulltextEnabled($node);
186186

187187
foreach ($nodeType->getProperties() as $propertyName => $propertyConfiguration) {
188188

189189
// Property Indexing
190190
if (isset($propertyConfiguration['elasticSearch']) && isset($propertyConfiguration['elasticSearch']['indexing'])) {
191191
if ($propertyConfiguration['elasticSearch']['indexing'] !== '') {
192-
$nodePropertiesToBeStoredInElasticSearchIndex[$propertyName] = $this->evaluateEelExpression($propertyConfiguration['elasticSearch']['indexing'], $nodeData, $propertyName, ($nodeData->hasProperty($propertyName) ? $nodeData->getProperty($propertyName) : NULL), $persistenceObjectIdentifier);
192+
$nodePropertiesToBeStoredInElasticSearchIndex[$propertyName] = $this->evaluateEelExpression($propertyConfiguration['elasticSearch']['indexing'], $node, $propertyName, ($node->hasProperty($propertyName) ? $node->getProperty($propertyName) : NULL), $identifier);
193193
}
194194
} elseif (isset($propertyConfiguration['type']) && isset($this->defaultConfigurationPerType[$propertyConfiguration['type']]['indexing'])) {
195195

196196
if ($this->defaultConfigurationPerType[$propertyConfiguration['type']]['indexing'] !== '') {
197-
$nodePropertiesToBeStoredInElasticSearchIndex[$propertyName] = $this->evaluateEelExpression($this->defaultConfigurationPerType[$propertyConfiguration['type']]['indexing'], $nodeData, $propertyName, ($nodeData->hasProperty($propertyName) ? $nodeData->getProperty($propertyName) : NULL), $persistenceObjectIdentifier);
197+
$nodePropertiesToBeStoredInElasticSearchIndex[$propertyName] = $this->evaluateEelExpression($this->defaultConfigurationPerType[$propertyConfiguration['type']]['indexing'], $node, $propertyName, ($node->hasProperty($propertyName) ? $node->getProperty($propertyName) : NULL), $identifier);
198198
}
199199
} else {
200-
$this->logger->log(sprintf('NodeIndexer (%s) - Property "%s" not indexed because no configuration found.', $persistenceObjectIdentifier, $propertyName), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
200+
$this->logger->log(sprintf('NodeIndexer (%s) - Property "%s" not indexed because no configuration found.', $identifier, $propertyName), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
201201
}
202202

203203
if ($fulltextIndexingEnabledForNode === TRUE) {
204204
if (isset($propertyConfiguration['elasticSearch']) && isset($propertyConfiguration['elasticSearch']['fulltextExtractor'])) {
205205
if ($propertyConfiguration['elasticSearch']['fulltextExtractor'] !== '') {
206206
$fulltextExtractionExpression = $propertyConfiguration['elasticSearch']['fulltextExtractor'];
207207

208-
$fulltextIndexOfProperty = $this->evaluateEelExpression($fulltextExtractionExpression, $nodeData, $propertyName, ($nodeData->hasProperty($propertyName) ? $nodeData->getProperty($propertyName) : NULL), $persistenceObjectIdentifier);
208+
$fulltextIndexOfProperty = $this->evaluateEelExpression($fulltextExtractionExpression, $node, $propertyName, ($node->hasProperty($propertyName) ? $node->getProperty($propertyName) : NULL));
209209

210210
if (!is_array($fulltextIndexOfProperty)) {
211-
throw new Exception\IndexingException('The fulltext index for property "' . $propertyName . '" of node "' . $nodeData->getPath() . '" could not be retrieved; the Eel expression "' . $fulltextExtractionExpression . '" is no valid fulltext extraction expression.');
211+
throw new Exception\IndexingException('The fulltext index for property "' . $propertyName . '" of node "' . $node->getPath() . '" could not be retrieved; the Eel expression "' . $fulltextExtractionExpression . '" is no valid fulltext extraction expression.');
212212
}
213213

214214
foreach ($fulltextIndexOfProperty as $bucket => $value) {
@@ -225,13 +225,13 @@ public function indexNode(NodeData $nodeData) {
225225

226226
$document = new ElasticSearchDocument($mappingType,
227227
$nodePropertiesToBeStoredInElasticSearchIndex,
228-
$persistenceObjectIdentifier
228+
$identifier
229229
);
230230

231231
$documentData = $document->getData();
232232

233233
if ($fulltextIndexingEnabledForNode === TRUE) {
234-
if ($this->isFulltextRoot($nodeData)) {
234+
if ($this->isFulltextRoot($node)) {
235235
// for fulltext root documents, we need to preserve the "__fulltext" field. That's why we use the
236236
// "update" API instead of the "index" API, with a custom script internally; as we
237237
// shall not delete the "__fulltext" part of the document if it has any.
@@ -270,31 +270,31 @@ public function indexNode(NodeData $nodeData) {
270270
);
271271
}
272272

273-
$this->updateFulltext($nodeData, $fulltextIndexOfNode);
273+
$this->updateFulltext($node, $fulltextIndexOfNode);
274274
}
275275

276-
$this->logger->log(sprintf('NodeIndexer: Added / updated node %s. Persistence ID: %s', $nodeData->getContextPath(), $persistenceObjectIdentifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
276+
$this->logger->log(sprintf('NodeIndexer: Added / updated node %s. Persistence ID: %s', $node->getContextPath(), $identifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
277277
}
278278

279279
/**
280280
*
281281
*
282-
* @param NodeData $nodeData
282+
* @param Node $node
283283
* @param array $fulltextIndexOfNode
284284
* @return void
285285
*/
286-
protected function updateFulltext(NodeData $nodeData, array $fulltextIndexOfNode) {
287-
if ($nodeData->getWorkspace()->getName() !== 'live' || count($fulltextIndexOfNode) === 0) {
286+
protected function updateFulltext(Node $node, array $fulltextIndexOfNode) {
287+
if ($node->getWorkspace()->getName() !== 'live' || count($fulltextIndexOfNode) === 0) {
288288
// fulltext indexing should only be done in live workspace, and if there's something to index
289289
return;
290290
}
291291

292-
$closestFulltextNode = $nodeData;
292+
$closestFulltextNode = $node;
293293
while (!$this->isFulltextRoot($closestFulltextNode)) {
294294
$closestFulltextNode = $closestFulltextNode->getParent();
295295
if ($closestFulltextNode === NULL) {
296296
// root of hierarchy, no fulltext root found anymore, abort silently...
297-
$this->logger->log('No fulltext root found for ' . $nodeData->getPath(), LOG_WARNING);
297+
$this->logger->log('No fulltext root found for ' . $node->getPath(), LOG_WARNING);
298298
return;
299299
}
300300
}
@@ -303,7 +303,7 @@ protected function updateFulltext(NodeData $nodeData, array $fulltextIndexOfNode
303303
array(
304304
'update' => array(
305305
'_type' => NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($closestFulltextNode->getNodeType()->getName()),
306-
'_id' => $this->persistenceManager->getIdentifierByObject($closestFulltextNode)
306+
'_id' => sha1($closestFulltextNode->getContextPath())
307307
)
308308
),
309309
// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-update.html
@@ -327,13 +327,13 @@ protected function updateFulltext(NodeData $nodeData, array $fulltextIndexOfNode
327327
}
328328
',
329329
'params' => array(
330-
'identifier' => $nodeData->getIdentifier(),
330+
'identifier' => $node->getIdentifier(),
331331
'fulltext' => $fulltextIndexOfNode
332332
),
333333
'upsert' => array(
334334
'__fulltext' => $fulltextIndexOfNode,
335335
'__fulltextParts' => array(
336-
$nodeData->getIdentifier() => $fulltextIndexOfNode
336+
$node->getIdentifier() => $fulltextIndexOfNode
337337
)
338338
)
339339
)
@@ -343,12 +343,12 @@ protected function updateFulltext(NodeData $nodeData, array $fulltextIndexOfNode
343343
/**
344344
* Whether the node has fulltext indexing enabled.
345345
*
346-
* @param NodeData $nodeData
346+
* @param Node $node
347347
* @return boolean
348348
*/
349-
protected function isFulltextEnabled(NodeData $nodeData) {
350-
if ($nodeData->getNodeType()->hasElasticSearch()) {
351-
$elasticSearchSettingsForNode = $nodeData->getNodeType()->getElasticSearch();
349+
protected function isFulltextEnabled(Node $node) {
350+
if ($node->getNodeType()->hasConfiguration('elasticSearch')) {
351+
$elasticSearchSettingsForNode = $node->getNodeType()->getConfiguration('elasticSearch');
352352
if (isset($elasticSearchSettingsForNode['fulltext']['enable']) && $elasticSearchSettingsForNode['fulltext']['enable'] === TRUE) {
353353
return TRUE;
354354
}
@@ -360,12 +360,12 @@ protected function isFulltextEnabled(NodeData $nodeData) {
360360
/**
361361
* Whether the node is configured as fulltext root.
362362
*
363-
* @param NodeData $nodeData
363+
* @param Node $node
364364
* @return boolean
365365
*/
366-
protected function isFulltextRoot(NodeData $nodeData) {
367-
if ($nodeData->getNodeType()->hasElasticSearch()) {
368-
$elasticSearchSettingsForNode = $nodeData->getNodeType()->getElasticSearch();
366+
protected function isFulltextRoot(Node $node) {
367+
if ($node->getNodeType()->hasConfiguration('elasticSearch')) {
368+
$elasticSearchSettingsForNode = $node->getNodeType()->getConfiguration('elasticSearch');
369369
if (isset($elasticSearchSettingsForNode['fulltext']['isRoot']) && $elasticSearchSettingsForNode['fulltext']['isRoot'] === TRUE) {
370370
return TRUE;
371371
}
@@ -375,25 +375,25 @@ protected function isFulltextRoot(NodeData $nodeData) {
375375
}
376376

377377
/**
378-
* schedule node removal into the current bulk request.
378+
* Schedule node removal into the current bulk request.
379379
*
380-
* @param NodeData $nodeData
380+
* @param Node $node
381381
* @return string
382382
*/
383-
public function removeNode(NodeData $nodeData) {
383+
public function removeNode(Node $node) {
384384
// TODO: handle deletion from the fulltext index as well
385-
$persistenceObjectIdentifier = $this->persistenceManager->getIdentifierByObject($nodeData);
385+
$identifier = sha1($node->getContextPath());
386386

387387
$this->currentBulkRequest[] = array(
388388
array(
389389
'delete' => array(
390-
'_type' => NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($nodeData->getNodeType()),
391-
'_id' => $persistenceObjectIdentifier
390+
'_type' => NodeTypeMappingBuilder::convertNodeTypeNameToMappingName($node->getNodeType()),
391+
'_id' => $identifier
392392
)
393393
)
394394
);
395395

396-
$this->logger->log(sprintf('NodeIndexer: Removed node %s from index (node actually removed). Persistence ID: %s', $nodeData->getContextPath(), $persistenceObjectIdentifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
396+
$this->logger->log(sprintf('NodeIndexer: Removed node %s from index (node actually removed). Persistence ID: %s', $node->getContextPath(), $identifier), LOG_DEBUG, NULL, 'ElasticSearch (CR)');
397397
}
398398

399399
/**
@@ -438,21 +438,19 @@ public function flush() {
438438
* TODO: REFACTOR TO Eel package (as this is copy/pasted from TypoScript Runtime)
439439
*
440440
* @param string $expression The Eel expression to evaluate
441-
* @param NodeData $node
441+
* @param Node $node
442442
* @param string $propertyName
443443
* @param mixed $value
444-
* @param string $persistenceObjectIdentifier
445444
* @return mixed The result of the evaluated Eel expression
446445
* @throws Exception
447446
*/
448-
protected function evaluateEelExpression($expression, NodeData $node, $propertyName, $value, $persistenceObjectIdentifier) {
447+
protected function evaluateEelExpression($expression, Node $node, $propertyName, $value) {
449448
$matches = NULL;
450449
if (preg_match(\TYPO3\Eel\Package::EelExpressionRecognizer, $expression, $matches)) {
451450
$contextVariables = array_merge($this->getDefaultContextVariables(), array(
452451
'node' => $node,
453452
'propertyName' => $propertyName,
454-
'value' => $value,
455-
'persistenceObjectIdentifier' => $persistenceObjectIdentifier
453+
'value' => $value
456454
));
457455

458456
$context = new \TYPO3\Eel\Context($contextVariables);

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Indexer/NodeIndexingManager.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Exception;
1515
use Flowpack\ElasticSearch\Domain\Model\Client;
1616
use TYPO3\Flow\Annotations as Flow;
17-
use TYPO3\TYPO3CR\Domain\Model\NodeData;
17+
use TYPO3\TYPO3CR\Domain\Model\Node;
1818

1919
/**
2020
* Indexer for Content Repository Nodes. Manages an indexing queue to allow for deferred indexing.
@@ -64,31 +64,32 @@ public function injectSettings(array $settings) {
6464
/**
6565
* Schedule a node for indexing
6666
*
67-
* @param NodeData $nodeData
67+
* @param Node $node
6868
* @return void
6969
*/
70-
public function indexNode(NodeData $nodeData) {
71-
$this->nodesToBeRemoved->detach($nodeData);
72-
$this->nodesToBeIndexed->attach($nodeData);
70+
public function indexNode(Node $node) {
71+
$this->nodesToBeRemoved->detach($node);
72+
$this->nodesToBeIndexed->attach($node);
7373

7474
$this->flushQueuesIfNeeded();
7575
}
7676

7777
/**
7878
* Schedule a node for removal of the index
7979
*
80-
* @param NodeData $nodeData
80+
* @param Node $node
8181
* @return void
8282
*/
83-
public function removeNode(NodeData $nodeData) {
84-
$this->nodesToBeIndexed->detach($nodeData);
85-
$this->nodesToBeRemoved->attach($nodeData);
83+
public function removeNode(Node $node) {
84+
$this->nodesToBeIndexed->detach($node);
85+
$this->nodesToBeRemoved->attach($node);
8686

8787
$this->flushQueuesIfNeeded();
8888
}
8989

9090
/**
91-
*
91+
* Flush the indexing/removal queues, actually processing them, if the
92+
* maximum indexing batch size has been reached.
9293
*
9394
* @return void
9495
*/

Classes/Flowpack/ElasticSearch/ContentRepositoryAdaptor/Package.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ public function boot(Bootstrap $bootstrap) {
3838
}
3939

4040
/**
41-
* Registers slots for repository signals in order to be able to index nodes
41+
* Registers slots for signals in order to be able to index nodes
4242
*
4343
* @param Bootstrap $bootstrap
4444
*/
4545
public function registerIndexingSlots(Bootstrap $bootstrap) {
46-
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Repository\NodeDataRepository', 'nodeAdded', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'indexNode');
47-
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Repository\NodeDataRepository', 'nodeUpdated', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'indexNode');
48-
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Repository\NodeDataRepository', 'nodeRemoved', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'removeNode');
46+
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Model\Node', 'nodeAdded', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'indexNode');
47+
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Model\Node', 'nodeUpdated', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'indexNode');
48+
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\TYPO3CR\Domain\Model\Node', 'nodeRemoved', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'removeNode');
4949
$bootstrap->getSignalSlotDispatcher()->connect('TYPO3\Flow\Persistence\Doctrine\PersistenceManager', 'allObjectsPersisted', 'Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexingManager', 'flushQueues');
5050
}
5151
}

0 commit comments

Comments
 (0)