* @author Delphine CAUQUIL * @author Jean-Pascal MILCENT * @license GPL v3 * @license CECILL v2 * @version 0.1 * @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org) */ class Projets extends RestService { /** Contients les paramètres.*/ private $parametres = array(); /** Contients les ressources.*/ private $ressources = array(); /** Nom du projet courrant. */ private $projetNom = array(); /** Nom du service demandé. */ private $serviceNom = array(); /** Chemin vers le dossier courrant. */ private $cheminCourrant = null; private $classe = null; private $cache; /** Indique si oui (true) ou non (false), on veut utiliser les paramètres brutes. */ protected $utilisationParametresBruts = true; public function __construct() { $this->cheminCourrant = dirname(__FILE__).DS; } public function consulter($ressources, $parametres) { $resultat = ''; $reponseHttp = new ReponseHttp(); try { $this->initialiserRessourcesEtParametres($ressources, $parametres); $resultat = $this->traiterRessources(); $reponseHttp->setResultatService($resultat); } catch (Exception $e) { $reponseHttp->ajouterErreur($e); } if(strpos($_SERVER['SCRIPT_NAME'], 'phpunit') === FALSE) $reponseHttp->emettreLesEntetes(); $corps = $reponseHttp->getCorps(); return $corps; } private function initialiserRessourcesEtParametres($ressources, $parametres) { $this->ressources = $ressources; $this->parametres = $parametres; } private function traiterRessources() { $retour = ''; if ($this->avoirRessources()) { if ($this->avoirRessourceProjet()) { $this->chargerNomDuService(); // défini $this->serviceNom $this->initialiserProjet(); // autoload defined here if ($this->avoirRessourceService()) { $this->classe = self::debusquerClasse($this->projetNom, $this->serviceNom); $retour = $this->initialiserService(); } } } return $retour; } private function avoirRessources() { $presenceDeRessources = false; if (isset($this->ressources) && count($this->ressources) > 0) { $presenceDeRessources = true; } else { $message = "Aucune ressource n'a été indiquée.\n". "Veuillez indiquer au moins un code de projet et un type de service."; $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($message, $code); } return $presenceDeRessources; } private function avoirRessourceProjet() { $presenceRessourceProjet = false; $projet = $this->ressources[0]; $projetsDispo = Outils::recupererTableauConfig('projetsDispo'); if (in_array($projet, $projetsDispo)) { $presenceRessourceProjet = true; } else { $message = "La ressource '$projet' n'indique pas un projet existant.\n". "Les projets existant sont :\n".implode(', ', $projetsDispo); $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($message, $code); } return $presenceRessourceProjet; } private function initialiserProjet() { $this->chargerNomDuProjet(); $this->chargerConfigProjet(); // php5.3 : Enregistrement en première position des autoload de la méthode gérant les classes des services if (phpversion() < 5.3) { spl_autoload_register(array($this, 'chargerClasseProjet')); } else { spl_autoload_register(array($this, 'chargerClasseProjet'), true , true); } } private function chargerNomDuProjet() { $this->projetNom = $this->ressources[0]; } private function chargerConfigProjet() { $projet = $this->projetNom; $chemin = Config::get('chemin_configurations')."config_$projet.ini"; Config::charger($chemin); } /* 1) jusqu'à présent: * le principe pour URL = a/b est: de charger * require_once($chemin/a/ucfirst(c).php) * new ucfirst(c); ucfirst(c)->consulter() * sachant que ucfirst(c).php et la classe ucfirst(c) apparaîssent à de multiples emplacements (selon a) 1") Beurk... (php-className conflicts en PHP 5.2) Ici nous faisons des cas particuliers pour Ontologies, mais en suivant ce principe, sont affectés: Images, Informations, InformationsTaxonsSup, LegendeCartes, NomCommune, Noms, NomsVernaculaires, Projets, Statuts, Taxons, TaxonsCartes, Textes, ZoneGeo cf: $ grep -r '^[cC]lass '|grep -F '.php:'|egrep -w " \($(grep -rh '^[cC]lass '|awk '{print $2}'|sort|uniq -d|tr "\n" '|')\) " \ |sort -k2 PS: "Using two class with the same name" http://stackoverflow.com/questions/4555186/using-two-class-with-the-same-name > Stop. > Whatever you are doing is wrong. Backup. Re-evaluate what you are doing and why. */ private static function debusquerClasse($p, $s) { if($s == 'ontologies') { switch($p) { case 'baseflor': return 'BaseFloreOntologies'; case 'eflore': return 'EfloreOntologies'; case 'chorodep': return 'ChorodepOntologies'; case 'baseveg': return 'BasevegOntologies'; case 'moissonnage': return 'MoissonnageOntologies'; case 'commun': return 'Ontologies'; } } if($s == 'cartes') { switch($p) { case 'bdtxa': return 'BdtxaCartes'; case 'eflore': return 'EfloreCartes'; case 'chorodep': return 'ChorodepCartes'; case 'moissonnage': return 'MoissonnageCartes'; case 'sophy': return 'SophyCartes'; } } return NULL; } private function chargerClasseProjet($classe) { if (class_exists($classe)) { return null; } if($this->serviceNom == 'ontologies') { $c = NULL; switch($this->projetNom) { case 'baseflor': $c = 'BaseFloreOntologies'; break; case 'eflore': $c = 'EfloreOntologies'; break; case 'chorodep': $c = 'ChorodepOntologies'; break; case 'baseveg': $c = 'BasevegOntologies'; break; case 'moissonnage': $c = 'MoissonnageOntologies'; break; case 'commun': $c = 'Ontologies'; break; } if($c) { require_once($this->cheminCourrant . 'commun' . DS . 'Commun.php'); require_once($this->cheminCourrant . $this->projetNom . DS . $this->obtenirNomClasseService($this->serviceNom) . '.php'); return; } } // problème de class-name conflict. Exemple: // phpunit --verbose --debug --filter 'ChorodepCartesTest::testCarteGenerique|EfloreCartesTest::testCarteGenerale' if($this->serviceNom == 'cartes') { $c = NULL; switch($this->projetNom) { case 'bdtxa': $c = 'BdtxaCartes'; break; case 'eflore': $c = 'EfloreCartes'; break; case 'chorodep': $c = 'ChorodepCartes'; break; case 'moissonnage': $c = 'MoissonnageCartes'; break; case 'sophy': $c = 'SophyCartes'; break; } if($c) { require_once($this->cheminCourrant . 'commun' . DS . 'Commun.php'); require_once($this->cheminCourrant . $this->projetNom . DS . $this->obtenirNomClasseService($this->serviceNom) . '.php'); return; } } $cheminBiblio = Config::get('chemin_bibliotheque'); $chemins = array(); $chemins[] = $this->cheminCourrant.$this->projetNom.DS; $chemins[] = $this->cheminCourrant.'commun'.DS; $chemins[] = $cheminBiblio; $chemins[] = $cheminBiblio.'robots'.DS; foreach ($chemins as $chemin) { $chemin = $chemin.$classe.'.php'; if (file_exists($chemin)) { require_once $chemin; break; } } } private function avoirRessourceService() { $presenceRessourceService = false; $servicesDispo = Outils::recupererTableauConfig('servicesDispo'); if (isset($this->ressources[1])) { $service = $this->ressources[1]; if (in_array($service, $servicesDispo)) { $presenceRessourceService = true; } else { $message = "Le service demandé '$service' n'est pas disponible pour le projet {$this->projetNom} !\n". "Les services disponibles sont : ".implode(', ', $servicesDispo); $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; throw new Exception($message, $code); } } else { $message = "Vous n'avez pas indiqué de service pour le projet {$this->projetNom} !\n". "Les services disponibles sont : ".implode(', ', $servicesDispo); $code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE; throw new Exception($message, $code); } return $presenceRessourceService; } private function initialiserService() { if($this->classe) { $classe = $this->classe; $service = new $classe($this->getBdd()); return $service->consulter($this->filtrerRessourcesPourService(), $this->parametres, $this->getBdd()); } $classe = $this->obtenirNomClasseService($this->serviceNom); $chemins = array(); $chemins[] = $this->cheminCourrant.$this->projetNom.DS.$classe.'.php'; $chemins[] = $this->cheminCourrant.'commun'.DS.$classe.'.php'; $service = null; foreach ($chemins as $chemin) { if (file_exists($chemin)) { $service = new $classe($this->getBdd()); // Affichage utile lors de PHPUnit pour détecter les conflits d'autoload de classes de même nom // $reflector = new ReflectionClass($classe); // printf("===> Projets init classe '%s' depuis '%s', mais provenant de '%s'\n", $classe, $chemin, $reflector->getFileName()); $ressourcesPourService = $this->filtrerRessourcesPourService(); return $service->consulter($ressourcesPourService, $this->parametres, $this->getBdd()); } } if (is_null($service)) { $message = "Le service demandé '{$this->serviceNom}' n'existe pas dans le projet {$this->projetNom} !"; $code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE; throw new Exception($message, $code); } return NULL; } private function chargerNomDuService() { $this->serviceNom = $this->ressources[1]; } private function obtenirNomClasseService($mot) { return str_replace(' ', '', ucwords(strtolower(str_replace('-', ' ', $mot)))); } private function filtrerRessourcesPourService() { $ressourcesPourService = array(); $nbreDeRessources = count($this->ressources); for ($i = 2; $i < $nbreDeRessources; $i++) { $ressourcesPourService[] = $this->ressources[$i]; } return $ressourcesPourService; } } ?>