Creative Commons License
This work is licensed under a
Creative Commons
Attribution-Share Alike 3.0
Unported License.

Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Symfony hosting done right

ServerGrove, outstanding support at the right price for your Symfony hosting needs.
servergrove.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com

Come usare l'ereditarietà per sovrascrivere parti di un bundle

Come usare l'ereditarietà per sovrascrivere parti di un bundle

Lavorando con bundle di terze parti, ci si troverà probabilmente in situazioni in cui si vuole sovrascrivere un file in quel bundle con un file del proprio bundle. Symfony fornisce un modo molto conveniente per sovrascrivere cose come controllori, template, traduzioni e altri file nella cartella Resources/ di un bundle.

Per esempio, si supponga di aver installato FOSUserBundle, ma di voler sovrascrivere il suo template base layout.html.twig, così come uno dei suoi controllori. Si supponga anche di avere il proprio AcmeUserBundle, in cui si vogliono mettere i file sovrascritti. Si inizi registrando FOSUserBundle come "genitore" del proprio bundle:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// src/Acme/UserBundle/AcmeUserBundle.php
namespace Acme\UserBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class AcmeUserBundle extends Bundle
{
    public function getParent()
    {
        return 'FOSUserBundle';
    }
}

Con questa semplice modifica, si possono ora sovrascrivere diverse parti di FOSUserBundle, semplicemente creando un file con lo stesso nome.

Note

A dispetto del nome del metodo, non c'è una relatzione genitore/figlio tra i bundle, è solo un modo per estendere e sovrascrivere un bundle esistente.

Sovrascrivere i controllori

Si supponga di voler aggiungere alcune funzionalità a registerAction di un RegistrationController, che sta dentro FOSUserBundle. Per poterlo fare, creare un proprio RegistrationController.php, ridefinire i metodi originali del bundle e cambiarne le funzionalità:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// src/Acme/UserBundle/Controller/RegistrationController.php
namespace Acme\UserBundle\Controller;

use FOS\UserBundle\Controller\RegistrationController as BaseController;

class RegistrationController extends BaseController
{
    public function registerAction()
    {
        $response = parent::registerAction();

        // ... fare qualcosa
        return $response;
    }
}

Tip

A seconda di quanto si vuole cambiare il comportamento, si potrebbe voler richiamare parent::registerAction() oppure sostituirne completamente la logica con una propria.

Note

Sovrascrivere i controllori in questo modo funziona solo se il bundle fa riferimento al controllore tramite la sintassi standard FOSUserBundle:Registration:register in rotte e template. Questa è la best practice.

Sovrascrivere risorse: template, rotte, traduzioni, validazione, ecc.

Anche molte risorse possono essere sovrascritte, semplicemente creando un file con lo stesso percorso del bundle genitore.

Per esempio, è molto comune l'esigenza di sovrascrivere il template layout.html.twig di FOSUserBundle, in modo che usi il layout di base della propria applicazione. Poiché il file si trova in Resources/views/layout.html.twig di FOSUserBundle, si può creare il proprio file nello stesso posto in AcmeUserBundle. Symfony ignorerà completamente il file dentro FOSUserBundle e userà il nuovo file al suo posto.

Lo stesso vale per i file delle rotte, della configurazione della validazione e di altre risorse.

Note

La sovrascrittura di risorse funziona solo se ci si riferisce alle risorse col metodo @FosUserBundle/Resources/config/routing/security.xml. Se ci si riferisce alle risorse senza usare la scorciatoia @NomeBundle, non possono essere sovrascritte in tal modo.

Caution

I file delle traduzioni non funzionano nel modo descritto sopra. Tutti i file di traduzione sono raggruppati in un insieme di domini di "pool" (uno per ciascuno). Symfony carica i file delle traduzioni prima dai bundle (nell'ordine in cui i bundle sono inizializzati) e poi dalla cartella app/Resources. Se la stessa traduzione compare in più risorse, sarà applicata la traduzione della risorsa caricata per ultima.