IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel pour apprendre à utiliser le framework Laravel 4


précédentsommairesuivant

XXVIII. Chapitre 28 : Créer une commande

Nous avons vu plusieurs fois l'utilisation d'Artisan au cours des précédents articles, que ce soit pour créer un contrôleur, remplir une base, générer l'autoload, créer un workbench… Pour connaître toutes les commandes disponibles il suffit de taper dans la console php artisan list :

Image non disponible

Et pour obtenir le détail d'une commande particulière on utilise la syntaxe php artisan help commande(ou la syntaxe courte php artisan commande -h) :

Image non disponible

Mais il se peut que l'on ait besoin d'une commande non prévue, un truc à notre sauce. Laravel nous permet de composer une commande personnalisée facilement, c'est ce que nous allons voir avec un exemple.

Il existe la commande command:make pour créer un paquetage, comme nous l'avons vu dans un chapitre précédentchapitre précédent précédentChapitre 26 : Création d'un paquetage. Mais il y a un truc un peu agaçant, il faut au préalable renseigner le fichier app/config/workbench avec le nom et l'email. On va créer une commande qui permet de renseigner ces deux valeurs et ensuite lancer la commande de base.

Vous avez la documentation correspondante ici. Je n'ai pas détaillé toutes les possibilités, reportez-vous à cette page pour les détails.

XXVIII-A. Générer la classe

La première chose consiste à générer la classe avec Artisan. La syntaxe est simple :

Image non disponible

Le nom de la classe doit comporter le suffixe Command. Voici le code généré :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
 
class WorkbenchPlusCommand extends Command {
 
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'command:name';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description.';
 
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
 
    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        //
    }
 
    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return array(
            array('example', InputArgument::REQUIRED, 'An example argument.'),
        );
    }
 
    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return array(
            array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null),
        );
    }
 
}

Et on enregistre notre commande dans le fichier app/start/artisan.php :

 
Sélectionnez
Artisan::add(new WorkbenchPlusCommand);

On va commencer par renseigner le nom de la commande ainsi que sa description :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
/**
 * The console command name.
 *
 * @var string
 */
protected $name = 'workbenchplus';
 
/**
 * The console command description.
 *
 * @var string
 */
protected $description = 'Create a new package workbench with name and email.';

On vérifie que la commande est bien prise en compte avec php artisan list :

Image non disponible

XXVIII-A-1. Argument et options

Une commande peut avoir un argument et des options. C'est le cas de la commande workbench. On peut le vérifier :

Image non disponible

Puisqu'on veut reproduire cette commande et la compléter, il faut prévoir son argument et ses options :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
/**
 * Get the console command arguments.
 *
 * @return array
 */
protected function getArguments()
{
    return array(
        array('package', InputArgument::REQUIRED, 'The name (vendor/name) of the package.'),
    );
}
 
/**
 * Get the console command options.
 *
 * @return array
 */
protected function getOptions()
{
    return array(
        array('resources', null, InputOption::VALUE_NONE, 'Create Laravel specific directories.'),
    );
}

On vérifie :

Image non disponible

XXVIII-A-2. Codage de la commande

Il ne nous reste plus qu'à coder la commande. Il nous faut :

  • lire le fichier app/config/workbench.php ;
  • interroger l'utilisateur pour avoir les valeurs pour le nom et l'email ;
  • modifier le fichier app/config/workbench.php en conséquence ;
  • lancer la commande workbench.

Laravel offre la classe Illuminate\Filesystem\Filesystem pour faciliter les manipulations de fichiers. Nous allons donc utiliser cette classe. Voici le code complet de la commande (comme les commentaires de base étaient en anglais j'ai continué dans ce langage Image non disponible) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
 
class WorkbenchPlusCommand extends Command {
 
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'workbenchplus';
 
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create a new package workbench.';
 
    /**
     * The file system instance.
     *
     * @var string
     */
    protected $files;
 
    /**
     * Set configuration item
     *
     * @param  string $contents
     * @param  string $key
     * @param  string $value
     * @return void
     */
    private function setItem(&$contents, $key, $value)
    {
        $pattern = "#('$key' => ').*'#";
        $replacement = "$1$value'";
        $contents = preg_replace($pattern, $replacement, $contents);
    }
    /**
     * Create a new command instance.
     *
     * @param  \Illuminate\Filesystem\Filesystem  $files
     * @return void
     */
    public function __construct(Filesystem $files)
    {
        parent::__construct();
        $this->files = $files;
    }
 
    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        // Name
        $name = $this->ask("What is the name ?");
        // Email
        $email = $this->ask("What is the email ?");
        // Workbench config file content
        $contents = $this->files->get($path = $this->laravel['path'].'/config/workbench.php');    
        // Set name
        $this->setItem($contents, 'name', $name);
        // Set email
        $this->setItem($contents, 'email', $email);
        // Save config file
        $this->files->put($path, $contents);
        // Call workbench command
        $this->call('workbench', array(
            'package' => $this->argument('package'), 
            '--resources' => $this->option('resources') 
        ));
    }
 
    /**
     * Get the console command arguments.
     *
     * @return array
     */
    protected function getArguments()
    {
        return array(
            array('package', InputArgument::REQUIRED, 'The name (vendor/name) of the package.'),
        );
    }
 
    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return array(
            array('resources', null, InputOption::VALUE_OPTIONAL, 'Create Laravel specific directories.', null),
        );
    }
 
}

Vous remarquez que j'ai prévu l'injection d'une instance de la classe Filesystem plutôt que de l'utiliser directement dans le code. C'est une approche orientée sur la testabilité du code. Mais du coup il faut compléter l'appel de la commande dans le fichier app/start/artisan.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
use Illuminate\Filesystem\Filesystem;
 
/*
|--------------------------------------------------------------------------
| Register The Artisan Commands
|--------------------------------------------------------------------------
|
| Each available Artisan command must be registered with the console so
| that it is available to be called. We'll register every command so
| the console gets access to each of the command object instances.
|
*/
 
Artisan::add(new WorkbenchPlusCommand(new Filesystem));

Et son test :

Image non disponible

On vérifie l'écriture des valeurs dans le fichier app/config/workbench.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
return array(
 
    /*
    |--------------------------------------------------------------------------
    | Workbench Author Name
    |--------------------------------------------------------------------------
    |
    | When you create new packages via the Artisan "workbench" command your
    | name is needed to generate the composer.json file for your package.
    | You may specify it now so it is used for all of your workbenches.
    |
    */
 
    'name' => 'bestmomo',
 
    /*
    |--------------------------------------------------------------------------
    | Workbench Author E-Mail Address
    |--------------------------------------------------------------------------
    |
    | Like the option above, your e-mail address is used when generating new
    | workbench packages. The e-mail is placed in your composer.json file
    | automatically after the package is created by the workbench tool.
    |
    */
 
    'email' => 'bestmomo@chez.moi',
 
);

Et la création du workbench :

Image non disponible

On supprime ce dossier et on teste avec l'option -resources :

Image non disponible

Résultat :

Image non disponible

précédentsommairesuivant

Copyright © 2017 Laravel. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.