3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Stdlib
;
13 * Wrapper for glob with fallback if GLOB_BRACE is not available.
20 const GLOB_MARK
= 0x01;
21 const GLOB_NOSORT
= 0x02;
22 const GLOB_NOCHECK
= 0x04;
23 const GLOB_NOESCAPE
= 0x08;
24 const GLOB_BRACE
= 0x10;
25 const GLOB_ONLYDIR
= 0x20;
26 const GLOB_ERR
= 0x40;
30 * Find pathnames matching a pattern.
32 * @see http://docs.php.net/glob
33 * @param string $pattern
35 * @param bool $forceFallback
37 * @throws Exception\RuntimeException
39 public static function glob($pattern, $flags = 0, $forceFallback = false)
41 if (!defined('GLOB_BRACE') ||
$forceFallback) {
42 return static::fallbackGlob($pattern, $flags);
45 return static::systemGlob($pattern, $flags);
49 * Use the glob function provided by the system.
51 * @param string $pattern
54 * @throws Exception\RuntimeException
56 protected static function systemGlob($pattern, $flags)
60 self
::GLOB_MARK
=> GLOB_MARK
,
61 self
::GLOB_NOSORT
=> GLOB_NOSORT
,
62 self
::GLOB_NOCHECK
=> GLOB_NOCHECK
,
63 self
::GLOB_NOESCAPE
=> GLOB_NOESCAPE
,
64 self
::GLOB_BRACE
=> defined('GLOB_BRACE') ? GLOB_BRACE
: 0,
65 self
::GLOB_ONLYDIR
=> GLOB_ONLYDIR
,
66 self
::GLOB_ERR
=> GLOB_ERR
,
71 foreach ($flagMap as $internalFlag => $globFlag) {
72 if ($flags & $internalFlag) {
73 $globFlags |
= $globFlag;
80 ErrorHandler
::start();
81 $res = glob($pattern, $globFlags);
82 $err = ErrorHandler
::stop();
84 throw new Exception\
RuntimeException("glob('{$pattern}', {$globFlags}) failed", 0, $err);
90 * Expand braces manually, then use the system glob.
92 * @param string $pattern
95 * @throws Exception\RuntimeException
97 protected static function fallbackGlob($pattern, $flags)
99 if (!$flags & self
::GLOB_BRACE
) {
100 return static::systemGlob($pattern, $flags);
103 $flags &= ~self
::GLOB_BRACE
;
104 $length = strlen($pattern);
107 if ($flags & self
::GLOB_NOESCAPE
) {
108 $begin = strpos($pattern, '{');
113 if ($begin === $length) {
116 } elseif ($pattern[$begin] === '\\' && ($begin +
1) < $length) {
118 } elseif ($pattern[$begin] === '{') {
126 if ($begin === false) {
127 return static::systemGlob($pattern, $flags);
130 $next = static::nextBraceSub($pattern, $begin +
1, $flags);
132 if ($next === null) {
133 return static::systemGlob($pattern, $flags);
138 while ($pattern[$rest] !== '}') {
139 $rest = static::nextBraceSub($pattern, $rest +
1, $flags);
141 if ($rest === null) {
142 return static::systemGlob($pattern, $flags);
149 $subPattern = substr($pattern, 0, $begin)
150 . substr($pattern, $p, $next - $p)
151 . substr($pattern, $rest +
1);
153 $result = static::fallbackGlob($subPattern, $flags | self
::GLOB_BRACE
);
156 $paths = array_merge($paths, $result);
159 if ($pattern[$next] === '}') {
164 $next = static::nextBraceSub($pattern, $p, $flags);
167 return array_unique($paths);
171 * Find the end of the sub-pattern in a brace expression.
173 * @param string $pattern
178 protected static function nextBraceSub($pattern, $begin, $flags)
180 $length = strlen($pattern);
184 while ($current < $length) {
185 if (!$flags & self
::GLOB_NOESCAPE
&& $pattern[$current] === '\\') {
186 if (++
$current === $length) {
192 if (($pattern[$current] === '}' && $depth-- === 0) ||
($pattern[$current] === ',' && $depth === 0)) {
194 } elseif ($pattern[$current++
] === '{') {
200 return ($current < $length ?
$current : null);