Zend Framework, Formulaire et Base de donnée, partie 2

database

On continue avec la deuxième partie de la gestion d’un formulaire, de la création de formulaire, et d’ajout de donnée en BDD dans le Zend Framework. Dans cette partie nous verrons comment afficher les données, les modifier à l’aide du même formulaire que pour l’ajout, et la suppression des données.

Sommaire

Afficher les données de la base de données.

Il faut tout d’abord toucher a notre controller qui gère la page user pour donner à la vue une instance de la classe >Model_DbTable_Users(). Vu que j’utilise souvent cette classe, j’ai fait une méthode dans la classe controller : (application/modules/Frontend/controllers/UserController.php)

private function getUsersAll() {
	$dbUser = new Model_DbTable_Users();
	return $dbUser->fetchAll()->toArray();
}

Et maintenant on a juste a passer cette classe à la vue :

public function indexAction(){
	$this->view->usersAll = $this->getUsersAll();
}

On passe maintenant à la vue (application/modules/Frontend/views/scripts/user/index.phtml).

if (isset($this->usersAll)){ ?>
	<h2><?php echo $this->translate('view_user_modify')?> : </h2>
	<table>
		<tr>
	    	<th><?php echo $this->translate('view_user_firstname')?></th>
	    	<th><?php echo $this->translate('view_user_name')?></th>
	    	<th><?php echo $this->translate('view_user_email')?></th>
	    	<th><?php echo $this->translate('view_user_modify')?></th>

		</tr>
		<?php
		$users = $this->usersAll;
		foreach ($users as $user){
			if ($user['active'] == 1){
				echo '<tr>';
			}else{
				echo '<tr style="text-decoration:line-through">';
			}
			echo '<td>'.$user['nom'].'</td>';
			echo '<td>'.$user['prenom'].'</td>';
			echo '<td>'.$user['email'].'</td>';

			echo '<td><a href="'.$this->url(array('action'=>'edit','id'=>$user['idUser'])).'">Modifier</a> | <a href="'.$this->url(array('action'=>'del','id'=>$user['idUser'])).'" >Supprimer</a></td>';
			echo '</tr>';
		}
		?>
	</table>
<?php
}
?>

liste users

On commence par vérifier que la variable usersAll est bien définit. Dans ce cas la on construit notre tableau assez naturellement. Encore une fois j’utilise ici la traduction du framework (mais on n’est pas forcé de le faire).

			if ($user['active'] == 1){
				echo '<tr>';
			}else{
				echo '<tr style="text-decoration:line-through">';
			}

Ce code sert juste a vérifié que l’utilisateur est actif. Si il ne l’est pas on barre la ligne :

echo '<td><a href="'.$this->url(array('action'=>'edit','id'=>$user['idUser'])).'">Modifier</a> | <a href="'.$this->url(array('action'=>'del','id'=>$user['idUser'])).'" >Supprimer</a></td>';

Enfin cette ligne est assez sympa : en effet on veut pouvoir éditer et supprimer des utilisateurs. Il nous faut donc des liens pour le faire. Et bien pour fabriquer ces liens on va utiliser une aide de vues (View Helper : Zend_View_Helper_Url) qui va nous construire notre lien directement. On lui passe comme argument un tableau, avec comme clés l’action, le controller, le module et des paramètres. Tout ces champs ne sont pas obligatoires. Dans mon cas, je reste sur le même controller, et donc le même module. Donc je n’utilise que l’action et un paramètre id. Ce paramètre est passé en GET donc directement dans l’url. De plus zend> va gérer automatiquement l’url rewriting, qui est beaucoup plus user-friendly et seo-friendly. Voyons ce que donne le résultat : (il y a un peu de css)

Modification d’un enregistrement

Donc notre lien pour modifier un utilisateur est déjà fait, et comme on a pu le voir, il pointe sur l’action edit du controller UserController.php. Il va donc falloir modifier celui-ci, ainsi que la classe qui gère le formulaire et la vue. On commence avec le formulaire. En fait on va utiliser la même classe que pour l’ajout, mais on va y rajouter un peu de code (à la fin de la méthode).

Model

		$idUser = $this->getIdUser();
		if (isset ( $idUser ) && $idUser != "") {
			$user = new Model_DbTable_Users ( );
			$user = $user->fetchRow ( array ("idUser = ?" => $idUser ) );
			if ($user != null) {
				$user = $user->toArray ();
				$this->populate ( $user );
			} else {
				throw new Zend_Exception ( "Il n'y a pas de d'utilisateur avec l'id : " . $idUser );
			}
			$password->setDescription ( "form_user_update_password_change" );
			$password->setRequired ( false );
			$submit->setLabel ( 'form_user_update_submit' );
		}

On commence par récupérer la valeur de l’id de l’utilisateur. Bien entendu, il faut déclarer une variable (private) et faire le getter et le setter qui va bien. Si il y a bien une valeur et qu’elle est différente de null on récupère une instance de la classe Model_DbTable_Users. On sélectionne la ligne qui va bien en fonction de l’id. Si on a bien récupérer un utilisateur (c’est a dire qu’il y a bien un enregistrement avec cet id)> on peuple le formulaire, c’est a dire qu’on le rempli des données récupérer. Sinon on renvoi une erreur. Ensuite, ce n’est pas obligatoire, mais je laisse le choix a l’utilisateur : si il ne veut pas changer de mot de passe, il ne fait rien, sinon il en rentre un nouveau. Enfin on change le label du bouton envoyer>. Mais ce n’est pas finit. En effet il reste un problème de validateur> sur le champs email. Il vaut donc le supprimer, mais que si c’est le même email (saisi) que l’email qui est déjà dans la BDD. De la même marnière que dans la partie 1, on va devoir redéfinir la méthode isValid :

	public function isValid($data)
	{
	    $this->getElement('password')->addValidator(new App_Validate_PasswordMatch($data['password2']));
		if ($this->getElement('email')->getValue() == $data['email']){
				$this->getElement('email')->removeValidator ( "Zend_Validate_Db_NoRecordExists" );
		}
	    return parent::isValid($data);
	}

Par rapport au code de la partie 1, on a rajouté le bloc IF : Si la valeur en base est la même que la valeur saisi, on supprime le validateur>, sinon on ne fait rien (et donc on le laisse).
Voilà notre formulaire est enfin prêt. On passe maintenant au controller.

Controller

	public function editAction() {
		try {
			$form = new Model_Form_User_User ( );
			$form->setIdUser($this->getRequest ()->getParam ( 'id' ));
			$form->init();
			$this->view->formUserEdit = $form;
		} catch (Zend_Exception $e) {
			$this->view->formUserEdit = $e->getMessage();
		}
	}

On essaye d’instancier la classe Model_Form_User_User ( ). Ensuite on récupère la valeur du paramètre id (passer en GET) et on la passe a notre classe forme. On est obligé de refaire le formulaire puis on la passe a la vue. Si il y a un problème (pas d’utilisateur avec id X) on passe les erreurs a la vue.

		if ($this->_request->isPost ()) {
			$formData = $this->_request->getPost ();
			if ($form->isValid ( $formData )) {

Ensuite, comme dans la première partie, on vérifie qu’il y ai des données de poster, et les recupère puis on les passes au validateur.

				$user = new Model_DbTable_Users ( );
				if ($formData ['password'] == "") {
					unset ( $formData ['password'] );
					unset ( $formData ['password2'] );
				} else {
					$formData ['password'] = md5 ( $formData ['password'] );
					unset ( $formData ['password2'] );
				}
				unset ( $formData ['submit'] );
				$result = $user->update ( $formData, array ("idUser = ?" => $formData ['idUser'] ) );

Si elle sont valide, on instancie la classe Model_DbTable_Users. On vérifie la valeur du champs password : Si elle est nul, on enlève du tableau de donnée formData les champs password et password2, sinon on chiffre en md5 le champ password et en enlève password2. Enfin on enlève le champ submit. Et pour finir on met a jour la base de donnée.

$this->_helper->redirector ( 'index', 'user' );

Enfin on redirige vers l’action index du controller user.

Vue

Ici c’est le même principe que pour le formulaire d’ajout

if (isset($this->formUserEdit)){ ?>
	<h2><?php echo $this->translate('view_user_edit')?> : </h2>
	<?php echo $this->formUserEdit;
}

edit user

Supprimer un Enregistrement

La suppression d’un utilisateur va se faire en deux étape, la première servant à confirmer la demande de suppression. Donc on crée une action intermédiaire qui passe à la vue la valeur de l’id de l’utilisateur.
public function delAction() {

	public function delAction() {
		$id = $this->getRequest ()->getParam ( 'id' );
		$this->view->delUserId = $id;
		$this->render('index');
	}

Et on ajoute à la vue le code qui va générer notre demande de suppression. Encore ici on réutilise l’aide de vue url.

if (isset($this->delUserId)){ ?>
	<h2><?php echo $this->translate('are_you_sure')?> : </h2>
	<a href="<?php echo $this->url(array('action'=>'delete','id'=>$this->delUserId));?>"><?php echo $this->translate('yes')?></a>
	<a href="<?php echo $this->url(array('action'=>'index','controller'=>'user'),null,true)?>"><?php echo $this->translate('no')?></a>
	<?php
}

Enfin si l’utilisateur clique sur oui, on exécute l’action suivante :

	public function deleteAction() {
		public function deleteAction() {
		$id = $this->getRequest ()->getParam ( 'id' );
		$user = new Model_DbTable_Users ( );
		$result = $user->delete ( array ("idUser = ?" => $id ) );
		$this->_helper->redirector ( 'index', 'user' );
	}

Et voilà le tour est joué. On a bien supprimer notre utilisateur.

Conclusion

On à enfin finit la gestion d’une table de la base de donnée grâce a un seul formulaire. Je vous donne donc maintenant le code de tous les fichiers dont j’ai eu besoin. Il y a des petites différence dans la mesure ou j’ai ajouté des messages de confirmation ou d’échec. De plus la structure de l’archive n’est pas bonne du tout… Il y a bien tous les fichiers (enfin je pense, mais c’est plus a titre indicatif). Il ne fonctionneront pas sans le bootstrap, le fichier de config, le fichier de traduction et enfin la bdd. Je referais un gros package plus tard.
Fichiers

Articles en rapport:

25 thoughts on “Zend Framework, Formulaire et Base de donnée, partie 2

  1. Slt!
    je travaille sur le ZendFramework depuis lors mais g des problémes si je veux des jointures entre tables et recupérer les valeurs pour un éventuel suppression ou modification.Si je peux avoir un exemple sur ça.

  2. la j’ai pas d’exemple sous la main. Quand j’ai des jointures (complexes) a faire j’utilise l’objet select.
    Mais pour une suppression ou un update, tu peux le faire avec les outils habituelles. Tu peux donner un tableau en argument de la fonction update. regardes dans la doc de zf …

  3. Merci pour la réponse.
    Mais je veux faire le méme exemple ke vs avé fait pour la suppression et modification mais en utilisation des champs issue de table différents de ma bases de données.Par exemple voici ce ke j’essaye de faire:
    escape($this->title);?>
    Administration

    id_Article
    Titre
    Section
    Categorie
     

    query(« select article.id_art,article.titre,section.id_sect,categorie.id_cat from article a,section s,categorie c where a.id_art = c.id_cat and c.id_cat= s.id_sect; »)?>

    escape($article->id_art); ?>
    escape($article->titre_art); ?>
    escape($categorie->id_cat); ?>
    escape($section->id_sect); ?>

    <a href="url(array(‘controller’=>’administration’,'action’=>’modifierarticle’,'id_art’=>$article->id_art));?> »>Modifier /
    <a href="url(array(‘controller’=>’administration’,'action’=>’supprimerarticle’,'id_art’=>$article->id_art));?> »>Supprimer

    Gspr ke vs comprendrez ce ke je veux faire avc ça.Mon problém c de recupéré les données de ma requéte pr chak champ.

  4. Hm, la je suis désolé, j’ai pas trop compris. En plus WordPress vire toutes les balises html / php.
    Dans tous les cas je pense que tu ferais mieux de poster un message sur le forum francais : http://z-f.fr/ … Par contre evite le langage sms

  5. Voici un exemple d’erreur:

    id_Article Titre Section Categorie

    Notice: Undefined variable: article in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 15

    Notice: Trying to get property of non-object in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 15

    Notice: Undefined variable: article in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 16

    Notice: Trying to get property of non-object in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 16

    Notice: Undefined variable: categorie in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 17

    Notice: Trying to get property of non-object in C:wampwwwIntranetapplicationviewsscriptsadministrationindex.phtml on line 17

  6. bjr tt le monde je veu faire un un supression de utilisateur , mai c’est un peut compliquer , ce que je veut faire c’est d’envoyer des newsletter (sa je peu le faire) mai il y as des e-mail non actif ou bien des faux email alors je recu des e-mail qui dit que c ‘est impossible d’envoyer l’email , alors ce que je veu faire c’est suprimer tout les utilisateur qui on des e-mail unactif ,,,,,, ben je sai pas comment rédiger la requéte alors un peu d’aide si c possible

  7. bonjour,

    J’aime venir ici !
    Debutant que je suis, je trouve enormement d’info !
    Particulierement dans les articles precedent ou tout était détaillé.
    Cependant cette tendance disparait et cela me manque; tu citais auparavant explicitement le nom des fichiers dans lesquel il fallait intervenir.
    C’est qui m’a permis d’avancer à une vitesse fulgurante sur certain concept, par rapport à d’autre tuto.
    Cependant je constate que tu le fait de moins en moins, bien que je comprend qu’il faut evolué et qu’il est tant d’apprendre les bases, je trouve que cela mettait BEAUCOUP plus de clarté dans la comprehension du bousin Zend !

  8. Merci pour ce commentaire « moi ». C’est vrai que les derniers tutos sont peut etre moins bien que les premiers. En tous cas, rédiger des tutos est extrêmement chronophage. J’aimerais bien les reprendre et les rendres plus propres, mais ca prend un temps fou… Qui sait, un jour ca viendra peut etre :d

  9. Ces tutos ne sont pas suffisamment détaillés pour permettre de créer l’application en même temps.
    C’est bien dommage, car c’est le but même d’un tuto que de voir le résultat du code…

  10. Bonjour,

    J’ai encore une autre question. Dans mon formulaire « Zend_Form », j’ai utilisé des « zend_form_element_select » pour respectivement des Jours, Mois, et Années (je suis en train de faire un formulaire de profil, avec une date de naissance à remplir).

    J’aimerai savoir comment récupérer la valeur de ce que l’utilisateur a rentré. En effet, en base, il ne me rentre que l’indice de la valeur choisie.

    Merci.

  11. Je pense que la méthode utilisé n’est pas la bonne. En effet, un utilisateur pourra facilement choisir une date comme 31/02/2010 …
    Il vaut mieux (de même que pour l’ergonomie) mettre un champ texte avec un date picker.
    Sinon pour récupérer la valeur, ça se fait de la même façon que dans les autres cas.

  12. Il n’empêche que je me retrouve avec le même problème … Un getElement(‘maListe’) renvoie une ComboBox et un getValue(‘maListe’) renvoie l’index :/

    • je ne fais plus de tout de Zend depuis un boute de temps. je suis complétement passé a symfony. Mais essaye de regarder dans le code source pour voir comment faire, et n’hésite pas a revenir donner la réponse ici ;)

  13. bonjour :)
    finalement, nous ne nous sommes pas servit d’un combobox, mais j’avais réussis en faisant un tableau de correspondance qui se remplissait dynamiquement avec un foreach ;)

  14. Bonsoir,
    j’ai copié le code tel quel et pourtant le « populate » ne fonctionne pas.
    Une idée sur une erreur de débutant que j’aurais pu faire ?
    merci

  15. Désolé, j’avais pas mis mon populate au bon endroit dans la méthode…
    J’en profite pour vous remercier, car ce blog m’aide énormément.

  16. J’obtiens cette erreur, lorsque je clique sur edit, j’ai beau cherché je ne trouve pas d’où ça vient ><

    Exception information:

    Message: Only form elements and groups may be overloaded; variable of type "string" provided

  17. Problème résolus , il fallait rajouter private $id_user en haut du formulaire .
    Par contre , il faut faire soit même le populate lors de l’édition d’un user ?

    merci d’avance ;)