9. VichUploaderBundle
- File and folder names
- Inject the file into the entity
- Delete the file upon removal of the entity
- Templating helpers
https://github.com/dustin10/VichUploaderBundle
15. Basic usage
use GaufretteFilesystem;
use GaufretteAdapterLocal as LocalAdapter;
// First, you need a filesystem adapter
$adapter = new LocalAdapter('/var/media');
// Then, you can access your filesystem directly
var_dump($filesystem->read('myFile')); // bool(false)
$filesystem->write('myFile', 'Hello world!');
//Then, create filesystem with adapter
$filesystem = new Filesystem($adapter);
16. Extras: Resolvable filesystem
https://github.com/Gaufrette/extras
- AwsS3PublicUrlResolver: Create a URL for an object stored
on S3 with public ACL.
- AwsS3PresignedUrlResolver: Create a temporary URL, valid
for a given amount of time.
- StaticUrlResolver: Resolves the object into an URL by
concatenating a prefix with object path.
17. Usage example
$client = // AwsS3 client instantiation
$expDate = new DateTime('+ 1 hour');
$decorated = new Filesystem(
new AwsS3($client, 'my_bucket', ['directory' => 'root/dir'])
);
$filesystem = new ResolvableFilesystem(
$decorated,
new AwsS3PresignedUrlResolver($client, 'my_bucket', 'root/dir', $expDate)
);
$url = $filesystem->resolve('/foo/bar.png');
// https://eu-west-1.blabla.aws.com/my_bucket/root/dir/foo/bar.png?token
20. Basic usage
// get from filesystem map service
$container->get('knp_gaufrette.filesystem_map')->get('bar');
//get by filesystem alias “foo”
$container->get('gaufrette.foo_filesystem');
//stream_wrapper usage example
$fileStream = sprintf('gaufrette://your_defined_fs/%s', 'path/to/file.pdf');
$response = new BinaryFileResponse($fileStream);
25. Cache Resolvers
interface ResolverInterface
{
public function isStored($path, $filter);
public function resolve($path, $filter);
public function store(BinaryInterface $binary, $path, $filter);
public function remove(array $paths, array $filters);
}
28. kernel.terminate
How it works: fastcgi_finish_request()
When to use:
- short time processes
- small number of requests
Possible problems:
- exceptions breaks profiler
- execution control complexity
- pm.max_children limitation
32. Message Producer
//send to all "fire and forget"
$producer->sendEvent('a_topic', 'Hello there!');
use EnqueueClientProducerInterface;
$producer = $container->get(ProducerInterface::class);
// send to one consumer
$producer->sendCommand('a_processor_name', 'Hello there!');
33. Spool Producer
use EnqueueClientSpoolProducer;
$spoolProducer = $container->get(SpoolProducer::class);
// messages is being sent on console.terminate or kernel.terminate event
$spoolProducer->sendEvent('a_topic', 'Hello there!');
$spoolProducer->sendCommand('a_processor_name', 'Hello there!');
// you could send queued messages manually by calling flush method
$spoolProducer->flush();
34. Message Processor
use InteropQueuePsrProcessor;
use InteropQueuePsrMessage;
use InteropQueuePsrContext;
class SendMailProcessor implements PsrProcessor
{
public function process(PsrMessage $message, PsrContext $context)
{
$this->mailer->send('foo@example.com', $message->getBody());
return self::ACK;
}
}
35. Consumer extensions
use InteropQueuePsrContext;
use EnqueueConsumptionChainExtension;
use EnqueueConsumptionQueueConsumer;
use EnqueueConsumptionExtensionReplyExtension;
/** @var InteropQueuePsrContext $psrContext */
$queueConsumer = new QueueConsumer(
$psrContext,
new ChainExtension([
new ReplyExtension()
])
);
36. Reply extension
use EnqueueConsumptionResult;
use InteropQueuePsrProcessor;
use InteropQueuePsrMessage;
use InteropQueuePsrContext;
class SendMailProcessor implements PsrProcessor
{
public function process(PsrMessage $message, PsrContext $context)
{
$this->mailer->send('foo@example.com', $message->getBody());
$replyMessage = $context->createMessage('Message has been sent');
return Result::reply($replyMessage);
}
}
37. Async commands
(enqueue/async-command)
use EnqueueAsyncCommand{CommandResult, Commands, RunCommand};
$promise = $producer->sendCommand(
Commands::RUN_COMMAND,
new RunCommand('debug:container'),
true
);
// do other stuff.
if ($replyMessage = $promise->receive(5000)) {
$result = CommandResult::jsonUnserialize($replyMessage->getBody());
echo $result->getOutput();
}
40. Long running commands
● Clear all Doctrine ORM entity managers (to prevent outdated entities from being
updated)
● Reset all closed Doctrine ORM entity managers (after a failed transaction)
● Close all database connections (to prevent database timeout errors)
● Clear all Monolog "fingers crossed" handlers (clears messages and resets the handler
when there was no failure during the execution of a task)
● Close all Monolog buffer handlers (clears log messages that were buffered during the
execution of a task)
● Flush all Swift Mailer "in memory" spools (i.e. send spooled e-mails)
● Flush all unsent Sentry errors (in case they are handled async)
https://github.com/LongRunning/LongRunning
''long_running.delegating_cleaner'' service
42. Message Bus
use AppMessageMyMessage;
use SymfonyComponentMessengerMessageBus;
use SymfonyComponentMessengerHandlerLocatorHandlerLocator;
use SymfonyComponentMessengerMiddlewareHandleMessageMiddleware;
$bus = new MessageBus([
new HandleMessageMiddleware(new HandlerLocator([
MyMessage::class => $handler,
])),
]);
//Default middleware: LoggingMiddleware, SendMessageMiddleware, HandleMessageMiddleware
$result = $bus->dispatch(new MyMessage(/* ... */));