This class implements an Ant-like version of PHP's glob() function. The
wildcard "*" matches any number of characters except directory separators.
The double wildcard "**" matches any number of characters, including
directory separators.
Use {@link glob()} to glob the filesystem for paths:
php
foreach (Glob::glob('/project/**.twig') as $path) {
do something...
}
Use {@link match()} to match a file path against a glob:
php
if (Glob::match('/project/views/index.html.twig', '/project/**.twig')) {
path matches
}
You can also filter an array of paths for all paths that match your glob with
{@link filter()}:
php
$filteredPaths = Glob::filter($paths, '/project/**.twig');
Internally, the methods described above convert the glob into a regular
expression that is then matched against the matched paths. If you need to
match many paths against the same glob, you should convert the glob manually
and use {@link preg_match()} to test the paths:
php
$staticPrefix = Glob::getStaticPrefix('/project/**.twig');
$regEx = Glob::toRegEx('/project/**.twig');
if (0 !== strpos($path, $staticPrefix)) {
no match
}
if (!preg_match($regEx, $path)) {
no match
}
The method {@link getStaticPrefix()} returns the part of the glob up to the
first wildcard "*". You should always test whether a path has this prefix
before calling the much more expensive {@link preg_match()}.
/** * Creates a new iterator. * * @param string $glob The glob pattern. * @param int $flags A bitwise combination of the flag constants in * {@link Glob}. */ public function __construct($glob, $flags = 0) { $basePath = Glob::getBasePath($glob, $flags); if (!Glob::isDynamic($glob) && file_exists($glob)) { // If the glob is a file path, return that path $innerIterator = new ArrayIterator(array($glob)); } elseif (is_dir($basePath)) { // Use the system's much more efficient glob() function where we can if (false === strpos($glob, '/**/') && false === strpos($glob, '://') && ('\\' !== DIRECTORY_SEPARATOR || false === strpos($glob, '[^'))) { $results = glob($glob, GLOB_BRACE); // $results may be empty or false if $glob is invalid if (empty($results)) { // Parse glob and provoke errors if invalid Glob::toRegEx($glob); // Otherwise return empty result set $innerIterator = new EmptyIterator(); } else { $innerIterator = new ArrayIterator($results); } } else { // Otherwise scan the glob's base directory for matches $innerIterator = new GlobFilterIterator($glob, new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basePath, RecursiveDirectoryIterator::CURRENT_AS_PATHNAME | RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST), GlobFilterIterator::FILTER_VALUE, $flags); } } else { // If the glob's base directory does not exist, return nothing $innerIterator = new EmptyIterator(); } parent::__construct($innerIterator); }
private function actionForGlob($action, $rootDirectory, $globPattern) { $matches = Glob::glob($globPattern); return array_reduce($matches, function ($acc, $file) use($action, $rootDirectory) { $acc[$file] = $this->strategy($action, $this->toAssetPath($file, $rootDirectory)); return $acc; }, []); }
public function testIterationForGlob() { $glob = '/fixtures/**/*.css'; $basePath = Glob::getBasePath($glob); $it = new RecursiveDirectoryIterator($this->filesystem, $basePath, RecursiveDirectoryIterator::KEY_FOR_GLOB); $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST); $it = new GlobFilterIterator($glob, $it, GlobFilterIterator::FILTER_KEY | GlobFilterIterator::KEY_AS_KEY); $expected = ['fixtures/base.css', 'fixtures/css/old/old_style.css', 'fixtures/css/reset.css', 'fixtures/css/style.css']; $this->assertIterator($expected, $it); $this->assertIteratorInForeach($expected, $it); }
private function generateUrlForBinding(ResourceBinding $binding, $repositoryPath) { $bindingPath = Glob::getStaticPrefix($binding->getQuery()); $webBasePath = trim($binding->getParameterValue(AssetPlugin::PATH_PARAMETER), '/'); $webPath = substr_replace($repositoryPath, $webBasePath, 0, strlen($bindingPath)); $targetName = $binding->getParameterValue(AssetPlugin::TARGET_PARAMETER); if (!$this->targets->contains($targetName)) { throw new CannotGenerateUrlException(sprintf('The target "%s" mapped for path "%s" does not exist.', $targetName, $repositoryPath)); } $target = $this->targets->get($targetName); return sprintf($target->getUrlFormat(), ltrim($webPath, '/')); }
/** * Handles the "url" command. * * @param Args $args The console arguments. * @param IO $io The I/O. * * @return int The status code. */ public function handle(Args $args, IO $io) { foreach ($args->getArgument('path') as $path) { if (!Glob::isDynamic($path)) { $this->printUrl($path, $io); continue; } foreach ($this->repo->find($path) as $resource) { $this->printUrl($resource->getPath(), $io); } } return 0; }
/** * Creates the installation request. * * @param ResourceInstaller $installer The used resource installer. * @param InstallerDescriptor $installerDescriptor The descriptor of the * resource installer. * @param ResourceCollection $resources The resources to install. * @param AssetMapping $mapping The asset mapping. * @param Server $server The asset server. * @param string $rootDir The project's root directory. */ public function __construct(ResourceInstaller $installer, InstallerDescriptor $installerDescriptor, ResourceCollection $resources, AssetMapping $mapping, Server $server, $rootDir) { $glob = $mapping->getGlob(); $parameterValues = $server->getParameterValues(); $this->validateParameterValues($parameterValues, $installerDescriptor); $this->installer = $installer; $this->installerDescriptor = $installerDescriptor; $this->resources = $resources; $this->mapping = $mapping; $this->server = $server; $this->rootDir = $rootDir; $this->basePath = Glob::isDynamic($glob) ? Glob::getBasePath($glob) : $glob; $this->parameterValues = array_replace($installerDescriptor->getParameterValues(), $parameterValues); }
public function def($glob = 'src/**.php') { $buildOk = true; echo "Linting {$glob}\n"; $files = Glob::glob(Path::makeAbsolute($glob, getcwd())); foreach ($files as $file) { $output = ''; $returnValue = $this->runCommandSilent('php', ['-l', $file], $output); if ($returnValue) { echo "Linting error: {$output}\n"; $buildOk = false; } } return $buildOk; }
static function matchesGlobs($basePath, $path, $globArr) { foreach ($globArr as $glob) { if ($glob[0] == '/') { if (Glob::match($path, $glob)) { return true; } } else { if (Glob::match($path, $basePath . "/" . $glob)) { return true; } } } return false; }
/** * Creates a new iterator. * * @param string $glob The glob pattern. * @param int $flags A bitwise combination of the flag constants in * {@link Glob}. */ public function __construct($glob, $flags = 0) { $basePath = Glob::getBasePath($glob); if (!Glob::isDynamic($glob) && file_exists($glob)) { // If the glob is a file path, return that path $innerIterator = new ArrayIterator(array($glob)); } elseif (is_dir($basePath)) { // Otherwise scan the glob's base directory for matches $innerIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basePath, RecursiveDirectoryIterator::CURRENT_AS_PATHNAME | RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST); } else { // If the glob's base directory does not exist, return nothing $innerIterator = new EmptyIterator(); } parent::__construct($glob, $innerIterator, self::FILTER_VALUE, $flags); }
/** * Constructor. * * @param FilesystemInterface $filesystem The filesystem to search * @param string $glob The glob pattern * @param int $flags A bitwise combination of the flag constants in {@see Glob} */ public function __construct(FilesystemInterface $filesystem, $glob, $flags = 0) { // Glob code requires absolute paths, so prefix path // with leading slash, but not before mount point if (strpos($glob, '://') > 0) { $glob = str_replace('://', ':///', $glob); } else { $glob = '/' . ltrim($glob, '/'); } if (!Glob::isDynamic($glob)) { // If the glob is a file path, return that path. $innerIterator = new \ArrayIterator([$glob => $filesystem->get($glob)]); } else { $basePath = Glob::getBasePath($glob); $innerIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($filesystem, $basePath, RecursiveDirectoryIterator::KEY_FOR_GLOB), RecursiveIteratorIterator::SELF_FIRST); } parent::__construct($glob, $innerIterator, static::FILTER_KEY, $flags); }
/** * Creates a new iterator. * * @param string $glob The canonical glob. * @param Iterator $innerIterator The filtered iterator. * @param int $mode A bitwise combination of the mode constants. * @param int $flags A bitwise combination of the flag constants * in {@link Glob}. */ public function __construct($glob, Iterator $innerIterator, $mode = self::FILTER_VALUE, $flags = 0) { parent::__construct(Glob::toRegEx($glob, $flags), Glob::getStaticPrefix($glob, $flags), $innerIterator, $mode); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage *.css */ public function testFilterFailsIfNotAbsolute() { Glob::filter(array('/foo/bar.css'), '*.css'); }
public function try_file_filter() { if (!check_ajax_referer('my-wp-backup-fileFilter', 'nonce')) { wp_die(esc_html__('Nope! Security check failed!', 'my-wp-backup')); } if (!isset($_POST['filters'])) { // input var okay wp_die(); } $filters = array_map('sanitize_text_field', preg_split("/\r\n|\n|\r/", $_POST['filters'])); //input var okay; $excluded = array(); /** * @param \SplFileInfo $file * @return bool True if you need to recurse or if the item is acceptable */ $filter = function ($file) use($filters, &$excluded) { $filePath = $file->getPathname(); $relativePath = substr($filePath, strlen(MyWPBackup::$info['root_dir'])); if ($file->isDir()) { $relativePath .= '/'; } foreach ($filters as $exclude) { if (Glob::match($filePath, Path::makeAbsolute($exclude, MyWPBackup::$info['root_dir']))) { array_push($excluded, $relativePath); return false; } } return true; }; $files = new \RecursiveIteratorIterator(new RecursiveCallbackFilterIterator(new \RecursiveDirectoryIterator(MyWPBackup::$info['root_dir'], \RecursiveDirectoryIterator::SKIP_DOTS), $filter)); iterator_to_array($files); wp_send_json($excluded); }
/** * Execute this builder. * * @param ServerRequestInterface $request * @param ResponseInterface $response * @param callable $next * * @return ResponseInterface */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) { if (Glob::match($request->getUri()->getPath(), $this->uriPattern)) { $runner = new Runner(array_merge($this->queue, [$this->endPoint])); $response = $runner($request, $response->withStatus(200)); if ($response->getStatusCode() === 200) { return $response; } } return $next($request, $response); }
/** * Returns whether a resource path matches a query. * * @param string $resourcePath The resource path. * @param string $query The resource query of a binding. * * @return bool Returns `true` if the resource path matches the query. */ protected function resourcePathMatchesQuery($resourcePath, $query) { if (false !== strpos($query, '*')) { return Glob::match($resourcePath, $query); } return $query === $resourcePath || Path::isBasePath($query, $resourcePath); }
/** * {@inheritdoc} */ public function contains($query, $language = 'glob') { $this->failUnlessGlob($language); $query = $this->sanitizePath($query); if (Glob::isDynamic($query)) { $iterator = $this->getGlobIterator($query); $iterator->rewind(); return $iterator->valid(); } return isset($this->resources[$query]); }
/** * Constructor. * * {@inheritdoc} */ public function __construct($pattern, $uriPattern = '/**/*') { parent::__construct($pattern, $uriPattern); $this->pipe(Middleware::basePath(Glob::getBasePath($this->uriPattern))); $this->endPoint(Middleware::readResponse(Glob::getBasePath($this->pattern))); }
/** * @param array $previous_files * * @return \Iterator */ public function do_files(array $previous_files) { $this->log(__('Comparing files...', 'my-wp-backup'), 'debug'); $excludes = array(); foreach ($this['file_filters'] as $exclude) { $exclude = Path::makeAbsolute($exclude, MyWPBackup::$info['root_dir']); array_push($excludes, Glob::toRegEx($exclude)); } $filtered =& $this->files['filtered']; $unchanged =& $this->files['unchanged']; $overwritten =& $this->files['overwritten']; $exclude_uploads = '1' !== $this['backup_uploads']; $wp_upload_dir = wp_upload_dir(); $uploads_dir = $wp_upload_dir['basedir']; /** * @param \SplFileInfo $file * @return bool True if you need to recurse or if the item is acceptable */ $filter = function ($file) use($excludes, $uploads_dir, $exclude_uploads, $previous_files, &$filtered, &$unchanged, &$overwritten) { $filePath = $file->getPathname(); $relativePath = substr($filePath, strlen(MyWPBackup::$info['root_dir'])); if ('.my-wp-backup' === $relativePath) { return false; } // Exclude backup directory. if (false !== strpos($filePath, MyWPBackup::$info['backup_dir'])) { $filtered[$relativePath] = true; return false; } if ($exclude_uploads && false !== strpos($filePath, $uploads_dir)) { $filtered[$relativePath] = true; return false; } foreach ($excludes as $exclude) { if (preg_match($exclude, $filePath)) { $filtered[$relativePath] = true; return false; } } if (isset($previous_files[$relativePath])) { if (hash_file('crc32b', $file) === $previous_files[$relativePath]) { $unchanged[$relativePath] = true; return false; } else { $overwritten[$relativePath] = true; return true; } } return true; }; if ('1' === $this['backup_files']) { $base_iterator = new \RecursiveDirectoryIterator(MyWPBackup::$info['root_dir'], \RecursiveDirectoryIterator::SKIP_DOTS); } else { $base_iterator = new RecursiveArrayOnlyIterator(array(MyWPBackup::$info['root_dir'] . Database\ExportFile::FILENAME => new \SplFileInfo(MyWPBackup::$info['root_dir'] . Database\ExportFile::FILENAME))); } $this->files['iterator'] = new \RecursiveIteratorIterator(new RecursiveCallbackFilterIterator($base_iterator, $filter)); $this->log(__('Ok.', 'my-wp-backup'), 'debug'); return $this->files; }
/** * @expectedException \InvalidArgumentException */ public function testFilterFailsIfInvalidFlags() { Glob::filter(array(42 => '/foo/bar.css'), '/foo/*.css', Glob::FILTER_KEY | Glob::FILTER_VALUE); }
private function generateUrlForBinding(ResourceBinding $binding, $repositoryPath) { $serverName = $binding->getParameterValue(self::SERVER_PARAMETER); if (!isset($this->urlFormats[$serverName])) { throw new CannotGenerateUrlException(sprintf('The server "%s" mapped for path "%s" does not exist.', $serverName, $repositoryPath)); } $repoBasePath = Glob::getStaticPrefix($binding->getQuery()); $serverBasePath = trim($binding->getParameterValue(self::PATH_PARAMETER), '/'); // The server path is generated by replacing the base repository path // (= the path of the binding) by the stored server base path in the // repository path of the resource. // // Example: // // resource path: /acme/blog/public/css/style.css // binding path: /acme/blog/public{,/**/*} // repo base path: /acme/blog/public // server base path: /blog // // final server path: /blog/css/style.css $serverPath = substr_replace($repositoryPath, $serverBasePath, 0, strlen($repoBasePath)); // The server path is inserted into the "%s" parameter of the URL format return sprintf($this->urlFormats[$serverName], ltrim($serverPath, '/')); }
/** * {@inheritdoc} */ protected function getReferencesForGlob($glob, $flags = 0) { if (!Glob::isDynamic($glob)) { return $this->getReferencesForPath($glob); } return $this->getReferencesForRegex(Glob::getStaticPrefix($glob), Glob::toRegEx($glob), $flags); }
/** * Exclude the given path? * TODO: extract (to trait?). * * @param $path * @param $globArray * * @return bool */ protected function exclude($path, $globArray = []) { $path = str_replace(["\n", "\r", "\t"], '', $path); if (!is_array($globArray)) { return false; } foreach ($globArray as $pattern) { if (Glob::match('/' . $path, Path::makeAbsolute($pattern, '/'))) { return true; } } return false; }