Merge pull request #22 from Orange-Management/route-restructure

Route restructure
This commit is contained in:
Dennis Eichhorn 2016-04-09 10:48:38 +02:00
commit 49696d57df
33 changed files with 753 additions and 555 deletions

View File

@ -18,6 +18,7 @@ namespace phpOMS\Config;
use phpOMS\DataStorage\Database\DatabaseType; use phpOMS\DataStorage\Database\DatabaseType;
use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\DataStorage\Database\DatabaseExceptionFactory;
/** /**
* Settings class. * Settings class.
@ -90,25 +91,30 @@ abstract class SettingsAbstract implements OptionsInterface
*/ */
public function get(array $columns) public function get(array $columns)
{ {
$options = []; try {
$options = [];
switch ($this->connection->getType()) { switch ($this->connection->getType()) {
case DatabaseType::MYSQL: case DatabaseType::MYSQL:
$query = new Builder($this->connection); $query = new Builder($this->connection);
$sql = $query->select(...static::$columns) $sql = $query->select(...static::$columns)
->from($this->connection->prefix . static::$table) ->from($this->connection->prefix . static::$table)
->where(static::$columns[0], 'in', $columns) ->where(static::$columns[0], 'in', $columns)
->toSql(); ->toSql();
$sth = $this->connection->con->prepare($sql); $sth = $this->connection->con->prepare($sql);
$sth->execute(); $sth->execute();
$options = $sth->fetchAll(\PDO::FETCH_KEY_PAIR); $options = $sth->fetchAll(\PDO::FETCH_KEY_PAIR);
$this->setOptions($options); $this->setOptions($options);
break; break;
}
return $options;
} catch (\PDOException $e) {
// todo does it mean that the recognition isn't here but at the place where the new happens?
throw DatabaseExceptionFactory::create($e);
} }
return $options;
} }
/** /**

View File

@ -0,0 +1,57 @@
<?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\DataStorage\Database;
use phpOMS\DataStorage\Database\Schema\Exception\TableException;
/**
* Path exception class.
*
* @category System
* @package Framework
* @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 DatabaseExceptionFactory
{
/**
* Constructor.
*
* @param string $message Exception message
* @param int $code Exception code
* @param \Exception Previous exception
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public static function create(\PDOException $e) : \PDOException
{
switch($e->getCode()) {
case '42S02':
return self::createTableViewException($e);
default:
return $e;
}
}
private static function createTableViewException(\PDOException $e) : \PDOException
{
return new TableException(TableException::findTable($e->getMessage()));
}
}

View File

@ -0,0 +1,62 @@
<?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\DataStorage\Database\Schema\Exception;
/**
* Path exception class.
*
* @category System
* @package Framework
* @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 TableException extends \PDOException
{
/**
* Constructor.
*
* @param string $message Exception message
* @param int $code Exception code
* @param \Exception Previous exception
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function __construct(string $message, int $code = 0, \Exception $previous = null)
{
parent::__construct('The table "' . $message . '" doesn\'t exist.', $code, $previous);
}
public static function findTable(string $message) : string
{
$pos1 = strpos($message, '\'');
if($pos1 === false) {
return $message;
}
$pos2 = strpos($message, '\'', $pos1+1);
if($pos2 === false) {
return $message;
}
return substr($message, $pos1+1, $pos2-$pos1-1);
}
}

View File

View File

@ -85,31 +85,16 @@ class Dispatcher
$views = []; $views = [];
$type = ViewLayout::UNDEFINED; $type = ViewLayout::UNDEFINED;
if (is_array($controller) && isset($controller['type'])) { if (is_array($controller) && isset($controller['dest'])) {
$type = $controller['type'];
$controller = $controller['dest']; $controller = $controller['dest'];
} }
if (is_string($controller)) { if (is_string($controller)) {
$dispatch = explode(':', $controller); $views += $this->dispatchString($controller, $request, $response, $data);
$this->get($dispatch[0]);
if (($c = count($dispatch)) == 3) {
/* Handling static functions */
$views[$type][$controller] = $dispatch[0]::$dispatch[2]();
} elseif ($c == 2) {
$views[$type][$controller] = $this->controllers[$dispatch[0]]->{$dispatch[1]}($request, $response, $data);
} else {
throw new \UnexpectedValueException('Unexpected function.');
}
} elseif (is_array($controller)) { } elseif (is_array($controller)) {
foreach ($controller as $controllerSingle) { $views += $this->dispatchArray($controller, $request, $response, $data);
foreach ($controllerSingle as $c) {
$views += $this->dispatch($c, $request, $response, $data);
}
}
} elseif ($controller instanceof \Closure) { } elseif ($controller instanceof \Closure) {
$views[$type][] = $controller($this->app, $request, $response, $data); $views[] = $this->dispatchClosure($controller, $request, $response, $data);
} else { } else {
throw new \UnexpectedValueException('Unexpected controller type.'); throw new \UnexpectedValueException('Unexpected controller type.');
} }
@ -117,17 +102,42 @@ class Dispatcher
return $views; return $views;
} }
/** private function dispatchString(string $controller, RequestAbstract $request, ResponseAbstract $response, $data = null)
* Get controller. {
* $views =[];
* @param string $controller Controller string $dispatch = explode(':', $controller);
* $this->getController($dispatch[0]);
* @return mixed
* if (($c = count($dispatch)) == 3) {
* @since 1.0.0 /* Handling static functions */
* @author Dennis Eichhorn <d.eichhorn@oms.com> $views[$controller] = $dispatch[0]::$dispatch[2]();
*/ } elseif ($c == 2) {
public function get(string $controller) $views[$controller] = $this->controllers[$dispatch[0]]->{$dispatch[1]}($request, $response, $data);
} else {
throw new \UnexpectedValueException('Unexpected function.');
}
return $views;
}
private function dispatchArray(array $controller, RequestAbstract $request, ResponseAbstract $response, $data = null) : array
{
$views = [];
foreach ($controller as $controllerSingle) {
foreach ($controllerSingle as $c) {
$views += $this->dispatch($c, $request, $response, $data);
}
}
return $views;
}
private function dispatchClosure(\Closure $controller, RequestAbstract $request, ResponseAbstract $response, $data = null)
{
return $controller($this->app, $request, $response, $data);
}
private function getController(string $controller)
{ {
if (!isset($this->controllers[$controller])) { if (!isset($this->controllers[$controller])) {
if (realpath($path = ROOT_PATH . '/' . str_replace('\\', '/', $controller) . '.php') === false) { if (realpath($path = ROOT_PATH . '/' . str_replace('\\', '/', $controller) . '.php') === false) {
@ -161,5 +171,4 @@ class Dispatcher
return false; return false;
} }
} }

View File

View File

View File

View File

View File

@ -0,0 +1,32 @@
<?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;
/**
* 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 HeaderAbstract
{
private static $isLocked = false;
}

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

@ -0,0 +1,201 @@
<?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\Message\HeaderAbstract;
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');
}
public function getHeaders() : array
{
return getallheaders();
}
/**
* {@inheritdoc}
*/
public function getHeader(string $name) : string
{
return getallheaders()[$name];
}
/**
* 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

@ -20,6 +20,7 @@ use phpOMS\Message\RequestAbstract;
use phpOMS\Uri\Http; use phpOMS\Uri\Http;
use phpOMS\Uri\UriFactory; use phpOMS\Uri\UriFactory;
use phpOMS\Uri\UriInterface; use phpOMS\Uri\UriInterface;
use phpOMS\Router\RouteVerb;
/** /**
* Request class. * Request class.
@ -387,7 +388,7 @@ class Request extends RequestAbstract
public function getMethod() : string public function getMethod() : string
{ {
if (!isset($this->method)) { if (!isset($this->method)) {
$this->method = $_SERVER['REQUEST_METHOD']; $this->method = $_SERVER['REQUEST_METHOD'] ?? RequestMethod::GET;
} }
return $this->method; return $this->method;
@ -401,30 +402,6 @@ class Request extends RequestAbstract
return $_SERVER['SERVER_PROTOCOL']; return $_SERVER['SERVER_PROTOCOL'];
} }
/**
* {@inheritdoc}
*/
public function getHeaders() : array
{
return getallheaders();
}
/**
* {@inheritdoc}
*/
public function hasHeader(string $name) : bool
{
return array_key_exists($name, getallheaders());
}
/**
* {@inheritdoc}
*/
public function getHeader(string $name) : string
{
return getallheaders()[$name];
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -454,21 +431,17 @@ class Request extends RequestAbstract
return $this->files; return $this->files;
} }
public function setHeader($key, string $header, bool $overwrite = true) public function getRouteVerb() : int
{ {
// NOT Required for Http request switch($this->getMethod()) {
} case RequestMethod::GET:
return RouteVerb::GET;
/** case RequestMethod::PUT:
* Get request route. return RouteVerb::PUT;
* case RequestMethod::POST:
* @return string return RouteVerb::SET;
* default:
* @since 1.0.0 throw new \Exception();
* @author Dennis Eichhorn <d.eichhorn@oms.com> }
*/
public function getRoutify() : string
{
return $this->uri->__toString();
} }
} }

View File

@ -13,7 +13,7 @@
* @version 1.0.0 * @version 1.0.0
* @link http://orange-management.com * @link http://orange-management.com
*/ */
namespace phpOMS\Message; namespace phpOMS\Message\Http;
use phpOMS\Datatypes\Enum; use phpOMS\Datatypes\Enum;

View File

@ -15,10 +15,9 @@
*/ */
namespace phpOMS\Message\Http; namespace phpOMS\Message\Http;
use phpOMS\Contract\ArrayableInterface; use phpOMS\System\MimeType;
use phpOMS\Contract\RenderableInterface; use phpOMS\Contract\RenderableInterface;
use phpOMS\Message\ResponseAbstract; use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Html\Head;
use phpOMS\Utils\ArrayUtils; use phpOMS\Utils\ArrayUtils;
use phpOMS\DataStorage\Cookie\CookieJar; use phpOMS\DataStorage\Cookie\CookieJar;
use phpOMS\DataStorage\Session\HttpSession; use phpOMS\DataStorage\Session\HttpSession;
@ -36,25 +35,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 +43,7 @@ class Response extends ResponseAbstract implements RenderableInterface
*/ */
public function __construct() public function __construct()
{ {
$this->setHeader('Content-Type', 'text/html; charset=utf-8'); $this->header = new Header();
$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,20 +131,33 @@ 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)) {
$render .= json_encode($response); $render .= json_encode($response);
// TODO: remove this. This should never happen since then someone forgot to set the correct header. it should be json header! // TODO: remove this. This should never happen since then someone forgot to set the correct header. it should be json header!
} else { } else {
var_dump($response);
throw new \Exception('Wrong response type'); throw new \Exception('Wrong response type');
} }
} }
@ -323,30 +165,25 @@ class Response extends ResponseAbstract implements RenderableInterface
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 +191,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

@ -15,7 +15,7 @@
*/ */
namespace phpOMS\Message\Http; namespace phpOMS\Message\Http;
use phpOMS\Message\RequestMethod; use phpOMS\Message\Http\RequestMethod;
/** /**
* Rest request class. * Rest request class.

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

@ -122,6 +122,8 @@ abstract class RequestAbstract implements MessageInterface
*/ */
protected $hash = []; protected $hash = [];
protected $header = null;
/** /**
* Constructor. * Constructor.
* *
@ -321,6 +323,11 @@ abstract class RequestAbstract implements MessageInterface
return $this->status; return $this->status;
} }
public function getHeader() : HeaderAbstract
{
return $this->header;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -343,4 +350,6 @@ abstract class RequestAbstract implements MessageInterface
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
abstract public function getRequestTarget() : string; abstract public function getRequestTarget() : string;
abstract public function getRouteVerb() : int;
} }

View File

@ -1,52 +0,0 @@
<?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;
use phpOMS\Datatypes\Enum;
/**
* Request page enum.
*
* Possible page requests. Page requests can have completely different themes, permissions and page structures.
*
* @category Request
* @package Framework
* @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
*/
abstract class RequestDestination extends Enum
{
const WEBSITE = 'Website'; /* Website */
const API = 'Api'; /* API */
const SHOP = 'Shop'; /* Shop */
const BACKEND = 'Backend'; /* Backend */
const STATICP = 'Static'; /* Static content */
const FORUM = 'Forum'; /* Forum */
const TICKET = 'Ticket'; /* ???? */
const SUPPORT = 'Support'; /* Support center */
const SURVEY = 'Survey'; /* Survey page */
const BLOG = 'Blog'; /* Blog */
const CHART = 'Chart'; /* Chart view */
const CALENDAR = 'Calendar'; /* Calendar */
const PROFILE = 'Profile'; /* User profile page */
const CHAT = 'Chat'; /* Chat page */
const GALLERY = 'Gallery'; /* Chat page */
const REPORTER = 'Reporter'; /* Reporter page */
// This or let api handle this const GUI = 'gui'; /* Request GUI elements */
}

View File

@ -15,10 +15,9 @@
*/ */
namespace phpOMS\Message; namespace phpOMS\Message;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\Contract\JsonableInterface;
use phpOMS\Localization\Localization; use phpOMS\Localization\Localization;
use phpOMS\Utils\ArrayUtils; use phpOMS\Utils\ArrayUtils;
use phpOMS\Message\Http\Header;
/** /**
* Response abstract class. * Response abstract class.
@ -31,7 +30,7 @@ use phpOMS\Utils\ArrayUtils;
* @link http://orange-management.com * @link http://orange-management.com
* @since 1.0.0 * @since 1.0.0
*/ */
abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, JsonableInterface abstract class ResponseAbstract implements MessageInterface
{ {
/** /**
@ -66,10 +65,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 +121,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 +156,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 abstract public function getBody() : string;
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
abstract public function generateHeader(int $code);
} }

View File

@ -59,14 +59,18 @@ class InfoManager
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn * @author Dennis Eichhorn
*/ */
public function __construct(string $module) public function __construct($path)
{ {
if (($path = realpath($oldPath = ModuleAbstract::MODULE_PATH . '/' . $module . '/info.json')) === false || Validator::startsWith($path, ModuleAbstract::MODULE_PATH)) { $this->path = $path;
throw new PathException($oldPath); }
public function load()
{
if (($path = realpath($this->path)) === false) {
throw new PathException($this->path);
} }
$this->path = $path; $this->info = json_decode(file_get_contents($path), true);
$this->info = json_decode(file_get_contents($this->path), true);
} }
/** /**
@ -111,4 +115,34 @@ class InfoManager
{ {
return $this->info; return $this->info;
} }
public function getInternalName() : string
{
return $this->info['name']['internal'];
}
public function getDependencies() : array
{
return $this->info['dependencies'];
}
public function getProviding() : array
{
return $this->info['providing'];
}
public function getDirectory() : string
{
return $this->info['directory'];
}
public function getVersion() : string
{
return $this->info['version'];
}
public function getLoad() : array
{
return $this->info['load'];
}
} }

View File

@ -16,6 +16,9 @@
namespace phpOMS\Module; namespace phpOMS\Module;
use phpOMS\DataStorage\Database\Pool; use phpOMS\DataStorage\Database\Pool;
use phpOMS\Module\InfoManager;
use phpOMS\Router\RouteVerb;
use phpOMS\Utils\Parser\Php\ArrayParser;
/** /**
* Installer Abstract class. * Installer Abstract class.
@ -42,7 +45,25 @@ class InstallerAbstract
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public static function install(Pool $dbPool, array $info) public static function install(Pool $dbPool, InfoManager $info)
{ {
self::installRoutes(ROOT_PATH . '/Web/Routes.php', ROOT_PATH . '/Modules/' . $info->getDirectory() . '/Admin/Routes/http.php');
self::installRoutes(ROOT_PATH . '/Socket/Routes.php', ROOT_PATH . '/Modules/' . $info->getDirectory() . '/Admin/Routes/socket.php');
self::installRoutes(ROOT_PATH . '/Console/Routes.php', ROOT_PATH . '/Modules/' . $info->getDirectory() . '/Admin/Routes/console.php');
}
private static function installRoutes(string $appRoutePath, string $moduleRoutePath)
{
if(file_exists($appRoutePath) && file_exists($moduleRoutePath)) {
$appRoutes = include $appRoutePath;
$moduleRoutes = include $moduleRoutePath;
$appRoutes = array_merge_recursive($appRoutes, $moduleRoutes);
if(is_writable($appRoutePath)) {
file_put_contents($appRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', LOCK_EX);
} else {
throw new PermissionException($appRoutePath);
}
}
} }
} }

View File

@ -80,14 +80,6 @@ abstract class ModuleAbstract
*/ */
protected static $localization = []; protected static $localization = [];
/**
* Routes.
*
* @var array
* @since 1.0.0
*/
protected static $routes = [];
/** /**
* Dependencies. * Dependencies.
* *
@ -115,12 +107,6 @@ abstract class ModuleAbstract
public function __construct($app) public function __construct($app)
{ {
$this->app = $app; $this->app = $app;
foreach (static::$routes as $route => $destinations) {
foreach ($destinations as $destination) {
$this->app->router->add($route, $destination['dest'], $destination['method'], $destination['type']);
}
}
} }
/** /**
@ -148,20 +134,13 @@ abstract class ModuleAbstract
public function getLocalization(string $language, string $destination) : array public function getLocalization(string $language, string $destination) : array
{ {
$lang = []; $lang = [];
if (isset(static::$localization[$destination])) { if (($path = realpath($oldPath = __DIR__ . '/../../Modules/' . static::MODULE_NAME . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) === false) {
/** @noinspection PhpUnusedLocalVariableInspection */ throw new PathException($oldPath);
foreach (static::$localization[$destination] as $file) {
if (($path = realpath($oldPath = __DIR__ . '/../../Modules/' . static::MODULE_NAME . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) === false) {
throw new PathException($oldPath);
}
/** @noinspection PhpIncludeInspection */
include realpath($path);
/** @var array $MODLANG */
$lang += $MODLANG;
}
} }
/** @noinspection PhpIncludeInspection */
$lang = include $path;
return $lang; return $lang;
} }

View File

@ -20,6 +20,7 @@ use phpOMS\DataStorage\Database\DatabaseType;
use phpOMS\Log\FileLogger; use phpOMS\Log\FileLogger;
use phpOMS\Message\Http\Request; use phpOMS\Message\Http\Request;
use phpOMS\System\File\PathException; use phpOMS\System\File\PathException;
use phpOMS\Autoloader;
use phpOMS\Utils\IO\Json\InvalidJsonException; use phpOMS\Utils\IO\Json\InvalidJsonException;
/** /**
@ -296,18 +297,34 @@ class ModuleManager
// todo download; // todo download;
} }
$path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json'); try {
$info = $this->loadInfo($module);
if ($path === false || strpos($path, self::MODULE_PATH) === false) { $this->registerInDatabase($info);
throw new PathException($module); $this->installed[$module] = $info;
} $this->installDependencies($info->getDependencies());
$this->installModule($info);
$info = json_decode(file_get_contents($path), true);
/* Install providing */
if (!isset($info)) { $providing = $info->getProviding();
throw new InvalidJsonException($path); foreach ($providing as $key => $version) {
$this->installProviding($module, $key);
}
/* Install receiving */
foreach ($installed as $key => $value) {
$this->installProviding($key, $module);
}
} catch(PathException $e) {
// todo: handle module doesn't exist or files are missing
//echo $e->getMessage();
} catch(\Exception $e) {
//echo $e->getMessage();
} }
}
private function registerInDatabase(InfoManager $info)
{
switch ($this->app->dbPool->get('core')->getType()) { switch ($this->app->dbPool->get('core')->getType()) {
case DatabaseType::MYSQL: case DatabaseType::MYSQL:
$this->app->dbPool->get('core')->con->beginTransaction(); $this->app->dbPool->get('core')->con->beginTransaction();
@ -317,11 +334,11 @@ class ModuleManager
(:internal, :theme, :path, :active, :version);' (:internal, :theme, :path, :active, :version);'
); );
$sth->bindValue(':internal', $info['name']['internal'], \PDO::PARAM_INT); $sth->bindValue(':internal', $info->getInternalName(), \PDO::PARAM_INT);
$sth->bindValue(':theme', 'Default', \PDO::PARAM_STR); $sth->bindValue(':theme', 'Default', \PDO::PARAM_STR);
$sth->bindValue(':path', $info['directory'], \PDO::PARAM_STR); $sth->bindValue(':path', $info->getDirectory(), \PDO::PARAM_STR);
$sth->bindValue(':active', 1, \PDO::PARAM_INT); $sth->bindValue(':active', 1, \PDO::PARAM_INT);
$sth->bindValue(':version', $info['version'], \PDO::PARAM_STR); $sth->bindValue(':version', $info->getVersion(), \PDO::PARAM_STR);
$sth->execute(); $sth->execute();
@ -330,7 +347,8 @@ class ModuleManager
(:pid, :type, :from, :for, :file);' (:pid, :type, :from, :for, :file);'
); );
foreach ($info['load'] as $val) { $load = $info->getLoad();
foreach ($load as $val) {
foreach ($val['pid'] as $pid) { foreach ($val['pid'] as $pid) {
$sth->bindValue(':pid', $pid, \PDO::PARAM_STR); $sth->bindValue(':pid', $pid, \PDO::PARAM_STR);
$sth->bindValue(':type', $val['type'], \PDO::PARAM_INT); $sth->bindValue(':type', $val['type'], \PDO::PARAM_INT);
@ -346,26 +364,39 @@ class ModuleManager
break; break;
} }
}
foreach ($info['dependencies'] as $key => $version) { private function installDependencies(array $dependencies)
{
foreach ($dependencies as $key => $version) {
$this->install($key); $this->install($key);
} }
}
private function installModule(InfoManager $info)
{
$class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Installer';
if(!Autoloader::exists($class)) {
throw new \Exception('Module installer does not exist');
}
$class = '\\Modules\\' . $module . '\\Admin\\Installer';
/** @var $class InstallerAbstract */ /** @var $class InstallerAbstract */
$class::install($this->app->dbPool, $info); $class::install($this->app->dbPool, $info);
}
// TODO: change this private function loadInfo(string $module) : InfoManager
$this->installed[$module] = true; {
$path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json');
foreach ($info['providing'] as $key => $version) { if ($path === false || strpos($path, self::MODULE_PATH) === false) {
$this->installProviding($module, $key); throw new PathException($oldPath);
} }
/* Install receiving */ $info = new InfoManager($path);
foreach ($installed as $key => $value) { $info->load();
$this->installProviding($key, $module);
} return $info;
} }
/** /**
@ -426,25 +457,35 @@ class ModuleManager
public function initModule($module) public function initModule($module)
{ {
if (is_array($module)) { if (is_array($module)) {
foreach ($module as $m) { $this->initModuleArray($module);
try {
$this->initModule($m);
} catch (\InvalidArgumentException $e) {
$this->app->logger->warning(FileLogger::MSG_FULL, [
'message' => 'Trying to initialize ' . $m . ' without controller.',
'line' => $e->getLine(),
'file' => $e->getFile(),
]);
}
}
} elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) { } elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) {
$this->running[$module] = ModuleFactory::getInstance($module, $this->app); $this->initModuleController($module);
$this->app->dispatcher->set($this->running[$module], '\Modules\\' . $module . '\\Controller');
} else { } else {
throw new \InvalidArgumentException('Invalid Module'); throw new \InvalidArgumentException('Invalid Module');
} }
} }
private function initModuleArray(array $modules)
{
foreach ($modules as $module) {
try {
$this->initModule($module);
} catch (\InvalidArgumentException $e) {
$this->app->logger->warning(FileLogger::MSG_FULL, [
'message' => 'Trying to initialize ' . $module . ' without controller.',
'line' => $e->getLine(),
'file' => $e->getFile(),
]);
}
}
}
private function initModuleController(string $module)
{
$this->running[$module] = ModuleFactory::getInstance($module, $this->app);
$this->app->dispatcher->set($this->running[$module], '\Modules\\' . $module . '\\Controller');
}
/** /**
* Get module instance. * Get module instance.
* *

View File

@ -42,7 +42,7 @@ class UninstallAbstract
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public static function uninstall(Pool $dbPool, array $info) public static function uninstall(Pool $dbPool, InfoManager $info)
{ {
} }

View File

@ -0,0 +1,34 @@
<?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\Router;
/**
* Router class.
*
* @category Framework
* @package phpOMS\Socket
* @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 RouteAbstract
{
}

37
Router/RouteVerb.php Normal file
View File

@ -0,0 +1,37 @@
<?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\Router;
use phpOMS\Datatypes\Enum;
/**
* View layout enum.
*
* @category Framework
* @package phpOMS\Socket
* @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
*/
abstract class RouteVerb extends Enum
{
const GET = 1;
const PUT = 2;
const SET = 3;
const ANY = 4;
}

View File

@ -15,8 +15,8 @@
*/ */
namespace phpOMS\Router; namespace phpOMS\Router;
use phpOMS\Message\RequestMethod;
use phpOMS\Views\ViewLayout; use phpOMS\Views\ViewLayout;
use phpOMS\Message\RequestAbstract;
/** /**
* Router class. * Router class.
@ -50,25 +50,29 @@ class Router
{ {
} }
public function importFromFile(string $path)
{
$this->routes = include $path;
}
/** /**
* Add route. * Add route.
* *
* @param string $route Route regex * @param string $route Route regex
* @param mixed $destination Destination e.g. Module:function & method * @param mixed $destination Destination e.g. Module:function & verb
* @param string $method Request method * @param string $verb Request verb
* @param int $type Result type * @param int $layout Result layout
* *
* @return void * @return void
* *
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function add(string $route, $destination, string $method = RequestMethod::GET, int $type = ViewLayout::MAIN) public function add(string $route, $destination, string $verb = RouteVerb::GET)
{ {
$this->routes[$route][] = [ $this->routes[$route][] = [
'dest' => $destination, 'dest' => $destination,
'method' => $method, 'verb' => $verb,
'type' => $type,
]; ];
} }
@ -76,20 +80,20 @@ class Router
* Route uri. * Route uri.
* *
* @param string $uri Uri to route * @param string $uri Uri to route
* @param string $remoteMethod GET/POST etc. * @param string $verb GET/POST etc.
* *
* @return string[] * @return string[]
* *
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
public function route(string $uri, string $remoteMethod = RequestMethod::GET) : array public function route(RequestAbstract $request) : array
{ {
$bound = []; $bound = [];
foreach ($this->routes as $route => $destination) { foreach ($this->routes as $route => $destination) {
foreach ($destination as $d) { foreach ($destination as $d) {
if ($this->match($route, $d['method'], $uri, $remoteMethod)) { if ($this->match($route, $d['verb'], $request->getUri(), $request->getRouteVerb())) {
$bound[$route][] = ['dest' => $d['dest'], 'type' => $d['type']]; $bound[] = ['dest' => $d['dest']];
} }
} }
} }
@ -101,17 +105,17 @@ class Router
* Match route and uri. * Match route and uri.
* *
* @param string $route Route * @param string $route Route
* @param string $method GET,POST for this route * @param string $verb GET,POST for this route
* @param string $uri Uri * @param string $uri Uri
* @param string $remoteMethod Method this request is using * @param string $verb Verb this request is using
* *
* @return bool * @return bool
* *
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
private function match(string $route, string $method, string $uri, string $remoteMethod = RequestMethod::GET) : bool private function match(string $route, string $routeVerb, string $uri, string $remoteVerb = RouteVerb::GET) : bool
{ {
return (bool) preg_match('~^' . $route . '$~', $uri) && ($method == 'any' || $remoteMethod == $method); return (bool) preg_match('~^' . $route . '$~', $uri) && ($routeVerb == RouteVerb::ANY || $remoteVerb == $routeVerb);
} }
} }

View File

@ -217,7 +217,7 @@ class Directory extends FileAbstract implements \Iterator, \ArrayAccess
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
private function createNode() : bool public function createNode() : bool
{ {
return self::createPath($this->path, $this->permission, true); return self::createPath($this->path, $this->permission, true);
} }
@ -225,7 +225,7 @@ class Directory extends FileAbstract implements \Iterator, \ArrayAccess
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
private function removeNode() : bool public function removeNode() : bool
{ {
return true; return true;
} }

View File

@ -77,7 +77,7 @@ class File extends FileAbstract
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
private function createNode() : bool public function createNode() : bool
{ {
return self::create($this->path); return self::create($this->path);
} }
@ -85,7 +85,7 @@ class File extends FileAbstract
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
private function removeNode() : bool public function removeNode() : bool
{ {
return true; return true;
} }

View File

@ -184,7 +184,7 @@ abstract class FileAbstract
* @since 1.0.0 * @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com> * @author Dennis Eichhorn <d.eichhorn@oms.com>
*/ */
abstract private function createNode() : bool; abstract public function createNode() : bool;
/** /**
* Get created at. * Get created at.

View File

@ -15,8 +15,6 @@
*/ */
namespace phpOMS\Uri; namespace phpOMS\Uri;
/** /**
* Uri interface. * Uri interface.
* *

View File

@ -16,7 +16,6 @@
namespace phpOMS\Views; namespace phpOMS\Views;
use phpOMS\ApplicationAbstract; use phpOMS\ApplicationAbstract;
use phpOMS\Contract\RenderableInterface;
use phpOMS\Localization\Localization; use phpOMS\Localization\Localization;
use phpOMS\Message\RequestAbstract; use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract; use phpOMS\Message\ResponseAbstract;
@ -34,7 +33,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 \Serializable
{ {
/** /**
@ -250,25 +249,6 @@ class View implements RenderableInterface
} }
} }
/**
* Get view/template response of all views.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function renderAll() : string
{
ob_start();
foreach ($this->views as $key => $view) {
echo $view->render();
}
return ob_get_clean();
}
/** /**
* Get view/template response. * Get view/template response.
* *
@ -288,9 +268,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 +340,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->render();
}
public function unserialize($raw)
{
}
} }