From 1f1090424b714ff854eed780f9998f8829aaba74 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 22:12:25 +0200 Subject: [PATCH] Handle different mime types as results --- Message/Http/Header.php | 191 +++++++++++++++++++ Message/{ => Http}/RequestMethod.php | 0 Message/{ => Http}/RequestStatus.php | 0 Message/Http/Response.php | 273 ++++----------------------- Message/MessageInterface.php | 40 +--- Message/ResponseAbstract.php | 24 +-- Views/View.php | 32 +++- 7 files changed, 262 insertions(+), 298 deletions(-) create mode 100644 Message/Http/Header.php rename Message/{ => Http}/RequestMethod.php (100%) rename Message/{ => Http}/RequestStatus.php (100%) diff --git a/Message/Http/Header.php b/Message/Http/Header.php new file mode 100644 index 000000000..dd0943f2e --- /dev/null +++ b/Message/Http/Header.php @@ -0,0 +1,191 @@ + + * @author Dennis Eichhorn + * @copyright 2013 Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ +namespace phpOMS\Message\Http; + +use phpOMS\Contract\ArrayableInterface; +use phpOMS\Contract\RenderableInterface; +use phpOMS\Message\ResponseAbstract; +use phpOMS\Model\Html\Head; +use phpOMS\Utils\ArrayUtils; +use phpOMS\DataStorage\Cookie\CookieJar; +use phpOMS\DataStorage\Session\HttpSession; + +/** + * Response class. + * + * @category Framework + * @package phpOMS\Response + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +class Header extends HeaderAbstract +{ + + /** + * Header. + * + * @var string[][] + * @since 1.0.0 + */ + private $header = []; + + public function __constrct() + { + $this->setHeader('Content-Type', 'text/html; charset=utf-8'); + } + + /** + * Remove header by ID. + * + * @param int $key Header key + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function remove(int $key) : bool + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + if (isset($this->header[$key])) { + unset($this->header[$key]); + + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function get(string $id) : array + { + return $this->header[$id] ?? []; + } + + /** + * {@inheritdoc} + */ + public function has(string $name) : bool + { + return array_key_exists($name, $this->header); + } + + /** + * {@inheritdoc} + */ + public function set($key, string $header, bool $overwrite = false) : bool + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + if (!$overwrite && isset($this->header[$key])) { + return false; + } elseif ($overwrite) { + unset($this->header[$key]); + } + + if (!isset($this->header[$key])) { + $this->header[$key] = []; + } + + $this->header[$key][] = $header; + + return true; + } + + /** + * Push all headers. + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function push() + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + foreach ($this->header as $name => $arr) { + foreach ($arr as $ele => $value) { + header($name . ': ' . $value); + } + } + + $this->lock(); + } + + private function lock() + { + CookieJar::lock(); + HttpSession::lock(); + self::$isLocked = true; + } + + /** + * Generate header automatically based on code. + * + * @param string $code HTTP status code + * + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function generate(string $code) + { + switch($code) { + case RequestStatus::R_403: + $this->generate403(); + break; + case RequestStatus::R_406: + $this->generate406(); + break; + case RequestStatus::R_407: + $this->generate503(); + break; + default: + throw new \Exception('Unexpected header code'); + } + } + + private function generate403() + { + $this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden'); + $this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden'); + } + + private function generate406() + { + $this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable'); + $this->setHeader('Status', 'Status: 406 Not acceptable'); + } + + private function generate503() + { + $this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable'); + $this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable'); + $this->setHeader('Retry-After', 'Retry-After: 300'); + } +} \ No newline at end of file diff --git a/Message/RequestMethod.php b/Message/Http/RequestMethod.php similarity index 100% rename from Message/RequestMethod.php rename to Message/Http/RequestMethod.php diff --git a/Message/RequestStatus.php b/Message/Http/RequestStatus.php similarity index 100% rename from Message/RequestStatus.php rename to Message/Http/RequestStatus.php diff --git a/Message/Http/Response.php b/Message/Http/Response.php index c44a01cba..fe4ed8917 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -36,25 +36,6 @@ use phpOMS\DataStorage\Session\HttpSession; */ class Response extends ResponseAbstract implements RenderableInterface { - - /** - * Header. - * - * @var string[][] - * @since 1.0.0 - */ - private $header = []; - - /** - * html head. - * - * @var Head - * @since 1.0.0 - */ - private $head = null; - - private static $isLocked = false; - /** * Constructor. * @@ -63,96 +44,6 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function __construct() { - $this->setHeader('Content-Type', 'text/html; charset=utf-8'); - $this->head = new Head(); - } - - /** - * Push header by ID. - * - * @param mixed $name Header ID - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function pushHeaderId($name) - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - foreach ($this->header[$name] as $key => $value) { - header($name, $value); - } - - $this->lock(); - } - - /** - * Remove header by ID. - * - * @param int $key Header key - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function removeHeader(int $key) : bool - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - if (isset($this->header[$key])) { - unset($this->header[$key]); - - return true; - } - - return false; - } - - /** - * Generate header automatically based on code. - * - * @param int $code HTTP status code - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function generateHeader(int $code) - { - if ($code === 403) { - $this->generate403(); - } elseif ($code === 406) { - $this->generate406(); - } elseif ($code === 503) { - $this->generate503(); - } - } - - private function generate403() - { - $this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden'); - $this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden'); - } - - private function generate406() - { - $this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable'); - $this->setHeader('Status', 'Status: 406 Not acceptable'); - } - - private function generate503() - { - $this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable'); - $this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable'); - $this->setHeader('Retry-After', 'Retry-After: 300'); } /** @@ -187,44 +78,6 @@ class Response extends ResponseAbstract implements RenderableInterface ob_end_flush(); } - /** - * Generate response. - * - * @return \Iterator - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getYield() : \Iterator - { - yield $this->head->render(); - - foreach ($this->response as $key => $response) { - yield $response; - } - } - - /** - * Push all headers. - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function pushHeader() - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - foreach ($this->header as $name => $arr) { - foreach ($arr as $ele => $value) { - header($name . ': ' . $value); - } - } - - $this->lock(); - } - /** * Remove response by ID. * @@ -250,14 +103,6 @@ class Response extends ResponseAbstract implements RenderableInterface return false; } - /** - * {@inheritdoc} - */ - public function getHead() - { - return $this->head; - } - /** * {@inheritdoc} */ @@ -266,22 +111,6 @@ class Response extends ResponseAbstract implements RenderableInterface return '1.0'; } - /** - * {@inheritdoc} - */ - public function getHeaders() : array - { - return $this->header; - } - - /** - * {@inheritdoc} - */ - public function hasHeader(string $name) : bool - { - return array_key_exists($name, $this->header); - } - /** * {@inheritdoc} */ @@ -302,14 +131,26 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function render() : string { - $render = $this->head->render(); + switch($this->header->get('Content-Type')) { + case MimeType::M_JSON: + return $this->getJson(); + default: + return $this->getRaw(); + } + } + + private function getJson() : string + { + return json_encode($this->getArray()); + } + + private function getRaw() : string + { + $render = ''; - // todo: fix api return - // right now it is_object hence not printing the request key => object and only object->render(); - // this can't be changed easily since view uses this as well and this mustn't print a key. maybe view instanceof View? foreach ($this->response as $key => $response) { - if (is_object($response)) { - $render .= $response->render(); + if ($response instanceOf \Serializable) { + $render .= $response->serialize(); } elseif (is_string($response) || is_numeric($response)) { $render .= $response; } elseif (is_array($response)) { @@ -319,34 +160,29 @@ class Response extends ResponseAbstract implements RenderableInterface throw new \Exception('Wrong response type'); } } - + return $render; } - /** - * {@inheritdoc} - */ - public function toCsv() : string + private function getArray() : array { - return ArrayUtils::arrayToCSV($this->toArray()); - } + $result = []; - /** - * {@inheritdoc} - */ - public function toArray() : array - { - $arr = []; - - foreach ($this->response as $key => $response) { - if ($response instanceof ArrayableInterface) { - $arr = ArrayUtils::setArray($key, $arr, $response->toArray(), ':'); + foreach($this->response as $key => $response) { + if($reponse instanceof Views) { + $result += $response->getArray(); + } elseif(is_array($response)) { + $result += $response; + } elseif(is_scalar($response)) { + $result[] = $response; + } elseif($response instanceof \Serializable) { + $result[] = $response->serialize(); } else { - $arr = ArrayUtils::setArray($key, $arr, $response, ':'); + throw new \Exception('Wrong response type'); } } - return $arr; + return $result; } /** @@ -354,49 +190,6 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function getReasonPhrase() : string { - return $this->getHeader('Status'); - } - - /** - * {@inheritdoc} - */ - public function getHeader(string $name) - { - if (isset($this->header[$name])) { - return $this->header[$name]; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function setHeader($key, string $header, bool $overwrite = false) : bool - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - if (!$overwrite && isset($this->header[$key])) { - return false; - } elseif ($overwrite) { - unset($this->header[$key]); - } - - if (!isset($this->header[$key])) { - $this->header[$key] = []; - } - - $this->header[$key][] = $header; - - return true; - } - - private function lock() - { - CookieJar::lock(); - HttpSession::lock(); - self::$isLocked = true; + return $this->header->getHeader('Status'); } } diff --git a/Message/MessageInterface.php b/Message/MessageInterface.php index ad0984cb2..853e4fd6f 100644 --- a/Message/MessageInterface.php +++ b/Message/MessageInterface.php @@ -45,45 +45,7 @@ interface MessageInterface * @since 1.0.0 * @author Dennis Eichhorn */ - public function getHeaders() : array; - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Header name - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function hasHeader(string $name) : bool; - - /** - * Retrieves a message header value by the given case-insensitive name. - * - * @param string $name Header name - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getHeader(string $name); - - /** - * Add header by ID. - * - * @param mixed $key Header ID - * @param string $header Header string - * @param bool $overwrite Overwrite existing headers - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function setHeader($key, string $header, bool $overwrite = true); + public function getHeader() : HeaderAbstract; /** * Gets the body of the message. diff --git a/Message/ResponseAbstract.php b/Message/ResponseAbstract.php index c54d694b6..205927c03 100644 --- a/Message/ResponseAbstract.php +++ b/Message/ResponseAbstract.php @@ -66,10 +66,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, */ protected $account = null; - /** - * {@inheritdoc} - */ - abstract public function setHeader($key, string $header, bool $overwrite = true); + protected $header = null; /** * {@inheritdoc} @@ -125,7 +122,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, public function setStatusCode(string $status) { $this->status = $status; - $this->generateHeader($status); + $this->header->generate($status); } /** @@ -160,15 +157,10 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, return json_encode($this->toArray()); } - /** - * Generate header automatically based on code. - * - * @param int $code HTTP status code - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - abstract public function generateHeader(int $code); + public function getHeader() : HeaderAbstract + { + return $this->header; + } + + public function getBody() : string; } diff --git a/Views/View.php b/Views/View.php index 1c6b62cad..028197018 100644 --- a/Views/View.php +++ b/Views/View.php @@ -34,7 +34,7 @@ use phpOMS\Validation\Validator; * @link http://orange-management.com * @since 1.0.0 */ -class View implements RenderableInterface +class View implements \Serializeable { /** @@ -288,9 +288,14 @@ class View implements RenderableInterface ob_start(); /** @noinspection PhpIncludeInspection */ - include $path; + $data = include $path; + $ob = ob_get_clean(); - return ob_get_clean(); + if(is_array($data)) { + return $data; + } + + return $ob; } /** @@ -355,4 +360,25 @@ class View implements RenderableInterface $this->data[$id] = $data; } + public function getArray() : array + { + $viewArray = []; + + $viewArray[] = $this->render(); + + foreach($this->views as $key => $view) { + $viewArray[$key] = $view->getArray(); + } + } + + public function serialize() + { + return $this->renderAll(); + } + + public function unserialize($raw) + { + + } + }