控制台应用,yzncms本身基于tp5.1框架,里面的队列用不了,bug,坑
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PropertyPath.php 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\PropertyAccess;
  11. use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
  12. use Symfony\Component\PropertyAccess\Exception\InvalidPropertyPathException;
  13. use Symfony\Component\PropertyAccess\Exception\OutOfBoundsException;
  14. /**
  15. * Default implementation of {@link PropertyPathInterface}.
  16. *
  17. * @author Bernhard Schussek <bschussek@gmail.com>
  18. *
  19. * @implements \IteratorAggregate<int, string>
  20. */
  21. class PropertyPath implements \IteratorAggregate, PropertyPathInterface
  22. {
  23. /**
  24. * Character used for separating between plural and singular of an element.
  25. */
  26. public const SINGULAR_SEPARATOR = '|';
  27. /**
  28. * The elements of the property path.
  29. *
  30. * @var list<string>
  31. */
  32. private $elements = [];
  33. /**
  34. * The number of elements in the property path.
  35. *
  36. * @var int
  37. */
  38. private $length;
  39. /**
  40. * Contains a Boolean for each property in $elements denoting whether this
  41. * element is an index. It is a property otherwise.
  42. *
  43. * @var array
  44. */
  45. private $isIndex = [];
  46. /**
  47. * String representation of the path.
  48. *
  49. * @var string
  50. */
  51. private $pathAsString;
  52. /**
  53. * Constructs a property path from a string.
  54. *
  55. * @param PropertyPath|string $propertyPath The property path as string or instance
  56. *
  57. * @throws InvalidArgumentException If the given path is not a string
  58. * @throws InvalidPropertyPathException If the syntax of the property path is not valid
  59. */
  60. public function __construct($propertyPath)
  61. {
  62. // Can be used as copy constructor
  63. if ($propertyPath instanceof self) {
  64. /* @var PropertyPath $propertyPath */
  65. $this->elements = $propertyPath->elements;
  66. $this->length = $propertyPath->length;
  67. $this->isIndex = $propertyPath->isIndex;
  68. $this->pathAsString = $propertyPath->pathAsString;
  69. return;
  70. }
  71. if (!\is_string($propertyPath)) {
  72. throw new InvalidArgumentException(sprintf('The property path constructor needs a string or an instance of "Symfony\Component\PropertyAccess\PropertyPath". Got: "%s".', get_debug_type($propertyPath)));
  73. }
  74. if ('' === $propertyPath) {
  75. throw new InvalidPropertyPathException('The property path should not be empty.');
  76. }
  77. $this->pathAsString = $propertyPath;
  78. $position = 0;
  79. $remaining = $propertyPath;
  80. // first element is evaluated differently - no leading dot for properties
  81. $pattern = '/^(([^\.\[]++)|\[([^\]]++)\])(.*)/';
  82. while (preg_match($pattern, $remaining, $matches)) {
  83. if ('' !== $matches[2]) {
  84. $element = $matches[2];
  85. $this->isIndex[] = false;
  86. } else {
  87. $element = $matches[3];
  88. $this->isIndex[] = true;
  89. }
  90. $this->elements[] = $element;
  91. $position += \strlen($matches[1]);
  92. $remaining = $matches[4];
  93. $pattern = '/^(\.([^\.|\[]++)|\[([^\]]++)\])(.*)/';
  94. }
  95. if ('' !== $remaining) {
  96. throw new InvalidPropertyPathException(sprintf('Could not parse property path "%s". Unexpected token "%s" at position %d.', $propertyPath, $remaining[0], $position));
  97. }
  98. $this->length = \count($this->elements);
  99. }
  100. /**
  101. * {@inheritdoc}
  102. */
  103. public function __toString()
  104. {
  105. return $this->pathAsString;
  106. }
  107. /**
  108. * {@inheritdoc}
  109. */
  110. public function getLength()
  111. {
  112. return $this->length;
  113. }
  114. /**
  115. * {@inheritdoc}
  116. */
  117. public function getParent()
  118. {
  119. if ($this->length <= 1) {
  120. return null;
  121. }
  122. $parent = clone $this;
  123. --$parent->length;
  124. $parent->pathAsString = substr($parent->pathAsString, 0, max(strrpos($parent->pathAsString, '.'), strrpos($parent->pathAsString, '[')));
  125. array_pop($parent->elements);
  126. array_pop($parent->isIndex);
  127. return $parent;
  128. }
  129. /**
  130. * Returns a new iterator for this path.
  131. *
  132. * @return PropertyPathIteratorInterface
  133. */
  134. #[\ReturnTypeWillChange]
  135. public function getIterator()
  136. {
  137. return new PropertyPathIterator($this);
  138. }
  139. /**
  140. * {@inheritdoc}
  141. */
  142. public function getElements()
  143. {
  144. return $this->elements;
  145. }
  146. /**
  147. * {@inheritdoc}
  148. */
  149. public function getElement(int $index)
  150. {
  151. if (!isset($this->elements[$index])) {
  152. throw new OutOfBoundsException(sprintf('The index "%s" is not within the property path.', $index));
  153. }
  154. return $this->elements[$index];
  155. }
  156. /**
  157. * {@inheritdoc}
  158. */
  159. public function isProperty(int $index)
  160. {
  161. if (!isset($this->isIndex[$index])) {
  162. throw new OutOfBoundsException(sprintf('The index "%s" is not within the property path.', $index));
  163. }
  164. return !$this->isIndex[$index];
  165. }
  166. /**
  167. * {@inheritdoc}
  168. */
  169. public function isIndex(int $index)
  170. {
  171. if (!isset($this->isIndex[$index])) {
  172. throw new OutOfBoundsException(sprintf('The index "%s" is not within the property path.', $index));
  173. }
  174. return $this->isIndex[$index];
  175. }
  176. }