PageRenderTime 59ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/standard/tags/release-1.5.0RC1/library/Zend/Controller/Action/Helper/Redirector.php

https://github.com/jorgenils/zend-framework
PHP | 496 lines | 216 code | 50 blank | 230 comment | 43 complexity | a9b5c46e81b14a729a29e23f8ed48165 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Controller
  17. * @subpackage Action_Helper
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /** Zend_Controller_Action_Exception */
  22. require_once 'Zend/Controller/Action/Exception.php';
  23. /** Zend_Controller_Action_Helper_Abstract */
  24. require_once 'Zend/Controller/Action/Helper/Abstract.php';
  25. /**
  26. * @category Zend
  27. * @package Zend_Controller
  28. * @subpackage Zend_Controller_Action
  29. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_Controller_Action_Helper_Redirector extends Zend_Controller_Action_Helper_Abstract
  33. {
  34. /**
  35. * HTTP status code for redirects
  36. * @var int
  37. */
  38. protected $_code = 302;
  39. /**
  40. * Whether or not calls to _redirect() should exit script execution
  41. * @var bool
  42. */
  43. protected $_exit = true;
  44. /**
  45. * Whether or not _redirect() should attempt to prepend the base URL to the
  46. * passed URL (if it's a relative URL)
  47. * @var bool
  48. */
  49. protected $_prependBase = true;
  50. /**
  51. * Url to which to redirect
  52. * @var string
  53. */
  54. protected $_redirectUrl = null;
  55. /**
  56. * Whether or not to use an absolute URI when redirecting
  57. * @var bool
  58. */
  59. protected $_useAbsoluteUri = false;
  60. /**
  61. * Retrieve HTTP status code to emit on {@link _redirect()} call
  62. *
  63. * @return int
  64. */
  65. public function getCode()
  66. {
  67. return $this->_code;
  68. }
  69. /**
  70. * Validate HTTP status redirect code
  71. *
  72. * @param int $code
  73. * @return true
  74. * @throws Zend_Controller_Action_Exception on invalid HTTP status code
  75. */
  76. protected function _checkCode($code)
  77. {
  78. if (!is_int($code) || (300 > $code) || (307 < $code)) {
  79. require_once 'Zend/Controller/Exception.php';
  80. throw new Zend_Controller_Action_Exception('Invalid redirect HTTP status code (' . $code . ')');
  81. }
  82. return true;
  83. }
  84. /**
  85. * Retrieve HTTP status code for {@link _redirect()} behaviour
  86. *
  87. * @param int $code
  88. * @return Zend_Controller_Action_Helper_Redirector
  89. */
  90. public function setCode($code)
  91. {
  92. $this->_checkCode($code);
  93. $this->_code = $code;
  94. return $this;
  95. }
  96. /**
  97. * Retrieve flag for whether or not {@link _redirect()} will exit when finished.
  98. *
  99. * @return bool
  100. */
  101. public function getExit()
  102. {
  103. return $this->_exit;
  104. }
  105. /**
  106. * Retrieve exit flag for {@link _redirect()} behaviour
  107. *
  108. * @param bool $flag
  109. * @return Zend_Controller_Action_Helper_Redirector
  110. */
  111. public function setExit($flag)
  112. {
  113. $this->_exit = ($flag) ? true : false;
  114. return $this;
  115. }
  116. /**
  117. * Retrieve flag for whether or not {@link _redirect()} will prepend the
  118. * base URL on relative URLs
  119. *
  120. * @return bool
  121. */
  122. public function getPrependBase()
  123. {
  124. return $this->_prependBase;
  125. }
  126. /**
  127. * Retrieve 'prepend base' flag for {@link _redirect()} behaviour
  128. *
  129. * @param bool $flag
  130. * @return Zend_Controller_Action_Helper_Redirector
  131. */
  132. public function setPrependBase($flag)
  133. {
  134. $this->_prependBase = ($flag) ? true : false;
  135. return $this;
  136. }
  137. /**
  138. * Return use absolute URI flag
  139. *
  140. * @return boolean
  141. */
  142. public function getUseAbsoluteUri()
  143. {
  144. return $this->_useAbsoluteUri;
  145. }
  146. /**
  147. * Set use absolute URI flag
  148. *
  149. * @param bool $flag
  150. * @return Zend_Controller_Action_Helper_Redirector
  151. */
  152. public function setUseAbsoluteUri($flag = true)
  153. {
  154. $this->_useAbsoluteUri = ($flag) ? true : false;
  155. return $this;
  156. }
  157. /**
  158. * Set redirect in response object
  159. *
  160. * @return void
  161. */
  162. protected function _redirect($url)
  163. {
  164. $this->_redirectUrl = $url;
  165. if ($this->getUseAbsoluteUri() && !preg_match('#^(https?|ftp)://#', $url)) {
  166. $host = $_SERVER['HTTP_HOST'];
  167. $proto = (empty($_SERVER['HTTPS'])) ? 'http' : 'https';
  168. $port = $_SERVER['SERVER_PORT'];
  169. $uri = $proto . '://' . $host;
  170. if ((('http' == $proto) && (80 != $port)) || (('https' == $proto) && (443 != $port))) {
  171. $uri .= ':' . $port;
  172. }
  173. $url = $uri . '/' . ltrim($url, '/');
  174. }
  175. $this->getResponse()->setRedirect($url, $this->getCode());
  176. }
  177. /**
  178. * Retrieve currently set URL for redirect
  179. *
  180. * @return string
  181. */
  182. public function getRedirectUrl()
  183. {
  184. return $this->_redirectUrl;
  185. }
  186. /**
  187. * Determine if the baseUrl should be prepended, and prepend if necessary
  188. *
  189. * @param string $url
  190. * @return string
  191. */
  192. protected function _prependBase($url)
  193. {
  194. if ($this->getPrependBase()) {
  195. $request = $this->getRequest();
  196. if ($request instanceof Zend_Controller_Request_Http) {
  197. $base = rtrim($request->getBaseUrl(), '/');
  198. if (!empty($base) && ('/' != $base)) {
  199. $url = $base . '/' . ltrim($url, '/');
  200. }
  201. }
  202. }
  203. return $url;
  204. }
  205. /**
  206. * Set a redirect URL of the form /module/controller/action/params
  207. *
  208. * @param string $action
  209. * @param string $controller
  210. * @param string $module
  211. * @param array $params
  212. * @return void
  213. */
  214. public function setGoto($action, $controller = null, $module = null, array $params = array())
  215. {
  216. $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
  217. $request = $this->getRequest();
  218. if (null === $module) {
  219. $module = $request->getModuleName();
  220. if ($module == $dispatcher->getDefaultModule()) {
  221. $module = '';
  222. }
  223. }
  224. if (null === $controller) {
  225. $controller = $request->getControllerName();
  226. if (empty($controller)) {
  227. $controller = $dispatcher->getDefaultControllerName();
  228. }
  229. }
  230. $paramsNormalized = array();
  231. foreach ($params as $key => $value) {
  232. $paramsNormalized[] = $key . '/' . $value;
  233. }
  234. $paramsString = implode('/', $paramsNormalized);
  235. if (!empty($paramsString)) {
  236. $url = $module . '/' . $controller . '/' . $action . '/' . $paramsString;
  237. } else {
  238. if ($action != $dispatcher->getDefaultAction()) {
  239. $url = $module . '/' . $controller . '/' . $action;
  240. } else {
  241. if ($controller != $dispatcher->getDefaultControllerName()) {
  242. $url = $module . '/' . $controller;
  243. } else {
  244. $url = $module;
  245. }
  246. }
  247. }
  248. $url = '/' . trim($url, '/');
  249. $url = $this->_prependBase($url);
  250. $this->_redirect($url);
  251. }
  252. /**
  253. * Build a URL based on a route
  254. *
  255. * @param array $urlOptions
  256. * @param string $name Route name
  257. * @param boolean $reset
  258. * @return void
  259. */
  260. public function setGotoRoute(array $urlOptions = array(), $name = null, $reset = false)
  261. {
  262. $router = Zend_Controller_Front::getInstance()->getRouter();
  263. if (empty($name)) {
  264. try {
  265. $name = $router->getCurrentRouteName();
  266. } catch (Zend_Controller_Router_Exception $e) {
  267. if ($router->hasRoute('default')) {
  268. $name = 'default';
  269. }
  270. }
  271. }
  272. $route = $router->getRoute($name);
  273. $request = $this->getRequest();
  274. $url = rtrim($request->getBaseUrl(), '/') . '/';
  275. $url .= $route->assemble($urlOptions, $reset);
  276. $this->_redirect($url);
  277. }
  278. /**
  279. * Set a redirect URL string
  280. *
  281. * By default, emits a 302 HTTP status header, prepends base URL as defined
  282. * in request object if url is relative, and halts script execution by
  283. * calling exit().
  284. *
  285. * $options is an optional associative array that can be used to control
  286. * redirect behaviour. The available option keys are:
  287. * - exit: boolean flag indicating whether or not to halt script execution when done
  288. * - prependBase: boolean flag indicating whether or not to prepend the base URL when a relative URL is provided
  289. * - code: integer HTTP status code to use with redirect. Should be between 300 and 307.
  290. *
  291. * _redirect() sets the Location header in the response object. If you set
  292. * the exit flag to false, you can override this header later in code
  293. * execution.
  294. *
  295. * If the exit flag is true (true by default), _redirect() will write and
  296. * close the current session, if any.
  297. *
  298. * @param string $url
  299. * @param array $options
  300. * @return void
  301. */
  302. public function setGotoUrl($url, array $options = array())
  303. {
  304. // prevent header injections
  305. $url = str_replace(array("\n", "\r"), '', $url);
  306. $exit = $this->getExit();
  307. $prependBase = $this->getPrependBase();
  308. $code = $this->getCode();
  309. if (null !== $options) {
  310. if (isset($options['exit'])) {
  311. $this->setExit(($options['exit']) ? true : false);
  312. }
  313. if (isset($options['prependBase'])) {
  314. $this->setPrependBase(($options['prependBase']) ? true : false);
  315. }
  316. if (isset($options['code'])) {
  317. $this->setCode($options['code']);
  318. }
  319. }
  320. // If relative URL, decide if we should prepend base URL
  321. if (!preg_match('|^[a-z]+://|', $url)) {
  322. $url = $this->_prependBase($url);
  323. }
  324. $this->_redirect($url);
  325. }
  326. /**
  327. * Perform a redirect to an action/controller/module with params
  328. *
  329. * @param string $action
  330. * @param string $controller
  331. * @param string $module
  332. * @param array $params
  333. * @return void
  334. */
  335. public function goto($action, $controller = null, $module = null, array $params = array())
  336. {
  337. $this->setGoto($action, $controller, $module, $params);
  338. if ($this->getExit()) {
  339. $this->redirectAndExit();
  340. }
  341. }
  342. /**
  343. * Perform a redirect to an action/controller/module with params, forcing an immdiate exit
  344. *
  345. * @param mixed $action
  346. * @param mixed $controller
  347. * @param mixed $module
  348. * @param array $params
  349. * @return void
  350. */
  351. public function gotoAndExit($action, $controller = null, $module = null, array $params = array())
  352. {
  353. $this->setGoto($action, $controller, $module, $params);
  354. $this->redirectAndExit();
  355. }
  356. /**
  357. * Redirect to a route-based URL
  358. *
  359. * Uses route's assemble method tobuild the URL; route is specified by $name;
  360. * default route is used if none provided.
  361. *
  362. * @param array $urlOptions Array of key/value pairs used to assemble URL
  363. * @param string $name
  364. * @param boolean $reset
  365. * @return void
  366. */
  367. public function gotoRoute(array $urlOptions = array(), $name = null, $reset = false)
  368. {
  369. $this->setGotoRoute($urlOptions, $name, $reset);
  370. if ($this->getExit()) {
  371. $this->redirectAndExit();
  372. }
  373. }
  374. /**
  375. * Redirect to a route-based URL, and immediately exit
  376. *
  377. * Uses route's assemble method tobuild the URL; route is specified by $name;
  378. * default route is used if none provided.
  379. *
  380. * @param array $urlOptions Array of key/value pairs used to assemble URL
  381. * @param string $name
  382. * @param boolean $reset
  383. * @return void
  384. */
  385. public function gotoRouteAndExit(array $urlOptions = array(), $name = null, $reset = false)
  386. {
  387. $this->setGotoRoute($urlOptions, $name, $reset);
  388. $this->redirectAndExit();
  389. }
  390. /**
  391. * Perform a redirect to a url
  392. *
  393. * @param string $url
  394. * @param array $options
  395. * @return void
  396. */
  397. public function gotoUrl($url, array $options = array())
  398. {
  399. $this->setGotoUrl($url, $options);
  400. if ($this->getExit()) {
  401. $this->redirectAndExit();
  402. }
  403. }
  404. /**
  405. * Set a URL string for a redirect, perform redirect, and immediately exit
  406. *
  407. * @param string $url
  408. * @param array $options
  409. * @return void
  410. */
  411. public function gotoUrlAndExit($url, array $options = array())
  412. {
  413. $this->gotoUrl($url, $options);
  414. $this->redirectAndExit();
  415. }
  416. /**
  417. * exit(): Perform exit for redirector
  418. *
  419. * @return void
  420. */
  421. public function redirectAndExit()
  422. {
  423. // Close session, if started
  424. if (class_exists('Zend_Session', false) && Zend_Session::isStarted()) {
  425. Zend_Session::writeClose();
  426. } elseif (isset($_SESSION)) {
  427. session_write_close();
  428. }
  429. $this->getResponse()->sendHeaders();
  430. exit();
  431. }
  432. /**
  433. * direct(): Perform helper when called as
  434. * $this->_helper->redirector($action, $controller, $module, $params)
  435. *
  436. * @param string $action
  437. * @param string $controller
  438. * @param string $module
  439. * @param array $params
  440. * @return void
  441. */
  442. public function direct($action, $controller = null, $module = null, array $params = array())
  443. {
  444. $this->goto($action, $controller, $module, $params);
  445. }
  446. }