Skip to content

Commit e0d7f8f

Browse files
committed
Merge branch 'master' into feature-disable-indexin-per-nodetype-or-namespace
# Conflicts: # Classes/Mapping/NodeTypeMappingBuilder.php
2 parents 70b0e62 + 7d2e2aa commit e0d7f8f

60 files changed

Lines changed: 1299 additions & 1061 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
language: php
2+
sudo: false
3+
git:
4+
depth: 5
5+
submodules: false
6+
addons:
7+
apt:
8+
packages:
9+
- oracle-java8-set-default
210
matrix:
311
include:
4-
- php: 7.0
5-
env: ES=1
6-
- php: 7.0
7-
env: ES=2
8-
- php: 7.1
9-
env: ES=1
10-
- php: 7.1
11-
env: ES=2
12-
sudo: false
12+
- php: 7.2
13+
env: ES=5
14+
1315
before_install:
14-
- export NEOS_TARGET_VERSION=3.0
16+
- export NEOS_TARGET_VERSION=4.0
1517
- cd ..
16-
- if [ "$ES" = 1 ]; then wget --no-check-certificate https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.6.zip && unzip elasticsearch-1.7.6.zip && mv elasticsearch-1.7.6 elasticsearch; fi
17-
- if [ "$ES" = 2 ]; then wget --no-check-certificate https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-2.4.5.zip && unzip elasticsearch-2.4.5.zip && mv elasticsearch-2.4.5 elasticsearch; fi
18+
- if [ "$ES" = 5 ]; then wget --no-check-certificate https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.8.zip && unzip elasticsearch-5.6.8.zip && mv elasticsearch-5.6.8 elasticsearch; fi
1819
- cd elasticsearch
1920
- bin/elasticsearch -d
2021
- cd ..
@@ -29,5 +30,4 @@ install:
2930
- cd neos-base-distribution
3031
script:
3132
- bin/phpunit --colors -c Build/BuildEssentials/PhpUnit/UnitTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Unit
32-
- if [ "$ES" = 1 ]; then FLOW_CONTEXT="Testing/ElasticVersion1" bin/phpunit --colors --stop-on-failure -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Functional; fi
33-
- if [ "$ES" = 2 ]; then FLOW_CONTEXT="Testing/ElasticVersion2" bin/phpunit --colors --stop-on-failure -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Functional; fi
33+
- if [ "$ES" = 5 ]; then FLOW_CONTEXT="Testing/ElasticVersion5" bin/phpunit --colors --stop-on-failure -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Application/Flowpack.ElasticSearch.ContentRepositoryAdaptor/Tests/Functional; fi

Classes/Client/ClientFactory.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ClientFactory
3232
* Create a client
3333
*
3434
* @return Client
35+
* @throws \Flowpack\ElasticSearch\Exception
3536
*/
3637
public function create()
3738
{

Classes/Command/NodeIndexCommandController.php

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
*/
1313

1414
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\Error\ErrorInterface;
15+
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver\NodeTypeMappingBuilderInterface;
1516
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\LoggerInterface;
16-
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Mapping\NodeTypeMappingBuilder;
1717
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Service\ErrorHandlingService;
1818
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Service\IndexWorkspaceTrait;
1919
use Flowpack\ElasticSearch\Domain\Model\Mapping;
@@ -23,13 +23,14 @@
2323
use Neos\ContentRepository\Domain\Repository\NodeDataRepository;
2424
use Neos\ContentRepository\Domain\Repository\WorkspaceRepository;
2525
use Neos\ContentRepository\Domain\Service\ContentDimensionPresetSourceInterface;
26-
use Neos\ContentRepository\Domain\Service\Context;
27-
use Neos\ContentRepository\Domain\Service\ContextFactoryInterface;
2826
use Neos\ContentRepository\Search\Indexer\NodeIndexerInterface;
2927
use Neos\Flow\Annotations as Flow;
3028
use Neos\Flow\Cli\CommandController;
3129
use Neos\Flow\Configuration\ConfigurationManager;
30+
use Neos\Flow\Configuration\Exception\InvalidConfigurationTypeException;
31+
use Neos\Flow\Mvc\Exception\StopActionException;
3232
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
33+
use Neos\Neos\Controller\CreateContentContextTrait;
3334
use Symfony\Component\Yaml\Yaml;
3435

3536
/**
@@ -41,6 +42,8 @@ class NodeIndexCommandController extends CommandController
4142
{
4243
use IndexWorkspaceTrait;
4344

45+
use CreateContentContextTrait;
46+
4447
/**
4548
* @Flow\Inject
4649
* @var ErrorHandlingService
@@ -79,7 +82,7 @@ class NodeIndexCommandController extends CommandController
7982

8083
/**
8184
* @Flow\Inject
82-
* @var NodeTypeMappingBuilder
85+
* @var NodeTypeMappingBuilderInterface
8386
*/
8487
protected $nodeTypeMappingBuilder;
8588

@@ -95,12 +98,6 @@ class NodeIndexCommandController extends CommandController
9598
*/
9699
protected $configurationManager;
97100

98-
/**
99-
* @Flow\Inject
100-
* @var ContextFactoryInterface
101-
*/
102-
protected $contextFactory;
103-
104101
/**
105102
* @var array
106103
*/
@@ -110,6 +107,7 @@ class NodeIndexCommandController extends CommandController
110107
* Called by the Flow object framework after creating the object and resolving all dependencies.
111108
*
112109
* @param integer $cause Creation cause
110+
* @throws InvalidConfigurationTypeException
113111
*/
114112
public function initializeObject($cause)
115113
{
@@ -159,6 +157,7 @@ public function showMappingCommand()
159157
* @param string $identifier
160158
* @param string $workspace
161159
* @return void
160+
* @throws StopActionException
162161
*/
163162
public function indexNodeCommand($identifier, $workspace = null)
164163
{
@@ -226,8 +225,9 @@ public function indexNodeCommand($identifier, $workspace = null)
226225
* @param string $workspace name of the workspace which should be indexed
227226
* @param string $postfix Index postfix, index with the same postfix will be deleted if exist
228227
* @return void
228+
* @throws StopActionException
229229
*/
230-
public function buildCommand($limit = null, $update = false, $workspace = null, $postfix = null)
230+
public function buildCommand($limit = null, $update = false, $workspace = null, $postfix = '')
231231
{
232232
if ($workspace !== null && $this->workspaceRepository->findByIdentifier($workspace) === null) {
233233
$this->logger->log('The given workspace (' . $workspace . ') does not exist.', LOG_ERR);
@@ -303,33 +303,12 @@ public function cleanupCommand()
303303
}
304304
} catch (ApiException $exception) {
305305
$response = json_decode($exception->getResponse());
306-
$this->logger->log(sprintf('Nothing removed. ElasticSearch responded with status %s, saying "%s: %s"', $response->status, $response->error->type, $response->error->reason));
307-
}
308-
}
309-
310-
/**
311-
* Create a ContentContext based on the given workspace name
312-
*
313-
* @param string $workspaceName Name of the workspace to set for the context
314-
* @param array $dimensions Optional list of dimensions and their values which should be set
315-
* @return Context
316-
*/
317-
protected function createContentContext($workspaceName, array $dimensions = [])
318-
{
319-
$contextProperties = [
320-
'workspaceName' => $workspaceName,
321-
'invisibleContentShown' => true,
322-
'inaccessibleContentShown' => true
323-
];
324-
325-
if ($dimensions !== []) {
326-
$contextProperties['dimensions'] = $dimensions;
327-
$contextProperties['targetDimensions'] = array_map(function ($dimensionValues) {
328-
return array_shift($dimensionValues);
329-
}, $dimensions);
306+
if ($response->error instanceof \stdClass) {
307+
$this->logger->log(sprintf('Nothing removed. ElasticSearch responded with status %s, saying "%s: %s"', $response->status, $response->error->type, $response->error->reason));
308+
} else {
309+
$this->logger->log(sprintf('Nothing removed. ElasticSearch responded with status %s, saying "%s"', $response->status, $response->error));
310+
}
330311
}
331-
332-
return $this->contextFactory->create($contextProperties);
333312
}
334313

335314
/**
@@ -338,7 +317,7 @@ protected function createContentContext($workspaceName, array $dimensions = [])
338317
* @param string $postfix
339318
* @return void
340319
*/
341-
protected function createNewIndex($postfix)
320+
protected function createNewIndex(string $postfix)
342321
{
343322
$this->nodeIndexer->setIndexNamePostfix($postfix ?: time());
344323
if ($this->nodeIndexer->getIndex()->exists() === true) {

Classes/Command/NodeTypeCommandController.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* source code.
1212
*/
1313

14+
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
15+
use Neos\ContentRepository\Exception\NodeTypeNotFoundException;
1416
use Neos\Flow\Annotations as Flow;
1517
use Neos\Flow\Cli\CommandController;
1618

@@ -25,7 +27,7 @@ class NodeTypeCommandController extends CommandController
2527
{
2628
/**
2729
* @Flow\Inject
28-
* @var \Neos\ContentRepository\Domain\Service\NodeTypeManager
30+
* @var NodeTypeManager
2931
*/
3032
protected $nodeTypeManager;
3133

@@ -34,6 +36,7 @@ class NodeTypeCommandController extends CommandController
3436
*
3537
* @param string $nodeType the node type to optionally filter for
3638
* @return void
39+
* @throws NodeTypeNotFoundException
3740
*/
3841
public function showCommand($nodeType = null)
3942
{

Classes/Driver/AbstractIndexerDriver.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@
1111
* source code.
1212
*/
1313

14+
use Neos\Flow\Annotations as Flow;
1415
use Neos\ContentRepository\Domain\Model\NodeInterface;
1516

1617
/**
1718
* Abstract Fulltext Indexer Driver
1819
*/
1920
abstract class AbstractIndexerDriver extends AbstractDriver
2021
{
22+
/**
23+
* @Flow\Inject
24+
* @var NodeTypeMappingBuilderInterface
25+
*/
26+
protected $nodeTypeMappingBuilder;
27+
2128
/**
2229
* Whether the node is configured as fulltext root.
2330
*
2431
* @param NodeInterface $node
25-
* @return boolean
32+
* @return bool
2633
*/
27-
protected function isFulltextRoot(NodeInterface $node)
34+
protected function isFulltextRoot(NodeInterface $node): bool
2835
{
2936
if ($node->getNodeType()->hasConfiguration('search')) {
3037
$elasticSearchSettingsForNode = $node->getNodeType()->getConfiguration('search');
@@ -35,4 +42,26 @@ protected function isFulltextRoot(NodeInterface $node)
3542

3643
return false;
3744
}
45+
46+
/**
47+
* @param NodeInterface $node
48+
* @return NodeInterface|null
49+
*/
50+
protected function findClosestFulltextRoot(NodeInterface $node)
51+
{
52+
$closestFulltextNode = $node;
53+
while (!$this->isFulltextRoot($closestFulltextNode)) {
54+
$closestFulltextNode = $closestFulltextNode->getParent();
55+
if ($closestFulltextNode === null) {
56+
// root of hierarchy, no fulltext root found anymore, abort silently...
57+
if ($node->getPath() !== '/' && $node->getPath() !== '/sites') {
58+
$this->logger->log(sprintf('NodeIndexer: No fulltext root found for node %s (%s)', $node->getIdentifier(), $node->getContextPath()), LOG_WARNING, null, 'ElasticSearch (CR)');
59+
}
60+
61+
return null;
62+
}
63+
}
64+
65+
return $closestFulltextNode;
66+
}
3867
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
namespace Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver;
3+
4+
/*
5+
* This file is part of the Flowpack.ElasticSearch.ContentRepositoryAdaptor package.
6+
*
7+
* (c) Contributors of the Neos Project - www.neos.io
8+
*
9+
* This package is Open Source Software. For the full copyright and license
10+
* information, please view the LICENSE file which was distributed with this
11+
* source code.
12+
*/
13+
14+
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
15+
use Neos\Error\Messages\Result;
16+
use Neos\Flow\Annotations as Flow;
17+
use Neos\Flow\Configuration\ConfigurationManager;
18+
use Neos\Flow\Configuration\Exception\InvalidConfigurationTypeException;
19+
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
20+
21+
/**
22+
* Builds the mapping information for Content Repository Node Types in Elasticsearch
23+
*
24+
* @Flow\Scope("singleton")
25+
*/
26+
abstract class AbstractNodeTypeMappingBuilder implements NodeTypeMappingBuilderInterface
27+
{
28+
/**
29+
* The default configuration for a given property type in NodeTypes.yaml, if no explicit elasticSearch section defined there.
30+
*
31+
* @var array
32+
*/
33+
protected $defaultConfigurationPerType;
34+
35+
/**
36+
* @Flow\Inject
37+
* @var NodeTypeManager
38+
*/
39+
protected $nodeTypeManager;
40+
41+
/**
42+
* @var Result
43+
*/
44+
protected $lastMappingErrors;
45+
46+
/**
47+
* @Flow\Inject
48+
* @var ConfigurationManager
49+
*/
50+
protected $configurationManager;
51+
52+
/**
53+
* Called by the Flow object framework after creating the object and resolving all dependencies.
54+
*
55+
* @param integer $cause Creation cause
56+
* @throws InvalidConfigurationTypeException
57+
*/
58+
public function initializeObject($cause)
59+
{
60+
if ($cause === ObjectManagerInterface::INITIALIZATIONCAUSE_CREATED) {
61+
$settings = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.ContentRepository.Search');
62+
$this->defaultConfigurationPerType = $settings['defaultConfigurationPerType'];
63+
}
64+
}
65+
66+
/**
67+
* Converts a Content Repository Node Type name into a name which can be used for an Elasticsearch Mapping
68+
*
69+
* @param string $nodeTypeName
70+
* @return string
71+
*/
72+
public function convertNodeTypeNameToMappingName(string $nodeTypeName): string
73+
{
74+
return str_replace('.', '-', $nodeTypeName);
75+
}
76+
77+
/**
78+
* @return Result
79+
*/
80+
public function getLastMappingErrors()
81+
{
82+
return $this->lastMappingErrors;
83+
}
84+
}

Classes/Driver/AbstractQuery.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,22 @@ public function aggregation($name, array $aggregationDefinition, $parentPath = '
109109
}
110110
}
111111

112+
/**
113+
* {@inheritdoc}
114+
* @throws Exception\QueryBuildingException
115+
*/
116+
public function moreLikeThis(array $like, array $fields = [], $options = [])
117+
{
118+
$moreLikeThis = $options;
119+
$moreLikeThis['like'] = $like;
120+
121+
if (!empty($fields)) {
122+
$moreLikeThis['fields'] = $fields;
123+
}
124+
125+
$this->appendAtPath('query.bool.filter.bool.must', ['more_like_this' => $moreLikeThis]);
126+
}
127+
112128
/**
113129
* This is an low level method for internal usage.
114130
*
@@ -119,7 +135,7 @@ public function aggregation($name, array $aggregationDefinition, $parentPath = '
119135
* @param string $parentPath The parent path to add the sub aggregation to
120136
* @param string $name The name to identify the resulting aggregation
121137
* @param array $aggregationConfiguration
122-
* @return QueryInterface
138+
* @return void
123139
* @throws Exception\QueryBuildingException
124140
*/
125141
protected function addSubAggregation($parentPath, $name, $aggregationConfiguration)

0 commit comments

Comments
 (0)