* @author Aurélien Peronnet * @copyright 2010 Tela-Botanica * @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL * @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL */ class CartoControleur extends AppControleur { // identifiant de la france pour l'accès direct private $id_france = 'fr'; // nom du fond de carte en cours private $nom_fond = ''; private $niveau = 0; // contient le tableau de données sur les continents une fois chargé private $donnees_continents = array(); // contient le tableau de données sur les pays une fois chargé private $donnees_pays = array(); // contient le tableau de données sur les departements une fois chargé private $donnees_departements = array(); // contient le nombre total d'inscrits dans la zone en cours de consultation private $total_inscrits_zone = 0; //+----------------------------------------------------------------------------------------------------------------+ // Méthodes /** * Fonction d'affichage par défaut, elle appelle la cartographie */ public function executerActionParDefaut() { return $this->cartographier(1); } /** * Cartographier un annuaire. * @param int $id_annuaire l'identitifiant de l'annuaire à cartographier * @param int $continent l'identitifiant du continent sur lequel on se trouve * @param string $pays l'identitifiant du pays sur lequel on se trouve (normalement seulement la france si présent) * @return string la vue correspondante */ public function cartographier($id_annuaire, $continent= null , $pays = null) { // Initialisation de variable $donnees = array(); // la présence d'un pays (non) et d'un continent (ou non) détermine le niveau de carte à afficher $this->niveau = $this->calculerNiveau($continent, $pays); // suivant le niveau, continent et pays, on renvoie un template html différent $fond = $this->renvoyerPrefixePourNiveau($this->niveau, $continent, $pays); $carte = ''; // chaque continent possède un fond de carte différent if ($this->niveau == 1) { $carte = $this->renvoyerSuffixePourContinent($this->niveau, $continent, $pays); } // Création de la carte $options = array( 'carte_nom' => $fond.$carte, 'formule' => Cartographie::FORMULE_PROPORTIONNEL, 'couleur_claire' => Config::get('carte_couleur_claire'), 'couleur_foncee' => Config::get('carte_couleur_foncee'), 'fond_fichier' => Config::get('carte_base_nom_'.$fond).$carte, 'fond_dossier' => Application::getChemin().Config::get('carte_fonds_chemin'), 'stock_dossier' => Config::get('carte_stockage_chemin'), 'stock_url' => Config::get('carte_stockage_url'), 'debug' => Config::get('carte_mode_debug')); $cartographie = Composant::fabrique('cartographie', $options); $this->nom_fond = Config::get('carte_base_nom_'.$fond).$carte; // Construction des données nécessaires à la cartographie $zones = $cartographie->getCarteZones(); $this->chargerZonesNbre($id_annuaire,$zones, $this->niveau); $this->chargerZonesUrls($id_annuaire, $zones, $continent, $pays, $this->niveau); $navigation = new NavigationControleur(); $donnees_navigation = $this->obtenirUrlsNavigation($id_annuaire, $continent, $pays, null); $donnees['infos_pays'] = $donnees_navigation; $donnees['navigation'] = $navigation->afficherBandeauNavigationCartographie($donnees_navigation); $donnees['nb_resultats'] = $this->total_inscrits_zone; $cartographie->setCarteZones($zones); $cartographie->creerCarte(); $donnees['map'] = $cartographie->getImageMap(); $resultat = $this->getVue('cartes/'.$fond, $donnees); return $resultat; } /** * Charge le nombre d'inscrit par zone pour un annuaire donné * @param int $id_annuaire l'identifiant de l'annuaire * @param array $zones les zones à cartographier (attention, passage par référence, donc les zones sont modifiées) * @param int $niveau le niveau de la carto (monde, continent, ou pays) */ private function chargerZonesNbre($id_annuaire, &$zones, $niveau = 0) { $metaModele = $this->getModele('AnnuaireModele'); // on charge les inscrits pour le niveau donné $zones_infos = $this->chargerNombreInscritsParNiveauGeographique($id_annuaire, $niveau); foreach ($zones as $id => &$infos) { // si l'on a des données pour la zone, on renseigne le nombre d'inscrits if (isset($zones_infos[$id])) { $nbre = $zones_infos[$id]; $infos['info_nombre'] = $nbre; $this->total_inscrits_zone += $nbre; } else { // sinon on le met à 0 $infos['info_nombre'] = 0; } } } /** * Charge les des zones pour un annuaire donné * @param int $id_annuaire l'identifiant de l'annuaire * @param array $zones les zones à cartographier (attention, passage par référence, donc les zones sont modifiées) * @param int $continent l'identitifiant du continent sur lequel on se trouve * @param string $pays l'identitifiant du pays sur lequel on se trouve (normalement seulement la france si présent) * @param int $niveau le niveau de la carto (monde, continent, ou pays) */ private function chargerZonesUrls($id_annuaire, &$zones, $continent = null, $pays = null, $niveau = 0) { $url = new URL(Config::get('url_base')); $url->setVariableRequete('id_annuaire', $id_annuaire); foreach ($zones as $id => &$infos) { switch ($niveau) { // niveau 0 de la carte : on affiche tous les continents // l'url va pointer vers un continent en particulier case 0: $url->setVariableRequete('m', 'annuaire_afficher_carte'); $url->setVariableRequete('continent', $id); break; // niveau 1, on est sur un continent en particulier : on affiche le détail du continent demandé // l'url pointe sur des pays case 1: $url->setVariableRequete('continent', $continent); // si le pays c'est la france alors l'url pointera vers la carte des départements if($id == $this->id_france) { $url->setVariableRequete('m', 'annuaire_afficher_carte'); } else { // sinon l'url pointe vers la liste des inscrits de ce pays $url->setVariableRequete('m', 'annuaire_inscrits_carto'); } $url->setVariableRequete('pays', $id); break; // niveau 2, si on a cliqué sur la france pour afficher les départements : case 2: $url->setVariableRequete('m','annuaire_inscrits_carto'); $url->setVariableRequete('continent', $continent); $url->setVariableRequete('pays', $pays); $url->setVariableRequete('departement', $id); break; } $infos['url'] = sprintf($url, $id); } } /** * Renvoie le niveau auquel on se trouve suivant la présence ou non de certains paramètres * @param int $continent l'identitifiant du continent sur lequel on se trouve * @param string $pays l'identitifiant du pays sur lequel on se trouve (normalement seulement la france si présent) */ private function calculerNiveau($continent, $pays) { // le niveau 0 c'est la carte de base $niveau = 0; // le niveau 1 on consulte un continent en particulier (ex. Amérique du Sud) if($continent != null) { $niveau = 1; } // le niveau 2 c'est un pays en particulier (ce cas là n'arrive que pour la france) if($pays != null) { $niveau = 2; } return $niveau; } /** * Renvoie le type de template à utiliser suivant le niveau de certains paramètres * @param int $niveau le niveau de la carto * @return string le type de template */ private function renvoyerPrefixePourNiveau($niveau) { switch ($niveau) { case 0: $fond = 'continents'; break; case 1: $fond = 'pays'; break; case 2 : $fond = 'france'; break; default: $fond = ''; break; } return $fond; } /** * Renvoie le suffixe de fond de carte à utiliser pour un continent donné * @param int $niveau le niveau de la carto * @param int $niveau l'identifiant de continent * @return string le suffixe */ private function renvoyerSuffixePourContinent($niveau, $continent) { switch ($continent) { case 1: $carte = '_afrique'; break; case 2: $carte = '_nord_amerique'; break; case 3: $carte = '_asie'; break; case 4: $carte = '_europe'; break; case 5: $carte = '_oceanie'; break; case 6: $carte = '_sud_amerique'; break; case 7: $carte = '_moyen_orient'; break; default: $carte = ''; break; } return $carte; } /** * renvoie tous les noms templates pour chaque zone du monde * @return array un tableau associatif indexé par les identifiants de zone et contenant les noms de templates */ private function renvoyerTousTemplates() { return array(1 => 'pays_afrique', 2 => 'pays_nord_amerique', 3 => 'pays_asie', 4 => 'pays_europe', 5 => 'pays_oceanie', 6 => 'pays_sud_amerique', 7 => 'pays_moyen_orient'); } /** * Charge la liste des inscrits par zone pour un niveau géographique donné * @param int $id_annuaire l'identifiant de l'annuaire * @param int $niveau le niveau où l'on se situe * @return array un tableau associatif indexé par les identifiants de zone et contenant le nombre d'inscrits pour chaque zone */ private function chargerNombreInscritsParNiveauGeographique($id_annuaire, $niveau) { if ($niveau == 0) { // si on est au niveau des continents $zones_ids = array(); // il faut faire la somme des inscrits par zones géographique $templates = $this->renvoyerTousTemplates(); } else { // sinon on appelle la fonction pour la zone demandée $zones_ids = $this->chargerZonesParCsv(Application::getChemin().Config::get('carte_fonds_chemin').$this->nom_fond); } $annuaire_controleur = new AnnuaireControleur(); $nb_inscrits = array(); switch ($niveau) { case 0 : // niveau de la carte du monde // pour chacun des continents, on fait la somme des membres de sa zone foreach ($templates as $id_continent => $template) { $zones_continent_ids = $this->chargerZonesParCsv(Application::getChemin().Config::get('carte_fonds_chemin').$template); $nb_inscrits[$id_continent] = array_sum($annuaire_controleur->chargerNombreAnnuaireListeInscritsParPays($id_annuaire, $zones_continent_ids)); } break; case 1 : // niveau de la carte des pays d'un continent $nb_inscrits = $annuaire_controleur->chargerNombreAnnuaireListeInscritsParPays($id_annuaire, $zones_ids); break; case 2 : // détail d'un pays $nb_inscrits = $annuaire_controleur->chargerNombreAnnuaireListeInscritsParDepartement($id_annuaire); break; } return $nb_inscrits; } public function obtenirUrlsNavigation($id_annuaire ,$continent = null, $pays = null, $departement = null) { $url_carte_monde = new URL(Config::get('url_base')); $url_carte_monde->setVariableRequete('id_annuaire', $id_annuaire); $url_carte_monde->setVariableRequete('m', 'annuaire_afficher_carte'); $donnees = array(); $donnees['url_carte_monde'] = $url_carte_monde; $donnees['nom_carte_monde'] = 'Carte du monde'; if ($continent != null && trim($continent) != '') { $infos_continents = $this->chargerInformationsContinentCsv(); $url_continent = new URL(Config::get('url_base')); $url_continent->setVariableRequete('id_annuaire', $id_annuaire); $url_continent->setVariableRequete('m', 'annuaire_afficher_carte'); $url_continent->setVariableRequete('continent', $continent); $donnees['url_continent'] = $url_continent; $donnees['nom_continent'] = $infos_continents[$continent][2]; } if ($pays != null && trim($pays) != '') { $templates_continents = $this->renvoyerTousTemplates(); $infos_continents = $this->chargerInformationsPaysDuContinentsCsv($templates_continents[$continent]); $infos_pays = $infos_continents[$pays]; $url_pays = new URL(Config::get('url_base')); $url_pays->setVariableRequete('id_annuaire', $id_annuaire); if ($pays == $this->id_france) { $url_pays->setVariableRequete('m', 'annuaire_afficher_carte'); } else { // sinon l'url pointe vers la liste des inscrits de ce pays $url_pays->setVariableRequete('m', 'annuaire_inscrits_carto'); } $url_pays->setVariableRequete('continent', $continent); $url_pays->setVariableRequete('pays', $pays); $donnees['url_pays'] = $url_pays; $donnees['nom_pays'] = $infos_pays[2]; } if ($departement != null && trim($departement) != '') { $infos_departement = $this->chargerInformationsDepartementsFranceCsv(); $url_departement = new URL(Config::get('url_base')); $url_departement->setVariableRequete('id_annuaire', $id_annuaire); $url_departement->setVariableRequete('m', 'annuaire_afficher_carte'); $url_departement->setVariableRequete('continent', $continent); $url_departement->setVariableRequete('departement', $departement); $url_departement->setVariableRequete('pays', $pays); $donnees['url_departement'] = $url_departement; $donnees['nom_departement'] = $infos_departement[$departement][2]; } $donnees['nb_resultats'] = $this->total_inscrits_zone; return $donnees; } public function chargerInformationsContinentCsv() { $nom_csv = Application::getChemin().Config::get('carte_fonds_chemin').'continents'; return $this->chargerInformationsCompletesParCsv($nom_csv); } public function chargerInformationsPaysDuContinentsCsv($continent) { $nom_csv = Application::getChemin().Config::get('carte_fonds_chemin').$continent; return $this->chargerInformationsCompletesParCsv($nom_csv); } public function chargerInformationsDepartementsFranceCsv() { $nom_csv = Application::getChemin().Config::get('carte_fonds_chemin').'france'; return $this->chargerInformationsCompletesParCsv($nom_csv); } public function chargerInformationsCompletesParCsv($nom_csv) { $fichier_csv = $nom_csv.'.csv'; $infos = array(); if (($handle = fopen($fichier_csv, 'r')) !== false) { $ligne = 0; while (($donnees = fgetcsv($handle, 1000, ',')) !== false) { if($ligne != 0 && trim($donnees[0]) != '') { $infos[$donnees[0]] = $donnees; } $ligne++; } fclose($handle); } return $infos; } /** * Récupère les identifiants de zone dans un fichier csv donné * @param string $nom_csv chemin vers le fichier csv (sans extension) qui contient les données * @return array un tableau contenant les identifiants des zones */ private function chargerZonesParCsv($nom_csv) { $fichier_csv = $nom_csv.'.csv'; $zones_id = array(); if (($handle = fopen($fichier_csv, 'r')) !== false) { $ligne = 0; while (($donnees = fgetcsv($handle, 1000, ',')) !== false) { if($ligne != 0 && trim($donnees[0]) != '') { $zones_id[] = "'".$donnees[0]."'"; } $ligne++; } fclose($handle); } return $zones_id; } }