chemin.php (4640B)
1 <?php 2 3 require_once(dirname(__FILE__) . "/path.php"); 4 5 define('CHEMIN_JOKER_MULTI_SEGMENTS', '**'); 6 define('CHEMIN_JOKER_SEGMENT', '*'); 7 8 class Chemin { 9 // Si $chemin est un tableau, chaque segment doit vérifier les invariants de nettoyer_segment. 10 public function __construct($chemin, $est_un_motif = false) { 11 if (! is_array($chemin)) { 12 $this->segments = self::nettoyer_chemin($chemin, $est_un_motif); 13 } else { 14 $this->segments = $chemin; 15 } 16 } 17 18 public function correspond($motif) { 19 $motif = $motif->segments; 20 // motif : liste de segments pouvant être un chaîne ou un jocker 21 // correspondant à "n'importe quelle chaîne pour ce segment". Le 22 // dernier segment peut être le joker "n'importe quelle suite de 23 // segments (le motif doit donc correspondre à un préfixe du chemin 24 // dans ce cas-là). 25 // chemin : liste de segments. 26 27 // SÉCURITÉ : les segments de chemin et motif sont déjà nettoyés. 28 29 if ((count($motif) != count($this->segments)) && (end($motif) != CHEMIN_JOKER_MULTI_SEGMENTS)) { 30 return false; 31 } 32 for ($i = 0; $i < count($motif); $i++) { 33 if ($motif[$i] == CHEMIN_JOKER_MULTI_SEGMENTS) { 34 continue; 35 } 36 if ($motif[$i] == CHEMIN_JOKER_SEGMENT) { 37 continue; 38 } 39 if ($i < count($this->segments) && $motif[$i] == $this->segments[$i]) { 40 continue; 41 } 42 return false; 43 } 44 return true; 45 } 46 47 // Invariant de sécurité : la chaîne renvoyée ne commence ni ne 48 // termine par '/'. 49 public function get($slash_debut = true) { 50 return ($slash_debut ? '/' : '') . join($this->segments, '/'); 51 } 52 53 public function get_url($fin = "") { 54 // Config::get("url_base") DOIT se terminer par '/', tel que spécifié 55 // dans config.php. 56 $ch = $this->get(false) . "/"; 57 if ($ch == '/') $ch = ''; 58 return Config::get("url_base") . $ch . $fin; 59 } 60 61 public function get_fs_stockage() { 62 return Path::combine(Config::get("chemin_base_stockage"), $this->get()); 63 } 64 65 public function get_fs_public() { 66 return Path::combine(Config::get("chemin_base_public"), $this->get()); 67 } 68 69 public function enfant($nom) { 70 $s = $this->segments; 71 $x = self::nettoyer_segment($nom); 72 if ($x != '') { 73 array_push($s, $x); 74 } 75 return new self($s); 76 } 77 78 public function parent() { 79 return new self(array_slice($this->segments, 0, -1)); 80 } 81 82 public function renomer($nom) { 83 return $this->parent()->enfant($nom); 84 } 85 86 public function dernier() { 87 return end($this->segments); 88 } 89 90 91 public static function nettoyer_chemin($chemin, $est_un_motif = false) { 92 // SÉCURITÉ : $chemin nettoyé 93 // * Ne contient pas '\0' 94 // * Ne contient pas '../' 95 // * Ne contient pas de double occurence de '/' 96 // * Ne se termine pas par '/' 97 // * Ne commence pas par '/' 98 // * Est découpé en segments 99 // * Chaque segment est nettoyé avec nettoyer_segment(). 100 101 $chemin = preg_replace("/\\0/", '', $chemin); // TODO : vérifier si c'est bien ça ! (supprime _toutes_ les occurences ???) 102 $chemin = Path::normalize($chemin); 103 $chemin = preg_replace("/^\\/*/", '', $chemin); 104 $chemin = preg_replace("/\\/*$/", '', $chemin); 105 106 $segments = qw($chemin, '/'); 107 if ($est_un_motif) { 108 $segments = array_map(array("self", "nettoyer_segment_motif"), $segments); 109 } else { 110 $segments = array_map(array("self", "nettoyer_segment"), $segments); 111 } 112 113 return $segments; 114 } 115 116 public static function nettoyer_segment($segment, $est_un_motif = false) { 117 // SÉCURITÉ : $segment nettoyé : 118 // * /!\ Ne peut pas être vide /!\ 119 // * Ne doit pas contenir '\0' (octet NULL). 120 // * Ne doit pas contenir '/' non plus, remplacer par '-'. 121 // * Ne doit pas contenir '*' non plus, remplacer par '-'. 122 // * Ne contient pas "__prop__", remplacer par "___prop___". 123 124 if ($segment == "") $segment = "_vide_"; 125 $segment = preg_replace("/\\0/", '', $segment); // TODO : vérifier si c'est bien ça ! (supprime _toutes_ les occurences ???) 126 $segment = preg_replace("/\\//", '-', $segment); // TODO : vérifier si c'est bien ça ! (supprime _toutes_ les occurences ???) 127 if (!$est_un_motif) $segment = preg_replace("/\\*/", '-', $segment); // TODO : vérifier ... 128 $segment = preg_replace("/__prop__/", '___prop___', $segment); // TODO : vérifier si c'est bien ça ! (supprime _toutes_ les occurences ???) 129 return $segment; 130 } 131 132 public static function nettoyer_segment_motif($segment) { 133 return self::nettoyer_segment($segment, true); 134 } 135 } 136 137 ?>