[ Index ]
 

Code source de Symfony 1.0.0

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

title

Body

[fermer]

/lib/vendor/pake/ -> pakeFinder.class.php (source)

   1  <?php
   2  
   3  /**
   4   * @package    pake
   5   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
   6   * @copyright  2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
   7   * @license    see the LICENSE file included in the distribution
   8   * @version    SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
   9   */
  10  
  11  require_once dirname(__FILE__).'/pakeGlobToRegex.class.php';
  12  require_once dirname(__FILE__).'/pakeNumberCompare.class.php';
  13  
  14  if (class_exists('pakeFinder'))
  15  {
  16    return;
  17  }
  18  
  19  /**
  20   *
  21   * Allow to build rules to find files and directories.
  22   *
  23   * All rules may be invoked several times, except for ->in() method.
  24   * Some rules are cumulative (->name() for example) whereas others are destructive
  25   * (most recent value is used, ->maxdepth() method for example).
  26   *
  27   * All methods return the current pakeFinder object to allow easy chaining:
  28   *
  29   * $files = pakeFinder::type('file')->name('*.php')->in(.);
  30   *
  31   * Interface loosely based on perl File::Find::Rule module.
  32   *
  33   * @package    pake
  34   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  35   * @copyright  2004-2005 Fabien Potencier <fabien.potencier@symfony-project.com>
  36   * @license    see the LICENSE file included in the distribution
  37   * @version    SVN: $Id: pakeFinder.class.php 3268 2007-01-13 20:19:33Z fabien $
  38   */
  39  class pakeFinder
  40  {
  41    private $type        = 'file';
  42    private $names       = array();
  43    private $prunes      = array();
  44    private $discards    = array();
  45    private $execs       = array();
  46    private $mindepth    = 0;
  47    private $sizes       = array();
  48    private $maxdepth    = 1000000;
  49    private $relative    = false;
  50    private $follow_link = false;
  51    private $search_dir  = '';
  52  
  53    /**
  54     * Sets maximum directory depth.
  55     *
  56     * Finder will descend at most $level levels of directories below the starting point.
  57     *
  58     * @param  integer level
  59     * @return object current pakeFinder object
  60     */
  61    public function maxdepth($level)
  62    {
  63      $this->maxdepth = $level;
  64  
  65      return $this;
  66    }
  67  
  68    /**
  69     * Sets minimum directory depth.
  70     *
  71     * Finder will start applying tests at level $level.
  72     *
  73     * @param  integer level
  74     * @return object current pakeFinder object
  75     */
  76    public function mindepth($level)
  77    {
  78      $this->mindepth = $level;
  79  
  80      return $this;
  81    }
  82  
  83    public function get_type()
  84    {
  85      return $this->type;
  86    }
  87  
  88    /**
  89     * Sets the type of elements to returns.
  90     *
  91     * @param  string directory or file or any (for both file and directory)
  92     * @return object new pakeFinder object
  93     */
  94    public static function type($name)
  95    {
  96      $finder = new pakeFinder();
  97  
  98      if (strtolower(substr($name, 0, 3)) == 'dir')
  99      {
 100        $finder->type = 'directory';
 101      }
 102      else if (strtolower($name) == 'any')
 103      {
 104        $finder->type = 'any';
 105      }
 106      else
 107      {
 108        $finder->type = 'file';
 109      }
 110  
 111      return $finder;
 112    }
 113  
 114    /*
 115     * glob, patterns (must be //) or strings
 116     */
 117    private function to_regex($str)
 118    {
 119      if ($str[0] == '/' && $str[strlen($str) - 1] == '/')
 120      {
 121        return $str;
 122      }
 123      else
 124      {
 125        return pakeGlobToRegex::glob_to_regex($str);
 126      }
 127    }
 128  
 129    private function args_to_array($arg_list, $not = false)
 130    {
 131      $list = array();
 132  
 133      for ($i = 0; $i < count($arg_list); $i++)
 134      {
 135        if (is_array($arg_list[$i]))
 136        {
 137          foreach ($arg_list[$i] as $arg)
 138          {
 139            $list[] = array($not, $this->to_regex($arg));
 140          }
 141        }
 142        else
 143        {
 144          $list[] = array($not, $this->to_regex($arg_list[$i]));
 145        }
 146      }
 147  
 148      return $list;
 149    }
 150  
 151    /**
 152     * Adds rules that files must match.
 153     *
 154     * You can use patterns (delimited with / sign), globs or simple strings.
 155     *
 156     * $finder->name('*.php')
 157     * $finder->name('/\.php$/') // same as above
 158     * $finder->name('test.php')
 159     *
 160     * @param  list   a list of patterns, globs or strings
 161     * @return object current pakeFinder object
 162     */
 163    public function name()
 164    {
 165      $args = func_get_args();
 166      $this->names = array_merge($this->names, $this->args_to_array($args));
 167  
 168      return $this;
 169    }
 170  
 171    /**
 172     * Adds rules that files must not match.
 173     *
 174     * @see    ->name()
 175     * @param  list   a list of patterns, globs or strings
 176     * @return object current pakeFinder object
 177     */
 178    public function not_name()
 179    {
 180      $args = func_get_args();
 181      $this->names = array_merge($this->names, $this->args_to_array($args, true));
 182  
 183      return $this;
 184    }
 185  
 186    /**
 187     * Adds tests for file sizes.
 188     *
 189     * $finder->size('> 10K');
 190     * $finder->size('<= 1Ki');
 191     * $finder->size(4);
 192     *
 193     * @param  list   a list of comparison strings
 194     * @return object current pakeFinder object
 195     */
 196    public function size()
 197    {
 198      $args = func_get_args();
 199      for ($i = 0; $i < count($args); $i++)
 200      {
 201        $this->sizes[] = new pakeNumberCompare($args[$i]);
 202      }
 203  
 204      return $this;
 205    }
 206  
 207    /**
 208     * Traverses no further.
 209     *
 210     * @param  list   a list of patterns, globs to match
 211     * @return object current pakeFinder object
 212     */
 213    public function prune()
 214    {
 215      $args = func_get_args();
 216      $this->prunes = array_merge($this->prunes, $this->args_to_array($args));
 217  
 218      return $this;
 219    }
 220  
 221    /**
 222     * Discards elements that matches.
 223     *
 224     * @param  list   a list of patterns, globs to match
 225     * @return object current pakeFinder object
 226     */
 227    public function discard()
 228    {
 229      $args = func_get_args();
 230      $this->discards = array_merge($this->discards, $this->args_to_array($args));
 231  
 232      return $this;
 233    }
 234  
 235    /**
 236     * Ignores version control directories.
 237     *
 238     * Currently supports subversion, CVS, DARCS, Gnu Arch, Monotone, Bazaar-NG
 239     *
 240     * @return object current pakeFinder object
 241     */
 242    public function ignore_version_control()
 243    {
 244      $ignores = array('.svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr');
 245  
 246      return $this->discard($ignores)->prune($ignores);
 247    }
 248  
 249    /**
 250     * Executes function or method for each element.
 251     *
 252     * Element match if functino or method returns true.
 253     *
 254     * $finder->exec('myfunction');
 255     * $finder->exec(array($object, 'mymethod'));
 256     *
 257     * @param  mixed  function or method to call
 258     * @return object current pakeFinder object
 259     */
 260    public function exec()
 261    {
 262      $args = func_get_args();
 263      for ($i = 0; $i < count($args); $i++)
 264      {
 265        if (is_array($args[$i]) && !method_exists($args[$i][0], $args[$i][1]))
 266        {
 267          throw new pakeException(sprintf("Method %s does not exist for object %s.", $args[$i][1], $args[$i][0]));
 268        }
 269        else if (!is_array($args[$i]) && !function_exists($args[$i]))
 270        {
 271          throw new pakeException(sprintf("Function %s does not exist.", $args[$i]));
 272        }
 273  
 274        $this->execs[] = $args[$i];
 275      }
 276  
 277      return $this;
 278    }
 279  
 280    /**
 281     * Returns relative paths for all files and directories.
 282     *
 283     * @return object current pakeFinder object
 284     */
 285    public function relative()
 286    {
 287      $this->relative = true;
 288  
 289      return $this;
 290    }
 291  
 292    /**
 293     * Symlink following.
 294     *
 295     * @return object current sfFinder object
 296     */
 297    public function follow_link()
 298    {
 299      $this->follow_link = true;
 300  
 301      return $this;
 302    }
 303  
 304    /**
 305     * Searches files and directories which match defined rules.
 306     *
 307     * @return array list of files and directories
 308     */
 309    public function in()
 310    {
 311      $files    = array();
 312      $here_dir = getcwd();
 313      $numargs  = func_num_args();
 314      $arg_list = func_get_args(); 
 315  
 316      // first argument is an array?
 317      if ($numargs == 1 && is_array($arg_list[0]))
 318      {
 319        $arg_list = $arg_list[0];
 320        $numargs  = count($arg_list);
 321      }
 322  
 323      $dirs = array();
 324      for ($i = 0; $i < $numargs; $i++)
 325      {
 326        if ($argDirs = glob($arg_list[$i]))
 327        {
 328          $dirs = array_merge($dirs, $argDirs);
 329        }
 330      }
 331  
 332      foreach ($dirs as $dir)
 333      {
 334        $real_dir = realpath($dir);
 335  
 336        // absolute path?
 337        if (!self::isPathAbsolute($real_dir))
 338        {
 339          $dir = $here_dir.DIRECTORY_SEPARATOR.$real_dir;
 340        }
 341        else
 342        {
 343          $dir = $real_dir;
 344        }
 345  
 346        if (!is_dir($real_dir))
 347        {
 348          continue;
 349        }
 350  
 351        $this->search_dir = $dir;
 352  
 353        if ($this->relative)
 354        {
 355          $files = array_merge($files, str_replace($dir.DIRECTORY_SEPARATOR, '', $this->search_in($dir)));
 356        }
 357        else
 358        {
 359          $files = array_merge($files, $this->search_in($dir));
 360        }
 361      }
 362  
 363      return array_unique($files);
 364    }
 365  
 366    private function search_in($dir, $depth = 0)
 367    {
 368      if ($depth > $this->maxdepth)
 369      {
 370        return array();
 371      }
 372  
 373      if (is_link($dir) && !$this->follow_link)
 374      {
 375        return array();
 376      }
 377  
 378      $files = array();
 379  
 380      if (is_dir($dir))
 381      {
 382        $current_dir = opendir($dir);
 383        while (false !== $entryname = readdir($current_dir))
 384        {
 385          if ($entryname == '.' || $entryname == '..') continue;
 386  
 387          $current_entry = $dir.DIRECTORY_SEPARATOR.$entryname;
 388          if (is_link($current_entry) && !$this->follow_link)
 389          {
 390            continue;
 391          }
 392  
 393          if (is_dir($current_entry))
 394          {
 395            if (($this->type == 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->exec_ok($dir, $entryname))
 396            {
 397              $files[] = realpath($current_entry);
 398            }
 399  
 400            if (!$this->is_pruned($dir, $entryname))
 401            {
 402              $files = array_merge($files, $this->search_in($current_entry, $depth + 1));
 403            }
 404          }
 405          else
 406          {
 407            if (($this->type != 'directory' || $this->type == 'any') && ($depth >= $this->mindepth) && !$this->is_discarded($dir, $entryname) && $this->match_names($dir, $entryname) && $this->size_ok($dir, $entryname) && $this->exec_ok($dir, $entryname))
 408            {
 409              $files[] = realpath($current_entry);
 410            }
 411          }
 412        }
 413        closedir($current_dir);
 414      }
 415  
 416      return $files;
 417    }
 418  
 419    private function match_names($dir, $entry)
 420    {
 421      if (!count($this->names)) return true;
 422  
 423      // we must match one "not_name" rules to be ko
 424      $one_not_name_rule = false;
 425      foreach ($this->names as $args)
 426      {
 427        list($not, $regex) = $args;
 428        if ($not)
 429        {
 430          $one_not_name_rule = true;
 431          if (preg_match($regex, $entry))
 432          {
 433            return false;
 434          }
 435        }
 436      }
 437  
 438      $one_name_rule = false;
 439      // we must match one "name" rules to be ok
 440      foreach ($this->names as $args)
 441      {
 442        list($not, $regex) = $args;
 443        if (!$not)
 444        {
 445          $one_name_rule = true;
 446          if (preg_match($regex, $entry))
 447          {
 448            return true;
 449          }
 450        }
 451      }
 452  
 453      if ($one_not_name_rule && $one_name_rule)
 454      {
 455        return false;
 456      }
 457      else if ($one_not_name_rule)
 458      {
 459        return true;
 460      }
 461      else if ($one_name_rule)
 462      {
 463        return false;
 464      }
 465      else
 466      {
 467        return true;
 468      }
 469    }
 470  
 471    private function size_ok($dir, $entry)
 472    {
 473      if (!count($this->sizes)) return true;
 474  
 475      if (!is_file($dir.DIRECTORY_SEPARATOR.$entry)) return true;
 476  
 477      $filesize = filesize($dir.DIRECTORY_SEPARATOR.$entry);
 478      foreach ($this->sizes as $number_compare)
 479      {
 480        if (!$number_compare->test($filesize)) return false;
 481      }
 482  
 483      return true;
 484    }
 485  
 486    private function is_pruned($dir, $entry)
 487    {
 488      if (!count($this->prunes)) return false;
 489  
 490      foreach ($this->prunes as $args)
 491      {
 492        $regex = $args[1];
 493        if (preg_match($regex, $entry)) return true;
 494      }
 495  
 496      return false;
 497    }
 498  
 499    private function is_discarded($dir, $entry)
 500    {
 501      if (!count($this->discards)) return false;
 502  
 503      foreach ($this->discards as $args)
 504      {
 505        $regex = $args[1];
 506        if (preg_match($regex, $entry)) return true;
 507      }
 508  
 509      return false;
 510    }
 511  
 512    private function exec_ok($dir, $entry)
 513    {
 514      if (!count($this->execs)) return true;
 515  
 516      foreach ($this->execs as $exec)
 517      {
 518        if (!call_user_func_array($exec, array($dir, $entry))) return false;
 519      }
 520  
 521      return true;
 522    }
 523  
 524    public static function isPathAbsolute($path)
 525    {
 526      if ($path{0} == '/' || $path{0} == '\\' ||
 527          (strlen($path) > 3 && ctype_alpha($path{0}) &&
 528           $path{1} == ':' &&
 529           ($path{2} == '\\' || $path{2} == '/')
 530          )
 531         )
 532      {
 533        return true;
 534      }
 535  
 536      return false;
 537    }
 538  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7