Generare URL e inviare email da console

Sfortunatamente, la linea di comando non sa nulla degli host virtuali o dei nomi di dominio. Questo vuol dire che, se si generano URL assoluti da un comando da console, probabilmente si otterrà qualcosa come http://localhost/pippo/pluto, il che non è molto utile.

Per risolvere il problema, bisogna configurare il “contesto della richiesta”, che è un modo particolare per dire che occorre configurare l’ambiente, in modo tale che sappia quale URL vada usato per la generazione.

Ci sono due modi per configurare il contesto della richiesta: a livello di applicazione o per comando.

Configurare il contesto della richiesta globalmente

Per configurare il contesto della richiesta, usato dal generatore di URL, si possono ridefinire i parametri che usa come valori predefiniti, per cambiare l’host (localhost) e lo schema (http) predefiniti. Si noti che ciò non impatta sugli URL generati tramite normali richieste web, poiché sovrascriveranno tali valori.

Si noti che questo non ha impatto su URL generati tramite normali richieste web, perché queste ultime sovrascriveranno i valori predefiniti.

  • YAML
    # app/config/parameters.yml
    parameters:
        router.request_context.host: example.org
        router.request_context.scheme: https
        router.request_context.base_url: my/path
    
  • XML
    <!-- app/config/parameters.xml -->
    <?xml version="1.0" encoding="UTF-8"?>
    
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    
        <parameters>
            <parameter key="router.request_context.host">example.org</parameter>
            <parameter key="router.request_context.scheme">https</parameter>
            <parameter key="router.request_context.base_url">my/path</parameter>
        </parameters>
    </container>
    
  • PHP
    // app/config/config_test.php
    $container->setParameter('router.request_context.host', 'example.org');
    $container->setParameter('router.request_context.scheme', 'https');
    $container->setParameter('router.request_context.base_url', 'my/path');
    

Configurare il contesto della richiesta per comando

Per cambiare un singolo comando, si può semplicemente recuperare il servizio del contesto della richiesta e sovrascrivere le sue impostazioni:

// src/Acme/DemoBundle/Command/DemoCommand.php

// ...
class DemoCommand extends ContainerAwareCommand
{
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $context = $this->getContainer()->get('router')->getContext();
        $context->setHost('example.com');
        $context->setScheme('https');
        $context->setBaseUrl('my/path');

        // ... del codice
    }
}

Usare lo spool memory

Nuovo nella versione 2.3: Se si usano Symfony 2.3+ e SwiftmailerBundle 2.3.5+, lo spool memory è ora gestita automaticamente in CLI e il codice successivo non è più necessario.

L’invio di email in un comando da console funziona nello stesso modo descritto in Spedire un’email, tranne per il fatto che viene usato lo spool memory.

Quando si usa lo spool memory (vedere Lo spool della posta per maggiori informazioni), bisogna essere consapevoli che, a causa del modo in cui Symfony gestisce i comandi da console, le email non sono inviate automaticamente. Ci si deve occupare del flush della coda da soli. Usare il codice seguente per inviare email da dentro un comando di console:

$message = new \Swift_Message();

// ... preparare il messaggio

$container = $this->getContainer();
$mailer = $container->get('mailer');

$mailer->send($message);

// flush manuale della coda
$spool = $mailer->getTransport()->getSpool();
$transport = $container->get('swiftmailer.transport.real');

$spool->flushQueue($transport);

Un’altra possibilità è quella di creare un ambiente usato solo dai comandi di console e usare un metodo di spool differente.

Nota

Ci si deve occupare dello spool solo quando si usa lo spool memory. Se invece si usa lo spool file (o nessuno spool), non occorre alcun flush manuale della coda all’interno del comando.