Commit 5d320a2c authored by Emma's avatar Emma 🏳🌈

soft-delete submissions/refactor submission stuff

parent 9686fc35
Pipeline #60830186 passed with stages
in 8 minutes and 23 seconds
...@@ -14,4 +14,8 @@ ...@@ -14,4 +14,8 @@
&--warn { &--warn {
background: var(--bg-orange); background: var(--bg-orange);
} }
&--error {
background: var(--bg-red);
}
} }
...@@ -227,6 +227,12 @@ ...@@ -227,6 +227,12 @@
"css": "sun-inv", "css": "sun-inv",
"code": 59416, "code": 59416,
"src": "iconic" "src": "iconic"
},
{
"uid": "5211af474d3a9848f67f945e2ccaf143",
"css": "cancel",
"code": 59415,
"src": "fontawesome"
} }
] ]
} }
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
height="0"><defs> height="0"><defs>
<symbol id="attention" viewBox="0 0 1000 1000"><path d="M571 767V661q0-8-5-13t-12-5H446q-7 0-12 5t-5 13v106q0 8 5 13t12 6h108q7 0 12-6t5-13zm-1-208l10-257q0-6-5-10-7-6-14-6H439q-6 0-14 6-5 4-5 12l9 255q0 5 6 9t13 3h103q8 0 14-3t5-9zm-7-522l428 786q20 35-1 70-9 17-26 26t-35 10H71q-18 0-35-10t-26-26q-21-35-1-70L438 37q9-17 26-27t36-10 36 10 27 27z"/></symbol> <symbol id="attention" viewBox="0 0 1000 1000"><path d="M571 767V661q0-8-5-13t-12-5H446q-7 0-12 5t-5 13v106q0 8 5 13t12 6h108q7 0 12-6t5-13zm-1-208l10-257q0-6-5-10-7-6-14-6H439q-6 0-14 6-5 4-5 12l9 255q0 5 6 9t13 3h103q8 0 14-3t5-9zm-7-522l428 786q20 35-1 70-9 17-26 26t-35 10H71q-18 0-35-10t-26-26q-21-35-1-70L438 37q9-17 26-27t36-10 36 10 27 27z"/></symbol>
<symbol id="block" viewBox="0 0 857.1 1000"><path d="M732 498q0-90-48-164L263 754q76 50 166 50 62 0 118-25t96-65 65-97 24-119zM175 665l421-421q-75-50-167-50-83 0-153 40T166 345t-41 153q0 91 50 167zm682-167q0 88-34 168t-91 137-137 92-166 34-167-34-137-92-91-137T0 498t34-167 91-137 137-91 167-34 166 34 137 91 91 137 34 167z"/></symbol> <symbol id="block" viewBox="0 0 857.1 1000"><path d="M732 498q0-90-48-164L263 754q76 50 166 50 62 0 118-25t96-65 65-97 24-119zM175 665l421-421q-75-50-167-50-83 0-153 40T166 345t-41 153q0 91 50 167zm682-167q0 88-34 168t-91 137-137 92-166 34-167-34-137-92-91-137T0 498t34-167 91-137 137-91 167-34 166 34 137 91 91 137 34 167z"/></symbol>
<symbol id="cancel" viewBox="0 0 785.7 1000"><path d="M724 738q0 22-15 38l-76 76q-16 15-38 15t-38-15L393 687 229 852q-16 15-38 15t-38-15l-76-76q-16-16-16-38t16-38l164-164L77 372q-16-16-16-38t16-38l76-76q16-16 38-16t38 16l164 164 164-164q16-16 38-16t38 16l76 76q15 15 15 38t-15 38L545 536l164 164q15 15 15 38z"/></symbol>
<symbol id="clock" viewBox="0 0 857.1 1000"><path d="M500 304v250q0 7-5 12t-13 5H304q-8 0-13-5t-5-12v-36q0-8 5-13t13-5h125V304q0-8 5-13t12-5h36q8 0 13 5t5 13zm232 196q0-83-41-152T581 237t-152-41-153 41-110 111-41 152 41 152 110 111 153 41 152-41 110-111 41-152zm125 0q0 117-57 215T644 871t-215 58-216-58T58 715 0 500t58-215 155-156 216-58 215 58 156 156 57 215z"/></symbol> <symbol id="clock" viewBox="0 0 857.1 1000"><path d="M500 304v250q0 7-5 12t-13 5H304q-8 0-13-5t-5-12v-36q0-8 5-13t13-5h125V304q0-8 5-13t12-5h36q8 0 13 5t5 13zm232 196q0-83-41-152T581 237t-152-41-153 41-110 111-41 152 41 152 110 111 153 41 152-41 110-111 41-152zm125 0q0 117-57 215T644 871t-215 58-216-58T58 715 0 500t58-215 155-156 216-58 215 58 156 156 57 215z"/></symbol>
<symbol id="comment" viewBox="0 0 1000 1000"><path d="M1000 500q0 97-67 179T751 809t-251 48q-39 0-81-4-110 97-257 135-27 8-63 12-10 1-17-5t-10-16v-1q-2-2 0-6t1-6 2-5l4-5 4-5 4-5q4-5 17-19t20-22 17-22 18-28 15-33 15-42q-88-50-138-123T0 500q0-73 40-139t106-114 160-76 194-28q136 0 251 48t182 130 67 179z"/></symbol> <symbol id="comment" viewBox="0 0 1000 1000"><path d="M1000 500q0 97-67 179T751 809t-251 48q-39 0-81-4-110 97-257 135-27 8-63 12-10 1-17-5t-10-16v-1q-2-2 0-6t1-6 2-5l4-5 4-5 4-5q4-5 17-19t20-22 17-22 18-28 15-33 15-42q-88-50-138-123T0 500q0-73 40-139t106-114 160-76 194-28q136 0 251 48t182 130 67 179z"/></symbol>
<symbol id="down" viewBox="0 0 928 1000"><path d="M911 499L464 947 18 499l158-158 177 176V53h223v464l176-175z"/></symbol> <symbol id="down" viewBox="0 0 928 1000"><path d="M911 499L464 947 18 499l158-158 177 176V53h223v464l176-175z"/></symbol>
......
...@@ -18,7 +18,7 @@ submission_shortcut: ...@@ -18,7 +18,7 @@ submission_shortcut:
comment: comment:
controller: App\Controller\SubmissionController::commentPermalink controller: App\Controller\SubmissionController::commentPermalink
defaults: { slug: '-' } defaults: { slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/comment/{comment_id} path: /f/{forum_name}/{submission_id}/{slug}/comment/{comment_id}
requirements: { submission_id: "%number_regex%", comment_id: "%number_regex%" } requirements: { submission_id: "%number_regex%", comment_id: "%number_regex%" }
...@@ -31,49 +31,56 @@ comment_legacy_redirect: ...@@ -31,49 +31,56 @@ comment_legacy_redirect:
edit_submission: edit_submission:
controller: App\Controller\SubmissionController::editSubmission controller: App\Controller\SubmissionController::editSubmission
defaults: { slug: '-' } defaults: { slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/edit path: /f/{forum_name}/{submission_id}/{slug}/edit
methods: [GET, POST] methods: [GET, POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
submission_delete_immediately: submission_delete_own:
controller: App\Controller\SubmissionController::deleteImmediately controller: App\Controller\SubmissionController::deleteOwn
defaults: { slug: '-' } defaults: { slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/delete path: /f/{forum_name}/{submission_id}/{slug}/delete
methods: [POST] methods: [POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
submission_delete_with_reason: submission_mod_delete:
controller: App\Controller\SubmissionController::deleteWithReason controller: App\Controller\SubmissionController::modDelete
defaults: { slug: '-' } defaults: { slug: -, purge: false }
path: /f/{forum_name}/{submission_id}/{slug}/delete_with_reason path: /f/{forum_name}/{submission_id}/{slug}/mod_delete
methods: [GET, POST]
requirements: { submission_id: "%number_regex%" }
submission_purge:
controller: App\Controller\SubmissionController::modDelete
defaults: { slug: -, purge: true }
path: /f/{forum_name}/{submission_id}/{slug}/purge
methods: [GET, POST] methods: [GET, POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
lock: lock:
controller: App\Controller\SubmissionController::lock controller: App\Controller\SubmissionController::lock
defaults: { lock: true, slug: '-' } defaults: { lock: true, slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/lock path: /f/{forum_name}/{submission_id}/{slug}/lock
methods: [POST] methods: [POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
unlock: unlock:
controller: App\Controller\SubmissionController::lock controller: App\Controller\SubmissionController::lock
defaults: { lock: false, slug: '-' } defaults: { lock: false, slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/unlock path: /f/{forum_name}/{submission_id}/{slug}/unlock
methods: [POST] methods: [POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
pin: pin:
controller: App\Controller\SubmissionController::pin controller: App\Controller\SubmissionController::pin
defaults: { pin: true, slug: '-' } defaults: { pin: true, slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/pin path: /f/{forum_name}/{submission_id}/{slug}/pin
methods: [POST] methods: [POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
unpin: unpin:
controller: App\Controller\SubmissionController::pin controller: App\Controller\SubmissionController::pin
defaults: { pin: false, slug: '-' } defaults: { pin: false, slug: - }
path: /f/{forum_name}/{submission_id}/{slug}/unpin path: /f/{forum_name}/{submission_id}/{slug}/unpin
methods: [POST] methods: [POST]
requirements: { submission_id: "%number_regex%" } requirements: { submission_id: "%number_regex%" }
......
...@@ -12,9 +12,8 @@ user_shortcut: ...@@ -12,9 +12,8 @@ user_shortcut:
user_submissions: user_submissions:
controller: App\Controller\UserController::submissions controller: App\Controller\UserController::submissions
defaults: { page: 1 } defaults: { page: 1 }
path: /user/{username}/submissions/{page} path: /user/{username}/submissions
methods: [GET] methods: [GET]
requirements: { page: \d+ }
user_comments: user_comments:
controller: App\Controller\UserController::comments controller: App\Controller\UserController::comments
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Forum; use App\Entity\Forum;
use App\Entity\Submission;
use App\Entity\User; use App\Entity\User;
use App\Entity\UserBlock; use App\Entity\UserBlock;
use App\Form\Model\UserBlockData; use App\Form\Model\UserBlockData;
...@@ -83,16 +84,10 @@ final class UserController extends AbstractController { ...@@ -83,16 +84,10 @@ final class UserController extends AbstractController {
]); ]);
} }
/** public function submissions(User $user, Request $request): Response {
* @param User $user $submissions = $this->submissions->findSubmissions(Submission::SORT_NEW, [
* @param int $page 'users' => [$user],
* ], $request);
* @return Response
*/
public function submissions(User $user, int $page) {
$submissions = $user->getPaginatedSubmissions($page);
$this->submissions->hydrate(...$submissions);
return $this->render('user/submissions.html.twig', [ return $this->render('user/submissions.html.twig', [
'submissions' => $submissions, 'submissions' => $submissions,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
namespace App\Entity; namespace App\Entity;
use App\Entity\Exception\BannedFromForumException; use App\Entity\Exception\BannedFromForumException;
use App\Entity\Exception\SubmissionLockedException;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\Criteria;
...@@ -20,9 +21,13 @@ use Symfony\Component\Serializer\Annotation\SerializedName; ...@@ -20,9 +21,13 @@ use Symfony\Component\Serializer\Annotation\SerializedName;
* @ORM\Index(name="submissions_comment_count_id_idx", columns={"comment_count", "id"}), * @ORM\Index(name="submissions_comment_count_id_idx", columns={"comment_count", "id"}),
* @ORM\Index(name="submissions_net_score_id_idx", columns={"net_score", "id"}), * @ORM\Index(name="submissions_net_score_id_idx", columns={"net_score", "id"}),
* @ORM\Index(name="submissions_search_idx", columns={"search_doc"}), * @ORM\Index(name="submissions_search_idx", columns={"search_doc"}),
* @ORM\Index(name="submissions_visibility_idx", columns={"visibility"}),
* }) * })
*/ */
class Submission extends Votable { class Submission extends Votable {
public const VISIBILITY_VISIBLE = 'visible';
public const VISIBILITY_DELETED = 'deleted';
public const FRONT_FEATURED = 'featured'; public const FRONT_FEATURED = 'featured';
public const FRONT_SUBSCRIBED = 'subscribed'; public const FRONT_SUBSCRIBED = 'subscribed';
public const FRONT_ALL = 'all'; public const FRONT_ALL = 'all';
...@@ -77,7 +82,7 @@ class Submission extends Votable { ...@@ -77,7 +82,7 @@ class Submission extends Votable {
* *
* @Groups({"submission:read", "abbreviated_relations"}) * @Groups({"submission:read", "abbreviated_relations"})
* *
* @var int * @var int|null
*/ */
private $id; private $id;
...@@ -144,6 +149,15 @@ class Submission extends Votable { ...@@ -144,6 +149,15 @@ class Submission extends Votable {
*/ */
private $lastActive; private $lastActive;
/**
* @ORM\Column(type="text")
*
* @Groups({"submission:read"})
*
* @var string
*/
private $visibility = self::VISIBILITY_VISIBLE;
/** /**
* @ORM\JoinColumn(nullable=false) * @ORM\JoinColumn(nullable=false)
* @ORM\ManyToOne(targetEntity="Forum", inversedBy="submissions") * @ORM\ManyToOne(targetEntity="Forum", inversedBy="submissions")
...@@ -173,7 +187,7 @@ class Submission extends Votable { ...@@ -173,7 +187,7 @@ class Submission extends Votable {
private $votes; private $votes;
/** /**
* @ORM\OneToMany(targetEntity="SubmissionMention", mappedBy="submission", cascade={"remove"}) * @ORM\OneToMany(targetEntity="SubmissionMention", mappedBy="submission", cascade={"remove"}, orphanRemoval=true)
* *
* @var SubmissionMention[]|Collection * @var SubmissionMention[]|Collection
*/ */
...@@ -182,7 +196,7 @@ class Submission extends Votable { ...@@ -182,7 +196,7 @@ class Submission extends Votable {
/** /**
* @ORM\Column(type="text", nullable=true) * @ORM\Column(type="text", nullable=true)
* *
* @var string * @var string|null
*/ */
private $image; private $image;
...@@ -232,7 +246,7 @@ class Submission extends Votable { ...@@ -232,7 +246,7 @@ class Submission extends Votable {
* *
* @var int * @var int
*/ */
private $userFlag; private $userFlag = UserFlags::FLAG_NONE;
/** /**
* @ORM\Column(type="boolean", options={"default": false}) * @ORM\Column(type="boolean", options={"default": false})
...@@ -275,8 +289,6 @@ class Submission extends Votable { ...@@ -275,8 +289,6 @@ class Submission extends Votable {
Forum $forum, Forum $forum,
User $user, User $user,
?string $ip, ?string $ip,
bool $sticky = false,
int $userFlag = UserFlags::FLAG_NONE,
\DateTime $timestamp = null \DateTime $timestamp = null
) { ) {
if ($ip !== null && !filter_var($ip, FILTER_VALIDATE_IP)) { if ($ip !== null && !filter_var($ip, FILTER_VALIDATE_IP)) {
...@@ -293,9 +305,7 @@ class Submission extends Votable { ...@@ -293,9 +305,7 @@ class Submission extends Votable {
$this->forum = $forum; $this->forum = $forum;
$this->user = $user; $this->user = $user;
$this->ip = $user->isTrustedOrAdmin() ? null : $ip; $this->ip = $user->isTrustedOrAdmin() ? null : $ip;
$this->sticky = $sticky; $this->timestamp = $timestamp ?? new \DateTime('@'.time());
$this->setUserFlag($userFlag);
$this->timestamp = $timestamp ?: new \DateTime('@'.time());
$this->comments = new ArrayCollection(); $this->comments = new ArrayCollection();
$this->votes = new ArrayCollection(); $this->votes = new ArrayCollection();
$this->mentions = new ArrayCollection(); $this->mentions = new ArrayCollection();
...@@ -311,7 +321,7 @@ class Submission extends Votable { ...@@ -311,7 +321,7 @@ class Submission extends Votable {
return $this->title; return $this->title;
} }
public function setTitle(string $title) { public function setTitle(string $title): void {
$this->title = $title; $this->title = $title;
} }
...@@ -319,7 +329,7 @@ class Submission extends Votable { ...@@ -319,7 +329,7 @@ class Submission extends Votable {
return $this->url; return $this->url;
} }
public function setUrl(?string $url) { public function setUrl(?string $url): void {
$this->url = $url; $this->url = $url;
} }
...@@ -327,7 +337,7 @@ class Submission extends Votable { ...@@ -327,7 +337,7 @@ class Submission extends Votable {
return $this->body; return $this->body;
} }
public function setBody(?string $body) { public function setBody(?string $body): void {
$this->body = $body; $this->body = $body;
} }
...@@ -356,7 +366,7 @@ class Submission extends Votable { ...@@ -356,7 +366,7 @@ class Submission extends Votable {
return $comments; return $comments;
} }
public function addComment(Comment ...$comments) { public function addComment(Comment ...$comments): void {
foreach ($comments as $comment) { foreach ($comments as $comment) {
if (!$this->comments->contains($comment)) { if (!$this->comments->contains($comment)) {
$this->comments->add($comment); $this->comments->add($comment);
...@@ -368,7 +378,7 @@ class Submission extends Votable { ...@@ -368,7 +378,7 @@ class Submission extends Votable {
$this->updateLastActive(); $this->updateLastActive();
} }
public function removeComment(Comment ...$comments) { public function removeComment(Comment ...$comments): void {
// hydrate the collection // hydrate the collection
$this->comments->get(-1); $this->comments->get(-1);
...@@ -417,6 +427,21 @@ class Submission extends Votable { ...@@ -417,6 +427,21 @@ class Submission extends Votable {
} }
} }
public function getVisibility(): string {
return $this->visibility;
}
public function softDelete(): void {
$this->visibility = self::VISIBILITY_DELETED;
$this->title = '';
$this->url = null;
$this->body = null;
$this->image = null;
$this->sticky = false;
$this->userFlag = 0;
$this->mentions->clear();
}
public function getForum(): Forum { public function getForum(): Forum {
return $this->forum; return $this->forum;
} }
...@@ -426,23 +451,21 @@ class Submission extends Votable { ...@@ -426,23 +451,21 @@ class Submission extends Votable {
} }
/** /**
* {@inheritdoc} * @return Collection|SubmissionVote[]
*/ */
public function getVotes(): Collection { public function getVotes(): Collection {
return $this->votes; return $this->votes;
} }
/**
* {@inheritdoc}
*/
protected function createVote(User $user, ?string $ip, int $choice): Vote { protected function createVote(User $user, ?string $ip, int $choice): Vote {
return new SubmissionVote($user, $ip, $choice, $this); return new SubmissionVote($user, $ip, $choice, $this);
} }
/**
* {@inheritdoc}
*/
public function vote(User $user, ?string $ip, int $choice): void { public function vote(User $user, ?string $ip, int $choice): void {
if ($this->visibility === self::VISIBILITY_DELETED) {
throw new SubmissionLockedException();
}
if ($this->forum->userIsBanned($user)) { if ($this->forum->userIsBanned($user)) {
throw new BannedFromForumException(); throw new BannedFromForumException();
} }
...@@ -453,7 +476,7 @@ class Submission extends Votable { ...@@ -453,7 +476,7 @@ class Submission extends Votable {
$this->updateRanking(); $this->updateRanking();
} }
public function addMention(User $mentioned) { public function addMention(User $mentioned): void {
if ($mentioned === $this->getUser()) { if ($mentioned === $this->getUser()) {
// don't notify yourself // don't notify yourself
return; return;
...@@ -476,7 +499,7 @@ class Submission extends Votable { ...@@ -476,7 +499,7 @@ class Submission extends Votable {
return $this->image; return $this->image;
} }
public function setImage(?string $image) { public function setImage(?string $image): void {
$this->image = $image; $this->image = $image;
} }
...@@ -488,18 +511,15 @@ class Submission extends Votable { ...@@ -488,18 +511,15 @@ class Submission extends Votable {
return $this->sticky; return $this->sticky;
} }
public function setSticky(bool $sticky) { public function setSticky(bool $sticky): void {
$this->sticky = $sticky; $this->sticky = $sticky;
} }
/**
* @return int
*/
public function getRanking(): int { public function getRanking(): int {
return $this->ranking; return $this->ranking;
} }
public function updateRanking() { public function updateRanking(): void {
$netScore = $this->getNetScore(); $netScore = $this->getNetScore();
$netScoreAdvantage = $netScore * self::NETSCORE_MULTIPLIER; $netScoreAdvantage = $netScore * self::NETSCORE_MULTIPLIER;
...@@ -518,7 +538,7 @@ class Submission extends Votable { ...@@ -518,7 +538,7 @@ class Submission extends Votable {
return $this->editedAt; return $this->editedAt;
} }
public function setEditedAt(?\DateTime $editedAt) { public function setEditedAt(?\DateTime $editedAt): void {
$this->editedAt = $editedAt; $this->editedAt = $editedAt;
} }
...@@ -526,7 +546,7 @@ class Submission extends Votable { ...@@ -526,7 +546,7 @@ class Submission extends Votable {
return $this->moderated; return $this->moderated;
} }
public function setModerated(bool $moderated) { public function setModerated(bool $moderated): void {
$this->moderated = $moderated; $this->moderated = $moderated;
} }
...@@ -537,14 +557,12 @@ class Submission extends Votable { ...@@ -537,14 +557,12 @@ class Submission extends Votable {
/** /**
* @Groups({"submission:read"}) * @Groups({"submission:read"})
* @SerializedName("userFlag") * @SerializedName("userFlag")
*
* @return string|null
*/ */
public function getReadableUserFlag(): ?string { public function getReadableUserFlag(): ?string {
return UserFlags::toReadable($this->userFlag); return UserFlags::toReadable($this->userFlag);
} }
public function setUserFlag(int $userFlag) { public function setUserFlag(int $userFlag): void {
if (!in_array($userFlag, UserFlags::FLAGS, true)) { if (!in_array($userFlag, UserFlags::FLAGS, true)) {
throw new \InvalidArgumentException('Bad flag'); throw new \InvalidArgumentException('Bad flag');
} }
...@@ -556,7 +574,7 @@ class Submission extends Votable { ...@@ -556,7 +574,7 @@ class Submission extends Votable {
return $this->locked; return $this->locked;
} }
public function setLocked(bool $locked) { public function setLocked(bool $locked): void {
$this->locked = $locked; $this->locked = $locked;
} }
......
...@@ -425,20 +425,6 @@ class User implements UserInterface, EquatableInterface { ...@@ -425,20 +425,6 @@ class User implements UserInterface, EquatableInterface {
return $this->submissions; return $this->submissions;
} }
/**
* @param int $page
* @param int $maxPerPage
*
* @return Pagerfanta|Comment[]
*/
public function getPaginatedSubmissions(int $page, int $maxPerPage = 25): Pagerfanta {
$submissions = new Pagerfanta(new DoctrineCollectionAdapter($this->submissions));
$submissions->setMaxPerPage($maxPerPage);
$submissions->setCurrentPage($page);
return $submissions;
}
public function getSubmissionVotes(): Collection { public function getSubmissionVotes(): Collection {
return $this->submissionVotes; return $this->submissionVotes;
} }
......
...@@ -68,17 +68,11 @@ class SubmissionData { ...@@ -68,17 +68,11 @@ class SubmissionData {
return $self; return $self;
} }
public function toSubmission(User $user, $ip): Submission { public function toSubmission(User $user, ?string $ip): Submission {
return new Submission( $submission = new Submission($this->title, $this->url, $this->body, $this->forum, $user, $ip);
$this->title, $submission->setUserFlag($this->userFlag);
$this->url,
$this->body, return $submission;
$this->forum,
$user,
$ip,
false,
$this->userFlag
);
} }
public function updateSubmission(Submission $submission, User $editingUser) { public function updateSubmission(Submission $submission, User $editingUser) {
......
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20190511110139 extends AbstractMigration {
public function getDescription(): string {
return 'Add visibility field to submissions';
}
public function up(Schema $schema): void {
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE submissions ADD visibility TEXT NOT NULL DEFAULT \'visible\'');
$this->addSql('ALTER TABLE submissions ALTER visibility DROP DEFAULT');
$this->addSql('CREATE INDEX submissions_visibility_idx ON submissions (visibility)');
}
public function down(Schema $schema): void {
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE submissions DROP visibility');
}
}
...@@ -88,6 +88,8 @@ class SubmissionRepository extends ServiceEntityRepository { ...@@ -88,6 +88,8 @@ class SubmissionRepository extends ServiceEntityRepository {
$qb = $this->_em->getConnection()->createQueryBuilder() $qb = $this->_em->getConnection()->createQueryBuilder()
->select($rsm->generateSelectClause()) ->select($rsm->generateSelectClause())
->from('submissions', 's') ->from('submissions', 's')
->where('s.visibility IN (:visibility)')
->setParameter('visibility', Submission::VISIBILITY_VISIBLE)
->setMaxResults($maxPerPage + 1); ->setMaxResults($maxPerPage + 1);
if (!\in_array($sortBy, Submission::SORT_OPTIONS, true)) { if (!\in_array($sortBy, Submission::SORT_OPTIONS, true)) {
......
...@@ -122,8 +122,10 @@ class UserRepository extends ServiceEntityRepository implements UserLoaderInterf ...@@ -122,8 +122,10 @@ class UserRepository extends ServiceEntityRepository implements UserLoaderInterf
->from(Submission::class, 's') ->from(Submission::class, 's')
->where('s.user = ?1') ->where('s.user = ?1')
->andWhere('s.timestamp <= ?2') ->andWhere('s.timestamp <= ?2')
->andWhere('s.visibility = ?3')
->setParameter(1, $user) ->setParameter(1, $user)
->setParameter(2, $nextTimestamp, Type::DATETIMETZ) ->setParameter(2, $nextTimestamp, Type::DATETIMETZ)
->setParameter(3, Submission::VISIBILITY_VISIBLE)
->orderBy('s.timestamp', 'DESC') ->orderBy('s.timestamp', 'DESC')
->setMaxResults(26) ->setMaxResults(26)
->getQuery() ->getQuery()
......
...@@ -5,85 +5,114 @@ namespace App\Security\Voter; ...@@ -5,85 +5,114 @@ namespace App\Security\Voter;
use App\Entity\Submission; use App\Entity\Submission;
use App\Entity\User; use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;