You are here

Candidates.php in Zircon Profile 8.0

Same filename and directory in other branches
  1. 8 vendor/symfony-cmf/routing/Candidates/Candidates.php

File

vendor/symfony-cmf/routing/Candidates/Candidates.php
View source
<?php

/*
 * This file is part of the Symfony CMF package.
 *
 * (c) 2011-2014 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|boolean 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;
  }

}

Classes

Namesort descending Description
Candidates A straightforward strategy that splits the URL on "/".