Handle different mime types as results

This commit is contained in:
Dennis Eichhorn 2016-04-02 22:12:25 +02:00
parent a1cbf8f2bb
commit 1f1090424b
7 changed files with 262 additions and 298 deletions

191
Message/Http/Header.php Normal file
View File

@ -0,0 +1,191 @@
<?php
/**
* Orange Management
*
* PHP Version 7.0
*
* @category TBD
* @package TBD
* @author OMS Development Team <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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 <dev@oms.com>
* @author Dennis Eichhorn <d.eichhorn@oms.com>
* @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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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');
}
}

View File

@ -36,25 +36,6 @@ use phpOMS\DataStorage\Session\HttpSession;
*/ */
class Response extends ResponseAbstract implements RenderableInterface 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. * Constructor.
* *
@ -63,96 +44,6 @@ class Response extends ResponseAbstract implements RenderableInterface
*/ */
public function __construct() 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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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(); ob_end_flush();
} }
/**
* Generate response.
*
* @return \Iterator
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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. * Remove response by ID.
* *
@ -250,14 +103,6 @@ class Response extends ResponseAbstract implements RenderableInterface
return false; return false;
} }
/**
* {@inheritdoc}
*/
public function getHead()
{
return $this->head;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -266,22 +111,6 @@ class Response extends ResponseAbstract implements RenderableInterface
return '1.0'; 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} * {@inheritdoc}
*/ */
@ -302,14 +131,26 @@ class Response extends ResponseAbstract implements RenderableInterface
*/ */
public function render() : string 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) { foreach ($this->response as $key => $response) {
if (is_object($response)) { if ($response instanceOf \Serializable) {
$render .= $response->render(); $render .= $response->serialize();
} elseif (is_string($response) || is_numeric($response)) { } elseif (is_string($response) || is_numeric($response)) {
$render .= $response; $render .= $response;
} elseif (is_array($response)) { } elseif (is_array($response)) {
@ -319,34 +160,29 @@ class Response extends ResponseAbstract implements RenderableInterface
throw new \Exception('Wrong response type'); throw new \Exception('Wrong response type');
} }
} }
return $render; return $render;
} }
/** private function getArray() : array
* {@inheritdoc}
*/
public function toCsv() : string
{ {
return ArrayUtils::arrayToCSV($this->toArray()); $result = [];
}
/** foreach($this->response as $key => $response) {
* {@inheritdoc} if($reponse instanceof Views) {
*/ $result += $response->getArray();
public function toArray() : array } elseif(is_array($response)) {
{ $result += $response;
$arr = []; } elseif(is_scalar($response)) {
$result[] = $response;
foreach ($this->response as $key => $response) { } elseif($response instanceof \Serializable) {
if ($response instanceof ArrayableInterface) { $result[] = $response->serialize();
$arr = ArrayUtils::setArray($key, $arr, $response->toArray(), ':');
} else { } 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 public function getReasonPhrase() : string
{ {
return $this->getHeader('Status'); return $this->header->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;
} }
} }

View File

@ -45,45 +45,7 @@ interface MessageInterface
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function getHeaders() : array; public function getHeader() : HeaderAbstract;
/**
* 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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
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 <d.eichhorn@oms.com>
*/
public function setHeader($key, string $header, bool $overwrite = true);
/** /**
* Gets the body of the message. * Gets the body of the message.

View File

@ -66,10 +66,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface,
*/ */
protected $account = null; protected $account = null;
/** protected $header = null;
* {@inheritdoc}
*/
abstract public function setHeader($key, string $header, bool $overwrite = true);
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -125,7 +122,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface,
public function setStatusCode(string $status) public function setStatusCode(string $status)
{ {
$this->status = $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()); return json_encode($this->toArray());
} }
/** public function getHeader() : HeaderAbstract
* Generate header automatically based on code. {
* return $this->header;
* @param int $code HTTP status code }
*
* @return void public function getBody() : string;
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
abstract public function generateHeader(int $code);
} }

View File

@ -34,7 +34,7 @@ use phpOMS\Validation\Validator;
* @link http://orange-management.com * @link http://orange-management.com
* @since 1.0.0 * @since 1.0.0
*/ */
class View implements RenderableInterface class View implements \Serializeable
{ {
/** /**
@ -288,9 +288,14 @@ class View implements RenderableInterface
ob_start(); ob_start();
/** @noinspection PhpIncludeInspection */ /** @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; $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)
{
}
} }