Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

AbstractFindAdapter.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 10.63 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Finder\Adapter;
 013   
 014  @trigger_error('The '.__NAMESPACE__.'\AbstractFindAdapter class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
 015   
 016  use Symfony\Component\Finder\Exception\AccessDeniedException;
 017  use Symfony\Component\Finder\Iterator;
 018  use Symfony\Component\Finder\Shell\Shell;
 019  use Symfony\Component\Finder\Expression\Expression;
 020  use Symfony\Component\Finder\Shell\Command;
 021  use Symfony\Component\Finder\Comparator\NumberComparator;
 022  use Symfony\Component\Finder\Comparator\DateComparator;
 023   
 024  /**
 025   * Shell engine implementation using GNU find command.
 026   *
 027   * @author Jean-François Simon <contact@jfsimon.fr>
 028   *
 029   * @deprecated since 2.8, to be removed in 3.0. Use Finder instead.
 030   */
 031  abstract class AbstractFindAdapter extends AbstractAdapter
 032  {
 033      /**
 034       * @var Shell
 035       */
 036      protected $shell;
 037   
 038      /**
 039       * Constructor.
 040       */
 041      public function __construct()
 042      {
 043          $this->shell = new Shell();
 044      }
 045   
 046      /**
 047       * {@inheritdoc}
 048       */
 049      public function searchInDirectory($dir)
 050      {
 051          // having "/../" in path make find fail
 052          $dir = realpath($dir);
 053   
 054          // searching directories containing or not containing strings leads to no result
 055          if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
 056              return new Iterator\FilePathsIterator(array(), $dir);
 057          }
 058   
 059          $command = Command::create();
 060          $find = $this->buildFindCommand($command, $dir);
 061   
 062          if ($this->followLinks) {
 063              $find->add('-follow');
 064          }
 065   
 066          $find->add('-mindepth')->add($this->minDepth + 1);
 067   
 068          if (PHP_INT_MAX !== $this->maxDepth) {
 069              $find->add('-maxdepth')->add($this->maxDepth + 1);
 070          }
 071   
 072          if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
 073              $find->add('-type d');
 074          } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
 075              $find->add('-type f');
 076          }
 077   
 078          $this->buildNamesFiltering($find, $this->names);
 079          $this->buildNamesFiltering($find, $this->notNames, true);
 080          $this->buildPathsFiltering($find, $dir, $this->paths);
 081          $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
 082          $this->buildSizesFiltering($find, $this->sizes);
 083          $this->buildDatesFiltering($find, $this->dates);
 084   
 085          $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
 086          $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
 087   
 088          if ($useGrep && ($this->contains || $this->notContains)) {
 089              $grep = $command->ins('grep');
 090              $this->buildContentFiltering($grep, $this->contains);
 091              $this->buildContentFiltering($grep, $this->notContains, true);
 092          }
 093   
 094          if ($useSort) {
 095              $this->buildSorting($command, $this->sort);
 096          }
 097   
 098          $command->setErrorHandler(
 099              $this->ignoreUnreadableDirs
 100                  // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
 101                  ? function ($stderr) { }
 102                  : function ($stderr) { throw new AccessDeniedException($stderr); }
 103          );
 104   
 105          $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
 106          $iterator = new Iterator\FilePathsIterator($paths, $dir);
 107   
 108          if ($this->exclude) {
 109              $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
 110          }
 111   
 112          if (!$useGrep && ($this->contains || $this->notContains)) {
 113              $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
 114          }
 115   
 116          if ($this->filters) {
 117              $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
 118          }
 119   
 120          if (!$useSort && $this->sort) {
 121              $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
 122              $iterator = $iteratorAggregate->getIterator();
 123          }
 124   
 125          return $iterator;
 126      }
 127   
 128      /**
 129       * {@inheritdoc}
 130       */
 131      protected function canBeUsed()
 132      {
 133          return $this->shell->testCommand('find');
 134      }
 135   
 136      /**
 137       * @param Command $command
 138       * @param string  $dir
 139       *
 140       * @return Command
 141       */
 142      protected function buildFindCommand(Command $command, $dir)
 143      {
 144          return $command
 145              ->ins('find')
 146              ->add('find ')
 147              ->arg($dir)
 148              ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
 149      }
 150   
 151      /**
 152       * @param Command  $command
 153       * @param string[] $names
 154       * @param bool     $not
 155       */
 156      private function buildNamesFiltering(Command $command, array $names, $not = false)
 157      {
 158          if (0 === count($names)) {
 159              return;
 160          }
 161   
 162          $command->add($not ? '-not' : null)->cmd('(');
 163   
 164          foreach ($names as $i => $name) {
 165              $expr = Expression::create($name);
 166   
 167              // Find does not support expandable globs ("*.{a,b}" syntax).
 168              if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
 169                  $expr = Expression::create($expr->getGlob()->toRegex(false));
 170              }
 171   
 172              // Fixes 'not search' and 'full path matching' regex problems.
 173              // - Jokers '.' are replaced by [^/].
 174              // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
 175              if ($expr->isRegex()) {
 176                  $regex = $expr->getRegex();
 177                  $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
 178                      ->setStartFlag(false)
 179                      ->setStartJoker(true)
 180                      ->replaceJokers('[^/]');
 181                  if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
 182                      $regex->setEndJoker(false)->append('[^/]*');
 183                  }
 184              }
 185   
 186              $command
 187                  ->add($i > 0 ? '-or' : null)
 188                  ->add($expr->isRegex()
 189                      ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
 190                      : ($expr->isCaseSensitive() ? '-name' : '-iname')
 191                  )
 192                  ->arg($expr->renderPattern());
 193          }
 194   
 195          $command->cmd(')');
 196      }
 197   
 198      /**
 199       * @param Command  $command
 200       * @param string   $dir
 201       * @param string[] $paths
 202       * @param bool     $not
 203       */
 204      private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
 205      {
 206          if (0 === count($paths)) {
 207              return;
 208          }
 209   
 210          $command->add($not ? '-not' : null)->cmd('(');
 211   
 212          foreach ($paths as $i => $path) {
 213              $expr = Expression::create($path);
 214   
 215              // Find does not support expandable globs ("*.{a,b}" syntax).
 216              if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
 217                  $expr = Expression::create($expr->getGlob()->toRegex(false));
 218              }
 219   
 220              // Fixes 'not search' regex problems.
 221              if ($expr->isRegex()) {
 222                  $regex = $expr->getRegex();
 223                  $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
 224              } else {
 225                  $expr->prepend('*')->append('*');
 226              }
 227   
 228              $command
 229                  ->add($i > 0 ? '-or' : null)
 230                  ->add($expr->isRegex()
 231                      ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
 232                      : ($expr->isCaseSensitive() ? '-path' : '-ipath')
 233                  )
 234                  ->arg($expr->renderPattern());
 235          }
 236   
 237          $command->cmd(')');
 238      }
 239   
 240      /**
 241       * @param Command            $command
 242       * @param NumberComparator[] $sizes
 243       */
 244      private function buildSizesFiltering(Command $command, array $sizes)
 245      {
 246          foreach ($sizes as $i => $size) {
 247              $command->add($i > 0 ? '-and' : null);
 248   
 249              switch ($size->getOperator()) {
 250                  case '<=':
 251                      $command->add('-size -'.($size->getTarget() + 1).'c');
 252                      break;
 253                  case '>=':
 254                      $command->add('-size +'.($size->getTarget() - 1).'c');
 255                      break;
 256                  case '>':
 257                      $command->add('-size +'.$size->getTarget().'c');
 258                      break;
 259                  case '!=':
 260                      $command->add('-size -'.$size->getTarget().'c');
 261                      $command->add('-size +'.$size->getTarget().'c');
 262                      break;
 263                  case '<':
 264                  default:
 265                      $command->add('-size -'.$size->getTarget().'c');
 266              }
 267          }
 268      }
 269   
 270      /**
 271       * @param Command          $command
 272       * @param DateComparator[] $dates
 273       */
 274      private function buildDatesFiltering(Command $command, array $dates)
 275      {
 276          foreach ($dates as $i => $date) {
 277              $command->add($i > 0 ? '-and' : null);
 278   
 279              $mins = (int) round((time() - $date->getTarget()) / 60);
 280   
 281              if (0 > $mins) {
 282                  // mtime is in the future
 283                  $command->add(' -mmin -0');
 284                  // we will have no result so we don't need to continue
 285                  return;
 286              }
 287   
 288              switch ($date->getOperator()) {
 289                  case '<=':
 290                      $command->add('-mmin +'.($mins - 1));
 291                      break;
 292                  case '>=':
 293                      $command->add('-mmin -'.($mins + 1));
 294                      break;
 295                  case '>':
 296                      $command->add('-mmin -'.$mins);
 297                      break;
 298                  case '!=':
 299                      $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
 300                      break;
 301                  case '<':
 302                  default:
 303                      $command->add('-mmin +'.$mins);
 304              }
 305          }
 306      }
 307   
 308      /**
 309       * @param Command $command
 310       * @param string  $sort
 311       *
 312       * @throws \InvalidArgumentException
 313       */
 314      private function buildSorting(Command $command, $sort)
 315      {
 316          $this->buildFormatSorting($command, $sort);
 317      }
 318   
 319      /**
 320       * @param Command $command
 321       * @param string  $sort
 322       */
 323      abstract protected function buildFormatSorting(Command $command, $sort);
 324   
 325      /**
 326       * @param Command $command
 327       * @param array   $contains
 328       * @param bool    $not
 329       */
 330      abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
 331  }
 332