Skip to content

Commit ff404e2

Browse files
authored
Merge pull request #32 from kdambekalns/task/neos-9.0-compatibility
Neos 9.0 compatibility
2 parents 1c09d5a + 59416c0 commit ff404e2

File tree

25 files changed

+225
-205
lines changed

25 files changed

+225
-205
lines changed

Classes/Command/AtomImportCommandController.php

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@
1313
* source code.
1414
*/
1515

16-
use Neos\ContentRepository\Domain\Model\NodeInterface;
17-
use Neos\ContentRepository\Domain\Model\NodeTemplate;
18-
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
19-
use Neos\ContentRepository\Exception\NodeException;
20-
use Neos\ContentRepository\Exception\NodeExistsException;
21-
use Neos\ContentRepository\Exception\NodeTypeNotFoundException;
22-
use Neos\ContentRepository\Utility;
23-
use Neos\Eel\Exception;
16+
use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
17+
use Neos\ContentRepository\Core\NodeType\NodeTypeName;
18+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
19+
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
20+
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
21+
use Neos\ContentRepository\Core\SharedModel\Node\NodeName;
22+
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
23+
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
2424
use Neos\Eel\FlowQuery\FlowQuery;
2525
use Neos\Flow\Annotations as Flow;
2626
use Neos\Flow\Cli\CommandController;
27-
use Neos\Neos\Domain\Service\ContentContextFactory;
27+
use Neos\Rector\ContentRepository90\Legacy\LegacyContextStub;
2828

2929
/**
3030
* BlogCommand command controller for the RobertLemke.Plugin.Blog package
@@ -33,27 +33,12 @@
3333
*/
3434
class AtomImportCommandController extends CommandController
3535
{
36-
/**
37-
* @Flow\Inject
38-
* @var NodeTypeManager
39-
*/
40-
protected $nodeTypeManager;
36+
protected Node $blogNode;
4137

42-
/**
43-
* @Flow\Inject
44-
* @var ContentContextFactory
45-
*/
46-
protected $contentContextFactory;
38+
protected array $tagNodes = [];
4739

48-
/**
49-
* @var NodeInterface
50-
*/
51-
protected $blogNode;
52-
53-
/**
54-
* @var array
55-
*/
56-
protected $tagNodes = [];
40+
#[Flow\Inject]
41+
protected ContentRepositoryRegistry $contentRepositoryRegistry;
5742

5843
/**
5944
* Imports atom data into the blog
@@ -62,10 +47,6 @@ class AtomImportCommandController extends CommandController
6247
* @param string $targetNode The target node (expressed as a FlowQuery find condition)
6348
* @param string $atomFile The atom file to import
6449
* @return void
65-
* @throws NodeException
66-
* @throws NodeExistsException
67-
* @throws NodeTypeNotFoundException
68-
* @throws Exception
6950
*/
7051
public function migrateCommand(string $workspace, string $targetNode, string $atomFile): void
7152
{
@@ -74,10 +55,15 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
7455
$this->quit(1);
7556
}
7657

77-
$context = $this->contentContextFactory->create(['workspaceName' => $workspace]);
78-
$q = new FlowQuery([$context->getRootNode()]);
58+
$context = new LegacyContextStub(['workspaceName' => $workspace]);
59+
// TODO 9.0 migration: !! MEGA DIRTY CODE! Ensure to rewrite this; by getting rid of LegacyContextStub.
60+
$contentRepository = $this->contentRepositoryRegistry->get(ContentRepositoryId::fromString('default'));
61+
$workspace = $contentRepository->findWorkspaceByName(WorkspaceName::fromString('live'));
62+
$rootNodeAggregate = $contentRepository->getContentGraph($workspace->workspaceName)->findRootNodeAggregateByType(NodeTypeName::fromString('Neos.Neos:Sites'));
63+
$subgraph = $contentRepository->getContentGraph($workspace->workspaceName)->getSubgraph(DimensionSpacePoint::fromLegacyDimensionArray($context->dimensions ?? []), $context->invisibleContentShown ? VisibilityConstraints::withoutRestrictions() : VisibilityConstraints::default());
64+
$q = new FlowQuery([$subgraph->findNodeById($rootNodeAggregate->nodeAggregateId)]);
7965
$this->blogNode = $q->find($targetNode)->get(0);
80-
if (!($this->blogNode instanceof NodeInterface)) {
66+
if (!($this->blogNode instanceof Node)) {
8167
$this->outputLine('<error>Target node not found.</error>');
8268
$this->quit(1);
8369
}
@@ -93,15 +79,15 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
9379
$items = $parser->get_items();
9480

9581
$comments = [];
96-
/** @var $item \SimplePie_Item */
82+
/** @var \SimplePie_Item $item */
9783
foreach ($items as $item) {
9884
$categories = $item->get_categories();
9985

10086
if (!is_array($categories)) {
10187
continue;
10288
}
10389

104-
/** @var $category \SimplePie_Category */
90+
/** @var \SimplePie_Category $category */
10591
foreach ($categories as $category) {
10692
if ($category->get_term() === 'http://schemas.google.com/blogger/2008/kind#comment') {
10793
$inReplyTo = current($item->get_item_tags('http://purl.org/syndication/thread/1.0', 'in-reply-to'));
@@ -110,9 +96,10 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
11096
}
11197
}
11298
}
99+
$contentRepository = $this->contentRepositoryRegistry->get(ContentRepositoryId::fromString('default'));
113100

114-
$textNodeType = $this->nodeTypeManager->getNodeType('Neos.NodeTypes:Text');
115-
$commentNodeType = $this->nodeTypeManager->getNodeType('RobertLemke.Plugin.Blog:Content.Comment');
101+
$textNodeType = $contentRepository->getNodeTypeManager()->getNodeType('Neos.NodeTypes:Text');
102+
$commentNodeType = $contentRepository->getNodeTypeManager()->getNodeType('RobertLemke.Plugin.Blog:Content.Comment');
116103
$counter = 0;
117104
foreach ($parser->get_items() as $item) {
118105
$categories = $item->get_categories();
@@ -134,8 +121,9 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
134121
continue;
135122
}
136123

124+
// TODO 9.0 migration: !! NodeTemplate is removed in Neos 9.0. Use the "CreateNodeAggregateWithNode" command to create new nodes or "CreateNodeVariant" command to create variants of an existing node in other dimensions.
137125
$nodeTemplate = new NodeTemplate();
138-
$nodeTemplate->setNodeType($this->nodeTypeManager->getNodeType('RobertLemke.Plugin.Blog:Document.Post'));
126+
$nodeTemplate->setNodeType($contentRepository->getNodeTypeManager()->getNodeType('RobertLemke.Plugin.Blog:Document.Post'));
139127
$nodeTemplate->setProperty('title', $item->get_title());
140128
$nodeTemplate->setProperty('author', $item->get_author()->get_name());
141129
$published = new \DateTime();
@@ -144,15 +132,15 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
144132
$nodeTemplate->setProperty('tags', $this->getTagNodes($tags));
145133

146134
$slug = strtolower(str_replace([' ', ',', ':', 'ü', 'à', 'é', '?', '!', '[', ']', '.', '\''], ['-', '', '', 'u', 'a', 'e', '', '', '', '', '-', ''], $item->get_title()));
147-
/** @var NodeInterface $postNode */
135+
/** @var Node $postNode */
148136
$postNode = $this->blogNode->createNodeFromTemplate($nodeTemplate, $slug);
149137
$postNode->getNode('main')->createNode(uniqid('node'), $textNodeType)->setProperty('text', $item->get_content());
150138

151139
$postComments = $comments[$item->get_id()] ?? [];
152140
if ($postComments !== []) {
153-
/** @var NodeInterface $commentsNode */
141+
/** @var Node $commentsNode */
154142
$commentsNode = $postNode->getNode('comments');
155-
/** @var $postComment \SimplePie_Item */
143+
/** @var \SimplePie_Item $postComment */
156144
foreach ($postComments as $postComment) {
157145
$commentNode = $commentsNode->createNode(uniqid('comment-', true), $commentNodeType);
158146
$commentNode->setProperty('author', html_entity_decode($postComment->get_author()->get_name(), ENT_QUOTES, 'utf-8'));
@@ -164,9 +152,7 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
164152
$commentNode->setProperty('text', $commentText);
165153
$commentNode->setProperty('spam', false);
166154
$previousCommentNode = $commentNode;
167-
if ($previousCommentNode !== null) {
168-
$commentNode->moveAfter($previousCommentNode);
169-
}
155+
$commentNode->moveAfter($previousCommentNode);
170156
}
171157
}
172158

@@ -179,19 +165,18 @@ public function migrateCommand(string $workspace, string $targetNode, string $at
179165

180166
/**
181167
* @param array $tags
182-
* @return array<NodeInterface>
183-
* @throws NodeExistsException
184-
* @throws NodeTypeNotFoundException
168+
* @return array<Node>
185169
*/
186170
protected function getTagNodes(array $tags): array
187171
{
188172
$tagNodes = [];
189173

190174
foreach ($tags as $tag) {
191175
if (!isset($this->tagNodes[$tag])) {
192-
$tagNodeType = $this->nodeTypeManager->getNodeType('RobertLemke.Plugin.Blog:Document.Tag');
176+
$contentRepository = $this->contentRepositoryRegistry->get(ContentRepositoryId::fromString('default'));
177+
$tagNodeType = $contentRepository->getNodeTypeManager()->getNodeType('RobertLemke.Plugin.Blog:Document.Tag');
193178

194-
$tagNode = $this->blogNode->createNode(Utility::renderValidNodeName($tag), $tagNodeType);
179+
$tagNode = $this->blogNode->createNode(NodeName::fromString($tag)->value, $tagNodeType);
195180
$tagNode->setProperty('title', $tag);
196181
$this->tagNodes[$tag] = $tagNode;
197182
}

Classes/Eel/Helper/Teaser.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
namespace RobertLemke\Plugin\Blog\Eel\Helper;
55

6-
use Neos\Flow\Annotations as Flow;
7-
use Neos\ContentRepository\Domain\Model\NodeInterface;
6+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
87
use Neos\Eel\ProtectedContextAwareInterface;
8+
use Neos\Flow\Annotations as Flow;
99
use RobertLemke\Plugin\Blog\Service\ContentService;
1010

1111
class Teaser implements ProtectedContextAwareInterface
@@ -16,7 +16,7 @@ class Teaser implements ProtectedContextAwareInterface
1616
*/
1717
protected $contentService;
1818

19-
public function getCroppedTeaser(NodeInterface $node, int $maximumLength = 500): string
19+
public function getCroppedTeaser(Node $node, int $maximumLength = 500): string
2020
{
2121
return $this->contentService->renderTeaser($node, $maximumLength);
2222
}

Classes/Runtime/Action/CreateCommentAction.php

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,82 +3,98 @@
33

44
namespace RobertLemke\Plugin\Blog\Runtime\Action;
55

6+
use Neos\ContentRepository\Core\DimensionSpace\OriginDimensionSpacePoint;
7+
use Neos\ContentRepository\Core\Feature\NodeCreation\Command\CreateNodeAggregateWithNode;
8+
use Neos\ContentRepository\Core\Feature\NodeModification\Dto\PropertyValuesToWrite;
9+
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
10+
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
11+
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
12+
use Neos\ContentRepository\Core\SharedModel\Node\NodeName;
13+
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
14+
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
615
use Neos\Flow\Annotations as Flow;
7-
use Neos\ContentRepository\Domain\Model\NodeInterface;
8-
use Neos\ContentRepository\Domain\NodeAggregate\NodeName;
9-
use Neos\ContentRepository\Domain\Model\NodeTemplate;
10-
use Neos\ContentRepository\Domain\Service\NodeService;
11-
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
12-
use Neos\ContentRepository\Domain\Utility\NodePaths;
13-
use Neos\Fusion\Form\Runtime\Action\AbstractAction;
1416
use Neos\Flow\Mvc\ActionResponse;
17+
use Neos\Fusion\Form\Runtime\Action\AbstractAction;
1518
use Neos\Fusion\Form\Runtime\Domain\Exception\ActionException;
16-
use Neos\Neos\Controller\CreateContentContextTrait;
1719
use RobertLemke\Akismet\Exception\ConnectionException;
1820
use RobertLemke\Akismet\Service;
1921

2022

2123
class CreateCommentAction extends AbstractAction
2224
{
23-
use CreateContentContextTrait;
24-
2525
#[Flow\Inject]
2626
protected Service $akismetService;
2727

2828
#[Flow\Inject]
29-
protected NodeTypeManager $nodeTypeManager;
30-
31-
#[Flow\Inject]
32-
protected NodeService $nodeService;
29+
protected ContentRepositoryRegistry $contentRepositoryRegistry;
3330

3431
/**
3532
* @return ActionResponse|null
33+
* @throws ActionException
3634
*/
3735
public function perform(): ?ActionResponse
3836
{
39-
$response = new ActionResponse();
40-
4137
$author = $this->options['author'] ?? null;
4238
$text = $this->options['text'] ?? null;
4339
$emailAddress = $this->options['emailAddress'] ?? null;
4440
$postNodePath = $this->options['postNode'] ?? null;
4541

42+
// TODO 9.0 migration: !! CreateContentContextTrait::createContentContext() is removed in Neos 9.0.
4643
$contentContext = $this->createContentContext('live', []);
4744
$postNode = $contentContext->getNode($postNodePath);
4845

4946
if ($postNode === null) {
5047
throw new ActionException('Required parameters missing', 1740574436);
5148
}
5249

53-
$textNodeType = $this->nodeTypeManager->getNodeType('RobertLemke.Plugin.Blog:Content.Comment');
54-
$nodeTemplate = new NodeTemplate();
55-
$nodeTemplate->setNodeType($textNodeType);
56-
$nodeTemplate->setProperty('author', htmlspecialchars($author));
57-
$nodeTemplate->setProperty('text', htmlspecialchars($text));
58-
$nodeTemplate->setProperty('emailAddress', htmlspecialchars($emailAddress));
59-
$nodeTemplate->setProperty('spam', false);
60-
61-
$commentNode = $postNode
62-
->findNamedChildNode(NodeName::fromString('comments'))
63-
->createNodeFromTemplate($nodeTemplate, NodePaths::generateRandomNodeName());
64-
65-
$commentNode->setProperty('datePublished', new \DateTime());
66-
50+
$isSpam = false;
6751
try {
6852
if ($this->akismetService->isCommentSpam('', $text, 'comment', $author, $emailAddress)) {
69-
$commentNode->setProperty('spam', true);
53+
$isSpam = true;
7054
}
7155
} catch (ConnectionException $e) {
72-
throw new ActionException('Akismet service not available', 1740575405);
56+
throw new ActionException('Akismet service not available', 1740575405, $e);
7357
}
7458

75-
$this->emitCommentCreated($commentNode, $postNode);
59+
$contentRepository = $this->contentRepositoryRegistry->get(ContentRepositoryId::fromString('default'));
60+
$textNodeType = $contentRepository->getNodeTypeManager()->getNodeType('RobertLemke.Plugin.Blog:Content.Comment');
61+
$commentsNode = $postNode->findNamedChildNode(NodeName::fromString('comments'));
62+
63+
// TODO 9.0 migration: Fix this for real
64+
$contentRepository->handle(CreateNodeAggregateWithNode::create(
65+
WorkspaceName::forLive(),
66+
NodeAggregateId::create(),
67+
$textNodeType?->name,
68+
OriginDimensionSpacePoint::fromDimensionSpacePoint($arbitraryRootDimensionSpacePoint),
69+
$commentsNode->aggregateId,
70+
null,
71+
PropertyValuesToWrite::fromArray([
72+
'author' => htmlspecialchars($author),
73+
'text' => htmlspecialchars($text),
74+
'emailAddress' => htmlspecialchars($emailAddress),
75+
'spam' => $isSpam,
76+
'datePublished' => new \DateTime(),
77+
])
78+
));
79+
80+
$this->emitCommentCreated(
81+
[
82+
'author' => htmlspecialchars($author),
83+
'text' => htmlspecialchars($text),
84+
'emailAddress' => htmlspecialchars($emailAddress),
85+
'spam' => $isSpam,
86+
'datePublished' => new \DateTime(),
87+
],
88+
$postNode
89+
);
90+
91+
$response = new ActionResponse();
7692
$response->setContent($this->options['message']);
7793
return $response;
7894
}
7995

8096
#[Flow\Signal]
81-
protected function emitCommentCreated(NodeInterface $commentNode, NodeInterface $postNode): void
97+
protected function emitCommentCreated(array $comment, Node $postNode): void
8298
{
8399
}
84100
}

0 commit comments

Comments
 (0)