aboutsummaryrefslogtreecommitdiffhomepage
path: root/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
diff options
context:
space:
mode:
authormarvin-borner@live.com2018-04-10 21:50:16 +0200
committermarvin-borner@live.com2018-04-10 21:54:48 +0200
commitfc9401f04a3aca5abb22f87ebc210de8afe11d32 (patch)
treeb0b310f3581764ec3955f4e496a05137a32951c3 /assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
parent286d643180672f20526f3dc3bd19d7b751e2fa97 (diff)
Initial Commit
Diffstat (limited to 'assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php')
-rw-r--r--assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php238
1 files changed, 238 insertions, 0 deletions
diff --git a/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php b/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
new file mode 100644
index 0000000..7365808
--- /dev/null
+++ b/assets/php/vendor/symfony/routing/Matcher/Dumper/StaticPrefixCollection.php
@@ -0,0 +1,238 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Routing\Matcher\Dumper;
+
+/**
+ * Prefix tree of routes preserving routes order.
+ *
+ * @author Frank de Jonge <info@frankdejonge.nl>
+ *
+ * @internal
+ */
+class StaticPrefixCollection
+{
+ /**
+ * @var string
+ */
+ private $prefix;
+
+ /**
+ * @var array[]|StaticPrefixCollection[]
+ */
+ private $items = array();
+
+ /**
+ * @var int
+ */
+ private $matchStart = 0;
+
+ public function __construct($prefix = '')
+ {
+ $this->prefix = $prefix;
+ }
+
+ public function getPrefix()
+ {
+ return $this->prefix;
+ }
+
+ /**
+ * @return mixed[]|StaticPrefixCollection[]
+ */
+ public function getItems()
+ {
+ return $this->items;
+ }
+
+ /**
+ * Adds a route to a group.
+ *
+ * @param string $prefix
+ * @param mixed $route
+ */
+ public function addRoute($prefix, $route)
+ {
+ $prefix = '/' === $prefix ? $prefix : rtrim($prefix, '/');
+ $this->guardAgainstAddingNotAcceptedRoutes($prefix);
+
+ if ($this->prefix === $prefix) {
+ // When a prefix is exactly the same as the base we move up the match start position.
+ // This is needed because otherwise routes that come afterwards have higher precedence
+ // than a possible regular expression, which goes against the input order sorting.
+ $this->items[] = array($prefix, $route);
+ $this->matchStart = count($this->items);
+
+ return;
+ }
+
+ foreach ($this->items as $i => $item) {
+ if ($i < $this->matchStart) {
+ continue;
+ }
+
+ if ($item instanceof self && $item->accepts($prefix)) {
+ $item->addRoute($prefix, $route);
+
+ return;
+ }
+
+ $group = $this->groupWithItem($item, $prefix, $route);
+
+ if ($group instanceof self) {
+ $this->items[$i] = $group;
+
+ return;
+ }
+ }
+
+ // No optimised case was found, in this case we simple add the route for possible
+ // grouping when new routes are added.
+ $this->items[] = array($prefix, $route);
+ }
+
+ /**
+ * Tries to combine a route with another route or group.
+ *
+ * @param StaticPrefixCollection|array $item
+ * @param string $prefix
+ * @param mixed $route
+ *
+ * @return null|StaticPrefixCollection
+ */
+ private function groupWithItem($item, $prefix, $route)
+ {
+ $itemPrefix = $item instanceof self ? $item->prefix : $item[0];
+ $commonPrefix = $this->detectCommonPrefix($prefix, $itemPrefix);
+
+ if (!$commonPrefix) {
+ return;
+ }
+
+ $child = new self($commonPrefix);
+
+ if ($item instanceof self) {
+ $child->items = array($item);
+ } else {
+ $child->addRoute($item[0], $item[1]);
+ }
+
+ $child->addRoute($prefix, $route);
+
+ return $child;
+ }
+
+ /**
+ * Checks whether a prefix can be contained within the group.
+ *
+ * @param string $prefix
+ *
+ * @return bool Whether a prefix could belong in a given group
+ */
+ private function accepts($prefix)
+ {
+ return '' === $this->prefix || 0 === strpos($prefix, $this->prefix);
+ }
+
+ /**
+ * Detects whether there's a common prefix relative to the group prefix and returns it.
+ *
+ * @param string $prefix
+ * @param string $anotherPrefix
+ *
+ * @return false|string A common prefix, longer than the base/group prefix, or false when none available
+ */
+ private function detectCommonPrefix($prefix, $anotherPrefix)
+ {
+ $baseLength = strlen($this->prefix);
+ $commonLength = $baseLength;
+ $end = min(strlen($prefix), strlen($anotherPrefix));
+
+ for ($i = $baseLength; $i <= $end; ++$i) {
+ if (substr($prefix, 0, $i) !== substr($anotherPrefix, 0, $i)) {
+ break;
+ }
+
+ $commonLength = $i;
+ }
+
+ $commonPrefix = rtrim(substr($prefix, 0, $commonLength), '/');
+
+ if (strlen($commonPrefix) > $baseLength) {
+ return $commonPrefix;
+ }
+
+ return false;
+ }
+
+ /**
+ * Optimizes the tree by inlining items from groups with less than 3 items.
+ */
+ public function optimizeGroups()
+ {
+ $index = -1;
+
+ while (isset($this->items[++$index])) {
+ $item = $this->items[$index];
+
+ if ($item instanceof self) {
+ $item->optimizeGroups();
+
+ // When a group contains only two items there's no reason to optimize because at minimum
+ // the amount of prefix check is 2. In this case inline the group.
+ if ($item->shouldBeInlined()) {
+ array_splice($this->items, $index, 1, $item->items);
+
+ // Lower index to pass through the same index again after optimizing.
+ // The first item of the replacements might be a group needing optimization.
+ --$index;
+ }
+ }
+ }
+ }
+
+ private function shouldBeInlined()
+ {
+ if (count($this->items) >= 3) {
+ return false;
+ }
+
+ foreach ($this->items as $item) {
+ if ($item instanceof self) {
+ return true;
+ }
+ }
+
+ foreach ($this->items as $item) {
+ if (is_array($item) && $item[0] === $this->prefix) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Guards against adding incompatible prefixes in a group.
+ *
+ * @param string $prefix
+ *
+ * @throws \LogicException when a prefix does not belong in a group
+ */
+ private function guardAgainstAddingNotAcceptedRoutes($prefix)
+ {
+ if (!$this->accepts($prefix)) {
+ $message = sprintf('Could not add route with prefix %s to collection with prefix %s', $prefix, $this->prefix);
+
+ throw new \LogicException($message);
+ }
+ }
+}