"Fossies" - the Fresh Open Source Software Archive

Member "contao-4.11.5/core-bundle/src/Routing/Candidates/AbstractCandidates.php" (23 Jun 2021, 3835 Bytes) of package /linux/www/contao-4.11.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AbstractCandidates.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 
    3 declare(strict_types=1);
    4 
    5 /*
    6  * This file is part of Contao.
    7  *
    8  * (c) Leo Feyer
    9  *
   10  * @license LGPL-3.0-or-later
   11  */
   12 
   13 namespace Contao\CoreBundle\Routing\Candidates;
   14 
   15 use Symfony\Cmf\Component\Routing\Candidates\CandidatesInterface;
   16 use Symfony\Component\HttpFoundation\Request;
   17 
   18 class AbstractCandidates implements CandidatesInterface
   19 {
   20     /**
   21      * A limit to apply to the number of candidates generated.
   22      *
   23      * This is to prevent abusive requests with a lot of "/". The limit is per
   24      * batch, that is if a locale matches you could get as many as 2 * $limit
   25      * candidates if the URL has that many slashes.
   26      *
   27      * @var int
   28      */
   29     private const LIMIT = 20;
   30 
   31     /**
   32      * @var array
   33      */
   34     protected $urlPrefixes;
   35 
   36     /**
   37      * @var array
   38      */
   39     protected $urlSuffixes;
   40 
   41     public function __construct(array $urlPrefixes, array $urlSuffixes)
   42     {
   43         $this->urlPrefixes = $urlPrefixes;
   44         $this->urlSuffixes = $urlSuffixes;
   45     }
   46 
   47     public function isCandidate($name): bool
   48     {
   49         return 0 === strncmp($name, 'tl_page.', 8);
   50     }
   51 
   52     public function restrictQuery($queryBuilder): void
   53     {
   54     }
   55 
   56     /**
   57      * Generates possible page aliases from the request path by removing
   58      * prefixes, suffixes and parameters.
   59      *
   60      * Example 1:
   61      *   Path: /en/alias/foo/bar.html
   62      *   Prefixes: [en, de]
   63      *   Suffixes: [.html]
   64      *   Possible aliases:
   65      *     - alias/foo/bar
   66      *     - alias/foo
   67      *     - alias
   68      *
   69      * Example 2:
   70      *   Path: /en/alias/foo/bar.html
   71      *   Prefixes: [en, '']
   72      *   Suffixes: [.html, '']
   73      *   Possible aliases:
   74      *     - en/alias/foo/bar.html
   75      *     - en/alias/foo/bar
   76      *     - en/alias/foo
   77      *     - en/alias
   78      *     - alias/foo/bar.html
   79      *     - alias/foo/bar
   80      *     - alias/foo
   81      *     - alias
   82      */
   83     public function getCandidates(Request $request): array
   84     {
   85         $url = $request->getPathInfo();
   86         $url = rawurldecode(substr($url, 1));
   87 
   88         if (empty($url)) {
   89             throw new \RuntimeException(__METHOD__.' cannot handle empty path');
   90         }
   91 
   92         $candidates = [];
   93 
   94         foreach ($this->urlPrefixes as $prefix) {
   95             // Language prefix only (e.g. URL = /en/)
   96             // Includes "/en" to redirect to language prefix with slash
   97             if ($url === $prefix.'/' || $url === $prefix) {
   98                 $candidates[] = 'index';
   99                 continue;
  100             }
  101 
  102             $withoutPrefix = $url;
  103 
  104             if ('' !== $prefix) {
  105                 if (0 !== strncmp($url, $prefix.'/', \strlen($prefix) + 1)) {
  106                     continue;
  107                 }
  108 
  109                 $withoutPrefix = substr($url, \strlen($prefix) + 1);
  110             }
  111 
  112             foreach ($this->urlSuffixes as $suffix) {
  113                 $withoutSuffix = $withoutPrefix;
  114 
  115                 if ('' !== $suffix) {
  116                     if (0 !== substr_compare($withoutPrefix, $suffix, -\strlen($suffix))) {
  117                         continue;
  118                     }
  119 
  120                     $withoutSuffix = substr($withoutPrefix, 0, -\strlen($suffix));
  121                 }
  122 
  123                 $this->addCandidatesFor($withoutSuffix, $candidates);
  124             }
  125         }
  126 
  127         return array_values(array_unique($candidates));
  128     }
  129 
  130     private function addCandidatesFor(string $url, array &$candidates): void
  131     {
  132         if ('' === $url) {
  133             $candidates[] = 'index';
  134 
  135             return;
  136         }
  137 
  138         $part = $url;
  139         $count = 0;
  140 
  141         while (false !== ($pos = strrpos($part, '/'))) {
  142             ++$count;
  143 
  144             if ($count > self::LIMIT) {
  145                 return;
  146             }
  147 
  148             $candidates[] = $part;
  149             $part = substr($url, 0, $pos);
  150         }
  151 
  152         $candidates[] = $part;
  153     }
  154 }