Symfony workshop p3

 
  • Event Dispatcher
  • Services
  • Repository as service
 

Event Dispatcher

Click to read more about event dispatcher

The Symfony EventDispatcher component implements the Mediator pattern.

 

The Mediator pattern in one scratch.

Click to read more about mediator.

Observer

 

Mediator

 

Symfony Framework Events

Each event has access to the following information:

getRequestType() - can be master or sub request.

getKernel() - Kernel

getRequest() - Current Request being handled.

kernel.request
kernel.controller
kernel.view
kernel.response
kernel.finish_request
kernel.terminate
kernel.exception

kernel.reques

 

Typical Purposes: To add more information to the Request, initialize parts of the system, or return a Response if possible.

 

kernel.controller

 

Typical Purposes: Initialize things or change the controller just before the controller is executed.

 

kernel.response

 

Typical Purposes: Modify the Response object just before it is sent

 

Sub-Request

 
{# an internal sub-request via a regular URL #}
{{ render(url('route_name')) }}
//some controller action
$payload = json_decode($request->getContent(),true);

$note->setTitle($payload['title']);
$note->setContent($payload['content']);
//some controller action
$note->setTitle($request->get('title'));
$note->setContent($request->get('content'));

We are going to use krnel.request even to automatically convert JSON to parameters list.


# src/AppBundle/EventListener/RequestListener.php

class RequestListener
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();

        if ($this->isRequestJson($request))
        {
            $parameters = json_decode($request->getContent(),true);

            if(is_array($parameters))
            {
                $request->request->add($parameters);
            }
        }
    }
}
# app/config/services.yml

services:
  kernel.listener.onrequest:
    class: AppBundle\EventListener\RequestListener
    tags:
      - { name: kernel.event_listener, event: kernel.request }

Registering listener

 

At this point, if you've done everything right, event listener should work and convert Angular request to parameters bug.

1

But what this config above is actually for, and what it is doing?

 

Service container

 

Service is any PHP object that performs some sort of "global" task.

 

Service

 

Service Container is simply a PHP object that manages the instantiation of services

 

Registering a service

 
# app/config/services.yml
services:
    app.mailer:
        class:        AppBundle\Mailer
        arguments:    ["sendmail"]

Getting a service

 
public function someAction()
{
    // ...
    $mailer = $this->get('app.mailer');
}
parameters:
    # ...
    mailer.transport: "sendmail"

services:
    mailer:
        class:     Mailer
        arguments: ['%mailer.transport%']
    newsletter_manager:
        class:     NewsletterManager
        calls:
            - [setMailer, ["@mailer"]]

Using a Factory to Create Services

 
class NewsletterManagerFactory
{
    public function createNewsletterManager()
    {
        $newsletterManager = new NewsletterManager();

        // ...

        return $newsletterManager;
    }
}
services:
    newsletter_manager.factory:
        class: NewsletterManagerFactory
    newsletter_manager:
        class:   NewsletterManager
        factory: ["@newsletter_manager.factory", createNewsletterManager]
//some controller action
$noteRepository = $this->getDoctrine()
                    ->getManager()->getRepository(Note::class);
//some controller action
$noteRepository = $this->get('repository.note');

To do so, we will register a service, using factory

 
# app/config/services.yml
services:
  repository.note:
    class: Doctrine\ORM\EntityRepository
    factory: ["@doctrine.orm.default_entity_manager", getRepository]
    arguments:
      - AppBundle:Note

Move the repository.note  container definition into a new container resource file inside AppBundle.

 

We have placed repository service definition in app folder, but it would make more sense to place it in AppBundle

 

Then we have to import our resource file.

# app/config/config.yml
imports:
    - { resource: '@AppBundle/Resources/config/services.yml' }
AppBundle/Resources/config/services.yml

Symfony2 workshop week 3

By Semyon Radionov