Wikiwig PHP Cross Reference Collaborative Wikis

Source: /_wk/lib/Wiki.php - 1033 lines - 41529 bytes - Summary - Text - Print

   1  <?php
   2    if (!class_exists('Dir'))
   3      require_once dirname(__FILE__).'/filesystem/Dir.php';
   4    if (!class_exists('File'))
   5      require_once dirname(__FILE__).'/filesystem/File.php';
   6    if (!class_exists('Wiki_Locker'))
   7      require_once dirname(__FILE__).'/Wiki_Locker.php';
   8    if (!class_exists('Wiki_User'))
   9      require_once dirname(__FILE__).'/Wiki_User.php';
  10    if (!class_exists('Wiki_Strings'))
  11      require_once dirname(__FILE__).'/Wiki_Strings.php';
  12    if (!class_exists('Wiki_Parser'))
  13      require_once dirname(__FILE__).'/Wiki_Parser.php';
  14    if (!class_exists('Wiki_PageDir'))
  15      require_once dirname(__FILE__).'/Wiki_PageDir.php';
  16    if (!class_exists('Wiki_History'))
  17      require_once dirname(__FILE__).'/Wiki_History.php';
  18  
  19  
  20    @define('WK_DIR_RIGHTS',0755);
  21    @define('WK_FILE_RIGHTS',0755);
  22    @define('WK_TPL_BASIC_PAGE','wk_basic_page.tpl');
  23  
  24    /**

  25     * Classe Globale du Wiki

  26     * Elle définit une interface de méthodes appelées par les différentes pages de

  27     * WikiWig. Toutes les actions du Wiki sont définies dans cette classe.

  28     *

  29     */
  30    class Wiki {
  31      var $errors   = array();
  32  
  33      /**

  34       * Constructor PHP 4

  35       * Call the <code>__construct</code> method.

  36       * View <code>__construct</code> method for details.

  37       */
  38      function Wiki(){$this->__construct();}
  39      /**

  40       * Constructor PHP 5

  41       */
  42      function __construct(){}
  43  
  44      // Configuration

  45      ////////////////

  46      function getConfig($var_name=false) {
  47        // defined vars

  48        global $WK;
  49        if ((isset($WK)) && (isset($WK[$var_name]))) {
  50          return $WK[$var_name];
  51        } else if (isset($WK)) {
  52          if ($var_name == 'reserved_dirnames') {
  53            $reserved_dirnames = array(Wiki::getConfig('systemDir'),
  54                                       Wiki::getConfig('trashDir'),
  55                                       Wiki::getConfig('efm_images_dir'),
  56                                       Wiki::getConfig('efm_files_dir'),
  57                                       Wiki::getConfig('backupDir'));
  58            // adding user defined dirs to hide

  59            $reserved_dirnames = array_merge($reserved_dirnames, Wiki::getConfig('hiddenDirs'));
  60            // make a strtolower on each element, to prepare further testing

  61            $reserved_dirnames = array_map('strtolower',$reserved_dirnames);
  62            return $reserved_dirnames;
  63          }
  64        } else {
  65          return false;
  66        }
  67      } //getConfig

  68  
  69      function getConfigVars() {
  70        global $WK;
  71        if (isset($WK)) {
  72          $ar_res = $WK;
  73          $ar_res[] = Wiki::getConfig('reserved_dirnames');
  74          return $ar_res;
  75        } else {
  76          $ar_empty = array();
  77          return $ar_empty;
  78        }
  79      }
  80  
  81      // Listings Files & Folders

  82      ////////////////////////////

  83        /**

  84         *

  85         */
  86        function listPages($folder,$order_by='name',$order_way=0) {
  87          $wkPath = Wiki::getConfig('wkPath');
  88          $folder = trim($folder,'/');
  89          $reserved_dirnames = array(); // empty, cos we are just listing files

  90          $folder_full_path = $wkPath.$folder;
  91          $ar_tmp = Dir::listDir($folder_full_path,2,1,$reserved_dirnames,'html');
  92          if (empty($ar_tmp))
  93              return $ar_tmp;
  94  
  95          // Lock System Infos

  96          // updates the current locks

  97          Wiki_Locker::updateLocks();
  98          // get the current locks

  99          $ar_locked_pages = Wiki_Locker::getLocks();
 100  
 101          $ar_pages = array();
 102          $ar_multisort_index = array();
 103          $index_page = array();
 104          $index_key = 0;
 105          // make the array of pages

 106          // with infos from each file

 107          // index page 'index.html' is a special case, and must not be included in array pages before ordering

 108          // because it is always put on top of the list, so should be treated as special case

 109          foreach($ar_tmp as $file){
 110            $file_wiki_name = '/'.ltrim(str_replace($wkPath,'',$file),'/');
 111            $page_locked = isset($ar_locked_pages[$file_wiki_name]);
 112            $user = ($page_locked) ? $ar_locked_pages[$file_wiki_name]['pages_utilisateur'] : '';
 113            $page = array( 'name'   => basename($file),
 114                           'url'    => ltrim($file_wiki_name,'/'),
 115                           'encoded_url' => Wiki_Strings::url_encode(ltrim($file_wiki_name,'/')),
 116                           'wk_url' => $file_wiki_name,
 117                           'size'   => filesize($file),
 118                           'date'   => filemtime($file),
 119                           'locked' => $page_locked,
 120                           'user'   => $user
 121                          );
 122            // special case: be nice with index.html

 123            if ($page['name'] == 'index.html'){
 124              $index_page = $page;
 125            } else {
 126              $ar_pages[$index_key++] = $page;
 127              // prepare the multisort array

 128              $ar_multisort_index[] = $page[$order_by];
 129            }
 130          } // foreach

 131  
 132          // Multisort

 133          if (!empty($ar_pages)) { // could be empty if only the index page
 134            // verification of order options

 135            if ($order_way == 1)
 136              $order_way = SORT_DESC;
 137            else
 138              $order_way = SORT_ASC;
 139  
 140            $allowed_orders = array('name','size','date');
 141            if (empty($order_by) && !in_array($order_by,$allowed_orders))
 142              $order_by = 'name';
 143            // order the array

 144            array_multisort($ar_multisort_index,$order_way,$ar_pages);
 145          }
 146          // Add index page properties

 147          if (!empty($index_page)){
 148            array_unshift($ar_pages,$index_page); // add index to top of pages

 149          }
 150          return $ar_pages;
 151        } // listPages

 152  
 153        /**

 154         * function

 155         */
 156        function listAllFolders($hidden_path=false, $hidden_folders=false) {
 157          $ar_folders = Wiki::listSubFolders('/',$hidden_path);
 158          array_unshift($ar_folders,'/');
 159          if (is_array($hidden_folders)) {
 160            $ar_folders = array_diff($ar_folders,$hidden_folders);
 161          }
 162          return $ar_folders;
 163        }
 164        /**

 165         *

 166         */
 167        function listSubFolders($folder,$hidden_path=false) {
 168          $wkPath = Wiki::getConfig('wkPath');
 169          $folder = trim($folder,'/');
 170          if (empty($folder)) { // in the root, special system and hidden folders should not be included
 171            $reserved_dirnames = Wiki::getConfig('reserved_dirnames');
 172          } else {
 173            $reserved_dirnames = array();
 174          }
 175  
 176          $folder_full_path = $wkPath.$folder;
 177          // get the list

 178          $ar_tmp = Dir::listDir($folder_full_path,1,0,$reserved_dirnames);
 179          if (empty($ar_tmp))
 180              return $ar_tmp;
 181  
 182          $ar_folders = array();
 183          // clean folder names and extract hidden path

 184          foreach($ar_tmp as $folder){
 185            $clean_folder_name = str_replace($wkPath,'',$folder).'/';
 186            if (($hidden_path !== false) && (strpos($clean_folder_name,$hidden_path) === 0)) {
 187              continue;
 188            }
 189            $ar_folders[] = $clean_folder_name;
 190          }
 191          sort($ar_folders);
 192          return $ar_folders;
 193        } // listSubFolders

 194  
 195        function &getTplContent($tpl_content_file_name=false) {
 196          $content = '';
 197            if (!empty($tpl_content_file_name) && $tpl_content_file_name!==false){
 198              $tpl_content_file_path = Wiki::getConfig('wkPath').Wiki::getConfig('templatesDir').'/'.$tpl_content_file_name;
 199              $content = File::read($tpl_content_file_path);
 200            }
 201          return $content;
 202        }
 203  
 204        // Pages

 205        /////////////////////

 206        function createPage($path, $filename, $content, $title=false, $overwrite=false) {
 207          $err = array();
 208          if ($path!='' && $path!='/')
 209            $full_path = Wiki::getConfig('wkPath').trim($path,'/').'/';
 210          else
 211            $full_path = Wiki::getConfig('wkPath');
 212          $clean_filename = Wiki_Strings::transliterate($filename);
 213          $clean_filename = Dir::cleanName($clean_filename);
 214          $file_path = $full_path.$clean_filename.'.html';
 215  
 216          // verify conditions to create file

 217          if (!@is_dir($full_path)) // dir not exists
 218            $err[] = sprintf(WK_ERR_DIR_NOT_EXISTS,$path);
 219          elseif(!Dir::isWritable($full_path)) // dir not writable
 220            $err[] = sprintf(WK_ERR_DIR_NOT_WRITABLE,$path);
 221          elseif(@is_file($file_path) && $overwrite === false) // file already exists
 222            $err[] = sprintf(WK_ERR_FILE_EXISTS,$clean_filename);
 223          elseif(empty($clean_filename))
 224            $err[] = sprintf(WK_ERR_FILE_BADNAME,$clean_filename);
 225  
 226          if (!empty($err))
 227            return $err;
 228  
 229          $entry = Wiki_PageDir::findByPath($file_path);
 230          if ($entry == false) {
 231            // new page

 232            $entry = new Wiki_PageDir();
 233            $entry->set_path($file_path);
 234            $entry->set_active(true);
 235            $res = $entry->insert();
 236          } else {
 237            if ($entry->active()) {
 238              // ACK DB is screwed up. File exists in DB and not in dir!

 239              // QQQ say something better

 240              $err[] = sprintf(WK_ERR_FILE_BADNAME,$clean_filename);
 241              return $err;
 242            }
 243            // A deleted file coming back to life

 244            $entry->set_active(true);
 245            $res = $entry->update();
 246          }
 247          // Did DB action succeed?

 248          if ($res !== true) {
 249            $err[] = $res;
 250            return $err;
 251          }
 252          $seq =  $entry->seq();
 253          $salt = 'giwikiw';
 254          // Be able to detect corruption of the sequence id.

 255          $seq = $seq . ":" . md5($salt . md5($seq . $salt));
 256  
 257          $tpl_file = Wiki::getConfig('wkPath').Wiki::getConfig('templatesSystemDir').'/'.WK_TPL_BASIC_PAGE;
 258          $tpl_content = File::read($tpl_file);
 259          if ($title===false)
 260            $title = $clean_filename;
 261          if ($tpl_content !== false){ // no pb to read template file
 262  
 263            $tpl_content = str_replace('{head_title}',$title,$tpl_content);
 264            $tpl_content = str_replace('{content_title}',$title,$tpl_content);
 265            $systemDirHTTPPath = Wiki::getConfig('wkHTTPPath').Wiki::getConfig('systemDir').'/';
 266            $tpl_content = str_replace('{CSS_HTTP_PATH}',$systemDirHTTPPath.'wk_dyn_pages.php?css',$tpl_content);
 267            $tpl_content = str_replace('{JS_HTTP_PATH}',$systemDirHTTPPath.'wk_dyn_pages.php?js',$tpl_content);
 268            $tpl_content = str_replace('{MAP}',WK_LABEL_FOLDER_MAP,$tpl_content);
 269            $tpl_content = str_replace('{MAP_LINK}',$systemDirHTTPPath.'wk_liste.php',$tpl_content);
 270  
 271  
 272            $tpl_content = str_replace('{SEQUENCE_ID}', "SEQ($seq)", $tpl_content);
 273  
 274            $tpl_content = str_replace('{content}',$content,$tpl_content);
 275  
 276          } else {
 277            $err[] = sprintf(WK_ERR_READ_TPL_FILE,$tpl_file_name);
 278          }
 279          $res = File::write($file_path,$tpl_content,WK_FILE_RIGHTS);
 280          if ($res === true) {
 281            // record_entry_by_path($path = '', $action = '', $comment = '', $user = false)

 282            $res = Wiki_History::record_entry_by_seq($entry->seq(), "CREATED", "");
 283          }
 284          return $res;
 285        } // createPage

 286  
 287        function updatePage($page_wiki_path,$new_content, $comment='') {
 288          $page_full_path    = Wiki::getConfig('wkPath').ltrim($page_wiki_path,'/');
 289          $page_full_content = File::read($page_full_path);
 290          $err =array();
 291          if ($page_full_content===false) {
 292            $err[] = sprintf(WK_ERR_FILE_READ,$page_wiki_path);
 293            return $err;
 294          }
 295          $new_full_content = Wiki_Parser::replaceContent($page_full_content,$new_content);
 296          // Make a backup

 297          Wiki::backupPage($page_wiki_path, "[ UPDATED: " . $comment . "]");
 298  
 299          // Writes the file

 300          //$err[] = $page_full_path . "debug (lign 261, lib/wiki.php)";

 301          //return $err;

 302          // error_log("UPD path: $page_wiki_path");

 303          if (!File::write($page_full_path,$new_full_content,WK_FILE_RIGHTS)) {
 304            $err[] = sprintf(WK_ERR_FILE_WRITE,$page_wiki_path);
 305            return $err;
 306          }
 307          // $res = Wiki_History::record_entry_by_path($page_wiki_path, "UPDATED", $comment);

 308          // if ($res !== true) {

 309            // return $res;

 310          // }

 311          return true;
 312        } // updatePage

 313  
 314        function readPage($page_wiki_path) {
 315          $page_full_path    = Wiki::getConfig('wkPath').ltrim($page_wiki_path,'/');
 316          $page_full_content = File::read($page_full_path);
 317          $err =array();
 318          if ($page_full_content===false) {
 319            $err[] = sprintf(WK_ERR_FILE_READ,$page_wiki_path);
 320            return $err;
 321          }
 322          return Wiki_Parser::getContent($page_full_content);
 323        } // readPage

 324  
 325        function deletePage($page_wiki_path, $comment='') {
 326          $wiki_dir = dirname($page_wiki_path);
 327          if ($wiki_dir == '\\' || $wiki_dir=='.' ) $wiki_dir = '';
 328          $page_full_path = Wiki::getConfig('wkPath').ltrim($page_wiki_path,'/');
 329          // verify page exists

 330          if (!@is_file($page_full_path)) {
 331            $err[] = sprintf(WK_ERR_FILE_NOT_EXISTS,$page_wiki_path);
 332            return $err;
 333          }
 334  
 335          $entry = Wiki_PageDir::findByPath($page_full_path);
 336          if ($entry === false) {
 337            // Bad error message

 338            $err[] = sprintf(WK_ERR_FILE_NOT_EXISTS,$page_wiki_path);
 339            return $err;
 340          }
 341  
 342          //FIXME: no verification on locked pages are made !!!!!!!!!!!

 343          // a fix have been set in the interface, locked pages not selectable for deletion,

 344          // but a POST Request to the delete page by a user with bad intentions can force the

 345          // deletion

 346          ///

 347          // $trash_dir_wiki_path = Wiki::getConfig('trashDir').'/'.ltrim($wiki_dir,'/');

 348          // $trash_dir_full_path = Wiki::getConfig('wkPath').$trash_dir_wiki_path.'/';

 349          // $trash_page_full_path = $trash_dir_full_path.basename($page_wiki_path);

 350          $trash_dir_full_path = Wiki::getConfig('wkPath') . Wiki::getConfig('trashDir') . "/";
 351          $fn = $entry->seq() . "_" . time();
 352          $trash_page_full_path = $trash_dir_full_path . $fn;
 353          error_log("trash $trash_page_full_path $fn");
 354  
 355  
 356          // create tree of directories in the trash dir

 357          // Dir::mkdirs($trash_dir_full_path,WK_DIR_RIGHTS);

 358  
 359          // copy to trash

 360          // backup

 361          @copy($page_full_path,$trash_page_full_path);
 362          // deletes File

 363          if (!@unlink($page_full_path)){
 364            $err[] = sprintf(WK_ERR_FILE_DELETE,$page_wiki_path);
 365            return $err;
 366          }
 367          $entry->set_active(false);
 368          $res = $entry->update();
 369          if ($res !== true) {
 370            // Bad error message

 371            $err[] = sprintf(WK_ERR_FILE_DELETE,$page_wiki_path);
 372            return $err;
 373          }
 374          $res = Wiki_History::record_entry_by_seq($entry->seq(), "DELETED", $comment);
 375          return true;
 376        } // deletePage

 377  
 378        function restoreFile($seq=false, $time=0, $num=0) {
 379          $entry = Wiki_PageDir::findBySeq($seq);
 380          if (!is_object($entry) || !ctype_digit($time) || !ctype_digit($num)) {
 381            return WK_RESTORE_BAD1;
 382          }
 383          $wiki_path = $entry->path();
 384          $res = Wiki::lockPage($wiki_path);
 385          if ($res !== true) {
 386            return $res;
 387          }
 388          $fn = $entry->seq() . "_" . $num;
 389          $backup_full_path = Wiki::getConfig('wkPath') . Wiki::getConfig('backupDir') . "/" . $fn;
 390          // error_log("RESTORE $backup_full_path");

 391  
 392          $page_full_content = File::read($backup_full_path);
 393          $err =array();
 394          if ($page_full_content===false) {
 395            $err[] = sprintf(WK_ERR_FILE_READ,$backup_full_path);
 396            return $err;
 397          }
 398          $page_full_content =  Wiki_Parser::getContent($page_full_content);
 399          $res = Wiki::updatePage($wiki_path, $page_full_content, "RESTORE $fn");
 400          if (is_array($res)) {
 401            $res = implode("<br>", $res);
 402          }
 403          if ($res === true) {
 404            $res = Wiki::unlockPage($wiki_path);
 405          }
 406  
 407          return $res;
 408  
 409        }
 410  
 411        function undeleteFile($seq=false, $time=0) {
 412          $entry = Wiki_PageDir::findBySeq($seq);
 413          if (!is_object($entry) || $entry->active()) {
 414            return WK_UNDELETE_BAD1;
 415          }
 416          $page_full_path    = Wiki::getConfig('wkPath').ltrim($entry->path(),'/');
 417          // error_log("UNDEL $page_full_path");

 418  
 419          $trash_dir_full_path = Wiki::getConfig('wkPath') . Wiki::getConfig('trashDir') . "/";
 420          $fn = $entry->seq() . "_" . $time;
 421          $trash_page_full_path = $trash_dir_full_path . $fn;
 422          // error_log("UNDEL $trash_page_full_path");

 423  
 424          if (@is_file($trash_page_full_path)) {
 425            @copy($trash_page_full_path, $page_full_path);
 426            if (!@unlink($trash_page_full_path)){
 427              $err[] = sprintf(WK_ERR_FILE_DELETE, $trash_page_full_path);
 428              return $err;
 429            }
 430            $entry->set_active(true);
 431            $res = $entry->update();
 432            $res = Wiki_History::record_entry_by_seq($entry->seq(), "UNDELETE", "$fn");
 433            return $res;
 434          } else {
 435            return WK_UNDELETE_BAD2;
 436          }
 437        }
 438  
 439        function backupPage($page_wiki_path,$comment ='', $permissions=WK_FILE_RIGHTS) {
 440          $wiki_dir = dirname($page_wiki_path);
 441          if ($wiki_dir == '\\') $wiki_dir = '/';
 442          $page_full_path   = Wiki::getConfig('wkPath').ltrim($page_wiki_path,'/');
 443          $entry = Wiki_PageDir::findByPath($page_full_path);
 444          if (!is_object($entry)) {
 445            return WK_BACKUP_BAD1;
 446          }
 447          $num = $entry->backup_id();
 448          $num++;
 449          if ($num > Wiki::getConfig('nbBackups')) {
 450            $num = 1;
 451          }
 452          // Encode the file name

 453          $fn = $entry->seq() . "_" . $num;
 454          // $backup_dir_wiki_path = Wiki::getConfig('backupDir').'/'.ltrim($wiki_dir,'/');

 455          // $backup_dir_full_path = Wiki::getConfig('wkPath').$backup_dir_wiki_path.'/';

 456          $backup_full_path = Wiki::getConfig('wkPath') . Wiki::getConfig('backupDir') . '/' . $fn;
 457          // error_log("BK $backup_full_path");

 458  
 459          // random number to tag the backup file

 460          // $no_bk = rand(1,Wiki::getConfig('nbBackups'));

 461          // $default_ext = '.html';

 462          // $backup_filename = substr(basename($page_wiki_path),0,-strlen($default_ext)).'_'.$no_bk.$default_ext;

 463          // $backup_page_full_path = $backup_dir_full_path.$backup_filename;

 464  
 465          // error_log("bu path: $page_wiki_path");

 466          if ($comment != '') {
 467            $comment = "FILE: $fn " . $comment;
 468          } else {
 469            $comment = "FILE: $fn ";
 470          }
 471          $res = Wiki_History::record_entry_by_path($page_wiki_path, "BACKUP", $comment);
 472          $entry->set_backup_id($num);
 473          $res = $entry->update();
 474  
 475          // create tree of directories in the backup dir

 476          // Dir::mkdirs($backup_dir_full_path,WK_DIR_RIGHTS);

 477  
 478          // backup

 479          // error_log("copy $page_full_path,$backup_full_path");

 480          @copy($page_full_path,$backup_full_path);
 481          // set permissions

 482          @chmod($backup_page_full_path,$permissions);
 483          return true;
 484        } // backupPage

 485  
 486        function movePage($old, $new) {
 487          // $old, $new are within the wiki

 488          $res = Wiki::lockPage($old);
 489          if ($res !== true) {
 490            return $res;
 491          }
 492          $old_page_full_path    = Wiki::getConfig('wkPath').ltrim($old,'/');
 493          $new_page_full_path    = Wiki::getConfig('wkPath').ltrim($new,'/');
 494          // error_log("mv: $old_p =>  $new_p");

 495          // error_log("mv: $old_page_full_path $new_page_full_path");

 496          $full_content = File::read($old_page_full_path);
 497          if ($full_content !== false) {
 498            $entry = Wiki_PageDir::findByPath($old_page_full_path);
 499            if ($entry === false) {
 500              Wiki::unlockPage($old);
 501              // Bad error message

 502              $err = sprintf(WK_ERR_FILE_NOT_EXISTS,$old_page_full_path);
 503              return $err;
 504            }
 505            $old_p = $entry->path();
 506            if (!File::write($new_page_full_path, $full_content,WK_FILE_RIGHTS)) {
 507              Wiki::unlockPage($old);
 508              $err = sprintf(WK_ERR_FILE_WRITE,$page_wiki_path);
 509              return $err;
 510            }
 511            if (!@unlink($old_page_full_path)){
 512              Wiki::unlockPage($old);
 513              $err = sprintf(WK_ERR_FILE_DELETE, $old);
 514              return $err;
 515            }
 516            $entry->set_path($new_page_full_path);
 517            $new_p = $entry->path();
 518            $res = Wiki_History::record_entry_by_seq($entry->seq(), "MOVED", "mv $old_p $new_p");
 519            $res = $entry->update();
 520            Wiki::unlockPage($old);
 521            return true;
 522          } else {
 523              $err = sprintf(WK_ERR_FILE_NOT_EXISTS,$old_page_full_path);
 524              return $err;
 525          }
 526  
 527        }
 528  
 529        function lockPage($page_wiki_path) {
 530  
 531          // For guests we invent a random name for the length of the session

 532          $user = Wiki_User::currentUser();
 533          if ($user->is_guest()) {
 534            if (isset($_SESSION['nom'])) {
 535              $username = $_SESSION['nom'];
 536            } else {
 537              $username = Wiki_Strings::genPass();
 538              $_SESSION['nom'] = $username;
 539            }
 540          } else {
 541            $username = $user->user_name();
 542          }
 543  
 544          // Lock System Infos

 545          // updates the current locks (i.e. deletes expired locks)

 546          Wiki_Locker::updateLocks();
 547          // get the current locks

 548          $ar_locked_pages = Wiki_Locker::getLocks();
 549  
 550          // if the page is already locked, and the user is not the same than the locker of the page

 551          // return errors

 552  
 553          $try_to_lock = true;
 554          if (isset($ar_locked_pages[$page_wiki_path])) {
 555            $locker = $ar_locked_pages[$page_wiki_path]['pages_utilisateur'];
 556            $try_to_lock = $username == $locker;
 557          }
 558          if ($try_to_lock) {
 559            // try to lock/reLock the page

 560            return Wiki_Locker::lockPage($page_wiki_path, $username);
 561          } else {
 562            // If a guest has a lock on the page then the name is a random name (supposedly) not in the db

 563            $locking_user = Wiki_User::findByUserName($locker);
 564            $page=split('/',$_GET['page']);
 565            $now = time();
 566            $dateBase = $ar_locked_pages[$page_wiki_path]['pages_temps'] + 600;
 567            $sec = $dateBase - $now ;
 568            $mn = $sec /60;
 569            $tps =substr($mn , 0,1);
 570            $err[]  =<<<EOT
 571  <script language="JavaScript">
 572    function popupcentre( page,largeur,hauteur,options){
 573      var top=(screen.height-hauteur)/2;
 574      var left=(screen.width-largeur)/2;
 575      window.open(page,"","top="+top+",left="+left+",width="+largeur+",height="+hauteur+","+options);
 576    }
 577  
 578  </script>
 579  EOT;
 580            $back = '';
 581            if (isset($_SESSION['referer'])) {
 582              $back = str_replace("wk_edition.php?page=/", '', $_SESSION['referer']);
 583            }
 584            if ($back == '') {
 585              if (isset($_GET['page'])) {
 586                $back = $_GET['page'];
 587                // QQQ VERIFY

 588                $back = Wiki::getConfig('wkHTTPPath') .ltrim($back, "/");
 589              }
 590            }
 591            $msg = "<div id='header'><img src='" . Wiki::getConfig('wkHTTPPath') .
 592                     "_wk/images/edition.png'>  " .
 593                     WK_ERR_PAGE_ALREADY_EDITED_TITLE .
 594                     " &nbsp;&nbsp;<a href='{$back}'>" .  WK_LABEL_BACK ;
 595  
 596            // If either user is a guest there is no way to chat so forget about chat

 597            if (is_object($locking_user) && !$user->is_guest()) {
 598              $msg .= "</a>&nbsp;&nbsp;<a href=\"javascript:popupcentre('../_wk/wk_chat.php?a=form&name=" .
 599                        $locking_user->user_name() .
 600                        "&page=" .
 601                        $page[1] .
 602                        "&emetteur=" .
 603                        $user->user_name() .
 604                        "',500,300,'menubar=no,statusbar=no,scrollbars=no,toolbar=no,directories=no,location=no')\" id='imgLien'>" .
 605                        WK_CHAT_LIEN ;
 606            }
 607            $msg .= "</a></div>";
 608            $err[] = $msg;
 609  
 610            $err[] .= sprintf("<div id='err' > ".WK_ERR_PAGE_ALREADY_EDITED,Wiki::getConfig('wkHTTPPath').ltrim($page_wiki_path,'/'), $page_wiki_path);
 611            if (is_object($locking_user)) {
 612              $err[] .= WK_ERR_PAGE_ALREADY_EDITED_ONE . $locker . WK_ERR_PAGE_ALREADY_EDITED_2 .$tps . WK_ERR_PAGE_ALREADY_EDITED_3."</div>";
 613            } else{
 614              $err[] .=  $locker. WK_ERR_PAGE_ALREADY_EDITED_2 .$tps . WK_ERR_PAGE_ALREADY_EDITED_3."</div>";
 615            }
 616          return $err;
 617          }
 618        } //lockPage

 619  
 620        function unlockPage($page_wiki_path) {
 621          return Wiki_Locker::unlockPage($page_wiki_path);
 622        }
 623  
 624        // Templates

 625        //////////////////////////

 626        function getPageTemplates() {
 627          $tpl_dir_path = Wiki::getConfig('wkPath').Wiki::getConfig('templatesDir');
 628          $reserved_dirnames = array();
 629          $ar_tmp = Dir::listDir($tpl_dir_path,2,1,$reserved_dirnames,'html');
 630          for($i=0;$i<count($ar_tmp);$i++){
 631            $ar_tmp[$i] = basename($ar_tmp[$i]); // retrieve only the name of the file

 632          }
 633          return $ar_tmp;
 634        }
 635  
 636        // Parsing

 637        ////////////////////////////

 638        function parsePage($file_full_path) {
 639          // Page Full Content

 640          $file_full_content = File::read($file_full_path);
 641          $file_old_title = Wiki_Parser::getHeadTitle($file_full_content);
 642          $file_old_content = Wiki_Parser::getContent($file_full_content);
 643  
 644          // Update any old internal links

 645          // $foo = 'http://oreo/~steve/t1/wikiwig/';

 646          $reg = preg_replace('/http:..\w*/', '', Wiki::getConfig('wkHTTPPath'));
 647          $matches = ';<a href="' . $reg . ".*?>;";
 648          // echo $matches;

 649          // extract the internal links

 650          if (preg_match_all($matches, $file_old_content, $links)) {
 651            $links = $links[0];
 652            foreach($links as $l => $v) {
 653              // extract the filenames from the internal urls

 654              if (preg_match('/".*?html"/', $v, $url)) {
 655                $url = $url[0];
 656                $fn = "/" . str_replace('"', '', str_replace($reg, '', $url));
 657                $entry = Wiki_PageDir::findByPath($fn);
 658                if ($entry == false) {
 659                  // old page prior to PageDir DB

 660                  $entry = new Wiki_PageDir();
 661                  $entry->set_path($fn);
 662                  $entry->set_active(true);
 663                  $res = $entry->insert();
 664                  // Did DB action succeed?

 665                  if ($res !== true) {
 666                    $err[] = $res;
 667                    return $err;
 668                  }
 669                }
 670                $seq =  $entry->seq();
 671                $newurl = '"' . Wiki::getConfig('wkHTTPPath') . Wiki::getConfig('systemDir') . "/wk_lookup.php?seq=$seq" . '"';
 672                $file_old_content = str_replace($url, $newurl, $file_old_content);
 673              }
 674            }
 675          }
 676  
 677          //echo '<hr />'.$title.'<br/>';

 678          //echo $file_old_content.'<br/><hr />';

 679          //return true;

 680  
 681          $entry = Wiki_PageDir::findByPath($file_full_path);
 682          if (!is_object($entry)) {
 683            $entry = Wiki_PageDir::createEntry($file_full_path);
 684            if (!is_object($entry)) {
 685              $err[] = $entry;
 686              return $err;
 687            }
 688          }
 689          $seq =  $entry->seq();
 690          $salt = 'giwikiw';
 691          // Be able to detect corruption of the sequence id.

 692          $seq = $seq . ":" . md5($salt . md5($seq . $salt));
 693  
 694          // Template content

 695          $tpl_file = Wiki::getConfig('wkPath').Wiki::getConfig('templatesSystemDir').'/'.WK_TPL_BASIC_PAGE;
 696          $tpl_content = File::read($tpl_file);
 697  
 698          if ($tpl_content !== false){ // no pb to read template file
 699            $tpl_content = str_replace('{head_title}',$file_old_title,$tpl_content);
 700            $systemDirHTTPPath = Wiki::getConfig('wkHTTPPath').Wiki::getConfig('systemDir').'/';
 701            $tpl_content = str_replace('{CSS_HTTP_PATH}',$systemDirHTTPPath.Wiki::getConfig('css_wiki'),$tpl_content);
 702            $tpl_content = str_replace('{JS_HTTP_PATH}',$systemDirHTTPPath.'wk_dyn_pages.php?js',$tpl_content);
 703            $tpl_content = str_replace('{MAP}',WK_LABEL_FOLDER_MAP,$tpl_content);
 704            $tpl_content = str_replace('{MAP_LINK}',$systemDirHTTPPath.'wk_liste.php',$tpl_content);
 705  
 706            $tpl_content = str_replace('{SEQUENCE_ID}', "SEQ($seq)", $tpl_content);
 707  
 708            $tpl_content = Wiki_Parser::replaceContent($tpl_content,$file_old_content);
 709          } else {
 710            $err[] = sprintf(WK_ERR_READ_TPL_FILE,$tpl_file_name);
 711            return $err;
 712          }
 713          $res = File::write($file_full_path,$tpl_content,WK_FILE_RIGHTS);
 714          if ($res === true) {
 715            $res = Wiki_History::record_entry_by_seq($seq, "RECONSTRUCT", "");
 716          }
 717          return $res;
 718        } // parsePage

 719  
 720        function parseAllPages($dir='') {
 721          // list dirs

 722          $wkPath = Wiki::getConfig('wkPath');
 723          $dir = trim($dir,'/');
 724          $dir_full_path = $wkPath.$dir;
 725          $reserved_dirnames = Wiki::getConfig('reserved_dirnames');
 726  
 727          // get the list

 728          $files_list = Dir::listDir($dir_full_path,2,0,$reserved_dirnames,'html');
 729          $ar_results = array();
 730          if (!empty($files_list)) {
 731            foreach($files_list as $file_full_path) {
 732              $file_rel_path = str_replace($wkPath,'',$file_full_path);
 733              $dirname = dirname($file_rel_path);
 734              $filename = basename($file_rel_path);
 735  
 736              // Create the wk_local.php file if not exists (in case of an update from older versions of Wikiwig)

 737              $current_dir_full_path = dirname($file_full_path);
 738              /* // older version using wk_local.php files

 739              if (!@is_file($current_dir_full_path.'/wk_local.php')) {

 740                if ($current_dir_full_path.'/' == $wkPath) // special case : root dir

 741                  Wiki::setFolderProperties(dirname($file_full_path).'/',$wkPath);

 742                else

 743                  Wiki::setFolderProperties(dirname($file_full_path));

 744              } else {

 745                // override permission set to this file

 746                // coming from bug #1105140

 747                File::chmod($current_dir_full_path.'/wk_local.php',WK_FILE_RIGHTS);

 748              }

 749              */
 750              // rewrite the page

 751              $res_rewrite = Wiki::ParsePage($file_full_path);
 752              if ($res_rewrite) {
 753                //  echo 'OK '.$file_full_path.'<br/>';

 754                $ar_results[] = array(true,$file_rel_path);
 755              } else {
 756                //  echo 'NOK';

 757                $ar_results[] = array(false,$file_rel_path);
 758              }
 759            }
 760          }
 761          return $ar_results;
 762        } // parseAllPages

 763  
 764        // Folders

 765        /////////////////////

 766        /**

 767         * Creates a new folder in the wiki

 768         *

 769         */
 770        function createFolder($path='',$dirname) {
 771          $err = array();
 772          $full_path = Wiki::getConfig('wkPath').trim($path,'/').'/';
 773          $clean_dirname = Wiki_Strings::transliterate($dirname);
 774          $clean_dirname = Dir::cleanName($clean_dirname);
 775  
 776          $reserved_dirnames = Wiki::getConfig('reserved_dirnames');
 777  
 778          // verify conditions to create file

 779          if (!@is_dir($full_path)) // dir not exists
 780            $err[] = sprintf(WK_ERR_DIR_PARENT_NOT_EXISTS,$path);
 781          elseif(!Dir::isWritable($full_path)) // dir not writable
 782            $err[] = sprintf(WK_ERR_DIR_PARENT_NOT_WRITABLE);
 783          elseif(in_array(strtolower($clean_dirname),$reserved_dirnames)) // reserved name
 784            $err[] = sprintf(WK_ERR_DIR_BADNAME,$clean_dirname);
 785          // empty clean name

 786          elseif(empty($clean_dirname))
 787            $err[] = sprintf(WK_ERR_DIR_BADNAME,$clean_dirname);
 788          elseif(@is_dir($full_path.$clean_dirname)) // dir already exists
 789            $err[] = sprintf(WK_ERR_DIR_EXISTS,$clean_dirname);
 790  
 791          // there is error

 792          if (!empty($err)) {
 793            return $err;
 794          }
 795          // Create the directory

 796          if (!@mkdir($full_path.$clean_dirname,WK_DIR_RIGHTS)) {
 797            $err[] =  sprintf(WK_ERR_DIR_MAKE,$clean_dirname);
 798            return $err;
 799          }
 800  
 801          // create index file

 802          //....

 803          $err = Wiki::createPage($path.$clean_dirname,
 804                                  'index',
 805                                  '', // No content
 806                                  $clean_dirname);
 807          // there is error

 808          if (is_array($err)) {
 809            return $err;
 810          } else
 811              $err = array(); // reinit err

 812  
 813          /* // older version using wk_local.php files

 814          if (!Wiki::setFolderProperties($full_path.$clean_dirname)) {

 815            $err[] = sprintf(WK_ERR_DIR_MAKE,$clean_dirname);

 816          }

 817          */
 818          // there is error

 819          if (!empty($err)) {
 820            return $err;
 821          }
 822  
 823          return $clean_dirname;
 824        } // createFolder

 825  
 826        /**

 827         * set to a folder the necessary properties files

 828         *

 829         *

 830         */
 831        function setFolderProperties($dir_full_path='',$wkPath=false) {
 832          if ($wkPath === false)
 833            $dir_rel_path = str_replace(Wiki::getConfig('wkPath'),'',$dir_full_path);
 834          else
 835            $dir_rel_path = str_replace($wkPath,'',$dir_full_path);
 836  
 837            $clean_path = trim($dir_rel_path,'/');
 838          if (!empty($clean_path))
 839            $nb_dirs = count(explode('/',$clean_path));
 840          else
 841            $nb_dirs = 0;
 842  
 843          $back_path = str_repeat('../',$nb_dirs);
 844          //echo 'Create Properties File of '.$dir_full_path.' Back_to_root='.$back_path.'<br />';

 845          // create local properties file

 846          // defines directory properties

 847          $props_file = <<<CONTENT
 848  <?php
 849  \$back_to_root = '$back_path';
 850  @include_once \$back_to_root.'_wk/wk_dyn_pages.php';
 851  ?>
 852  CONTENT;
 853          return File::write($dir_full_path.'/wk_local.php',$props_file,WK_FILE_RIGHTS);
 854        } // setFolderProperties

 855  
 856        /**

 857         * returns the parent folder in the wiki tree

 858         */
 859        function getParentFolder($folder) {
 860          if ($folder == '' ||  $folder == '/') // root folder
 861            return false;
 862          $parent_folder = dirname($folder);
 863          if ($parent_folder == '' || $parent_folder == '.')
 864            return '/';
 865          else
 866            return $parent_folder;
 867          $wkPath = Wiki::getConfig('wkPath');
 868          $folder_full_path = $wkPath.trim($folder,'/');
 869          if ($folder_full_path == $wkPath) // root folder
 870            return false;
 871  
 872          $folder_elems = explode('/',trim($folder,'/'));
 873          array_shift($folder_elems);
 874          if (empty($folder_elems))
 875            return '/';
 876          else
 877            return implode('/',$folder_elems);
 878        } // getParentFolder

 879  
 880        /**

 881         * Deletes a folder of the wiki

 882         *

 883         * @param string $wiki_dir fodler to move

 884         * @return mixed a boolean or an array of errors.

 885         */
 886        function deleteFolder($wiki_dir=false) {
 887          return Wiki::moveFolder($wiki_dir); // call with no target => delete

 888        }
 889  
 890        /**

 891         * Moves a folder of the wiki to another wiki folder

 892         * used by the trash process to delete folders. The inner system is to move

 893         * folder needed to delete to the trash folder, so similar to a move in the wiki tree.

 894         *

 895         * @param string $wiki_dir fodler to move

 896         * @param string $target_folder destination to where move the folder. If not set, will be moved to the trash dir. Equivalent to a delete call.

 897         * @return mixed a boolean or an array of errors.

 898         */
 899        function moveFolder($wiki_dir, $target_folder=false) {
 900          $err = array();
 901          if ($wiki_dir == '\\' || $wiki_dir=='.' || $wiki_dir == '/' || empty($wiki_dir) || $wiki_dir===false)
 902            $wiki_dir = '/';
 903          else
 904            $wiki_dir = '/'.trim($wiki_dir,'/').'/';
 905  
 906          $dir_full_path = Wiki::getConfig('wkPath').ltrim($wiki_dir,'/');
 907  
 908          $folder = trim($wiki_dir,'/');
 909          if (empty($folder)) { // in the root, special system and hidden folders should not be included
 910            $reserved_dirnames = Wiki::getConfig('reserved_dirnames');
 911          } else {
 912            $reserved_dirnames = Wiki::getConfig('hiddenDirs');
 913          }
 914  
 915          // get the list

 916          // error_log("listing: $dir_full_path");

 917  
 918          //echo 'start moving '.$dir_full_path;

 919  
 920          // check dir is not root folder

 921          if ($dir_full_path == Wiki::getConfig('wkPath')) { // root folder
 922            if ($target_folder===false)
 923              $err[] = sprintf(WK_ERR_DIR_DELETE_ROOT);
 924            else
 925              $err[] = sprintf(WK_ERR_DIR_MOVE_ROOT);
 926            return $err;
 927          }
 928  
 929          // checks dir exists

 930          if (!@is_dir($dir_full_path)) {
 931            $err[] = sprintf(WK_ERR_DIR_NOT_EXISTS,$wiki_dir);
 932            return $err;
 933          }
 934  
 935          // Check that no page is currently locked

 936          // Lock System Infos

 937          // updates the current locks

 938          Wiki_Locker::updateLocks();
 939          // get the current locks

 940          $ar_locked_pages = Wiki_Locker::getLocks();
 941          $locked_page_in_dir = false;
 942          foreach($ar_locked_pages as $k => $v) {
 943            if (substr($k,0,strlen($wiki_dir)) == $wiki_dir )
 944              $locked_page_in_dir = true;
 945          }
 946  
 947          if ($locked_page_in_dir) {
 948            if ($target_folder===false)
 949              $err[] = sprintf(WK_ERR_DIR_DELETE_LOCKS,$wiki_dir);
 950            else
 951            $err[] = sprintf(WK_ERR_DIR_MOVE_LOCKS,$wiki_dir);
 952            return $err;
 953          }
 954  
 955          //FIXME: no verification on locked pages are made !!!!!!!!!!!

 956          // a fix have been set in the interface, locked pages not selectable for deletion,

 957          // but a POST Request to the delete page by a user with bad intentions can force the

 958          // deletion

 959          ///

 960          if ($target_folder === false) { // no target => to trash
 961            //echo 'go to trash ';

 962            $trash_dir_wiki_path = Wiki::getConfig('trashDir').'/'.ltrim($wiki_dir,'/');
 963            $trash_dir_full_path = Wiki::getConfig('wkPath').rtrim($trash_dir_wiki_path,'/').'/';
 964            $target_full_path = $trash_dir_full_path;
 965            // create tree of directories in the trash dir

 966            Dir::mkdirs($trash_dir_full_path,WK_DIR_RIGHTS);
 967          } else {
 968            //echo 'move to  '.$target_folder;

 969            $target_full_path = Wiki::getConfig('wkPath').ltrim($target_folder,'/');
 970            // checks dir exists

 971            if (!@is_dir($target_full_path)) {
 972              $err[] = sprintf(WK_ERR_DIR_NOT_EXISTS,$target_dir);
 973              return $err;
 974            }
 975            // append the name of the folder to move

 976            $target_full_path.= basename($dir_full_path).'/';
 977            Dir::mkdirs($target_full_path,WK_DIR_RIGHTS);
 978          }
 979  
 980          //echo 'copy '.$dir_full_path.' vers '.$target_full_path.'<br />';

 981  
 982          // copy to target

 983          // backup

 984          if (Dir::copy($dir_full_path,$target_full_path)) {
 985            // $dir_full_path = Wiki::getConfig('wkPath').ltrim($wiki_dir,'/');

 986            $ar_tmp = Dir::listDir($dir_full_path, 2, 0, $reserved_dirnames, 'html');
 987            foreach ($ar_tmp as $value) {
 988              // $fn = str_replace(".html", '', str_replace(Wiki::getConfig('wkPath'), "/", $value));

 989              $entry = Wiki_PageDir::findByPath($value);
 990              if (is_object($entry)) {
 991                if ($target_folder === false) {
 992                  $entry->set_active(false);
 993                  $res = Wiki_History::record_entry_by_seq($entry->seq(), "DELETED", "Folder $folder deleted");
 994                } else {
 995                  $newfn = str_replace($dir_full_path, $target_full_path, $value);
 996                  // $newfn = str_replace(".html", '', str_replace(Wiki::getConfig('wkPath'), "/", $newfn));

 997                  $oldfn = $entry->path();
 998                  $entry->set_path($newfn);
 999                  $newfn = $entry->path();
1000                  // error_log("Rename: $fn -> $newfn");

1001                  $res = Wiki_History::record_entry_by_seq($entry->seq(), "MOVED", "mv $oldfn $newfn; Folder $folder renamed");
1002                }
1003                $res = $entry->update();
1004                if ($res !== true) {
1005                  $err[] = $res;
1006                }
1007              } else {
1008                // QQQ NEED BETTER ERROR msg

1009                $err[] = sprintf(WK_ERR_DIR_NOT_EXISTS,$fn);
1010              }
1011            }
1012  
1013            // delete from source

1014            $res = Dir::rmdir($dir_full_path);
1015          } else
1016            $res = false;
1017          return $res;
1018        } // moveFolder

1019  
1020    } // class Wiki

1021  
1022  // Standalone testing

1023  /*

1024  $WK = array();

1025  $WK['systemDir'] = '_wk';

1026  $WK['trashDir']  = '_wk_trash';

1027  $WK['uploadDir'] = '_wk_upload';

1028  $WK['backupDir'] = '_wk_backup';

1029  $WK['wkPath'] = 'C:/Julien/__projets__/___wikiwig___/__work__/wikiwig/wikiwig/';

1030  echo '<h1>Fichiers de ce répertoire</h1><pre>'.print_r(Wiki::listPages('/','date'),true).'</pre>';

1031  echo '<h1>Sous-Répertoires</h1><pre>'.print_r(Wiki::listSubFolders('/'),true).'</pre>';

1032  */
1033  ?>

title

Description

title

Description

title

Description

title

title

Body