[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/ -> pageutils.php (source)

   1  <?php
   2  /**
   3   * Utilities for handling pagenames
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Andreas Gohr <andi@splitbrain.org>
   7   * @todo       Combine similar functions like {wiki,media,meta}FN()
   8   */
   9  
  10  /**
  11   * Fetch the an ID from request
  12   *
  13   * Uses either standard $_REQUEST variable or extracts it from
  14   * the full request URI when userewrite is set to 2
  15   *
  16   * For $param='id' $conf['start'] is returned if no id was found.
  17   * If the second parameter is true (default) the ID is cleaned.
  18   *
  19   * @author Andreas Gohr <andi@splitbrain.org>
  20   */
  21  function getID($param='id',$clean=true){
  22    global $conf;
  23  
  24    $id = isset($_REQUEST[$param]) ? $_REQUEST[$param] : null;
  25  
  26    //construct page id from request URI
  27    if(empty($id) && $conf['userewrite'] == 2){
  28      //get the script URL
  29      if($conf['basedir']){
  30        $relpath = '';
  31        if($param != 'id') {
  32          $relpath = 'lib/exe/';
  33        }
  34        $script = $conf['basedir'].$relpath.basename($_SERVER['SCRIPT_FILENAME']);
  35      }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){
  36        $script = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','',
  37                                $_SERVER['SCRIPT_FILENAME']);
  38        $script = '/'.$script;
  39      }else{
  40        $script = $_SERVER['SCRIPT_NAME'];
  41      }
  42  
  43      //clean script and request (fixes a windows problem)
  44      $script  = preg_replace('/\/\/+/','/',$script);
  45      $request = preg_replace('/\/\/+/','/',$_SERVER['REQUEST_URI']);
  46  
  47      //remove script URL and Querystring to gain the id
  48      if(preg_match('/^'.preg_quote($script,'/').'(.*)/',$request, $match)){
  49        $id = preg_replace ('/\?.*/','',$match[1]);
  50      }
  51      $id = urldecode($id);
  52      //strip leading slashes
  53      $id = preg_replace('!^/+!','',$id);
  54    }
  55    if($clean) $id = cleanID($id);
  56    if(empty($id) && $param=='id') $id = $conf['start'];
  57  
  58    return $id;
  59  }
  60  
  61  /**
  62   * Remove unwanted chars from ID
  63   *
  64   * Cleans a given ID to only use allowed characters. Accented characters are
  65   * converted to unaccented ones
  66   *
  67   * @author Andreas Gohr <andi@splitbrain.org>
  68   * @param  string  $raw_id    The pageid to clean
  69   * @param  boolean $ascii     Force ASCII
  70   */
  71  function cleanID($raw_id,$ascii=false){
  72    global $conf;
  73    global $lang;
  74    static $sepcharpat = null;
  75  
  76    global $cache_cleanid;
  77    $cache = & $cache_cleanid;
  78  
  79    // check if it's already in the memory cache
  80    if (isset($cache[$raw_id])) {
  81      return $cache[$raw_id];
  82      }
  83  
  84    $sepchar = $conf['sepchar'];
  85    if($sepcharpat == null) // build string only once to save clock cycles
  86      $sepcharpat = '#\\'.$sepchar.'+#';
  87  
  88    $id = trim($raw_id);
  89    $id = utf8_strtolower($id);
  90  
  91    //alternative namespace seperator
  92    $id = strtr($id,';',':');
  93    if($conf['useslash']){
  94      $id = strtr($id,'/',':');
  95    }else{
  96      $id = strtr($id,'/',$sepchar);
  97    }
  98  
  99    if($conf['deaccent'] == 2 || $ascii) $id = utf8_romanize($id);
 100    if($conf['deaccent'] || $ascii) $id = utf8_deaccent($id,-1);
 101  
 102    //remove specials
 103    $id = utf8_stripspecials($id,$sepchar,'\*');
 104  
 105    if($ascii) $id = utf8_strip($id);
 106  
 107    //clean up
 108    $id = preg_replace($sepcharpat,$sepchar,$id);
 109    $id = preg_replace('#:+#',':',$id);
 110    $id = trim($id,':._-');
 111    $id = preg_replace('#:[:\._\-]+#',':',$id);
 112  
 113    $cache[$raw_id] = $id;
 114    return($id);
 115  }
 116  
 117  /**
 118   * Return namespacepart of a wiki ID
 119   *
 120   * @author Andreas Gohr <andi@splitbrain.org>
 121   */
 122  function getNS($id){
 123    $pos = strrpos($id,':');
 124    if($pos!==false){
 125      return substr($id,0,$pos);
 126    }
 127    return false;
 128  }
 129  
 130  /**
 131   * Returns the ID without the namespace
 132   *
 133   * @author Andreas Gohr <andi@splitbrain.org>
 134   */
 135  function noNS($id) {
 136    $pos = strrpos($id, ':');
 137    if ($pos!==false) {
 138      return substr($id, $pos+1);
 139    } else {
 140      return $id;
 141    }
 142  }
 143  
 144  /**
 145   * returns the full path to the datafile specified by ID and
 146   * optional revision
 147   *
 148   * The filename is URL encoded to protect Unicode chars
 149   *
 150   * @author Andreas Gohr <andi@splitbrain.org>
 151   */
 152  function wikiFN($raw_id,$rev='',$clean=true){
 153    global $conf;
 154  
 155    global $cache_wikifn;
 156    $cache = & $cache_wikifn;
 157  
 158    if (isset($cache[$raw_id]) && isset($cache[$raw_id][$rev])) {
 159      return $cache[$raw_id][$rev];
 160    }
 161  
 162    $id = $raw_id;
 163  
 164    if ($clean) $id = cleanID($id);
 165    $id = str_replace(':','/',$id);
 166    if(empty($rev)){
 167      $fn = $conf['datadir'].'/'.utf8_encodeFN($id).'.txt';
 168    }else{
 169      $fn = $conf['olddir'].'/'.utf8_encodeFN($id).'.'.$rev.'.txt';
 170      if($conf['compression']){
 171        //test for extensions here, we want to read both compressions
 172         if (@file_exists($fn . '.gz')){
 173            $fn .= '.gz';
 174         }else if(@file_exists($fn . '.bz2')){
 175            $fn .= '.bz2';
 176         }else{
 177            //file doesnt exist yet, so we take the configured extension
 178            $fn .= '.' . $conf['compression'];
 179         }
 180      }
 181    }
 182  
 183    if (!isset($cache[$raw_id])) { $cache[$raw_id] = array(); }
 184    $cache[$raw_id][$rev] = $fn;
 185    return $fn;
 186  }
 187  
 188  /**
 189   * Returns the full path to the file for locking the page while editing.
 190   *
 191   * @author Ben Coburn <btcoburn@silicodon.net>
 192   */
 193  function wikiLockFN($id) {
 194    global $conf;
 195    return $conf['lockdir'].'/'.md5(cleanID($id)).'.lock';
 196  }
 197  
 198  
 199  /**
 200   * returns the full path to the meta file specified by ID and extension
 201   *
 202   * The filename is URL encoded to protect Unicode chars
 203   *
 204   * @author Steven Danz <steven-danz@kc.rr.com>
 205   */
 206  function metaFN($id,$ext){
 207    global $conf;
 208    $id = cleanID($id);
 209    $id = str_replace(':','/',$id);
 210    $fn = $conf['metadir'].'/'.utf8_encodeFN($id).$ext;
 211    return $fn;
 212  }
 213  
 214  /**
 215   * returns an array of full paths to all metafiles of a given ID
 216   *
 217   * @author Esther Brunner <esther@kaffeehaus.ch>
 218   */
 219  function metaFiles($id){
 220     $name   = noNS($id);
 221     $dir    = metaFN(getNS($id),'');
 222     $files  = array();
 223  
 224     $dh = @opendir($dir);
 225     if(!$dh) return $files;
 226     while(($file = readdir($dh)) !== false){
 227       if(strpos($file,$name.'.') === 0 && !is_dir($dir.$file))
 228         $files[] = $dir.$file;
 229     }
 230     closedir($dh);
 231  
 232     return $files;
 233  }
 234  
 235  /**
 236   * returns the full path to the mediafile specified by ID
 237   *
 238   * The filename is URL encoded to protect Unicode chars
 239   *
 240   * @author Andreas Gohr <andi@splitbrain.org>
 241   */
 242  function mediaFN($id){
 243    global $conf;
 244    $id = cleanID($id);
 245    $id = str_replace(':','/',$id);
 246      $fn = $conf['mediadir'].'/'.utf8_encodeFN($id);
 247    return $fn;
 248  }
 249  
 250  /**
 251   * Returns the full filepath to a localized textfile if local
 252   * version isn't found the english one is returned
 253   *
 254   * @author Andreas Gohr <andi@splitbrain.org>
 255   */
 256  function localeFN($id){
 257    global $conf;
 258    $file = DOKU_INC.'inc/lang/'.$conf['lang'].'/'.$id.'.txt';
 259    if(!@file_exists($file)){
 260      //fall back to english
 261      $file = DOKU_INC.'inc/lang/en/'.$id.'.txt';
 262    }
 263    return $file;
 264  }
 265  
 266  /**
 267   * Resolve relative paths in IDs
 268   *
 269   * Do not call directly use resolve_mediaid or resolve_pageid
 270   * instead
 271   *
 272   * Partyly based on a cleanPath function found at
 273   * http://www.php.net/manual/en/function.realpath.php#57016
 274   *
 275   * @author <bart at mediawave dot nl>
 276   */
 277  function resolve_id($ns,$id,$clean=true){
 278    // if the id starts with a dot we need to handle the
 279    // relative stuff
 280    if($id{0} == '.'){
 281      // normalize initial dots without a colon
 282      $id = preg_replace('/^(\.+)(?=[^:\.])/','\1:',$id);
 283      // prepend the current namespace
 284      $id = $ns.':'.$id;
 285  
 286      // cleanup relatives
 287      $result = array();
 288      $pathA  = explode(':', $id);
 289      if (!$pathA[0]) $result[] = '';
 290      foreach ($pathA AS $key => $dir) {
 291        if ($dir == '..') {
 292          if (end($result) == '..') {
 293            $result[] = '..';
 294          } elseif (!array_pop($result)) {
 295            $result[] = '..';
 296          }
 297        } elseif ($dir && $dir != '.') {
 298          $result[] = $dir;
 299        }
 300      }
 301      if (!end($pathA)) $result[] = '';
 302      $id = implode(':', $result);
 303    }elseif($ns !== false && strpos($id,':') === false){
 304      //if link contains no namespace. add current namespace (if any)
 305      $id = $ns.':'.$id;
 306    }
 307  
 308    if($clean) $id = cleanID($id);
 309    return $id;
 310  }
 311  
 312  /**
 313   * Returns a full media id
 314   *
 315   * @author Andreas Gohr <andi@splitbrain.org>
 316   */
 317  function resolve_mediaid($ns,&$page,&$exists){
 318    $page   = resolve_id($ns,$page);
 319    $file   = mediaFN($page);
 320    $exists = @file_exists($file);
 321  }
 322  
 323  /**
 324   * Returns a full page id
 325   *
 326   * @author Andreas Gohr <andi@splitbrain.org>
 327   */
 328  function resolve_pageid($ns,&$page,&$exists){
 329    global $conf;
 330    $exists = false;
 331  
 332    //keep hashlink if exists then clean both parts
 333    if (strpos($page,'#')) {
 334      list($page,$hash) = split('#',$page,2);
 335    } else {
 336      $hash = '';
 337    }
 338    $hash = cleanID($hash);
 339    $page = resolve_id($ns,$page,false); // resolve but don't clean, yet
 340  
 341    // get filename (calls clean itself)
 342    $file = wikiFN($page);
 343  
 344    // if ends with colon we have a namespace link
 345    if(substr($page,-1) == ':'){
 346      if(@file_exists(wikiFN($page.$conf['start']))){
 347        // start page inside namespace
 348        $page = $page.$conf['start'];
 349        $exists = true;
 350      }elseif(@file_exists(wikiFN($page.noNS(cleanID($page))))){
 351        // page named like the NS inside the NS
 352        $page = $page.noNS(cleanID($page));
 353        $exists = true;
 354      }elseif(@file_exists(wikiFN($page))){
 355        // page like namespace exists
 356        $page = $page;
 357        $exists = true;
 358      }else{
 359        // fall back to default
 360        $page = $page.$conf['start'];
 361      }
 362    }else{
 363      //check alternative plural/nonplural form
 364      if(!@file_exists($file)){
 365        if( $conf['autoplural'] ){
 366          if(substr($page,-1) == 's'){
 367            $try = substr($page,0,-1);
 368          }else{
 369            $try = $page.'s';
 370          }
 371          if(@file_exists(wikiFN($try))){
 372            $page   = $try;
 373            $exists = true;
 374          }
 375        }
 376      }else{
 377        $exists = true;
 378      }
 379    }
 380  
 381    // now make sure we have a clean page
 382    $page = cleanID($page);
 383  
 384    //add hash if any
 385    if(!empty($hash)) $page .= '#'.$hash;
 386  }
 387  
 388  /**
 389   * Returns the name of a cachefile from given data
 390   *
 391   * The needed directory is created by this function!
 392   *
 393   * @author Andreas Gohr <andi@splitbrain.org>
 394   *
 395   * @param string $data  This data is used to create a unique md5 name
 396   * @param string $ext   This is appended to the filename if given
 397   * @return string       The filename of the cachefile
 398   */
 399  function getCacheName($data,$ext=''){
 400    global $conf;
 401    $md5  = md5($data);
 402    $file = $conf['cachedir'].'/'.$md5{0}.'/'.$md5.$ext;
 403    io_makeFileDir($file);
 404    return $file;
 405  }
 406  
 407  /**
 408   * Checks a pageid against $conf['hidepages']
 409   *
 410   * @author Andreas Gohr <gohr@cosmocode.de>
 411   */
 412  function isHiddenPage($id){
 413    global $conf;
 414    if(empty($conf['hidepages'])) return false;
 415  
 416    if(preg_match('/'.$conf['hidepages'].'/ui',':'.$id)){
 417      return true;
 418    }
 419    return false;
 420  }
 421  
 422  /**
 423   * Reverse of isHiddenPage
 424   *
 425   * @author Andreas Gohr <gohr@cosmocode.de>
 426   */
 427  function isVisiblePage($id){
 428    return !isHiddenPage($id);
 429  }
 430  
 431  /**
 432   * Checks and sets HTTP headers for conditional HTTP requests
 433   *
 434   * @author   Simon Willison <swillison@gmail.com>
 435   * @link     http://simon.incutio.com/archive/2003/04/23/conditionalGet
 436   * @param    timestamp $timestamp lastmodified time of the cache file
 437   * @returns  void or void with previously header() commands executed
 438   */
 439  function http_conditionalRequest($timestamp){
 440    // A PHP implementation of conditional get, see
 441    //   http://fishbowl.pastiche.org/archives/001132.html
 442    $last_modified = substr(date('r', $timestamp), 0, -5).'GMT';
 443    $etag = '"'.md5($last_modified).'"';
 444    // Send the headers
 445    header("Last-Modified: $last_modified");
 446    header("ETag: $etag");
 447    // See if the client has provided the required headers
 448    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
 449      $if_modified_since = stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']);
 450    }else{
 451      $if_modified_since = false;
 452    }
 453  
 454    if (isset($_SERVER['HTTP_IF_NONE_MATCH'])){
 455      $if_none_match = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
 456    }else{
 457      $if_none_match = false;
 458    }
 459  
 460    if (!$if_modified_since && !$if_none_match){
 461      return;
 462    }
 463  
 464    // At least one of the headers is there - check them
 465    if ($if_none_match && $if_none_match != $etag) {
 466      return; // etag is there but doesn't match
 467    }
 468  
 469    if ($if_modified_since && $if_modified_since != $last_modified) {
 470      return; // if-modified-since is there but doesn't match
 471    }
 472  
 473    // Nothing has changed since their last request - serve a 304 and exit
 474    header('HTTP/1.0 304 Not Modified');
 475    exit;
 476  }
 477  
 478  //Setup VIM: ex: et ts=2 enc=utf-8 :


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7