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\Query\Builder;
use phpOMS\DataStorage\Database\DatabaseExceptionFactory;
/**
* Settings class.
@ -90,25 +91,30 @@ abstract class SettingsAbstract implements OptionsInterface
*/
public function get(array $columns)
{
$options = [];
try {
$options = [];
switch ($this->connection->getType()) {
case DatabaseType::MYSQL:
$query = new Builder($this->connection);
$sql = $query->select(...static::$columns)
->from($this->connection->prefix . static::$table)
->where(static::$columns[0], 'in', $columns)
->toSql();
switch ($this->connection->getType()) {
case DatabaseType::MYSQL:
$query = new Builder($this->connection);
$sql = $query->select(...static::$columns)
->from($this->connection->prefix . static::$table)
->where(static::$columns[0], 'in', $columns)
->toSql();
$sth = $this->connection->con->prepare($sql);
$sth->execute();
$sth = $this->connection->con->prepare($sql);
$sth->execute();
$options = $sth->fetchAll(\PDO::FETCH_KEY_PAIR);
$this->setOptions($options);
break;
$options = $sth->fetchAll(\PDO::FETCH_KEY_PAIR);
$this->setOptions($options);
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 = [];
$type = ViewLayout::UNDEFINED;
if (is_array($controller) && isset($controller['type'])) {
$type = $controller['type'];
if (is_array($controller) && isset($controller['dest'])) {
$controller = $controller['dest'];
}
if (is_string($controller)) {
$dispatch = explode(':', $controller);
$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.');
}
$views += $this->dispatchString($controller, $request, $response, $data);
} elseif (is_array($controller)) {
foreach ($controller as $controllerSingle) {
foreach ($controllerSingle as $c) {
$views += $this->dispatch($c, $request, $response, $data);
}
}
$views += $this->dispatchArray($controller, $request, $response, $data);
} elseif ($controller instanceof \Closure) {
$views[$type][] = $controller($this->app, $request, $response, $data);
$views[] = $this->dispatchClosure($controller, $request, $response, $data);
} else {
throw new \UnexpectedValueException('Unexpected controller type.');
}
@ -117,17 +102,42 @@ class Dispatcher
return $views;
}
/**
* Get controller.
*
* @param string $controller Controller string
*
* @return mixed
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function get(string $controller)
private function dispatchString(string $controller, RequestAbstract $request, ResponseAbstract $response, $data = null)
{
$views =[];
$dispatch = explode(':', $controller);
$this->getController($dispatch[0]);
if (($c = count($dispatch)) == 3) {
/* Handling static functions */
$views[$controller] = $dispatch[0]::$dispatch[2]();
} elseif ($c == 2) {
$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 (realpath($path = ROOT_PATH . '/' . str_replace('\\', '/', $controller) . '.php') === false) {
@ -158,8 +168,7 @@ class Dispatcher
return true;
}
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\UriFactory;
use phpOMS\Uri\UriInterface;
use phpOMS\Router\RouteVerb;
/**
* Request class.
@ -387,7 +388,7 @@ class Request extends RequestAbstract
public function getMethod() : string
{
if (!isset($this->method)) {
$this->method = $_SERVER['REQUEST_METHOD'];
$this->method = $_SERVER['REQUEST_METHOD'] ?? RequestMethod::GET;
}
return $this->method;
@ -399,31 +400,7 @@ class Request extends RequestAbstract
public function getProtocolVersion() : string
{
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}
@ -454,21 +431,17 @@ class Request extends RequestAbstract
return $this->files;
}
public function setHeader($key, string $header, bool $overwrite = true)
public function getRouteVerb() : int
{
// NOT Required for Http request
}
/**
* Get request route.
*
* @return string
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function getRoutify() : string
{
return $this->uri->__toString();
switch($this->getMethod()) {
case RequestMethod::GET:
return RouteVerb::GET;
case RequestMethod::PUT:
return RouteVerb::PUT;
case RequestMethod::POST:
return RouteVerb::SET;
default:
throw new \Exception();
}
}
}

View File

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

View File

@ -15,10 +15,9 @@
*/
namespace phpOMS\Message\Http;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\System\MimeType;
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;
@ -36,25 +35,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 +43,7 @@ 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 <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');
$this->header = new Header();
}
/**
@ -187,44 +78,6 @@ class Response extends ResponseAbstract implements RenderableInterface
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.
*
@ -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,20 +131,33 @@ 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)) {
$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!
} else {
var_dump($response);
throw new \Exception('Wrong response type');
}
}
@ -323,30 +165,25 @@ class Response extends ResponseAbstract implements RenderableInterface
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 +191,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');
}
}

View File

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

View File

@ -45,45 +45,7 @@ interface MessageInterface
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
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 <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);
public function getHeader() : HeaderAbstract;
/**
* Gets the body of the message.

View File

@ -122,6 +122,8 @@ abstract class RequestAbstract implements MessageInterface
*/
protected $hash = [];
protected $header = null;
/**
* Constructor.
*
@ -321,6 +323,11 @@ abstract class RequestAbstract implements MessageInterface
return $this->status;
}
public function getHeader() : HeaderAbstract
{
return $this->header;
}
/**
* {@inheritdoc}
*/
@ -343,4 +350,6 @@ abstract class RequestAbstract implements MessageInterface
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
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;
use phpOMS\Contract\ArrayableInterface;
use phpOMS\Contract\JsonableInterface;
use phpOMS\Localization\Localization;
use phpOMS\Utils\ArrayUtils;
use phpOMS\Message\Http\Header;
/**
* Response abstract class.
@ -31,7 +30,7 @@ use phpOMS\Utils\ArrayUtils;
* @link http://orange-management.com
* @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;
/**
* {@inheritdoc}
*/
abstract public function setHeader($key, string $header, bool $overwrite = true);
protected $header = null;
/**
* {@inheritdoc}
@ -125,7 +121,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface,
public function setStatusCode(string $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());
}
/**
* 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>
*/
abstract public function generateHeader(int $code);
public function getHeader() : HeaderAbstract
{
return $this->header;
}
abstract public function getBody() : string;
}

View File

@ -59,14 +59,18 @@ class InfoManager
* @since 1.0.0
* @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)) {
throw new PathException($oldPath);
$this->path = $path;
}
public function load()
{
if (($path = realpath($this->path)) === false) {
throw new PathException($this->path);
}
$this->path = $path;
$this->info = json_decode(file_get_contents($this->path), true);
$this->info = json_decode(file_get_contents($path), true);
}
/**
@ -111,4 +115,34 @@ class InfoManager
{
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;
use phpOMS\DataStorage\Database\Pool;
use phpOMS\Module\InfoManager;
use phpOMS\Router\RouteVerb;
use phpOMS\Utils\Parser\Php\ArrayParser;
/**
* Installer Abstract class.
@ -42,7 +45,25 @@ class InstallerAbstract
* @since 1.0.0
* @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 = [];
/**
* Routes.
*
* @var array
* @since 1.0.0
*/
protected static $routes = [];
/**
* Dependencies.
*
@ -115,12 +107,6 @@ abstract class ModuleAbstract
public function __construct($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
{
$lang = [];
if (isset(static::$localization[$destination])) {
/** @noinspection PhpUnusedLocalVariableInspection */
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;
}
if (($path = realpath($oldPath = __DIR__ . '/../../Modules/' . static::MODULE_NAME . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) === false) {
throw new PathException($oldPath);
}
/** @noinspection PhpIncludeInspection */
$lang = include $path;
return $lang;
}

View File

@ -20,6 +20,7 @@ use phpOMS\DataStorage\Database\DatabaseType;
use phpOMS\Log\FileLogger;
use phpOMS\Message\Http\Request;
use phpOMS\System\File\PathException;
use phpOMS\Autoloader;
use phpOMS\Utils\IO\Json\InvalidJsonException;
/**
@ -296,18 +297,34 @@ class ModuleManager
// 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) {
throw new PathException($module);
}
$info = json_decode(file_get_contents($path), true);
if (!isset($info)) {
throw new InvalidJsonException($path);
$this->registerInDatabase($info);
$this->installed[$module] = $info;
$this->installDependencies($info->getDependencies());
$this->installModule($info);
/* Install providing */
$providing = $info->getProviding();
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()) {
case DatabaseType::MYSQL:
$this->app->dbPool->get('core')->con->beginTransaction();
@ -317,11 +334,11 @@ class ModuleManager
(: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(':path', $info['directory'], \PDO::PARAM_STR);
$sth->bindValue(':path', $info->getDirectory(), \PDO::PARAM_STR);
$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();
@ -330,7 +347,8 @@ class ModuleManager
(:pid, :type, :from, :for, :file);'
);
foreach ($info['load'] as $val) {
$load = $info->getLoad();
foreach ($load as $val) {
foreach ($val['pid'] as $pid) {
$sth->bindValue(':pid', $pid, \PDO::PARAM_STR);
$sth->bindValue(':type', $val['type'], \PDO::PARAM_INT);
@ -346,26 +364,39 @@ class ModuleManager
break;
}
}
foreach ($info['dependencies'] as $key => $version) {
private function installDependencies(array $dependencies)
{
foreach ($dependencies as $key => $version) {
$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 */
$class::install($this->app->dbPool, $info);
}
// TODO: change this
$this->installed[$module] = true;
private function loadInfo(string $module) : InfoManager
{
$path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json');
foreach ($info['providing'] as $key => $version) {
$this->installProviding($module, $key);
if ($path === false || strpos($path, self::MODULE_PATH) === false) {
throw new PathException($oldPath);
}
/* Install receiving */
foreach ($installed as $key => $value) {
$this->installProviding($key, $module);
}
$info = new InfoManager($path);
$info->load();
return $info;
}
/**
@ -426,25 +457,35 @@ class ModuleManager
public function initModule($module)
{
if (is_array($module)) {
foreach ($module as $m) {
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(),
]);
}
}
$this->initModuleArray($module);
} elseif (is_string($module) && realpath(self::MODULE_PATH . '/' . $module . '/Controller.php') !== false) {
$this->running[$module] = ModuleFactory::getInstance($module, $this->app);
$this->app->dispatcher->set($this->running[$module], '\Modules\\' . $module . '\\Controller');
$this->initModuleController($module);
} else {
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.
*

View File

@ -42,7 +42,7 @@ class UninstallAbstract
* @since 1.0.0
* @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;
use phpOMS\Message\RequestMethod;
use phpOMS\Views\ViewLayout;
use phpOMS\Message\RequestAbstract;
/**
* Router class.
@ -50,25 +50,29 @@ class Router
{
}
public function importFromFile(string $path)
{
$this->routes = include $path;
}
/**
* Add route.
*
* @param string $route Route regex
* @param mixed $destination Destination e.g. Module:function & method
* @param string $method Request method
* @param int $type Result type
* @param mixed $destination Destination e.g. Module:function & verb
* @param string $verb Request verb
* @param int $layout Result layout
*
* @return void
*
* @since 1.0.0
* @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][] = [
'dest' => $destination,
'method' => $method,
'type' => $type,
'verb' => $verb,
];
}
@ -76,20 +80,20 @@ class Router
* Route uri.
*
* @param string $uri Uri to route
* @param string $remoteMethod GET/POST etc.
* @param string $verb GET/POST etc.
*
* @return string[]
*
* @since 1.0.0
* @author Dennis Eichhorn <d.eichhorn@oms.com>
*/
public function route(string $uri, string $remoteMethod = RequestMethod::GET) : array
public function route(RequestAbstract $request) : array
{
$bound = [];
foreach ($this->routes as $route => $destination) {
foreach ($destination as $d) {
if ($this->match($route, $d['method'], $uri, $remoteMethod)) {
$bound[$route][] = ['dest' => $d['dest'], 'type' => $d['type']];
if ($this->match($route, $d['verb'], $request->getUri(), $request->getRouteVerb())) {
$bound[] = ['dest' => $d['dest']];
}
}
}
@ -101,17 +105,17 @@ class Router
* Match route and uri.
*
* @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 $remoteMethod Method this request is using
* @param string $verb Verb this request is using
*
* @return bool
*
* @since 1.0.0
* @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}
*/
private function createNode() : bool
public function createNode() : bool
{
return self::createPath($this->path, $this->permission, true);
}
@ -225,7 +225,7 @@ class Directory extends FileAbstract implements \Iterator, \ArrayAccess
/**
* {@inheritdoc}
*/
private function removeNode() : bool
public function removeNode() : bool
{
return true;
}

View File

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

View File

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

View File

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

View File

@ -16,7 +16,6 @@
namespace phpOMS\Views;
use phpOMS\ApplicationAbstract;
use phpOMS\Contract\RenderableInterface;
use phpOMS\Localization\Localization;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
@ -34,7 +33,7 @@ use phpOMS\Validation\Validator;
* @link http://orange-management.com
* @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.
*
@ -288,9 +268,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 +340,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->render();
}
public function unserialize($raw)
{
}
}