2015-03-10 15 views
9

ho bisogno di sovrascrivere il file /vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.phpQual è il modo "giusto" per ignorare un'estensione symfony da un altro fascio

Si carica il getAssetUrl ramoscello dal fascio tramite la funzione ramoscello 'patrimoniale'

/** 
* Returns a list of functions to add to the existing list. 
* 
* @return array An array of functions 
*/ 
public function getFunctions() 
{ 
    return array(
     new \Twig_SimpleFunction('asset', array($this, 'getAssetUrl')), 
     new \Twig_SimpleFunction('assets_version', array($this, 'getAssetsVersion')), 
    ); 
} 

voglio ignorare la funzione ramoscello di asset() senza toccare i file di base, che altrimenti sarebbe venir meno per il prossimo aggiornamento symfony

risposta

6

Considera il tuo codice dal vivo nello spazio dei nomi AppBundle. Prima crea la configurazione del servizio in app/config.yml o src/AppBundle/Resources/config/something.yml (devi caricare questo file di configurazione in bundle extension). Non dimenticare di metterlo sotto chiave servizi.

twig.extension.assets: 
    class:  AppBundle\Twig\AssetsExtension 
    arguments: ["@service_container", "@?router.request_context"] 
    public: false 
    tags: 
     - { name: twig.extension } 

Ora creiamo estensione src/AppBundle/Ramoscello/AssetsExtension.php. Questa classe eredita dall'estensione originale e sostituirò un solo metodo (nel modello asset()).

<?php 

namespace AppBundle\Twig; 

class AssetsExtension extends \Symfony\Bundle\TwigBundle\Extension\AssetsExtension 
{ 
    public function getAssetUrl($path, $packageName = null, $absolute = false, $version = null) 
    { 
     return parent::getAssetUrl('/something/' . $path, $packageName, $absolute, $version); 
    } 
} 

Ora, dopo ricarica, tutte le risorse dovrebbero essere errate e prefisso/qualcosa/per impostazione predefinita. Puoi provare ad eliminare la cache di Symfony in caso di problemi. Ho testato questo scenario su Symfony 2.5.5.

Un altro modo per lavorare con i servizi integrati è compiler pass. Nel passaggio del compilatore puoi modificare tutto il contenitore del servizio Symfony (cancella, sostituisci, modifica i servizi). Symfony è tutto su DIC. Spero che sia una soluzione abbastanza buona.

+1

Invece di duplicare la definizione di servizio si può anche solo impostare il parametro di twig.extension.assets.class per puntare alla nuova classe di estensione. Ma il passaggio del compilatore è davvero la soluzione migliore. In realtà, dubito della necessità di cambiare getAssertUrl. Probabilmente causerà più problemi di quanti ne valga la pena, specialmente se si utilizzano modelli di terze parti. Prendi in considerazione solo la scrittura della tua estensione e funzione. – Cerad

+0

Sì, è vero. Puoi anche impostare parametro twig.extension.assets.class con estensione personalizzata. La domanda era chiara: come sovrascrivere asset() senza toccare il codice Symfony. Non ho davvero idea del caso d'uso perché user3531149 ne ha bisogno. – kba

+0

La tua soluzione va bene. Spero che questo non sia un altro drive by. – Cerad

6

Fornisco un'altra soluzione, perché sin da symfony 3.0 i nomi delle classi dei servizi non sono più sostituibili. Devi scegliere la soluzione del pass del compilatore.

Diciamo che si desidera ignorare funzione nel ramoscello url(), è necessario creare un passaggio compilatore per esso e cambiare la definizione:

<?php 
// AppBundle/AppBundle.php 

namespace AppBundle; 

use AppBundle\DependencyInjection\Compiler\TwigRoutingExtensionPass; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 

class AppBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     parent::build($container); 

     $container->addCompilerPass(new TwigRoutingExtensionPass()); 
    } 
} 

quindi creare il file di TwigRoutingExtensionPass:

<?php 
// AppBundle/DependencyInjectoin/Compiler/TwigRoutingExtensionPass.php  

namespace AppBundle\DependencyInjection\Compiler; 

use AppBundle\Twig\Extension\RoutingExtension; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 

class TwigRoutingExtensionPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     if (false === $container->hasDefinition('twig.extension.routing')) { 
      return; 
     } 

     $definition = $container->getDefinition('twig.extension.routing'); 
     $definition->setClass(RoutingExtension::class); 
    } 
} 

E poi crea il tuo file RoutingExtension.

Se si vuole iniettare alcuni servizi per la nuova estensione:

<?php 

    $definition->addArgument('some_service'); 
    // OR 
    $definition->addMethodCall('setSomeService' [$container->get('some_service')]); 
+1

Ho provato la tua soluzione, ma ricevo un errore 'L'estensione" Symfony \ Bridge \ Twig \ Extension \ TranslationExtension "non è abilitata in" nel mio caso sto provando a sovrascrivere la funzione trans(). qualche idea ? –

+1

scusa ma, hai abilitato il traduttore? http://symfony.com/doc/current/translation.Configurazione html # – nikophil

Problemi correlati