1. sfWebController.class.php
  2. /** * sfWebController provides web specific methods to sfController such as, url redirection. * * @package symfony * @subpackage controller * @author Fabien Potencier * @author Sean Kerr * @version SVN: $Id: sfWebController.class.php 25406 2009-12-15 12:22:30Z FabianLange $ */
  3. abstract class sfWebController extends sfController
  4. {
  5. /**
  6. * Generates an URL from an array of parameters.
  7. *
  8. * @param mixed $parameters An associative array of URL parameters or an internal URI as a string.
  9. * @param boolean $absolute Whether to generate an absolute URL
  10. *
  11. * @return string A URL to a symfony resource
  12. */
  13. public function genUrl($parameters = array(), $absolute = false)
  14. {
  15. $route = '';
  16. $fragment = '';
  17. if (is_string($parameters))
  18. {
  19. // absolute URL or symfony URL?
  20. if (preg_match('#^[a-z][a-z0-9\+.\-]*\://#i', $parameters))
  21. {
  22. return $parameters;
  23. }
  24. // relative URL?
  25. if (0 === strpos($parameters, '/'))
  26. {
  27. return $parameters;
  28. }
  29. if ($parameters == '#')
  30. {
  31. return $parameters;
  32. }
  33. // strip fragment
  34. if (false !== ($pos = strpos($parameters, '#')))
  35. {
  36. $fragment = substr($parameters, $pos + 1);
  37. $parameters = substr($parameters, 0, $pos);
  38. }
  39. list($route, $parameters) = $this->convertUrlStringToParameters($parameters);
  40. }
  41. else if (is_array($parameters))
  42. {
  43. if (isset($parameters['sf_route']))
  44. {
  45. $route = $parameters['sf_route'];
  46. unset($parameters['sf_route']);
  47. }
  48. }
  49. // routing to generate path
  50. $url = $this->context->getRouting()->generate($route, $parameters, $absolute);
  51. if ($fragment)
  52. {
  53. $url .= '#'.$fragment;
  54. }
  55. return $url;
  56. }
  57. /**
  58. * Converts an internal URI string to an array of parameters.
  59. *
  60. * @param string $url An internal URI
  61. *
  62. * @return array An array of parameters
  63. */
  64. public function convertUrlStringToParameters($url)
  65. {
  66. $givenUrl = $url;
  67. $params = array();
  68. $queryString = '';
  69. $route = '';
  70. // empty url?
  71. if (!$url)
  72. {
  73. $url = '/';
  74. }
  75. // we get the query string out of the url
  76. if ($pos = strpos($url, '?'))
  77. {
  78. $queryString = substr($url, $pos + 1);
  79. $url = substr($url, 0, $pos);
  80. }
  81. // 2 url forms
  82. // @routeName?key1=value1&key2=value2...
  83. // module/action?key1=value1&key2=value2...
  84. // first slash optional
  85. if ($url[0] == '/')
  86. {
  87. $url = substr($url, 1);
  88. }
  89. // routeName?
  90. if ($url[0] == '@')
  91. {
  92. $route = substr($url, 1);
  93. }
  94. else if (false !== strpos($url, '/'))
  95. {
  96. list($params['module'], $params['action']) = explode('/', $url);
  97. }
  98. else if (!$queryString)
  99. {
  100. $route = $givenUrl;
  101. }
  102. else
  103. {
  104. throw new InvalidArgumentException(sprintf('An internal URI must contain a module and an action (module/action) ("%s" given).', $givenUrl));
  105. }
  106. // split the query string
  107. if ($queryString)
  108. {
  109. $matched = preg_match_all('/
  110. ([^&=]+) # key
  111. = # =
  112. (.*?) # value
  113. (?:
  114. (?=&[^&=]+=) | $ # followed by another key= or the end of the string
  115. )
  116. /x', $queryString, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
  117. foreach ($matches as $match)
  118. {
  119. $params[urldecode($match[1][0])] = urldecode($match[2][0]);
  120. }
  121. // check that all string is matched
  122. if (!$matched)
  123. {
  124. throw new sfParseException(sprintf('Unable to parse query string "%s".', $queryString));
  125. }
  126. }
  127. return array($route, $params);
  128. }
  129. /**
  130. * Redirects the request to another URL.
  131. *
  132. * @param string $url An associative array of URL parameters or an internal URI as a string
  133. * @param int $delay A delay in seconds before redirecting. This is only needed on
  134. * browsers that do not support HTTP headers
  135. * @param int $statusCode The status code
  136. *
  137. * @throws InvalidArgumentException If the url argument is null or an empty string
  138. */
  139. public function redirect($url, $delay = 0, $statusCode = 302)
  140. {
  141. if (empty($url))
  142. {
  143. throw new InvalidArgumentException('Cannot redirect to an empty URL.');
  144. }
  145. $url = $this->genUrl($url, true);
  146. if (sfConfig::get('sf_logging_enabled'))
  147. {
  148. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Redirect to "%s"', $url))));
  149. }
  150. // redirect
  151. $response = $this->context->getResponse();
  152. $response->clearHttpHeaders();
  153. $response->setStatusCode($statusCode);
  154. $response->setHttpHeader('Location', $url);
  155. $response->setContent(sprintf('<html><head><meta http-equiv="refresh" content="%d;url=%s"/></head></html>', $delay, htmlspecialchars($url, ENT_QUOTES, sfConfig::get('sf_charset'))));
  156. $response->send();
  157. }
  158. }

Debug toolbar