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