[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/finder/Adapter/ -> AbstractFindAdapter.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\Finder\Adapter;
  13  
  14  @trigger_error('The '.__NAMESPACE__.'\AbstractFindAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
  15  
  16  use Symfony\Component\Finder\Comparator\DateComparator;
  17  use Symfony\Component\Finder\Comparator\NumberComparator;
  18  use Symfony\Component\Finder\Exception\AccessDeniedException;
  19  use Symfony\Component\Finder\Expression\Expression;
  20  use Symfony\Component\Finder\Iterator;
  21  use Symfony\Component\Finder\Shell\Command;
  22  use Symfony\Component\Finder\Shell\Shell;
  23  
  24  /**
  25   * Shell engine implementation using GNU find command.
  26   *
  27   * @author Jean-Fran├žois Simon <contact@jfsimon.fr>
  28   *
  29   * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
  30   */
  31  abstract class AbstractFindAdapter extends AbstractAdapter
  32  {
  33      protected $shell;
  34  
  35      public function __construct()
  36      {
  37          $this->shell = new Shell();
  38      }
  39  
  40      /**
  41       * {@inheritdoc}
  42       */
  43      public function searchInDirectory($dir)
  44      {
  45          // having "/../" in path make find fail
  46          $dir = realpath($dir);
  47  
  48          // searching directories containing or not containing strings leads to no result
  49          if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
  50              return new Iterator\FilePathsIterator(array(), $dir);
  51          }
  52  
  53          $command = Command::create();
  54          $find = $this->buildFindCommand($command, $dir);
  55  
  56          if ($this->followLinks) {
  57              $find->add('-follow');
  58          }
  59  
  60          $find->add('-mindepth')->add($this->minDepth + 1);
  61  
  62          if (PHP_INT_MAX !== $this->maxDepth) {
  63              $find->add('-maxdepth')->add($this->maxDepth + 1);
  64          }
  65  
  66          if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
  67              $find->add('-type d');
  68          } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
  69              $find->add('-type f');
  70          }
  71  
  72          $this->buildNamesFiltering($find, $this->names);
  73          $this->buildNamesFiltering($find, $this->notNames, true);
  74          $this->buildPathsFiltering($find, $dir, $this->paths);
  75          $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
  76          $this->buildSizesFiltering($find, $this->sizes);
  77          $this->buildDatesFiltering($find, $this->dates);
  78  
  79          $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
  80          $useSort = \is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
  81  
  82          if ($useGrep && ($this->contains || $this->notContains)) {
  83              $grep = $command->ins('grep');
  84              $this->buildContentFiltering($grep, $this->contains);
  85              $this->buildContentFiltering($grep, $this->notContains, true);
  86          }
  87  
  88          if ($useSort) {
  89              $this->buildSorting($command, $this->sort);
  90          }
  91  
  92          $command->setErrorHandler(
  93              $this->ignoreUnreadableDirs
  94                  // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
  95                  ? function ($stderr) { }
  96                  : function ($stderr) { throw new AccessDeniedException($stderr); }
  97          );
  98  
  99          $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
 100          $iterator = new Iterator\FilePathsIterator($paths, $dir);
 101  
 102          if ($this->exclude) {
 103              $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
 104          }
 105  
 106          if (!$useGrep && ($this->contains || $this->notContains)) {
 107              $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
 108          }
 109  
 110          if ($this->filters) {
 111              $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
 112          }
 113  
 114          if (!$useSort && $this->sort) {
 115              $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
 116              $iterator = $iteratorAggregate->getIterator();
 117          }
 118  
 119          return $iterator;
 120      }
 121  
 122      /**
 123       * {@inheritdoc}
 124       */
 125      protected function canBeUsed()
 126      {
 127          return $this->shell->testCommand('find');
 128      }
 129  
 130      /**
 131       * @param Command $command
 132       * @param string  $dir
 133       *
 134       * @return Command
 135       */
 136      protected function buildFindCommand(Command $command, $dir)
 137      {
 138          return $command
 139              ->ins('find')
 140              ->add('find ')
 141              ->arg($dir)
 142              ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
 143      }
 144  
 145      /**
 146       * @param Command  $command
 147       * @param string[] $names
 148       * @param bool     $not
 149       */
 150      private function buildNamesFiltering(Command $command, array $names, $not = false)
 151      {
 152          if (0 === \count($names)) {
 153              return;
 154          }
 155  
 156          $command->add($not ? '-not' : null)->cmd('(');
 157  
 158          foreach ($names as $i => $name) {
 159              $expr = Expression::create($name);
 160  
 161              // Find does not support expandable globs ("*.{a,b}" syntax).
 162              if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
 163                  $expr = Expression::create($expr->getGlob()->toRegex(false));
 164              }
 165  
 166              // Fixes 'not search' and 'full path matching' regex problems.
 167              // - Jokers '.' are replaced by [^/].
 168              // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
 169              if ($expr->isRegex()) {
 170                  $regex = $expr->getRegex();
 171                  $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
 172                      ->setStartFlag(false)
 173                      ->setStartJoker(true)
 174                      ->replaceJokers('[^/]');
 175                  if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
 176                      $regex->setEndJoker(false)->append('[^/]*');
 177                  }
 178              }
 179  
 180              $command
 181                  ->add($i > 0 ? '-or' : null)
 182                  ->add($expr->isRegex()
 183                      ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
 184                      : ($expr->isCaseSensitive() ? '-name' : '-iname')
 185                  )
 186                  ->arg($expr->renderPattern());
 187          }
 188  
 189          $command->cmd(')');
 190      }
 191  
 192      /**
 193       * @param Command  $command
 194       * @param string   $dir
 195       * @param string[] $paths
 196       * @param bool     $not
 197       */
 198      private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
 199      {
 200          if (0 === \count($paths)) {
 201              return;
 202          }
 203  
 204          $command->add($not ? '-not' : null)->cmd('(');
 205  
 206          foreach ($paths as $i => $path) {
 207              $expr = Expression::create($path);
 208  
 209              // Find does not support expandable globs ("*.{a,b}" syntax).
 210              if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
 211                  $expr = Expression::create($expr->getGlob()->toRegex(false));
 212              }
 213  
 214              // Fixes 'not search' regex problems.
 215              if ($expr->isRegex()) {
 216                  $regex = $expr->getRegex();
 217                  $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).\DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
 218              } else {
 219                  $expr->prepend('*')->append('*');
 220              }
 221  
 222              $command
 223                  ->add($i > 0 ? '-or' : null)
 224                  ->add($expr->isRegex()
 225                      ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
 226                      : ($expr->isCaseSensitive() ? '-path' : '-ipath')
 227                  )
 228                  ->arg($expr->renderPattern());
 229          }
 230  
 231          $command->cmd(')');
 232      }
 233  
 234      /**
 235       * @param Command            $command
 236       * @param NumberComparator[] $sizes
 237       */
 238      private function buildSizesFiltering(Command $command, array $sizes)
 239      {
 240          foreach ($sizes as $i => $size) {
 241              $command->add($i > 0 ? '-and' : null);
 242  
 243              switch ($size->getOperator()) {
 244                  case '<=':
 245                      $command->add('-size -'.($size->getTarget() + 1).'c');
 246                      break;
 247                  case '>=':
 248                      $command->add('-size +'.($size->getTarget() - 1).'c');
 249                      break;
 250                  case '>':
 251                      $command->add('-size +'.$size->getTarget().'c');
 252                      break;
 253                  case '!=':
 254                      $command->add('-size -'.$size->getTarget().'c');
 255                      $command->add('-size +'.$size->getTarget().'c');
 256                      break;
 257                  case '<':
 258                  default:
 259                      $command->add('-size -'.$size->getTarget().'c');
 260              }
 261          }
 262      }
 263  
 264      /**
 265       * @param Command          $command
 266       * @param DateComparator[] $dates
 267       */
 268      private function buildDatesFiltering(Command $command, array $dates)
 269      {
 270          foreach ($dates as $i => $date) {
 271              $command->add($i > 0 ? '-and' : null);
 272  
 273              $mins = (int) round((time() - $date->getTarget()) / 60);
 274  
 275              if (0 > $mins) {
 276                  // mtime is in the future
 277                  $command->add(' -mmin -0');
 278                  // we will have no result so we don't need to continue
 279                  return;
 280              }
 281  
 282              switch ($date->getOperator()) {
 283                  case '<=':
 284                      $command->add('-mmin +'.($mins - 1));
 285                      break;
 286                  case '>=':
 287                      $command->add('-mmin -'.($mins + 1));
 288                      break;
 289                  case '>':
 290                      $command->add('-mmin -'.$mins);
 291                      break;
 292                  case '!=':
 293                      $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
 294                      break;
 295                  case '<':
 296                  default:
 297                      $command->add('-mmin +'.$mins);
 298              }
 299          }
 300      }
 301  
 302      /**
 303       * @param Command $command
 304       * @param string  $sort
 305       *
 306       * @throws \InvalidArgumentException
 307       */
 308      private function buildSorting(Command $command, $sort)
 309      {
 310          $this->buildFormatSorting($command, $sort);
 311      }
 312  
 313      /**
 314       * @param Command $command
 315       * @param string  $sort
 316       */
 317      abstract protected function buildFormatSorting(Command $command, $sort);
 318  
 319      /**
 320       * @param Command $command
 321       * @param array   $contains
 322       * @param bool    $not
 323       */
 324      abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
 325  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1