2012-01-11 13 views
8

Sto provando a inviare una email da un ContainerAwareCommand in Symfony2. Ma ottengo questa eccezione quando il modello e-mail è un rendering da:Symfony2 Templating senza richiesta

$body = $this->templating->render($template, $data); 

Eccezione:

("You cannot create a service ("templating.helper.assets") of an inactive scope ("request").") 

ho trovato in github che questo helper bisogno l'oggetto di richiesta. Qualcuno sa come posso istanziare l'oggetto Request?

risposta

1

Dal momento che non si dispone di una richiesta, è necessario chiamare il servizio di template direttamente in questo modo:

$this->container->get('templating')->render($template, $data); 
+3

Questo non risolve il problema. Poiché viene utilizzato logn come asset (probabilmente non visibile direttamente nei modelli) è necessario avere un servizio RequestContext in qualche modo. – BetaRide

+0

io sono sempre lo stesso errore, ma questa soluzione non risolve problem.http: //stackoverflow.com/questions/17942738/erro-you-cannot-create-a-service-templating-helper-assets-of-an-inactive -sco – vishal

+0

Questa soluzione ha funzionato per me quando l'ho pubblicata. Non disputerò per un minuto che non funzioni con le versioni più recenti di Symfony di quanto non avessi in quel momento. Quando si tratta di uscire dai sentieri battuti, Symfony è un obiettivo in movimento. Non ho avuto tempo per il codice per un po ', quindi non posso davvero indagare al momento, ma potresti provare la soluzione di BetaRide. – Matthew

19

è necessario impostare il contenitore nel campo di applicazione a destra e dargli un (finto) richiesta. Nella maggior parte dei casi questo sarà sufficiente:

//before you render template add bellow code 
$this->getContainer()->enterScope('request'); 
$this->getContainer()->set('request', new Request(), 'request'); 

La storia completa è here. Se vuoi conoscere i dettagli leggi questo issue on github.

+1

FYI: Questa è stata sconsigliata e viene rimosso in Symfony 3, ed è stato sostituito con "setScope" sul livello di servizio: https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#dependencyinjection – Rvanlaak

4

Il problema sorge perché si utilizza la funzione Asset() nel modello.

Per impostazione predefinita, attività() si basa su richiesta servizio per generare URL ai vostri beni (ha bisogno di sapere qual è il percorso di base per voi sito web o che cosa è il nome di dominio se si utilizzano URL di asset assoluti , per esempio).

Ma quando si esegue l'applicazione dalla riga di comando non è disponibile .

Un modo per risolvere questo problema è di definire esplicitamente gli URL di base per il suo patrimonio in config.yml come questo:

framework: 
    templating: 
    assets_base_urls: { http: ["http://yoursite.com"], ssl: ["http://yoursite.com"] } 

E 'importante definire sia http e ssl, perché se si omette una di esse asset() dipenderà comunque dal servizio Richiesta.

Il (possibile) lato negativo è che tutti gli URL delle risorse saranno ora assoluti.

+0

Grazie per la tua chiara spiegazione e la tua soluzione, funziona perfettamente! Ho provato prima questa soluzione http://symfony.com/doc/current/cookbook/console/sending_emails.html ma senza successo –

+0

Con questa soluzione, tutte le risorse utilizzano un URL assoluto. A volte può essere un problema. – ke20

+0

Questa soluzione funziona solo se l'url http e l'URL ssl sono esattamente gli stessi. –

1

Seguendo la risposta di BetaRide mi ha messo sulla strada giusta ma non era sufficiente. Poi si è lamentato: "Impossibile generare un URL per la named route" "come tale percorso non esiste."

per creare una richiesta valida ho modificato per richiedere la radice del progetto in questo modo: (? Radice assicurata)

$request = new Request(); 
$request->create('/'); 
$this->container->enterScope('request'); 
$this->container->set('request', $request, 'request'); 

si potrebbe aver bisogno di chiamare un percorso diverso, radice ha lavorato per me solo bene.

Symfony2 Docs

Bonus Inoltre:

che ho dovuto fare così tanto di template/routing in CLI attraverso Symfony2 comandi che ho aggiornato il metodo initializeContainer() in AppKernel. Si crea un percorso verso la radice del sito, imposta il contesto router e falsi un login utente:

protected function initializeContainer() 
{ 
    parent::initializeContainer(); 
    if (PHP_SAPI == 'cli') { 

     $container = $this->getContainer(); 

     /** 
     * Fake request to home page for cli router. 
     * Need to set router base url to request uri because when request object 
     * is created it perceives the "/portal" part as path info only, not base 
     * url and thus router will not include it in the generated url's. 
     */ 
     $request = Request::create($container->getParameter('domain')); 
     $container->enterScope('request'); 
     $container->set('request', $request, 'request'); 
     $context = new RequestContext(); 
     $context->fromRequest($request); 
     $container->get('router')->setContext($context); 
     $container->get('router')->getContext()->setBaseUrl($request->getRequestUri()); 

     /** 
     * Fake admin user login for cli. Try database read, 
     * gracefully print error message if failed and continue. 
     * Continue mainly for doctrine:fixture:load when db still empty. 
     */ 
     try { 
      $user = $container->get('fos_user.user_manager')->findUserByUsername('admin'); 
      if ($user !== null) { 
       $token = $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); 
       $this->getContainer()->get('security.token_storage')->setToken($token); 
      } 
     } catch (\Exception $e) { 
      echo "Fake Admin user login failed.\n"; 
     } 
    } 
} 

Potrebbe non essere necessario l'ultima $container->get('router')->getContext()->setBaseUrl($request->getRequestUri()); parte, ma ho dovuto farlo perché la mia principale del sito era a dominio .com/siteroot/e il router è stato stripping/siteroot/away per la generazione di URL.

+0

FYI: Questa è stata sconsigliata e viene rimosso in Symfony 3, ed è stato sostituito con "setScope" sul livello di servizio: https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#dependencyinjection – Rvanlaak