Statistiques

Compteur d'affichages des articles
1095546

 13-Cases à cocher multiple et tables annexes

Admettons que vous ayez un comité de lecture (soyons fous) composé de 3 personnes:

  • Pierre
  • Paul
  • Jacques

Un membre peut lire plusieurs livres et donner son avis, mais un livre peut-être lu par plusieurs membres. Pour gérer cela nous allons nous servir de la table Livres, de la table Users où sont enregistrés les membres du comité et d'un nouvelle table Livreusers.

Dans chaque enregistrement nous aurons l'id du livre, l'id du membre, une note ainsi qu'un commentaire. Pour un fonctionnement plus simple, les membres lisent le livre et vous envoient leurs impressions sur les livres qu'ils ont lu. C'est à vous de renseigner dans la fiche d'un livre les notes et commentaire des membres.

Création de la table #__livreusers

Nous allons nous servir du chapitre 4 tuto Cas pratiques sur Joomla - Partie 02 pour créer la table mais cette fois à partir de xxufl_auteurs .

Création nouvelle table

 

Nous allons insérer 2 champs juste après le champ id :

  • id_livre
  • id_user

 Demande de création de champs

 

Création des nouveaux champs

 

La structure de la table ressemble à cela :

Structure de la table

 

Les champs qui vont nous intéressé sont :

  1. id unique et auto-incrément
  2. id_livre id du livre concerné
  3. id_user id su user concerné
  4. title il faut mettre un titre=id_livre+"-"+id_auteur doit être unique
  5. alias doit correspondre au titre
  6. snippet nous servira pour insérer les commentaires du membre du comité.

Nous devons créer un groupe comme ceci:

Création du groupe Comité

Nous devons créer les 3 utilisateurs:

Utilisateurs

Bon, les bases étant posées, nous allons commencer à coder.

administrator\components\com_livres\views\livre\view.html.php

La fonction display est :

	public function display($tpl = null)
	{
		// Initialiase variables.
		$this->form		= $this->get('Form');
		$this->item		= $this->get('Item');
		$this->state	= $this->get('State');

		$this->canDo	= LivresHelper::getActions($this->state->get('filter.category_id'));

		// Check for errors.
		if (count($errors = $this->get('Errors'))) {
			JError::raiseError(500, implode("\n", $errors));
			return false;
		}
		$listeetatcomplete=$this->get('Listeetatcomplete');
		$this->assignRef('listeetatcomplete',		$listeetatcomplete);
		$this->addToolbar();
		parent::display($tpl);
	}

devient

	public function display($tpl = null)
	{
		// Initialiase variables.
		$this->form		= $this->get('Form');
		$this->item		= $this->get('Item');
		$this->state	= $this->get('State');

		$this->canDo	= LivresHelper::getActions($this->state->get('filter.category_id'));

		// Check for errors.
		if (count($errors = $this->get('Errors'))) {
			JError::raiseError(500, implode("\n", $errors));
			return false;
		}
		$listeetatcomplete=$this->get('Listeetatcomplete');
		$this->assignRef('listeetatcomplete',		$listeetatcomplete);
		$listecomscomplete=$this->get('Listecomscomplete');
		$this->assignRef('listecomscomplete',		$listecomscomplete);
		$this->addToolbar();
		parent::display($tpl);
	}

Nous remplissons la variable $listecomscomplete pour l'affichage des commentaires déjà renseignés ou non.

administrator\components\com_livres\models\livre.php

 La fonction getlistecomscomplete se comporte de la manière suivante:

  • On récupère la variable $item
		$item = parent::getItem();

  • remplir une array avec la liste des utilisateurs du groupe 9
    	$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('u.id, u.name');
		$query->from('#__users AS u, #__user_usergroup_map AS g');
		$query->where('u.id = g.user_id AND g.group_id=9');
		$db->setQuery($query->__toString());
		$result = $db->loadObjectList();

  • remplir une autre array avec le contenu de la table livresusers
    	$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('id,title,id_livre,id_user,snippet');
		$query->from('#__livreusers AS lu');
		$query->where('lu.id_livre = '.$item->id);
		$db->setQuery($query->__toString());
		$result2 = $db->loadObjectList();

  • imbrication du parcours de la deuxième array dans le parcours de la première pour tester les commentaires déjà renseignés du livre en cours
		for ($j=0, $m=count( $result ); $j < $m; $j++)
		{
           $result[$j]->Checked=0;
			for ($k=0, $o=count( $result2 ); $k < $o; $k++)
			{
			  if ($result[$j]->id==$result2[$k]->id_user ) {
				   $result[$j]->Checked="CHECKED";
				   $result[$j]->snippet=$result2[$k]->snippet;
			  }
			}
		}

  • transfert de l'array
		return $result;

La fonction complète est la suivante :

	  function getListecomscomplete()
	{
		$item = parent::getItem();
    	$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('u.id, u.name');
		$query->from('#__users AS u, #__user_usergroup_map AS g');
		$query->where('u.id = g.user_id AND g.group_id=9');
		$db->setQuery($query->__toString());
		$result = $db->loadObjectList();
    	$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('id,title,id_livre,id_user,snippet');
		$query->from('#__livreusers AS lu');
		$query->where('lu.id_livre = '.$item->id);
		$db->setQuery($query->__toString());
		$result2 = $db->loadObjectList();
		for ($j=0, $m=count( $result ); $j < $m; $j++)
		{
           $result[$j]->Checked=0;
			for ($k=0, $o=count( $result2 ); $k < $o; $k++)
			{
			  if ($result[$j]->id==$result2[$k]->id_user ) {
				   $result[$j]->Checked="CHECKED";
				   $result[$j]->snippet=$result2[$k]->snippet;
			  }
			}
		}
		return $result;
	}

Nous allons maintenant créer un bouveau fichier edit_commentaires.php dans administrator\components\com_livres\views\livre\tmpl

 

administrator\components\com_livres\views\livre\tmpl\edit_commentaires.php

Dans ce fichier nous lançons une boucle pour afficher les différentes valeurs contenu dans l'array $listecomscomplete

 

<?php
/**
 * @version     1.0.0
 * @package     com_livres
 * @copyright   Copyright (C) 2011 Amy Stephen. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
defined('_JEXEC') or die;

echo JHtml::_('sliders.panel',JText::_('COM_LIVRES_FIELDSET_COMMENTAIRES'), 'commentaires-details'); ?>

<fieldset class="panelform">

<table class="adminformlist">
	<?php for ($j=0, $m=count( $this->listecomscomplete ); $j < $m; $j++) {?>
 		<tr><td><?php echo $this->listecomscomplete[$j]->name; ?></td>
		<td><INPUT type="checkbox" size="1" id="com" name="com<?php echo $j+1;?>" value="<?php echo $this->listecomscomplete[$j]->id;?>" <?php echo $this->listecomscomplete[$j]->Checked;?>></td>
		<td><INPUT type="inputbox" size="150" id="com" name="comtexte<?php echo $j+1;?>" value="<?php echo $this->listecomscomplete[$j]->snippet;?>" ></td>
<?php }?>
	 <INPUT type="hidden" id="com" name="com0" value="<?php echo $m;?>">
</table>
</fieldset>

administrator\components\com_livres\views\livre\tmpl\edit.php

Nous allons modifier ce fichier pour qu'il appelle le fichier ci-dessus :

	<div class="width-40 fltrt">
		<?php echo JHtml::_('sliders.start','content-sliders-'.$this->item->id, array('useCookie'=>1)); ?>

			<?php echo $this->loadTemplate('commentaires'); ?>

			<?php echo $this->loadTemplate('publishing'); ?>

			<?php echo $this->loadTemplate('custom_fields'); ?>

			<?php echo $this->loadTemplate('parameters'); ?>

			<?php echo $this->loadTemplate('metadata'); ?>

		<?php echo JHtml::_('sliders.end'); ?>
        </div>

devient

	<div class="width-40 fltrt">
		<?php echo JHtml::_('sliders.start','content-sliders-'.$this->item->id, array('useCookie'=>1)); ?>

			<?php echo $this->loadTemplate('commentaires'); ?>

			<?php echo $this->loadTemplate('publishing'); ?>

			<?php echo $this->loadTemplate('custom_fields'); ?>

			<?php echo $this->loadTemplate('parameters'); ?>

			<?php echo $this->loadTemplate('metadata'); ?>

		<?php echo JHtml::_('sliders.end'); ?>
        </div>

Il faut rajouter dans le fichier de langue:

COM_LIVRES_FIELDSET_COMMENTAIRES="Comité de lecture"

Cela nous donne comme affichage, lors d'une première utilisation:

Première utilisation

Pour insérer un nouveau commentaire, il suffit de cocher un membre du comité et de saisir le commentaire de celui-ci puis d'enregistrer la fiche.

Il faut modifier la routine de sauvegarde pour enregistrer dans la table xxufl_livreusers les nouvelles données.

administrator\components\com_livres\models\livre.php

 La fonction save est :

	public function save($data)
	{
		$jinput = JFactory::getApplication()->input;
		$data['etat']=$jinput->get('etat', '', '');
		// Alter the title for save as copy
		if (JRequest::getVar('task') == 'save2copy') {
			list($title,$alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']);
			$data['title']	= $title;
			$data['alias']	= $alias;
		}
		if ( array_key_exists('pret', $data)) {
			$data['pret']='1';
		} else {
			$data['pret']='0';
		} 

		if (parent::save($data)) {
			return true;
		}

		return false;
	}

Nous allons lui rajouter quelques lignes.

Pour récupérer les valeurs du formulaire :

		$data['com0']=$jinput->get('com0', '', '');
		for ($k=1, $o=$jinput->get('com0', '', ''); $k < $o+1; $k++) {
			$var_com="com".$k;
			$var_comtexte="comtexte".$k;
			$recup=$jinput->get($var_com, '', '');
			if (!$recup=="") {
				$data[$var_com]=$jinput->get($var_com, '', '');
				$data[$var_comtexte]=$jinput->get($var_comtexte, '', '');
			} else {
				$data[$var_com]=0;
				$data[$var_comtexte]="";
			}
		}

Copie des données de $data dans une autre variable $datas pour les transmettre à une routine de sauvegarde.

		$datas=$data;

On appelle une routine de sauvegarde :

		$result=$this->SaveData($datas);

On crée en fin de fichier la fonction SaveData :

Elle se compose de plusieurs parties. On parcours d'abord les variables transmises et l'on compare avec les valeurs de la table et l'on voit si il faut créer ou mettre à jour le contenu de la table.

		for ($k=1, $o=$option['com0']; $k < $o+1; $k++) {
			$var_com="com".$k;
			$var_comtexte="comtexte".$k;
			if (isset($option[$var_com])) {
				$db = $this->getDbo();
				$query = $db->getQuery(true);
				$query->select('*');
				$query->from('#__livreusers AS lu');
				$query->where('lu.id_livre = ' . $option['id'].' AND lu.id_user = '.$option[$var_com].'');
				$db->setQuery($query->__toString());
				$result = $db->loadObject();
				if (!$option[$var_com] == 0) {
					if (empty($result)) {
						$db = JFactory::getDBO();
						if (!$option[$var_comtexte]=="") {
							$query = "INSERT INTO #__livreusers  (id_user,id_livre,snippet) VALUES ('" .$option[$var_com]."' , '".$option['id']."','".$option[$var_comtexte]."')";
						} else {
							$query = "INSERT INTO #__livreusers  (id_user,id_livre) VALUES ('" .$option[$var_com]."' , '".$option['id']."')";
						}
						$db->setQuery($query);
						$result = $db->query();
					} else {
						$db = JFactory::getDBO();
						$query = "UPDATE #__livreusers  SET snippet='".$option[$var_comtexte]."'";
						$db->setQuery($query);
						$result = $db->query();
					}
				}
			}
		}

Puis on parcours la table et l'on compare avec les variables transmises pour supprimer les enregistrements non souhaités.

		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('id, id_livre, id_user, snippet');
		$query->from('#__livreusers AS lu');
		$query->where('lu.id_livre = ' . $option['id'].'');
		$db->setQuery($query->__toString());
		$result = $db->loadObjectList();
		for ($j=0, $m=count( $result ); $j < $m; $j++) {
			$delete="0";
			for ($k=1, $o=$option['com0']; $k < $o+1; $k++) {
				$var_com="com".$k;
				if (isset($option[$var_com])) {
					if ($result[$j]->id_user == $option[$var_com]){
						$delete="1";
					}
				}
			}
			if ($delete=="0"){
				$db = JFactory::getDBO();
				$query = "DELETE FROM #__livreusers  WHERE id_livre = " . $result[$j]->id_livre." AND id_user=".$result[$j]->id_user;
				$db->setQuery($query);
				$result2 = $db->query();
			}
		}

Cela nous donne au final :

	function SaveData($option) {
		//Save table #__b_partint_bien
		for ($k=1, $o=$option['com0']; $k < $o+1; $k++) {
			$var_com="com".$k;
			$var_comtexte="comtexte".$k;
			if (isset($option[$var_com])) {
				$db = $this->getDbo();
				$query = $db->getQuery(true);
				$query->select('*');
				$query->from('#__livreusers AS lu');
				$query->where('lu.id_livre = ' . $option['id'].' AND lu.id_user = '.$option[$var_com].'');
				$db->setQuery($query->__toString());
				$result = $db->loadObject();
				if (!$option[$var_com] == 0) {
					if (empty($result)) {
						$db = JFactory::getDBO();
						if (!$option[$var_comtexte]=="") {
							$query = "INSERT INTO #__livreusers  (id_user,id_livre,snippet) VALUES ('" .$option[$var_com]."' , '".$option['id']."','".$option[$var_comtexte]."')";
						} else {
							$query = "INSERT INTO #__livreusers  (id_user,id_livre) VALUES ('" .$option[$var_com]."' , '".$option['id']."')";
						}
						$db->setQuery($query);
						$result = $db->query();
					} else {
						$db = JFactory::getDBO();
						$query = "UPDATE #__livreusers  SET snippet='".$option[$var_comtexte]."'";
						$db->setQuery($query);
						$result = $db->query();
					}
				}
			}
		}
		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('id, id_livre, id_user, snippet');
		$query->from('#__livreusers AS lu');
		$query->where('lu.id_livre = ' . $option['id'].'');
		$db->setQuery($query->__toString());
		$result = $db->loadObjectList();
		for ($j=0, $m=count( $result ); $j < $m; $j++) {
			$delete="0";
			for ($k=1, $o=$option['com0']; $k < $o+1; $k++) {
				$var_com="com".$k;
				if (isset($option[$var_com])) {
					if ($result[$j]->id_user == $option[$var_com]){
						$delete="1";
					}
				}
			}
			if ($delete=="0"){
				$db = JFactory::getDBO();
				$query = "DELETE FROM #__livreusers  WHERE id_livre = " . $result[$j]->id_livre." AND id_user=".$result[$j]->id_user;
				$db->setQuery($query);
				$result2 = $db->query();
			}
		}
	}

Voila vous pouvez gérer les commentaires des membres de votre comité.