[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |