[ Index ]
 

Code source de PHP PEAR 1.4.5

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

title

Body

[fermer]

/PEAR/PackageFileManager/ -> File.php (source)

   1  <?php
   2  //
   3  // +------------------------------------------------------------------------+
   4  // | PEAR :: Package File Manager                                           |
   5  // +------------------------------------------------------------------------+
   6  // | Copyright (c) 2003-2004 Gregory Beaver                                 |
   7  // | Email         cellog@phpdoc.org                                        |
   8  // +------------------------------------------------------------------------+
   9  // | This source file is subject to version 3.00 of the PHP License,        |
  10  // | that is available at http://www.php.net/license/3_0.txt.               |
  11  // | If you did not receive a copy of the PHP license and are unable to     |
  12  // | obtain it through the world-wide-web, please send a note to            |
  13  // | license@php.net so we can mail you a copy immediately.                 |
  14  // +------------------------------------------------------------------------+
  15  // | Portions of this code based on phpDocumentor                           |
  16  // | Web           http://www.phpdoc.org                                    |
  17  // | Mirror        http://phpdocu.sourceforge.net/                          |
  18  // +------------------------------------------------------------------------+
  19  // $Id: File.php,v 1.21 2005/03/28 06:37:35 cellog Exp $
  20  //
  21  /**
  22   * Retrieve the files from a directory listing
  23   * @package PEAR_PackageFileManager
  24   */
  25  /**
  26   * Retrieve the files from a directory listing
  27   *
  28   * This class is used to retrieve a raw directory
  29   * listing.  Use the {@link PEAR_PackageFileManager_CVS}
  30   * class to only retrieve the contents of a cvs
  31   * repository when generating the package.xml
  32   * @package PEAR_PackageFileManager
  33   */
  34  class PEAR_PackageFileManager_File {
  35      /**
  36       * @var array
  37       * @access private
  38       */
  39      var $_options = 
  40              array(
  41                   );
  42  
  43      /**
  44       * @access private
  45       * @var PEAR_PackageFileManager
  46       */
  47      var $_parent;
  48  
  49      /**
  50       * @access private
  51       * @var array|false
  52       */
  53      var $_ignore = false;
  54  
  55      /**
  56       * Set up the File filelist generator
  57       *
  58       * 'ignore' and 'include' are the only options that this class uses.  See
  59       * {@link PEAR_PackageFileManager::setOptions()} for
  60       * more information and formatting of this option
  61       * @param PEAR_PackageFileManager
  62       * @param array
  63       */
  64      function PEAR_PackageFileManager_File(&$parent, $options)
  65      {
  66          $this->_parent = &$parent;
  67          $this->_options = array_merge($this->_options, $options);
  68      }
  69      
  70      /**
  71       * Generate the <filelist></filelist> section
  72       * of the package file.
  73       *
  74       * This function performs the backend generation of the array
  75       * containing all files in this package
  76       * @return array
  77       */
  78      function getFileList()
  79      {
  80          $package_directory = $this->_options['packagedirectory'];
  81          $ignore = $this->_options['ignore'];
  82          // implicitly ignore packagefile
  83          $ignore[] = $this->_options['packagefile'];
  84          if ($this->_options['packagefile'] == 'package.xml') {
  85              // ignore auto-generated package2.xml from PEAR 1.4.0
  86              $ignore[] = 'package2.xml';
  87          }
  88          $include = $this->_options['include'];
  89          $this->ignore = array(false, false);
  90          $this->_setupIgnore($ignore, 1);
  91          $this->_setupIgnore($include, 0);
  92          $allfiles = $this->dirList(substr($package_directory, 0, strlen($package_directory) - 1));
  93          if (PEAR::isError($allfiles)) {
  94              return $allfiles;
  95          }
  96          if (!count($allfiles)) {
  97              return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_NO_FILES,
  98                  substr($package_directory, 0, strlen($package_directory) - 1));
  99          }
 100          $struc = array();
 101          foreach($allfiles as $file) {
 102              $path = substr(dirname($file), strlen(str_replace(DIRECTORY_SEPARATOR, 
 103                                                                '/',
 104                                                                realpath($package_directory))) + 1);
 105              if (!$path) {
 106                  $path = '/';
 107              }
 108              $ext = array_pop(explode('.', $file));
 109              if (strlen($ext) == strlen($file)) {
 110                  $ext = '';
 111              }
 112              $struc[$path][] = array('file' => basename($file),
 113                                      'ext' => $ext,
 114                                      'path' => (($path == '/') ? basename($file) : $path . '/' . basename($file)),
 115                                      'fullpath' => $file);
 116          }
 117          if (!count($struc)) {
 118              $newig = implode($this->_options['ignore'], ', ');
 119              return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING,
 120                  substr($package_directory, 0, strlen($package_directory) - 1), $newig);
 121          }
 122          uksort($struc,'strnatcasecmp');
 123          foreach($struc as $key => $ind) {
 124              usort($ind, array($this, 'sortfiles'));
 125              $struc[$key] = $ind;
 126          }
 127  
 128          $tempstruc = $struc;
 129          if (!isset($tempstruc['/'])) {
 130              $tempstruc['/'] = array();
 131          }
 132          $struc = array('/' => $tempstruc['/']);
 133          $bv = 0;
 134          foreach($tempstruc as $key => $ind) {
 135              $save = $key;
 136              if ($key != '/')
 137              {
 138                  $struc['/'] = $this->_setupDirs($struc['/'], explode('/',$key), $tempstruc[$key]);
 139              }
 140          }
 141          uksort($struc['/'], array($this, 'mystrucsort'));
 142  
 143          return $struc;
 144      }
 145      
 146      /**
 147       * Retrieve a listing of every file in $directory and
 148       * all subdirectories.
 149       *
 150       * The return format is an array of full paths to files
 151       * @access protected
 152       * @return array list of files in a directory
 153       * @param string $directory full path to the directory you want the list of
 154       * @throws PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST
 155       */
 156      function dirList($directory)
 157      {
 158          $ret = false;
 159          if (@is_dir($directory)) {
 160              $ret = array();
 161              $d = @dir($directory); // thanks to Jason E Sweat (jsweat@users.sourceforge.net) for fix
 162              while($d && false !== ($entry=$d->read())) {
 163                  if ($this->_testFile($directory, $entry)) {
 164                      if (is_file($directory . '/' . $entry)) {
 165                          // if include option was set, then only pass included files
 166                          if ($this->ignore[0]) {
 167                              if ($this->_checkIgnore($entry, $directory . '/' . $entry, 0)) {
 168                                  continue;
 169                              }
 170                          }
 171                          // if ignore option was set, then only pass included files
 172                          if ($this->ignore[1]) {
 173                              if ($this->_checkIgnore($entry, $directory . '/' . $entry, 1)) {
 174                                  continue;
 175                              }
 176                          }
 177                          $ret[] = $directory . '/' . $entry;
 178                      }
 179                      if (is_dir($directory . '/' . $entry)) {
 180                          $tmp = $this->dirList($directory . '/' . $entry);
 181                          if (is_array($tmp)) {
 182                              foreach($tmp as $ent) {
 183                                  $ret[] = $ent;
 184                              }
 185                          }
 186                      }
 187                  }
 188              }
 189              if ($d) {
 190                  $d->close();
 191              }
 192          } else {
 193              return PEAR_PackageFileManager::raiseError(PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST, $directory);
 194          }
 195          return $ret;
 196      }
 197      
 198      /**
 199       * Test whether an entry should be processed.
 200       * 
 201       * Normally, it ignores all files and directories that begin with "."  addhiddenfiles option
 202       * instead only ignores "." and ".." entries
 203       * @access private
 204       * @param string directory name of entry
 205       * @param string name
 206       */
 207      function _testFile($directory, $entry)
 208      {
 209          if ($this->_options['addhiddenfiles']) {
 210              return is_file($directory . '/' . $entry) || (is_dir($directory . '/' . $entry) && !in_array($entry, array('.', '..')));
 211          } else {
 212              return $entry{0} != '.';
 213          }
 214      }
 215  
 216      /**
 217       * Tell whether to ignore a file or a directory
 218       * allows * and ? wildcards
 219       *
 220       * @param    string  $file    just the file name of the file or directory,
 221       *                          in the case of directories this is the last dir
 222       * @param    string  $path    the full path
 223       * @param    1|0    $return  value to return if regexp matches.  Set this to
 224       *                            false to include only matches, true to exclude
 225       *                            all matches
 226       * @return   bool    true if $path should be ignored, false if it should not
 227       * @access private
 228       */
 229      function _checkIgnore($file, $path, $return = 1)
 230      {
 231          if (file_exists($path)) {
 232              $path = realpath($path);
 233          }
 234          if (is_array($this->ignore[$return])) {
 235              foreach($this->ignore[$return] as $match) {
 236                  // match is an array if the ignore parameter was a /path/to/pattern
 237                  if (is_array($match)) {
 238                      // check to see if the path matches with a path delimiter appended
 239                      preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path) . '/',$find);
 240                      if (!count($find)) {
 241                          // check to see if it matches without an appended path delimiter
 242                          preg_match('/^' . strtoupper($match[0]).'$/', strtoupper($path), $find);
 243                      }
 244                      if (count($find)) {
 245                          // check to see if the file matches the file portion of the regex string
 246                          preg_match('/^' . strtoupper($match[1]).'$/', strtoupper($file), $find);
 247                          if (count($find)) {
 248                              return $return;
 249                          }
 250                      }
 251                      // check to see if the full path matches the regex
 252                      preg_match('/^' . strtoupper($match[0]).'$/',
 253                                 strtoupper($path . DIRECTORY_SEPARATOR . $file), $find);
 254                      if (count($find)) {
 255                          return $return;
 256                      }
 257                  } else {
 258                      // ignore parameter was just a pattern with no path delimiters
 259                      // check it against the path
 260                      preg_match('/^' . strtoupper($match).'$/', strtoupper($path), $find);
 261                      if (count($find)) {
 262                          return $return;
 263                      }
 264                      // check it against the file only
 265                      preg_match('/^' . strtoupper($match).'$/', strtoupper($file), $find);
 266                      if (count($find)) {
 267                          return $return;
 268                      }
 269                  }
 270              }
 271          }
 272          return !$return;
 273      }
 274      
 275      /**
 276       * Construct the {@link $ignore} array
 277       * @param array strings of files/paths/wildcards to ignore
 278       * @param 0|1 0 = files to include, 1 = files to ignore
 279       * @access private
 280       */
 281      function _setupIgnore($ignore, $index)
 282      {
 283          $ig = array();
 284          if (is_array($ignore)) {
 285              for($i=0; $i<count($ignore);$i++) {
 286                  $ignore[$i] = strtr($ignore[$i], "\\", "/");
 287                  $ignore[$i] = str_replace('//','/',$ignore[$i]);
 288  
 289                  if (!empty($ignore[$i])) {
 290                      if (!is_numeric(strpos($ignore[$i], '/'))) {
 291                          $ig[] = $this->_getRegExpableSearchString($ignore[$i]);
 292                      } else {
 293                          if (basename($ignore[$i]) . '/' == $ignore[$i]) {
 294                              $ig[] = $this->_getRegExpableSearchString($ignore[$i]);
 295                          } else {
 296                              $ig[] = array($this->_getRegExpableSearchString($ignore[$i]),
 297                                        $this->_getRegExpableSearchString(basename($ignore[$i])));
 298                          }
 299                      }
 300                  }
 301              }
 302              if (count($ig)) {
 303                  $this->ignore[$index] = $ig;
 304              } else {
 305                  $this->ignore[$index] = false;
 306              }
 307          } else $this->ignore[$index] = false;
 308      }
 309      
 310      /**
 311       * Converts $s into a string that can be used with preg_match
 312       * @param string $s string with wildcards ? and *
 313       * @return string converts * to .*, ? to ., etc.
 314       * @access private
 315       */
 316      function _getRegExpableSearchString($s)
 317      {
 318          $y = '\/';
 319          if (DIRECTORY_SEPARATOR == '\\') {
 320              $y = '\\\\';
 321          }
 322          $s = str_replace('/', DIRECTORY_SEPARATOR, $s);
 323          $x = strtr($s, array('?' => '.','*' => '.*','.' => '\\.','\\' => '\\\\','/' => '\\/',
 324                                  '[' => '\\[',']' => '\\]','-' => '\\-'));
 325          if (strpos($s, DIRECTORY_SEPARATOR) !== false &&
 326                strrpos($s, DIRECTORY_SEPARATOR) === strlen($s) - 1) {
 327              $x = "(?:.*$y$x?.*|$x.*)";
 328          }
 329          return $x;
 330      }
 331      
 332      /**
 333       * Recursively move contents of $struc into associative array
 334       *
 335       * The contents of $struc have many indexes like 'dir/subdir/subdir2'.
 336       * This function converts them to
 337       * array('dir' => array('subdir' => array('subdir2')))
 338       * @param array struc is array('dir' => array of files in dir,
 339       *              'dir/subdir' => array of files in dir/subdir,...)
 340       * @param array array form of 'dir/subdir/subdir2' array('dir','subdir','subdir2')
 341       * @return array same as struc but with array('dir' =>
 342       *              array(file1,file2,'subdir' => array(file1,...)))
 343       * @access private
 344       */
 345      function _setupDirs($struc, $dir, $contents)
 346      {
 347          if (!count($dir)) {
 348              foreach($contents as $dir => $files) {
 349                  if (is_string($dir)) {
 350                      if (strpos($dir, '/')) {
 351                          $test = true;
 352                          $a = $contents[$dir];
 353                          unset($contents[$dir]);
 354                          $b = explode('/', $dir);
 355                          $c = array_shift($b);
 356                          if (isset($contents[$c])) {
 357                              $contents[$c] = $this->_setDir($contents[$c], $this->_setupDirs(array(), $b, $a));
 358                          } else {
 359                              $contents[$c] = $this->_setupDirs(array(), $b, $a);
 360                          }
 361                      }
 362                  }
 363              }
 364              return $contents;
 365          }
 366          $me = array_shift($dir);
 367          if (!isset($struc[$me])) {
 368              $struc[$me] = array();
 369          }
 370          $struc[$me] = $this->_setupDirs($struc[$me], $dir, $contents);
 371          return $struc;
 372      }
 373  
 374      
 375      /**
 376       * Recursively add all the subdirectories of $contents to $dir without erasing anything in
 377       * $dir
 378       * @param array
 379       * @param array
 380       * @return array processed $dir
 381       * @access private
 382       */
 383      function _setDir($dir, $contents)
 384      {
 385          while(list($one,$two) = each($contents)) {
 386              if (isset($dir[$one])) {
 387                  $dir[$one] = $this->_setDir($dir[$one], $contents[$one]);
 388              } else {
 389                  $dir[$one] = $two;
 390              }
 391          }
 392          return $dir;
 393      }
 394  
 395      
 396      /**#@+
 397       * Sorting functions for the file list
 398       * @param string
 399       * @param string
 400       * @access private
 401       */
 402      function sortfiles($a, $b)
 403      {
 404          return strnatcasecmp($a['file'],$b['file']);
 405      }
 406      
 407      function mystrucsort($a, $b)
 408      {
 409          if (is_numeric($a) && is_string($b)) return 1;
 410          if (is_numeric($b) && is_string($a)) return -1;
 411          if (is_numeric($a) && is_numeric($b))
 412          {
 413              if ($a > $b) return 1;
 414              if ($a < $b) return -1;
 415              if ($a == $b) return 0;
 416          }
 417          return strnatcasecmp($a,$b);
 418      }
 419      /**#@-*/
 420  }
 421  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7