From d09296f3676b138112c106d1e23ca72b9a64e01a Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 28 Mar 2016 20:20:40 +0200 Subject: [PATCH 01/10] Preparing dispatcher for micro services --- Dispatcher/ConsoleDispatcher.php | 0 Dispatcher/DispatcherInterface.php | 0 Dispatcher/HttpDispatcher.php | 0 Dispatcher/LocalDispatcher.php | 0 Dispatcher/SocketDispatcher.php | 0 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Dispatcher/ConsoleDispatcher.php create mode 100644 Dispatcher/DispatcherInterface.php create mode 100644 Dispatcher/HttpDispatcher.php create mode 100644 Dispatcher/LocalDispatcher.php create mode 100644 Dispatcher/SocketDispatcher.php diff --git a/Dispatcher/ConsoleDispatcher.php b/Dispatcher/ConsoleDispatcher.php new file mode 100644 index 000000000..e69de29bb diff --git a/Dispatcher/DispatcherInterface.php b/Dispatcher/DispatcherInterface.php new file mode 100644 index 000000000..e69de29bb diff --git a/Dispatcher/HttpDispatcher.php b/Dispatcher/HttpDispatcher.php new file mode 100644 index 000000000..e69de29bb diff --git a/Dispatcher/LocalDispatcher.php b/Dispatcher/LocalDispatcher.php new file mode 100644 index 000000000..e69de29bb diff --git a/Dispatcher/SocketDispatcher.php b/Dispatcher/SocketDispatcher.php new file mode 100644 index 000000000..e69de29bb From 3f5d562af9a2bc992b8d47a2b000d7828830485d Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 16:21:23 +0200 Subject: [PATCH 02/10] New dispatcher and router --- Dispatcher/Dispatcher.php | 70 ++++++++++++++++++++---------------- Message/Http/Request.php | 21 +++++------ Message/RequestAbstract.php | 2 ++ Module/InstallerAbstract.php | 19 ++++++++++ Router/RouteAbstract.php | 34 ++++++++++++++++++ Router/RouteVerb.php | 36 +++++++++++++++++++ Router/Router.php | 31 +++++++++------- Uri/Http.php | 2 -- 8 files changed, 160 insertions(+), 55 deletions(-) create mode 100644 Router/RouteVerb.php diff --git a/Dispatcher/Dispatcher.php b/Dispatcher/Dispatcher.php index 49b60b33a..1ce64f549 100644 --- a/Dispatcher/Dispatcher.php +++ b/Dispatcher/Dispatcher.php @@ -91,25 +91,11 @@ class Dispatcher } 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[$type][] = $this->dispatchClosure($controller, $request, $response, $data); } else { throw new \UnexpectedValueException('Unexpected controller type.'); } @@ -117,17 +103,42 @@ class Dispatcher return $views; } - /** - * Get controller. - * - * @param string $controller Controller string - * - * @return mixed - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - 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[$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.'); + } + + 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 +169,7 @@ class Dispatcher return true; } - + return false; } - } diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 70b48507a..b67174a82 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -459,16 +459,17 @@ class Request extends RequestAbstract // NOT Required for Http request } - /** - * Get request route. - * - * @return string - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getRoutify() : string + public function getRouteVerb() : int { - return $this->uri->__toString(); + switch($this->method) { + case RequestMethod::GET: + return RouteVerb::GET; + case RequestMethod::PUT: + return RouteVerb::PUT; + case RequestMethod::POST: + return RouteVerb::SET; + default: + throw new \Exception(); + } } } diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index 6fec593cd..c8b595076 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -343,4 +343,6 @@ abstract class RequestAbstract implements MessageInterface * @author Dennis Eichhorn */ abstract public function getRequestTarget() : string; + + abstract public function getRouteVerb() : int; } diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index 3add342ff..b4c4c82c7 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -44,5 +44,24 @@ class InstallerAbstract */ public static function install(Pool $dbPool, array $info) { + + self::$installRoutes(ROOT_PATH . '/Web/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/http.php'); + self::$installRoutes(ROOT_PATH . '/Socket/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/socket.php'); + self::$installRoutes(ROOT_PATH . '/Console/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/console.php'); + } + + private static function installRoutes(string $appRoutePath, string $moduleRoutePath) + { + if(file_exists($appRoutePath) && file_exists($moduleRoutePath)) { + include $appRoutePath; + include $moduleRoutePath; + $appRoutes = array_merge_recursive($appRoutes, $moduleRoutes); + + if(is_writable($appRoutePath)) { + file_put_contents(ArrayParser::createFile('moduleRoutes', $appRoutes), $appRoutePath); + } else { + throw new PermissionException($appRoutePath); + } + } } } diff --git a/Router/RouteAbstract.php b/Router/RouteAbstract.php index e69de29bb..5eec48460 100644 --- a/Router/RouteAbstract.php +++ b/Router/RouteAbstract.php @@ -0,0 +1,34 @@ + + * @author Dennis Eichhorn + * @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 + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +class RouteAbstract +{ + + + +} \ No newline at end of file diff --git a/Router/RouteVerb.php b/Router/RouteVerb.php new file mode 100644 index 000000000..5cb9493a1 --- /dev/null +++ b/Router/RouteVerb.php @@ -0,0 +1,36 @@ + + * @author Dennis Eichhorn + * @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 + * @author Dennis Eichhorn + * @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; +} diff --git a/Router/Router.php b/Router/Router.php index 41594f3e8..ae1e2e169 100644 --- a/Router/Router.php +++ b/Router/Router.php @@ -50,25 +50,30 @@ class Router { } + public function importFromFile(string $path) + { + include $path; + $this->routes = $appRoutes; + } + /** * 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 */ - 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,19 +81,19 @@ 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 */ - 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)) { + if ($this->match($route, $d['verb'], $request->getUri(), $request->getRouteVerb())) { $bound[$route][] = ['dest' => $d['dest'], 'type' => $d['type']]; } } @@ -101,17 +106,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 */ - 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); } } diff --git a/Uri/Http.php b/Uri/Http.php index 87d5d19ca..3fe8aee18 100644 --- a/Uri/Http.php +++ b/Uri/Http.php @@ -15,8 +15,6 @@ */ namespace phpOMS\Uri; - - /** * Uri interface. * From 0b77a3811bc306feed887618a9206472a80242e6 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 16:56:11 +0200 Subject: [PATCH 03/10] array loading changed --- Module/InstallerAbstract.php | 6 +++--- Router/Router.php | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index b4c4c82c7..9e536afc7 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -53,12 +53,12 @@ class InstallerAbstract private static function installRoutes(string $appRoutePath, string $moduleRoutePath) { if(file_exists($appRoutePath) && file_exists($moduleRoutePath)) { - include $appRoutePath; - include $moduleRoutePath; + $appRoutes = include $appRoutePath; + $moduleRoutes = include $moduleRoutePath; $appRoutes = array_merge_recursive($appRoutes, $moduleRoutes); if(is_writable($appRoutePath)) { - file_put_contents(ArrayParser::createFile('moduleRoutes', $appRoutes), $appRoutePath); + file_put_contents('routes = $appRoutes; + $this->routes = include $path; } /** From d7289adf9e7a47e3999fc0dafd3c5039561ba3df Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 17:24:15 +0200 Subject: [PATCH 04/10] Remove request destination --- Message/RequestDestination.php | 52 ---------------------------------- Module/ModuleAbstract.php | 33 +++++---------------- 2 files changed, 7 insertions(+), 78 deletions(-) delete mode 100644 Message/RequestDestination.php diff --git a/Message/RequestDestination.php b/Message/RequestDestination.php deleted file mode 100644 index 7b39125ae..000000000 --- a/Message/RequestDestination.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @author Dennis Eichhorn - * @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 - * @author Dennis Eichhorn - * @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 */ -} diff --git a/Module/ModuleAbstract.php b/Module/ModuleAbstract.php index 564a8ce24..1a8889ba7 100644 --- a/Module/ModuleAbstract.php +++ b/Module/ModuleAbstract.php @@ -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,15 @@ 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 */ + include $path; + /** @var array $MODLANG */ + $lang += $MODLANG; + return $lang; } From 1b0837af1e97ccfcba7ba6491e0164dbf6e80bbc Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 17:25:41 +0200 Subject: [PATCH 05/10] Module init restructure --- Module/ModuleManager.php | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Module/ModuleManager.php b/Module/ModuleManager.php index efdaf7dc5..a1cebdc8b 100644 --- a/Module/ModuleManager.php +++ b/Module/ModuleManager.php @@ -426,25 +426,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. * From b4fae9cb679a8e05be33b084738bd12b4a86bb55 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 17:46:56 +0200 Subject: [PATCH 06/10] Usage of InfoManager --- Module/InstallerAbstract.php | 2 +- Module/ModuleManager.php | 65 +++++++++++++++++++++++++----------- Module/UninstallAbstract.php | 2 +- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index 9e536afc7..09ff3a34b 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -42,7 +42,7 @@ class InstallerAbstract * @since 1.0.0 * @author Dennis Eichhorn */ - 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['directory'] . '/Admin/Routes/http.php'); diff --git a/Module/ModuleManager.php b/Module/ModuleManager.php index a1cebdc8b..c3c2f9543 100644 --- a/Module/ModuleManager.php +++ b/Module/ModuleManager.php @@ -296,18 +296,27 @@ class ModuleManager // todo download; } - $path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json'); + $info = $this->loadInfo(); - if ($path === false || strpos($path, self::MODULE_PATH) === false) { - throw new PathException($module); + $this->registerInDatabase(); + $this->installDependencies($info->getDependencies()); + $this->installModule($module); + $this->installed[$module] = true; + + /* Install providing */ + $providing = $info->getProviding(); + foreach ($providing as $key => $version) { + $this->installProviding($module, $key); } - $info = json_decode(file_get_contents($path), true); - - if (!isset($info)) { - throw new InvalidJsonException($path); + /* Install receiving */ + foreach ($installed as $key => $value) { + $this->installProviding($key, $module); } + } + private function registerInDatabase(InfoManager $info) + { switch ($this->app->dbPool->get('core')->getType()) { case DatabaseType::MYSQL: $this->app->dbPool->get('core')->con->beginTransaction(); @@ -317,11 +326,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 +339,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 +356,41 @@ 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(string $module) + { + $class = '\\Modules\\' . $module . '\\Admin\\Installer'; + + if(!Autoloader::exist($class)) { + throw new \Exception('Module installer does not exist'); + } + /** @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($module); } - /* Install receiving */ - foreach ($installed as $key => $value) { - $this->installProviding($key, $module); - } + $info = InfoManager($module); + $info->load(); + + return $info; } /** diff --git a/Module/UninstallAbstract.php b/Module/UninstallAbstract.php index cfc9c06f6..9da0da83d 100644 --- a/Module/UninstallAbstract.php +++ b/Module/UninstallAbstract.php @@ -42,7 +42,7 @@ class UninstallAbstract * @since 1.0.0 * @author Dennis Eichhorn */ - public static function uninstall(Pool $dbPool, array $info) + public static function uninstall(Pool $dbPool, InfoManager $info) { } From a1cbf8f2bb99e29b0b13e8e7d336f96432d683d8 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 17:55:42 +0200 Subject: [PATCH 07/10] Setting up key functionality --- Module/InfoManager.php | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/Module/InfoManager.php b/Module/InfoManager.php index d0ad53b61..ecc436153 100644 --- a/Module/InfoManager.php +++ b/Module/InfoManager.php @@ -60,12 +60,16 @@ class InfoManager * @author Dennis Eichhorn */ public function __construct(string $module) + { + $this->path = $path; + } + + public function load() { if (($path = realpath($oldPath = ModuleAbstract::MODULE_PATH . '/' . $module . '/info.json')) === false || Validator::startsWith($path, ModuleAbstract::MODULE_PATH)) { throw new PathException($oldPath); } - $this->path = $path; $this->info = json_decode(file_get_contents($this->path), true); } @@ -111,4 +115,34 @@ class InfoManager { return $this->info; } + + public function getInternalName() : string + { + return $this->info['name']['internal']; + } + + public function getDependencies() : string + { + return $this->info['dependencies']; + } + + public function getProviding() : string + { + return $this->info['providing']; + } + + public function getDirectory() : string + { + return $this->info['directory']; + } + + public function getVersion() : string + { + return $this->info['version']; + } + + public function getLoad() : string + { + return $this->info['load']; + } } From 1f1090424b714ff854eed780f9998f8829aaba74 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 2 Apr 2016 22:12:25 +0200 Subject: [PATCH 08/10] Handle different mime types as results --- Message/Http/Header.php | 191 +++++++++++++++++++ Message/{ => Http}/RequestMethod.php | 0 Message/{ => Http}/RequestStatus.php | 0 Message/Http/Response.php | 273 ++++----------------------- Message/MessageInterface.php | 40 +--- Message/ResponseAbstract.php | 24 +-- Views/View.php | 32 +++- 7 files changed, 262 insertions(+), 298 deletions(-) create mode 100644 Message/Http/Header.php rename Message/{ => Http}/RequestMethod.php (100%) rename Message/{ => Http}/RequestStatus.php (100%) diff --git a/Message/Http/Header.php b/Message/Http/Header.php new file mode 100644 index 000000000..dd0943f2e --- /dev/null +++ b/Message/Http/Header.php @@ -0,0 +1,191 @@ + + * @author Dennis Eichhorn + * @copyright 2013 Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link http://orange-management.com + */ +namespace phpOMS\Message\Http; + +use phpOMS\Contract\ArrayableInterface; +use phpOMS\Contract\RenderableInterface; +use phpOMS\Message\ResponseAbstract; +use phpOMS\Model\Html\Head; +use phpOMS\Utils\ArrayUtils; +use phpOMS\DataStorage\Cookie\CookieJar; +use phpOMS\DataStorage\Session\HttpSession; + +/** + * Response class. + * + * @category Framework + * @package phpOMS\Response + * @author OMS Development Team + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +class Header extends HeaderAbstract +{ + + /** + * Header. + * + * @var string[][] + * @since 1.0.0 + */ + private $header = []; + + public function __constrct() + { + $this->setHeader('Content-Type', 'text/html; charset=utf-8'); + } + + /** + * Remove header by ID. + * + * @param int $key Header key + * + * @return bool + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function remove(int $key) : bool + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + if (isset($this->header[$key])) { + unset($this->header[$key]); + + return true; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function get(string $id) : array + { + return $this->header[$id] ?? []; + } + + /** + * {@inheritdoc} + */ + public function has(string $name) : bool + { + return array_key_exists($name, $this->header); + } + + /** + * {@inheritdoc} + */ + public function set($key, string $header, bool $overwrite = false) : bool + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + if (!$overwrite && isset($this->header[$key])) { + return false; + } elseif ($overwrite) { + unset($this->header[$key]); + } + + if (!isset($this->header[$key])) { + $this->header[$key] = []; + } + + $this->header[$key][] = $header; + + return true; + } + + /** + * Push all headers. + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function push() + { + if (self::$isLocked) { + throw new \Exception('Already locked'); + } + + foreach ($this->header as $name => $arr) { + foreach ($arr as $ele => $value) { + header($name . ': ' . $value); + } + } + + $this->lock(); + } + + private function lock() + { + CookieJar::lock(); + HttpSession::lock(); + self::$isLocked = true; + } + + /** + * Generate header automatically based on code. + * + * @param string $code HTTP status code + * + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function generate(string $code) + { + switch($code) { + case RequestStatus::R_403: + $this->generate403(); + break; + case RequestStatus::R_406: + $this->generate406(); + break; + case RequestStatus::R_407: + $this->generate503(); + break; + default: + throw new \Exception('Unexpected header code'); + } + } + + private function generate403() + { + $this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden'); + $this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden'); + } + + private function generate406() + { + $this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable'); + $this->setHeader('Status', 'Status: 406 Not acceptable'); + } + + private function generate503() + { + $this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable'); + $this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable'); + $this->setHeader('Retry-After', 'Retry-After: 300'); + } +} \ No newline at end of file diff --git a/Message/RequestMethod.php b/Message/Http/RequestMethod.php similarity index 100% rename from Message/RequestMethod.php rename to Message/Http/RequestMethod.php diff --git a/Message/RequestStatus.php b/Message/Http/RequestStatus.php similarity index 100% rename from Message/RequestStatus.php rename to Message/Http/RequestStatus.php diff --git a/Message/Http/Response.php b/Message/Http/Response.php index c44a01cba..fe4ed8917 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -36,25 +36,6 @@ use phpOMS\DataStorage\Session\HttpSession; */ class Response extends ResponseAbstract implements RenderableInterface { - - /** - * Header. - * - * @var string[][] - * @since 1.0.0 - */ - private $header = []; - - /** - * html head. - * - * @var Head - * @since 1.0.0 - */ - private $head = null; - - private static $isLocked = false; - /** * Constructor. * @@ -63,96 +44,6 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function __construct() { - $this->setHeader('Content-Type', 'text/html; charset=utf-8'); - $this->head = new Head(); - } - - /** - * Push header by ID. - * - * @param mixed $name Header ID - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function pushHeaderId($name) - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - foreach ($this->header[$name] as $key => $value) { - header($name, $value); - } - - $this->lock(); - } - - /** - * Remove header by ID. - * - * @param int $key Header key - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function removeHeader(int $key) : bool - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - if (isset($this->header[$key])) { - unset($this->header[$key]); - - return true; - } - - return false; - } - - /** - * Generate header automatically based on code. - * - * @param int $code HTTP status code - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function generateHeader(int $code) - { - if ($code === 403) { - $this->generate403(); - } elseif ($code === 406) { - $this->generate406(); - } elseif ($code === 503) { - $this->generate503(); - } - } - - private function generate403() - { - $this->setHeader('HTTP', 'HTTP/1.0 403 Forbidden'); - $this->setHeader('Status', 'Status: HTTP/1.0 403 Forbidden'); - } - - private function generate406() - { - $this->setHeader('HTTP', 'HTTP/1.0 406 Not acceptable'); - $this->setHeader('Status', 'Status: 406 Not acceptable'); - } - - private function generate503() - { - $this->setHeader('HTTP', 'HTTP/1.0 503 Service Temporarily Unavailable'); - $this->setHeader('Status', 'Status: 503 Service Temporarily Unavailable'); - $this->setHeader('Retry-After', 'Retry-After: 300'); } /** @@ -187,44 +78,6 @@ class Response extends ResponseAbstract implements RenderableInterface ob_end_flush(); } - /** - * Generate response. - * - * @return \Iterator - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getYield() : \Iterator - { - yield $this->head->render(); - - foreach ($this->response as $key => $response) { - yield $response; - } - } - - /** - * Push all headers. - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function pushHeader() - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - foreach ($this->header as $name => $arr) { - foreach ($arr as $ele => $value) { - header($name . ': ' . $value); - } - } - - $this->lock(); - } - /** * Remove response by ID. * @@ -250,14 +103,6 @@ class Response extends ResponseAbstract implements RenderableInterface return false; } - /** - * {@inheritdoc} - */ - public function getHead() - { - return $this->head; - } - /** * {@inheritdoc} */ @@ -266,22 +111,6 @@ class Response extends ResponseAbstract implements RenderableInterface return '1.0'; } - /** - * {@inheritdoc} - */ - public function getHeaders() : array - { - return $this->header; - } - - /** - * {@inheritdoc} - */ - public function hasHeader(string $name) : bool - { - return array_key_exists($name, $this->header); - } - /** * {@inheritdoc} */ @@ -302,14 +131,26 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function render() : string { - $render = $this->head->render(); + switch($this->header->get('Content-Type')) { + case MimeType::M_JSON: + return $this->getJson(); + default: + return $this->getRaw(); + } + } + + private function getJson() : string + { + return json_encode($this->getArray()); + } + + private function getRaw() : string + { + $render = ''; - // todo: fix api return - // right now it is_object hence not printing the request key => object and only object->render(); - // this can't be changed easily since view uses this as well and this mustn't print a key. maybe view instanceof View? foreach ($this->response as $key => $response) { - if (is_object($response)) { - $render .= $response->render(); + if ($response instanceOf \Serializable) { + $render .= $response->serialize(); } elseif (is_string($response) || is_numeric($response)) { $render .= $response; } elseif (is_array($response)) { @@ -319,34 +160,29 @@ class Response extends ResponseAbstract implements RenderableInterface throw new \Exception('Wrong response type'); } } - + return $render; } - /** - * {@inheritdoc} - */ - public function toCsv() : string + private function getArray() : array { - return ArrayUtils::arrayToCSV($this->toArray()); - } + $result = []; - /** - * {@inheritdoc} - */ - public function toArray() : array - { - $arr = []; - - foreach ($this->response as $key => $response) { - if ($response instanceof ArrayableInterface) { - $arr = ArrayUtils::setArray($key, $arr, $response->toArray(), ':'); + foreach($this->response as $key => $response) { + if($reponse instanceof Views) { + $result += $response->getArray(); + } elseif(is_array($response)) { + $result += $response; + } elseif(is_scalar($response)) { + $result[] = $response; + } elseif($response instanceof \Serializable) { + $result[] = $response->serialize(); } else { - $arr = ArrayUtils::setArray($key, $arr, $response, ':'); + throw new \Exception('Wrong response type'); } } - return $arr; + return $result; } /** @@ -354,49 +190,6 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function getReasonPhrase() : string { - return $this->getHeader('Status'); - } - - /** - * {@inheritdoc} - */ - public function getHeader(string $name) - { - if (isset($this->header[$name])) { - return $this->header[$name]; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function setHeader($key, string $header, bool $overwrite = false) : bool - { - if (self::$isLocked) { - throw new \Exception('Already locked'); - } - - if (!$overwrite && isset($this->header[$key])) { - return false; - } elseif ($overwrite) { - unset($this->header[$key]); - } - - if (!isset($this->header[$key])) { - $this->header[$key] = []; - } - - $this->header[$key][] = $header; - - return true; - } - - private function lock() - { - CookieJar::lock(); - HttpSession::lock(); - self::$isLocked = true; + return $this->header->getHeader('Status'); } } diff --git a/Message/MessageInterface.php b/Message/MessageInterface.php index ad0984cb2..853e4fd6f 100644 --- a/Message/MessageInterface.php +++ b/Message/MessageInterface.php @@ -45,45 +45,7 @@ interface MessageInterface * @since 1.0.0 * @author Dennis Eichhorn */ - public function getHeaders() : array; - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Header name - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function hasHeader(string $name) : bool; - - /** - * Retrieves a message header value by the given case-insensitive name. - * - * @param string $name Header name - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function getHeader(string $name); - - /** - * Add header by ID. - * - * @param mixed $key Header ID - * @param string $header Header string - * @param bool $overwrite Overwrite existing headers - * - * @return bool - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function setHeader($key, string $header, bool $overwrite = true); + public function getHeader() : HeaderAbstract; /** * Gets the body of the message. diff --git a/Message/ResponseAbstract.php b/Message/ResponseAbstract.php index c54d694b6..205927c03 100644 --- a/Message/ResponseAbstract.php +++ b/Message/ResponseAbstract.php @@ -66,10 +66,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, */ protected $account = null; - /** - * {@inheritdoc} - */ - abstract public function setHeader($key, string $header, bool $overwrite = true); + protected $header = null; /** * {@inheritdoc} @@ -125,7 +122,7 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, public function setStatusCode(string $status) { $this->status = $status; - $this->generateHeader($status); + $this->header->generate($status); } /** @@ -160,15 +157,10 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, return json_encode($this->toArray()); } - /** - * Generate header automatically based on code. - * - * @param int $code HTTP status code - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - abstract public function generateHeader(int $code); + public function getHeader() : HeaderAbstract + { + return $this->header; + } + + public function getBody() : string; } diff --git a/Views/View.php b/Views/View.php index 1c6b62cad..028197018 100644 --- a/Views/View.php +++ b/Views/View.php @@ -34,7 +34,7 @@ use phpOMS\Validation\Validator; * @link http://orange-management.com * @since 1.0.0 */ -class View implements RenderableInterface +class View implements \Serializeable { /** @@ -288,9 +288,14 @@ class View implements RenderableInterface ob_start(); /** @noinspection PhpIncludeInspection */ - include $path; + $data = include $path; + $ob = ob_get_clean(); - return ob_get_clean(); + if(is_array($data)) { + return $data; + } + + return $ob; } /** @@ -355,4 +360,25 @@ class View implements RenderableInterface $this->data[$id] = $data; } + public function getArray() : array + { + $viewArray = []; + + $viewArray[] = $this->render(); + + foreach($this->views as $key => $view) { + $viewArray[$key] = $view->getArray(); + } + } + + public function serialize() + { + return $this->renderAll(); + } + + public function unserialize($raw) + { + + } + } From bab6abfd0dd0fe3c290f350e4701f0b01a945e99 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sun, 3 Apr 2016 21:14:54 +0200 Subject: [PATCH 09/10] General bug fixes --- Autoloader.php | 2 ++ Dispatcher/Dispatcher.php | 2 +- Message/HeaderAbstract.php | 32 ++++++++++++++++++++++++++++ Message/Http/Header.php | 18 ++++++++++++---- Message/Http/Request.php | 31 +-------------------------- Message/Http/RequestMethod.php | 2 +- Message/Http/Response.php | 6 +++--- Message/Http/Rest.php | 2 +- Message/RequestAbstract.php | 7 ++++++ Message/{Http => }/RequestStatus.php | 0 Message/ResponseAbstract.php | 7 +++--- Router/Router.php | 1 - System/File/Directory.php | 4 ++-- System/File/File.php | 4 ++-- System/File/FileAbstract.php | 2 +- Views/View.php | 23 ++------------------ 16 files changed, 72 insertions(+), 71 deletions(-) create mode 100644 Message/HeaderAbstract.php rename Message/{Http => }/RequestStatus.php (100%) diff --git a/Autoloader.php b/Autoloader.php index 6907dfad7..8d5f545bf 100644 --- a/Autoloader.php +++ b/Autoloader.php @@ -73,6 +73,8 @@ class Autoloader return $class; } + echo $class; + return false; } diff --git a/Dispatcher/Dispatcher.php b/Dispatcher/Dispatcher.php index 1ce64f549..bd961a9c9 100644 --- a/Dispatcher/Dispatcher.php +++ b/Dispatcher/Dispatcher.php @@ -118,7 +118,7 @@ class Dispatcher throw new \UnexpectedValueException('Unexpected function.'); } - return $views + return $views; } private function dispatchArray(array $controller, RequestAbstract $request, ResponseAbstract $response, $data = null) : array diff --git a/Message/HeaderAbstract.php b/Message/HeaderAbstract.php new file mode 100644 index 000000000..def6fb17c --- /dev/null +++ b/Message/HeaderAbstract.php @@ -0,0 +1,32 @@ + + * @author Dennis Eichhorn + * @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 + * @author Dennis Eichhorn + * @license OMS License 1.0 + * @link http://orange-management.com + * @since 1.0.0 + */ +class HeaderAbstract +{ + private static $isLocked = false; +} \ No newline at end of file diff --git a/Message/Http/Header.php b/Message/Http/Header.php index dd0943f2e..0ca37694e 100644 --- a/Message/Http/Header.php +++ b/Message/Http/Header.php @@ -15,10 +15,7 @@ */ namespace phpOMS\Message\Http; -use phpOMS\Contract\ArrayableInterface; -use phpOMS\Contract\RenderableInterface; -use phpOMS\Message\ResponseAbstract; -use phpOMS\Model\Html\Head; +use phpOMS\Message\HeaderAbstract; use phpOMS\Utils\ArrayUtils; use phpOMS\DataStorage\Cookie\CookieJar; use phpOMS\DataStorage\Session\HttpSession; @@ -50,6 +47,19 @@ class Header extends HeaderAbstract $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. * diff --git a/Message/Http/Request.php b/Message/Http/Request.php index b67174a82..6780bc4ee 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -399,31 +399,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,11 +430,6 @@ class Request extends RequestAbstract return $this->files; } - public function setHeader($key, string $header, bool $overwrite = true) - { - // NOT Required for Http request - } - public function getRouteVerb() : int { switch($this->method) { diff --git a/Message/Http/RequestMethod.php b/Message/Http/RequestMethod.php index 9f51448fb..dcdd4c4f7 100644 --- a/Message/Http/RequestMethod.php +++ b/Message/Http/RequestMethod.php @@ -13,7 +13,7 @@ * @version 1.0.0 * @link http://orange-management.com */ -namespace phpOMS\Message; +namespace phpOMS\Message\Http; use phpOMS\Datatypes\Enum; diff --git a/Message/Http/Response.php b/Message/Http/Response.php index fe4ed8917..3f5a1c812 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -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; @@ -44,6 +43,7 @@ class Response extends ResponseAbstract implements RenderableInterface */ public function __construct() { + $this->header = new Header(); } /** @@ -160,7 +160,7 @@ class Response extends ResponseAbstract implements RenderableInterface throw new \Exception('Wrong response type'); } } - + return $render; } diff --git a/Message/Http/Rest.php b/Message/Http/Rest.php index d99435014..39210d4c3 100644 --- a/Message/Http/Rest.php +++ b/Message/Http/Rest.php @@ -15,7 +15,7 @@ */ namespace phpOMS\Message\Http; -use phpOMS\Message\RequestMethod; +use phpOMS\Message\Http\RequestMethod; /** * Rest request class. diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index c8b595076..a59e9d70b 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -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} */ diff --git a/Message/Http/RequestStatus.php b/Message/RequestStatus.php similarity index 100% rename from Message/Http/RequestStatus.php rename to Message/RequestStatus.php diff --git a/Message/ResponseAbstract.php b/Message/ResponseAbstract.php index 205927c03..4c1ecb88b 100644 --- a/Message/ResponseAbstract.php +++ b/Message/ResponseAbstract.php @@ -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 { /** @@ -162,5 +161,5 @@ abstract class ResponseAbstract implements MessageInterface, ArrayableInterface, return $this->header; } - public function getBody() : string; + abstract public function getBody() : string; } diff --git a/Router/Router.php b/Router/Router.php index aebd6fe63..bb1703aeb 100644 --- a/Router/Router.php +++ b/Router/Router.php @@ -15,7 +15,6 @@ */ namespace phpOMS\Router; -use phpOMS\Message\RequestMethod; use phpOMS\Views\ViewLayout; /** diff --git a/System/File/Directory.php b/System/File/Directory.php index 1d6b15dbe..62f66d96a 100644 --- a/System/File/Directory.php +++ b/System/File/Directory.php @@ -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; } diff --git a/System/File/File.php b/System/File/File.php index 611548f07..4af2bd6d9 100644 --- a/System/File/File.php +++ b/System/File/File.php @@ -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; } diff --git a/System/File/FileAbstract.php b/System/File/FileAbstract.php index 87dca8ef3..88ce3f03f 100644 --- a/System/File/FileAbstract.php +++ b/System/File/FileAbstract.php @@ -184,7 +184,7 @@ abstract class FileAbstract * @since 1.0.0 * @author Dennis Eichhorn */ - abstract private function createNode() : bool; + abstract public function createNode() : bool; /** * Get created at. diff --git a/Views/View.php b/Views/View.php index 028197018..c58fed212 100644 --- a/Views/View.php +++ b/Views/View.php @@ -34,7 +34,7 @@ use phpOMS\Validation\Validator; * @link http://orange-management.com * @since 1.0.0 */ -class View implements \Serializeable +class View implements \Serializable { /** @@ -250,25 +250,6 @@ class View implements \Serializeable } } - /** - * Get view/template response of all views. - * - * @return string - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function renderAll() : string - { - ob_start(); - - foreach ($this->views as $key => $view) { - echo $view->render(); - } - - return ob_get_clean(); - } - /** * Get view/template response. * @@ -373,7 +354,7 @@ class View implements \Serializeable public function serialize() { - return $this->renderAll(); + return $this->render(); } public function unserialize($raw) From 4a127fd1acaf03951c37c09fa0973c4e29f4788e Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Sat, 9 Apr 2016 10:44:12 +0200 Subject: [PATCH 10/10] Fixing remaining bugs for route-restructure --- Autoloader.php | 2 - Config/SettingsAbstract.php | 36 ++++++----- .../Connection/ConnectionException.php | 0 .../Database/DatabaseExceptionFactory.php | 57 +++++++++++++++++ .../Schema/Exception/TableException.php | 62 +++++++++++++++++++ Dispatcher/Dispatcher.php | 9 ++- Message/Http/Request.php | 5 +- Message/Http/Response.php | 1 + Module/InfoManager.php | 14 ++--- Module/InstallerAbstract.php | 12 ++-- Module/ModuleAbstract.php | 4 +- Module/ModuleManager.php | 46 ++++++++------ Router/RouteVerb.php | 1 + Router/Router.php | 3 +- Views/View.php | 1 - 15 files changed, 192 insertions(+), 61 deletions(-) create mode 100644 DataStorage/Database/Connection/ConnectionException.php create mode 100644 DataStorage/Database/DatabaseExceptionFactory.php create mode 100644 DataStorage/Database/Schema/Exception/TableException.php diff --git a/Autoloader.php b/Autoloader.php index 8d5f545bf..6907dfad7 100644 --- a/Autoloader.php +++ b/Autoloader.php @@ -73,8 +73,6 @@ class Autoloader return $class; } - echo $class; - return false; } diff --git a/Config/SettingsAbstract.php b/Config/SettingsAbstract.php index 7cf6a8eb1..a0ead306e 100644 --- a/Config/SettingsAbstract.php +++ b/Config/SettingsAbstract.php @@ -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; } /** diff --git a/DataStorage/Database/Connection/ConnectionException.php b/DataStorage/Database/Connection/ConnectionException.php new file mode 100644 index 000000000..e69de29bb diff --git a/DataStorage/Database/DatabaseExceptionFactory.php b/DataStorage/Database/DatabaseExceptionFactory.php new file mode 100644 index 000000000..1524f84b2 --- /dev/null +++ b/DataStorage/Database/DatabaseExceptionFactory.php @@ -0,0 +1,57 @@ + + * @author Dennis Eichhorn + * @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 + * @author Dennis Eichhorn + * @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 + */ + 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())); + } +} diff --git a/DataStorage/Database/Schema/Exception/TableException.php b/DataStorage/Database/Schema/Exception/TableException.php new file mode 100644 index 000000000..836ad46c9 --- /dev/null +++ b/DataStorage/Database/Schema/Exception/TableException.php @@ -0,0 +1,62 @@ + + * @author Dennis Eichhorn + * @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 + * @author Dennis Eichhorn + * @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 + */ + 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); + } +} diff --git a/Dispatcher/Dispatcher.php b/Dispatcher/Dispatcher.php index bd961a9c9..dd113d76b 100644 --- a/Dispatcher/Dispatcher.php +++ b/Dispatcher/Dispatcher.php @@ -85,8 +85,7 @@ 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']; } @@ -95,7 +94,7 @@ class Dispatcher } elseif (is_array($controller)) { $views += $this->dispatchArray($controller, $request, $response, $data); } elseif ($controller instanceof \Closure) { - $views[$type][] = $this->dispatchClosure($controller, $request, $response, $data); + $views[] = $this->dispatchClosure($controller, $request, $response, $data); } else { throw new \UnexpectedValueException('Unexpected controller type.'); } @@ -111,9 +110,9 @@ class Dispatcher if (($c = count($dispatch)) == 3) { /* Handling static functions */ - $views[$type][$controller] = $dispatch[0]::$dispatch[2](); + $views[$controller] = $dispatch[0]::$dispatch[2](); } elseif ($c == 2) { - $views[$type][$controller] = $this->controllers[$dispatch[0]]->{$dispatch[1]}($request, $response, $data); + $views[$controller] = $this->controllers[$dispatch[0]]->{$dispatch[1]}($request, $response, $data); } else { throw new \UnexpectedValueException('Unexpected function.'); } diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 6780bc4ee..629f9a8c6 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -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; @@ -432,7 +433,7 @@ class Request extends RequestAbstract public function getRouteVerb() : int { - switch($this->method) { + switch($this->getMethod()) { case RequestMethod::GET: return RouteVerb::GET; case RequestMethod::PUT: diff --git a/Message/Http/Response.php b/Message/Http/Response.php index 3f5a1c812..752937651 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -157,6 +157,7 @@ class Response extends ResponseAbstract implements RenderableInterface $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'); } } diff --git a/Module/InfoManager.php b/Module/InfoManager.php index ecc436153..343491d2a 100644 --- a/Module/InfoManager.php +++ b/Module/InfoManager.php @@ -59,18 +59,18 @@ class InfoManager * @since 1.0.0 * @author Dennis Eichhorn */ - public function __construct(string $module) + public function __construct($path) { $this->path = $path; } public function load() { - if (($path = realpath($oldPath = ModuleAbstract::MODULE_PATH . '/' . $module . '/info.json')) === false || Validator::startsWith($path, ModuleAbstract::MODULE_PATH)) { - throw new PathException($oldPath); + if (($path = realpath($this->path)) === false) { + throw new PathException($this->path); } - $this->info = json_decode(file_get_contents($this->path), true); + $this->info = json_decode(file_get_contents($path), true); } /** @@ -121,12 +121,12 @@ class InfoManager return $this->info['name']['internal']; } - public function getDependencies() : string + public function getDependencies() : array { return $this->info['dependencies']; } - public function getProviding() : string + public function getProviding() : array { return $this->info['providing']; } @@ -141,7 +141,7 @@ class InfoManager return $this->info['version']; } - public function getLoad() : string + public function getLoad() : array { return $this->info['load']; } diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index 09ff3a34b..8fb39a65e 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -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. @@ -44,10 +47,9 @@ class InstallerAbstract */ public static function install(Pool $dbPool, InfoManager $info) { - - self::$installRoutes(ROOT_PATH . '/Web/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/http.php'); - self::$installRoutes(ROOT_PATH . '/Socket/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/socket.php'); - self::$installRoutes(ROOT_PATH . '/Console/Routes.php', ROOT_PATH . '/Modules/' . $info['directory'] . '/Admin/Routes/console.php'); + 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) @@ -58,7 +60,7 @@ class InstallerAbstract $appRoutes = array_merge_recursive($appRoutes, $moduleRoutes); if(is_writable($appRoutePath)) { - file_put_contents('loadInfo(); + try { + $info = $this->loadInfo($module); - $this->registerInDatabase(); - $this->installDependencies($info->getDependencies()); - $this->installModule($module); - $this->installed[$module] = true; + $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 providing */ + $providing = $info->getProviding(); + foreach ($providing as $key => $version) { + $this->installProviding($module, $key); + } - /* Install receiving */ - foreach ($installed as $key => $value) { - $this->installProviding($key, $module); + /* 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(); } } @@ -365,13 +373,11 @@ class ModuleManager } } - private function installModule(string $module) + private function installModule(InfoManager $info) { + $class = '\\Modules\\' . $info->getDirectory() . '\\Admin\\Installer'; - - $class = '\\Modules\\' . $module . '\\Admin\\Installer'; - - if(!Autoloader::exist($class)) { + if(!Autoloader::exists($class)) { throw new \Exception('Module installer does not exist'); } @@ -384,10 +390,10 @@ class ModuleManager $path = realpath($oldPath = self::MODULE_PATH . '/' . $module . '/' . 'info.json'); if ($path === false || strpos($path, self::MODULE_PATH) === false) { - throw new PathException($module); + throw new PathException($oldPath); } - $info = InfoManager($module); + $info = new InfoManager($path); $info->load(); return $info; diff --git a/Router/RouteVerb.php b/Router/RouteVerb.php index 5cb9493a1..7fe08ddfb 100644 --- a/Router/RouteVerb.php +++ b/Router/RouteVerb.php @@ -33,4 +33,5 @@ abstract class RouteVerb extends Enum const GET = 1; const PUT = 2; const SET = 3; + const ANY = 4; } diff --git a/Router/Router.php b/Router/Router.php index bb1703aeb..8723951ee 100644 --- a/Router/Router.php +++ b/Router/Router.php @@ -16,6 +16,7 @@ namespace phpOMS\Router; use phpOMS\Views\ViewLayout; +use phpOMS\Message\RequestAbstract; /** * Router class. @@ -92,7 +93,7 @@ class Router foreach ($this->routes as $route => $destination) { foreach ($destination as $d) { if ($this->match($route, $d['verb'], $request->getUri(), $request->getRouteVerb())) { - $bound[$route][] = ['dest' => $d['dest'], 'type' => $d['type']]; + $bound[] = ['dest' => $d['dest']]; } } } diff --git a/Views/View.php b/Views/View.php index c58fed212..9e08b94a3 100644 --- a/Views/View.php +++ b/Views/View.php @@ -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;