protected function UrlGenerator::doGenerate

Throws

MissingMandatoryParametersException When route has some missing mandatory parameters

InvalidParameterException When a parameter value is not correct

1 call to UrlGenerator::doGenerate()
UrlGenerator::generate in drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php
Generates a URL from the given parameters.

File

drupal/core/vendor/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php, line 132

Class

UrlGenerator
UrlGenerator generates a URL based on a set of routes.

Namespace

Symfony\Component\Routing\Generator

Code

protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) {
  $variables = array_flip($variables);
  $originParameters = $parameters;
  $parameters = array_replace($this->context
    ->getParameters(), $parameters);
  $tparams = array_replace($defaults, $parameters);

  // all params must be given
  if ($diff = array_diff_key($variables, $tparams)) {
    throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff))));
  }
  $url = '';
  $optional = true;
  foreach ($tokens as $token) {
    if ('variable' === $token[0]) {
      if (false === $optional || !array_key_exists($token[3], $defaults) || isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]]) {
        if (!($isEmpty = in_array($tparams[$token[3]], array(
          null,
          '',
          false,
        ), true))) {

          // check requirement
          if ($tparams[$token[3]] && !preg_match('#^' . $token[2] . '$#', $tparams[$token[3]])) {
            $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]]);
            if ($this->strictRequirements) {
              throw new InvalidParameterException($message);
            }
            if ($this->logger) {
              $this->logger
                ->err($message);
            }
            return null;
          }
        }
        if (!$isEmpty || !$optional) {
          $url = $token[1] . $tparams[$token[3]] . $url;
        }
        $optional = false;
      }
    }
    elseif ('text' === $token[0]) {
      $url = $token[1] . $url;
      $optional = false;
    }
  }
  if ('' === $url) {
    $url = '/';
  }

  // do not encode the contexts base url as it is already encoded (see Symfony\Component\HttpFoundation\Request)
  $url = $this->context
    ->getBaseUrl() . strtr(rawurlencode($url), $this->decodedChars);

  // the path segments "." and ".." are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3
  // so we need to encode them as they are not used for this purpose here
  // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route
  $url = strtr($url, array(
    '/../' => '/%2E%2E/',
    '/./' => '/%2E/',
  ));
  if ('/..' === substr($url, -3)) {
    $url = substr($url, 0, -2) . '%2E%2E';
  }
  elseif ('/.' === substr($url, -2)) {
    $url = substr($url, 0, -1) . '%2E';
  }

  // add a query string if needed
  $extra = array_diff_key($originParameters, $variables, $defaults);
  if ($extra && ($query = http_build_query($extra, '', '&'))) {
    $url .= '?' . $query;
  }
  if ($this->context
    ->getHost()) {
    $scheme = $this->context
      ->getScheme();
    if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) {
      $absolute = true;
      $scheme = $req;
    }
    if ($absolute) {
      $port = '';
      if ('http' === $scheme && 80 != $this->context
        ->getHttpPort()) {
        $port = ':' . $this->context
          ->getHttpPort();
      }
      elseif ('https' === $scheme && 443 != $this->context
        ->getHttpsPort()) {
        $port = ':' . $this->context
          ->getHttpsPort();
      }
      $url = $scheme . '://' . $this->context
        ->getHost() . $port . $url;
    }
  }
  return $url;
}