Commit b03c0953 authored by Emma's avatar Emma

add NotForumBanned constraint/validator

parent 59570284
......@@ -93,15 +93,13 @@ final class CommentController extends AbstractController {
EventDispatcherInterface $dispatcher,
Comment $comment = null
) {
$data = new CommentData();
$data = new CommentData($submission);
$form = $this->createForm(CommentType::class, $data, ['forum' => $forum]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $this->getUser();
$ip = $request->getClientIp();
$reply = $data->toComment($submission, $user, $comment, $ip);
$reply = $data->toComment($this->getUser(), $comment, $request->getClientIp());
$em->persist($reply);
$em->flush();
......
......@@ -6,9 +6,18 @@ use App\Entity\Comment;
use App\Entity\Submission;
use App\Entity\User;
use App\Entity\UserFlags;
use App\Validator\Constraints\NotForumBanned;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @NotForumBanned(forumPath="submission.forum", errorPath="body")
*/
class CommentData {
/**
* @var Submission
*/
private $submission;
/**
* @Assert\NotBlank(message="The comment must not be empty.")
* @Assert\Regex("/[[:graph:]]/u", message="The comment must not be empty.")
......@@ -24,23 +33,23 @@ class CommentData {
private $userFlag = UserFlags::FLAG_NONE;
public static function createFromComment(Comment $comment): self {
$self = new self();
$self = new self($comment->getSubmission());
$self->submission = $comment->getSubmission();
$self->body = $comment->getBody();
$self->userFlag = $comment->getUserFlag();
return $self;
}
public function toComment(
Submission $submission,
User $user,
Comment $parent = null,
$ip = null
): Comment {
public function __construct(Submission $submission) {
$this->submission = $submission;
}
public function toComment(User $user, Comment $parent = null, $ip = null): Comment {
return new Comment(
$this->body,
$user,
$submission,
$this->submission,
$this->userFlag,
$parent,
$ip
......@@ -60,31 +69,23 @@ class CommentData {
}
}
/**
* @return string|null
*/
public function getBody() {
public function getBody(): ?string {
return $this->body;
}
/**
* @param string|null $body
*/
public function setBody($body) {
public function setBody($body): void {
$this->body = $body;
}
/**
* @return int|null
*/
public function getUserFlag() {
public function getUserFlag(): ?int {
return $this->userFlag;
}
/**
* @param int|null $userFlag
*/
public function setUserFlag($userFlag) {
public function setUserFlag($userFlag): void {
$this->userFlag = $userFlag;
}
public function getSubmission(): Submission {
return $this->submission;
}
}
......@@ -6,6 +6,7 @@ use App\Entity\Forum;
use App\Entity\Submission;
use App\Entity\User;
use App\Entity\UserFlags;
use App\Validator\Constraints\NotForumBanned;
use App\Validator\Constraints\RateLimit;
use Symfony\Component\Validator\Constraints as Assert;
......@@ -44,6 +45,7 @@ class SubmissionData {
private $userFlag = UserFlags::FLAG_NONE;
/**
* @NotForumBanned()
* @Assert\NotBlank(groups={"create", "edit"})
*
* @var Forum|null
......
<?php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class NotForumBanned extends Constraint {
public $message = 'You have been banned from this forum.';
public $forumPath;
public $errorPath;
public const FORUM_BANNED_ERROR = 'eeb18913-1b45-47d6-b676-39aec0059487';
protected static $errorNames = [
self::FORUM_BANNED_ERROR => 'FORUM_BANNED_ERROR',
];
public function getTargets(): array {
return [self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT];
}
}
<?php
namespace App\Validator\Constraints;
use App\Entity\Forum;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class NotForumBannedValidator extends ConstraintValidator {
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage) {
$this->tokenStorage = $tokenStorage;
}
public function validate($value, Constraint $constraint): void {
if (!$value || !$this->tokenStorage->getToken() || !$this->tokenStorage->getToken()->getUser()) {
return;
}
if (!\is_object($value)) {
throw new UnexpectedTypeException($value, 'object');
}
if (!$constraint instanceof NotForumBanned) {
throw new UnexpectedTypeException($constraint, NotForumBanned::class);
}
if ($constraint->forumPath) {
$propertyAccessor = PropertyAccess::createPropertyAccessor();
if (!$propertyAccessor->isReadable($value, $constraint->forumPath)) {
throw new InvalidArgumentException(sprintf(
'Cannot read property %s on object of type %s',
$constraint->forumPath,
\get_class($value)
));
}
$forum = $propertyAccessor->getValue($value, $constraint->forumPath);
} else {
$forum = $value;
}
if ($forum === null) {
return;
}
if (!$forum instanceof Forum) {
throw new InvalidArgumentException(sprintf(
'Property %s on object of type %s is not of type %s',
$constraint->forumPath,
\get_class($value),
Forum::class
));
}
$token = $this->tokenStorage->getToken();
if (!$token) {
return;
}
if ($forum->userIsBanned($token->getUser())) {
$this->context->buildViolation($constraint->message)
->setCode(NotForumBanned::FORUM_BANNED_ERROR)
->atPath($constraint->errorPath)
->addViolation();
}
}
}
......@@ -20,3 +20,4 @@
'The IP address is not valid.': 'The IP address is not valid.'
'The CIDR mask is not valid.': 'The CIDR mask is not valid.'
'Missing CIDR mask.': 'Missing CIDR mask.'
'You have been banned from this forum.': 'You have been banned from this forum.'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment