Skip to content

Commit 32fa434

Browse files
Merge pull request #79 from dlubitz/neos-9
!!! FEATURE: Neos 9.0 compatibility
2 parents bdb8bec + b80e9d9 commit 32fa434

File tree

12 files changed

+74
-63
lines changed

12 files changed

+74
-63
lines changed

Classes/Controller/AjaxSearchController.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Flowpack\SearchPlugin\Controller;
34

45
/*
@@ -11,8 +12,7 @@
1112
* source code.
1213
*/
1314

14-
use Neos\ContentRepository\Domain\Model\NodeInterface;
15-
use Neos\Flow\Annotations as Flow;
15+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
1616
use Neos\Flow\Mvc\Controller\ActionController;
1717
use Neos\Neos\View\FusionView;
1818

@@ -27,11 +27,11 @@ class AjaxSearchController extends ActionController
2727
protected $defaultViewObjectName = FusionView::class;
2828

2929
/**
30-
* @param NodeInterface $node
30+
* @param Node $node
3131
*
3232
* @return void
3333
*/
34-
public function searchAction(NodeInterface $node)
34+
public function searchAction(Node $node)
3535
{
3636
/* @var FusionView $view */
3737
$view = $this->view;

Classes/Controller/SuggestController.php

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Flowpack\SearchPlugin\Controller;
34

45
/*
@@ -17,16 +18,16 @@
1718
use Flowpack\SearchPlugin\Suggestion\SuggestionContextInterface;
1819
use Flowpack\SearchPlugin\Utility\SearchTerm;
1920
use Neos\Cache\Frontend\VariableFrontend;
20-
use Neos\ContentRepository\Domain\Model\NodeInterface;
21+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
22+
use Neos\ContentRepository\Core\SharedModel\Node\NodeAddress;
23+
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
24+
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
2125
use Neos\Flow\Annotations as Flow;
2226
use Neos\Flow\Mvc\Controller\ActionController;
2327
use Neos\Flow\Mvc\View\JsonView;
24-
use Neos\Neos\Controller\CreateContentContextTrait;
2528

2629
class SuggestController extends ActionController
2730
{
28-
use CreateContentContextTrait;
29-
3031
/**
3132
* @var ElasticSearchClient
3233
*/
@@ -62,6 +63,10 @@ class SuggestController extends ActionController
6263
*/
6364
protected $searchAsYouTypeSettings = [];
6465

66+
67+
#[Flow\Inject()]
68+
protected ContentRepositoryRegistry $contentRepositoryRegistry;
69+
6570
public function initializeObject()
6671
{
6772
if ($this->objectManager->isRegistered(ElasticSearchClient::class)) {
@@ -72,13 +77,13 @@ public function initializeObject()
7277

7378
/**
7479
* @param string $term
75-
* @param string $contextNodeIdentifier
80+
* @param string $contextNode
7681
* @param string $dimensionCombination
7782
* @return void
7883
* @throws QueryBuildingException
7984
* @throws \Neos\Flow\Persistence\Exception\IllegalObjectTypeException
8085
*/
81-
public function indexAction(string $term = '', string $contextNodeIdentifier = '', string $dimensionCombination = null): void
86+
public function indexAction(string $term = '', string $contextNode = ''): void
8287
{
8388
if ($this->elasticSearchClient === null) {
8489
throw new \RuntimeException('The SuggestController needs an ElasticSearchClient, it seems you run without the flowpack/elasticsearch-contentrepositoryadaptor package, though.', 1487189823);
@@ -95,7 +100,8 @@ public function indexAction(string $term = '', string $contextNodeIdentifier = '
95100
return;
96101
}
97102

98-
$requestJson = $this->buildRequestForTerm($term, $contextNodeIdentifier, $dimensionCombination);
103+
$contextNodeAddress = NodeAddress::fromJsonString($contextNode);
104+
$requestJson = $this->buildRequestForTerm($term, $contextNodeAddress);
99105

100106
try {
101107
$response = $this->elasticSearchClient->getIndex()->request('POST', '/_search', [], $requestJson)->getTreatedContent();
@@ -110,16 +116,16 @@ public function indexAction(string $term = '', string $contextNodeIdentifier = '
110116

111117
/**
112118
* @param string $term
113-
* @param string $contextNodeIdentifier
119+
* @param string $contextNode
114120
* @param string|null $dimensionCombination
115121
* @return string
116122
* @throws QueryBuildingException
117123
* @throws \Neos\Cache\Exception
118124
* @throws \Neos\Flow\Persistence\Exception\IllegalObjectTypeException
119125
*/
120-
protected function buildRequestForTerm(string $term, string $contextNodeIdentifier, string $dimensionCombination = null): string
126+
protected function buildRequestForTerm(string $term, NodeAddress $contextNodeAddress): string
121127
{
122-
$cacheKey = $contextNodeIdentifier . '-' . md5($dimensionCombination);
128+
$cacheKey = $contextNodeAddress->aggregateId->value . '-' . $contextNodeAddress->dimensionSpacePoint->hash;
123129
$termPlaceholder = '---term-soh2gufuNi---';
124130
$term = strtolower($term);
125131

@@ -128,11 +134,11 @@ protected function buildRequestForTerm(string $term, string $contextNodeIdentifi
128134
$suggestTerm = SearchTerm::sanitize(explode(' ', $term)[0]);
129135

130136
if (!$this->elasticSearchQueryTemplateCache->has($cacheKey)) {
131-
$contentContext = $this->createContentContext('live', $dimensionCombination ? json_decode($dimensionCombination, true) : []);
132-
$contextNode = $contentContext->getNodeByIdentifier($contextNodeIdentifier);
137+
$subgraph = $this->contentRepositoryRegistry->get($contextNodeAddress->contentRepositoryId)->getContentSubgraph(WorkspaceName::forLive(), $contextNodeAddress->dimensionSpacePoint);
138+
$contextNode = $subgraph->findNodeById($contextNodeAddress->aggregateId);
133139

134-
if (!$contextNode instanceof NodeInterface) {
135-
throw new \Exception(sprintf('The context node for search with identifier %s could not be found', $contextNodeIdentifier), 1634467679);
140+
if (!$contextNode instanceof Node) {
141+
throw new \Exception(sprintf('The context node for search with identifier %s could not be found', $contextNodeAddress->aggregateId->value), 1634467679);
136142
}
137143

138144
$sourceFields = array_filter($this->searchAsYouTypeSettings['suggestions']['sourceFields'] ?? ['neos_path']);
@@ -178,7 +184,7 @@ protected function buildRequestForTerm(string $term, string $contextNodeIdentifi
178184

179185
$requestTemplate = json_encode($request);
180186

181-
$this->elasticSearchQueryTemplateCache->set($contextNodeIdentifier, $requestTemplate);
187+
$this->elasticSearchQueryTemplateCache->set($contextNodeAddress->aggregateId->value, $requestTemplate);
182188
} else {
183189
$requestTemplate = $this->elasticSearchQueryTemplateCache->get($cacheKey);
184190
}

Classes/EelHelper/SuggestionIndexHelper.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Flowpack\SearchPlugin\Exception;
1717
use Flowpack\SearchPlugin\Suggestion\SuggestionContextInterface;
1818
use Flowpack\SearchPlugin\Utility\SearchTerm;
19-
use Neos\ContentRepository\Domain\Model\NodeInterface;
19+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
2020
use Neos\Eel\ProtectedContextAwareInterface;
2121
use Neos\Flow\Annotations as Flow;
2222

@@ -26,12 +26,6 @@
2626
class SuggestionIndexHelper implements ProtectedContextAwareInterface
2727
{
2828

29-
/**
30-
* Rhe length of '/sites/'
31-
* @var int
32-
*/
33-
protected const SITES_OFFSET = 7;
34-
3529
/**
3630
* @Flow\Inject
3731
* @var SuggestionContextInterface
@@ -52,7 +46,7 @@ public function build($input, $weight = 1): array
5246
];
5347
}
5448

55-
public function buildContext(NodeInterface $node): string
49+
public function buildContext(Node $node): string
5650
{
5751
return (string)($this->suggestionContext->buildForIndex($node));
5852
}

Classes/Suggestion/SuggestionContext.php

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,41 @@
1313
* source code.
1414
*/
1515

16-
use Neos\ContentRepository\Domain\Model\NodeInterface;
16+
use Neos\ContentRepository\Core\NodeType\NodeTypeNames;
17+
use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\FindClosestNodeFilter;
18+
use Neos\ContentRepository\Core\Projection\ContentGraph\Filter\NodeType\NodeTypeCriteria;
19+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
20+
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
21+
use Neos\Flow\Annotations as Flow;
22+
use Neos\Neos\Domain\Service\NodeTypeNameFactory;
23+
use Neos\Neos\Domain\SubtreeTagging\NeosSubtreeTag;
1724

1825
class SuggestionContext implements SuggestionContextInterface
1926
{
20-
21-
/**
22-
* Rhe length of '/sites/'
23-
* @var int
24-
*/
25-
protected const SITES_OFFSET = 7;
26-
2727
/**
2828
* @var array
2929
*/
3030
protected $contextValues = [];
3131

32-
public function buildForIndex(NodeInterface $node): SuggestionContextInterface
32+
#[Flow\Inject]
33+
protected ContentRepositoryRegistry $contentRepositoryRegistry;
34+
35+
public function buildForIndex(Node $node): SuggestionContextInterface
3336
{
3437
$this->contextValues = [
3538
'siteName' => $this->getSiteName($node),
36-
'workspace' => $node->getWorkspace()->getName(),
37-
'isHidden' => $node->isHidden() ? 'hidden' : 'visible',
39+
'workspace' => $node->workspaceName->value,
40+
'isHidden' => $node->tags->contain(NeosSubtreeTag::disabled()) ? 'hidden' : 'visible',
3841
];
3942

4043
return $this;
4144
}
4245

43-
public function buildForSearch(NodeInterface $node): SuggestionContextInterface
46+
public function buildForSearch(Node $node): SuggestionContextInterface
4447
{
4548
$this->contextValues = [
4649
'siteName' => $this->getSiteName($node),
47-
'workspace' => $node->getWorkspace()->getName(),
50+
'workspace' => $node->workspaceName->value,
4851
'isHidden' => 'visible',
4952
];
5053

@@ -62,11 +65,20 @@ public function __toString()
6265
}
6366

6467
/**
65-
* @param NodeInterface $node
68+
* @param Node $node
6669
* @return string
6770
*/
68-
protected function getSiteName(NodeInterface $node): string
71+
protected function getSiteName(Node $node): string
6972
{
70-
return substr($node->getPath(), self::SITES_OFFSET, strpos($node->getPath() . '/', '/', self::SITES_OFFSET) - self::SITES_OFFSET);
73+
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
74+
$siteNode = $subgraph->findClosestNode($node->aggregateId, FindClosestNodeFilter::create(
75+
NodeTypeCriteria::createWithAllowedNodeTypeNames(
76+
NodeTypeNames::with(
77+
NodeTypeNameFactory::forSite()
78+
)
79+
)
80+
));
81+
82+
return $siteNode->name->value;
7183
}
7284
}

Classes/Suggestion/SuggestionContextInterface.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,21 @@
1313

1414
namespace Flowpack\SearchPlugin\Suggestion;
1515

16-
use Neos\ContentRepository\Domain\Model\NodeInterface;
16+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
1717

1818
interface SuggestionContextInterface
1919
{
20-
2120
/**
2221
* Build the context from a given node
23-
* @param NodeInterface $node
22+
* @param Node $node
2423
*/
25-
public function buildForIndex(NodeInterface $node): SuggestionContextInterface;
24+
public function buildForIndex(Node $node): SuggestionContextInterface;
2625

2726
/**
2827
* Build the context from a given node
29-
* @param NodeInterface $node
28+
* @param Node $node
3029
*/
31-
public function buildForSearch(NodeInterface $node): SuggestionContextInterface;
30+
public function buildForSearch(Node $node): SuggestionContextInterface;
3231

3332
/**
3433
* Returns the calculated context identifier
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<div{attributes -> f:format.raw()}>
22
{searchResultRenderer -> f:format.raw()}
3-
</div>
3+
</div>

Resources/Private/Fusion/Content/SearchPlugin/Form/Form.fusion

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
prototype(Flowpack.SearchPlugin:Search.Form) < prototype(Neos.Fusion:Template) {
22
node = ${site}
3-
dimensionCombination = ${Json.stringify(this.node.context.dimensions)}
43
templatePath = 'resource://Flowpack.SearchPlugin/Private/Fusion/Content/SearchPlugin/Form/Form.html'
54

65
inputClassNames = ''
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<form method="GET">
22
<input type="search" name="search" value="{searchWord}" class="{inputClassNames}" autocomplete="off"
33
placeholder="{f:translate(id: 'search', package: 'Flowpack.SearchPlugin')}"
4-
data-autocomplete-source="{f:uri.action(action: 'index', controller: 'Suggest', package: 'Flowpack.SearchPlugin', format: 'json', absolute: 1, arguments: {contextNodeIdentifier: node.identifier, dimensionCombination: dimensionCombination})}"/>
4+
data-autocomplete-source="{f:uri.action(action: 'index', controller: 'Suggest', package: 'Flowpack.SearchPlugin', format: 'json', absolute: 1, arguments: {contextNode: node})}"/>
55
<button type="submit">{f:translate(id: 'search', package: 'Flowpack.SearchPlugin')}</button>
66
</form>

Resources/Private/Fusion/Content/SearchPlugin/Search/Search.fusion

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ prototype(Flowpack.SearchPlugin:Search) < prototype(Neos.Neos:Content) {
88

99
searchForm = Flowpack.SearchPlugin:Search.Form
1010

11-
configuration = Neos.Fusion:RawArray {
11+
configuration = Neos.Fusion:DataStructure {
1212
itemsPerPage = 25
1313
insertAbove = false
1414
insertBelow = true

Resources/Private/Fusion/Helper/ResultRendering/ResultRendering.fusion

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
prototype(Flowpack.SearchPlugin:SingleResult) < prototype(Neos.Fusion:Case) {
22
default {
33
condition = Neos.Fusion:CanRender {
4-
type = ${node.nodeType.name + 'SearchResult'}
4+
type = ${node.nodeTypeName + 'SearchResult'}
55
}
6-
type = ${node.nodeType.name + 'SearchResult'}
6+
type = ${node.nodeTypeName + 'SearchResult'}
77
}
88

99
fallback {

0 commit comments

Comments
 (0)