123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- <?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;
- }
- }
|