ActionApps PHP Cross Reference Groupware Applications

Source: /include/files.class.php3 - 1561 lines - 47191 bytes - Summary - Text - Print

Description: File Utilities.

   1  <?php
   2  /**
   3   *
   4   * File Utilities.
   5   *
   6   * PHP versions 4 and 5
   7   *
   8   * LICENSE: This program is free software; you can redistribute it and/or modify
   9   * it under the terms of the GNU General Public License as published by
  10   * the Free Software Foundation; either version 2 of the License, or
  11   * (at your option) any later version.
  12   *
  13   * This program is distributed in the hope that it will be useful,
  14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16   * GNU General Public License for more details.
  17   *
  18   * You should have received a copy of the GNU General Public License
  19   * along with this program (LICENSE); if not, write to the Free Software
  20   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21   *
  22   * @version   $Id: files.class.php3 2748 2008-11-28 07:48:47Z honzam $
  23   * @author    Honza Malik <honza.malik@ecn.cz>
  24   * @license   http://opensource.org/licenses/gpl-license.php GNU Public License
  25   * @copyright Copyright (c) 2002-3 Association for Progressive Communications
  26   * @link      http://www.apc.org/ APC
  27   *
  28  */
  29  
  30  
  31  
  32  define('FILE_ERROR_NO_SOURCE',        100);
  33  define('FILE_ERROR_COPY_FAILED',      101);
  34  define('FILE_ERROR_DST_DIR_FAILED',   102);
  35  define('FILE_ERROR_NOT_UPLOADED',     104);
  36  define('FILE_ERROR_TYPE_NOT_ALLOWED', 105); // type of uploaded file not allowed
  37  define('FILE_ERROR_DIR_CREATE',       106); // can't create directory for image uploads
  38  define('FILE_ERROR_CHMOD',            107);
  39  define('FILE_ERROR_WRITE',            108);
  40  define('FILE_ERROR_NO_DESTINATION',   109);
  41  define('FILE_ERROR_READ',             110);
  42  define('FILE_COPY_OK',                199);
  43  
  44  
  45  class Files {
  46      /** lastErr function
  47       *  Method returns or sets last file error
  48       *  The trick for static class variables is used
  49       * @param $err_id
  50       * @param $err_msg
  51       * @param $getmsg
  52       */
  53      function lastErr($err_id = null, $err_msg = null, $getmsg = false) {
  54          static $lastErr;
  55          static $lastErrMsg;
  56          if (!is_null($err_id)) {
  57              $lastErr    = $err_id;
  58              $lastErrMsg = $err_msg;
  59          }
  60          return $getmsg ? $lastErrMsg : $lastErr;
  61      }
  62  
  63      /** lastErrMsg function
  64       *  Return last error message - it is grabbed from static variable
  65       *  of lastErr() method
  66       */
  67      function lastErrMsg() {
  68          return Files::lastErr(null, null, true);
  69      }
  70  
  71      /** destinationDir function
  72       *  Prepares slice directories for uploaded file and returns destination
  73       *  dir name
  74       * @param $slice
  75       */
  76      function destinationDir(&$slice) {
  77          $upload = $slice->getUploadBase();
  78          return Files::_destinationDirCreate($upload['path'], $upload['perms']);
  79      }
  80  
  81      /** aadestinationDir
  82       *  Prepares global AA directory for uploaded file and returns destination
  83       *  dir name
  84       */
  85      function aadestinationDir() {
  86          return Files::_destinationDirCreate(IMG_UPLOAD_PATH. AA_ID, (int)IMG_UPLOAD_DIR_MODE);
  87      }
  88  
  89      /** _destinationDirCreate function
  90       *  Prepares directory for uploaded file and returns destination dir name
  91       * @param $path
  92       * @param $perms
  93       */
  94      function _destinationDirCreate($path, $perms) {
  95          if (!$path OR !is_dir($path)) {
  96              if (!Files::CreateFolder($path, $perms)) {
  97                  Files::lastErr(FILE_ERROR_DIR_CREATE, _m("Can't create directory for image uploads"));  // set error code
  98                  return false;
  99              }
 100          }
 101          return $path;
 102      }
 103  
 104      /** genereateUnusedFilename function
 105       *  checks, if the file is not exist and in case it exist, it finds similar
 106       *  file name which do not exists. If modificator specified, then it is
 107       *  added to fileneme (like '_thumb')
 108       * @param $file_name
 109       * @param $modificator
 110       */
 111      function generateUnusedFilename($file_name, $modificator='') {
 112          $path_parts = pathinfo($file_name);
 113  
 114          // we have to process dot (extension do not contain it)
 115          // we must think about the files as 'test' or '.test' as well
 116          if ( strpos($path_parts['basename'], '.') === false ) {
 117              $extension = '';
 118              $base      = $path_parts['basename'] .$modificator;
 119          } else {
 120              $extension = '.'. $path_parts['extension'];
 121              $base = substr($path_parts['basename'],0,-strlen($extension)).$modificator;
 122          }
 123          $add = '';
 124          $i   = 0;
 125          while (file_exists($dest_file = Files::makeFile($path_parts['dirname'], "$base$add$extension"))) {
 126              $add = '_'. (++$i);
 127          }
 128          return $dest_file;
 129      }
 130  
 131      /** getUploadedFile function
 132       *  Returns all content of the uploaded file as the string.
 133       *  The file is deleted after read
 134       *  @param string $filevarname - name of form variable, where the file is stored
 135       */
 136      function getUploadedFile($filevarname) {
 137          $file_name  = Files::getTmpFilename('tmp');
 138  
 139          // upload file - todo: error is not returned, if not exist
 140  
 141          if (($dest_file = Files::uploadFile($filevarname, Files::aaDestinationDir(), '', 'overwrite', $file_name)) === false) {
 142              return false;  // error code is already set from Files::uploadFile()
 143          }
 144  
 145          if (($text = file_get_contents($dest_file)) === false) {
 146              Files::lastErr(FILE_ERROR_READ, _m("Can't read the file %1", array($dest_file)));  // set error code
 147              return false;
 148          }
 149  
 150          // delete files older than one week in the img_upload directory
 151          Files::deleteTmpFiles('tmp');
 152  
 153          return $text;
 154      }
 155  
 156      /** uploadFile function
 157       *  Uploads file to slice's directory
 158       *  @param $filevarname - name of form variable containing the uploaded data
 159       *                        (like "upfile")
 160       *  @param $dest_dir
 161       *  @param $type        - allowed file types (like 'image/jpeg', 'image/*')
 162       *  @param $replacemethod - how to handle conflicts with existing file
 163       *                            'new'       - stored as new (unused) filename
 164       *                            'overwrite' - the old file is overwriten
 165       *                            'backup'    - old file is backuped to new
 166       *                                          (unused) filename
 167       * @param $filename     - the name of file as you want to store it (if you
 168       *                        do not want to use original name)
 169       */
 170      function uploadFile($filevarname, $dest_dir, $type='', $replacemethod='new', $filename=null) {
 171          $up_file = $_FILES[$filevarname];
 172  
 173          $dest_file = Files::makeFile($dest_dir, Files::escape($filename ? $filename : basename($up_file['name'])));
 174          if ($dest_file === false) {
 175              Files::lastErr(FILE_ERROR_NO_DESTINATION, _m('No destination file specified'));  // set error code
 176              return false;
 177          }
 178  
 179          // look if the uploaded file exists
 180          if (!is_uploaded_file($up_file['tmp_name'])) {
 181              Files::lastErr(FILE_ERROR_NOT_UPLOADED);  // set error code
 182              return false;
 183          }
 184  
 185          // look if type of file is allowed
 186          $file_type = (substr($type,-1)=='*') ? substr($type,0,strpos($type,'/')) : $type;
 187  
 188          if ((@strpos($up_file['type'],$file_type)===false) AND ($type!="")) {
 189              Files::lastErr(FILE_ERROR_TYPE_NOT_ALLOWED, _m('type of uploaded file not allowed'));  // set error code
 190              return false;
 191          }
 192  
 193          switch ($replacemethod) {
 194              case 'overwrite':
 195                  // nothing to do - file is overwriten, if already exists
 196                  break;
 197              case 'backup':
 198                  if (Files::backupFile($dest_file) === false) {
 199                      return false;
 200                  }
 201                  break; // current file will be overwritten
 202              case 'new':
 203              default:
 204                  // find new name for the file, if the file already exists
 205                  $dest_file = Files::generateUnusedFilename($dest_file);
 206          }  // else - mode 'overwrite' - file is overwritten
 207  
 208          // copy the file from the temp directory to the upload directory, and test for success
 209          // (if the file already exists, move_uploaded_file will overwrite it!)
 210          if (!move_uploaded_file($up_file['tmp_name'], $dest_file)) {
 211              Files::lastErr(FILE_ERROR_TYPE_NOT_ALLOWED, _m("Can't move image  %1 to %2", array($up_file['tmp_name'], $dest_file)));  // set error code
 212              return false;
 213          }
 214  
 215          // now change permissions (if we have to)
 216          $perms = (int)IMG_UPLOAD_FILE_MODE;
 217          if ($perms AND !chmod($dest_file, $perms)) {
 218              Files::lastErr(FILE_ERROR_CHMOD, _m("Can't change permissions on uploaded file: %1 - %2. See IMG_UPLOAD_FILE_MODE in your config.php3", $dest_file, (int)IMG_UPLOAD_FILE_MODE));  // set error code
 219              return false;
 220          }
 221  
 222          return $dest_file;
 223      }
 224  
 225      /** createFileFromString function
 226       *  Creates or rewrites file in slice's directory and stores there the $text
 227       * @param $text
 228       * @param $dest_dir
 229       * @param $filename
 230       */
 231      function createFileFromString(&$text, $dest_dir, $filename) {
 232          $dest_file = Files::makeFile($dest_dir, Files::escape($filename));
 233          if ($dest_file === false) {
 234              // lastErr is already set from destinationFile;
 235              return false;
 236          }
 237  
 238          if (!$handle = fopen($dest_file, 'w')) {
 239              Files::lastErr(FILE_ERROR_WRITE, _m("Can't open file for writing: %1", $dest_file));  // set error code
 240              return false;
 241          }
 242  
 243          // Write $somecontent to our opened file.
 244          if (fwrite($handle, $text) === false) {
 245              Files::lastErr(FILE_ERROR_WRITE, _m("Can't write to file: %1", $dest_file));  // set error code
 246              return false;
 247          }
 248          fclose($handle);
 249  
 250          return $dest_file;
 251      }
 252      /** getTmpFilename function
 253       * @param $ident
 254       */
 255      function getTmpFilename($ident) {
 256          return $ident . "_" . md5(uniqid(rand(),1))  . "_" . date("mdY");
 257      }
 258  
 259      /** deleteTmpFiles function
 260       *  Delete all files with the format : {ident}_{hash20}_mmddyyyy older than
 261       *  7 days (used as temporary upload files)
 262       * @param $ident
 263       * @param $slice
 264       */
 265      function deleteTmpFiles($ident, $slice=null) {
 266          if ( !$slice ) {
 267              $upload_dir = IMG_UPLOAD_PATH. AA_ID;
 268          } else {
 269              $dir = $slice->getUploadBase();
 270              $upload_dir = $dir['path'];
 271          }
 272          if ($handle = opendir($upload_dir)) {
 273              while (false !== ($file = readdir($handle))) {
 274                  if (strlen($ident)+42 != strlen($file) || (substr($file,0,strlen($file)-42) != $ident)) {
 275                      continue;
 276                  }
 277                  $date=mktime(0,0,0,date("m"),date("d")-7,date("Y")) ;
 278                  $filedate = mktime (0,0,0,substr($file,-8,2) ,substr($file,-6,2),substr($file,-4,4));
 279                  $fileName = Files::makeFile($upload_dir, $file);
 280                  if ($filedate < $date) {
 281                      if (Files::delFile($fileName)) {
 282                          AA_Log::write("FILE IMP.",_m("Ok : file deleted "). $fileName);
 283                      } else {
 284                          AA_Log::write("FILE IMP.",_m("Error: Cannot delete file"). $fileName);
 285                      }
 286                  }
 287              }
 288              closedir($handle);
 289          } else {
 290              AA_Log::write("FILE IMP:",_m("Error: Invalid directory") .$upload_dir);
 291          }
 292      }
 293  
 294  
 295      /** backupFile function
 296       *  Create backup copy of the file
 297       *  @param $source
 298       *  @return whole filename of the backup file (or empty string, if
 299       *           the source file do not exists; returns false if backup fails
 300       */
 301      function backupFile($source) {
 302          if (!is_file($source)) {
 303              return "";
 304          }
 305  
 306          $destination = Files::generateUnusedFilename($source);
 307          if (copy($source, $destination)) {
 308              if (is_file($destination)) {
 309                  return $destination;
 310              }
 311          }
 312  
 313          Files::lastErr(FILE_ERROR_COPY_FAILED, _m('can\'t create backup of the file'));  // set error code
 314          return false;
 315      }
 316  
 317  
 318  
 319      /** copyFile function
 320       * Copy a file from source to destination. If unique == true, then if
 321       * the destination exists, it will be renamed by appending an increamenting
 322       * counting number.
 323       * @param string $source where the file is from, full path to the files required
 324       * @param string $destination_file name of the new file, just the filename
 325       * @param string $destination_dir where the files, just the destination dir,
 326       *                  e.g., /www/html/gallery/
 327       * @param boolean $unique create unique destination file if true.
 328       * @return string the new copied filename, else error if anything goes bad.
 329       */
 330      function copyFile($source, $destination_dir, $destination_file, $unique=true) {
 331          if (!(file_exists($source) && is_file($source))) {
 332              return FILE_ERROR_NO_SOURCE;
 333          }
 334  
 335          $destination_dir = Files::fixPath($destination_dir);
 336  
 337          if (!is_dir($destination_dir)) {
 338              return FILE_ERROR_DST_DIR_FAILED;
 339          }
 340  
 341          $destination = Files::makeFile($destination_dir, Files::escape($destination_file));
 342  
 343          if ($unique) {
 344              $destination = Files::generateUnusedFilename($destination);
 345          }
 346  
 347          if (!copy($source, $destination)) {
 348              return FILE_ERROR_COPY_FAILED;
 349          }
 350  
 351          //verify that it copied, new file must exists
 352          return is_file($destination) ? basename($destination) : FILE_ERROR_COPY_FAILED;
 353      }
 354  
 355  
 356      /** createFolder function
 357       * Create a new folder.
 358       * @param string $newFolder specifiy the full path of the new folder.
 359       * @param $perms
 360       * @return boolean true if the new folder is created, false otherwise.
 361       */
 362      function createFolder($newFolder, $perms=0777) {
 363          mkdir($newFolder, $perms);
 364          return chmod($newFolder, $perms);
 365      }
 366  
 367  
 368      /** escape function
 369       * Escape the filenames, any non-word characters will be
 370       * replaced by an underscore.
 371       * @param string $filename the orginal filename
 372       * @return string the escaped safe filename
 373       */
 374      function escape($filename) {
 375          return preg_replace('/[^\w\._]/', '_', $filename);
 376      }
 377  
 378      /** delFile function
 379       * Delete a file.
 380       * @param string $file file to be deleted
 381       * @return boolean true if deleted, false otherwise.
 382       */
 383      function delFile($file) {
 384          return @is_file($file) ? @unlink($file) : false;
 385      }
 386  
 387      /** delFolder function
 388       * Delete folder(s), can delete recursively.
 389       * @param string $folder the folder to be deleted.
 390       * @param boolean $recursive if true, all files and sub-directories
 391       * are delete. If false, tries to delete the folder, can throw
 392       * error if the directory is not empty.
 393       * @return boolean true if deleted.
 394       */
 395      function delFolder($folder, $recursive=false) {
 396          $deleted = true;
 397          if ($recursive) {
 398              $d = dir($folder);
 399              while (false !== ($entry = $d->read()))    {
 400                  if ($entry != '.' && $entry != '..') {
 401                      $obj = Files::fixPath($folder).$entry;
 402                      if (is_file($obj)) {
 403                          $deleted &= Files::delFile($obj);
 404                      } elseif (is_dir($obj))    {
 405                          $deleted &= Files::delFolder($obj, $recursive);
 406                      }
 407                  }
 408              }
 409              $d->close();
 410          }
 411  
 412          $deleted &= (is_dir($folder) ? rmdir($folder) : false);
 413  
 414          return $deleted;
 415      }
 416  
 417      /** fixPath function
 418       * Append a / to the path if required.
 419       * @param string $path the path
 420       * @return string path with trailing /
 421       */
 422      function fixPath($path) {
 423          //append a slash to the path if it doesn't exists.
 424          if (!(substr($path,-1) == '/')) {
 425              $path .= '/';
 426          }
 427          return $path;
 428      }
 429  
 430      /** makePath function
 431       * Concat two paths together. Basically $pathA+$pathB
 432       * @param string $pathA path one
 433       * @param string $pathB path two
 434       * @return string a trailing slash combinded path.
 435       */
 436      function makePath($pathA, $pathB) {
 437          $pathA = Files::fixPath($pathA);
 438          if (substr($pathB,0,1)=='/') {
 439              $pathB = substr($pathB,1);
 440          }
 441          return Files::fixPath($pathA.$pathB);
 442      }
 443  
 444      /** makeFile function
 445       * Similar to makePath, but the second parameter
 446       * is not only a path, it may contain say a file ending.
 447       * @param string $pathA the leading path
 448       * @param string $pathB the ending path with file
 449       * @return string combined file path.
 450       */
 451      function makeFile($pathA, $pathB) {
 452          $pathA = Files::fixPath($pathA);
 453          if (substr($pathB,0,1)=='/') {
 454              $pathB = substr($pathB,1);
 455          }
 456          return $pathA.$pathB;
 457      }
 458  
 459  
 460      /** formatSize function
 461       * Format the file size, limits to Mb.
 462       * @param int $size the raw filesize
 463       * @return string formated file size.
 464       */
 465      function formatSize($size) {
 466          if ($size < 1024) {
 467              return $size.' bytes';
 468          } elseif ($size >= 1024 && $size < 1024*1024) {
 469              return sprintf('%01.2f',$size/1024.0).' Kb';
 470          } else {
 471              return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';
 472          }
 473      }
 474  
 475      /** sourceType function
 476       * Returns type of the source
 477       * @param string $filename the name of file (with path, protocol, ...)
 478       * @return string FILE, HTTP, HTTPS, ...
 479       */
 480       function sourceType($filename) {
 481           if ( strtoupper(substr($filename,0,5)) == 'HTTPS') return 'HTTPS';
 482           if ( strtoupper(substr($filename,0,4)) == 'HTTP')  return 'HTTP';
 483           if ( strtoupper(substr($filename,0,3)) == 'FTP')   return 'FTP';
 484           return 'FILE';
 485       }
 486  }
 487  
 488  /**
 489   * AA_File_Wrapper class
 490   *
 491   * Copyright (c) 2003-2006 John Willinsky
 492   * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
 493   * (@see http://pkp.sfu.ca/ojs)
 494   *
 495   * Class abstracting operations for reading remote files using various protocols.
 496   * (for when allow_url_fopen is disabled).
 497   *
 498   * @todo:
 499   *     - Other protocols?
 500   *     - Write mode (where possible)
 501   *
 502   * Usage:  $file = &AA_File_Wrapper::wrapper($filename);
 503   *         if (!$file->open()) {
 504   *               $result = false;
 505   *               return $result;
 506   *           }
 507   *           while ($data = $file->read()) {
 508   *             //...
 509   *         }
 510   *           $file->close();
 511   *
 512   */
 513  class AA_File_Wrapper {
 514  
 515      /** @var $url string URL to the file */
 516      var $url;
 517  
 518      /** @var $info array parsed URL info */
 519      var $info;
 520  
 521      /** @var $fp int the file descriptor */
 522      var $fp;
 523  
 524      /** AA_File_Wrapper function
 525       * Constructor.
 526       * @param $url string
 527       * @param $info array
 528       */
 529      function AA_File_Wrapper($url, &$info) {
 530          $this->url = $url;
 531          $this->info = $info;
 532      }
 533  
 534      /** contents function
 535       * Read and return the contents of the file (like file_get_contents()).
 536       * @return string
 537       */
 538      function contents() {
 539          $contents = '';
 540          if ($this->open()) {
 541              while (!$this->eof()) {
 542                  $contents .= $this->read();
 543              }
 544              $this->close();
 545          }
 546          return $contents;
 547      }
 548  
 549      /** open function
 550       * Open the file.
 551       * @param $mode string only 'r' (read-only) is currently supported
 552       * @return boolean
 553       */
 554      function open($mode = 'r') {
 555          $this->fp = null;
 556          $this->fp = @fopen($this->url, $mode);
 557          return $this->fp;
 558      }
 559  
 560      /** close function
 561       * Close the file.
 562       */
 563      function close() {
 564          fclose($this->fp);
 565          unset($this->fp);
 566      }
 567  
 568      /** read function
 569       * Read from the file.
 570       * @param $len int
 571       * @return string
 572       */
 573      function read($len = 8192) {
 574          return fread($this->fp, $len);
 575      }
 576  
 577      /** eof function
 578       * Check for end-of-file.
 579       * @return boolean
 580       */
 581      function eof() {
 582          return feof($this->fp);
 583      }
 584  
 585      function getExif(){
 586          return new AA_Exif($this->url);
 587      }
 588  
 589      function getUrl(){
 590          return $this->url;
 591      }
 592  
 593      //
 594      // Static
 595      //
 596  
 597      /** &wrapper function
 598       * Return instance of a class for reading the specified URL.
 599       * @param $url string
 600       * @return AA_File_Wrapper
 601       */
 602      function &wrapper($url) {
 603          $info = parse_url($url);
 604          if (ini_get('allow_url_fopen')) {
 605              $wrapper = &new AA_File_Wrapper($url, $info);
 606          } else {
 607              switch (@$info['scheme']) {
 608                  case 'http':
 609                      $wrapper = &new AA_HTTP_File_Wrapper($url, $info);
 610                      break;
 611                  case 'https':
 612                      $wrapper = &new AA_HTTPS_File_Wrapper($url, $info);
 613                      break;
 614                  case 'ftp':
 615                      $wrapper = &new AA_FTP_File_Wrapper($url, $info);
 616                      break;
 617                  default:
 618                      $wrapper = &new AA_File_Wrapper($url, $info);
 619              }
 620          }
 621          return $wrapper;
 622      }
 623  }
 624  
 625  
 626  /**
 627   * HTTP protocol class.
 628   */
 629  class AA_HTTP_File_Wrapper extends AA_File_Wrapper {
 630      var $headers;
 631      var $defaultPort;
 632      var $defaultHost;
 633      var $defaultPath;
 634      /** AA_HTTP_File_Wrapper function
 635       * @param $url
 636       * @param $info
 637       */
 638      function AA_HTTP_File_Wrapper($url, &$info) {
 639          parent::AA_File_Wrapper($url, $info);
 640          $this->setDefaultPort(80);
 641          $this->setDefaultHost('localhost');
 642          $this->setDefaultPath('/');
 643      }
 644      /** setDefaultPort function
 645       * @param $port
 646       */
 647      function setDefaultPort($port) {
 648          $this->defaultPort = $port;
 649      }
 650      /** setDefaultHost function
 651       * @param $port
 652       */
 653      function setDefaultHost($host) {
 654          $this->defaultHost = $host;
 655      }
 656      /** setDefaultPath function
 657       * @param $port
 658       */
 659      function setDefaultPath($path) {
 660          $this->defaultPath = $path;
 661      }
 662      /** addHeader function
 663       * @param $name
 664       * @param $value
 665       */
 666      function addHeader($name, $value) {
 667          if (!isset($this->headers)) {
 668              $this->headers = array();
 669          }
 670          $this->headers[$name] = $value;
 671      }
 672      /** open function
 673       * @param $mode
 674       */
 675      function open($mode = 'r') {
 676          $host = isset($this->info['host']) ? $this->info['host'] : $this->defaultHost;
 677          $port = isset($this->info['port']) ? (int)$this->info['port'] : $this->defaultPort;
 678          $path = isset($this->info['path']) ? $this->info['path'] : $this->defaultPath;
 679          if (isset($this->info['query'])) {
 680              $path .= '?' . $this->info['query'];
 681          }
 682  
 683          if (!($this->fp = fsockopen($host, $port, $errno, $errstr))) {
 684              return false;
 685          }
 686  
 687          $additionalHeadersString = '';
 688          if (is_array($this->headers)) foreach ($this->headers as $name => $value) {
 689              $additionalHeadersString .= "$name: $value\r\n";
 690          }
 691  
 692          $request = "GET $path HTTP/1.0\r\n" .
 693              "Host: $host\r\n" .
 694              $additionalHeadersString .
 695              "Connection: Close\r\n\r\n";
 696          fwrite($this->fp, $request);
 697  
 698          $response = fgets($this->fp, 4096);
 699          $rc = 0;
 700          sscanf($response, "HTTP/%*s %u %*[^\r\n]\r\n", $rc);
 701          if ($rc == 200) {
 702              while(fgets($this->fp, 4096) !== "\r\n");
 703              return true;
 704          }
 705          $this->close();
 706          return false;
 707      }
 708  }
 709  
 710  /**
 711   * HTTPS protocol class.
 712   */
 713  class AA_HTTPS_File_Wrapper extends AA_HTTP_File_Wrapper {
 714      /** AA_HTTPS_File_Wrapper function
 715       * @param $url
 716       * @param $info
 717       */
 718      function AA_HTTPS_File_Wrapper($url, &$info) {
 719          parent::AA_HTTP_File_Wrapper($url, $info);
 720          $this->setDefaultPort(443);
 721          $this->setDefaultHost('ssl://localhost');
 722          if (isset($this->info['host'])) {
 723              $this->info['host'] = 'ssl://' . $this->info['host'];
 724          }
 725      }
 726  }
 727  
 728  /**
 729   * FTP protocol class.
 730   */
 731  class AA_FTP_File_Wrapper extends AA_File_Wrapper {
 732  
 733      var $ctrl;
 734      /** open function
 735       * @param $mode
 736       */
 737      function open($mode = 'r') {
 738          $user = isset($this->info['user']) ? $this->info['user'] : 'anonymous';
 739          $pass = isset($this->info['pass']) ? $this->info['pass'] : 'user@example.com';
 740          $host = isset($this->info['host']) ? $this->info['host'] : 'localhost';
 741          $port = isset($this->info['port']) ? (int)$this->info['port'] : 21;
 742          $path = isset($this->info['path']) ? $this->info['path'] : '/';
 743  
 744          if (!($this->ctrl = fsockopen($host, $port, $errno, $errstr))) {
 745              return false;
 746          }
 747  
 748          if ($this->_open($user, $pass, $path)){
 749              return true;
 750          }
 751  
 752          $this->close();
 753          return false;
 754      }
 755      /** close function
 756       *
 757       */
 758      function close() {
 759          if ($this->fp) {
 760              parent::close();
 761              $rc = $this->_receive(); // FIXME Check rc == 226 ?
 762          }
 763  
 764          $this->_send('QUIT'); // FIXME Check rc == 221?
 765          $rc = $this->_receive();
 766  
 767          fclose($this->ctrl);
 768          $this->ctrl = null;
 769      }
 770      /** _open function
 771       * @param $user
 772       * @param $pass
 773       * @param $path
 774       */
 775      function _open($user, $pass, $path) {
 776          // Connection establishment
 777          if ($this->_receive() != '220') {
 778              return false;
 779          }
 780  
 781          // Authentication
 782          $this->_send('USER', $user);
 783          $rc = $this->_receive();
 784          if ($rc == '331') {
 785              $this->_send('PASS', $pass);
 786              $rc = $this->_receive();
 787          }
 788          if ($rc != '230') {
 789              return false;
 790          }
 791  
 792          // Binary transfer mode
 793          $this->_send('TYPE', 'I');
 794          if ($this->_receive() != '200') {
 795              return false;
 796          }
 797  
 798          // Enter passive mode and open data transfer connection
 799          $this->_send('PASV');
 800          if ($this->_receiveLine($line) != '227') {
 801              return false;
 802          }
 803  
 804          if (!preg_match('/(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/', $line, $matches)) {
 805              return false;
 806          }
 807          list($tmp, $h1, $h2, $h3, $h4, $p1, $p2) = $matches;
 808  
 809          $host = "$h1.$h2.$h3.$h4";
 810          $port = ($p1 << 8) + $p2;
 811  
 812          if (!($this->fp = fsockopen($host, $port, $errno, $errstr))) {
 813              return false;
 814          }
 815  
 816          // Retrieve file
 817          $this->_send('RETR', $path);
 818          $rc = $this->_receive();
 819          if ($rc != '125' && $rc != '150') {
 820              return false;
 821          }
 822  
 823          return true;
 824      }
 825      /** _send function
 826       * @param $command
 827       * @param $data
 828       */
 829      function _send($command, $data = '') {
 830          return fwrite($this->ctrl, $command . (empty($data) ? '' : ' ' . $data) . "\r\n");
 831      }
 832      /** _receive function
 833       *
 834       */
 835      function _receive() {
 836          return $this->_receiveLine($line);
 837      }
 838      /** _receiveLine function
 839       * @param $line
 840       */
 841      function _receiveLine(&$line) {
 842          do {
 843              $line = fgets($this->ctrl);
 844          } while($line !== false && ($tmp = substr(trim($line), 3, 1)) != ' ' && $tmp != '');
 845  
 846          if ($line !== false) {
 847              return substr($line, 0, 3);
 848          }
 849          return false;
 850      }
 851  }
 852  
 853  /**
 854   * AA_File_Info class
 855   *
 856   * Copyright (c) 2007 Jan Cerny
 857   * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
 858   * (@see http://pkp.sfu.ca/ojs)
 859   *
 860   * Class abstracting getting of file metadata
 861   *
 862   * @todo:
 863   *
 864   * Usage:  $file_info = &AA_File_info::wrapper
 865   */
 866  
 867  class AA_File_Info {
 868      /** @var $url string URL to the file */
 869      var $url;
 870      /** @var $size int bytes of the file */
 871      var $size;
 872  
 873      /**
 874       * Constructor.
 875       * @param $url string
 876       */
 877      function AA_File_Info($url) {
 878          $this->url = $url;
 879          $this->size = filesize($this->url);
 880      }
 881  
 882      /**
 883       * Read and return size of file
 884       * @return array of string
 885       */
 886      function getInfo() {
 887          return array('file_size' => $this->getSize(true));
 888      }
 889  
 890      /**
 891       * Read and return size of file
 892       * @param $optimize boolean
 893       * @return int / string file size without / with unit
 894       */
 895      function getSize($optimize = false) {
 896          if ($optimize) {
 897              if ($this->size < 1024) {
 898                  return $this->size . ' bytes';
 899              } elseif ($this->size >= 1024 && $this->size < 1024*1024) {
 900                  return sprintf('%01.2f',$this->size/1024.0).' Kb';
 901              } else {
 902                  return sprintf('%01.2f',$this->size/(1024.0*1024)).' Mb';
 903              }
 904          } else {
 905              return $this->size;
 906          }
 907      }
 908  
 909      /**
 910       * Return instance of a class for reading the specified URL.
 911       * @param $url string
 912       * @return file info wrapper (type by $url)
 913       */
 914      function &wrapper($url) {
 915          $info = parse_url($url);
 916          /*if (ini_get('allow_url_fopen')) {
 917              $wrapper = &new AA_File_Wrapper($url, $info);
 918          } else {*/
 919          switch (strtolower(substr($info['path'], strrpos($info['path'], '.')+1 ))) { //parse extension
 920              case 'jpg':
 921                      $wrapper = &new AA_Jpg_Image_File_Info($url);
 922                      break;
 923              case 'gif':
 924              case 'png':
 925                      $wrapper = &new  AA_Image_File_Info($url);
 926                  default:
 927                      $wrapper = &new AA_File_Info($url);
 928              }
 929          return $wrapper;
 930      }
 931  }
 932  
 933  /**
 934   * AA_Image_File_Info class
 935   */
 936  class AA_Image_File_Info extends AA_File_Info {
 937      /** @var $img_height int height of image */
 938      var $img_height;
 939      /** @var $img_width int width of image */
 940      var $img_width;
 941      /** @var img_type string type of image according PHP IMAGETYPE_XXX constants */
 942      var $img_type;
 943  
 944      /**
 945       * Constructor.
 946       * @param $url string
 947       */
 948      function AA_Image_File_Info($url) {
 949          parent::AA_File_Info($url);
 950          //print_r(getimagesize($this->url));
 951          $size = getimagesize($this->url);
 952          list($this->img_width, $this->img_height) = $size;
 953          $this->img_type = $size['mime'];
 954      }
 955  
 956      /**
 957       * Read and return infor array
 958       * @return array of strings - infos
 959       */
 960      function getInfo() {
 961          $return_array = parent::getInfo();
 962          $return_array += array( 'img_height' => $this->getImgHeight(),
 963                                  'img_width'  => $this->getImgWidth(),
 964                                  'img_type'   => $this->getImgType());
 965          return $return_array;
 966      }
 967  
 968      function getImgHeight() {
 969          return $this->img_height;
 970      }
 971  
 972      function getImgWidth() {
 973          return $this->img_width;
 974      }
 975  
 976      function getImgType() {
 977          return $this->img_type;
 978      }
 979  }
 980  
 981  /**
 982   * AA_Jpg_Image_File_Info class
 983   */
 984  class AA_Jpg_Image_File_Info extends AA_Image_File_Info {
 985      /** @var $make string Exif make name */
 986      var $make;
 987      /** @var $model string Exif model name */
 988      var $model;
 989      /** @var $exposure_time string Exif exposure time */
 990      var $exposure_time;
 991      /** @var $aperture string Exif aperture */
 992      var $aperture;
 993      /** @var $focal_length string Exif foca_length */
 994      var $focal_length;
 995      /** @var $data_taken string Exif data taken*/
 996      var $data_taken;
 997      /** @var $whole_exif string whole Exif as a string */
 998      var $whole_exif;
 999      /** @var $orientation int Exif orientation of image */
1000      var $orientation; //only for rotation
1001  
1002      /**
1003       * Constructor.
1004       * @param $url string
1005       */
1006      function AA_Jpg_Image_File_Info($url) {
1007          parent::AA_Image_File_Info($url);
1008          $this->exifParse();
1009      }
1010  
1011      /**
1012       * Read and return infor array
1013       * @return array of strings - infos
1014       */
1015      function getInfo() {
1016          $return_array = parent::getInfo();
1017          $return_array += array( 'make'          => $this->getMake(),
1018                                  'model'         => $this->getModel(),
1019                                  'exposure_time' => $this->getExposureTime(),
1020                                  'aperture'      => $this->getAperture(),
1021                                  'focal_length'  => $this->getFocalLength(),
1022                                  'data_taken'    => $this->getDataTaken(),
1023                                  'orientation'   => $this->getOrientation(),
1024                                  'whole_exif'    => $this->getWholeExif());
1025          return $return_array;
1026      }
1027  
1028      /**
1029       * Read and parse the Exif of a picture
1030       * @return boolean wheather read
1031       */
1032      function exifParse() {
1033          if (!is_readable($this->url)) return false;
1034  
1035          //if ($this->img_type != IMAGETYPE_JPEG) return false; //not a jpg file
1036  
1037          $exif = exif_read_data($this->url,ANY_TAG,true);
1038          if (!$exif) return false;
1039  
1040          $this->exifParsed = array();
1041  
1042          if (isset($exif['IFD0']['Make'])) {
1043              $this->make = $exif['IFD0']['Make'];
1044          }
1045          if (isset($exif['IFD0']['Model'])) {
1046              $this->model = $exif['IFD0']['Model'];
1047          }
1048  
1049          if (isset($exif['COMPUTED']['ExposureTime'])) {
1050              $this->exposure_time = $exif['COMPUTED']['ExposureTime'];
1051          } elseif (isset($exif['EXIF']['ExposureTime'])){
1052              $this->exifParseFracval($exif['EXIF']['ExposureTime'], $num, $den);
1053              $exTime = $num / ($den ? $den : 1);
1054              if ($exTime <= 0.5 ) {
1055                  $this->exposure_time = sprintf("%0.3f s (1/%d)", $exTime, 1/$exTime);
1056              } else {
1057                  $this->exposure_time = sprintf("%3.2f s", $exTime);
1058              }
1059          }
1060  
1061          if (isset($exif['EXIF']['FNumber'])){
1062              $this->exifParseFracval($exif['EXIF']['FNumber'], $num, $den);
1063              $this->aperture = "f/".$num / ($den ? $den : 1);
1064          } elseif (isset($exif['COMPUTED']['ApertureFNumber'])) {
1065              $this->aperture = $exif['COMPUTED']['ApertureFNumber'];
1066          }
1067  
1068          if (isset($exif['EXIF']['FocalLength'])){
1069              $this->exifParseFracval($exif['EXIF']['FocalLength'], $num, $den);
1070              $this->focal_length = sprintf("%d mm", $num / ($den ? $den : 1));
1071          }
1072  
1073          if (isset($exif['EXIF']['DateTimeDigitized'])) {
1074              $this->data_taken = $exif['EXIF']['DateTimeDigitized'];
1075          }
1076  
1077          foreach ($exif as $key => $section) {
1078              foreach ($section as $name => $val) {
1079                  $this->whole_exif .= "$key.$name: $val<br />\n";
1080              }
1081          }
1082  
1083          if (isset($exif['IFD0']['Orientation'])) {
1084              $this->orientation = $exif['IFD0']['Orientation'];
1085          }
1086  
1087          return true;
1088      }
1089  
1090      function exifParseFracval($val, &$num, &$den) {
1091         $num = intval(strtok($val, "/"));
1092         $den = intval(strtok("/"));
1093      }
1094  
1095      function getMake() {
1096          return $this->make;
1097      }
1098  
1099      function getModel() {
1100          return $this->model;
1101      }
1102  
1103      function getExposureTime() {
1104          return $this->exposure_time;
1105      }
1106  
1107      function getAperture() {
1108          return $this->aperture;
1109      }
1110      function getFocalLength() {
1111          return $this->focal_length;
1112      }
1113  
1114      function getDataTaken() {
1115          return $this->data_taken;
1116      }
1117      function getWholeExif() {
1118          return $this->whole_exif;
1119      }
1120      function getOrientation() {
1121          return $this->orientation;
1122      }
1123  }
1124  
1125  /**
1126   * AA_Image_Manipulator class
1127   *
1128   * Copyright (c) 2007 Jan Cerny
1129   * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
1130   * (@see http://pkp.sfu.ca/ojs)
1131   *
1132   * Class abstracting manipulating with images
1133   *
1134   * @todo:
1135   *
1136   */
1137  
1138  class AA_Image_Manipulator {
1139      /** @var $url string URL to the file */
1140      var $url;
1141  
1142      /**
1143       * Constructor.
1144       * @param $url string
1145       */
1146      function AA_Image_Manipulator($url) {
1147          $this->url = $url;
1148      }
1149  
1150      /**
1151       * Rotate image by given angle
1152       * @param $angle float angle of rotation
1153       * @param $bg_color int color of uncovered zone after rotation
1154       * @return return value of imagejpeg() function
1155       */
1156      function rotateIt($angle, $bg_color) {
1157          $rot_img = imagecreatefromjpeg($this->url);
1158          $rot_img = imagerotate($rot_img, $angle, $bg_color);
1159          $ret_val = imagejpeg($rot_img , $this->url);
1160          imagedestroy($rot_img);
1161          return $ret_val;
1162      }
1163  
1164      /**
1165       * Rotate image by given Exif orientation or read it themself
1166       * @param $orientation int Exif orientation
1167       * @return return value of $this->rotateIt() function
1168       */
1169      function rotateAccordingToExif($orientation = 0) {
1170          if (!is_readable($this->url)) return false;
1171  
1172          if ($orientation == 0) {
1173              $file_info = new AA_Jpg_Image_File_Info($this->url);
1174              $orientation = $file_info->getOrientation();
1175          }
1176  
1177          switch($orientation) {
1178              case 3: //if upper left
1179                  $ret_val = $this->rotateIt(180, 0);
1180                  break;
1181              case 6: //if lower right
1182                 $ret_val = $this->rotateIt(270, 0);
1183                 break;
1184              case 8: // end if upper right
1185                 $ret_val = $this->rotateIt(90, 0);
1186                 break;
1187              default: // no rotate needed
1188                 $ret_val = false;
1189          }
1190  
1191          return $ret_val;
1192      }
1193  }
1194  
1195  /**
1196   * AA_Directory_Wrapper class
1197   *
1198   * Copyright (c) 2007 Jan Cerny
1199   * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
1200   * (@see http://pkp.sfu.ca/ojs)
1201   *
1202   * Class abstracting operations for reading remote directories using various
1203   * protocols.
1204   *
1205   * @todo:
1206   *     - Other protocols?
1207   *     - adding slash is unix like / (not sure with at win)
1208   *     - where to check for posting .. (go up) as args
1209   *     - cache the scaned structure somewhere?
1210   *
1211   * Usage:  $dir = &AA_Directory_Wrapper::wrapper($dirname);
1212   *         if (!$dir->open()) {
1213   *               $result = false;
1214   *               return $result;
1215   *           }
1216   *           while ($data = $dir->read()) {
1217   *             //...
1218   *         }
1219   *           $dir->close();
1220   *
1221   */
1222  class AA_Directory_Wrapper {
1223  
1224      /** @var $url string URL to the directory */
1225      var $url;
1226  
1227      /** @var $info array parsed URL info */
1228      var $info;
1229  
1230      /** @var $dp int the directory descriptor */
1231      var $dp;
1232  
1233      /** @var $is_read boolean specified if the content od directory is read */
1234      var $is_read;
1235  
1236      /** @var $subdir_names array of subdir names */
1237      var $subdir_names;
1238  
1239      /** @var $file_names array of file names */
1240      var $file_names;
1241  
1242      /** @var $reg_file_filter aplied to file names */
1243      var $reg_file_filter;
1244  
1245      /**
1246       * Constructor.
1247       * @param $url string
1248       * @param $info array
1249       */
1250      function AA_Directory_Wrapper($url, &$info) {
1251          $this->url = $url;
1252          if (!ereg("/$", $this->url)) {
1253              $this->url .= "/";
1254          }
1255          $this->info = $info;
1256  
1257          $this->dp = NULL;
1258          $this->is_read = false;
1259          $this->subdir_names = array();
1260          $this->file_names = array();
1261          $this->reg_file_filter = false;
1262      }
1263  
1264      /** Method returns or sets last error
1265       *  The trick for static class variables is used */
1266      function lastErr($err_id = null, $err_msg = null, $getmsg = false) {
1267          static $lastErr;
1268          static $lastErrMsg;
1269          if (!is_null($err_id)) {
1270              $lastErr    = $err_id;
1271              $lastErrMsg = $err_msg;
1272          }
1273          return $getmsg ? $lastErrMsg : $lastErr;
1274      }
1275  
1276      /** Return last error message - it is grabbed from static variable
1277       *  of lastErr() method */
1278      function lastErrMsg() {
1279          return self::lastErr(null, null, true);
1280      }
1281  
1282      /** Repository of static variables (trick for PHP4)
1283       *  The trick for static class variables is used */
1284      function _setStatic($varname, $value, $set=true) {
1285          static $variables;
1286          if ( $set ) {
1287              $variables[$varname] = $value;
1288          }
1289          return $variables[$varname];
1290      }
1291  
1292      /** Repository of static variables (trick for PHP4)
1293       *  The trick for static class variables is used */
1294      function _getStatic($varname) {
1295          return _setStatic($varname, null, false);
1296      }
1297  
1298      /**
1299       * Open the dir.
1300       * @return int directory descriptor or false if $url id not directory
1301       */
1302      function open() {
1303          if ($this->dp) {
1304              $this->close();
1305          }
1306  
1307          if (is_dir ($this->url)) {
1308              $this->dp = opendir($this->url);
1309              return $this->dp;
1310          } else {
1311              self::lastErr(AA_DIRECTORY_WRAPPER_ERROR_NOT_DIR, $this->url . _m(": No such directory"));
1312              return false;
1313          }
1314      }
1315  
1316      /**
1317       * Close the dir.
1318       */
1319      function close() {
1320          if ($this->dp) {
1321              closedir($this->dp);
1322          }
1323          $this_dp = NULL;
1324      }
1325  
1326      /**
1327       * Read one item from dir.
1328       * @return string next file in directory
1329       */
1330      function read() {
1331          return readdir($this->dp);
1332      }
1333  
1334      /**
1335       * Read whole content of directory to class arrays if needed, fill the class arrays
1336       */
1337      function readWholeDir() {
1338          if (!$this->is_read) {
1339              if ($this->open()) {
1340                  while ($file_name = $this->read()) {
1341                      if (is_dir($this->url . $file_name)) {
1342                          if ($file_name != "." && $file_name != "..") {
1343                              $this->subdir_names[] = $file_name;
1344                          }
1345                      }
1346                      elseif(is_file($this->url . $file_name)) {
1347                          $this->file_names[] = $file_name;
1348                      }
1349                  }
1350              } else {
1351                  return false;
1352              }
1353              $this->is_read = true;
1354              $this->close();
1355          }
1356          return true;
1357      }
1358  
1359      /**
1360       * Reload dir to class arrays
1361       */
1362      function reloadWholeDir() {
1363          $this->is_read = false;
1364          $this->subdir_names = array();
1365          $this->file_names = array();
1366          $this->readWholeDir();
1367      }
1368  
1369      /**
1370       * Make file wrapper from file array
1371       * @return array of AA_File_Wrapper instances
1372       */
1373      function makeFileWrappers() {
1374          foreach ($this->file_names as $file_name) {
1375              $return_array[] = AA_File_Wrapper::wrapper($file_name);
1376          }
1377          return $return_array;
1378      }
1379  
1380      /**
1381       * Make subdir wrapper from subdir array
1382       * @return array of AA_Directory_Wrapper instances
1383       */
1384      function makeSubdirWrappers() {
1385          foreach ($this->subdir_names as $subdir_name) {
1386              $return_array[] = AA_Directory_Wrapper::wrapper($subdir_name);
1387          }
1388          return $return_array;
1389      }
1390  
1391      /**
1392       * Read and return the contents of the directory.
1393       * @return array of AA_File_Wrapper instances
1394       */
1395      function getFiles() {
1396          if ($this->readWholeDir()) {
1397              return $this->makeFileWrappers();
1398          } else {
1399              return false;
1400          }
1401      }
1402  
1403      /**
1404       * Read and return wrapped subdirs
1405       * @return array of directory wrappers (type by my type)
1406       */
1407      function getSubdirs() {
1408          if ($this->readWholeDir()) {
1409              return $this->makeSubdirWrappers();
1410          } else {
1411              return false;
1412          }
1413      }
1414  
1415      /**
1416       * Read and return file names
1417       * @param $full_path
1418       * @return array of strings file names
1419       */
1420      function getFileNames($full_path = false) {
1421          if ($this->readWholeDir()) {
1422              if ($full_path) {
1423                  foreach ($this->file_names as $file_name) {
1424                      $return_array[] = $this->url . $file_name;
1425                  }
1426                  return $return_array;
1427              } else {
1428                  return $this->file_names;
1429              }
1430          } else {
1431              return false;
1432          }
1433      }
1434  
1435      /**
1436       * Read and return filtered file names
1437       * @param $full_path
1438       * @return array of strings filtered file names
1439       */
1440      function getRegFilteredFileNames($full_path = false) {
1441          if (!is_array($all_file_names = $this->getFileNames($full_path))) {
1442              return false;
1443          }
1444          if ($this->reg_file_filter) {
1445              $return_array = array();
1446              foreach ($all_file_names as $file_name) {
1447                  if (eregi($this->reg_file_filter, $file_name)) {
1448                      $return_array[] = $file_name;
1449                  }
1450              }
1451              return $return_array;
1452          } else {
1453              return false;
1454          }
1455      }
1456  
1457      /**
1458       * Read and return subdir names
1459       * @param $full_path
1460       * @return array of strings subdir names
1461       */
1462      function getSubdirNames($full_path = false) {
1463          if ($this->readWholeDir()) {
1464              if ($full_path) {
1465                  foreach ($this->subdir_names as $subdir_name) {
1466                      $return_array[] = $this->url . $subdir_name;
1467                  }
1468                  return $return_array;
1469              } else {
1470                  return $this->subdir_names;
1471              }
1472          } else {
1473              return false;
1474          }
1475      }
1476  
1477      /**
1478       * Read and return complete subdirtree
1479       * @return array of arrays indexed by values
1480       */
1481      function getSubdirTree() {
1482          return $this->getSubdirNamesRecur();
1483      }
1484  
1485      /**
1486       * Read and return complete subdirtree - internal
1487       * @return array of arrays indexed by values
1488       */
1489      function  getSubdirNamesRecur() {
1490          if ($this->readWholeDir()) {
1491              //compare if is it prefered subdir
1492              if ($this->url == self::_getStatic('needed_subdir_name')) {
1493                  self::_setStatic('subdir_file_names', $this->file_names);
1494              }
1495              if (empty($this->subdir_names)) {
1496                  return array();
1497              }
1498  
1499              foreach ($this->subdir_names as $subdir_name) {
1500                  $subdir = AA_Directory_Wrapper::wrapper($this->url . $subdir_name);
1501                  $return_array[$subdir_name] = $subdir->getSubdirNamesRecur();
1502              }
1503              return $return_array;
1504  
1505          } else {
1506              return false;
1507          }
1508      }
1509  
1510      /**
1511       * Return file names in specified directory
1512       * @return array of string
1513       */
1514      function getSubdirFileNames() {
1515          return self::_getStatic('subdir_file_names');
1516      }
1517  
1518      /**
1519       * Set the $reg_file_filter variable
1520       * @param $filter string
1521       */
1522      function setRegFileFilter($filter = false) {
1523          $this->reg_file_filter = $filter;
1524      }
1525  
1526      /**
1527       * Set the $needed_subdir_name variable
1528       * @param $name string
1529       */
1530      function setNeededSubdir($name) {
1531          self::_setStatic('needed_subdir_name', $name);
1532      }
1533  
1534      //
1535      // Static
1536      //
1537  
1538      /**
1539       * Return instance of a class for reading the specified URL.
1540       * @param $url string
1541       * @return directory wrapper (type by $url)
1542       */
1543      function &wrapper($url) {
1544          $info = parse_url($url);
1545          /*if (ini_get('allow_url_fopen')) {
1546              $wrapper = &new AA_File_Wrapper($url, $info);
1547          } else {*/
1548  
1549              switch (@$info['scheme']) {
1550                  case 'ftp':
1551                      echo "ftp directory not yet implemented\n";
1552                      //$wrapper = &new AA_FTP_Directory_Wrapper($url, $info);
1553                      break;
1554                  default:
1555                      $wrapper = &new AA_Directory_Wrapper($url, $info);
1556              }
1557          return $wrapper;
1558      }
1559  }
1560  
1561  ?>

title

Description

title

Description

title

Description

title

title

Body