PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/devblocks/libs/ZendFramework/Zend/Controller/Response/Abstract.php

https://github.com/sluther/portsensor
PHP | 739 lines | 352 code | 81 blank | 306 comment | 67 complexity | af1e26a38b2008f743d3c0c7bfd94ab0 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause
  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. * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. /**
  21. * Zend_Controller_Response_Abstract
  22. *
  23. * Base class for Zend_Controller responses
  24. *
  25. * @package Zend_Controller
  26. * @subpackage Response
  27. * @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
  28. * @license http://framework.zend.com/license/new-bsd New BSD License
  29. */
  30. abstract class Zend_Controller_Response_Abstract
  31. {
  32. /**
  33. * Body content
  34. * @var array
  35. */
  36. protected $_body = array();
  37. /**
  38. * Exception stack
  39. * @var Exception
  40. */
  41. protected $_exceptions = array();
  42. /**
  43. * Array of headers. Each header is an array with keys 'name' and 'value'
  44. * @var array
  45. */
  46. protected $_headers = array();
  47. /**
  48. * Array of raw headers. Each header is a single string, the entire header to emit
  49. * @var array
  50. */
  51. protected $_headersRaw = array();
  52. /**
  53. * HTTP response code to use in headers
  54. * @var int
  55. */
  56. protected $_httpResponseCode = 200;
  57. /**
  58. * Flag; is this response a redirect?
  59. * @var boolean
  60. */
  61. protected $_isRedirect = false;
  62. /**
  63. * Whether or not to render exceptions; off by default
  64. * @var boolean
  65. */
  66. protected $_renderExceptions = false;
  67. /**
  68. * Flag; if true, when header operations are called after headers have been
  69. * sent, an exception will be raised; otherwise, processing will continue
  70. * as normal. Defaults to true.
  71. *
  72. * @see canSendHeaders()
  73. * @var boolean
  74. */
  75. public $headersSentThrowsException = true;
  76. /**
  77. * Set a header
  78. *
  79. * If $replace is true, replaces any headers already defined with that
  80. * $name.
  81. *
  82. * @param string $name
  83. * @param string $value
  84. * @param boolean $replace
  85. * @return Zend_Controller_Response_Abstract
  86. */
  87. public function setHeader($name, $value, $replace = false)
  88. {
  89. $this->canSendHeaders(true);
  90. $name = (string) $name;
  91. $value = (string) $value;
  92. if ($replace) {
  93. foreach ($this->_headers as $key => $header) {
  94. if ($name == $header['name']) {
  95. unset($this->_headers[$key]);
  96. }
  97. }
  98. }
  99. $this->_headers[] = array(
  100. 'name' => $name,
  101. 'value' => $value,
  102. 'replace' => $replace
  103. );
  104. return $this;
  105. }
  106. /**
  107. * Set redirect URL
  108. *
  109. * Sets Location header and response code. Forces replacement of any prior
  110. * redirects.
  111. *
  112. * @param string $url
  113. * @param int $code
  114. * @return Zend_Controller_Response_Abstract
  115. */
  116. public function setRedirect($url, $code = 302)
  117. {
  118. $this->canSendHeaders(true);
  119. $this->setHeader('Location', $url, true)
  120. ->setHttpResponseCode($code);
  121. return $this;
  122. }
  123. /**
  124. * Is this a redirect?
  125. *
  126. * @return boolean
  127. */
  128. public function isRedirect()
  129. {
  130. return $this->_isRedirect;
  131. }
  132. /**
  133. * Return array of headers; see {@link $_headers} for format
  134. *
  135. * @return array
  136. */
  137. public function getHeaders()
  138. {
  139. return $this->_headers;
  140. }
  141. /**
  142. * Clear headers
  143. *
  144. * @return Zend_Controller_Response_Abstract
  145. */
  146. public function clearHeaders()
  147. {
  148. $this->_headers = array();
  149. return $this;
  150. }
  151. /**
  152. * Set raw HTTP header
  153. *
  154. * Allows setting non key => value headers, such as status codes
  155. *
  156. * @param string $value
  157. * @return Zend_Controller_Response_Abstract
  158. */
  159. public function setRawHeader($value)
  160. {
  161. $this->canSendHeaders(true);
  162. if ('Location' == substr($value, 0, 8)) {
  163. $this->_isRedirect = true;
  164. }
  165. $this->_headersRaw[] = (string) $value;
  166. return $this;
  167. }
  168. /**
  169. * Retrieve all {@link setRawHeader() raw HTTP headers}
  170. *
  171. * @return array
  172. */
  173. public function getRawHeaders()
  174. {
  175. return $this->_headersRaw;
  176. }
  177. /**
  178. * Clear all {@link setRawHeader() raw HTTP headers}
  179. *
  180. * @return Zend_Controller_Response_Abstract
  181. */
  182. public function clearRawHeaders()
  183. {
  184. $this->_headersRaw = array();
  185. return $this;
  186. }
  187. /**
  188. * Clear all headers, normal and raw
  189. *
  190. * @return Zend_Controller_Response_Abstract
  191. */
  192. public function clearAllHeaders()
  193. {
  194. return $this->clearHeaders()
  195. ->clearRawHeaders();
  196. }
  197. /**
  198. * Set HTTP response code to use with headers
  199. *
  200. * @param int $code
  201. * @return Zend_Controller_Response_Abstract
  202. */
  203. public function setHttpResponseCode($code)
  204. {
  205. if (!is_int($code) || (100 > $code) || (599 < $code)) {
  206. require_once 'Zend/Controller/Response/Exception.php';
  207. throw new Zend_Controller_Response_Exception('Invalid HTTP response code');
  208. }
  209. if ((300 <= $code) && (307 >= $code)) {
  210. $this->_isRedirect = true;
  211. } else {
  212. $this->_isRedirect = false;
  213. }
  214. $this->_httpResponseCode = $code;
  215. return $this;
  216. }
  217. /**
  218. * Retrieve HTTP response code
  219. *
  220. * @return int
  221. */
  222. public function getHttpResponseCode()
  223. {
  224. return $this->_httpResponseCode;
  225. }
  226. /**
  227. * Can we send headers?
  228. *
  229. * @param boolean $throw Whether or not to throw an exception if headers have been sent; defaults to false
  230. * @return boolean
  231. * @throws Zend_Controller_Response_Exception
  232. */
  233. public function canSendHeaders($throw = false)
  234. {
  235. $ok = headers_sent($file, $line);
  236. if ($ok && $throw && $this->headersSentThrowsException) {
  237. require_once 'Zend/Controller/Response/Exception.php';
  238. throw new Zend_Controller_Response_Exception('Cannot send headers; headers already sent in ' . $file . ', line ' . $line);
  239. }
  240. return !$ok;
  241. }
  242. /**
  243. * Send all headers
  244. *
  245. * Sends any headers specified. If an {@link setHttpResponseCode() HTTP response code}
  246. * has been specified, it is sent with the first header.
  247. *
  248. * @return Zend_Controller_Response_Abstract
  249. */
  250. public function sendHeaders()
  251. {
  252. // Only check if we can send headers if we have headers to send
  253. if (count($this->_headersRaw) || count($this->_headers) || (200 != $this->_httpResponseCode)) {
  254. $this->canSendHeaders(true);
  255. } elseif (200 == $this->_httpResponseCode) {
  256. // Haven't changed the response code, and we have no headers
  257. return $this;
  258. }
  259. $httpCodeSent = false;
  260. foreach ($this->_headersRaw as $header) {
  261. if (!$httpCodeSent && $this->_httpResponseCode) {
  262. header($header, true, $this->_httpResponseCode);
  263. $httpCodeSent = true;
  264. } else {
  265. header($header);
  266. }
  267. }
  268. foreach ($this->_headers as $header) {
  269. if (!$httpCodeSent && $this->_httpResponseCode) {
  270. header($header['name'] . ': ' . $header['value'], $header['replace'], $this->_httpResponseCode);
  271. $httpCodeSent = true;
  272. } else {
  273. header($header['name'] . ': ' . $header['value'], $header['replace']);
  274. }
  275. }
  276. if (!$httpCodeSent) {
  277. header('HTTP/1.1 ' . $this->_httpResponseCode);
  278. $httpCodeSent = true;
  279. }
  280. return $this;
  281. }
  282. /**
  283. * Set body content
  284. *
  285. * If $name is not passed, or is not a string, resets the entire body and
  286. * sets the 'default' key to $content.
  287. *
  288. * If $name is a string, sets the named segment in the body array to
  289. * $content.
  290. *
  291. * @param string $content
  292. * @param null|string $name
  293. * @return Zend_Controller_Response_Abstract
  294. */
  295. public function setBody($content, $name = null)
  296. {
  297. if ((null === $name) || !is_string($name)) {
  298. $this->_body = array('default' => (string) $content);
  299. } else {
  300. $this->_body[$name] = (string) $content;
  301. }
  302. return $this;
  303. }
  304. /**
  305. * Append content to the body content
  306. *
  307. * @param string $content
  308. * @param null|string $name
  309. * @return Zend_Controller_Response_Abstract
  310. */
  311. public function appendBody($content, $name = null)
  312. {
  313. if ((null === $name) || !is_string($name)) {
  314. if (isset($this->_body['default'])) {
  315. $this->_body['default'] .= (string) $content;
  316. } else {
  317. return $this->append('default', $content);
  318. }
  319. } elseif (isset($this->_body[$name])) {
  320. $this->_body[$name] .= (string) $content;
  321. } else {
  322. return $this->append($name, $content);
  323. }
  324. return $this;
  325. }
  326. /**
  327. * Clear body array
  328. *
  329. * With no arguments, clears the entire body array. Given a $name, clears
  330. * just that named segment; if no segment matching $name exists, returns
  331. * false to indicate an error.
  332. *
  333. * @param string $name Named segment to clear
  334. * @return boolean
  335. */
  336. public function clearBody($name = null)
  337. {
  338. if (null !== $name) {
  339. $name = (string) $name;
  340. if (isset($this->_body[$name])) {
  341. unset($this->_body[$name]);
  342. return true;
  343. }
  344. return false;
  345. }
  346. $this->_body = array();
  347. return true;
  348. }
  349. /**
  350. * Return the body content
  351. *
  352. * If $spec is false, returns the concatenated values of the body content
  353. * array. If $spec is boolean true, returns the body content array. If
  354. * $spec is a string and matches a named segment, returns the contents of
  355. * that segment; otherwise, returns null.
  356. *
  357. * @param boolean $spec
  358. * @return string|array|null
  359. */
  360. public function getBody($spec = false)
  361. {
  362. if (false === $spec) {
  363. ob_start();
  364. $this->outputBody();
  365. return ob_get_clean();
  366. } elseif (true === $spec) {
  367. return $this->_body;
  368. } elseif (is_string($spec) && isset($this->_body[$spec])) {
  369. return $this->_body[$spec];
  370. }
  371. return null;
  372. }
  373. /**
  374. * Append a named body segment to the body content array
  375. *
  376. * If segment already exists, replaces with $content and places at end of
  377. * array.
  378. *
  379. * @param string $name
  380. * @param string $content
  381. * @return Zend_Controller_Response_Abstract
  382. */
  383. public function append($name, $content)
  384. {
  385. if (!is_string($name)) {
  386. require_once 'Zend/Controller/Response/Exception.php';
  387. throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")');
  388. }
  389. if (isset($this->_body[$name])) {
  390. unset($this->_body[$name]);
  391. }
  392. $this->_body[$name] = (string) $content;
  393. return $this;
  394. }
  395. /**
  396. * Prepend a named body segment to the body content array
  397. *
  398. * If segment already exists, replaces with $content and places at top of
  399. * array.
  400. *
  401. * @param string $name
  402. * @param string $content
  403. * @return void
  404. */
  405. public function prepend($name, $content)
  406. {
  407. if (!is_string($name)) {
  408. require_once 'Zend/Controller/Response/Exception.php';
  409. throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")');
  410. }
  411. if (isset($this->_body[$name])) {
  412. unset($this->_body[$name]);
  413. }
  414. $new = array($name => (string) $content);
  415. $this->_body = $new + $this->_body;
  416. return $this;
  417. }
  418. /**
  419. * Insert a named segment into the body content array
  420. *
  421. * @param string $name
  422. * @param string $content
  423. * @param string $parent
  424. * @param boolean $before Whether to insert the new segment before or
  425. * after the parent. Defaults to false (after)
  426. * @return Zend_Controller_Response_Abstract
  427. */
  428. public function insert($name, $content, $parent = null, $before = false)
  429. {
  430. if (!is_string($name)) {
  431. require_once 'Zend/Controller/Response/Exception.php';
  432. throw new Zend_Controller_Response_Exception('Invalid body segment key ("' . gettype($name) . '")');
  433. }
  434. if ((null !== $parent) && !is_string($parent)) {
  435. require_once 'Zend/Controller/Response/Exception.php';
  436. throw new Zend_Controller_Response_Exception('Invalid body segment parent key ("' . gettype($parent) . '")');
  437. }
  438. if (isset($this->_body[$name])) {
  439. unset($this->_body[$name]);
  440. }
  441. if ((null === $parent) || !isset($this->_body[$parent])) {
  442. return $this->append($name, $content);
  443. }
  444. $ins = array($name => (string) $content);
  445. $keys = array_keys($this->_body);
  446. $loc = array_search($parent, $keys);
  447. if (!$before) {
  448. // Increment location if not inserting before
  449. ++$loc;
  450. }
  451. if (0 === $loc) {
  452. // If location of key is 0, we're prepending
  453. $this->_body = $ins + $this->_body;
  454. } elseif ($loc >= (count($this->_body))) {
  455. // If location of key is maximal, we're appending
  456. $this->_body = $this->_body + $ins;
  457. } else {
  458. // Otherwise, insert at location specified
  459. $pre = array_slice($this->_body, 0, $loc);
  460. $post = array_slice($this->_body, $loc);
  461. $this->_body = $pre + $ins + $post;
  462. }
  463. return $this;
  464. }
  465. /**
  466. * Echo the body segments
  467. *
  468. * @return void
  469. */
  470. public function outputBody()
  471. {
  472. foreach ($this->_body as $content) {
  473. echo $content;
  474. }
  475. }
  476. /**
  477. * Register an exception with the response
  478. *
  479. * @param Exception $e
  480. * @return Zend_Controller_Response_Abstract
  481. */
  482. public function setException(Exception $e)
  483. {
  484. $this->_exceptions[] = $e;
  485. return $this;
  486. }
  487. /**
  488. * Retrieve the exception stack
  489. *
  490. * @return array
  491. */
  492. public function getException()
  493. {
  494. return $this->_exceptions;
  495. }
  496. /**
  497. * Has an exception been registered with the response?
  498. *
  499. * @return boolean
  500. */
  501. public function isException()
  502. {
  503. return !empty($this->_exceptions);
  504. }
  505. /**
  506. * Does the response object contain an exception of a given type?
  507. *
  508. * @param string $type
  509. * @return boolean
  510. */
  511. public function hasExceptionOfType($type)
  512. {
  513. foreach ($this->_exceptions as $e) {
  514. if ($e instanceof $type) {
  515. return true;
  516. }
  517. }
  518. return false;
  519. }
  520. /**
  521. * Does the response object contain an exception with a given message?
  522. *
  523. * @param string $message
  524. * @return boolean
  525. */
  526. public function hasExceptionOfMessage($message)
  527. {
  528. foreach ($this->_exceptions as $e) {
  529. if ($message == $e->getMessage()) {
  530. return true;
  531. }
  532. }
  533. return false;
  534. }
  535. /**
  536. * Does the response object contain an exception with a given code?
  537. *
  538. * @param int $code
  539. * @return boolean
  540. */
  541. public function hasExceptionOfCode($code)
  542. {
  543. $code = (int) $code;
  544. foreach ($this->_exceptions as $e) {
  545. if ($code == $e->getCode()) {
  546. return true;
  547. }
  548. }
  549. return false;
  550. }
  551. /**
  552. * Retrieve all exceptions of a given type
  553. *
  554. * @param string $type
  555. * @return false|array
  556. */
  557. public function getExceptionByType($type)
  558. {
  559. $exceptions = array();
  560. foreach ($this->_exceptions as $e) {
  561. if ($e instanceof $type) {
  562. $exceptions[] = $e;
  563. }
  564. }
  565. if (empty($exceptions)) {
  566. $exceptions = false;
  567. }
  568. return $exceptions;
  569. }
  570. /**
  571. * Retrieve all exceptions of a given message
  572. *
  573. * @param string $message
  574. * @return false|array
  575. */
  576. public function getExceptionByMessage($message)
  577. {
  578. $exceptions = array();
  579. foreach ($this->_exceptions as $e) {
  580. if ($message == $e->getMessage()) {
  581. $exceptions[] = $e;
  582. }
  583. }
  584. if (empty($exceptions)) {
  585. $exceptions = false;
  586. }
  587. return $exceptions;
  588. }
  589. /**
  590. * Retrieve all exceptions of a given code
  591. *
  592. * @param mixed $code
  593. * @return void
  594. */
  595. public function getExceptionByCode($code)
  596. {
  597. $code = (int) $code;
  598. $exceptions = array();
  599. foreach ($this->_exceptions as $e) {
  600. if ($code == $e->getCode()) {
  601. $exceptions[] = $e;
  602. }
  603. }
  604. if (empty($exceptions)) {
  605. $exceptions = false;
  606. }
  607. return $exceptions;
  608. }
  609. /**
  610. * Whether or not to render exceptions (off by default)
  611. *
  612. * If called with no arguments or a null argument, returns the value of the
  613. * flag; otherwise, sets it and returns the current value.
  614. *
  615. * @param boolean $flag Optional
  616. * @return boolean
  617. */
  618. public function renderExceptions($flag = null)
  619. {
  620. if (null !== $flag) {
  621. $this->_renderExceptions = $flag ? true : false;
  622. }
  623. return $this->_renderExceptions;
  624. }
  625. /**
  626. * Send the response, including all headers, rendering exceptions if so
  627. * requested.
  628. *
  629. * @return void
  630. */
  631. public function sendResponse()
  632. {
  633. $this->sendHeaders();
  634. if ($this->isException() && $this->renderExceptions()) {
  635. $exceptions = '';
  636. foreach ($this->getException() as $e) {
  637. $exceptions .= $e->__toString() . "\n";
  638. }
  639. echo $exceptions;
  640. return;
  641. }
  642. $this->outputBody();
  643. }
  644. /**
  645. * Magic __toString functionality
  646. *
  647. * Proxies to {@link sendResponse()} and returns response value as string
  648. * using output buffering.
  649. *
  650. * @return string
  651. */
  652. public function __toString()
  653. {
  654. ob_start();
  655. $this->sendResponse();
  656. return ob_get_clean();
  657. }
  658. }