PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/zendframework/zendframework/library/Zend/Stdlib/Glob.php

https://bitbucket.org/raulgracia/zendframework2
PHP | 193 lines | 142 code | 14 blank | 37 comment | 16 complexity | 0601a0284b1e974255a1e492b0b51482 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Stdlib;
  10. /**
  11. * Wrapper for glob with fallback if GLOB_BRACE is not available.
  12. */
  13. abstract class Glob
  14. {
  15. /**#@+
  16. * Glob constants.
  17. */
  18. const GLOB_MARK = 0x01;
  19. const GLOB_NOSORT = 0x02;
  20. const GLOB_NOCHECK = 0x04;
  21. const GLOB_NOESCAPE = 0x08;
  22. const GLOB_BRACE = 0x10;
  23. const GLOB_ONLYDIR = 0x20;
  24. const GLOB_ERR = 0x40;
  25. /**#@-*/
  26. /**
  27. * Find pathnames matching a pattern.
  28. *
  29. * @see http://docs.php.net/glob
  30. * @param string $pattern
  31. * @param integer $flags
  32. * @param bool $forceFallback
  33. * @return array|false
  34. */
  35. public static function glob($pattern, $flags, $forceFallback = false)
  36. {
  37. if (!defined('GLOB_BRACE') || $forceFallback) {
  38. return static::fallbackGlob($pattern, $flags);
  39. }
  40. return static::systemGlob($pattern, $flags);
  41. }
  42. /**
  43. * Use the glob function provided by the system.
  44. *
  45. * @param string $pattern
  46. * @param integer $flags
  47. * @return array|false
  48. */
  49. protected static function systemGlob($pattern, $flags)
  50. {
  51. if ($flags) {
  52. $flagMap = array(
  53. self::GLOB_MARK => GLOB_MARK,
  54. self::GLOB_NOSORT => GLOB_NOSORT,
  55. self::GLOB_NOCHECK => GLOB_NOCHECK,
  56. self::GLOB_NOESCAPE => GLOB_NOESCAPE,
  57. self::GLOB_BRACE => GLOB_BRACE,
  58. self::GLOB_ONLYDIR => GLOB_ONLYDIR,
  59. self::GLOB_ERR => GLOB_ERR,
  60. );
  61. $globFlags = 0;
  62. foreach ($flagMap as $internalFlag => $globFlag) {
  63. if ($flags & $internalFlag) {
  64. $globFlags |= $globFlag;
  65. }
  66. }
  67. } else {
  68. $globFlags = 0;
  69. }
  70. return glob($pattern, $globFlags);
  71. }
  72. /**
  73. * Expand braces manually, then use the system glob.
  74. *
  75. * @param string $pattern
  76. * @param integer $flags
  77. * @return array|false
  78. */
  79. protected static function fallbackGlob($pattern, $flags)
  80. {
  81. if (!$flags & self::GLOB_BRACE) {
  82. return static::systemGlob($pattern, $flags);
  83. }
  84. $flags &= ~self::GLOB_BRACE;
  85. $length = strlen($pattern);
  86. $paths = array();
  87. if ($flags & self::GLOB_NOESCAPE) {
  88. $begin = strpos($pattern, '{');
  89. } else {
  90. $begin = 0;
  91. while (true) {
  92. if ($begin === $length) {
  93. $begin = false;
  94. break;
  95. } elseif ($pattern[$begin] === '\\' && ($begin + 1) < $length) {
  96. $begin++;
  97. } elseif ($pattern[$begin] === '{') {
  98. break;
  99. }
  100. $begin++;
  101. }
  102. }
  103. if ($begin === false) {
  104. return static::systemGlob($pattern, $flags);
  105. }
  106. $next = static::nextBraceSub($pattern, $begin + 1, $flags);
  107. if ($next === null) {
  108. return static::systemGlob($pattern, $flags);
  109. }
  110. $rest = $next;
  111. while ($pattern[$rest] !== '}') {
  112. $rest = static::nextBraceSub($pattern, $rest + 1, $flags);
  113. if ($rest === null) {
  114. return static::systemGlob($pattern, $flags);
  115. }
  116. }
  117. $p = $begin + 1;
  118. while (true) {
  119. $subPattern = substr($pattern, 0, $begin)
  120. . substr($pattern, $p, $next - $p)
  121. . substr($pattern, $rest + 1);
  122. $result = static::fallbackGlob($subPattern, $flags | self::GLOB_BRACE);
  123. if ($result) {
  124. $paths = array_merge($paths, $result);
  125. }
  126. if ($pattern[$next] === '}') {
  127. break;
  128. }
  129. $p = $next + 1;
  130. $next = static::nextBraceSub($pattern, $p, $flags);
  131. }
  132. return array_unique($paths);
  133. }
  134. /**
  135. * Find the end of the sub-pattern in a brace expression.
  136. *
  137. * @param string $pattern
  138. * @param integer $begin
  139. * @param integer $flags
  140. * @return integer|null
  141. */
  142. protected static function nextBraceSub($pattern, $begin, $flags)
  143. {
  144. $length = strlen($pattern);
  145. $depth = 0;
  146. $current = $begin;
  147. while ($current < $length) {
  148. if (!$flags & self::GLOB_NOESCAPE && $pattern[$current] === '\\') {
  149. if (++$current === $length) {
  150. break;
  151. }
  152. $current++;
  153. } else {
  154. if (($pattern[$current] === '}' && $depth-- === 0) || ($pattern[$current] === ',' && $depth === 0)) {
  155. break;
  156. } elseif ($pattern[$current++] === '{') {
  157. $depth++;
  158. }
  159. }
  160. }
  161. return ($current < $length ? $current : null);
  162. }
  163. }