Ridimensionamento delle immagini
Nel design della pagina della conferenza, le foto sono limitate a una dimensione massima di 200 x 150 pixel. Che ne dite di ottimizzare le immagini e ridurne le dimensioni se l'immagine originale caricata è più grande dei limiti?
Questo è un lavoro perfetto da aggiungere al workflow dei commenti, probabilmente subito dopo che il commento è stato convalidato e subito prima della sua pubblicazione.
Aggiungiamo un nuovo stato ready
e una transizione optimize
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
--- a/config/packages/workflow.yaml
+++ b/config/packages/workflow.yaml
@@ -16,6 +16,7 @@ framework:
- potential_spam
- spam
- rejected
+ - ready
- published
transitions:
accept:
@@ -29,13 +30,16 @@ framework:
to: spam
publish:
from: potential_spam
- to: published
+ to: ready
reject:
from: potential_spam
to: rejected
publish_ham:
from: ham
- to: published
+ to: ready
reject_ham:
from: ham
to: rejected
+ optimize:
+ from: ready
+ to: published
Generare una rappresentazione visiva della nuova configurazione del workflow per assicurarci che descriva ciò che vogliamo:
1
$ symfony console workflow:dump comment | dot -Tpng -o workflow.png
Ottimizzare le immagini con Imagine
L'ottimizzazione delle immagini sarà fatta grazie a GD (verificare che l'installazione locale di PHP abbia l'estensione GD abilitata) e Imagine:
1
$ symfony composer req "imagine/imagine:^1.2"
Il ridimensionamento di un'immagine può essere eseguito tramite la seguente classe:
Dopo aver ottimizzato la foto, salviamo il nuovo file al posto di quello originale. Tuttavia, si potrebbe voler mantenere l'immagine originale da qualche parte.
Aggiungere un nuovo passo al workflow
Modificare il workflow per gestire il nuovo stato:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
--- a/src/MessageHandler/CommentMessageHandler.php
+++ b/src/MessageHandler/CommentMessageHandler.php
@@ -2,6 +2,7 @@
namespace App\MessageHandler;
+use App\ImageOptimizer;
use App\Message\CommentMessage;
use App\Repository\CommentRepository;
use App\SpamChecker;
@@ -21,10 +22,12 @@ class CommentMessageHandler implements MessageHandlerInterface
private $bus;
private $workflow;
private $mailer;
+ private $imageOptimizer;
private $adminEmail;
+ private $photoDir;
private $logger;
- public function __construct(EntityManagerInterface $entityManager, SpamChecker $spamChecker, CommentRepository $commentRepository, MessageBusInterface $bus, WorkflowInterface $commentStateMachine, MailerInterface $mailer, string $adminEmail, LoggerInterface $logger = null)
+ public function __construct(EntityManagerInterface $entityManager, SpamChecker $spamChecker, CommentRepository $commentRepository, MessageBusInterface $bus, WorkflowInterface $commentStateMachine, MailerInterface $mailer, ImageOptimizer $imageOptimizer, string $adminEmail, string $photoDir, LoggerInterface $logger = null)
{
$this->entityManager = $entityManager;
$this->spamChecker = $spamChecker;
@@ -32,7 +35,9 @@ class CommentMessageHandler implements MessageHandlerInterface
$this->bus = $bus;
$this->workflow = $commentStateMachine;
$this->mailer = $mailer;
+ $this->imageOptimizer = $imageOptimizer;
$this->adminEmail = $adminEmail;
+ $this->photoDir = $photoDir;
$this->logger = $logger;
}
@@ -64,6 +69,12 @@ class CommentMessageHandler implements MessageHandlerInterface
->to($this->adminEmail)
->context(['comment' => $comment])
);
+ } elseif ($this->workflow->can($comment, 'optimize')) {
+ if ($comment->getPhotoFilename()) {
+ $this->imageOptimizer->resize($this->photoDir.'/'.$comment->getPhotoFilename());
+ }
+ $this->workflow->apply($comment, 'optimize');
+ $this->entityManager->flush();
} elseif ($this->logger) {
$this->logger->debug('Dropping comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);
}
Si noti che $photoDir
viene automaticamente iniettato, avendo in precedenza definito un bind nel container per tale variabile:
Salvare i dati caricati in produzione
Abbiamo già definito una speciale cartella in lettura e scrittura per i file caricati in .platform.app.yaml
. Ma il mount è locale. Se vogliamo che il container e il consumer dei messaggi siano in grado di accedere allo stesso mount, dobbiamo creare un servizio per i file:
1 2 3 4 5 6 7 8 9 10
--- a/.platform/services.yaml
+++ b/.platform/services.yaml
@@ -11,3 +11,7 @@ varnish:
vcl: !include
type: string
path: config.vcl
+
+files:
+ type: network-storage:1.0
+ disk: 256
Usarlo per la cartella di caricamento delle foto:
1 2 3 4 5 6 7 8 9 10 11
--- a/.platform.app.yaml
+++ b/.platform.app.yaml
@@ -35,7 +35,7 @@ web:
mounts:
"/var": { source: local, source_path: var }
- "/public/uploads": { source: local, source_path: uploads }
+ "/public/uploads": { source: service, service: files, source_path: uploads }
relationships:
database: "database:postgresql"
Questo dovrebbe essere sufficiente per farlo funzionare in produzione.