Mon template de commande Symfony

Publié le 24/11/2019 • Mis à jour le 24/11/2019

English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧

On peut générer une commande avec le bundle Maker (php bin/console make:command). J'utilise un template légérement différent ou le texte d'aide est généré dynamiquement avec des constantes. Celles-ci sont aussi utilisées en tant que paramétres des différentes options afin de ne pas avoir de code dupliqué. Supprimez le paramètre du constructeur, il est spécifique à ce blog (c'est un paramètre "nommé" dans le fichier services.yaml). Pour lancer ce snippet, j'utiliserai cette fois un testeur de commandes (CommandTester) au lieu d'utiliser le composant Process.


<?php declare(strict_types=1);

// src/Command/SendSlackNotificationCommand.php

namespace App\Command;

use Monolog\Logger;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * @see SendSlackNotificationCommand::DESC
 */
class SendSlackNotificationCommand extends Command
{
    private const STATUS_OK            = 0;
    private const STATUS_ERROR         = -1;
    private const STATUS_NOTHING_TO_DO = -2;

    public const NAMESPACE  = 'strangebuzz'; // used by command tester
    public const CMD        = 'send-slack';
    private const DESC      = 'Send a message on a slack channel.';
    private const ARG1_KEY  = 'message';
    private const ARGS = [
       self::ARG1_KEY => 'The message to send'
    ];

    private $slackLogger;

    public function __construct(Logger $slackLogger)
    {
        parent::__construct();
        $this->slackLogger = $slackLogger;
    }

    protected function configure(): void
    {
        $namespace = self::NAMESPACE;
        $cmd = self::CMD;
        $desc = self::DESC;
        $arg1 = self::ARGS[self::ARG1_KEY];
        $this
            ->setName($namespace.':'.$cmd)
            ->setDescription(self::DESC)
            ->addArgument(self::ARG1_KEY, InputArgument::REQUIRED, self::ARGS[self::ARG1_KEY])
            ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
            ->setHelp(
                <<<EOT
{$desc}

DEV:
<info>php bin/console {$namespace}:{$cmd} "{$arg1}" -v</info>

PROD:
<info>php bin/console {$namespace}:{$cmd} "{$arg1}" --no-debug</info>
EOT
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);
        $message = $input->getArgument(self::ARG1_KEY);
        $message = \is_string($message) ? $message : ''; // You know, for PHPStan. 🙃
        $this->slackLogger->info($message);
        $io->note($message);
        $io->success(' -> DONE!');

        return self::STATUS_OK;
    }
}
En bonus, le snippet permettant d'utiliser ce code : 🎉
<?php declare(strict_types=1);

namespace App\Controller\Snippet;

use App\Command\SendSlackNotificationCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\KernelInterface;

/**
 * J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
 * Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
 * ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Les services sont injectés dans le constructeur du contrôleur principal.
 *
 * @property KernelInterface              $kernel
 * @property SendSlackNotificationCommand $sendSlackNotificationCommand
 */
trait Snippet58Trait
{
    public function snippet58(): void
    {
        $app = new Application($this->kernel);
        $app->add($this->sendSlackNotificationCommand);
        $command = $app->find(SendSlackNotificationCommand::NAMESPACE.':'.SendSlackNotificationCommand::CMD);
        $commandTester = new CommandTester($command);
        $commandTester->execute([
            'command' => $command->getName(),
            'message' => 'Hello World!'
        ]);

        // Sorry the output doesn't look great but it will be the case when running it from your console.
        echo $commandTester->getDisplay(); // That's it! 😁
    }
}

 Exécuter le snippet  Plus sur Stackoverflow   Lire la doc