This repository has been archived on 2025-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
drupalcampbristol/vendor/symfony-cmf/routing/Candidates/Candidates.php
2018-11-23 12:29:20 +00:00

155 lines
3.9 KiB
PHP

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