Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 1124 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
/**
 * Retourne la liste des noms de répertoriés par le projet chorodep, associés à la liste de
 * leurs statuts de protection, la liste de leurs noms vernaculaires, et leur présence, utile
 * surtout dans le cas où on filtre par zone géo.
 * Merci Monsieur Plus !
 * Paramètres :
 * - masque.nom : un LIKE sera effectué sur le nom
 * - masque.zone-geo : limite les résultats aux noms des espèces présentes dans le département (nombre à 2 chiffres) spécifié
 * - masque.proteges : si '0' retourne les protections NULL, si '1' les NOT NULL
 *
 * @package chorodep
 * @author Mathias Chouet <mathias@tela-botanica.org>
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
 * @version 1.0
 * @copyright 1999-2014 Tela Botanica (accueil@tela-botanica.org)
 */

class NomsPlus extends Noms {

        protected $tableNomsVernaculaires;
        protected $tableStatutsProtection;

        protected function init() {
                parent::init();
                $this->tableNomsVernaculaires = Config::get('table_chorologie_nv');
                $this->tableStatutsProtection = Config::get('table_chorologie_sp');
                $this->serviceNom = 'noms-plus';
        }

        protected function setMasque($parametres) {
                parent::setMasque($parametres);
                // masque sur protection
                if(isset($parametres['masque.proteges']) && $parametres['masque.proteges'] != '') {
                        $this->masque['proteges'] = $parametres['masque.proteges'];
                }
        }

        /**
         * Renvoie la liste des taxons, les noms vernaculaires et statuts de protacion associés; si
         * un masque a été défini sur une zone géographique, retourne aussi la présence sur cette zone
         */
        protected function listeNoms() {
                $req = "SELECT DISTINCT c.num_nom, c.nom_sci, group_concat(DISTINCT nv.nom_vernaculaire) as noms_vernaculaires";
                if (isset($this->masque['zone-geo']) && $this->masque['zone-geo'] != null) {
                        $req .= ", max(`" . $this->masque['zone-geo'] . "`) as presence";
                }
                $req .= ", sp.protection";
                $req .= " FROM " . $this->table . " c";
                $req .= " LEFT JOIN " . $this->tableNomsVernaculaires . " nv";
                $req .= " ON c.num_tax = nv.num_tax";
                $req .= " LEFT JOIN " . $this->tableStatutsProtection . " sp";
                $req .= " ON c.num_nom = sp.num_nom";
                $req .= $this->construireWhere();
                $req .= " GROUP BY c.num_nom";
                $req .= " ORDER BY " . $this->tri . " " . $this->tri_dir . " ";
                $req .= " LIMIT " . $this->depart. ", " . $this->limite;

                //echo "REQUETE: $req"; exit;
                $resultat = $this->getBdd()->recupererTous($req);
                // décodage des statuts de protection
                foreach ($resultat as $k => $r) {
                        $resultat[$k]['statuts_protection'] = json_decode($r['protection']);
                        unset($resultat[$k]['protection']);
                }

                return $resultat;
        }

        protected function compterNoms() {
                $req = "SELECT count(DISTINCT c.num_nom, c.nom_sci) AS compte"
                        . " FROM " . $this->table . " c" // alias pour compatibilité avec le where
                        . " LEFT JOIN " . $this->tableStatutsProtection . " sp" // jointure pour compatibilité avec le where
                        . " ON c.num_nom = sp.num_nom";
                $req .= $this->construireWhere();
                $resultat = $this->getBdd()->recuperer($req);

                return $resultat['compte'];
        }

        protected function construireWhere() {
                $where = "";
                $conditions = array();
                // élimination des entrées sans nn valide
                $conditions[] = "CAST(c.num_nom AS decimal) != 0";
                // masque
                if(!empty($this->masque)) {
                        $masqueZg = null;
                        if(isset($this->masque['nom'])) {
                                $masqueNom = $this->getBdd()->proteger($this->masque['nom']);
                                $conditions[] = "c.nom_sci LIKE $masqueNom";
                        }
                        if(isset($this->masque['zone-geo'])) {
                                $masqueZg = $this->masque['zone-geo'];
                                $conditions[] = "`$masqueZg` in ('1', '1?')";
                        }
                        if(isset($this->masque['proteges'])) {
                                $masqueProteges = ($this->masque['proteges'] === '1');
                                if ($masqueZg) { // protection sur les zones concernées seulement
                                        $sousConditions = array();
                                        $zonesProtegees = $this->zonesProtegeesParDepartement($masqueZg);
                                        foreach ($zonesProtegees as $zp) {
                                                // @ACHTUNG pas de $this->getBdd()->proteger() sinon ça foire les doubles quotes - danger !
                                                $zpP = "'%" . 'zone":"' . $zp . "%'"; // fouille dans le JSON à l'arrache
                                                $sousConditions[] = "sp.protection " . ($masqueProteges ? "" : "NOT ") . "LIKE $zpP";
                                        }
                                        // si clause négative, IS NULL OR (NOT LIKE [AND NOT LIKE]*) sinon LIKE [OR LIKE]*
                                        if ($masqueProteges) {
                                                $conditions[] = '(' . implode(" OR ", $sousConditions) . ')';
                                        } else {
                                                $conditions[] = '( sp.protection IS NULL OR (' . implode(" AND ", $sousConditions) . '))';
                                        }
                                } else {
                                        $conditions[] = "sp.protection IS " . ($masqueProteges ? "NOT " : "") . "NULL ";
                                }
                        }
                }
                $where = " WHERE " . implode(' AND ', $conditions);
                return $where;
        }

        /**
         * Retourne la liste des codes de zones d'application de la protection concernant un département,
         * soit le code du département lui-même, le code de sa région, plus les codes "France" et "Europe"
         * @TODO déplacer dans sptb ?
         * @param string $dept une chaîne représentant le département, sur 2 chiffres
         */
        protected function zonesProtegeesParDepartement($dept) {
                $zones = array('FX', 'EU');
                $zones[] = "Dpt-$dept";

                // Appel service insee-d pour connaître la région
                $url_tpl = Config::get('insee_d_url_tpl');
                $url = sprintf($url_tpl, $dept);
                $donnees = $this->getRestClient()->consulter($url);
                $donnees = json_decode($donnees, true);
                if (! empty($donnees['region.code'])) {
                        $zones[] = 'Reg-' . $donnees['region.code'];
                }

                return $zones;
        }

        /**
         * Méthode permettant de faire appel à un client REST en fonction des besoins du service.
         */
        /*protected function getRestClient() {
                if (! isset($this->RestClient)) {
                        $this->RestClient = new RestClient();
                }
                return $this->RestClient;
        }*/
}