1: <?php
2: // declare(encoding='UTF-8');
3: /**
4: * Classe fournissant des méthodes statiques de manipulation des tableaux (Array).
5: *
6: * @category PHP 5.2
7: * @package Utilitaire
8: * @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
9: * @copyright Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
10: * @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL-v3
11: * @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL-v2
12: * @version $Id: Tableau.php 400 2011-11-25 16:26:26Z jpm $
13: * @link /doc/framework/
14: */
15: // TODO : réaliser une seule méthode pour trierMD et trierMDType
16: class Tableau {
17: const TRI_NATUREL = 'nat';
18: const TRI_CASSE_SENSIBLE = 'ci';
19: const TRI_CASSE_INSENSIBLE = 'ci';
20:
21: private static $triMultiDimension = null;
22: private static $triType = null;
23:
24: /**
25: * Etend le tableau à étendre avec les données du tableau à copier. Si des clés sont identiques entre les deux tableaux
26: * une erreur est déclenchée et la valeur du tableau à étendre est gardée. Si les deux tableaux ont des clés numériques
27: * leurs valeurs sont gardées (à la différence de array_merge).
28: * Les tableaux sont passés par références et le tableau à copier est progressivement détruit pour éviter la consomation
29: * de mémoire.
30: *
31: * @param array $tableau_a_etendre
32: * @param array $tableau_a_copier
33: * @return void
34: */
35: public static function etendre(Array &$tableau_a_etendre, Array &$tableau_a_copier) {
36: $cles_existantes = null;
37: foreach($tableau_a_copier as $cle => $val) {
38: if (!isset($tableau_a_etendre[$cle])) {
39: $tableau_a_etendre[$cle] = $val;
40: unset($tableau_a_copier[$cle]);
41: } else {
42: $cles_existantes[] = $cle;
43: }
44: }
45: if (is_array($cles_existantes)) {
46: $e = "Le tableau a étendre contenait déjà les clés suivantes : ".implode(', ', $cles_existantes);
47: trigger_error($e, E_USER_WARNING);
48: }
49: }
50:
51: /**
52: * @deprecated Utiliser la méthode trierMD()
53: * @see trierMD()
54: */
55: public static function trierTableauMd($array, $cols) {
56: return self::trierMD($array, $cols);
57: }
58:
59: /**
60: * Permet de trier un tableau multi-dimenssionnel en gardant l'ordre des clés.
61: *
62: * @param Array $array le tableau à trier
63: * @param Array $cols tableau indiquant en clé la colonne à trier et en valeur l'ordre avec SORT_ASC ou SORT_DESC
64: * @return Array le tableau trié.
65: * @author cagret at gmail dot com
66: * @see http://fr.php.net/manual/fr/function.array-multisort.php Post du 21-Jun-2009 12:38
67: */
68: public static function trierMD($array, $cols) {
69: $colarr = array();
70: foreach ($cols as $col => $order) {
71: $colarr[$col] = array();
72: foreach ($array as $k => $row) {
73: $colarr[$col]['_'.$k] = strtolower($row[$col]);
74: }
75: }
76: $params = array();
77: foreach ($cols as $col => $order) {
78: $params[] =& $colarr[$col];
79: $orders = (array) $order;
80: foreach($orders as $orderElement) {
81: $params[] =& $orderElement;
82: }
83: }
84: call_user_func_array('array_multisort', $params);
85: $ret = array();
86: $keys = array();
87: $first = true;
88: foreach ($colarr as $col => $arr) {
89: foreach ($arr as $k => $v) {
90: if ($first) {
91: $keys[$k] = substr($k, 1);
92: }
93: $k = $keys[$k];
94: if (!isset($ret[$k])) {
95: $ret[$k] = $array[$k];
96: }
97: $ret[$k][$col] = $array[$k][$col];
98: }
99: $first = false;
100: }
101: return $ret;
102: }
103:
104: /**
105: * Méthode réalisant un tri d'un tableau multidimension. Attention les clés du tableau ne sont pas modifiées.
106: * A utiliser de cette façon:
107: * EfloreTriage::trieMultiple( $tableau_multidimension, array('ma_cle1' => SORT_ASC, 'ma_cle2' => SORT_DESC), $type_de_tri);
108: * Utiliser les constantes php SORT_DESC ou SORT_ASC pour l'odre de tri.
109: * Pour le type de tri : utiliser :
110: * - Tableau::TRI_NATUREL pour un trie naturel,
111: * - Tableau::TRI_CASSE_SENSIBLE pour un tri sensible à la casse,
112: * - Tableau::TRI_CASSE_INSENSIBLE pour un tri insensible à la casse.
113: * @param array le tableau à trier
114: * @param array le talbeau des colonnes à trier constituer de nom de clé en clé et d'ordres de tri en valeur.
115: * @param string le type de tri à appliquer.
116: * @return array le tableau trié.
117: */
118: public static function trierMDType(&$tableau, $cols, $type = self::TRI_CASSE_INSENSIBLE) {
119: self::$triMultiDimension = $cols;
120: self::$triType = $type;
121: uasort($tableau, array('self', 'comparer'));
122: return $tableau;
123: }
124:
125: private static function comparer($a, $b) {
126: $resultat = 0;
127: foreach (self::$triMultiDimension as $champ => $ordre) {
128: if ($resultat == 0) {
129: $mot_01 = Chaine::supprimerAccents($b[$champ]);
130: $mot_02 = Chaine::supprimerAccents($a[$champ]);
131: switch (self::$triType) {
132: case self::TRI_NATUREL :
133: $resultat = ($ordre == SORT_DESC) ? strnatcmp($mot_01, $mot_02) : strnatcmp($mot_02, $mot_01);
134: break;
135: case self::TRI_CASSE_SENSIBLE :
136: $resultat = ($ordre == SORT_DESC) ? strcmp($mot_01, $mot_02) : strcmp($mot_02, $mot_01);
137: break;
138: case self::TRI_CASSE_INSENSIBLE :
139: $resultat = ($ordre == SORT_DESC) ? strcasecmp($mot_01, $mot_02) : strcasecmp($mot_02, $mot_01);
140: break;
141: default:
142: $resultat = ($ordre == SORT_DESC) ? strcasecmp($mot_01, $mot_02) : strcasecmp($mot_02, $mot_01);
143: break;
144: }
145:
146: }
147: }
148: return $resultat;
149: }
150: }
151: ?>