예제 #1
0
파일: Finder.php 프로젝트: splot/framework
 /**
  * Expands GLOB resource patterns.
  * 
  * @param  string $resource Resource name.
  * @param  string $type    Type of the resource.
  * @return array
  */
 public function expand($resource, $type)
 {
     list($moduleName, $subDir, $filePattern) = $this->parseResourceName($resource);
     $resourceLocation = $moduleName . ':' . $subDir . ':';
     // read from application dir
     $appDir = rtrim($this->_application->getApplicationDir(), DS) . DS . 'Resources' . DS;
     // if a module name was specified then point to a subfolder with the module name
     if (!empty($moduleName)) {
         // check for module existence in the first place
         if (!$this->_application->hasModule($moduleName)) {
             throw new ResourceNotFoundException('There is no module "' . $moduleName . '" registered, so cannot find its resource.');
         }
         $appDir = $appDir . $moduleName . DS;
     }
     $appDir = $this->buildResourcePath($appDir, $type, $subDir, '');
     $appFiles = FilesystemUtils::glob($appDir . $filePattern, FilesystemUtils::GLOB_ROOTFIRST | GLOB_BRACE);
     $resources = array();
     foreach ($appFiles as $file) {
         $resources[] = $resourceLocation . substr($file, mb_strlen($appDir));
     }
     // now take care of the module dir
     if ($moduleName) {
         $module = $this->_application->getModule($moduleName);
         $moduleDir = rtrim($module->getModuleDir(), DS) . DS . 'Resources' . DS;
         $moduleDir = $this->buildResourcePath($moduleDir, $type, $subDir, '');
         $moduleFiles = FilesystemUtils::glob($moduleDir . $filePattern, GLOB_BRACE);
         foreach ($moduleFiles as $file) {
             $resources[] = $resourceLocation . substr($file, mb_strlen($moduleDir));
         }
     }
     $resources = array_unique($resources);
     return ArrayUtils::sortPaths($resources, true);
 }
예제 #2
0
 public function testSortPaths()
 {
     $paths = array('app.js', 'app.min.js', 'dolor.txt', 'global.js', 'global.min.js', 'ipsum.txt', 'lorem.txt', 'company/bilbo.txt', 'company/dwarves/bifur.txt', 'company/dwarves/bombur.txt', 'company/dwarves/oin.txt', 'company/dwarves/oin.txt', 'company/dwarves/thorin.txt', 'company/wizards/gandalf.txt', 'company/wizards/radagast.txt', 'lipsum/root.js', 'lipsum/dolor/dolor.txt', 'lipsum/dolor/valuptatos.js', 'lipsum/dolor/amet/adipiscit.txt', 'lipsum/dolor/amet/elit.txt', 'lipsum/dolor/amet/lorem.txt', 'newdir/file.txt', 'newdir/dummy/dummy.js', 'newdir/dummy/leaf.txt');
     shuffle($paths);
     $this->assertEquals(array('company/dwarves/bifur.txt', 'company/dwarves/bombur.txt', 'company/dwarves/oin.txt', 'company/dwarves/oin.txt', 'company/dwarves/thorin.txt', 'company/wizards/gandalf.txt', 'company/wizards/radagast.txt', 'company/bilbo.txt', 'lipsum/dolor/amet/adipiscit.txt', 'lipsum/dolor/amet/elit.txt', 'lipsum/dolor/amet/lorem.txt', 'lipsum/dolor/dolor.txt', 'lipsum/dolor/valuptatos.js', 'lipsum/root.js', 'newdir/dummy/dummy.js', 'newdir/dummy/leaf.txt', 'newdir/file.txt', 'app.js', 'app.min.js', 'dolor.txt', 'global.js', 'global.min.js', 'ipsum.txt', 'lorem.txt'), ArrayUtils::sortPaths($paths), 'Failed to sort with child first.');
     shuffle($paths);
     $this->assertEquals(array('app.js', 'app.min.js', 'dolor.txt', 'global.js', 'global.min.js', 'ipsum.txt', 'lorem.txt', 'company/bilbo.txt', 'company/dwarves/bifur.txt', 'company/dwarves/bombur.txt', 'company/dwarves/oin.txt', 'company/dwarves/oin.txt', 'company/dwarves/thorin.txt', 'company/wizards/gandalf.txt', 'company/wizards/radagast.txt', 'lipsum/root.js', 'lipsum/dolor/dolor.txt', 'lipsum/dolor/valuptatos.js', 'lipsum/dolor/amet/adipiscit.txt', 'lipsum/dolor/amet/elit.txt', 'lipsum/dolor/amet/lorem.txt', 'newdir/file.txt', 'newdir/dummy/dummy.js', 'newdir/dummy/leaf.txt'), ArrayUtils::sortPaths($paths, true), 'Failed to sort with root first.');
 }
예제 #3
0
 /**
  * Extended `glob()` functionality that supports double star `**` (globstar) wildcard.
  *
  * PHP's `glob()` implementation doesn't allow for `**` wildcard. In Bash 4 it can be enabled with `globstar` setting.
  *
  * In case the `**` wildcard is not used in the pattern then this method just calls PHP's `glob()`.
  *
  * For full documentation see PHP's [`glob()` documentation](http://php.net/manual/en/function.glob.php).
  *
  * It's worth noting that if you want to find files inside current directory and their subdirectories,
  * then you have to use a `GLOB_BRACE` flag and pattern, e.g.:
  * 
  *     echo \MD\Foundation\Utils\FilesystemUtils::glob('{,** /}*.js', GLOB_BRACE); // note: remove space between * and /
  *     // -> array(
  *     //      'main.js',
  *     //      'dir/script.js',
  *     //      'dir/more/scripts.js'
  *     // );
  *      
  * Implementation of this convention varies between libs in various languages and `MD\Foundation` sticks
  * with what [Bash manual states](http://www.gnu.org/software/bash/manual/bashref.html#Pattern-Matching).
  * More about this is explained in [#2](https://github.com/michaldudek/Foundation/issues/2).
  *
  * This function also supports its own implementation of `GLOB_BRACE` flag on systems that do not support it
  * (e.g. Alpine Linux, popular base for Docker containers). Because it's impossible to detect if that flag was
  * passed or not (as it has `null` or `0` value), on such systems the function assumes that yes, this flag was
  * passed if there are any `{}` braces used in the pattern. This implementation might not be so fast as a system
  * implementation, so use with caution or switch to "fuller" distro.
  *
  * Additionally it provides sorting option to the results, which you can pass along with
  * other flags. Constants `FilesystemUtils::GLOB_ROOTFIRST` and `FilesystemUtils::GLOB_CHILDFIRST`
  * sort the results either as "root first" where files in a directory are listed before directories and
  * subdirectories, or "child first" where subdirectories are listed before files.
  * 
  * @param  string  $pattern The pattern. Supports `**` wildcard.
  * @param  int $flags [optional] `glob()` flags. See `glob()`'s documentation. Default: `0`.
  * @return array|bool
  */
 public static function glob($pattern, $flags = 0)
 {
     // turn off custom flags
     $globFlags = ($flags | static::GLOB_CHILDFIRST | static::GLOB_ROOTFIRST) ^ (static::GLOB_CHILDFIRST | static::GLOB_ROOTFIRST);
     // our custom implementation will be expanding some patterns (namely globstar and braces) so we gather them all
     $patterns = array($pattern);
     // expand GLOB_BRACE if it's not defined on the system (e.g. Alpine Linux)
     // let's assume that it's passed always in such cases (most common usage)
     // and keeping the original pattern will make us safe to detect the desired files with {} in name anyway
     if (!defined('GLOB_BRACE') || !GLOB_BRACE) {
         $patterns = array_merge($patterns, self::globBraceExpand($patterns));
     }
     // expand globstar if added
     if (stripos($pattern, '**') !== false) {
         $patterns = array_merge($patterns, self::globStarExpand($patterns, $globFlags));
     }
     // finally when all patterns expanded, just rerun them and merge results
     $files = array();
     foreach ($patterns as $pat) {
         $files = array_merge($files, glob($pat, $globFlags));
     }
     // fix some paths as they might have gotten double // due to not-perfect pattern expansion
     $files = array_map(function ($file) {
         return str_replace('//', '/', $file);
     }, $files);
     // make sure no repetitions from all the patterns provided
     $files = array_unique($files);
     // sort by root first?
     if ($flags & static::GLOB_ROOTFIRST) {
         $files = ArrayUtils::sortPaths($files, true);
     } else {
         if ($flags & static::GLOB_CHILDFIRST) {
             $files = ArrayUtils::sortPaths($files, false);
         } elseif (!($flags & GLOB_NOSORT)) {
             // default sort order is alphabetically
             sort($files);
         }
     }
     return $files;
 }