protected function toRegex($str) { if (preg_match('/^([^a-zA-Z0-9\\\\]).+?\\1[ims]?$/', $str)) { return $str; } return Glob::toRegex($str); }
public function testGlobToRegexDelimiters() { $this->assertEquals('#^(?=[^\\.])\\#$#', Glob::toRegex('#')); $this->assertEquals('#^\\.[^/]*$#', Glob::toRegex('.*')); $this->assertEquals('^\\.[^/]*$', Glob::toRegex('.*', true, true, '')); $this->assertEquals('/^\\.[^/]*$/', Glob::toRegex('.*', true, true, '/')); }
public function addFromTags($filter = null) { $tags = array_filter(explode("\n", $this->execute(array('tag')))); $versions = array_filter($tags, $this->filter); if (null !== $filter) { if (!$filter instanceof \Closure) { $regexes = array(); foreach ((array) $filter as $f) { $regexes[] = Glob::toRegex($f); } $filter = function ($version) use($regexes) { foreach ($regexes as $regex) { if (preg_match($regex, $version)) { return true; } } return false; }; } $versions = array_filter($versions, $filter); } usort($versions, $this->sorter); foreach ($versions as $version) { $version = new Version($version); $version->setFrozen(true); $this->add($version); } return $this; }
/** * @dataProvider getToRegexData */ public function testToRegex($glob, $match, $noMatch) { foreach ($match as $m) { $this->assertRegExp(Glob::toRegex($glob), $m, '::toRegex() converts a glob to a regexp'); } foreach ($noMatch as $m) { $this->assertNotRegExp(Glob::toRegex($glob), $m, '::toRegex() converts a glob to a regexp'); } }
/** @inheritdoc */ public function discover($packages) { // This is the array that we will return $this->conflicts = []; // Get a list of packages that have multiple versions, // that "might" have name conflicts. $possibleConflicts = Linq::from($packages)->where(function ($v) { return count($v) > 1; }); foreach ($possibleConflicts as $packageName => $versions) { $psrLoaded = []; $mapLoaded = []; foreach ($versions as $version) { $psrLoaded[$version] = []; $mapLoaded[$version] = []; // Read the composer file $composer = $this->reader->setPackage($packageName)->setVersion($version)->getComposerObject(); // Make sure it defines an autoload section. // If it does not autoload anything then we ignore it. if (!isset($composer['autoload'])) { continue; } // Read in any excludes - getFilesFromMap will filter // out any files matched by these exclude globs. if (isset($composer['autoload']['exclude-from-classmap'])) { $this->excludes = []; $excludes = $composer['autoload']['exclude-from-classmap']; foreach ($excludes as $exclude) { $this->excludes[] = s(Glob::toRegex(s($exclude)->removeLeft('/')->ensureRight('**'), false))->replace('[^/]*[^/]*', '.*?'); } } // Find all autoloaded src files for this version if (isset($composer['autoload']['psr-4'])) { $psrLoaded[$version] = array_merge($psrLoaded[$version], $this->getFilesFromMap($packageName, $version, $composer['autoload']['psr-4'])); } if (isset($composer['autoload']['psr-0'])) { $psrLoaded[$version] = array_merge($psrLoaded[$version], $this->getFilesFromMap($packageName, $version, $composer['autoload']['psr-0'])); } if (isset($composer['autoload']['classmap'])) { $mapLoaded[$version] = array_merge($mapLoaded[$version], $this->getFilesFromMap($packageName, $version, $composer['autoload']['classmap'])); } if (isset($composer['autoload']['files'])) { $mapLoaded[$version] = array_merge($mapLoaded[$version], $this->getFilesFromMap($packageName, $version, $composer['autoload']['files'])); } } // We now know about all files that composer knows about. // Now we will search for any conflicting types, classes|functions // that have the exact same Fully Qualified Name. $this->findPsrConflicts($packageName, $psrLoaded); $this->findMappedConflicts($packageName, $mapLoaded); } return $this->conflicts; }
protected function generatePattern($rule) { $negate = false; $pattern = '#'; if (strlen($rule) && $rule[0] === '!') { $negate = true; $rule = substr($rule, 1); } if (strlen($rule) && $rule[0] === '/') { $pattern .= '^/'; $rule = substr($rule, 1); } elseif (false === strpos($rule, '/') || strlen($rule) - 1 === strpos($rule, '/')) { $pattern .= '/'; } $pattern .= substr(Finder\Glob::toRegex($rule), 2, -2); return array($pattern . '#', $negate, false); }
/** * Lists templates, optionally filtered by $filter. * * @param string $filter * @param boolean $safe * * @return array Sorted and possibly filtered templates */ public function listTemplates($filter = '', $safe) { // No need to list templates in safe mode. if ($safe) { return null; } // Get the active themeconfig $appConfig = $this->app['config']->getConfig(); $themeConfig = $appConfig['theme']; $files = []; // Check: Are the templates for template chooser defined? if (!empty($themeConfig['templateselect'])) { foreach ($themeConfig['templateselect']['templates'] as $templateFile) { if (!empty($templateFile['name']) && !empty($templateFile['filename'])) { $files[$templateFile['filename']] = $templateFile['name']; } } } else { if ($filter) { $name = Glob::toRegex($filter, false, false); } else { $name = '/^[a-zA-Z0-9]\\V+\\.twig$/'; } $finder = new Finder(); $finder->files()->in($this->app['resources']->getPath('templatespath'))->notname('/^_/')->notPath('node_modules')->notPath('bower_components')->notPath('.sass-cache')->depth('<2')->path($name)->sortByName(); foreach ($finder as $file) { $name = $file->getRelativePathname(); $files[$name] = $name; } } return $files; }
/** * @param bool $strictLeadingDot * @param bool $strictWildcardSlash * * @return Regex */ public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true) { $regex = FinderGlob::toRegex($this->pattern, $strictLeadingDot, $strictWildcardSlash, ''); return new Regex($regex); }
/** * Generates an exclude pattern for filter() from a gitignore rule * * @param string $rule An exclude rule in gitignore syntax * * @return array An exclude pattern */ protected function generatePattern($rule) { $negate = false; $pattern = '{'; if (strlen($rule) && $rule[0] === '!') { $negate = true; $rule = substr($rule, 1); } if (strlen($rule) && $rule[0] === '/') { $pattern .= '^/'; $rule = substr($rule, 1); } elseif (strlen($rule) - 1 === strpos($rule, '/')) { $pattern .= '/'; $rule = substr($rule, 0, -1); } elseif (false === strpos($rule, '/')) { $pattern .= '/'; } // remove delimiters as well as caret (^) and dollar sign ($) from the regex $pattern .= substr(Finder\Glob::toRegex($rule), 2, -2) . '(?=$|/)'; return array($pattern . '}', $negate, false); }
/** * Lists templates, optionally filtered by $filter. * * @param string $filter * @param boolean $safe * * @return array Sorted and possibly filtered templates */ public function listTemplates($filter = null, $safe = false) { // No need to list templates in safe mode. if ($safe) { return null; } $files = []; $name = $filter ? Glob::toRegex($filter, false, false) : '/^[a-zA-Z0-9]\\V+\\.twig$/'; $finder = new Finder(); $finder->files()->in($this->app['resources']->getPath('templatespath'))->notname('/^_/')->notPath('node_modules')->notPath('bower_components')->notPath('.sass-cache')->depth('<2')->path($name)->sortByName(); foreach ($finder as $file) { $name = $file->getRelativePathname(); $files[$name] = $name; } // Get the active themeconfig $themeConfig = $this->app['config']->get('theme/templateselect/templates', false); // Check: Have we defined names for any of the matched templates? if ($themeConfig) { foreach ($themeConfig as $templateFile) { if (!empty($templateFile['name']) && !empty($templateFile['filename']) && in_array($templateFile['filename'], $files)) { $files[$templateFile['filename']] = $templateFile['name']; } } } return $files; }
/** * Returns directory contents * * @param string $dir * @param mixed $names * @param mixed $notNames * @param boolean $dirs * @param boolean $files * @param integer $sort * @return array */ public static function readDir($dir, $names = '*', $notNames = false, $dirs = true, $files = true, $sort = SORT_DESC) { $found = array(); $finder = new Finder(); $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); if ($dirs && !$files) { $finder->directories(); } elseif (!$dirs && $files) { $finder->files(); } foreach ((array) $names as $name) { $finder->name($name); } if ($notNames !== false) { $regExps = array(); foreach ((array) $notNames as $notName) { $regExps[] = Glob::toRegex($notName, false, false); } $finder->filter(function (\SplFileInfo $fileinfo) use($dir, $regExps) { $localName = str_replace(array($dir . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), array(NULL, '/'), $fileinfo->getRealpath()); foreach ($regExps as $regExp) { if (preg_match($regExp, $localName)) { return false; } } return true; }); } foreach ($finder->in($dir) as $path) { $found[] = realpath($path->getRealpath()); } return self::sortByDepth($found, $sort); }
public function match($inDir) { $results = []; // Pop out placeholders from given pattern preg_match_all('/<(?P<placeholder>\\w+)>/', $this->pattern, $matches); $placeholders = $matches['placeholder']; // Replace placeholder by a valid string foreach ($placeholders as $placeholder) { $this->pattern = str_replace("<{$placeholder}>", "___{$placeholder}_placeholder___", $this->pattern); } // Transform pattern to regex $regex = Glob::toRegex($this->pattern); $regex = trim($regex, '#'); // Englobe every part of the regex into a matching pattern. // Then build final regex by concatening parts & placeholders. // Be sure to make copy of placeholders. $counter = 0; $parts = preg_split('/___\\w+_placeholder___/', $regex); $placeholderStack = $placeholders; $regex = ''; while ($part = array_shift($parts)) { $counter++; $regex .= "(?P<___part_{$counter}___>{$part})"; if (null !== ($placeholder = array_shift($placeholderStack))) { $regex .= "(?P<{$placeholder}>\\w+)"; } } // Re-add regex delimiters $regex = '#' . $regex . '#'; // Find files $finder = new Finder(); $finder->in($inDir)->path($regex); foreach ($finder->files() as $file) { // Replacing Windows backslashes by linux slashes $relativePathnameSanitized = str_replace("\\", "/", $file->getRelativePathname()); if (!preg_match($regex, $relativePathnameSanitized, $matches)) { // Should not happen, but it better to check continue; } $parts = []; $attributes = []; foreach ($matches as $key => $match) { if (!is_string($key)) { continue; } if (preg_match('/___part_\\d+___/', $key)) { $parts[] = $match; } else { $attributes[$key] = $match; } } $filePattern = ''; $placeholderStack = $placeholders; // make copy of placeholders do { $part = array_shift($parts); $filePattern .= $part; if (null !== ($placeholder = array_shift($placeholderStack))) { $filePattern .= "<{$placeholder}>"; } } while (null !== $part); $results[] = new FileInfo($inDir, new Pattern($filePattern), $attributes); } return $results; }
/** * @param string $string * * @return string */ private function toRegex($string) { return $this->isRegex($string) ? $string : Glob::toRegex($string); }
/** * Generates an exclude pattern for filter() from a hg glob expression * * @param string $line A line from .hgignore in glob mode * * @return array An exclude pattern for filter() */ protected function patternFromGlob($line) { $pattern = '#' . substr(Finder\Glob::toRegex($line), 2, -1) . '#'; $pattern = str_replace('[^/]*', '.*', $pattern); return array($pattern, false, true); }
/** * lists templates, optionally filtered by $filter. * * @param string $filter * * @return array Sorted and possibly filtered templates */ public function listTemplates($filter = "") { // No need to list templates in safe mode. if ($this->safe) { return null; } if ($filter) { $name = Glob::toRegex($filter, false, false); } else { $name = '/^[a-zA-Z0-9]\\V+\\.twig$/'; } $finder = new Finder(); $finder->files()->in($this->app['paths']['templatespath'])->notname('/^_/')->notPath('node_modules')->notPath('bower_components')->notPath('.sass-cache')->depth('<2')->path($name)->sortByName(); $files = array(); foreach ($finder as $file) { $name = $file->getRelativePathname(); $files[$name] = $name; } return $files; }
/** * Action for Add an ignore pattern. * * @param string $pattern The pattern */ public function doAddPattern($pattern) { if (0 === strpos($pattern, '!')) { $searchPattern = substr($pattern, 1); $this->finder->notPath(Glob::toRegex($searchPattern, true, true)); $pathComponents = explode('/', $searchPattern); if (1 < count($pathComponents)) { $parentDirectories = array_slice($pathComponents, 0, -1); $basePath = ''; foreach ($parentDirectories as $dir) { $this->finder->notPath('/\\b(' . preg_quote($basePath . $dir, '/') . ')(?!\\/)\\b/'); $basePath .= $dir . '/'; } } } else { $this->finder->path(Glob::toRegex($pattern, true, true)); } }
/** * Action for Add an ignore pattern. * * @param string $pattern The pattern */ public function doAddPattern($pattern) { if (0 === strpos($pattern, '!')) { $this->finder->notPath(Glob::toRegex(substr($pattern, 1), true, false)); } else { $this->finder->path(Glob::toRegex($pattern, true, false)); } }
public function has($pattern) { if ('*' !== substr($pattern, -1)) { if ('/' === substr($pattern, -1, 1)) { $pattern .= '*'; } } $regex = Glob::toRegex($pattern, false, false); foreach ($this->files as $file) { if (1 === preg_match($regex, $file)) { return true; } } return false; }
/** * Converts glob to regexp. * * PCRE patterns are left unchanged. * Glob strings are transformed with Glob::toRegex(). * * @param string $str * Pattern: glob or regexp * * @return string regexp corresponding to a given glob or regexp */ protected function toRegex($str) { return $this->isRegex($str) ? $str : Glob::toRegex($str); }
public function testGlobToRegexDelimiters() { $this->assertEquals(Glob::toRegex('.*'), '#^\\.[^/]*$#'); $this->assertEquals(Glob::toRegex('.*', true, true, ''), '^\\.[^/]*$'); $this->assertEquals(Glob::toRegex('.*', true, true, '/'), '/^\\.[^/]*$/'); }