WIP: feature_paste #1
|
@ -3,8 +3,9 @@ declare(strict_types = 1);
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Form\Type\PasteForm;
|
||||
use App\DTO\PasteFormData;
|
||||
use App\Entity\Paste;
|
||||
use App\Form\Type\PasteForm;
|
||||
use App\Repository\PasteRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
@ -17,19 +18,29 @@ class PasteController extends AbstractController
|
|||
#[Route('/')]
|
||||
public function new(Request $request, PasteRepository $pasteRepository): Response
|
||||
{
|
||||
$paste = new Paste();
|
||||
$form = $this->createForm(PasteForm::class, $paste);
|
||||
$pasteData = new PasteFormData();
|
||||
$form = $this->createForm(PasteForm::class, $pasteData);
|
||||
|
||||
$form->handleRequest($request);
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$paste = $form->getData();
|
||||
$paste->setIp($request->getClientIp());
|
||||
$paste->setPublishDate(new \DateTime());
|
||||
$pasteData = $form->getData();
|
||||
|
||||
if ($paste->isPrivate()) {
|
||||
$paste->setSecret(hash('sha1', random_bytes(25)));
|
||||
$secret = null;
|
||||
if ($pasteData->isPrivate()) {
|
||||
$secret = hash('sha1', random_bytes(25));
|
||||
}
|
||||
|
||||
$paste = new Paste(
|
||||
$pasteData->getText(),
|
||||
$pasteData->getLanguage(),
|
||||
$pasteData->getDescription(),
|
||||
$pasteData->getFilename(),
|
||||
$pasteData->getAuthor(),
|
||||
new \DateTimeImmutable(),
|
||||
$pasteData->getExpirationDate(),
|
||||
|
||||
$request->getClientIp(),
|
||||
$secret
|
||||
);
|
||||
$pasteRepository->save($paste);
|
||||
|
||||
return $this->redirectToRoute($request->attributes->get('_route'));
|
||||
|
|
122
src/DTO/PasteFormData.php
Normal file
122
src/DTO/PasteFormData.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace App\DTO;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
|
||||
class PasteFormData
|
||||
{
|
||||
private int $id;
|
||||
|
||||
#[Assert\NotBlank]
|
||||
private string $text;
|
||||
|
||||
#[Assert\Type(\boolean::class)]
|
||||
private bool $private;
|
||||
|
||||
private ?string $language = null;
|
||||
|
||||
skobkin marked this conversation as resolved
skobkin
commented
Why Why `string` and `Assert\NotBlank`?
|
||||
private ?string $description = null;
|
||||
|
||||
skobkin marked this conversation as resolved
skobkin
commented
Is this validation being processed BEFORE storing the data in the DTO? Is this validation being processed BEFORE storing the data in the DTO?
If not, it's pointless as with `bool` field earlier.
|
||||
private ?string $filename = null;
|
||||
|
||||
skobkin marked this conversation as resolved
skobkin
commented
Or you can make constructor Or you can make constructor `private`, use property promotion and add `fromPaste()` method to create it from the entity.
|
||||
#[Assert\NotBlank]
|
||||
private string $author = 'anonymous';
|
||||
|
||||
#[Assert\Type(\DateTimeImmutable::class)]
|
||||
private ?\DateTimeImmutable $expirationDate;
|
||||
|
||||
private ?string $secret;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function setText(string $text): void
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function getLanguage(): ?string
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function setLanguage(?string $language): void
|
||||
{
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
public function setFilename(?string $filename): void
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
public function getAuthor(): string
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function setAuthor(string $author): void
|
||||
{
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
public function getExpirationDate(): ?\DateTime
|
||||
{
|
||||
return $this->expirationDate;
|
||||
}
|
||||
|
||||
public function setExpirationDate(?\DateTime $date): void
|
||||
{
|
||||
$this->expirationDate = $date;
|
||||
}
|
||||
|
||||
public function getSecret(): ?string
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
public function setSecret(?string $secret): void
|
||||
{
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
public function isPrivate(): bool
|
||||
{
|
||||
return $this->private;
|
||||
}
|
||||
|
||||
public function setPrivate(bool $private): void
|
||||
{
|
||||
$this->private = $private;
|
||||
}
|
||||
}
|
|
@ -6,158 +6,33 @@ namespace App\Entity;
|
|||
use App\Repository\PasteRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
skobkin
commented
I'd suggest explicitly defining Especially since you're defining I'd suggest explicitly defining `Table` attribute here.
Especially since you're defining `Column` attributes below ⬇️
skobkin
commented
I'd also suggest to make this entity readonly. It'll give some performance benefits. You can read about that here. I'd also suggest to make this entity readonly. It'll give some performance benefits.
You can read about that [here](https://www.doctrine-project.org/projects/doctrine-orm/en/2.15/reference/attributes-reference.html#attrref_entity).
|
||||
#[ORM\Entity(repositoryClass: PasteRepository::class)]
|
||||
class Paste
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(nullable: false)]
|
||||
private int $id;
|
||||
#[ORM\Column]
|
||||
skobkin
commented
Why not also constructor promotion though? Why not also constructor promotion though?
|
||||
public readonly int $id;
|
||||
|
||||
public function __construct(
|
||||
#[ORM\Column(type: 'text', nullable: false)]
|
||||
#[Assert\NotBlank]
|
||||
private string $text;
|
||||
|
||||
#[ORM\Column(type: 'boolean', nullable: false)]
|
||||
#[Assert\Type(\boolean::class)]
|
||||
private bool $private;
|
||||
|
||||
public readonly string $text,
|
||||
#[ORM\Column(length: 25, nullable: true)]
|
||||
private ?string $language;
|
||||
|
||||
public readonly ?string $language,
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $description;
|
||||
|
||||
public readonly ?string $description,
|
||||
#[ORM\Column(length: 128, nullable: true)]
|
||||
skobkin
commented
Why 128? Why 128?
|
||||
private ?string $filename;
|
||||
|
||||
public readonly ?string $filename,
|
||||
#[ORM\Column(length: 128, nullable: false)]
|
||||
#[Assert\NotBlank]
|
||||
private string $author = 'anonymous';
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)]
|
||||
#[Assert\Type(\DateTime::class)]
|
||||
private \DateTime $publishDate;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
|
||||
#[Assert\Type(\DateTime::class)]
|
||||
private ?\DateTime $expirationDate;
|
||||
|
||||
public readonly string $author,
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)]
|
||||
public readonly \DateTimeImmutable $publishDate,
|
||||
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
|
||||
public readonly ?\DateTimeImmutable $expirationDate,
|
||||
#[ORM\Column(length: 15, nullable: false)]
|
||||
private string $ip;
|
||||
|
||||
public readonly string $ip,
|
||||
#[ORM\Column(length: 40, nullable: true)]
|
||||
private ?string $secret;
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function setText(string $text): void
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function getLanguage(): ?string
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function setLanguage(?string $language): void
|
||||
{
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): void
|
||||
{
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
public function getFilename(): ?string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
public function setFilename(?string $filename): void
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
public function getAuthor(): string
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
|
||||
public function setAuthor(string $author): void
|
||||
{
|
||||
$this->author = $author;
|
||||
}
|
||||
|
||||
public function getPublishDate(): \DateTime
|
||||
{
|
||||
return $this->publishDate;
|
||||
}
|
||||
|
||||
public function setPublishDate(\DateTime $date): void
|
||||
{
|
||||
$this->publishDate = $date;
|
||||
}
|
||||
|
||||
public function getExpirationDate(): ?\DateTime
|
||||
{
|
||||
return $this->expirationDate;
|
||||
}
|
||||
|
||||
public function setExpirationDate(?\DateTime $date): void
|
||||
{
|
||||
$this->expirationDate = $date;
|
||||
}
|
||||
|
||||
public function getIp(): string
|
||||
{
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
public function setIP(string $ip): void
|
||||
{
|
||||
$this->ip = $ip;
|
||||
}
|
||||
|
||||
public function getSecret(): ?string
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
public function setSecret(?string $secret): void
|
||||
{
|
||||
$this->secret = $secret;
|
||||
}
|
||||
|
||||
public function isPrivate(): bool
|
||||
{
|
||||
return $this->private;
|
||||
}
|
||||
|
||||
public function setPrivate(bool $private): void
|
||||
{
|
||||
$this->private = $private;
|
||||
}
|
||||
public readonly ?string $secret,
|
||||
) {}
|
||||
}
|
||||
skobkin
commented
You can use You can use `self` as return type hint too.
|
Loading…
Reference in a new issue
show_paste
at least.