Version 1
[yaffs-website] / vendor / symfony-cmf / routing / Candidates / Candidates.php
diff --git a/vendor/symfony-cmf/routing/Candidates/Candidates.php b/vendor/symfony-cmf/routing/Candidates/Candidates.php
new file mode 100644 (file)
index 0000000..21bef55
--- /dev/null
@@ -0,0 +1,154 @@
+<?php
+
+/*
+ * This file is part of the Symfony CMF package.
+ *
+ * (c) 2011-2015 Symfony CMF
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Cmf\Component\Routing\Candidates;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * A straightforward strategy that splits the URL on "/".
+ *
+ * If locales is set, additionally generates candidates removing the locale if
+ * it is one of the configured locales, for non-locale specific URLs.
+ *
+ * @author David Buchmann <mail@davidbu.ch>
+ */
+class Candidates implements CandidatesInterface
+{
+    /**
+     * @var array
+     */
+    protected $locales;
+
+    /**
+     * A limit to apply to the number of candidates generated.
+     *
+     * This is to prevent abusive requests with a lot of "/". The limit is per
+     * batch, that is if a locale matches you could get as many as 2 * $limit
+     * candidates if the URL has that many slashes.
+     *
+     * @var int
+     */
+    protected $limit;
+
+    /**
+     * @param array $locales The locales to support.
+     * @param int   $limit   A limit to apply to the candidates generated.
+     */
+    public function __construct(array $locales = array(), $limit = 20)
+    {
+        $this->setLocales($locales);
+        $this->limit = $limit;
+    }
+
+    /**
+     * Set the locales to support by this strategy.
+     *
+     * @param array $locales The locales to support.
+     */
+    public function setLocales(array $locales)
+    {
+        $this->locales = $locales;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * Always returns true.
+     */
+    public function isCandidate($name)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * Does nothing.
+     */
+    public function restrictQuery($queryBuilder)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCandidates(Request $request)
+    {
+        $url = $request->getPathInfo();
+        $candidates = $this->getCandidatesFor($url);
+
+        $locale = $this->determineLocale($url);
+        if ($locale) {
+            $candidates = array_unique(array_merge($candidates, $this->getCandidatesFor(substr($url, strlen($locale) + 1))));
+        }
+
+        return $candidates;
+    }
+
+    /**
+     * Determine the locale of this URL.
+     *
+     * @param string $url The url to determine the locale from.
+     *
+     * @return string|bool The locale if $url starts with one of the allowed locales.
+     */
+    protected function determineLocale($url)
+    {
+        if (!count($this->locales)) {
+            return false;
+        }
+
+        $matches = array();
+        if (preg_match('#('.implode('|', $this->locales).')(/|$)#', $url, $matches)) {
+            return $matches[1];
+        }
+
+        return false;
+    }
+
+    /**
+     * Handle a possible format extension and split the $url on "/".
+     *
+     * $prefix is prepended to every candidate generated.
+     *
+     * @param string $url    The URL to split.
+     * @param string $prefix A prefix to prepend to every pattern.
+     *
+     * @return array Paths that could represent routes that match $url and are
+     *               child of $prefix.
+     */
+    protected function getCandidatesFor($url, $prefix = '')
+    {
+        $candidates = array();
+        if ('/' !== $url) {
+            // handle format extension, like .html or .json
+            if (preg_match('/(.+)\.[a-z]+$/i', $url, $matches)) {
+                $candidates[] = $prefix.$url;
+                $url = $matches[1];
+            }
+
+            $part = $url;
+            $count = 0;
+            while (false !== ($pos = strrpos($part, '/'))) {
+                if (++$count > $this->limit) {
+                    return $candidates;
+                }
+                $candidates[] = $prefix.$part;
+                $part = substr($url, 0, $pos);
+            }
+        }
+
+        $candidates[] = $prefix ?: '/';
+
+        return $candidates;
+    }
+}