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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez / Téléchargez Sources et Outils PHP Discussion :

Classe de formatage HTML par catégorie d'un array PHP


Sujet :

Contribuez / Téléchargez Sources et Outils PHP

  1. #1
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut Classe de formatage HTML par catégorie d'un array PHP
    J'ai développé la classe suivante, si elle vous intéresse, servez-vous !
    Elle tourne comme je veux en PHP 5.6.3
    Elle règle de façon générique une problématique récurrente quand on récupère des données des bases, et que l'on veut afficher autre chose.
    J'explique !

    On a un tableau PHP de ce type, suite à une requête en base :
    Le classique tableau de tableaux associatifs quoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Array
    (
        [0] => Array
            (
                [fonction_libelle] => Manutentionnaire
                [employe_id] => 8
                [civ] => Mme
                [nom] => ARNAUD
                [prenom] => Louise
                [age] => 19 ans
            )
     
        [1] => Array
            (
                [fonction_libelle] => Manutentionnaire
                [employe_id] => 7
                [civ] => M
                [nom] => HENRI
                [prenom] => Frédéric
                [age] => 29 ans
            )
     
        [2] => Array
            (
                [fonction_libelle] => Ouvrier qualifié
                [employe_id] => 4
                [civ] => M
                [nom] => LAKHDAR
                [prenom] => Mokrane
                [age] => 22 ans
            )
     
        [3] => Array
            (
                [fonction_libelle] => Ouvrier spécialisé
                [employe_id] => 9
                [civ] => M
                [nom] => MARTIN
                [prenom] => Ziggy
                [age] => 19 ans
            )
     
        [4] => Array
            (
                [fonction_libelle] => Ouvrier spécialisé
                [employe_id] => 10
                [civ] => Mme
                [nom] => MARTIN
                [prenom] => Zora
                [age] => 18 ans
            )
     
    )
    A partir de ceci, on aimerait regrouper les personnels par fonction_libelle, sans redondance. Appelons cela catégoriser, et ça pourrait prendre ces différentes formes HTML :


    Une table HTML


    Nom : beau_tableau.jpg
Affichages : 641
Taille : 35,4 Ko


    Une ul HTML (bon on a prévu ol aussi bien sûr)


    Nom : ul.jpg
Affichages : 605
Taille : 28,2 Ko


    et enfin un select HTML avec des optgroup


    Nom : select.jpg
Affichages : 688
Taille : 32,7 Ko

    Voici donc la classe View_categorise.class.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    <?php
    class View_categorise{
    	protected $data=array();//array PHP tableau de tableaux associatifs
    	protected $keys=array();//les clés des sous-tableaux associatifs
    	protected $quelle_categorie='';//Quel clé doit être la catégorie qui provoque le cumul des autres ?
    	protected $quel_html='';//que veut on sortir comme structure HTML (table, ul, ol, select avec optgroup)
    	protected $quel_select_id_key='';//si select : il nous faut obligatoirement un champ comportant id pour la value
    	protected $quel_style='';//paramètre optionnel, mais s'il y en a un, il ne faut pas qu'il soit avec seulement des espaces
    	protected $html_genere='';//le HTML généré par la classe
     
    	public function __construct(array $data, $quelle_categorie, $quel_html, $quel_style='', $quel_select_id_key=''){
    		if($this->set_data($data)!==false && $this->set_quel_style($quel_style) !== false && $this->set_quel_html($quel_html) !== false){
    			if($this->set_quelle_categorie($quelle_categorie)!==false && $this->set_quel_select_id_key($quel_select_id_key)!==false){
    				$this->set_html_genere();
    			}
    			else{
    				return false;
    			}
    		}
    		else{
    			return false;
    		}
    	}
    	//pré-requis 0
    	//on attend un tableau de tableaux associatifs d'au moins une ligne avec au moins 2 champs
    	protected function set_data(array $data){
    		if(count($data)>0){
    			$keys=array_keys($data[0]);
    			if(is_array($keys)){
    				if(count($keys)<2){
    					return false;
    				}
    				else{
    					$this->data=$data;
    					$this->keys=$keys;
    				}
    			}
    			else{
    				return false;
    			}
    		}
    		else{
    			return false;
    		}
    	}
    	//pré-requis 0
    	//on attend que le style est soit non fourni, soit fourni auquel cas ne doit pas comporter que des espaces
    	protected function set_quel_style($quel_style=''){
    		if(is_string($quel_style) && trim($quel_style)!=''){
    			$this->quel_style=trim($quel_style);
    		}
    	}
    	//pré-requis 0
    	//on attend 4 entités HTML précises
    	protected function set_quel_html($quel_html){
    		$htmls=array('table','ul','ol','select');
    		if(in_array($quel_html,$htmls)){
    			$this->quel_html=$quel_html;
    		}
    		else{
    			return false;
    		}
    	}
    	//pré-requis set_data
    	//on attend que la catégorie choisie soit bien une clé du tableau $this->keys
    	protected function set_quelle_categorie($quelle_categorie){
    		if (in_array($quelle_categorie, $this->keys)) {
    			$this->quelle_categorie=$quelle_categorie;
    		}
    		else{
    			return false;
    		}
    	}
    	//pré-requis set_quel_html ET set_data
    	//Si $this->quel_html=='select' 
    	//=> 1 il a saisi quel_select_id_key
    	//=> 2 non alors on attend qu'une clé ET UNE SEULE possède ce format : "id" ou "id_foo" ou "foo_id"
    	protected function set_quel_select_id_key($quel_select_id_key=''){
    		if($this->quel_html=='select'){
    			$count=0;
    			if( !empty($quel_select_id_key) ){
    				if (in_array($quel_select_id_key, $this->keys)) {
    					$count=1;
    					$this->quel_select_id_key=$quel_select_id_key;
    				}
    			} 
    			else{
    				foreach($this->keys as $key){
    					if($key=='id' || strtolower(substr($key,0,3))=='id_' || strtolower(substr($key,-3))=='_id'){
    						$quel_select_id_key=$key;
    						$count++;
    					}
    				}
    				if($count==1){
    					$this->quel_select_id_key=$quel_select_id_key;
    				}
    			}
    			if($count!=1){
    				return false;
    			}
    		}
    	}
    	//pré-requis : tous les setters OK
    	protected function set_html_genere(){
    		switch($this->quel_html){
    			case 'table':
    				$this->html_genere='<table'.($this->quel_style==''?NULL:' class="'.$this->quel_style.'"').'>'."\n";
    				$this->html_genere.='<thead>'."\n";
    				$this->html_genere.='<tr>';
    				foreach($this->keys as $key){
    					if($key!=$this->quelle_categorie){
    						$this->html_genere.='<th>'.mb_convert_case($key , MB_CASE_TITLE).'</th>';
    					}
    				}
    				$this->html_genere.='</tr>'."\n";
    				$this->html_genere.='</thead>'."\n";
    				$this->html_genere.='<tbody>'."\n";
    				$categorie = "";//passage de témoin
    				foreach($this->data as $row){
    					//tr changement de categorie
    					if($row[$this->quelle_categorie]!=$categorie){
    						$this->html_genere.='<tr><th colspan="'.(count($this->keys)-1).'">'.mb_convert_case($row[$this->quelle_categorie] , MB_CASE_TITLE).'</th></tr>'."\n";
    						$categorie=$row[$this->quelle_categorie];
    					}
    					//tr ordinaire
    					$this->html_genere.='<tr>';
    					foreach($this->keys as $key){
    						if($this->quelle_categorie!=$key){
    							$this->html_genere.='<td>'.$row[$key].'</td>';
    						}
    					}
    					$this->html_genere.='</tr>'."\n";
    				}
    				$this->html_genere.='</tbody>'."\n";
    				$this->html_genere.='</table>'."\n";
    			break;
    			case 'ul':
    			case 'ol':
    				$start=true;
    				//ul niveau 1
    				$this->html_genere='<'.$this->quel_html.($this->quel_style==''?NULL:' class="'.$this->quel_style.'"').'>'."\n";
    				$categorie = "";//passage de témoin
    				foreach($this->data as $row){
    					//ul niveau 2 ferme
    					if($row[$this->quelle_categorie]!=$categorie){
    						if(! $start){
    							$this->html_genere.='</'.$this->quel_html.'>'."\n".'</li>'."\n";
    						}
    						//ul niveau 2 ouvre
    						$this->html_genere.='<li>'.mb_convert_case($row[$this->quelle_categorie] , MB_CASE_TITLE)."\n";
    						$this->html_genere.='<'.$this->quel_html.'>'."\n";
    						$categorie=$row[$this->quelle_categorie];
    					}
    					//li ordinaire
    					$this->html_genere.='<li>';
    					foreach($this->keys as $key){
    						if($this->quelle_categorie!=$key){
    							$this->html_genere.=$row[$key].' ';
    						}
    					}
    					$this->html_genere.='</li>'."\n";
    					$start=false;
    				}
    				//FERMETURE de 3 balises : ul niveau 2, puis li niveau 2, puis ul niveau 1
    				$this->html_genere.='</'.$this->quel_html.'></li></'.$this->quel_html.'>'."\n";
    			break;
    			case 'select':
    				$start=true;
    				$this->html_genere='<select'.($this->quel_style==''?NULL:' class="'.$this->quel_style.'"').' name="'.$this->quel_select_id_key.'">'."\n";
    				$categorie = "";//passage de témoin
    				foreach($this->data as $row){
    					//opgroup ferme
    					if($row[$this->quelle_categorie]!=$categorie){
    						if(! $start){
    							$this->html_genere.='</optgroup>'."\n";
    						}
    						//opgroup ouvert 
    						$this->html_genere.='<optgroup label="'.mb_convert_case($row[$this->quelle_categorie] , MB_CASE_TITLE).'">'."\n";
    						$categorie=$row[$this->quelle_categorie];
    					}
    					//option ordinaire
    					$this->html_genere.='<option value="'.$row[$this->quel_select_id_key].'">';
    					foreach($this->keys as $key){
    						if($this->quelle_categorie!=$key && $this->quel_select_id_key!=$key){
    							$this->html_genere.=$row[$key].' ';
    						}
    					}
    					$this->html_genere.='</option>'."\n";
    					$start=false;
    				}
    				$this->html_genere.='</optgroup></select>'."\n";
    			break;
    		}
    	}
    	public function get_html_genere(){
    		return $this->html_genere;
    	}
    }
    Et voici le script qui utilise cette classe, employe.php

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?php
    spl_autoload_register(function ($class) {
        include '../classes/' . $class . '.class.php';
    });
    $sql='SELECT f.libelle AS fonction_libelle,e.id as employe_id,e.civ,IF(e.nom_usage IS NOT NULL,e.nom_usage,e.nom_naissance) AS nom,e.prenom,concat(TIMESTAMPDIFF(YEAR,e.naissance,now()), " ans") AS age
    FROM employe e
    INNER JOIN fonction f ON e.fonction_id=f.id
    WHERE f.libelle like ? or f.libelle=?
    ORDER BY fonction_libelle,nom,prenom;';
    $data=array();
    try {
    	//(affiche ou pas erreur, UTF8 par défaut -latin1 accepté)
    	$connex=new Connexion_db(true);
    	$connex->set_pdo_rh_local();
    	$db=$connex->get_pdo();
    	$stmt = $db->prepare($sql);
    	$stmt->execute(array('Ouvrier%','Manutentionnaire'));
    	while($row= $stmt->fetch(PDO::FETCH_ASSOC)){
    		$data[]=$row;
    	}
    	unset($db);
    	if(sizeof($data)>0){
    		$view=new View_categorise($data,'fonction_libelle','table','elegant');
    		if($view!==false){
    			$tableau=$view->get_html_genere();
    		}
    		$view=new View_categorise($data,'fonction_libelle','ul');
    		if($view!==false){
    			$ul=$view->get_html_genere();
    		}
    		$view=new View_categorise($data,'fonction_libelle','ol');
    		if($view!==false){
    			$ol=$view->get_html_genere();
    		}
    		$view=new View_categorise($data,'fonction_libelle','select');
    		if($view!==false){
    			$select=$view->get_html_genere();
    		}
    	}
    } catch (Exception $e) {
    	print "Erreur ! " . $e->getMessage() . "<br/>";
    }
    ?>
    <!DOCTYPE html>
    <html lang="fr">
    	<head>
    		<meta charset="utf-8">
    		<title>Liste des Employés</title>
    		<link rel="stylesheet" href="../style.css" media="screen">
    	</head>
    	<body>
    		<div>
    			<?php 
    			echo isset($tableau)?'<div>'.$tableau.'</div>':NULL;
    			echo isset($ol)?'<div>'.$ol.'</div>':NULL;
    			echo isset($ul)?'<div>'.$ul.'</div>':NULL;
    			if(isset($select)){
    				echo '<div><form action="traitement.php" method="POST">';
    				echo $select;
    				echo '<input type="submit" name="submit" value="OK" />';
    				echo '</form></div>';
    			}
    			?>
    		</div>
    	</body>
    </html>
    ENJOY !
    Merci Jreaux62 et Rawsrc, relecteurs sévères mais justes comme je les aime !

    Et pour les sceptiques, je mets le code source HTML de la page employe.php, pour prouver qu'il n'y a aucun bug résiduel :
    Bien sûr, j'ai indenté à la main...

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <!DOCTYPE html>
    <html lang="fr">
       <head>
          <meta charset="utf-8">
          <title>Liste des Employés</title>
          <link rel="stylesheet" href="../style.css" media="screen">
       </head>
       <body>
          <div>
             <div>
                <table class="elegant">
                   <thead>
                      <tr><th>Employe_Id</th><th>Civ</th><th>Nom</th><th>Prenom</th><th>Age</th></tr>
                   </thead>
                   <tbody>
                      <tr><th colspan="5">Manutentionnaire</th></tr>
                      <tr><td>8</td><td>Mme</td><td>ARNAUD</td><td>Louise</td><td>19 ans</td></tr>
                      <tr><td>7</td><td>M</td><td>HENRI</td><td>Frédéric</td><td>29 ans</td></tr>
                      <tr><th colspan="5">Ouvrier Qualifié</th></tr>
                      <tr><td>4</td><td>M</td><td>LAKHDAR</td><td>Mokrane</td><td>22 ans</td></tr>
                      <tr><th colspan="5">Ouvrier Spécialisé</th></tr>
                      <tr><td>9</td><td>M</td><td>MARTIN</td><td>Ziggy</td><td>19 ans</td></tr>
                      <tr><td>10</td><td>Mme</td><td>MARTIN</td><td>Zora</td><td>18 ans</td></tr>
                   </tbody>
                </table>
             </div>
             <div>
                <ol>
                   <li>Manutentionnaire
                      <ol>
                         <li>8 Mme ARNAUD Louise 19 ans </li>
                         <li>7 M HENRI Frédéric 29 ans </li>
                      </ol>
                   </li>
                   <li>Ouvrier Qualifié
                      <ol>
                         <li>4 M LAKHDAR Mokrane 22 ans </li>
                      </ol>
                   </li>
                   <li>Ouvrier Spécialisé
                      <ol>
                         <li>9 M MARTIN Ziggy 19 ans </li>
                         <li>10 Mme MARTIN Zora 18 ans </li>
                      </ol>
                   </li>
                </ol>
             </div>
             <div>
                <ul>
                   <li>Manutentionnaire
                      <ul>
                         <li>8 Mme ARNAUD Louise 19 ans </li>
                         <li>7 M HENRI Frédéric 29 ans </li>
                      </ul>
                   </li>
                   <li>Ouvrier Qualifié
                      <ul>
                         <li>4 M LAKHDAR Mokrane 22 ans </li>
                      </ul>
                   </li>
                   <li>Ouvrier Spécialisé
                      <ul>
                         <li>9 M MARTIN Ziggy 19 ans </li>
                         <li>10 Mme MARTIN Zora 18 ans </li>
                      </ul>
                   </li>
                </ul>
             </div>
             <div>
                <form action="traitement.php" method="POST">
                   <select name="employe_id">
                      <optgroup label="Manutentionnaire">
                         <option value="8">Mme ARNAUD Louise 19 ans </option>
                         <option value="7">M HENRI Frédéric 29 ans </option>
                      </optgroup>
                      <optgroup label="Ouvrier Qualifié">
                         <option value="4">M LAKHDAR Mokrane 22 ans </option>
                      </optgroup>
                      <optgroup label="Ouvrier Spécialisé">
                         <option value="9">M MARTIN Ziggy 19 ans </option>
                         <option value="10">Mme MARTIN Zora 18 ans </option>
                      </optgroup>
                   </select>
                   <input type="submit" name="submit" value="OK" />
                </form>
             </div>
          </div>
       </body>
    </html>
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,


    1- Il manque des commentaires / explications dans ton code.
    Notamment la définition des paramètres.

    2- je suppose que les echo 'Erreur...' ne sont là que pour le debugage ?

    3- Je vois quelques optimisations possibles...

    Dernière modification par Invité ; 06/05/2018 à 10h53.

  3. #3
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    houlala, pas simple de te relire.

    Tu exiges un tableau en paramètre protected function set_data(array $data) et ensuite tu vérifies si c'est bien un tableau : if(is_array($data)){, PHP vérifie les exigences pour toi et si ça colle pas, déclenche une Exception. Donc ce test est inutile.
    Après je t'avouerai que je n'ai pas trop compris la question
    une classe de type vue des items HTML
    ??
    Précise aussi quelle version de PHP tu vises stp

  4. #4
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Merci de vos retours Jreaux et Raw...
    Côté présentation, j'ai appliqué vos remarques.
    Je pensais à tort que la rubrique scripts étaient la proposition de scripts qui tournent...
    Je vais maintenant appliquer vos remarques sur le code... et j'édite ce message quand c'est prêt.

    Done messieurs ! Merci. Je pense avoir tenu compte de toutes vos remarques.

    edit : ah non, j'avais laissé un bug sur <ul> et <ol>, je corrige.

    edit : voili, voilou... 13h01 ! Me restera juste à voir cette histoire de ucfirst qui chiffonne Jreaux, je fais une pause.

    14h43 : fini pour de bon ! Super contente ! Merciiiiiiiii !
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  5. #5
    Invité
    Invité(e)
    Par défaut
    Hello,

    après test, il semble y avoir quelques "petits défauts"...

    1- Cas du <select> :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	protected $quel_select_id_key='';//si select : il nous faut obligatoirement un champ comportant id pour la value
    ...
    function set_quel_select_id_key()
    ...
    			if($count==1){
    Si on a plusieurs colonnes contenant "id" ou "id_..." ou "..._id" (ce qui est très probable*), $count et supérieur à 1 (il y a trop d'id !) -> le <select> bugue.
    *ex. : id, id_profession, id_civilite,....... (ça dépend des tables, de la requête,...)
    Pas glop.

    A mon avis, on ne peut pas se contenter de "déduire" le name du <select> aussi empiriquement !
    Il faut UN AUTRE Classe (ou un dérivé de celle-ci) pour un élément comme <select>, qui réclame des paramètres supplémentaires.

    2/ $quelle_categorie

    La requête est : "........ ORDER BY fonction_libelle,nom,prenom;"
    On est d'accord qu'il faut choisir la catégorie dans ces colonnes uniquement !

    Sinon, l'affichage n'est pas correct.
    Ex. : si on choisi "civ" ou "age", ça ne va plus.

  6. #6
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Moi elle me convient parfaitement pour l'instant. Bien sûr que le développeur qui l'utilise doit connaître les contraintes.
    Mais n'hésite pas à la faire évoluer si tu as d'autres besoins !
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  7. #7
    Invité
    Invité(e)
    Par défaut
    Il faudrait peut-être préciser ces "contraintes".

    1- D'abord, que le tri se fait d'abord par la requête SQL, sur la catégorie qu'on veut afficher.
    (dans ton exemple, avec "...ORDER BY fonction_libelle...")

    2- Attention quand même à mon 1er point précédent : si plusieurs colonnes sont des id, l'option <select> ne fonctionne plus.

    A priori, il suffit d'ajouter le paramètre ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	public function __construct(array $data, $quelle_categorie, $quel_html, $quel_style='', $quel_select_id_key=''){
    Et de modifier en conséquence la fonction set_quel_select_id_key().

  8. #8
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Un exemple (après je lis ton dernier message)

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT if(e.civ="Mme","F","H") as genre,
    concat(TIMESTAMPDIFF(YEAR,e.naissance,now()), " ans") AS age,
    IF(e.nom_usage IS NOT NULL,e.nom_usage,e.nom_naissance) AS nom,
    e.prenom
    FROM employe e
    INNER JOIN fonction f ON e.fonction_id=f.id
    ORDER BY genre,age,nom,prenom;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $view=new View_categorise($data,'genre','ul');
    if($view!==false){
    	$ul=$view->get_html_genere();
    }

    Sera parfaitement gérée par table, ul ou ol... Et ne génèrera pas de select, sans provoquer d'erreur... parce qu'il n'y a pas d'id.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    F
       18 ans MARTIN Zora
       19 ans ARNAUD Louise
       27 ans STAGNET Jessica
       30 ans VALTIN Steff
    H
       19 ans MARTIN Ziggy
       22 ans LAKHDAR Mokrane
       29 ans HENRI Frédéric
       43 ans YEMEN Aziz
       53 ans VERDON Antoine
       62 ans NEYMAR Jean
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  9. #9
    Invité
    Invité(e)
    Par défaut
    Un correctif :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public function __construct(array $data, $quelle_categorie, $quel_html, $quel_style='', $quel_select_id_key=''){
    		if($this->set_data($data)!==false && $this->set_quel_style($quel_style) !== false && $this->set_quel_html($quel_html) !== false){
    			if($this->set_quelle_categorie($quelle_categorie)!==false && $this->set_quel_select_id_key($quel_select_id_key)!==false){
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    	protected function set_quel_select_id_key($quel_select_id_key){
    		if($this->quel_html=='select')
    		{
    			$count=0;
    			if( !empty($quel_select_id_key) )
    			{
    				$count=1;
    				$this->quel_select_id_key=$quel_select_id_key;
    			} else {
    				foreach($this->keys as $key){
    					if($key=='id' || strtolower(substr($key,0,3))=='id_' || strtolower(substr($key,-3))=='_id')
    					{
    						$quel_select_id_key=$key;
    						$count++;
    					}
    				}
    				if($count==1){
    					$this->quel_select_id_key=$quel_select_id_key;
    					echo 'quel_select_id_key : '.$quel_select_id_key;
    				}
    			}
    			if($count!=1){
    				return false;
    			}
    		}
    	}
    On peut alors définir le name du <select> :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	$view=new View_categorise($data,'fonction_libelle','select','','civ');
    Le select sera alors :
    (évidemment, 'civ' n'est qu'un exemple !)

    si tu veux que ce ne soit QUE des "...id..." :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    			if( !empty($quel_select_id_key) && $quel_select_id_key=='id' || strtolower(substr($quel_select_id_key,0,3))=='id_' || strtolower(substr($quel_select_id_key,-3))=='_id' )

    N.B. Et tant qu'on y est, il faudrait renommer quel_select_id_key en quel_select_name, puisque c'est le name du <select> !

  10. #10
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Ah oui ! super idée ! Laisser le développeur choisir l'identifiant si select !
    Impec, je modifie ça et puis j'arrête ! Merci jreaux !
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Dendrite Voir le message
    ...Je pensais à tort que la rubrique scripts étaient la proposition de scripts qui tournent...
    A priori, ce serait plutôt la rubrique PHP > langage > Codes sources et Outils.

  12. #12
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    J'ai intégré tes dernières modifs. Je te propose de déplacer dans le forum qui va bien !
    Un grand merci Jreaux ! Je vais me promener !
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  13. #13
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Encore une modif : pour générer des tableaux, les catégories appellent des <th> et pas des <td>... m'étais trompée.
    Et du coup, le tableau avec du style est plus beau.

    Bon, il ne me reste plus qu'à faire une toute petite doc technique...

    edit : ah non, je ne peux pas mettre return false dans le constructeur, ça ne se comporte pas comme je l'attends ! Je corrigerai.
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  14. #14
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut Dendrite,

    Je me permets de revenir sur ton script car j'ai pris le temps de le creuser un peu et je pense que tes premiers pas dans la POO peuvent être améliorés.
    Je m'explique : une classe ne doit surtout pas trop en faire or ta classe fait aussi le café. Le formatage d'un tableau est très éloigné d'un select qui lui-même est éloigné d'une liste ordonnée ou pas...
    Tu aurais dû séparer tes classes de formatage pour gagner en confort et lisibilité. Enfin, ces classes partent d'un même tableau de données, ce qui te permet d'envisager la factorisation du code relatif à ce tableau de données.
    En gros, ce sont des classes de génération de code HTML, ce qu'on appelle communément des Helper.

    Je te montre comment tu aurais pu organiser ton code différemment afin de bénéficier de toute la puissance conceptuelle de la programmation orientée objet :
    Le but est de générer trois formes de rendu :
    • select
    • table
    • liste ordonnée ou pas

    Donc on ne devra manipuler que ce que l'on souhaite générer : comme ceci $html = new Select() ou $html = new Table() ou $html = new Lists().
    Allez c'est parti :

    On définit une classe abstraite (qui ne pourra être instanciée) qui s'occupe de factoriser le code commun à tous les éléments de rendu : gestion du tableau des données, validation des données, noms des contrôles et réorganisation des données selon une clé de regroupement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    105
    <?php 
     
    abstract
    class Helper
    {
        /**
         * Parce qu'on la déclare abstract : chaque classe enfant aura L'OBLIGATION de fournir une fonction render() qui lui sera propre
         * 
         * @param  string $group_by
         * @return string HTML Code
         */
        abstract public function render(string $group_by): string;
        /**
         * @var array [[key => value]]
         */
        protected $raw_data;
        /**
         * @var string
         */
        protected $control_name = '';
        /**
        * @var string
        */
        protected $field_as_record_id = '';
        /**
         * @var array
         */
        protected $render_fields = [];
     
        /**
         * @param array  $raw_data
         * @param string $html_control_name
         * @param string $field_as_record_id    field's name from dataset to use as id for each row
         * @param array  $render_fields         [list of fields to render]
         */
        public function __construct(array $raw_data, string $html_control_name, string $field_as_record_id, array $render_fields)
        {
            $this->raw_data           = $raw_data;
            $this->control_name       = $html_control_name;
            $this->field_as_record_id = $field_as_record_id;
            $this->render_fields      = $render_fields;
        }
     
        /**
         * Check the structure of data
         *
         * @throws InvalidArgumentException
         */
        private function checkData()
        {
            if (empty($this->raw_data)) {
                throw new \InvalidArgumentException('Empty dataset');
            }
     
            $nb = count($this->render_fields);
     
            foreach ($this->raw_data as $k => $v) {
                // data must be an array and must have at least 2 fields
                if (( ! is_array($v)) || (count($v) < 2)) {
                    throw new \InvalidArgumentException('Bad structure');
                }
     
                // the dataset must have the field defined as record id
                if ( ! isset($v[$this->field_as_record_id])) {
                    throw new \InvalidArgumentException('Missing id key in dataset');
                }
     
                // the dataset must have the fields to be rendered
                $fields = array_intersect($this->render_fields, array_keys($v));
                if (count($fields) !== $nb) {
                    throw new \InvalidArgumentException('Missing fields to be rendered in datset');
                }
            }
        }
     
        /**
         * Walk through $raw_data and group by key
         *
         * @param  string $key  One key from the dataset
         * @return array
         * @throws InvalidArgumentException
         */
        protected function groupBy(string $key): array
        {
            $this->checkData();
     
            if ($key === $this->field_as_record_id) {
                throw new \InvalidArgumentException('Group key must be different from the key defined as record id');
            }
     
            $data = [];
            foreach ($this->raw_data as $k => $v) {
                if (in_array($key, array_keys($v), true)) {
                    if ( ! isset($data[$v[$key]])) {
                        $data[$v[$key]] = [];
                    }
                    $data[$v[$key]][] = $v;
                } else {
                    throw new \InvalidArgumentException('Group key not found in dataset');
                }
            }
     
            return $data;
        }
    }
    En continuant la logique, je vais m'occuper maintenant que d'un seul rendu : le select avec optgroup
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?php
     
    include 'Helper.php';
     
    class Select
    extends Helper
    {
        /**
         * @param  string $group_by
         * @return string
         */
        public function render(string $group_by): string
        {
            // échappement
            $hsc = function($p) { return htmlspecialchars($p, ENT_QUOTES, 'utf-8'); };
     
            $data  = $this->groupBy($group_by);
            $group = reset(reset($data))[$group_by]; // first group
            $rows  = ['<optgroup label="'.$hsc($group).'">'];
     
            foreach ($data as $k => $v) {
                if ($group !== $k) {
                    // end previous optgroup
                    $rows[] = '</optgroup>';
                    // start new optgroup
                    $rows[] = '<optgroup label="'.$hsc($k).'">';
                    $group  = $k;
                }
                // extraction et concaténation des valeurs à afficher
                foreach ($v as $value) {
                    $option_innex_text = implode(' ', array_intersect_key($value, array_flip($this->render_fields)));
                    $rows[]            = '<option value="'.$hsc($value[$this->field_as_record_id]).'">'.$hsc($option_innex_text).'</option>';
                }
            }
     
            return '<select name="'.$hsc($this->control_name).'">'.implode('', $rows).'</select>';
        }
    }
    comme tu peux le voir tu ne te concentres que sur le rendu propre d'un select et rien d'autre, pas la peine de penser à la table ou à la liste.
    Et maintenant comment l'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <?php
     
    include 'Select.php';
     
    $data = [[
        'fonction_libelle' => 'Manutentionnaire',
        'employe_id' => 8,
        'civ' => 'Mme',
        'nom' => 'ARNAUD',
        'prenom' => 'Louise',
        'age' => '19 ans'
    ], [
        'fonction_libelle' => 'Manutentionnaire',
        'employe_id' => 7,
        'civ' => 'M',
        'nom' => 'HENRI',
        'prenom' => 'Frédéric',
        'age' => '29 ans'
    ], [
        'fonction_libelle' => 'Ouvrier qualifié',
        'employe_id' => 4,
        'civ' => 'M',
        'nom' => 'LAKHDAR',
        'prenom' => 'Mokrane',
        'age' => '22 ans'
    ], [
        'fonction_libelle' => 'Ouvrier spécialisé',
        'employe_id' => 9,
        'civ' => 'M',
        'nom' => 'MARTIN',
        'prenom' => 'Ziggy',
        'age' => '19 ans'
    ], [
        'fonction_libelle' => 'Ouvrier spécialisé',
        'employe_id' => 10,
        'civ' => 'Mme',
        'nom' => 'MARTIN',
        'prenom' => 'Zora',
        'age' => '18 ans'
    ]];
     
    $select = new Select($data, 'id_employe', 'employe_id', ['civ', 'nom', 'prenom']);
    $html = $select->render('fonction_libelle');  // on regroupe par fonction_libelle
    echo $html;
    tu peux varier simplement ce qui doit être rendu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?php
     
    include 'Select.php';
     
    $select = new Select($data, 'id_employe', 'employe_id', ['prenom']); // on affiche juste le prénom
    $html = $select->render('fonction_libelle');  // on regroupe par fonction_libelle
    echo $html;
    Je te laisse réfléchir aux 2 autres classes de rendu : Table et ListEn espérant avoir été clair

  15. #15
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Merci beaucoup rawsrc, je regarde ça mardi. Rien de tel que d'aller au fond des choses en refaisant plusieurs fois la même chose de façon différente. Merki !
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  16. #16
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Bonjour.
    Je commence par le début : tester et comprendre ton code. Je n'en suis pas encore à le décliner.
    J'ai une erreur sur cette ligne : il n'accepte pas la syntaxe des : ?
    Parse error: syntax error, unexpected ':', expecting ';' or '{' in C:\wamp64\www\group_by\classes\Select.class.php on line 8
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        public function render(string $group_by): string
        {
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

  17. #17
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Tu dois passer en php7 pour pouvoir profiter de ces possibilités de typage.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  18. #18
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 235
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 235
    Points : 15 532
    Points
    15 532
    Par défaut
    pour utiliser la typage du retour, il faut au moins PHP 7. vous avez peut-être une ancienne version.
    https://secure.php.net/manual/fr/fun...ing-values.php

  19. #19
    Membre expert
    Avatar de Dendrite
    Femme Profil pro
    Développeuse informatique
    Inscrit en
    Juin 2008
    Messages
    2 129
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 58
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeuse informatique
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2008
    Messages : 2 129
    Points : 3 627
    Points
    3 627
    Billets dans le blog
    8
    Par défaut
    Ah, oh, merci à vous deux ! J'y retourne, mais ça risque de prendre un peu de temps du coup... Je vais faire évoluer mon wamp.
    PDO, une soupe et au lit !
    Partir de la fin est un bon moyen de retrouver son chemin. Bibi - 2020

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 13/01/2012, 10h58
  2. [MySQL] Modifier un champ d'une bdd à partir d'un tableau php
    Par pepone44 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 26/05/2008, 11h12
  3. Réponses: 11
    Dernier message: 11/03/2008, 09h35
  4. Réponses: 1
    Dernier message: 26/08/2007, 22h21
  5. [Tableaux] Tableau dynamique issue d'une requete
    Par JmL40 dans le forum Langage
    Réponses: 2
    Dernier message: 30/05/2007, 20h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo