/** * * @param \Swift_Mailer $mailer * @param UrlGeneratorInterface $router * @param \Twig_Environment $twig * @param Logger $logger * @param Translator $translator * @param array $parameters * @param \Swift_Mailer $immediateMailer */ public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, Logger $logger, Translator $translator, TemplateProviderInterface $templateProvider, EntityManager $entityManager, array $parameters, \Swift_Mailer $immediateMailer = null) { parent::__construct($mailer, $router, $twig, $parameters); $this->immediateMailer = $immediateMailer; $this->logger = $logger; $this->translator = $translator; $this->templateProvider = $templateProvider; $this->entityManager = $entityManager; $this->noReplyEmail = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_ADDRESS]; $this->noReplyName = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_NAME]; $this->routerContext = $router->getContext(); $this->currentHost = $this->routerContext->getHost(); $this->encodedItemIdPattern = "/^cid:.*@/"; }
/** * * @param \Swift_Mailer $mailer * @param UrlGeneratorInterface $router * @param \Twig_Environment $twig * @param Translator $translator * @param TemplateProviderInterface $templateProvider * @param ManagerRegistry $managerRegistry * @param EmailOpenTrackingCodeBuilderInterface $emailOpenTrackingCodeBuilder * @param AzineEmailTwigExtension $emailTwigExtension * @param array $parameters * @param \Swift_Mailer $immediateMailer */ public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, Translator $translator, TemplateProviderInterface $templateProvider, ManagerRegistry $managerRegistry, EmailOpenTrackingCodeBuilderInterface $emailOpenTrackingCodeBuilder, AzineEmailTwigExtension $emailTwigExtension, array $parameters, \Swift_Mailer $immediateMailer = null) { parent::__construct($mailer, $router, $twig, $parameters); $this->immediateMailer = $immediateMailer; $this->translator = $translator; $this->templateProvider = $templateProvider; $this->managerRegistry = $managerRegistry; $this->noReplyEmail = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_ADDRESS]; $this->noReplyName = $parameters[AzineEmailExtension::NO_REPLY][AzineEmailExtension::NO_REPLY_EMAIL_NAME]; $this->emailOpenTrackingCodeBuilder = $emailOpenTrackingCodeBuilder; $this->routerContext = $router->getContext(); $this->currentHost = $this->routerContext->getHost(); $this->encodedItemIdPattern = "/^cid:.*@/"; $this->emailTwigExtension = $emailTwigExtension; }
/** * Rebuild the request object from a URL with the help of the RequestContext. * * If the request context is not set, this simply returns the request object built from $uri. * * @param string $uri * * @return Request */ private function rebuildRequest($uri) { if (!$this->context) { return Request::create($uri); } $server = array(); if ($this->context->getHost()) { $server['SERVER_NAME'] = $this->context->getHost(); $server['HTTP_HOST'] = $this->context->getHost(); } if ($this->context->getBaseUrl()) { $uri = $this->context->getBaseUrl() . $uri; $server['SCRIPT_FILENAME'] = $this->context->getBaseUrl(); $server['PHP_SELF'] = $this->context->getBaseUrl(); } if ('https' === $this->context->getScheme()) { $server['HTTPS'] = 'on'; $server['SERVER_PORT'] = $this->context->getHttpsPort(); if (443 !== $this->context->getHttpsPort()) { // this is parsed from the host by symfony request // https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L971 $server['HTTP_HOST'] .= ':' . $this->context->getHttpsPort(); } } else { $server['SERVER_PORT'] = $this->context->getHttpPort(); if (80 !== $this->context->getHttpPort()) { // this is parsed from the host by symfony request // https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php#L971 $server['HTTP_HOST'] .= ':' . $this->context->getHttpPort(); } } return Request::create($uri, $this->context->getMethod(), $this->context->getParameters(), array(), array(), $server); }
/** * Decorates an URL with url context and query. * * @param string $url Relative URL * @param array $parameters An array of parameters * @param bool|string $referenceType The type of reference to be generated (one of the constants) * * @return string * * @throws \RuntimeException */ protected function decorateUrl($url, array $parameters = array(), $referenceType = self::ABSOLUTE_PATH) { if (!$this->context) { throw new \RuntimeException('No context associated to the CmsPageRouter'); } $schemeAuthority = ''; if ($this->context->getHost() && (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType)) { $port = ''; if ('http' === $this->context->getScheme() && 80 != $this->context->getHttpPort()) { $port = sprintf(':%s', $this->context->getHttpPort()); } elseif ('https' === $this->context->getScheme() && 443 != $this->context->getHttpsPort()) { $port = sprintf(':%s', $this->context->getHttpsPort()); } $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : sprintf('%s://', $this->context->getScheme()); $schemeAuthority = sprintf('%s%s%s', $schemeAuthority, $this->context->getHost(), $port); } if (self::RELATIVE_PATH === $referenceType) { $url = $this->getRelativePath($this->context->getPathInfo(), $url); } else { $url = sprintf('%s%s%s', $schemeAuthority, $this->context->getBaseUrl(), $url); } if (count($parameters) > 0) { return sprintf('%s?%s', $url, http_build_query($parameters, '', '&')); } return $url; }
/** * {@inheritdoc} */ public function getHost() { $site = $this->selector->retrieve(); if ($site && !$site->isLocalhost()) { return $site->getHost(); } return parent::getHost(); }
/** * @param string $pathInfo * @param bool|string $referenceType * * @return string */ private function buildUrl($pathInfo, $referenceType) { $scheme = $this->getScheme(); $port = $this->getPortPart($scheme); $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "{$scheme}://"; $schemeAuthority .= $this->context->getHost() . $port; return $schemeAuthority . $this->context->getBaseUrl() . $pathInfo; }
/** * Return the base URL, either the base_url defined in Config, or the URL * of the current language, if 'one_domain_foreach_lang' is enabled. * * @param bool $scheme_only if true, only the scheme will be returned. If false, the complete base URL, including path, is returned. * * @return string the base URL, with a trailing '/' */ public function getBaseUrl($scheme_only = false) { if (null === $this->baseUrlScheme) { $scheme = "http"; $port = 80; if ($host = $this->requestContext->getHost()) { $scheme = $this->requestContext->getScheme(); $port = ''; if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) { $port = ':' . $this->requestContext->getHttpPort(); } elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) { $port = ':' . $this->requestContext->getHttpsPort(); } } $this->baseUrlScheme = "{$scheme}://{$host}" . "{$port}"; } return $scheme_only ? $this->baseUrlScheme : $this->baseUrlScheme . $this->requestContext->getBaseUrl(); }
/** * Get host url (scheme, host, port) * * @return string Host url */ private function getHostUrl() { $url = $this->requestContext->getScheme() . '://' . $this->requestContext->getHost(); if ($this->requestContext->getScheme() == 'http' && $this->requestContext->getHttpPort() && $this->requestContext->getHttpPort() != 80) { $url .= ':' . $this->requestContext->getHttpPort(); } elseif ($this->requestContext->getScheme() == 'https' && $this->requestContext->getHttpsPort() && $this->requestContext->getHttpsPort() != 443) { $url .= ':' . $this->requestContext->getHttpsPort(); } return $url; }
public function generateI18nRouteFromCurrentRequest($culture, $referenceType = self::ABSOLUTE_PATH, $scheme = null) { $result = $this->match($this->context->getPathInfo(), $this->context->getHost(), $this->context->getScheme(), $this->context->getMethod()); $route = $result['_route']; if (strpos($route, ':i18n:') != false) { list(, , $route) = explode(':', $route, 3); } $result['_culture'] = $culture; unset($result['_route']); $parameters = new ArrayObject($result); $this->eventDispatcher->dispatch('Routing.preGenrateI18nRouteFromCurrentRequest', $this, compact('culture', 'referenceType', 'scheme', 'parameters')); return $this->generate($route, $parameters->getArrayCopy(), $referenceType, $scheme); }
/** * Returns base URL, with scheme, host and port, for current request context. * If no delivery URL is configured for current SiteAccess, will return base URL from current RequestContext. * * @return string */ protected function getBaseUrl() { $port = ''; if ($this->requestContext->getScheme() === 'https' && $this->requestContext->getHttpsPort() != 443) { $port = ":{$this->requestContext->getHttpsPort()}"; } if ($this->requestContext->getScheme() === 'http' && $this->requestContext->getHttpPort() != 80) { $port = ":{$this->requestContext->getHttpPort()}"; } $baseUrl = $this->requestContext->getBaseUrl(); if (substr($this->requestContext->getBaseUrl(), -4) === '.php') { $baseUrl = pathinfo($this->requestContext->getBaseurl(), PATHINFO_DIRNAME); } $baseUrl = rtrim($baseUrl, '/\\'); return sprintf('%s://%s%s%s', $this->requestContext->getScheme(), $this->requestContext->getHost(), $port, $baseUrl); }
/** * Get absolute path of a given pic url * * @param string $picUrl * @return string */ private function getAbsoluteUrlPic($picUrl = '') { if ($picUrl) { if ("/" == $picUrl[0]) { $scheme = $this->context->getScheme(); $host = $this->context->getHost(); $port = ''; if ('http' === $scheme && 80 != $this->context->getHttpPort()) { $port = ':' . $this->context->getHttpPort(); } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { $port = ':' . $this->context->getHttpsPort(); } return $scheme . "://" . $host . $port . $picUrl; } } return $picUrl; }
/** * Tries to match a URL with a set of routes. * * @param string $pathinfo The path info to be parsed * @param RouteCollection $routes The set of routes * * @return array An array of parameters * * @throws ResourceNotFoundException If the resource could not be found * @throws MethodNotAllowedException If the resource was found but the request method is not allowed */ protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { if ($route instanceof RouteCollection) { if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) { continue; } if (!($ret = $this->matchCollection($pathinfo, $route))) { continue; } return $ret; } $compiledRoute = $route->compile(); // check the static prefix of the URL first. Only use the more expensive preg_match when it matches if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { continue; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { continue; } $hostnameMatches = array(); if ($compiledRoute->getHostnameRegex() && !preg_match($compiledRoute->getHostnameRegex(), $this->context->getHost(), $hostnameMatches)) { continue; } // check HTTP method requirement if ($req = $route->getRequirement('_method')) { // HEAD and GET are equivalent as per RFC if ('HEAD' === ($method = $this->context->getMethod())) { $method = 'GET'; } if (!in_array($method, $req = explode('|', strtoupper($req)))) { $this->allow = array_merge($this->allow, $req); continue; } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } return $this->mergeDefaults(array_replace($matches, $hostnameMatches, array('_route' => $name)), $route->getDefaults()); } }
public function testFromRequest() { $request = Request::create('https://test.com:444/foo?bar=baz'); $requestContext = new RequestContext(); $requestContext->setHttpPort(123); $requestContext->fromRequest($request); $this->assertEquals('', $requestContext->getBaseUrl()); $this->assertEquals('GET', $requestContext->getMethod()); $this->assertEquals('test.com', $requestContext->getHost()); $this->assertEquals('https', $requestContext->getScheme()); $this->assertEquals('/foo', $requestContext->getPathInfo()); $this->assertEquals('bar=baz', $requestContext->getQueryString()); $this->assertSame(123, $requestContext->getHttpPort()); $this->assertSame(444, $requestContext->getHttpsPort()); $request = Request::create('http://test.com:8080/foo?bar=baz'); $requestContext = new RequestContext(); $requestContext->setHttpsPort(567); $requestContext->fromRequest($request); $this->assertSame(8080, $requestContext->getHttpPort()); $this->assertSame(567, $requestContext->getHttpsPort()); }
/** * Decorates an URL with url context and query * * @param string $url Relative URL * @param array $parameters An array of parameters * @param boolean $absolute Whether to generate an absolute path or not * * @return string * * @throws \RuntimeException */ protected function decorateUrl($url, array $parameters = array(), $absolute = false) { if (!$this->context) { throw new \RuntimeException('No context associated to the CmsPageRouter'); } $url = sprintf('%s%s', $this->context->getBaseUrl(), $url); if ($absolute && $this->context->getHost()) { $scheme = $this->context->getScheme(); $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; } if (count($parameters) > 0) { return sprintf('%s?%s', $url, http_build_query($parameters, '', '&')); } return $url; }
/** * Rebuild the request object from a URL with the help of the RequestContext. * * If the request context is not set, this simply returns the request object built from $uri. * * @param string $pathinfo * * @return Request */ private function rebuildRequest($pathinfo) { if (!$this->context) { return Request::create('http://localhost' . $pathinfo); } $uri = $pathinfo; $server = array(); if ($this->context->getBaseUrl()) { $uri = $this->context->getBaseUrl() . $pathinfo; $server['SCRIPT_FILENAME'] = $this->context->getBaseUrl(); $server['PHP_SELF'] = $this->context->getBaseUrl(); } $host = $this->context->getHost() ?: 'localhost'; if ('https' === $this->context->getScheme() && 443 !== $this->context->getHttpsPort()) { $host .= ':' . $this->context->getHttpsPort(); } if ('http' === $this->context->getScheme() && 80 !== $this->context->getHttpPort()) { $host .= ':' . $this->context->getHttpPort(); } $uri = $this->context->getScheme() . '://' . $host . $uri . '?' . $this->context->getQueryString(); return Request::create($uri, $this->context->getMethod(), $this->context->getParameters(), array(), array(), $server); }
/** * Tries to match a URL with a set of routes. * * @param string $pathinfo The path info to be parsed * @param RouteCollection $routes The set of routes * * @return array An array of parameters * * @throws ResourceNotFoundException If the resource could not be found * @throws MethodNotAllowedException If the resource was found but the request method is not allowed */ protected function matchCollection($pathinfo, RouteCollection $routes) { foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); // check the static prefix of the URL first. Only use the more expensive preg_match when it matches if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { continue; } if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { continue; } $hostMatches = array(); if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { continue; } // check HTTP method requirement if ($requiredMethods = $route->getMethods()) { // HEAD and GET are equivalent as per RFC if ('HEAD' === ($method = $this->context->getMethod())) { $method = 'GET'; } if (!in_array($method, $requiredMethods)) { $this->allow = array_merge($this->allow, $requiredMethods); continue; } } $status = $this->handleRouteRequirements($pathinfo, $name, $route); if (self::ROUTE_MATCH === $status[0]) { return $status[1]; } if (self::REQUIREMENT_MISMATCH === $status[0]) { continue; } return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); } }
/** * Generates an absolute URL from $uri and the request context * * @param string $uri * @param \Symfony\Component\Routing\RequestContext $requestContext * * @return string */ protected function generateAbsoluteUrl($uri, RequestContext $requestContext) { $scheme = $requestContext->getScheme(); $port = ''; if ($scheme === 'http' && $requestContext->getHttpPort() != 80) { $port = ':' . $requestContext->getHttpPort(); } else { if ($scheme === 'https' && $requestContext->getHttpsPort() != 443) { $port = ':' . $requestContext->getHttpsPort(); } } return $scheme . '://' . $requestContext->getHost() . $port . $uri; }
/** * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route * @throws InvalidParameterException When a parameter value for a placeholder is not correct because * it does not match the requirement */ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, array $requiredSchemes = array()) { $variables = array_flip($variables); $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); // all params must be given if ($diff = array_diff_key($variables, $mergedParams)) { throw new MissingMandatoryParametersException(sprintf('Some mandatory parameters are missing ("%s") to generate a URL for route "%s".', implode('", "', array_keys($diff)), $name)); } $url = ''; $optional = true; foreach ($tokens as $token) { if ('variable' === $token[0]) { if (!$optional || !array_key_exists($token[3], $defaults) || null !== $mergedParams[$token[3]] && (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { // check requirement if (null !== $this->strictRequirements && !preg_match('#^' . $token[2] . '$#', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->error($message); } return; } $url = $token[1] . $mergedParams[$token[3]] . $url; $optional = false; } } else { // static text $url = $token[1] . $url; $optional = false; } } if ('' === $url) { $url = '/'; } // the contexts base URL is already encoded (see Symfony\Component\HttpFoundation\Request) $url = 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'; } $schemeAuthority = ''; if ($host = $this->context->getHost()) { $scheme = $this->context->getScheme(); if ($requiredSchemes) { $schemeMatched = false; foreach ($requiredSchemes as $requiredScheme) { if ($scheme === $requiredScheme) { $schemeMatched = true; break; } } if (!$schemeMatched) { $referenceType = self::ABSOLUTE_URL; $scheme = current($requiredSchemes); } } elseif (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme !== $req) { // We do this for BC; to be removed if _scheme is not supported anymore $referenceType = self::ABSOLUTE_URL; $scheme = $req; } if ($hostTokens) { $routeHost = ''; foreach ($hostTokens as $token) { if ('variable' === $token[0]) { if (null !== $this->strictRequirements && !preg_match('#^' . $token[2] . '$#i', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given) to generate a corresponding URL.', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->error($message); } return; } $routeHost = $token[1] . $mergedParams[$token[3]] . $routeHost; } else { $routeHost = $token[1] . $routeHost; } } if ($routeHost !== $host) { $host = $routeHost; if (self::ABSOLUTE_URL !== $referenceType) { $referenceType = self::NETWORK_PATH; } } } if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) { $port = ''; if ('http' === $scheme && 80 != $this->context->getHttpPort()) { $port = ':' . $this->context->getHttpPort(); } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { $port = ':' . $this->context->getHttpsPort(); } $schemeAuthority = self::NETWORK_PATH === $referenceType ? '//' : "{$scheme}://"; $schemeAuthority .= $host . $port; } } if (self::RELATIVE_PATH === $referenceType) { $url = self::getRelativePath($this->context->getPathInfo(), $url); } else { $url = $schemeAuthority . $this->context->getBaseUrl() . $url; } // add a query string if needed $extra = array_diff_key($parameters, $variables, $defaults); if ($extra && ($query = http_build_query($extra, '', '&'))) { // "/" and "?" can be left decoded for better user experience, see // http://tools.ietf.org/html/rfc3986#section-3.4 $url .= '?' . strtr($query, array('%2F' => '/')); } return $url; }
/** * @param $uniqueId * * @return string */ public function getOutputFileUrl($uniqueId) { return sprintf("%s://%s%s%s/%s.html", $this->context->getScheme(), $this->context->getHost(), $this->contextBaseUrl === "" ? $this->context->getBaseUrl() : $this->contextBaseUrl, $this->config['temp_dir'], $uniqueId); }
/** * Sets the context from the domain. * * @param RequestContext $context * @param array $parameters * @param string $referenceType */ private function setContextFromDomain(RequestContext $context, array &$parameters, &$referenceType) { list($host, $port) = explode(':', $parameters['_domain'], 2); if ($host === $context->getHost()) { return; } $isSsl = true === $parameters['_ssl']; $referenceType = UrlGeneratorInterface::ABSOLUTE_URL; $context->setHost($host); $context->setScheme($isSsl ? 'https' : 'http'); $context->setHttpPort($port ?: ($isSsl ? 443 : 80)); }
public function testHost() { $requestContext = new RequestContext(); $requestContext->setHost('eXampLe.com'); $this->assertSame('example.com', $requestContext->getHost()); }
/** * Sets the context from the domain. * * @param RequestContext $context * @param array $parameters * @param string $referenceType */ private function addHostToContext(RequestContext $context, array $parameters, &$referenceType) { list($host, $port) = $this->getHostAndPort($parameters['_domain']); if ($context->getHost() === $host) { return; } $context->setHost($host); $referenceType = UrlGeneratorInterface::ABSOLUTE_URL; if (!$port) { return; } if (isset($parameters['_ssl']) && true === $parameters['_ssl']) { $context->setHttpsPort($port); } else { $context->setHttpPort($port); } }
/** * @throws MissingMandatoryParametersException When route has some missing mandatory parameters * @throws InvalidParameterException When a parameter value is not correct */ protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute, $hostnameTokens) { $variables = array_flip($variables); $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); // all params must be given if ($diff = array_diff_key($variables, $mergedParams)) { 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 (!$optional || !array_key_exists($token[3], $defaults) || (string) $mergedParams[$token[3]] !== (string) $defaults[$token[3]]) { // check requirement if (null !== $this->strictRequirements && !preg_match('#^' . $token[2] . '$#', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->err($message); } return null; } $url = $token[1] . $mergedParams[$token[3]] . $url; $optional = false; } } else { // static text $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($parameters, $variables); if ($extra && ($query = http_build_query($extra, '', '&'))) { $url .= '?' . $query; } if ($host = $this->context->getHost()) { $scheme = $this->context->getScheme(); if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { $absolute = true; $scheme = $req; } if ($hostnameTokens) { $routeHost = ''; foreach ($hostnameTokens as $token) { if ('variable' === $token[0]) { if (null !== $this->strictRequirements && !preg_match('#^' . $token[2] . '$#', $mergedParams[$token[3]])) { $message = sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $mergedParams[$token[3]]); if ($this->strictRequirements) { throw new InvalidParameterException($message); } if ($this->logger) { $this->logger->err($message); } return null; } $routeHost = $token[1] . $mergedParams[$token[3]] . $routeHost; } elseif ('text' === $token[0]) { $routeHost = $token[1] . $routeHost; } } if ($routeHost != $host) { $host = $routeHost; $absolute = true; } } 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 . '://' . $host . $port . $url; } } return $url; }