Pour être concret, nous allons créer une tâche pour insérer des utilisateurs dans un groupe. La tâche va utiliser la tâche create-user du plugin sfDoctrineGuard, ainsi que la tâche add-group. Comme son nom l'indique (même si c'est en grand breton), la première tâche permet de créer un utilisateur tandis que la deuxième permet d'associer un utilisateur à un groupe. Ce que nous voulons faire peut en réalité être fait en deux commandes :
# ./symfony guard:create-user jean@dupond.org jean dupond
# ./symfony guard:add-group jean members
Cela fonctionne à la condition que le groupe members existe. La tâche en question va appeler la tâche create-user. Puis elle va créer le groupe passé en argument si besoin est et finalement va appeler la tâche add-group.
Le constructeur d'une tâche symfony a comme paramètre d'appel un objet sfEventDispatcher et un objet sfFormatter. Pour appeler d'autres tâches il suffira de leur passer les objets que l'on aura reçu à l'appel. Par exemple pour sfGuardCreateUser, ce sera:
$task = new sfGuardCreateUserTask($this->dispatcher, $this->formatter);
J'ai eu un peu de mal à trouver cette information dans la documentation officielle même si je suis sûr qu'elle existe quelque part ! Il faut ensuite invoquer la tâche avec les paramètres et les options qui vont bien. On passe les paramètres que la tâche create-user attend, à savoir email, nom d'utilisateur et mot de passe dans cet ordre. Pour les options (environnement et application), on se contente de passer ceux qu'on a reçu ! Cela donne cela :
$task_arguments = array();
$task_arguments['username'] = $arguments['username'];
$task_arguments['password'] = $arguments['password'];
$task_arguments['email'] = $arguments['email'];
$task->run($task_arguments, $options);
Après le reste du code est des plus classique dans une tâche. Comme on va travailler sur la base on charge les différentes classes Doctrine :
$databaseManager = new sfDatabaseManager($this->configuration);
Il faudra appeler de la même manière la tâche add-group mais comme elle n'a que deux paramètres ce sera bien plus simple :
$task_arguments = array();
$task_arguments['username'] = $arguments['username'];
$task_arguments['group'] = $arguments['group'];
$task = new sfGuardAddGroupTask($this->dispatcher, $this->formatter);
$task->run($task_arguments, $options);
L'ensemble du code ressemble alors à ça. Par parenthèses, si vous connaissez un moyen de mettre du code facilement dans dotclear et de le colorer et surtout de pouvoir après continuer à éditer son billet, je suis preneur. Yash c'est une plaie.
class guardAddUserToGroupTask extends sfBaseTask
{
protected function configure() {
$this->addArguments(array(new sfCommandArgument('username', sfCommandArgument::REQUIRED, 'Username'),
new sfCommandArgument('password', sfCommandArgument::REQUIRED, 'Password'),
new sfCommandArgument('email', sfCommandArgument::REQUIRED, 'Email address'),
new sfCommandArgument('group', sfCommandArgument::REQUIRED, 'Group name')
));
$this->addOptions(array(new sfCommandOption('application', null, sfCommandOption::PARAMETER_OPTIONAL, 'Application name', 'frontend'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'Environment', 'dev'),
));
$this->namespace = 'guard';
$this->name = 'adduser2group';
$this->briefDescription = 'Create a user and add it to a group';
$this->etailedDescription = <<configuration);
$task_arguments = array();
$task_arguments['username'] = $arguments['username'];
$task_arguments['password'] = $arguments['password'];
$task_arguments['email'] = $arguments['email'];
$task = new sfGuardCreateUserTask($this->dispatcher, $this->formatter);
$task->run($task_arguments, $options);
$group = Doctrine_Core::getTable('sfGuardGroup')->findOneByName($arguments['group']);
if (!$group) {
$this->logSection('guard', sprintf('Group "%s" does not exist. It will be created', $arguments['group']));
$group = new sfGuardGroup();
$group->setName($arguments['group']);
$group->save();
$this->logSection('guard', sprintf('Create group "%s"', $arguments['group']));
}
$task_arguments = array();
$task_arguments['username'] = $arguments['username'];
$task_arguments['group'] = $arguments['group'];
$task = new sfGuardAddGroupTask($this->dispatcher, $this->formatter);
$task->run($task_arguments, $options);
}
}
On aurait pu faire de manière plus simple ou au moins différente. On aurait pu par exemple créer l'utilisateur de la même manière que l'on a créer le groupe. Une autre manière de faire aurait été de dériver la classe sfGuardAddGroupTask pour lui faire créer le groupe en cas de besoin.