PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Gaufrette/Glob.php

https://github.com/knpEdgar/Gaufrette
PHP | 134 lines | 89 code | 15 blank | 30 comment | 10 complexity | 037b3107068862de162e6ab4288dbea5 MD5 | raw file
  1. <?php
  2. namespace Gaufrette;
  3. class Glob
  4. {
  5. protected $pattern;
  6. protected $strictLeadingDot;
  7. protected $strictWildcartSlash;
  8. protected $regex = null;
  9. /**
  10. * Constructor
  11. *
  12. * @param string $pattern The glob pattern
  13. */
  14. public function __construct($pattern, $strictLeadingDot = true, $strictWildcartSlash = true)
  15. {
  16. $this->pattern = $pattern;
  17. }
  18. /**
  19. * Returns the pattern
  20. *
  21. * @return string
  22. */
  23. public function getPattern()
  24. {
  25. return $this->pattern;
  26. }
  27. /**
  28. * Returns the regex associated to the glob
  29. *
  30. * @return string
  31. */
  32. public function getRegex()
  33. {
  34. if (null === $this->regex) {
  35. $this->compile();
  36. }
  37. return $this->regex;
  38. }
  39. /**
  40. * Indicates whether the specified filename matches the glob
  41. *
  42. * @param string $filename The filename that is being tested
  43. */
  44. public function matches($filename)
  45. {
  46. return (boolean) preg_match($this->getRegex(), $filename);
  47. }
  48. /**
  49. * Filters the given input
  50. *
  51. * @param mixed $list
  52. *
  53. * @return array
  54. */
  55. public function filter($list)
  56. {
  57. return array_filter((array) $list, array($this, 'matches'));
  58. }
  59. /**
  60. * Build the regex for the pattern
  61. */
  62. protected function compile()
  63. {
  64. $firstByte = true;
  65. $escaping = false;
  66. $inCurlies = 0;
  67. $patternSize = strlen($this->pattern);
  68. $regex = '';
  69. for ($i = 0; $i < $patternSize; $i++) {
  70. $car = $this->pattern[$i];
  71. if ($firstByte) {
  72. if ($this->strictLeadingDot && '.' !== $car) {
  73. $regex.= '(?=[^\.])';
  74. }
  75. $firstByte = false;
  76. }
  77. switch ($car) {
  78. case '/':
  79. $firstByte = true;
  80. case '.':
  81. case '(':
  82. case ')':
  83. case '|':
  84. case '+':
  85. case '^':
  86. case '$':
  87. $regex.= '\\' . $car;
  88. break;
  89. case '[':
  90. case ']':
  91. $regex.= $escaping ? '\\' . $car : $car;
  92. break;
  93. case '*':
  94. $regex.= $escaping ? '\\*' : $this->strictWildcartSlash ? '[^/]*' : '.*';
  95. break;
  96. case '?':
  97. $regex.= $escaping ? '\\?' : $this->strictWildcartSlash ? '[^/]' : '.';
  98. break;
  99. case '{':
  100. $regex.= !$escaping && ++$inCurlies ? '(' : '\\{';
  101. break;
  102. case '}':
  103. $regex.= !$escaping && $inCurlies && $inCurlies-- ? ')' : '}';
  104. break;
  105. case ',':
  106. $regex.= !$escaping && $inCurlies ? '|' : ',';
  107. break;
  108. case '\\':
  109. $regex.= $escaping ? '\\\\' : '';
  110. $escaping = !$escaping;
  111. continue;
  112. default:
  113. $regex.= $car;
  114. }
  115. $escaping = false;
  116. }
  117. $this->regex = '#^' . $regex . '$#';
  118. }
  119. }