Skip to content

Commit eb8fbe9

Browse files
author
Marvin Kuhn
committed
Initial commit
0 parents  commit eb8fbe9

File tree

14 files changed

+466
-0
lines changed

14 files changed

+466
-0
lines changed

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; This file is for unifying the coding style for different editors and IDEs.
2+
; More information at http://editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
indent_size = 4
9+
indent_style = space
10+
end_of_line = lf
11+
insert_final_newline = true
12+
trim_trailing_whitespace = true
13+
14+
[.html,.yml,.yaml]
15+
indent_size = 2
16+
17+
[*.xlf]
18+
insert_final_newline = false
19+
20+
[*.md]
21+
trim_trailing_whitespace = false

Classes/Dto/CommentDto.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
namespace Breadlesscode\Commentable\Dto;
3+
4+
class CommentDto
5+
{
6+
/**
7+
* @var string
8+
*/
9+
protected $email;
10+
11+
/**
12+
* @var string
13+
*/
14+
protected $name;
15+
16+
/**
17+
* @var string
18+
*/
19+
protected $content;
20+
21+
/**
22+
* @var boolean
23+
*/
24+
protected $isHidden;
25+
26+
/**
27+
* @var \DateTime
28+
*/
29+
protected $createdAt;
30+
31+
public function __construct()
32+
{
33+
$this->createdAt = new \DateTime('now');
34+
}
35+
36+
/**
37+
* @return string
38+
*/
39+
public function getEmail(): string
40+
{
41+
return $this->email;
42+
}
43+
44+
/**
45+
* @param string $email
46+
*/
47+
public function setEmail(string $email): void
48+
{
49+
$this->email = $email;
50+
}
51+
52+
/**
53+
* @return string
54+
*/
55+
public function getName(): string
56+
{
57+
return $this->name;
58+
}
59+
60+
/**
61+
* @param string $name
62+
*/
63+
public function setName(string $name): void
64+
{
65+
$this->name = $name;
66+
}
67+
68+
/**
69+
* @return string
70+
*/
71+
public function getContent(): string
72+
{
73+
return $this->content;
74+
}
75+
76+
/**
77+
* @param string $content
78+
*/
79+
public function setContent(string $content): void
80+
{
81+
$this->content = $content;
82+
}
83+
84+
/**
85+
* @return \DateTime
86+
*/
87+
public function getCreatedAt(): \DateTime
88+
{
89+
return $this->createdAt;
90+
}
91+
92+
/**
93+
* @param \DateTime $createdAt
94+
*/
95+
public function setCreatedAt(\DateTime $createdAt): void
96+
{
97+
$this->createdAt = $createdAt;
98+
}
99+
100+
/**
101+
* @return bool
102+
*/
103+
public function isHidden(): bool
104+
{
105+
return $this->isHidden;
106+
}
107+
108+
/**
109+
* @param bool $isHidden
110+
*/
111+
public function setIsHidden(bool $isHidden): void
112+
{
113+
$this->isHidden = $isHidden;
114+
}
115+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace Breadlesscode\Commentable\Exception;
3+
4+
use Neos\Neos\Exception;
5+
6+
class InvalidNodeTypeException extends Exception
7+
{
8+
9+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
namespace Breadlesscode\Commentable\Form\Finisher;
3+
4+
use Breadlesscode\Commentable\Dto\CommentDto;
5+
use Breadlesscode\Commentable\Exception\InvalidNodeTypeException;
6+
use Breadlesscode\Commentable\Service\CommentService;
7+
use Neos\Form\Core\Model\AbstractFinisher;
8+
use Neos\Flow\Annotations as Flow;
9+
10+
class AddCommentFormFinisher extends AbstractFinisher
11+
{
12+
/**
13+
* @var CommentService
14+
* @Flow\Inject()
15+
*/
16+
protected $commentService;
17+
18+
/**
19+
* this finisher adds a comment to a given node
20+
*/
21+
protected function executeInternal()
22+
{
23+
try {
24+
$commentableNode = $this->parseOption('node');
25+
$this->commentService->addComment($commentableNode, $this->getCommentDto());
26+
} catch (\Exception | InvalidNodeTypeException $exception) {
27+
$this->finisherContext->cancel();
28+
}
29+
}
30+
31+
/**
32+
* @return CommentDto
33+
*/
34+
protected function getCommentDto(): CommentDto
35+
{
36+
$comment = new CommentDto();
37+
$comment->setName($this->parseOption('name'));
38+
$comment->setEmail($this->parseOption('email'));
39+
$comment->setContent($this->parseOption('content'));
40+
$comment->setIsHidden(true);
41+
42+
return $comment;
43+
}
44+
}

Classes/Service/CommentService.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
namespace Breadlesscode\Commentable\Service;
3+
4+
use Breadlesscode\Commentable\Dto\CommentDto;
5+
use Breadlesscode\Commentable\Exception\InvalidNodeTypeException;
6+
use Neos\ContentRepository\Domain\Model\NodeInterface;
7+
use Neos\ContentRepository\Domain\Model\NodeTemplate;
8+
use Neos\ContentRepository\Domain\Service\ContextFactoryInterface;
9+
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
10+
use Neos\Flow\Annotations as Flow;
11+
12+
class CommentService
13+
{
14+
/**
15+
* node type of the commentable mixin
16+
*/
17+
const COMMENTABLE_NODE_TYPE = 'Breadlesscode.Commentable:Mixin.Commentable';
18+
19+
/**
20+
* node type of the commentable mixin
21+
*/
22+
const COMMENT_NODE_TYPE = 'Breadlesscode.Commentable:Content.Comment';
23+
24+
/**
25+
* @Flow\Inject()
26+
* @var ContextFactoryInterface
27+
*/
28+
protected $contextFactory;
29+
30+
/**
31+
* @Flow\Inject()
32+
* @var NodeTypeManager
33+
*/
34+
protected $nodeTypeManager;
35+
36+
/**
37+
* creates a comment node from the CommentDto
38+
*
39+
* @param NodeInterface $commentCollection
40+
* @param CommentDto $comment
41+
* @return NodeInterface
42+
* @throws \Neos\ContentRepository\Exception\NodeTypeNotFoundException
43+
*/
44+
protected function createNode(NodeInterface $commentCollection, CommentDto $comment): NodeInterface
45+
{
46+
$commentNodeType = $this->nodeTypeManager->getNodeType(self::COMMENT_NODE_TYPE);
47+
$commentNodeTemplate = new NodeTemplate();
48+
$commentNodeTemplate->setNodeType($commentNodeType);
49+
50+
$commentNode = $commentCollection->createNodeFromTemplate($commentNodeTemplate);
51+
$commentNode->setProperty('name', $comment->getName());
52+
$commentNode->setProperty('email', $comment->getEmail());
53+
$commentNode->setProperty('content', $comment->getContent());
54+
$commentNode->setProperty('createdAt', $comment->getCreatedAt());
55+
$commentNode->setHidden($comment->isHidden());
56+
57+
return $commentNode;
58+
}
59+
60+
/**
61+
* adds a comment node to a blog post node
62+
*
63+
* @param NodeInterface $commentableNode
64+
* @param CommentDto $comment
65+
* @throws InvalidNodeTypeException
66+
* @throws \Neos\ContentRepository\Exception\NodeTypeNotFoundException
67+
*/
68+
public function addComment(NodeInterface $commentableNode, CommentDto $comment)
69+
{
70+
if (!$this->isCommentableNode($commentableNode)) {
71+
throw new InvalidNodeTypeException('The commentable node type should implement the mixin '.self::COMMENTABLE_NODE_TYPE, 1536244558);
72+
}
73+
74+
$this->createNode($commentableNode->getNode('comments'), $comment);
75+
}
76+
77+
/**
78+
* @param string $commentableIdentifier
79+
* @return NodeInterface|null
80+
* @throws \Exception
81+
*/
82+
public function findCommentable(string $commentableIdentifier): ?NodeInterface
83+
{
84+
$commentableNode = $this->getContext()->getNodeByIdentifier($commentableIdentifier);
85+
86+
if (!$this->isCommentableNode($commentableNode)) {
87+
throw new InvalidNodeTypeException('The commentable node type should implement the mixin '.self::COMMENTABLE_NODE_TYPE, 1536244559);
88+
}
89+
90+
return $commentableNode;
91+
}
92+
93+
/**
94+
* @param NodeInterface $node
95+
* @return bool
96+
*/
97+
public function isCommentableNode(NodeInterface $node): bool
98+
{
99+
return $node->getNodeType()->isOfType(self::COMMENTABLE_NODE_TYPE);
100+
}
101+
102+
/**
103+
* @return \Neos\ContentRepository\Domain\Service\Context
104+
* @throws \Exception
105+
*/
106+
protected function getContext()
107+
{
108+
return $this->contextFactory->create([
109+
'workspaceName' => 'live',
110+
'currentDateTime' => new \Neos\Flow\Utility\Now(),
111+
'dimensions' => [],
112+
'invisibleContentShown' => true,
113+
'removedContentShown' => false,
114+
'inaccessibleContentShown' => false
115+
]);
116+
}
117+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'Breadlesscode.Commentable:Collection.Comments':
2+
superTypes:
3+
'Neos.Neos:ContentCollection': true
4+
label: '${ I18n.translate(node.nodeType.label) }'
5+
ui:
6+
icon: 'icon-comments'
7+
label: 'Comments'
8+
constraints:
9+
nodeTypes:
10+
'*': false
11+
'Breadlesscode.Commentable:Content.Comment': true
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'Breadlesscode.Commentable:Content.Comment':
2+
superTypes:
3+
'Neos.Neos:Content': true
4+
ui:
5+
label: 'i18n'
6+
icon: 'icon-comment'
7+
inspector:
8+
groups:
9+
comment:
10+
label: 'i18n'
11+
properties:
12+
email:
13+
type: string
14+
ui:
15+
label: 'i18n'
16+
inspector:
17+
group: 'comment'
18+
name:
19+
type: string
20+
ui:
21+
label: 'i18n'
22+
inspector:
23+
group: 'comment'
24+
content:
25+
type: string
26+
isSpam:
27+
type: boolean
28+
ui:
29+
label: 'i18n'
30+
inspector:
31+
group: 'comment'
32+
createdAt:
33+
type: DateTime
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'Breadlesscode.Commentable:Mixin.Commentable':
2+
abstract: true
3+
childNodes:
4+
comments:
5+
type: 'Breadlesscode.Blog:Collection.Comments'
6+
position: 'after main'

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Marvin Kuhn
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)