| 1840 | jpm | 1 | <?php
 | 
        
           |  |  | 2 | // declare(encoding='UTF-8');
 | 
        
           |  |  | 3 | /**
 | 
        
           |  |  | 4 |  * Classe contenant des méthodes permettant de construire les requêtes SQL complexe concernant les images et obs.
 | 
        
           | 1881 | jpm | 5 |  * Rempli un tableau des clauses "join", "where", "group by" et "oder by" nécessaire à la *recherche* des ids des
 | 
        
           |  |  | 6 |  * observations/images correspondantes aux filtres passés dans l'url du web service de recherche
 | 
        
           |  |  | 7 |  * (ListeImages et ListeObservations).
 | 
        
           | 1840 | jpm | 8 |  *
 | 
        
           | 1881 | jpm | 9 |  * Attention, cela signifie que toutes les tables ne sont pas *forcément* jointées, par exemple si aucune
 | 
        
           |  |  | 10 |  * contrainte ne le nécessite.
 | 
        
           |  |  | 11 |  * La requête construite ici est utile pour récupérer la liste des ids d'observations/images qui match.
 | 
        
           |  |  | 12 |  * Pour la récupération effective de "toutes" les données nécessaire au retour du web service en json, c'est une autre
 | 
        
           |  |  | 13 |  * requête directement dans le web service qui s'en charge. Cette technique en deux étapes est la plus rapide !
 | 
        
           |  |  | 14 |  *
 | 
        
           |  |  | 15 |  * Note: toujours rajouter les préfixes de table (di, do ou du), en fonction de ce que défini
 | 
        
           |  |  | 16 |  * les JOIN qui sont utilisés :
 | 
        
           |  |  | 17 |  * - le préfix de del_image est "di"
 | 
        
           |  |  | 18 |  * - le préfix de del_observation est "do"
 | 
        
           |  |  | 19 |  * - le préfix de del_utilisateur est "du"
 | 
        
           |  |  | 20 |  *
 | 
        
           | 1840 | jpm | 21 |  * @category  DEL
 | 
        
           |  |  | 22 |  * @package   Services
 | 
        
           |  |  | 23 |  * @package   Bibliotheque
 | 
        
           |  |  | 24 |  * @version   0.1
 | 
        
           |  |  | 25 |  * @author    Mathias CHOUET <mathias@tela-botanica.org>
 | 
        
           |  |  | 26 |  * @author    Jean-Pascal MILCENT <jpm@tela-botanica.org>
 | 
        
           |  |  | 27 |  * @author    Aurelien PERONNET <aurelien@tela-botanica.org>
 | 
        
           |  |  | 28 |  * @license   GPL v3 <http://www.gnu.org/licenses/gpl.txt>
 | 
        
           |  |  | 29 |  * @license   CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
 | 
        
           |  |  | 30 |  * @copyright 1999-2014 Tela Botanica <accueil@tela-botanica.org>
 | 
        
           |  |  | 31 |  */
 | 
        
           |  |  | 32 | class Sql {
 | 
        
           |  |  | 33 |   | 
        
           | 1871 | jpm | 34 | 	const APPLI_IMG = 'IMG';
 | 
        
           |  |  | 35 | 	const APPLI_OBS = 'OBS';
 | 
        
           |  |  | 36 |   | 
        
           | 1840 | jpm | 37 | 	private $conteneur;
 | 
        
           |  |  | 38 | 	private $bdd;
 | 
        
           |  |  | 39 | 	private $parametres = array();
 | 
        
           | 1871 | jpm | 40 | 	private $appli;
 | 
        
           | 1840 | jpm | 41 | 	private $requete = array(
 | 
        
           |  |  | 42 | 		'join' => array(),
 | 
        
           |  |  | 43 | 		'where' => array(),
 | 
        
           |  |  | 44 | 		'groupby' => array(),
 | 
        
           |  |  | 45 | 		'orderby' => array());
 | 
        
           |  |  | 46 |   | 
        
           | 2004 | mathias | 47 | 	private $champsPrenom = array('prenom_utilisateur');
 | 
        
           |  |  | 48 | 	private $champsNom = array('nom_utilisateur');
 | 
        
           | 1985 | aurelien | 49 | 	private $champsSousRequeteObs = array('masque.genre', 'masque.famille', 'masque.ns', 'masque.commune', 'masque.milieu', 'masque.pays');
 | 
        
           | 1840 | jpm | 50 |   | 
        
           |  |  | 51 | 	public function __construct(Conteneur $conteneur) {
 | 
        
           |  |  | 52 | 		$this->conteneur = $conteneur;
 | 
        
           |  |  | 53 | 		$this->bdd = $this->conteneur->getBdd();
 | 
        
           |  |  | 54 | 	}
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 | 	public function setParametres(Array $parametres) {
 | 
        
           |  |  | 57 | 		$this->parametres = $parametres;
 | 
        
           |  |  | 58 | 	}
 | 
        
           |  |  | 59 |   | 
        
           | 1871 | jpm | 60 | 	public function setAppli($appliType) {
 | 
        
           |  |  | 61 | 		if ($appliType == 'IMG' || $appliType == 'OBS') {
 | 
        
           |  |  | 62 | 			$this->appli = $appliType;
 | 
        
           |  |  | 63 | 		} else {
 | 
        
           |  |  | 64 | 			throw new Exception("Les types d'appli disponible sont : IMG (pour PictoFlora) et OBS (pour IdentiPlante)");
 | 
        
           |  |  | 65 | 		}
 | 
        
           |  |  | 66 | 	}
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | 	private function getPrefixe() {
 | 
        
           |  |  | 69 | 		return $this->appli === 'IMG' ? 'di' : 'do';
 | 
        
           |  |  | 70 | 	}
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 | 	private function etreAppliImg() {
 | 
        
           |  |  | 73 | 		return $this->appli === 'IMG' ? true : false;
 | 
        
           |  |  | 74 | 	}
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 | 	private function etreAppliObs() {
 | 
        
           |  |  | 77 | 		return $this->appli === 'OBS' ? true : false;
 | 
        
           |  |  | 78 | 	}
 | 
        
           |  |  | 79 |   | 
        
           | 1840 | jpm | 80 | 	public function getRequeteSql() {
 | 
        
           |  |  | 81 | 		return $this->requete;
 | 
        
           |  |  | 82 | 	}
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 | 	private function addJoin($join) {
 | 
        
           | 1871 | jpm | 85 | 		if (!isset($this->requete['join'][$join])) {
 | 
        
           | 1922 | jpm | 86 | 			$this->requete['join'][$join] = $join;
 | 
        
           | 1871 | jpm | 87 | 		}
 | 
        
           | 1840 | jpm | 88 | 	}
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 | 	public function getJoin() {
 | 
        
           |  |  | 91 | 		return ($this->requete['join'] ? implode(' ', array_unique($this->requete['join'])).' ' : '');
 | 
        
           |  |  | 92 | 	}
 | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 | 	private function addJoinDis($join) {
 | 
        
           |  |  | 95 | 		$this->requete['join']['dis'] = $join;
 | 
        
           |  |  | 96 | 	}
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 | 	private function addWhere($idParam, $where) {
 | 
        
           |  |  | 99 | 		if (isset($this->parametres['_parametres_condition_or_'])
 | 
        
           |  |  | 100 | 				&& in_array($idParam, $this->parametres['_parametres_condition_or_'])) {
 | 
        
           | 1922 | jpm | 101 | 			if ($this->etreAppliImg() && in_array($idParam, $this->champsSousRequeteObs)) {
 | 
        
           |  |  | 102 | 				$this->requete['where']['OR_SOUS_REQUETE'][] = $where;
 | 
        
           |  |  | 103 | 			} else {
 | 
        
           |  |  | 104 | 				$this->requete['where']['OR'][] = $where;
 | 
        
           |  |  | 105 | 			}
 | 
        
           | 1840 | jpm | 106 | 		} else {
 | 
        
           |  |  | 107 | 			$this->requete['where']['AND'][] = $where;
 | 
        
           |  |  | 108 | 		}
 | 
        
           |  |  | 109 | 	}
 | 
        
           | 1922 | jpm | 110 |   | 
        
           | 1840 | jpm | 111 | 	public function getWhere() {
 | 
        
           | 1922 | jpm | 112 | 		// Sous-requete spéciale pour éviter de rechercher dans la table obs jointe à img depuis Pictoflora...
 | 
        
           |  |  | 113 | 		if (isset($this->requete['where']['OR_SOUS_REQUETE']) && count($this->requete['where']['OR_SOUS_REQUETE']) > 0) {
 | 
        
           |  |  | 114 | 			$clauseWhereSousRequete = implode(' OR ', $this->requete['where']['OR_SOUS_REQUETE']);
 | 
        
           |  |  | 115 | 			$sousRequete = 'di.ce_observation IN '.
 | 
        
           | 1981 | aurelien | 116 | 				"(SELECT id_observation FROM del_observation AS do WHERE $clauseWhereSousRequete ) ";
 | 
        
           | 1922 | jpm | 117 | 			$this->requete['where']['OR'][] = "( $sousRequete )";
 | 
        
           | 2034 | aurelien | 118 | 			unset($this->requete['join'][$this->getSqlJointureObs()]);
 | 
        
           | 1922 | jpm | 119 | 		}
 | 
        
           |  |  | 120 |   | 
        
           | 1840 | jpm | 121 | 		if (isset($this->requete['where']['OR']) && count($this->requete['where']['OR']) > 0) {
 | 
        
           |  |  | 122 | 			$this->requete['where']['AND'][] = '('.implode(' OR ', $this->requete['where']['OR']).')';
 | 
        
           |  |  | 123 | 		}
 | 
        
           |  |  | 124 |   | 
        
           |  |  | 125 | 		$where = ' TRUE ';
 | 
        
           |  |  | 126 | 		if (isset($this->requete['where']['AND']) && count($this->requete['where']['AND']) > 0) {
 | 
        
           |  |  | 127 | 			$where = implode(' AND ', $this->requete['where']['AND']).' ';
 | 
        
           |  |  | 128 | 		}
 | 
        
           |  |  | 129 | 		return $where;
 | 
        
           |  |  | 130 | 	}
 | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 | 	private function addGroupBy($groupBy) {
 | 
        
           |  |  | 133 | 		$this->requete['groupby'][] = $groupBy;
 | 
        
           |  |  | 134 | 	}
 | 
        
           |  |  | 135 |   | 
        
           |  |  | 136 | 	public function getGroupBy() {
 | 
        
           |  |  | 137 | 		$groupby = '';
 | 
        
           |  |  | 138 | 		if (isset($this->requete['groupby']) && count($this->requete['groupby']) > 0) {
 | 
        
           |  |  | 139 | 			$groupby = 'GROUP BY '.implode(', ', array_unique($this->requete['groupby'])).' ';
 | 
        
           |  |  | 140 | 		}
 | 
        
           |  |  | 141 | 		return $groupby;
 | 
        
           |  |  | 142 | 	}
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 | 	private function addOrderBy($orderby) {
 | 
        
           |  |  | 145 | 		$this->requete['orderby'][] = $orderby;
 | 
        
           |  |  | 146 | 	}
 | 
        
           |  |  | 147 |   | 
        
           |  |  | 148 | 	public function getOrderBy() {
 | 
        
           |  |  | 149 | 		$orderby = '';
 | 
        
           |  |  | 150 | 		if (isset($this->requete['orderby']) && count($this->requete['orderby']) > 0) {
 | 
        
           |  |  | 151 | 			$orderby = 'ORDER BY '.implode(', ', array_unique($this->requete['orderby'])).' ';
 | 
        
           |  |  | 152 | 		}
 | 
        
           |  |  | 153 | 		return $orderby;
 | 
        
           |  |  | 154 | 	}
 | 
        
           |  |  | 155 |   | 
        
           |  |  | 156 | 	public function getLimit() {
 | 
        
           |  |  | 157 | 		return 'LIMIT '.$this->parametres['navigation.depart'].','.$this->parametres['navigation.limite'].' ';
 | 
        
           |  |  | 158 | 	}
 | 
        
           |  |  | 159 |   | 
        
           |  |  | 160 | 	/**
 | 
        
           | 1881 | jpm | 161 |   | 
        
           | 1840 | jpm | 162 | 	 *
 | 
        
           |  |  | 163 | 	 * @param $p les paramètres (notamment de masque) passés par l'URL et déjà traités/filtrés (sauf quotes)
 | 
        
           |  |  | 164 | 	 * @param $req le tableau, passé par référence représentant les composants de la requête à bâtir
 | 
        
           |  |  | 165 | 	 */
 | 
        
           |  |  | 166 | 	public function ajouterContraintes() {
 | 
        
           |  |  | 167 | 		$this->ajouterContrainteAuteur();
 | 
        
           |  |  | 168 | 		$this->ajouterContrainteDate();
 | 
        
           | 1985 | aurelien | 169 | 		$this->ajouterContraintePays();
 | 
        
           | 1840 | jpm | 170 | 		$this->ajouterContrainteDepartement();
 | 
        
           |  |  | 171 | 		$this->ajouterContrainteIdZoneGeo();
 | 
        
           |  |  | 172 | 		$this->ajouterContrainteGenre();
 | 
        
           |  |  | 173 | 		$this->ajouterContrainteFamille();
 | 
        
           |  |  | 174 | 		$this->ajouterContrainteNs();
 | 
        
           |  |  | 175 | 		$this->ajouterContrainteNn();
 | 
        
           |  |  | 176 | 		$this->ajouterContrainteReferentiel();
 | 
        
           |  |  | 177 | 		$this->ajouterContrainteCommune();
 | 
        
           |  |  | 178 | 	}
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 | 	private function ajouterContrainteAuteur() {
 | 
        
           |  |  | 181 | 		if (isset($this->parametres['masque.auteur'])) {
 | 
        
           |  |  | 182 | 			$auteur = $this->parametres['masque.auteur'];
 | 
        
           |  |  | 183 | 			// id du poster de l'obs
 | 
        
           | 1871 | jpm | 184 | 			$prefixe = $this->getPrefixe();
 | 
        
           | 1840 | jpm | 185 |   | 
        
           |  |  | 186 | 			if (is_numeric($auteur)) {
 | 
        
           |  |  | 187 | 				$this->ajouterContrainteAuteurId();
 | 
        
           | 1871 | jpm | 188 | 			} elseif(preg_match('/@[a-z0-9-]+(?:\.[a-z0-9-]+)*\.[a-z]{2,}$/i', $auteur)) {
 | 
        
           | 1840 | jpm | 189 | 				$this->ajouterContrainteAuteurEmail();
 | 
        
           |  |  | 190 | 			} else {
 | 
        
           |  |  | 191 | 				$this->ajouterContrainteAuteurIntitule();
 | 
        
           |  |  | 192 | 			}
 | 
        
           |  |  | 193 | 		}
 | 
        
           |  |  | 194 | 	}
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 | 	private function ajouterContrainteAuteurId() {
 | 
        
           |  |  | 197 | 		$id = $this->parametres['masque.auteur'];
 | 
        
           | 1871 | jpm | 198 | 		$prefixe = $this->getPrefixe();
 | 
        
           | 2047 | mathias | 199 | 		$sqlTpl = "($prefixe.ce_utilisateur = %1\$d)";
 | 
        
           | 1840 | jpm | 200 | 		$whereAuteur = sprintf($sqlTpl, $id);
 | 
        
           |  |  | 201 | 		$this->addWhere('masque.auteur', $whereAuteur);
 | 
        
           |  |  | 202 | 	}
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 | 	private function ajouterContrainteAuteurEmail() {
 | 
        
           |  |  | 205 | 		$email = $this->parametres['masque.auteur'];
 | 
        
           | 1871 | jpm | 206 | 		$prefixe = $this->getPrefixe();
 | 
        
           | 2047 | mathias | 207 | 		$sqlTpl = "($prefixe.courriel_utilisateur LIKE %1\$s )";
 | 
        
           | 1840 | jpm | 208 | 		$emailP = $this->bdd->proteger("$email%");
 | 
        
           |  |  | 209 | 		$whereAuteur = sprintf($sqlTpl, $emailP);
 | 
        
           |  |  | 210 | 		$this->addWhere('masque.auteur', $whereAuteur);
 | 
        
           |  |  | 211 | 	}
 | 
        
           |  |  | 212 |   | 
        
           |  |  | 213 | 	/**
 | 
        
           |  |  | 214 | 	 * Retourne une clause where du style:
 | 
        
           |  |  | 215 | 	 * CONCAT(IF(du.prenom IS NULL, "", du.prenom), [...] vdi.i_nomutilisateur) REGEXP 'xxx'
 | 
        
           |  |  | 216 | 	 */
 | 
        
           |  |  | 217 | 	private function ajouterContrainteAuteurIntitule() {
 | 
        
           |  |  | 218 | 		$auteurExplode = explode(' ', $this->parametres['masque.auteur']);
 | 
        
           |  |  | 219 | 		$nbreMots = count($auteurExplode);
 | 
        
           |  |  | 220 |   | 
        
           |  |  | 221 | 		if ($nbreMots == 1) {
 | 
        
           |  |  | 222 | 			$this->ajouterContrainteAuteurPrenomOuNom();
 | 
        
           |  |  | 223 | 		} else if ($nbreMots == 2) {
 | 
        
           |  |  | 224 | 			$this->ajouterContrainteAuteurPrenomEtNom();
 | 
        
           |  |  | 225 | 		}
 | 
        
           |  |  | 226 | 	}
 | 
        
           |  |  | 227 |   | 
        
           |  |  | 228 | 	private function ajouterContrainteAuteurPrenomOuNom() {
 | 
        
           |  |  | 229 | 		$prenomOuNom = $this->parametres['masque.auteur'];
 | 
        
           |  |  | 230 |   | 
        
           |  |  | 231 | 		$sqlTpl = 'CONCAT(%s,%s) LIKE %s';
 | 
        
           | 1871 | jpm | 232 | 		$prefixe = $this->getPrefixe();
 | 
        
           |  |  | 233 | 		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
 | 
        
           |  |  | 234 | 		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
 | 
        
           | 1840 | jpm | 235 | 		$auteurMotif = $this->bdd->proteger("%$prenomOuNom%");
 | 
        
           |  |  | 236 |   | 
        
           |  |  | 237 | 		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $auteurMotif);
 | 
        
           |  |  | 238 | 		$this->addWhere('masque.auteur', $auteurWhere);
 | 
        
           |  |  | 239 | 	}
 | 
        
           |  |  | 240 |   | 
        
           |  |  | 241 | 	private function ajouterContrainteAuteurPrenomEtNom() {
 | 
        
           |  |  | 242 | 		list($prenom, $nom) = explode(' ', $this->parametres['masque.auteur']);
 | 
        
           |  |  | 243 |   | 
        
           |  |  | 244 | 		$sqlTpl = '(CONCAT(%1$s,%2$s) LIKE %3$s AND CONCAT(%1$s,%2$s) LIKE %4$s)';
 | 
        
           | 1871 | jpm | 245 | 		$prefixe = $this->getPrefixe();
 | 
        
           |  |  | 246 | 		$champsPrenomSql = self::ajouterIfNullPourConcat($this->champsPrenom, $prefixe);
 | 
        
           |  |  | 247 | 		$champsNomSql = self::ajouterIfNullPourConcat($this->champsNom, $prefixe);
 | 
        
           | 1840 | jpm | 248 | 		$prenomMotif = $this->bdd->proteger("%$prenom%");
 | 
        
           |  |  | 249 | 		$nomMotif = $this->bdd->proteger("%$nom%");
 | 
        
           |  |  | 250 |   | 
        
           |  |  | 251 | 		$auteurWhere = sprintf($sqlTpl, $champsPrenomSql, $champsNomSql, $prenomMotif, $nomMotif);
 | 
        
           |  |  | 252 | 		$this->addWhere('masque.auteur', $auteurWhere);
 | 
        
           |  |  | 253 | 	}
 | 
        
           |  |  | 254 |   | 
        
           | 1881 | jpm | 255 | 	/**
 | 
        
           |  |  | 256 | 	 * Lorsque l'on concatène des champs, un seul NULL prend le dessus.
 | 
        
           | 1840 | jpm | 257 | 	 * Il faut donc utiliser la syntaxe IFNULL(%s, "").
 | 
        
           | 1881 | jpm | 258 | 	 * Cette fonction effectue aussi l'implode() "final".
 | 
        
           | 1840 | jpm | 259 | 	 */
 | 
        
           | 1871 | jpm | 260 | 	private static function ajouterIfNullPourConcat($champs, $prefixe) {
 | 
        
           | 1840 | jpm | 261 | 		$champsProteges = array();
 | 
        
           |  |  | 262 | 		foreach ($champs as $champ) {
 | 
        
           | 1871 | jpm | 263 | 			if (strstr($champ, '.') === false) {
 | 
        
           |  |  | 264 | 				$champ = "$prefixe.$champ";
 | 
        
           |  |  | 265 | 			}
 | 
        
           | 1840 | jpm | 266 | 			$champsProteges[] = "IFNULL($champ, '')";
 | 
        
           |  |  | 267 | 		}
 | 
        
           |  |  | 268 | 		return implode(',', $champsProteges);
 | 
        
           |  |  | 269 | 	}
 | 
        
           |  |  | 270 |   | 
        
           |  |  | 271 | 	private function ajouterContrainteDate() {
 | 
        
           |  |  | 272 | 		if (isset($this->parametres['masque.date'])) {
 | 
        
           |  |  | 273 | 			$date = $this->parametres['masque.date'];
 | 
        
           | 1871 | jpm | 274 | 			if (preg_match('/^\d{4}$/', $date) && $date < 2030 && $date > 1600) {
 | 
        
           |  |  | 275 | 				$sqlTpl = "YEAR(do.date_observation) = %d";
 | 
        
           | 1840 | jpm | 276 | 				$dateWhere = sprintf($sqlTpl, $date);
 | 
        
           |  |  | 277 | 				$this->addWhere('masque.date', $dateWhere);
 | 
        
           |  |  | 278 | 			} else {
 | 
        
           | 1871 | jpm | 279 | 				$sqlTpl = "do.date_observation = %s";
 | 
        
           |  |  | 280 | 				$dateP = $this->bdd->proteger($date);
 | 
        
           | 1840 | jpm | 281 | 				$dateWhere = sprintf($sqlTpl, $dateP);
 | 
        
           |  |  | 282 | 				$this->addWhere('masque.date', $dateWhere);
 | 
        
           |  |  | 283 | 			}
 | 
        
           | 1871 | jpm | 284 |   | 
        
           | 2032 | aurelien | 285 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 286 | 		}
 | 
        
           |  |  | 287 | 	}
 | 
        
           |  |  | 288 |   | 
        
           |  |  | 289 | 	private function ajouterContrainteDepartement() {
 | 
        
           |  |  | 290 | 		if (isset($this->parametres['masque.departement'])) {
 | 
        
           |  |  | 291 | 			$dept = $this->parametres['masque.departement'];
 | 
        
           |  |  | 292 | 			$deptMotif = $this->bdd->proteger("INSEE-C:$dept");
 | 
        
           | 1871 | jpm | 293 | 			$this->addWhere('masque.departement', "do.ce_zone_geo LIKE $deptMotif");
 | 
        
           |  |  | 294 |   | 
        
           | 2032 | aurelien | 295 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 296 | 		}
 | 
        
           |  |  | 297 | 	}
 | 
        
           | 1985 | aurelien | 298 |   | 
        
           | 2034 | aurelien | 299 | 	private function ajouterContraintePays() {
 | 
        
           | 1985 | aurelien | 300 | 		if (isset($this->parametres['masque.pays'])) {
 | 
        
           |  |  | 301 | 			// Attention le standard contient parfois FX pour la france métropolitaine
 | 
        
           |  |  | 302 | 			// Dans ce cas particulier on cherche donc FR et FX
 | 
        
           |  |  | 303 | 			$this->parametres['masque.pays'] = strtoupper($this->parametres['masque.pays']);
 | 
        
           |  |  | 304 | 			if(strpos($this->parametres['masque.pays'], 'FR') !== false) {
 | 
        
           |  |  | 305 | 				$this->parametres['masque.pays'] = str_replace('FR', 'FR,FX', $this->parametres['masque.pays']);
 | 
        
           |  |  | 306 | 			}
 | 
        
           | 2034 | aurelien | 307 | 			$pays = explode(',', $this->parametres['masque.pays']);
 | 
        
           |  |  | 308 | 			$pays = implode(',', $this->bdd->proteger($pays));
 | 
        
           |  |  | 309 | 			$this->addWhere('masque.pays', "do.pays IN ($pays)");
 | 
        
           |  |  | 310 |   | 
        
           |  |  | 311 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           |  |  | 312 | 		}
 | 
        
           | 1985 | aurelien | 313 | 	}
 | 
        
           | 1840 | jpm | 314 |   | 
        
           |  |  | 315 | 	private function ajouterContrainteIdZoneGeo() {
 | 
        
           |  |  | 316 | 		if (isset($this->parametres['masque.id_zone_geo'])) {
 | 
        
           |  |  | 317 | 			$idZgMotif = $this->bdd->proteger($this->parametres['masque.id_zone_geo']);
 | 
        
           | 1871 | jpm | 318 | 			$this->addWhere('masque.id_zone_geo', "do.ce_zone_geo = $idZgMotif");
 | 
        
           | 2032 | aurelien | 319 |   | 
        
           |  |  | 320 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 321 | 		}
 | 
        
           |  |  | 322 | 	}
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 | 	private function ajouterContrainteGenre() {
 | 
        
           |  |  | 325 | 		if (isset($this->parametres['masque.genre'])) {
 | 
        
           |  |  | 326 | 			$genre = $this->parametres['masque.genre'];
 | 
        
           | 2004 | mathias | 327 | 			$genreMotif = $this->bdd->proteger("$genre%");
 | 
        
           | 1871 | jpm | 328 | 			$this->addWhere('masque.genre', "do.nom_sel LIKE $genreMotif");
 | 
        
           |  |  | 329 |   | 
        
           | 2032 | aurelien | 330 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 331 | 		}
 | 
        
           |  |  | 332 | 	}
 | 
        
           |  |  | 333 |   | 
        
           |  |  | 334 | 	private function ajouterContrainteFamille() {
 | 
        
           |  |  | 335 | 		if (isset($this->parametres['masque.famille'])) {
 | 
        
           |  |  | 336 | 			$familleMotif = $this->bdd->proteger($this->parametres['masque.famille']);
 | 
        
           | 1871 | jpm | 337 | 			$this->addWhere('masque.famille', "do.famille = $familleMotif");
 | 
        
           |  |  | 338 |   | 
        
           | 2032 | aurelien | 339 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 340 | 		}
 | 
        
           |  |  | 341 | 	}
 | 
        
           |  |  | 342 |   | 
        
           |  |  | 343 | 	private function ajouterContrainteNs() {
 | 
        
           |  |  | 344 | 		if (isset($this->parametres['masque.ns'])) {
 | 
        
           |  |  | 345 | 			$ns = $this->parametres['masque.ns'];
 | 
        
           |  |  | 346 | 			$nsMotif = $this->bdd->proteger("$ns%");
 | 
        
           | 1871 | jpm | 347 | 			$this->addWhere('masque.ns', "do.nom_sel LIKE $nsMotif");
 | 
        
           | 2032 | aurelien | 348 |   | 
        
           |  |  | 349 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 350 | 		}
 | 
        
           |  |  | 351 | 	}
 | 
        
           |  |  | 352 |   | 
        
           |  |  | 353 | 	private function ajouterContrainteNn() {
 | 
        
           |  |  | 354 | 		if (isset($this->parametres['masque.nn'])) {
 | 
        
           | 1871 | jpm | 355 | 			$sqlTpl = '(do.nom_sel_nn = %1$d OR do.nom_ret_nn = %1$d)';
 | 
        
           | 1840 | jpm | 356 | 			$nnWhere = sprintf($sqlTpl, $this->parametres['masque.nn']);
 | 
        
           |  |  | 357 | 			$this->addWhere('masque.nn', $nnWhere);
 | 
        
           | 1871 | jpm | 358 |   | 
        
           | 2032 | aurelien | 359 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 360 | 		}
 | 
        
           |  |  | 361 | 	}
 | 
        
           |  |  | 362 |   | 
        
           |  |  | 363 | 	private function ajouterContrainteReferentiel() {
 | 
        
           |  |  | 364 | 		if (isset($this->parametres['masque.referentiel'])) {
 | 
        
           |  |  | 365 | 			$ref = $this->parametres['masque.referentiel'];
 | 
        
           |  |  | 366 | 			$refMotif = $this->bdd->proteger("$ref%");
 | 
        
           | 1871 | jpm | 367 | 			$this->addWhere('masque.referentiel', "do.nom_referentiel LIKE $refMotif");
 | 
        
           |  |  | 368 |   | 
        
           | 2032 | aurelien | 369 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 370 | 		}
 | 
        
           |  |  | 371 | 	}
 | 
        
           |  |  | 372 |   | 
        
           |  |  | 373 | 	private function ajouterContrainteCommune() {
 | 
        
           |  |  | 374 | 		if (isset($this->parametres['masque.commune'])) {
 | 
        
           |  |  | 375 | 			$commune = $this->parametres['masque.commune'];
 | 
        
           |  |  | 376 | 			$communeMotif = $this->bdd->proteger("$commune%");
 | 
        
           | 1871 | jpm | 377 | 			$this->addWhere('masque.commune', "do.zone_geo LIKE $communeMotif");
 | 
        
           |  |  | 378 |   | 
        
           | 2032 | aurelien | 379 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           |  |  | 380 | 		}
 | 
        
           |  |  | 381 | 	}
 | 
        
           |  |  | 382 |   | 
        
           |  |  | 383 | 	private function ajouterJoinObsSiNecessaire() {
 | 
        
           | 1871 | jpm | 384 | 			if ($this->etreAppliImg()) {
 | 
        
           | 2034 | aurelien | 385 | 				$this->addJoin($this->getSqlJointureObs());
 | 
        
           | 1871 | jpm | 386 | 			}
 | 
        
           | 1840 | jpm | 387 | 	}
 | 
        
           | 2034 | aurelien | 388 |   | 
        
           |  |  | 389 | 	private function getSqlJointureObs() {
 | 
        
           | 2036 | aurelien | 390 | 		$typeJointure = !empty($this->parametres['masque']) ? 'LEFT' : 'INNER';
 | 
        
           | 2035 | aurelien | 391 | 		return $typeJointure.' JOIN del_observation AS do ON (di.ce_observation = do.id_observation) ';
 | 
        
           | 2034 | aurelien | 392 | 	}
 | 
        
           | 1840 | jpm | 393 |   | 
        
           | 1845 | jpm | 394 | 	public function ajouterConstrainteAppliObs() {
 | 
        
           |  |  | 395 | 		$this->ajouterContrainteTagCel();
 | 
        
           |  |  | 396 | 		$this->ajouterContrainteType();
 | 
        
           |  |  | 397 | 		// TODO : ATTENTION -> vue que l'on utilise une vue basée sur les images, nous devons grouper par obs
 | 
        
           | 1871 | jpm | 398 | 		$this->addGroupBy('do.id_observation');
 | 
        
           | 1845 | jpm | 399 | 	}
 | 
        
           |  |  | 400 |   | 
        
           |  |  | 401 | 	private function ajouterContrainteType() {
 | 
        
           | 1933 | aurelien | 402 | 		// Les contraintes régissant les onglets sont issus de la réunion dont le compte rendu
 | 
        
           |  |  | 403 | 		// disponible ici : http://tela-botanica.net/intranet/wakka.php?wiki=Octobre2014
 | 
        
           |  |  | 404 | 		// Ce lien est à modifier pour pointer vers toute nouvelle réunion modifiant ce fonctionnement
 | 
        
           |  |  | 405 |   | 
        
           | 1871 | jpm | 406 | 		if (isset($this->parametres['masque.type'])) {
 | 
        
           |  |  | 407 | 			if (array_key_exists('adeterminer', $this->parametres['masque.type'])) {
 | 
        
           | 1933 | aurelien | 408 | 				// A DETERMINER : toutes les observations qui ont le tag "aDeterminer"
 | 
        
           |  |  | 409 | 				// *ou* qui n'ont pas de nom d'espèce
 | 
        
           | 1871 | jpm | 410 | 				// *ou* qui ont la "certitude" à ("aDeterminer" *ou* "douteux")
 | 
        
           |  |  | 411 | 				$this->addWhere('masque.type', '('.
 | 
        
           |  |  | 412 | 					'do.certitude = "aDeterminer" '.
 | 
        
           |  |  | 413 | 					'OR do.certitude = "douteux" '.
 | 
        
           |  |  | 414 | 					'OR do.mots_cles_texte LIKE "%aDeterminer%" '.
 | 
        
           |  |  | 415 | 					'OR do.nom_sel_nn IS NULL '.
 | 
        
           |  |  | 416 | 					'OR do.nom_sel_nn = 0 '.// il ne DEVRAIT pas y avoir d'entrées à 0, mais il y en a quand-même !!
 | 
        
           |  |  | 417 | 					')');
 | 
        
           |  |  | 418 | 			}
 | 
        
           | 1933 | aurelien | 419 |   | 
        
           | 1871 | jpm | 420 | 			if (array_key_exists('validees', $this->parametres['masque.type'])) {
 | 
        
           | 1933 | aurelien | 421 | 				// VALIDEES : toutes les observations ayant un commentaire doté de proposition_retenue = 1
 | 
        
           |  |  | 422 | 				// ou bien possédant une proposition initiale avec un nom valide ayant totalisé un score d'au moins 4
 | 
        
           |  |  | 423 | 				// (ce qui correspond à au moins deux votes positifs dans la plupart des cas, dont un identifié)
 | 
        
           |  |  | 424 | 				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();
 | 
        
           | 1871 | jpm | 425 | 				$this->addJoin('INNER JOIN del_commentaire AS dc '.
 | 
        
           | 1933 | aurelien | 426 | 					'ON ( '.
 | 
        
           |  |  | 427 | 						'do.id_observation = dc.ce_observation '.
 | 
        
           |  |  | 428 | 						'AND ( '.
 | 
        
           |  |  | 429 | 							'dc.proposition_retenue = 1 OR '.
 | 
        
           |  |  | 430 | 							'( '.
 | 
        
           |  |  | 431 | 								'dc.proposition_initiale = 1 '.
 | 
        
           |  |  | 432 | 								'AND dc.nom_sel_nn != 0 '.
 | 
        
           |  |  | 433 | 								'AND dc.nom_sel_nn IS NOT NULL '.
 | 
        
           |  |  | 434 | 								' AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' >= 4) '.
 | 
        
           |  |  | 435 | 							') '.
 | 
        
           |  |  | 436 | 						') '.
 | 
        
           |  |  | 437 | 					')'
 | 
        
           |  |  | 438 | 				);
 | 
        
           | 1871 | jpm | 439 | 			}
 | 
        
           | 1933 | aurelien | 440 |   | 
        
           |  |  | 441 | 			if(array_key_exists('aconfirmer', $this->parametres['masque.type'])) {
 | 
        
           |  |  | 442 | 				// A CONFIRMER : toutes les observations moins les validées et à confirmer
 | 
        
           |  |  | 443 | 				// i.e. : des observations avec un nom valide, qui ne sont pas à déterminer
 | 
        
           |  |  | 444 | 				// (ni certitude "aDeterminer" ou "douteuse", ni mot clé),
 | 
        
           |  |  | 445 | 				// ne possédant pas de proposition officiellement retenue
 | 
        
           |  |  | 446 | 				// et ayant une proposition initiale totalisant un score de moins de 4
 | 
        
           | 2034 | aurelien | 447 | 				$sous_requete_score_prop_votees = $this->getSousRequeteSommeVotesPropositions();
 | 
        
           | 1933 | aurelien | 448 | 				$this->addWhere('masque.type',
 | 
        
           |  |  | 449 | 						'('.
 | 
        
           |  |  | 450 | 							'do.id_observation IN ('.
 | 
        
           |  |  | 451 | 								'SELECT dc.ce_observation FROM del_commentaire dc WHERE dc.proposition_retenue = 0'.
 | 
        
           | 2034 | aurelien | 452 | 								' AND ( '.
 | 
        
           |  |  | 453 | 									'dc.proposition_initiale = 1 '.
 | 
        
           |  |  | 454 | 									'AND dc.nom_sel_nn != 0 '.
 | 
        
           |  |  | 455 | 									'AND dc.nom_sel_nn IS NOT NULL '.
 | 
        
           |  |  | 456 | 									'AND dc.id_commentaire IN ('.$sous_requete_score_prop_votees.' < 4) '.
 | 
        
           | 1933 | aurelien | 457 | 								') '.
 | 
        
           |  |  | 458 | 							') AND do.id_observation NOT IN ('.
 | 
        
           |  |  | 459 | 								'SELECT dc.ce_observation FROM del_commentaire dc '.
 | 
        
           |  |  | 460 | 								'WHERE '.
 | 
        
           |  |  | 461 | 								' dc.proposition_retenue = 1'.
 | 
        
           |  |  | 462 | 							') '.
 | 
        
           | 2034 | aurelien | 463 | 							'AND do.certitude != "douteux" AND do.certitude != "aDeterminer" '.
 | 
        
           |  |  | 464 | 							'AND do.mots_cles_texte NOT LIKE "%aDeterminer%" '.
 | 
        
           |  |  | 465 | 							'AND do.nom_sel_nn != 0 '.
 | 
        
           | 1933 | aurelien | 466 | 							'AND do.nom_sel_nn IS NOT NULL'.
 | 
        
           |  |  | 467 | 						') '
 | 
        
           |  |  | 468 | 					);
 | 
        
           |  |  | 469 | 			}
 | 
        
           | 1845 | jpm | 470 |   | 
        
           | 2034 | aurelien | 471 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1845 | jpm | 472 | 		}
 | 
        
           |  |  | 473 | 	}
 | 
        
           | 1933 | aurelien | 474 |   | 
        
           |  |  | 475 | 	private function getSousRequeteSommeVotesPropositions() {
 | 
        
           |  |  | 476 | 		// ATTENTION : un vote identifié compte 3 votes anonymes (dans les deux sens)
 | 
        
           | 2034 | aurelien | 477 | 		return  'SELECT ce_proposition '.
 | 
        
           |  |  | 478 | 				'FROM del_commentaire_vote dcv '.
 | 
        
           |  |  | 479 | 				'GROUP BY ce_proposition HAVING '.
 | 
        
           |  |  | 480 | 				'SUM(CASE '.
 | 
        
           |  |  | 481 | 				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN 3 '.
 | 
        
           |  |  | 482 | 				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' != 0 THEN -3 '.
 | 
        
           |  |  | 483 | 				'	WHEN valeur = 1 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN 1 '.
 | 
        
           |  |  | 484 | 				'	WHEN valeur = 0 AND dcv.ce_utilisateur REGEXP \'^-?[0-9]+$\' = 0 THEN -1 '.
 | 
        
           |  |  | 485 | 				'END '.
 | 
        
           | 1933 | aurelien | 486 | 			') ';
 | 
        
           |  |  | 487 | 	}
 | 
        
           | 1845 | jpm | 488 |   | 
        
           | 1840 | jpm | 489 | 	public function ajouterConstrainteAppliImg() {
 | 
        
           |  |  | 490 | 		$this->ajouterContrainteMilieu();
 | 
        
           |  |  | 491 | 		$this->ajouterContrainteTri();
 | 
        
           |  |  | 492 | 		$this->ajouterContrainteTagCel();
 | 
        
           |  |  | 493 | 		$this->ajouterContrainteTagDel();
 | 
        
           |  |  | 494 | 	}
 | 
        
           |  |  | 495 |   | 
        
           |  |  | 496 | 	private function ajouterContrainteMilieu() {
 | 
        
           |  |  | 497 | 		if (isset($this->parametres['masque.milieu'])) {
 | 
        
           |  |  | 498 | 			$milieu = $this->parametres['masque.milieu'];
 | 
        
           |  |  | 499 | 			$milieuMotif = $this->bdd->proteger("%$milieu%");
 | 
        
           | 1871 | jpm | 500 | 			$this->addWhere('masque.milieu', "do.milieu LIKE $milieuMotif");
 | 
        
           |  |  | 501 |   | 
        
           | 2034 | aurelien | 502 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 503 | 		}
 | 
        
           |  |  | 504 | 	}
 | 
        
           |  |  | 505 |   | 
        
           |  |  | 506 | 	private function ajouterContrainteTri() {
 | 
        
           |  |  | 507 | 		if (isset($this->parametres['tri'])) {
 | 
        
           |  |  | 508 | 			$tri = $this->parametres['tri'];
 | 
        
           |  |  | 509 |   | 
        
           | 1863 | jpm | 510 | 			if (isset($this->parametres['protocole'])  && ($tri == 'moyenne-arithmetique' || $tri == 'points')) {
 | 
        
           | 1840 | jpm | 511 | 				// $this->parametres['protocole'] *est* défini (cf Outils::filtrerUrlsParams...())
 | 
        
           | 1871 | jpm | 512 | 				$sqlTpl = 'LEFT JOIN del_image_stat AS dis ON di.id_image = dis.ce_image AND dis.ce_protocole = %d';
 | 
        
           | 1840 | jpm | 513 | 				$triSql = sprintf($sqlTpl, $this->parametres['protocole']);
 | 
        
           |  |  | 514 | 				$this->addJoinDis($triSql);
 | 
        
           |  |  | 515 | 			}
 | 
        
           |  |  | 516 |   | 
        
           |  |  | 517 | 			if (isset($this->parametres['ordre']) && $tri == 'tags') {
 | 
        
           |  |  | 518 | 				$typeJointure = ($this->parametres['ordre'] == 'desc') ? 'INNER' : 'LEFT';
 | 
        
           | 1871 | jpm | 519 | 				$this->addJoin("$typeJointure JOIN del_image_stat AS dis ON di.id_image = dis.ce_image");
 | 
        
           | 1840 | jpm | 520 | 			}
 | 
        
           |  |  | 521 | 		}
 | 
        
           |  |  | 522 | 	}
 | 
        
           |  |  | 523 |   | 
        
           |  |  | 524 | 	private function ajouterContrainteTagCel() {
 | 
        
           | 1845 | jpm | 525 | 		if (isset($this->parametres['masque.tag_cel'])) {
 | 
        
           | 1840 | jpm | 526 | 			if (isset($this->parametres['masque.tag_cel']['AND'])) {
 | 
        
           |  |  | 527 | 				$tags = $this->parametres['masque.tag_cel']['AND'];
 | 
        
           |  |  | 528 | 				$clausesWhere = array();
 | 
        
           |  |  | 529 | 				foreach ($tags as $tag) {
 | 
        
           |  |  | 530 | 					$tagMotif = $this->bdd->proteger("%$tag%");
 | 
        
           | 1922 | jpm | 531 | 					if ($this->etreAppliImg()) {
 | 
        
           | 1981 | aurelien | 532 | 						$sousRequete = 'SELECT id_observation '.
 | 
        
           | 1922 | jpm | 533 | 							'FROM del_observation '.
 | 
        
           |  |  | 534 | 							"WHERE mots_cles_texte LIKE $tagMotif ";
 | 
        
           |  |  | 535 | 						$sql = " (di.mots_cles_texte LIKE $tagMotif OR di.id_image IN ($sousRequete) ) ";
 | 
        
           |  |  | 536 | 					} else {
 | 
        
           |  |  | 537 | 						// WARNING : la sous-requête est la meilleure solution trouvée pour contrer le fonctionnement
 | 
        
           |  |  | 538 | 						// étrange de l'optimiseur de MYSQL 5.6 (à retester avec Mysql 5.7 et suivant).
 | 
        
           |  |  | 539 | 						$sousRequete = 'SELECT DISTINCT ce_observation '.
 | 
        
           |  |  | 540 | 							'FROM del_image '.
 | 
        
           |  |  | 541 | 							"WHERE mots_cles_texte LIKE $tagMotif ".
 | 
        
           |  |  | 542 | 							'AND ce_observation IS NOT NULL';
 | 
        
           |  |  | 543 | 						$sql = " (do.mots_cles_texte LIKE $tagMotif OR do.id_observation IN ($sousRequete)) ";
 | 
        
           |  |  | 544 | 					}
 | 
        
           |  |  | 545 | 					$clausesWhere[] = $sql;
 | 
        
           | 1840 | jpm | 546 | 				}
 | 
        
           |  |  | 547 | 				$whereTags = implode(' AND ', $clausesWhere);
 | 
        
           |  |  | 548 | 				$this->addWhere('masque.tag_cel', "($whereTags)");
 | 
        
           |  |  | 549 | 			} else if (isset($this->parametres['masque.tag_cel']['OR'])) {
 | 
        
           |  |  | 550 | 				$tags = $this->parametres['masque.tag_cel']['OR'];
 | 
        
           | 1922 | jpm | 551 | 				$tagMotif = $this->bdd->proteger(implode('|', $tags));
 | 
        
           | 1871 | jpm | 552 | 				$sqlTpl = "CONCAT(IFNULL(do.mots_cles_texte,''),IFNULL(di.mots_cles_texte,'')) REGEXP %s";
 | 
        
           | 1840 | jpm | 553 | 				$tagSql = sprintf($sqlTpl, $tagMotif);
 | 
        
           | 1922 | jpm | 554 |   | 
        
           | 1840 | jpm | 555 | 				$this->addWhere('masque.tag_cel', $tagSql);
 | 
        
           | 1922 | jpm | 556 |   | 
        
           |  |  | 557 | 				if ($this->etreAppliObs()) {
 | 
        
           |  |  | 558 | 					$this->addJoin('LEFT JOIN del_image AS di ON (di.ce_observation = do.id_observation) ');
 | 
        
           |  |  | 559 | 				}
 | 
        
           | 1840 | jpm | 560 | 			}
 | 
        
           | 2034 | aurelien | 561 | 			$this->ajouterJoinObsSiNecessaire();
 | 
        
           | 1840 | jpm | 562 | 		}
 | 
        
           |  |  | 563 | 	}
 | 
        
           |  |  | 564 |   | 
        
           |  |  | 565 | 	/**
 | 
        
           | 1881 | jpm | 566 | 	 * Plusieurs solutions sont disponibles dans les anciennes versions (voir DelTk et l'historique SVN de ce fichier).
 | 
        
           | 1840 | jpm | 567 | 	 */
 | 
        
           |  |  | 568 | 	private function ajouterContrainteTagDel() {
 | 
        
           |  |  | 569 | 		if (isset($this->parametres['masque.tag_del'])) {
 | 
        
           | 2030 | aurelien | 570 | 			$nbTags = $this->getNombreDeTags();
 | 
        
           |  |  | 571 | 			if($nbTags > 1) {
 | 
        
           |  |  | 572 | 				$tagsMotif = $this->construireTagsMotif();
 | 
        
           |  |  | 573 | 				if (is_null($tagsMotif) === false) {
 | 
        
           |  |  | 574 | 					$sousRequete = 'SELECT ce_image '.
 | 
        
           |  |  | 575 | 						'FROM del_image_tag '.
 | 
        
           |  |  | 576 | 						'WHERE actif = 1 '.
 | 
        
           |  |  | 577 | 						'GROUP BY ce_image '.
 | 
        
           |  |  | 578 | 						"HAVING GROUP_CONCAT(DISTINCT tag_normalise ORDER BY tag_normalise) REGEXP $tagsMotif ";
 | 
        
           |  |  | 579 | 				}
 | 
        
           |  |  | 580 | 			} else {
 | 
        
           | 2034 | aurelien | 581 | 				// Si un seul tag est demandé il se trouve dans le OR dans le cas de la recherche
 | 
        
           |  |  | 582 | 				// spécifique et dans le AND dans le cas de la recherche générale
 | 
        
           |  |  | 583 | 				// WTF?
 | 
        
           |  |  | 584 | 				$tag = "";
 | 
        
           |  |  | 585 | 				if(isset($this->parametres['masque.tag_del']['OR'][0])) {
 | 
        
           |  |  | 586 | 					$tag = $this->parametres['masque.tag_del']['OR'][0];
 | 
        
           |  |  | 587 | 				} else if(isset($this->parametres['masque.tag_del']['AND'][0])) {
 | 
        
           |  |  | 588 | 					$tag = $this->parametres['masque.tag_del']['AND'][0];
 | 
        
           |  |  | 589 | 				}
 | 
        
           |  |  | 590 |   | 
        
           | 1922 | jpm | 591 | 				$sousRequete = 'SELECT ce_image '.
 | 
        
           | 2030 | aurelien | 592 | 						'FROM del_image_tag '.
 | 
        
           |  |  | 593 | 						'WHERE actif = 1 '.
 | 
        
           |  |  | 594 | 						'AND tag_normalise LIKE '.$this->bdd->proteger($tag.'%');
 | 
        
           | 1840 | jpm | 595 | 			}
 | 
        
           | 2030 | aurelien | 596 |   | 
        
           |  |  | 597 | 			$this->addWhere('masque.tag_del', "di.id_image IN ($sousRequete)");
 | 
        
           | 1840 | jpm | 598 | 		}
 | 
        
           |  |  | 599 | 	}
 | 
        
           | 2030 | aurelien | 600 |   | 
        
           |  |  | 601 | 	private function getNombreDeTags() {
 | 
        
           |  |  | 602 | 		$somme = 0;
 | 
        
           |  |  | 603 | 		if (isset($this->parametres['masque.tag_del']['AND'])) {
 | 
        
           |  |  | 604 | 			$somme = count($this->parametres['masque.tag_del']['AND']);
 | 
        
           | 2034 | aurelien | 605 | 		} else {
 | 
        
           |  |  | 606 | 			$somme = count($this->parametres['masque.tag_del']['OR']);
 | 
        
           | 2030 | aurelien | 607 | 		}
 | 
        
           |  |  | 608 | 		return $somme;
 | 
        
           |  |  | 609 | 	}
 | 
        
           | 1840 | jpm | 610 |   | 
        
           | 1922 | jpm | 611 | 	private function construireTagsMotif() {
 | 
        
           |  |  | 612 | 		$tagsMotif = null;
 | 
        
           |  |  | 613 | 		if (isset($this->parametres['masque.tag_del']['AND'])) {
 | 
        
           |  |  | 614 | 			$tags = $this->parametres['masque.tag_del']['AND'];
 | 
        
           |  |  | 615 | 			// ATTENTION -> optimisation: en cas de "AND" on sort() l'input et le GROUP_CONCAT()
 | 
        
           |  |  | 616 | 			// donc nous utilisons des ".*" plutôt que de multiples conditions et "|"
 | 
        
           |  |  | 617 | 			sort($tags);
 | 
        
           |  |  | 618 | 			$tagsMotif = $this->bdd->proteger(implode('.*', $tags));
 | 
        
           |  |  | 619 | 		} else if (isset($this->parametres['masque.tag_del']['OR'])) {
 | 
        
           |  |  | 620 | 			$tags = $this->parametres['masque.tag_del']['OR'];
 | 
        
           |  |  | 621 | 			$tagsMotif = $this->bdd->proteger(implode('|', $tags));
 | 
        
           | 1840 | jpm | 622 | 		}
 | 
        
           | 1922 | jpm | 623 | 		return $tagsMotif;
 | 
        
           | 1840 | jpm | 624 | 	}
 | 
        
           |  |  | 625 |   | 
        
           |  |  | 626 | 	/**
 | 
        
           |  |  | 627 | 	 * Partie spécifique à PictoFlora:
 | 
        
           | 1863 | jpm | 628 | 	 * Attention : si le critère de tri n'est pas suffisant, les résultats affichés peuvent varier à chaque appel
 | 
        
           |  |  | 629 | 	 * de la même page de résultat de PictoFlora.
 | 
        
           | 1840 | jpm | 630 | 	 */
 | 
        
           |  |  | 631 | 	public function definirOrdreSqlAppliImg() {
 | 
        
           |  |  | 632 | 		$ordre = $this->parametres['ordre'];
 | 
        
           | 1968 | aurelien | 633 |   | 
        
           |  |  | 634 | 		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
 | 
        
           |  |  | 635 | 		switch ($tri) {
 | 
        
           | 1863 | jpm | 636 | 			case 'moyenne-arithmetique' :
 | 
        
           | 1888 | jpm | 637 | 				$this->addOrderBy("dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
 | 
        
           | 1840 | jpm | 638 | 				break;
 | 
        
           |  |  | 639 | 			case 'points' :
 | 
        
           | 1888 | jpm | 640 | 				$this->addOrderBy("dis.nb_points $ordre, dis.moyenne $ordre, dis.nb_votes $ordre, id_image $ordre");
 | 
        
           | 1840 | jpm | 641 | 				break;
 | 
        
           |  |  | 642 | 			case 'tags' :
 | 
        
           | 1888 | jpm | 643 | 				$this->addOrderBy("dis.nb_tags $ordre, id_image $ordre");
 | 
        
           | 1840 | jpm | 644 | 				break;
 | 
        
           |  |  | 645 | 			case 'date_observation' :
 | 
        
           | 1871 | jpm | 646 | 				$this->addOrderBy("date_observation $ordre, ce_observation $ordre");
 | 
        
           | 1840 | jpm | 647 | 				break;
 | 
        
           | 1863 | jpm | 648 | 			case 'date_transmission' :
 | 
        
           | 1840 | jpm | 649 | 			default:
 | 
        
           | 1871 | jpm | 650 | 				$this->addOrderBy("di.date_transmission $ordre, ce_observation $ordre");
 | 
        
           | 1840 | jpm | 651 | 		}
 | 
        
           |  |  | 652 | 	}
 | 
        
           |  |  | 653 |   | 
        
           | 1845 | jpm | 654 | 	public function definirOrdreSqlAppliObs() {
 | 
        
           |  |  | 655 | 		$ordre = $this->parametres['ordre'];
 | 
        
           |  |  | 656 |   | 
        
           |  |  | 657 | 		// parmi self::$tri_possible
 | 
        
           | 1968 | aurelien | 658 | 		$tri = isset($this->parametres['tri']) ? $this->parametres['tri'] : '';
 | 
        
           |  |  | 659 | 			switch ($tri) {
 | 
        
           | 1845 | jpm | 660 | 			case 'date_observation' :
 | 
        
           |  |  | 661 | 				$this->addOrderBy("date_observation $ordre, id_observation $ordre");
 | 
        
           | 1933 | aurelien | 662 | 				break;
 | 
        
           | 2034 | aurelien | 663 | 			case 'nb_commentaires' :
 | 
        
           |  |  | 664 | 				$sql_nb_comms = '(SELECT COUNT(id_commentaire) FROM del_commentaire AS dc WHERE ce_observation = id_observation)';
 | 
        
           |  |  | 665 | 				$this->addOrderBy("$sql_nb_comms $ordre, id_observation $ordre");
 | 
        
           | 1845 | jpm | 666 | 				break;
 | 
        
           | 1933 | aurelien | 667 | 			case 'date_transmission' :
 | 
        
           | 1845 | jpm | 668 | 			default:
 | 
        
           | 1871 | jpm | 669 | 				$this->addOrderBy("do.date_transmission $ordre, id_observation $ordre");
 | 
        
           | 1845 | jpm | 670 | 		}
 | 
        
           |  |  | 671 | 	}
 | 
        
           |  |  | 672 |   | 
        
           | 1840 | jpm | 673 | 	public function getAliasDesChamps($champsEtAlias, $select = null, $prefix = null) {
 | 
        
           |  |  | 674 | 		$arr = ($select) ? array_intersect_key($champsEtAlias, array_flip($select)) :  $champsEtAlias;
 | 
        
           |  |  | 675 | 		$keys = array_keys($arr);
 | 
        
           |  |  | 676 |   | 
        
           |  |  | 677 | 		if ($prefix) {
 | 
        
           |  |  | 678 | 			array_walk($keys, create_function('&$val, $k, $prefix', '$val = sprintf("%s.`%s`", $prefix, $val);'), $prefix);
 | 
        
           |  |  | 679 | 		} else {
 | 
        
           |  |  | 680 | 			array_walk($keys, create_function('&$val, $k', '$val = sprintf("`%s`", $val);'));
 | 
        
           |  |  | 681 | 		}
 | 
        
           |  |  | 682 |   | 
        
           |  |  | 683 | 		return implode(', ', array_map(create_function('$v, $k', 'return sprintf("%s AS `%s`", $k, $v);'), $arr, $keys));
 | 
        
           |  |  | 684 | 	}
 | 
        
           |  |  | 685 |   | 
        
           |  |  | 686 | 	public function getVotesDesImages($idsImages, $protocole = null) {
 | 
        
           |  |  | 687 | 		if (!$idsImages) return;
 | 
        
           |  |  | 688 |   | 
        
           |  |  | 689 | 		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
 | 
        
           |  |  | 690 | 		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
 | 
        
           |  |  | 691 |  		$selectVotes = array('id_vote', 'ce_image', 'ce_protocole', 'ce_utilisateur', 'valeur', 'date');
 | 
        
           |  |  | 692 | 		$selectProtocole = array('id_protocole', 'intitule', 'descriptif', 'tag');
 | 
        
           |  |  | 693 | 		$voteChamps = $this->getAliasDesChamps($mappingVotes, $selectVotes, 'v'); // "v": cf alias dans la requête
 | 
        
           |  |  | 694 | 		$protoChamps = $this->getAliasDesChamps($mappingProtocoles, $selectProtocole, 'p');
 | 
        
           |  |  | 695 | 		$idImgsConcat = implode(',', $idsImages);
 | 
        
           |  |  | 696 |   | 
        
           |  |  | 697 | 		$requete = "SELECT $voteChamps, $protoChamps ".
 | 
        
           |  |  | 698 | 			'FROM del_image_vote AS v '.
 | 
        
           |  |  | 699 | 			'	INNER JOIN del_image_protocole AS p ON (v.ce_protocole = p.id_protocole) '.
 | 
        
           |  |  | 700 | 			"WHERE v.ce_image IN ($idImgsConcat) ".
 | 
        
           |  |  | 701 | 			($protocole ? "	AND v.ce_protocole = $protocole " : '').
 | 
        
           |  |  | 702 | 			"ORDER BY FIELD(v.ce_image, $idImgsConcat) ".
 | 
        
           |  |  | 703 | 			'-- '.__FILE__.':'.__LINE__;
 | 
        
           |  |  | 704 | 		return $this->bdd->recupererTous($requete);
 | 
        
           |  |  | 705 | 	}
 | 
        
           |  |  | 706 |   | 
        
           |  |  | 707 | 	/**
 | 
        
           |  |  | 708 | 	 * Ajoute les informations sur le protocole et les votes aux images.
 | 
        
           |  |  | 709 | 	 *
 | 
        
           |  |  | 710 | 	 * ATTENTION : Subtilité, nous passons ici le tableau d'images indexé par id_image qui est bien
 | 
        
           |  |  | 711 | 	 * plus pratique pour associer les vote à un tableau, puisque nous ne connaissons pas les id d'observation.
 | 
        
           |  |  | 712 | 	 * Mais magiquement (par référence), cela va remplir notre tableau indexé par couple d'id (id_image, id_observation)
 | 
        
           |  |  | 713 | 	 * cf ListeImages::reformateImagesDoubleIndex() à qui revient la tâche de créer ces deux versions
 | 
        
           |  |  | 714 | 	 * simultanément lorsque c'est encore possible.
 | 
        
           |  |  | 715 | 	 */
 | 
        
           | 1881 | jpm | 716 | 	// TODO : supprimer cette "subtilité" source d'erreurs
 | 
        
           | 1840 | jpm | 717 | 	public function ajouterInfosVotesProtocoles($votes, &$images) {
 | 
        
           |  |  | 718 | 		if (!$votes) return;
 | 
        
           | 1845 | jpm | 719 |   | 
        
           | 1840 | jpm | 720 | 		$mappingVotes = $this->conteneur->getParametreTableau('votes.mapping');
 | 
        
           |  |  | 721 | 		$mappingProtocoles = $this->conteneur->getParametreTableau('protocoles.mapping');
 | 
        
           |  |  | 722 |   | 
        
           |  |  | 723 | 		// pour chaque vote
 | 
        
           |  |  | 724 | 		foreach ($votes as $vote) {
 | 
        
           |  |  | 725 | 			$imgId = $vote['image.id'];
 | 
        
           |  |  | 726 | 			$protoId = $vote['protocole.id'];
 | 
        
           |  |  | 727 |   | 
        
           |  |  | 728 | 			if (!array_key_exists('protocoles_votes', $images[$imgId]) ||
 | 
        
           | 1863 | jpm | 729 | 					!array_key_exists($protoId, $images[$imgId]['protocoles_votes'])) {
 | 
        
           | 1840 | jpm | 730 | 				// extrait les champs spécifique au protocole (le LEFT JOIN de chargerVotesImage les ramène en doublons
 | 
        
           |  |  | 731 | 				$protocole = array_intersect_key($vote, array_flip($mappingProtocoles));
 | 
        
           |  |  | 732 | 				$images[$imgId]['protocoles_votes'][$protoId] = $protocole;
 | 
        
           |  |  | 733 | 			}
 | 
        
           |  |  | 734 |   | 
        
           |  |  | 735 | 			$chpsVotes = array('id_vote', 'ce_image', 'ce_utilisateur', 'valeur', 'date');
 | 
        
           |  |  | 736 | 			$voteSelection = array_intersect_key($mappingVotes, array_flip($chpsVotes));
 | 
        
           |  |  | 737 | 			$vote = array_intersect_key($vote, array_flip($voteSelection));
 | 
        
           |  |  | 738 | 			$images[$imgId]['protocoles_votes'][$protoId]['votes'][$vote['vote.id']] = $vote;
 | 
        
           |  |  | 739 | 		}
 | 
        
           |  |  | 740 | 	}
 | 
        
           | 1845 | jpm | 741 |   | 
        
           |  |  | 742 | 	public function getTotalLignesTrouvees() {
 | 
        
           | 1888 | jpm | 743 | 		$resultat = $this->bdd->recuperer('SELECT FOUND_ROWS() AS nbre -- '.__FILE__.':'.__LINE__);
 | 
        
           | 1845 | jpm | 744 | 		return intval($resultat['nbre']);
 | 
        
           |  |  | 745 | 	}
 | 
        
           | 1840 | jpm | 746 | }
 |