From b392eb9188f14b6a903984652efd1892ba77cfac Mon Sep 17 00:00:00 2001 From: coderkun Date: Fri, 9 Aug 2013 02:41:06 +0200 Subject: [PATCH 01/34] current state as framework --- .htaccess | 30 + agents/BottomlevelAgent.inc | 53 ++ agents/IntermediateAgent.inc | 48 ++ agents/ToplevelAgent.inc | 379 +++++++++++++ agents/bottomlevel/empty | 0 agents/intermediate/empty | 0 agents/toplevel/empty | 0 apis/WebApi.inc | 245 +++++++++ app/empty | 0 bootstrap.inc | 33 ++ configs/AppConfig.inc | 75 +++ configs/CoreConfig.inc | 167 ++++++ controllers/empty | 0 core/Agent.inc | 607 +++++++++++++++++++++ core/Api.inc | 163 ++++++ core/Autoloader.inc | 98 ++++ core/ClassLoader.inc | 129 +++++ core/Config.inc | 49 ++ core/Controller.inc | 381 +++++++++++++ core/Driver.inc | 96 ++++ core/Exception.inc | 65 +++ core/Linker.inc | 322 +++++++++++ core/Logger.inc | 116 ++++ core/Model.inc | 140 +++++ core/Request.inc | 64 +++ core/Response.inc | 158 ++++++ core/View.inc | 124 +++++ core/WebUtils.inc | 68 +++ drivers/DatabaseDriver.inc | 81 +++ drivers/MysqlDriver.inc | 153 ++++++ exceptions/ActionNotFoundException.inc | 77 +++ exceptions/AgentNotFoundException.inc | 67 +++ exceptions/AgentNotValidException.inc | 67 +++ exceptions/ClassNotFoundException.inc | 77 +++ exceptions/ClassNotValidException.inc | 77 +++ exceptions/ControllerNotFoundException.inc | 68 +++ exceptions/ControllerNotValidException.inc | 68 +++ exceptions/DatamodelException.inc | 99 ++++ exceptions/DriverNotFoundException.inc | 68 +++ exceptions/DriverNotValidException.inc | 68 +++ exceptions/FatalDatamodelException.inc | 96 ++++ exceptions/LayoutNotFoundException.inc | 68 +++ exceptions/LayoutNotValidException.inc | 67 +++ exceptions/ModelNotFoundException.inc | 67 +++ exceptions/ModelNotValidException.inc | 68 +++ exceptions/ParamsNotValidException.inc | 77 +++ exceptions/ServiceUnavailableException.inc | 77 +++ exceptions/ViewNotFoundException.inc | 77 +++ logs/empty | 0 models/DatabaseModel.inc | 129 +++++ requests/WebRequest.inc | 358 ++++++++++++ responses/WebResponse.inc | 250 +++++++++ views/error.tpl | 13 + views/inlineerror.tpl | 1 + www/.htaccess | 8 + www/index.php | 45 ++ 56 files changed, 5981 insertions(+) create mode 100644 .htaccess create mode 100644 agents/BottomlevelAgent.inc create mode 100644 agents/IntermediateAgent.inc create mode 100644 agents/ToplevelAgent.inc create mode 100644 agents/bottomlevel/empty create mode 100644 agents/intermediate/empty create mode 100644 agents/toplevel/empty create mode 100644 apis/WebApi.inc create mode 100644 app/empty create mode 100644 bootstrap.inc create mode 100644 configs/AppConfig.inc create mode 100644 configs/CoreConfig.inc create mode 100644 controllers/empty create mode 100644 core/Agent.inc create mode 100644 core/Api.inc create mode 100644 core/Autoloader.inc create mode 100644 core/ClassLoader.inc create mode 100644 core/Config.inc create mode 100644 core/Controller.inc create mode 100644 core/Driver.inc create mode 100644 core/Exception.inc create mode 100644 core/Linker.inc create mode 100644 core/Logger.inc create mode 100644 core/Model.inc create mode 100644 core/Request.inc create mode 100644 core/Response.inc create mode 100644 core/View.inc create mode 100644 core/WebUtils.inc create mode 100644 drivers/DatabaseDriver.inc create mode 100644 drivers/MysqlDriver.inc create mode 100644 exceptions/ActionNotFoundException.inc create mode 100644 exceptions/AgentNotFoundException.inc create mode 100644 exceptions/AgentNotValidException.inc create mode 100644 exceptions/ClassNotFoundException.inc create mode 100644 exceptions/ClassNotValidException.inc create mode 100644 exceptions/ControllerNotFoundException.inc create mode 100644 exceptions/ControllerNotValidException.inc create mode 100644 exceptions/DatamodelException.inc create mode 100644 exceptions/DriverNotFoundException.inc create mode 100644 exceptions/DriverNotValidException.inc create mode 100644 exceptions/FatalDatamodelException.inc create mode 100644 exceptions/LayoutNotFoundException.inc create mode 100644 exceptions/LayoutNotValidException.inc create mode 100644 exceptions/ModelNotFoundException.inc create mode 100644 exceptions/ModelNotValidException.inc create mode 100644 exceptions/ParamsNotValidException.inc create mode 100644 exceptions/ServiceUnavailableException.inc create mode 100644 exceptions/ViewNotFoundException.inc create mode 100644 logs/empty create mode 100644 models/DatabaseModel.inc create mode 100644 requests/WebRequest.inc create mode 100644 responses/WebResponse.inc create mode 100644 views/error.tpl create mode 100644 views/inlineerror.tpl create mode 100644 www/.htaccess create mode 100644 www/index.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 00000000..e5c5c191 --- /dev/null +++ b/.htaccess @@ -0,0 +1,30 @@ +Allow From All +Options -Indexes -MultiViews + +ErrorDocument 403 /www/error403.html +ErrorDocument 404 /www/error404.html +ErrorDocument 500 /www/error500.html + + + + Order Deny,Allow + Deny From All + + + + Order Deny,Allow + Deny From All + + + + Order Deny,Allow + Deny From All + + + + + RewriteEngine On + + RewriteBase / + RewriteRule ^(.*)$ www/$1 [L] + diff --git a/agents/BottomlevelAgent.inc b/agents/BottomlevelAgent.inc new file mode 100644 index 00000000..95629e48 --- /dev/null +++ b/agents/BottomlevelAgent.inc @@ -0,0 +1,53 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The BottomlevelAgent is the standard Agent and can have indefinite + * SubAgents. + * + * @author coderkun + */ + abstract class BottomlevelAgent extends \nre\core\Agent + { + + + + + /** + * Load a BottomlevelAgent. + * + * @throws AgentNotFoundException + * @throws AgentNotValidException + * @param string $agentName BottomlevelAgent name + */ + public static function load($agentName) + { + // Load class + parent::load_agent($agentName, Autoloader::getClassName(get_class())); + + // Determine full classname + $className = Autoloader::concatClassNames($agentName, Autoloader::getClassType(get_class())); + + // Validate class + try { + ClassLoader::check($className, get_class()); + } + catch(ClassNotValidException $e) { + throw new AgentNotValidException($e->getClassName()); + } + } + + } + +?> diff --git a/agents/IntermediateAgent.inc b/agents/IntermediateAgent.inc new file mode 100644 index 00000000..7139653d --- /dev/null +++ b/agents/IntermediateAgent.inc @@ -0,0 +1,48 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The IntermediateAgent assumes the task of a module. There is only one + * IntermediateAgent per request. + * + * @author coderkun + */ + abstract class IntermediateAgent extends \nre\core\Agent + { + + + + + /** + * Get the layout if it was explicitly defined. + * + * @return string Layout of the IntermediateAgent + */ + public static function getLayout($agentName) + { + // Determine classname + $className = Autoloader::concatClassNames($agentName, 'Agent'); + + // Check property + if(isset($className::$layout)) { + return $className::$layout; + } + + + return null; + } + + } + +?> diff --git a/agents/ToplevelAgent.inc b/agents/ToplevelAgent.inc new file mode 100644 index 00000000..af98c3d2 --- /dev/null +++ b/agents/ToplevelAgent.inc @@ -0,0 +1,379 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The ToplevelAgent assumes the task of a FrontController. There is + * only one per request. + * + * @author coderkun + */ + class ToplevelAgent extends \nre\core\Agent + { + /** + * Stage: Load + * + * @var string + */ + const STAGE_LOAD = 'load'; + /** + * Stage: Run + * + * @var string + */ + const STAGE_RUN = 'run'; + + /** + * Current request + * + * @var Request + */ + private $request; + /** + * Current response + * + * @var Response + */ + private $response; + /** + * Layout instace + * + * @var Layout + */ + private $layout = null; + /** + * IntermediateAgent instance + * + * @var IntermediateAgent + */ + private $intermediateAgent = null; + + + + + /** + * Construct a ToplevelAgent. + * + * @throws ServiceUnavailableException + * @throws DatamodelException + * @throws DriverNotValidException + * @throws DriverNotFoundException + * @throws ViewNotFoundException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ControllerNotValidException + * @throws ControllerNotFoundException + * @param Request $request Current request + * @param Response $respone Current response + * @param Logger $log Log-system + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + // Store values + $this->request = $request; + $this->response = $response; + + + // Create response + $response = clone $response; + $response->clearParams(1); + $response->addParams( + null, + \nre\configs\CoreConfig::$defaults['action'] + ); + + // Call parent constructor + parent::__construct($request, $response, $log, true); + + + // Load IntermediateAgent + $this->loadIntermediateAgent(); + } + + + + + /** + * Run the Controller of this Agent and its SubAgents. + * + * @throws ServiceUnavailableException + * @param Request $request Current request + * @param Response $response Current response + * @return Exception Last occurred exception of SubAgents + */ + public function run(\nre\core\Request $request, \nre\core\Response $response) + { + try { + return $this->_run($request, $response); + } + catch(ParamsNotValidException $e) { + $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + catch(IdNotFoundException $e) { + $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + catch(DatamodelException $e) { + $this->error($e, WebUtils::HTTP_SERVICE_UNAVAILABLE, self::STAGE_RUN); + } + catch(ActionNotFoundException $e) { + $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + } + + + /** + * Generate output of the Controller of this Agent and its + * SubAgents. + * + * @param array $data View data + * @return string Generated output + */ + public function render($data=array()) + { + // Render IntermediateAgent + $data = array(); + $data['intermediate'] = $this->intermediateAgent->render(); + + + // Render ToplevelAgent + return parent::render($data); + } + + + + + /** + * Load a SubAgent and add it. + * + * @throws ServiceUnavailableException + * @throws FatalDatamodelException + * @throws AgentNotFoundException + * @throws AgentNotValidException + * @param string $agentName Name of the Agent to load + * @param mixed … Additional parameters for the agent + */ + protected function addSubAgent($agentName) + { + try { + call_user_func_array( + array( + $this, + '_addSubAgent' + ), + func_get_args() + ); + } + catch(DatamodelException $e) { + throw new FatalDatamodelException($e->getDatamodelMessage(), $e->getDatamodelErrorNumber()); + } + } + + + + + /** + * Load IntermediateAgent defined by the current request. + * + * @throws ServiceUnavailableException + */ + private function loadIntermediateAgent() + { + try { + $this->_loadIntermediateAgent(); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\AgentNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + } + + + /** + * Load IntermediateAgent defined by the current request. + * + * @throws ServiceUnavailableException + */ + private function _loadIntermediateAgent() + { + // Determine IntermediateAgent + $agentName = $this->response->getParam(1); + if(is_null($agentName)) { + $agentName = $this->request->getParam(1, 'intermediate'); + $this->response->addParam($agentName); + } + + // Load IntermediateAgent + IntermediateAgent::load($agentName); + + + // Determine Action + $action = $this->response->getParam(2); + if(is_null($action)) { + $action = $this->request->getParam(2, 'action'); + $this->response->addParam($action); + } + + // Construct IntermediateAgent + $this->intermediateAgent = \nre\agents\IntermediateAgent::factory( + $agentName, + $this->request, + $this->response, + $this->log + ); + } + + + /** + * Run the Controller of this Agent and its SubAgents. + * + * @throws IdNotFoundException + * @throws ServiceUnavailableException + * @throws DatamodelException + * @param Request $request Current request + * @param Response $response Current response + * @return Exception Last occurred exception of SubAgents + */ + private function _run(\nre\core\Request $request, \nre\core\Response $response) + { + // Run IntermediateAgent + $this->runIntermediateAgent(); + + + // TODO Request instead of response? + $response = clone $response; + $response->clearParams(2); + $response->addParam(\nre\configs\CoreConfig::$defaults['action']); + + + // Run ToplevelAgent + return parent::run($request, $response); + } + + + /** + * Run IntermediateAgent. + * + * @throws ParamsNotValidException + * @throws IdNotFoundException + * @throws ServiceUnavailableException + * @throws DatamodelException + */ + private function runIntermediateAgent() + { + $this->intermediateAgent->run( + $this->request, + $this->response + ); + } + + + /** + * Handle an error that occurred during + * loading/cnostructing/running of the IntermediateAgent. + * + * @throws ServiceUnavailableException + * @param Exception $exception Occurred exception + * @param int $httpStatusCode HTTP-statuscode + * @param string $stage Stage of execution + */ + private function error($exception, $httpStatusCode, $stage=self::STAGE_LOAD) + { + // Log error + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + + try { + // Define ErrorAgent + $this->response->clearParams(1); + $this->response->addParams( + \nre\configs\AppConfig::$defaults['intermediate-error'], + \nre\configs\CoreConfig::$defaults['action'], + $httpStatusCode + ); + + // Load ErrorAgent + $this->_loadIntermediateAgent(); + + // Run ErrorAgent + if($stage == self::STAGE_RUN) { + $this->_run($this->request, $this->response); + } + } + catch(\nre\exceptions\ActionNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DatamodelException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DriverNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ModelNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\AgentNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(Exception $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + } + + + } + +?> diff --git a/agents/bottomlevel/empty b/agents/bottomlevel/empty new file mode 100644 index 00000000..e69de29b diff --git a/agents/intermediate/empty b/agents/intermediate/empty new file mode 100644 index 00000000..e69de29b diff --git a/agents/toplevel/empty b/agents/toplevel/empty new file mode 100644 index 00000000..e69de29b diff --git a/apis/WebApi.inc b/apis/WebApi.inc new file mode 100644 index 00000000..5d4ac7cd --- /dev/null +++ b/apis/WebApi.inc @@ -0,0 +1,245 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\apis; + + + /** + * WebApi-implementation. + * + * This class runs and renders an web-applictaion. + * + * @author coderkun + */ + class WebApi extends \nre\core\Api + { + + + + + /** + * Construct a new WebApi. + */ + public function __construct() + { + parent::__construct( + new \nre\requests\WebRequest(), + new \nre\responses\WebResponse() + ); + + // Add routes + $this->addRoutes(); + } + + + + + /** + * Run application. + * + * This method runs the application and handles all errors. + */ + public function run() + { + try { + $exception = parent::run(); + + if(!is_null($exception)) { + $this->errorService($exception); + } + } + catch(\nre\exceptions\ServiceUnavailableException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $this->error($e, WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\FatalDatamodelException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\AgentNoaatValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\ClassNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + $this->errorService($e); + } + } + + + /** + * Render output. + */ + public function render() + { + // Generate output + parent::render(); + + + // Set HTTP-header + $this->response->header(); + + // Show output + echo $this->response->getOutput(); + } + + + + + /** + * Add routes (normal and reverse) defined in the AppConfig. + */ + private function addRoutes() + { + // Normal routes + if(property_exists('\nre\configs\AppConfig', 'routes')) { + foreach(\nre\configs\AppConfig::$routes as &$route) { + $this->request->addRoute($route[0], $route[1], $route[2]); + } + } + + // Reverse routes + if(property_exists('\nre\configs\AppConfig', 'reverseRoutes')) { + foreach(\nre\configs\AppConfig::$reverseRoutes as &$route) { + $this->request->addReverseRoute($route[0], $route[1], $route[2]); + } + } + + // Revalidate request + $this->request->revalidate(); + } + + + /** + * Handle an error that orrcurred during the + * loading/constructing/running of the ToplevelAgent. + * + * @param Exception $exception Occurred exception + * @param int $httpStatusCode HTTP-statuscode + */ + private function error(\nre\core\Exception $exception, $httpStatusCode) + { + // Log error message + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + try { + // Set agent for handling errors + $this->response->clearParams(); + $this->response->addParams( + \nre\configs\AppConfig::$defaults['toplevel-error'], + \nre\configs\AppConfig::$defaults['intermediate-error'], + \nre\configs\CoreConfig::$defaults['action'], + $httpStatusCode + ); + + // Run this agent + parent::run(); + } + catch(\nre\exceptions\ServiceUnavailableException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DriverNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ModelNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\AgentNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + $this->errorService($e); + } + catch(Exception $e) { + $this->errorService($e); + } + } + + + /** + * Handle a error which cannot be handles by the system (and + * HTTP 503). + * + * $param Exception $exception Occurred exception + */ + private function errorService($exception) + { + // Log error message + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + // Set HTTP-rtatuscode + $this->response->addHeader(\nre\core\WebUtils::getHttpHeader(503)); + + + // Read and print static error file + $fileName = ROOT.DS.\nre\configs\CoreConfig::getClassDir('views').DS.\nre\configs\CoreConfig::$defaults['errorFile'].\nre\configs\CoreConfig::getFileExt('views'); + ob_start(); + include($fileName); + $this->response->setOutput(ob_get_clean()); + + + // Prevent further execution + $this->response->setExit(); + } + + } + +?> diff --git a/app/empty b/app/empty new file mode 100644 index 00000000..e69de29b diff --git a/bootstrap.inc b/bootstrap.inc new file mode 100644 index 00000000..55647ac0 --- /dev/null +++ b/bootstrap.inc @@ -0,0 +1,33 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + // Include required classes + require_once(ROOT.DS.'configs'.DS.'CoreConfig.inc'); + require_once(ROOT.DS.\nre\configs\CoreConfig::getClassDir('core').DS.'Autoloader.inc'); + + + // Set PHP-logging + ini_set('error_log', ROOT.DS.\nre\configs\CoreConfig::getClassDir('logs').DS.'php'.\nre\configs\CoreConfig::getFileExt('logs')); + + // Register autoloader + \nre\core\Autoloader::register(); + + + // Initialize WebApi + $webApi = new \nre\apis\WebApi(); + + // Run WebApi + $webApi->run(); + + // Render output + $webApi->render(); + +?> diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc new file mode 100644 index 00000000..7ce591b2 --- /dev/null +++ b/configs/AppConfig.inc @@ -0,0 +1,75 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\configs; + + + /** + * Application configuration. + * + * This class contains static variables with configuration values for + * the specific application. + * + * @author coderkun + */ + final class AppConfig + { + + /** + * Application values + * + * @static + * @var array + */ + public static $app = array( + //'namespace' => '', + //'timeZone' => '' + ); + + + /** + * Default values + * + * @static + * @var array + */ + public static $defaults = array( + //'toplevel' => '', + //'toplevel-error' => '', + //'intermediate' => '', + //'intermediate-error' => '' + ); + + + /** + * Routes + * + * @static + * @var array + */ + public static $routes = array( + //array('', '', '') + ); + + + /** + * Reverse routes + * + * @static + * @var array + */ + public static $reverseRoutes = array( + //array('', '', '') + ); + + } + +?> diff --git a/configs/CoreConfig.inc b/configs/CoreConfig.inc new file mode 100644 index 00000000..a28b6dbc --- /dev/null +++ b/configs/CoreConfig.inc @@ -0,0 +1,167 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\configs; + + + /** + * Core configuration. + * + * This class contains static variables with configuration values. + * + * @author coderkun + */ + final class CoreConfig + { + + /** + * Core values + * + * @static + * @var array + */ + public static $core = array( + 'namespace' => 'nre\\', + ); + + + /** + * Directories + * + * @static + * @var array + */ + public static $dirs = array( + 'core' => 'core', + 'publicDir' => 'www' + ); + + + /** + * File extensions + * + * @static + * @var array + */ + public static $fileExts = array( + 'default' => 'inc', + 'views' => 'tpl', + 'logs' => 'log', + ); + + + /** + * Default values + * + * @static + * @var array + */ + public static $defaults = array( + 'action' => 'index', + 'errorFile' => 'error', + 'inlineErrorFile' => 'inlineerror' + ); + + + /** + * Miscellaneous settings + * + * @static + * @var array + */ + public static $misc = array( + 'fileExtDot' => '.' + ); + + + /** + * Logging settings + * + * @static + * @var array + */ + public static $log = array( + 'filename' => 'errors', + 'format' => 'Fehler %d: %s in %s, Zeile %d' + ); + + + /** + * Class-specific settings + * + * @static + * @var array + */ + public static $classes = array( + 'linker' => array( + 'url' => array( + 'length' => 50, + 'delimiter' => '-' + ) + ) + ); + + + + + /** + * Determine the directory for a specific classtype. + * + * @param string $classType Classtype to get directory of + * @return string Directory of given classtype + */ + public static function getClassDir($classType) + { + // Default directory (for core classes) + $classDir = self::$dirs['core']; + + // Configurable directory + if(array_key_exists($classType, self::$dirs)) { + $classDir = self::$dirs[$classType]; + } + else + { + // Default directory for classtype + if(is_dir(ROOT.DS.$classType)) { + $classDir = $classType; + } + } + + + // Return directory + return $classDir; + } + + + /** + * Determine the file extension for a specific filetype. + * + * @param string $fileType Filetype to get file extension of + * @return string File extension of given filetype + */ + public static function getFileExt($fileType) + { + // Default file extension + $fileExt = self::$fileExts['default']; + + // Configurable file extension + if(array_key_exists($fileType, self::$fileExts)) { + $fileExt = self::$fileExts[$fileType]; + } + + + // Return file extension + return self::$misc['fileExtDot'].$fileExt; + } + + } + +?> diff --git a/controllers/empty b/controllers/empty new file mode 100644 index 00000000..e69de29b diff --git a/core/Agent.inc b/core/Agent.inc new file mode 100644 index 00000000..07bece26 --- /dev/null +++ b/core/Agent.inc @@ -0,0 +1,607 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for the implementation af an Agent. + * + * @author coderkun + */ + abstract class Agent + { + /** + * Name of BottomlevelAgent for showing inline errors + * + * @var string + */ + const INLINEERROR_AGENT = 'inlineerror'; + + /** + * Current request + * + * @var Request + */ + private $request; + /** + * Current response + * + * @var Response + */ + private $response; + /** + * Log-system + * + * @var Logger + */ + protected $log; + /** + * SubAgents + * + * @var array + */ + protected $subAgents = array(); + /** + * Controller of this Agent + * + * @var Controller + */ + public $controller = null; + + + + + /** + * Load the class of an Agent. + * + * @static + * @throws AgentNotFoundException + * @throws AgentNotValidException + * @param string $agentName Name of the Agent to load + */ + public static function load($agentName) + { + // Determine full classname + $agentType = self::getAgentType(); + $className = self::getClassName($agentName, $agentType); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + $parentAgentClassName = ClassLoader::concatClassNames($agentType, 'agent'); + $parentAgentClassName = "\\nre\\agents\\$parentAgentClassName"; + ClassLoader::check($className, $parentAgentClassName); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\AgentNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\AgentNotFoundException($e->getClassName()); + } + } + + + + /** + * Instantiate an Agent (Factory Pattern). + * + * @static + * @throws DatamodelException + * @throws DriverNotValidException + * @throws DriverNotFoundException + * @throws ViewNotFoundException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ControllerNotValidException + * @throws ControllerNotFoundException + * @param string $agentName Name of the Agent to instantiate + * @param Request $request Current request + * @param Response $respone Current respone + * @param Logger $log Log-system + */ + public static function factory($agentName, Request $request, Response $response, Logger $log=null) + { + // Determine full classname + $agentType = self::getAgentType(); + $className = self::getClassName($agentName, $agentType); + + + // Construct and return Agent + return new $className($request, $response, $log); + } + + + /** + * Determine the type of an Agent. + * + * @static + * @return string Agent type + */ + private static function getAgentType() + { + return strtolower(ClassLoader::getClassName(get_called_class())); + } + + + /** + * Determine the classname for the given Agent name. + * + * @static + * @param string $agentName Agent name to get classname of + * @param string $agentType Agent type of given Agent name + * @return string Classname for the Agent name + */ + private static function getClassName($agentName, $agentType) + { + $className = ClassLoader::concatClassNames($agentName, 'agent'); + + + return \nre\configs\AppConfig::$app['namespace']."agents\\$agentType\\$className"; + } + + + + + /** + * Construct a new Agent. + * + * @throws DatamodelException + * @throws DriverNotValidException + * @throws DriverNotFoundException + * @throws ViewNotFoundException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ControllerNotValidException + * @throws ControllerNotFoundException + * @param Request $request Current request + * @param Response $respone Current response + * @param Logger $log Log-system + */ + protected function __construct(Request $request, Response $response, Logger $log=null) + { + // Store values + $this->request = $request; + $this->response = $response; + $this->log = $log; + + // Construct SubAgent + $this->actionConstruct(); + + // Load corresponding Controller + $this->loadController(); + } + + + + + /** + * Run the Controller of this Agent and its SubAgents. + * + * @throws ParamsNotValidException + * @throws IdNotFoundException + * @throws DatamodelException + * @throws ActionNotFoundException + * @param Request $request Current request + * @param Response $response Current response + * @return Exception Last occurred exception of SubAgents + */ + public function run(Request $request, Response $response) + { + // Check Controller + if(!is_null($this->controller)) + { + // Call prefilter + $this->controller->preFilter($request, $response); + + // Run controller + $this->controller->run($request, $response); + + // Call postfilter + $this->controller->postFilter($request, $response); + } + + + // Run SubAgents + $exception = null; + foreach($this->subAgents as &$subAgent) + { + try { + $subAgent['object']->run( + $request, + $subAgent['response'] + ); + } + catch(ParamsNotValidException $e) { + $subAgent = $this->errorInline($subAgent, $request, $e); + } + catch(IdNotFoundException $e) { + $subAgent = $this->errorInline($subAgent, $request, $e); + } + catch(DatamodelException $e) { + $exception = $e; + $subAgent = $this->errorInline($subAgent, $request, $e); + } + catch(ActionNotFoundException $e) { + $subAgent = $this->errorInline($subAgent, $request, $e); + } + } + + + // Return last occurred exception + return $exception; + } + + + /** + * Generate output of the Controller of this Agent and its + * SubAgents. + * + * @param array $data View data + * @return string Generated output + */ + public function render($data=array()) + { + // Check Controller + if(!is_null($this->controller)) + { + // Render SubAgents + foreach($this->subAgents as $subAgent) + { + $label = array_key_exists('label', $subAgent) ? $subAgent['label'] : $subAgent['name']; + $data[$label] = $this->renderSubAgent($subAgent); + } + + // Render the Controller of this agent + return $this->controller->render($data); + } + } + + + + + /** + * Construct SubAgents (per Action). + */ + protected function actionConstruct() + { + // Action ermitteln + $action = $this->response->getParam(2); + if(is_null($action)) { + $action = $this->request->getParam(2, 'action'); + $this->response->addParam($action); + } + + // Initialisierungsmethode für diese Action ausführen + if(method_exists($this, $action)) + { + call_user_func_array( + array( + $this, + $action + ), + array( + $this->request, + $this->response + ) + ); + } + } + + + /** + * Load the Controller of this Agent. + * + * @throws DatamodelException + * @throws DriverNotValidException + * @throws DriverNotFoundException + * @throws ViewNotFoundException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ControllerNotValidException + * @throws ControllerNotFoundException + */ + protected function loadController() + { + // Determine Controller name + $controllerName = ClassLoader::getClassName(get_class($this)); + + // Determine ToplevelAgent + $toplevelAgentName = $this->response->getParam(0); + if(is_null($toplevelAgentName)) { + $toplevelAgentName = $this->request->getParam(0, 'toplevel'); + $this->response->addParam($toplevelAgentName); + } + + // Determine Action + $action = $this->response->getParam(2); + if(is_null($action)) { + $action = $this->request->getParam(2, 'action'); + $this->response->addParam($action); + } + + + // Load Controller + Controller::load($controllerName); + + // Construct Controller + $this->controller = Controller::factory($controllerName, $toplevelAgentName, $action, $this); + } + + + /** + * Log an error. + * + * @param Exception $exception Occurred exception + * @param int $logMode Log mode + */ + protected function log($exception, $logMode) + { + if(is_null($this->log)) { + return; + } + + $this->log->log( + $exception->getMessage(), + $logMode + ); + } + + + /** + * Load a SubAgent and add it. + * + * @throws ServiceUnavailableException + * @throws AgentNotFoundException + * @throws AgentNotValidException + * @param string $agentName Name of the Agent to load + * @param mixed … Additional parameters for the agent + */ + protected function addSubAgent($agentName) + { + try { + call_user_func_array( + array( + $this, + '_addSubAgent' + ), + func_get_args() + ); + } + catch(DatamodelException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + } + + + /** + * Load a SubAgent and add it. + * + * @throws ServiceUnavailableException + * @throws DatamodelException + * @throws AgentNotFoundException + * @throws AgentNotValidException + * @param string $agentName Name of the Agent to load + * @param mixed … Additional parameters for the agent + */ + protected function _addSubAgent($agentName) + { + try { + // Load Agent + BottomlevelAgent::load($agentName); + + // Construct Agent + $this->subAgents[] = call_user_func_array( + array( + $this, + 'newSubAgent' + ), + func_get_args() + ); + } + catch(ViewNotFoundException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(DriverNotValidException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(DriverNotFoundException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(ModelNotValidException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(ModelNotFoundException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(ControllerNotValidException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(ControllerNotFoundException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(AgentNotValidException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + catch(AgentNotFoundException $e) { + $this->subAgents[] = $this->newInlineError($agentName, $e); + } + } + + + + + /** + * Create a new SubAgent. + * + * @throws DatamodelException + * @param string $agentName Agent name + * @return array SubAgent + */ + private function newSubAgent($agentName) + { + // Response + $response = clone $this->response; + $response->clearParams(1); + $params = func_get_args(); + if(count($params) < 2 || empty($params[1])) { + $params[1] = \nre\configs\CoreConfig::$defaults['action']; + } + call_user_func_array( + array( + $response, + 'addParams' + ), + $params + ); + + return array( + 'name' => strtolower($agentName), + 'response' => $response, + 'object' => BottomlevelAgent::factory( + $agentName, + $this->request, + $response, + $this->log + ) + ); + } + + + /** + * Render a SubAgent. + * + * @param array $subAgent SubAgent to render + * @return string Generated output + */ + private function renderSubAgent(&$subAgent) + { + // Check for InlineError + if(array_key_exists('inlineerror', $subAgent) && !empty($subAgent['inlineerror'])) { + return file_get_contents($subAgent['inlineerror']); + } + + + // Rendern SubAgent and return its output + return $subAgent['object']->render(); + } + + + /** + * Handle the exception of a SubAgent. + * + * @param string $label Name of the original Agent + * @param Excepiton $exception Occurred exception + * @return array InlineError-SubAgent + */ + private function errorInline($subAgent, $request, $exception) + { + // Create the SubAgent for the exception + $subAgent = $this->newInlineError($subAgent['name'], $exception); + + + // Run the InlineError-SubAgent + try { + $subAgent['object']->run( + $request, + $subAgent['response'] + ); + } + catch(ActionNotFoundException $e) { + $this->log($e, Logger::LOGMODE_AUTO); + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + + + // Return the InlineError-SubAgent + return $subAgent; + } + + + /** + * Create a new InlineError. + * + * @param string $label Name of the original Agent + * @param Exception $exception Occurred exception + */ + private function newInlineError($label, $exception) + { + // Log error + $this->log($exception, Logger::LOGMODE_AUTO); + + // Determine Agent name + $agentName = self::INLINEERROR_AGENT; + + // Create SugAgent + $subAgent = array(); + + + try { + // Load Agenten + BottomlevelAgent::load($agentName); + + // Construct Agent + $subAgent = $this->newSubAgent($agentName); + $subAgent['label'] = $label; + $subAgent['response']->addParam($exception); + } + catch(ViewNotFoundException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(DatamodelException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(DriverNotValidException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(DriverNotFoundException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(ModelNotValidException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(ModelNotFoundException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(ControllerNotValidException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(ControllerNotFoundException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(AgentNotValidException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + catch(AgentNotFoundException $e) { + $subAgent['inlineerror'] = $this->newInlineErrorService(); + } + + + // Return SubAgent + return $subAgent; + } + + + /** + * Handle a hardcore error that could not be handled by the + * system. + */ + private function newInlineErrorService() + { + // Read and return static error file + return ROOT.DS.\nre\configs\CoreConfig::getClassDir('views').DS.\nre\configs\CoreConfig::$defaults['inlineErrorFile'].\nre\configs\Config::getFileExt('views'); + } + + } + +?> diff --git a/core/Api.inc b/core/Api.inc new file mode 100644 index 00000000..2623bba6 --- /dev/null +++ b/core/Api.inc @@ -0,0 +1,163 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class to implement an API. + * + * The API is the center of each application and specifies how and what + * to run and render. + * + * @author coderkun + */ + abstract class Api + { + /** + * Die aktuelle Anfrage + * + * @var Request + */ + protected $request; + /** + * Der Toplevelagent + * + * @var ToplevelAgent + */ + private $toplevelAgent = null; + /** + * Die aktuelle Antwort + * + * @var Response + */ + protected $response; + /** + * Log-System + * + * @var Logger + */ + private $log; + + + + + /** + * Construct a new API. + * + * @param Request $request Current request + * @param Response $respone Current response + */ + public function __construct(Request $request, Response $response) + { + // Store request + $this->request = $request; + + // Store response + $this->response = $response; + + // Init logging + $this->log = new \nre\core\Logger(); + } + + + + + /** + * Run the application. + * + * @throws DatamodelException + * @throws DriverNotValidException + * @throws DriverNotFoundException + * @throws ViewNotFoundException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ControllerNotValidException + * @throws ControllerNotFoundException + * @throws AgentNotValidException + * @throws AgentNotFoundException + * @return Exception Last occurred exception of an subagent + */ + public function run() + { + // Load ToplevelAgent + $this->loadToplevelAgent(); + + // Run ToplevelAgent + return $this->toplevelAgent->run($this->request, $this->response); + } + + + /** + * Render the output. + */ + public function render() + { + // Check exit-status + if($this->response->getExit()) { + return; + } + + // Render ToplevelAgent + $this->response->setOutput($this->toplevelAgent->render()); + } + + + + + /** + * Log an exception + * + * @param Exception $exception Occurred exception + * @param int $logMode Log-mode + */ + protected function log($exception, $logMode) + { + $this->log->log( + $exception->getMessage(), + $logMode + ); + } + + + + + /** + * Load the ToplevelAgent specified by the request. + * + * @throws ServiceUnavailableException + * @throws AgentNotValidException + * @throws AgentNotFoundException + */ + private function loadToplevelAgent() + { + // Determine agent + $agentName = $this->response->getParam(0); + if(is_null($agentName)) { + $agentName = $this->request->getParam(0, 'toplevel'); + $this->response->addParam($agentName); + } + + // Load agent + \nre\agents\ToplevelAgent::load($agentName); + + // Construct agent + $this->toplevelAgent = \nre\agents\ToplevelAgent::factory( + $agentName, + $this->request, + $this->response, + $this->log + ); + } + + } + +?> diff --git a/core/Autoloader.inc b/core/Autoloader.inc new file mode 100644 index 00000000..020b61f7 --- /dev/null +++ b/core/Autoloader.inc @@ -0,0 +1,98 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Autoloader. + * + * This class tries to load not yet used classes. + * + * @author coderkun + */ + class Autoloader + { + /** + * Private construct(). + */ + private function __construct() {} + + /** + * Private clone(). + */ + private function __clone() {} + + + + + /** + * Register load-method. + */ + public static function register() + { + spl_autoload_register( + array( + get_class(), + 'load' + ) + ); + } + + + /** + * Look for the given class and try to load it. + * + * @param string $fullClassName Die zu ladende Klasse + */ + public static function load($fullClassName) + { + $fullClassNameA = explode('\\', $fullClassName); + + if(strpos($fullClassName, \nre\configs\CoreConfig::$core['namespace']) !== 0) + { + // App + $className = array_slice($fullClassNameA, substr_count(\nre\configs\AppConfig::$app['namespace'], '\\')); + array_unshift($className, \nre\configs\CoreConfig::getClassDir('app')); + $filename = ROOT.DS.implode(DS, $className).\nre\configs\CoreConfig::getFileExt('includes'); + if(file_exists($filename)) { + require_once($filename); + } + } + else + { + // Core + $className = array_slice($fullClassNameA, substr_count(\nre\configs\CoreConfig::$core['namespace'], '\\')); + $filename = ROOT.DS.implode(DS, $className).\nre\configs\CoreConfig::getFileExt('includes'); + if(file_exists($filename)) { + require_once($filename); + } + } + + + } + + + /** + * Determine classtype of a class. + * + * @param string $className Name of the class to determine the classtype of + * @return string Classtype of the given class + */ + public static function getClassType($className) + { + // CamelCase + return strtolower(preg_replace('/^.*([A-Z][^A-Z]+)$/', '$1', $className)); + } + + } + +?> diff --git a/core/ClassLoader.inc b/core/ClassLoader.inc new file mode 100644 index 00000000..81cf537a --- /dev/null +++ b/core/ClassLoader.inc @@ -0,0 +1,129 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class for safely loading classes. + * + * @author coderkun + */ + class ClassLoader + { + + + + + /** + * Load a class. + * + * @throws ClassNotFoundException + * @param string $className Name of the class to load + */ + public static function load($fullClassName) + { + // Determine folder to look in + $className = explode('\\', $fullClassName); + $className = array_slice($className, substr_count(\nre\configs\AppConfig::$app['namespace'], '\\')); + + // Determine filename + $fileName = ROOT.DS.implode(DS, $className). \nre\configs\CoreConfig::getFileExt('includes'); + + + // Check file + if(!file_exists($fileName)) + { + throw new \nre\exceptions\ClassNotFoundException( + $fullClassName + ); + } + + // Include file + include_once($fileName); + } + + + /** + * Check inheritance of a class. + * + * @throws ClassNotValidException + * @param string $className Name of the class to check + * @param string $parentClassName Name of the parent class + */ + public static function check($className, $parentClassName) + { + // Check if class is subclass of parent class + if(!is_subclass_of($className, $parentClassName)) { + throw new \nre\exceptions\ClassNotValidException( + $className + ); + } + } + + + /** + * Strip the namespace from a class name. + * + * @param string $class Name of a class including its namespace + * @return Name of the given class without its namespace + */ + public static function stripNamespace($class) + { + return array_slice(explode('\\', $class), -1)[0]; + } + + + /** + * Strip the class type from a class name. + * + * @param string $className Name of a class + * @return Name of the given class without its class type + */ + public static function stripClassType($className) + { + return preg_replace('/^(.*)[A-Z][^A-Z]+$/', '$1', $className); + } + + + /** + * Strip the namespace and the class type of a full class name + * to get only its name. + * + * @param string $class Full name of a class + * @return Only the name of the given class + */ + public static function getClassName($class) + { + return self::stripClassType(self::stripNamespace($class)); + } + + + /** + * Concatenate strings to a class name following the CamelCase + * pattern. + * + * @param string $className1 Arbitrary number of strings to concat + * @return string Class name as CamelCase + */ + public static function concatClassNames($className1) + { + return implode('', array_map( + function($arg) { + return ucfirst(strtolower($arg)); + }, + func_get_args() + )); + } + + } + +?> diff --git a/core/Config.inc b/core/Config.inc new file mode 100644 index 00000000..b51f1e47 --- /dev/null +++ b/core/Config.inc @@ -0,0 +1,49 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Configuration. + * + * This class does not hold any configuration value but helps to + * determine values that can be hold by AppConfig or CoreConfig. + * + * @author coderkun + */ + final class Config + { + + + + + /** + * Get a default value. + * + * @param string $index Index of value to get + */ + public static function getDefault($index) + { + if(array_key_exists($index, \nre\configs\AppConfig::$defaults)) { + return \nre\configs\AppConfig::$defaults[$index]; + } + if(array_key_exists($index, \nre\configs\CoreConfig::$defaults)) { + return \nre\configs\CoreConfig::$defaults[$index]; + } + + + return null; + } + + } + +?> diff --git a/core/Controller.inc b/core/Controller.inc new file mode 100644 index 00000000..2c2309c4 --- /dev/null +++ b/core/Controller.inc @@ -0,0 +1,381 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Controller. + * + * @author coderkun + */ + abstract class Controller + { + /** + * Corresponding Agent + * + * @var Agent + */ + protected $agent; + /** + * View of the Controller + * + * @var View + */ + private $view = null; + /** + * Data to pass to the View + * + * @var array + */ + protected $viewData = array(); + /** + * Current request + * + * @var Request + */ + protected $request = null; + /** + * Current response + * + * @var Response + */ + protected $response = null; + + + + + /** + * Load the class of a Controller. + * + * @throws ControllerNotFoundException + * @throws ControllerNotValidException + * @param string $controllerName Name of the Controller to load + */ + public static function load($controllerName) + { + // Determine full classname + $className = self::getClassName($controllerName); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + ClassLoader::check($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\ControllerNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\ControllerNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Controller (Factory Pattern). + * + * @throws DatamodelException + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ViewNotFoundException + * @param string $controllerName Name of the Controller to instantiate + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + */ + public static function factory($controllerName, $layoutName, $action, $agent) + { + // Determine full classname + $className = self::getClassName($controllerName); + + // Construct and return Controller + return new $className($layoutName, $action, $agent); + } + + + /** + * Determine the classname for the given Controller name. + * + * @param string $controllerName Controller name to get classname of + * @return string Classname for the Controller name + */ + private static function getClassName($controllerName) + { + $className = \nre\core\ClassLoader::concatClassNames($controllerName, \nre\core\ClassLoader::stripNamespace(get_class())); + + + return \nre\configs\AppConfig::$app['namespace']."controllers\\$className"; + } + + + + + /** + * Construct a new Controller. + * + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws ModelNotValidException + * @throws ModelNotFoundException + * @throws ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param Agent $agent Corresponding Agent + */ + protected function __construct($layoutName, $action, $agent) + { + // Store values + $this->agent = $agent; + + // Load Models + $this->loadModels(); + + // Load View + $this->loadView($layoutName, $action); + } + + + + + /** + * Prefilter that is executed before running the Controller. + * + * @param Request $request Current request + * @param Response $response Current response + */ + public function preFilter(Request $request, Response $response) + { + // Request speichern + $this->request = $request; + + // Response speichern + $this->response = $response; + + + // Linker erstellen + $this->set('linker', new \nre\core\Linker($request)); + + } + + + /** + * Prefilter that is executed after running the Controller. + * + * @param Request $request Current request + * @param Response $response Current response + */ + public function postFilter(Request $request, Response $response) + { + } + + + /** + * Run the Controller. + * + * This method executes the Action of the Controller defined by + * the current Request. + * + * @throws ParamsNotValidException + * @throws IdNotFoundException + * @throws DatamodelException + * @throws ActionNotFoundException + * @param Request $request Current request + * @param Response $response Current response + */ + public function run(Request $request, Response $response) + { + // Determine Action + $action = $response->getParam(2, 'action'); + if(!method_exists($this, $action)) { + throw new \nre\exceptions\ActionNotFoundException($action); + } + + // Determine parameters + $params = $response->getParams(3); + if(empty($params)) { + $params = $request->getParams(3); + } + + // Fill missing parameters + $rc = new \ReflectionClass($this); + $nullParamsCount = $rc->getMethod($action)->getNumberOfParameters() - count($params); + $nullParams = ($nullParamsCount > 0 ? array_fill(0, $nullParamsCount, NULL) : array()); + + + // Call Action + call_user_func_array( + array( + $this, + $action + ), + array_merge( + $params, + $nullParams + ) + ); + } + + + /** + * Generate the output. + * + * @param array $viewData Data to pass to the View + * @return string Generated output + */ + public function render($viewData=null) + { + // Combine given data and data of this Controller + $data = $this->viewData; + if(!is_null($viewData)) { + $data = array_merge($viewData, $data); + } + + // Rendern and return output + return $this->view->render($data); + } + + + + + /** + * Set data for the View. + * + * @param string $name Key + * @param mixed $data Value + */ + protected function set($name, $data) + { + $this->viewData[$name] = $data; + } + + + /** + * Redirect to the given URL. + * + * @param string $url Relative URL + */ + protected function redirect($url) + { + $url = 'http://'.$_SERVER['HTTP_HOST'].$url; + header('Location: '.$url); + exit; + } + + + /** + * Check if Models of this Controller are loaded and available. + * + * @param string $modelName Arbitrary number of Models to check + * @return bool All given Models are loaded and available + */ + protected function checkModels($modelName) + { + foreach(func_get_args() as $modelName) + { + if(!isset($this->$modelName) || !is_subclass_of($this->$modelName, 'Model')) { + return false; + } + } + + + return true; + } + + + /** + * Get the View of the Controller + * + * @return View View of the Controller + */ + protected function getView() + { + return $this->view; + } + + + + + /** + * Load the Models of this Controller. + * + * @throws DatamodelException + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws ModelNotValidException + * @throws ModelNotFoundException + */ + private function loadModels() + { + // Determine Models + $explicit = false; + $models = \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripNamespace(get_class($this))); + if(property_exists($this, 'models')) + { + $models = $this->models; + $explicit = true; + } + if(!is_array($models)) { + $models = array($models); + } + + // Load Models + foreach($models as &$model) + { + try { + // Load class + Model::load($model); + + // Construct Model + $this->$model = Model::factory($model); + } + catch(\nre\exceptions\ModelNotValidException $e) { + if($explicit) { + throw $e; + } + } + catch(\nre\exceptions\ModelNotFoundException $e) { + if($explicit) { + throw $e; + } + } + } + } + + + /** + * Load the View of this Controller. + * + * @throws ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + */ + private function loadView($layoutName, $action) + { + // Check Layout name + if(is_null($layoutName)) { + return; + } + + // Determine controller name + $controllerName = \nre\core\ClassLoader::getClassName(get_class($this)); + + + // Load view + $isToplevel = is_subclass_of($this->agent, '\nre\agents\ToplevelAgent'); + $this->view = View::loadAndFactory($layoutName, $controllerName, $action, $isToplevel); + } + + } + +?> diff --git a/core/Driver.inc b/core/Driver.inc new file mode 100644 index 00000000..aa3096a6 --- /dev/null +++ b/core/Driver.inc @@ -0,0 +1,96 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Driver. + * + * @author coderkun + */ + abstract class Driver + { + + + + + /** + * Load the class of a Driver. + * + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @param string $driverName Name of the Driver to load + */ + public static function load($driverName) + { + // Determine full classname + $className = self::getClassName($driverName); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + ClassLoader::check($className, get_class()); + } + catch(ClassNotValidException $e) { + throw new DriverNotValidException($e->getClassName()); + } + catch(ClassNotFoundException $e) { + throw new DriverNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Driver (Factory Pattern). + * + * @param string $driverName Name of the Driver to instantiate + */ + public static function factory($driverName, $config) + { + // Determine full classname + $className = self::getClassName($driverName); + + + // Construct and return Driver + return new $className($config); + } + + + /** + * Determine the classname for the given Driver name. + * + * @param string $driverName Driver name to get classname of + * @return string Classname fore the Driver name + */ + private static function getClassName($driverName) + { + $className = \nre\core\ClassLoader::concatClassNames($driverName, \nre\core\ClassLoader::stripNamespace(get_class())); + + + return "\\nre\\drivers\\$className"; + } + + + + + /** + * Construct a new Driver. + */ + protected function __construct() + { + } + + } + +?> diff --git a/core/Exception.inc b/core/Exception.inc new file mode 100644 index 00000000..a17a700f --- /dev/null +++ b/core/Exception.inc @@ -0,0 +1,65 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Exception class. + * + * @author coderkun + */ + class Exception extends \Exception + { + + + + + /** + * Construct a new exception. + * + * @param string $message Error message + * @param int $code Error code + * @param string $name Name to insert + */ + function __construct($message, $code, $name=null) + { + parent::__construct( + $this->concat( + $message, + $name + ), + $code + ); + } + + + + + /** + * Insert the name in a message + * + * @param string $message Error message + * @param string $name Name to insert + */ + private function concat($message, $name) + { + if(is_null($name)) { + return $message; + } + + + return "$message: $name"; + } + + } + +?> diff --git a/core/Linker.inc b/core/Linker.inc new file mode 100644 index 00000000..61dd5fa8 --- /dev/null +++ b/core/Linker.inc @@ -0,0 +1,322 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class to create web links based on the current request. + * + * @author coderkun + */ + class Linker + { + /** + * Current request + * + * @var Request + */ + private $request; + + + + + /** + * Construct a new linker. + * + * @param Request $request Current request + */ + function __construct(\nre\requests\WebRequest $request) + { + $this->request = $request; + } + + + + + /** + * Process a title and optional a date to create link parameters. + * + * @param string $title Titel + * @param string $date Date + * @return string Created link parameters + */ + public static function getLinkParams($title, $date=null) + { + // Parameters + $param = ''; + + // Mask special sign seperately + $specials = array('/', '?', '&'); + foreach($specials as &$special) { + $title = str_replace($special, rawurlencode(rawurlencode($special)), $title); + } + + // Process title + $param .= str_replace( + ' ', + '-', + substr( + $title, + 0, + \nre\configs\CoreConfig::$classes['linker']['url']['length'] + ) + ); + + // Process date + if(!empty($date)) { + $param = substr($date, 0, 10).\nre\configs\CoreConfig::$classes['linker']['url']['delimiter'].$param; + } + + + // Mask and return parameters + return array(rawurlencode($param)); + } + + + /** + * Extract date and title from a parameter string. + * + * @param string $dateTitle Parameter string with date and title + * @return array Extracted date and title as associative array + */ + public static function extractDateTitle($dateTitle) + { + // Get delimiter + $delimiter = \nre\configs\CoreConfig::$classes[strtolower(get_class())]['url']['delimiter']; + + // Split + $dateTitle = explode($delimiter, $dateTitle); + if(count($dateTitle) < 4) { + throw new IdNotFoundException(implode($delimiter, $dateTitle)); + } + + // Get parts + $date = urldecode(implode($delimiter, array_slice($dateTitle, 0, 3))); + $title = urldecode(implode($delimiter, array_slice($dateTitle, 3))); + + + // Return date and title + return array( + 'date' => $date, + 'title' => $title + ); + } + + + + + /** + * Create a web link. + * + * @param array $params Parameters to use + * @param int $offset Ignore first parameters + * @param bool $exclusiveParams Use only the given parameters + * @param array $getParams GET-parameter to use + * @param bool $exclusiveGetParams Use only the given GET-parameters + * @param string $anchor Target anchor + * @param bool $absolute Include hostname etc. for an absolute URL + * @return string Created link + */ + public function link($params=null, $offset=0, $exclusiveParams=true, $getParams=null, $exclusiveGetParams=true, $anchor=null, $absolute=false) + { + // Make current request to response + $response = new \nre\responses\WebResponse(); + + + // Check parameters + if(is_null($params)) { + $params = array(); + } + elseif(!is_array($params)) { + $params = array($params); + } + + // Set parameters from request + $reqParams = array_slice($this->request->getParams(), 1, $offset); + if(count($reqParams) < $offset && $offset > 0) { + $reqParams[] = $this->request->getParam(1, 'intermediate'); + } + if(count($reqParams) < $offset && $offset > 1) { + $reqParams[] = $this->request->getParam(2, 'action'); + } + $params = array_map('rawurlencode', $params); + $params = array_merge($reqParams, $params); + + // Use Layout + $layout = \nre\configs\AppConfig::$defaults['toplevel']; + if(!empty($getParams) && array_key_exists('layout', $getParams)) { + $layout = $getParams['layout']; + } + array_unshift($params, $layout); + + // Use parameters from request only + if(!$exclusiveParams) + { + $params = array_merge( + $params, + array_slice( + $this->request->getParams(), + count($params) + ) + ); + } + + // Set parameters + call_user_func_array( + array( + $response, + 'addParams' + ), + $params + ); + + + // Check GET-parameters + if(is_null($getParams)) { + $getParams = array(); + } + elseif(!is_array($params)) { + $params = array($params); + } + if(!$exclusiveGetParams) + { + $getParams = array_merge( + $this->request->getGetParams(), + $getParams + ); + } + + // Set GET-parameters + $response->addGetParams($getParams); + + + // Create and return link + return self::createLink($this->request, $response, $anchor, $absolute); + } + + + /** + * Create a link from an URL. + * + * @param string $url URL to create link from + * @param bool $absolute Create absolute URL + * @return string Created link + */ + public function hardlink($url, $absolute=false) + { + return $this->createUrl($url, $this->request, $absolute); + } + + + + + /** + * Create a link. + * + * @param Request $request Current request + * @param Response $response Current response + * @param bool $absolute Create absolute link + * @param string $anchor Anchor on target + * @return string Created link + */ + private static function createLink(Request $request, Response $response, $anchor=null, $absolute=false) + { + // Check response + if(is_null($response)) { + return null; + } + + + // Get parameters + $params = $response->getParams(1); + + // Check Action + if(count($params) == 2 && $params[1] == \nre\configs\CoreConfig::$defaults['action']) { + array_pop($params); + } + + // Set parameters + $link = implode('/', $params); + + // Apply reverse-routes + $link = $request->applyReverseRoutes($link); + + + // Get GET-parameters + $getParams = $response->getGetParams(); + + // Layout überprüfen + if(array_key_exists('layout', $getParams) && $getParams['layout'] == \nre\configs\AppConfig::$defaults['toplevel']) { + unset($getParams['layout']); + } + + // Set GET-parameters + if(array_key_exists('url', $getParams)) { + unset($getParams['url']); + } + if(count($getParams) > 0) { + $link .= '?'.http_build_query($getParams); + } + + // Add anchor + if(!is_null($anchor)) { + $link .= "#$anchor"; + } + + + // Create URL + $url = self::createUrl($link, $request, $absolute); + + + return $url; + } + + + /** + * Adapt a link to the environment. + * + * @param string $url URL + * @param Request $request Current request + * @param bool $absolute Create absolute URL + * @return string Adapted URL + */ + private static function createUrl($url, Request $request, $absolute=false) + { + // Variables + $server = $_SERVER['SERVER_NAME']; + $uri = $_SERVER['REQUEST_URI']; + $prefix = ''; + + + // Determine prefix + $ppos = array(strlen($uri)); + if(($p = strpos($uri, '/'.$request->getParam(1, \nre\configs\AppConfig::$defaults['intermediate']))) !== false) { + $ppos[] = $p; + } + $prefix = substr($uri, 0, min($ppos)); + + // Create absolute URL + if($absolute) { + $prefix = "http://$server/".trim($prefix, '/'); + } + + // Put URL together + $url = rtrim($prefix, '/').'/'.ltrim($url, '/'); + + + // Return URL + return $url; + } + + } + +?> diff --git a/core/Logger.inc b/core/Logger.inc new file mode 100644 index 00000000..c96dff0a --- /dev/null +++ b/core/Logger.inc @@ -0,0 +1,116 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class to log messages to different targets. + * + * @author coderkun + */ + class Logger + { + /** + * Log mode: Detect automatic + * + * @var int + */ + const LOGMODE_AUTO = 0; + /** + * Log mode: Print to screen + * + * @var int + */ + const LOGMODE_SCREEN = 1; + /** + * Log mode: Use PHP-logging mechanism + * + * @var int + */ + const LOGMODE_PHP = 2; + + + + + /** + * Construct a new logger. + */ + public function __construct() + { + } + + + + + /** + * Log a message. + * + * @param string $message Message to log + * @param int $logMode Log mode to use + */ + public function log($message, $logMode=self::LOGMODE_SCREEN) + { + // Choose log mode automatically + if($logMode == self::LOGMODE_AUTO) { + $logMode = $this->getAutoLogMode(); + } + + // Print message to screen + if($logMode & self::LOGMODE_SCREEN) { + $this->logToScreen($message); + } + + // Use PHP-logging mechanism + if($logMode & self::LOGMODE_PHP) { + $this->logToPhp($message); + } + } + + + + + /** + * Print a message to screen. + * + * @param string $message Message to print + */ + private function logToScreen($message) + { + echo "$message
\n"; + } + + + /** + * Log a message by using PHP-logging mechanism. + * + * @param string $message Message to log + */ + private function logToPhp($message) + { + error_log($message, 0); + } + + + /** + * Detect log mode automatically by distinguishing between + * production and test environment. + * + * @return int Automatically detected log mode + */ + private function getAutoLogMode() + { + return ($_SERVER['SERVER_ADDR'] == '127.0.0.1') ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; + } + + } + +?> diff --git a/core/Model.inc b/core/Model.inc new file mode 100644 index 00000000..2906c404 --- /dev/null +++ b/core/Model.inc @@ -0,0 +1,140 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Model. + * + * @author coderkun + */ + abstract class Model + { + + + + + /** + * Load the class of a Model. + * + * @throws ModelNotFoundException + * @throws ModelNotValidException + * @param string $modelName Name of the Model to load + */ + public static function load($modelName) + { + // Determine full classname + $className = self::getClassName($modelName); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + ClassLoader::check($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\ModelNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\ModelNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Model (Factory Pattern). + * + * @param string $modelName Name of the Model to instantiate + */ + public static function factory($modelName) + { + // Determine full classname + $className = self::getClassName($modelName); + + // Construct and return Model + return new $className(); + } + + + /** + * Determine the classname for the given Model name. + * + * @param string $modelName Model name to get classname of + * @return string Classname fore the Model name + */ + private static function getClassName($modelName) + { + $className = \nre\core\ClassLoader::concatClassNames($modelName, \nre\core\ClassLoader::stripNamespace(get_class())); + + + return \nre\configs\AppConfig::$app['namespace']."models\\$className"; + } + + + + + /** + * Construct a new Model. + * + * TODO Catch exception + * + * @throws DatamodelException + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws ModelNotValidException + * @throws ModelNotFoundException + */ + protected function __construct() + { + // Load Models + $this->loadModels(); + } + + + + + /** + * Load the Models of this Model. + * + * @throws DatamodelException + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws ModelNotValidException + * @throws ModelNotFoundException + */ + private function loadModels() + { + // Determine Models + $models = array(); + if(property_exists($this, 'models')) { + $models = $this->models; + } + if(!is_array($models)) { + $models = array($models); + } + + + // Load Models + foreach($models as $model) + { + // Load class + Model::load($model); + + // Construct Model + $this->$model = Model::factory($model); + } + } + + } + +?> diff --git a/core/Request.inc b/core/Request.inc new file mode 100644 index 00000000..5fda187e --- /dev/null +++ b/core/Request.inc @@ -0,0 +1,64 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Base class to represent a request. + * + * @author coderkun + */ + class Request + { + /** + * Passed parameters + * + * @var array + */ + protected $params = array(); + + + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + // Return parameter + if(count($this->params) > $index) { + return $this->params[$index]; + } + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameter values + */ + public function getParams($offset=0) + { + return array_slice($this->params, $offset); + } + + } + +?> diff --git a/core/Response.inc b/core/Response.inc new file mode 100644 index 00000000..4781b2ab --- /dev/null +++ b/core/Response.inc @@ -0,0 +1,158 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Base class to represent a response. + * + * @author coderkun + */ + class Response + { + /** + * Applied parameters + * + * @var array + */ + protected $params = array(); + /** + * Generated output + * + * @var string + */ + private $output = ''; + /** + * Abort futher execution + * + * @var bool + */ + private $exit = false; + + + + + /** + * Add a parameter. + * + * @param mixed $value Value of parameter + */ + public function addParam($value) + { + $this->params[] = $value; + } + + + /** + * Add multiple parameters. + * + * @param mixed $value1 Value of first parameter + * @param mixed … Values of further parameters + */ + public function addParams($value1) + { + $this->params = array_merge( + $this->params, + func_get_args() + ); + } + + + /** + * Delete all stored parameters (from offset on). + * + * @param int $offset Offset-index + */ + public function clearParams($offset=0) + { + $this->params = array_slice($this->params, 0, $offset); + } + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + // Return parameter + if(count($this->params) > $index) { + return $this->params[$index]; + } + + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameter values + */ + public function getParams($offset=0) + { + return array_slice($this->params, $offset); + } + + + /** + * Set output. + * + * @param string $output Generated output + */ + public function setOutput($output) + { + $this->output = $output; + } + + + /** + * Get generated output. + * + * @return string Generated output + */ + public function getOutput() + { + return $this->output; + } + + + /** + * Set exit-state. + * + * @param bool $exit Abort further execution + */ + public function setExit($exit=true) + { + $this->exit = $exit; + } + + + /** + * Get exit-state. + * + * @return bool Abort further execution + */ + public function getExit() + { + return $this->exit; + } + + } + +?> diff --git a/core/View.inc b/core/View.inc new file mode 100644 index 00000000..513bd953 --- /dev/null +++ b/core/View.inc @@ -0,0 +1,124 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * View. + * + * Class to encapsulate a template file and to provide rendering methods. + * + * @author coderkun + */ + class View + { + /** + * Template filename + * + * @var string + */ + private $templateFilename; + + + + + /** + * Load and instantiate the View of an Agent. + * + * @throws ViewNotFoundException + * @param string $layoutName Name of Layout in use + * @param string $agentName Name of the Agent + * @param string $action Current Action + * @param bool $isToplevel Agent is a ToplevelAgent + */ + public static function loadAndFactory($layoutName, $agentName=null, $action=null, $isToplevel=false) + { + return new View($layoutName, $agentName, $action, $isToplevel); + } + + + + + /** + * Construct a new View. + * + * @throws ViewNotFoundException + * @param string $layoutName Name of Layout in use + * @param string $agentName Name of the Agent + * @param string $action Current Action + * @param bool $isToplevel Agent is a ToplevelAgent + */ + private function __construct($layoutName, $agentName=null, $action=null, $isToplevel=false) + { + // Create template filename + // LayoutName + $fileName = ROOT.DS. \nre\configs\CoreConfig::getClassDir('views').DS. strtolower($layoutName).DS; + // AgentName and Action + if(strtolower($agentName) != $layoutName || !$isToplevel) { + $fileName .= strtolower($agentName).DS.strtolower($action); + } + else { + $fileName .= strtolower($layoutName); + } + // File extension + $fileName .= \nre\configs\CoreConfig::getFileExt('views'); + + + // Check template file + if(!file_exists($fileName)) { + throw new \nre\exceptions\ViewNotFoundException($fileName); + } + + // Save filename + $this->templateFilename = $fileName; + } + + + + + /** + * Generate output + * + * @param array $data Data to have available in the template file + */ + public function render($data) + { + // Extract data + if(!is_null($data)) { + extract($data, EXTR_SKIP); + } + + // Buffer output + ob_start(); + + // Include template + include($this->templateFilename); + + + // Return buffered output + return ob_get_clean(); + } + + + /** + * Get template filename. + * + * @return string Template filename + */ + public function getTemplateFilename() + { + return $this->templateFilename; + } + + } + +?> diff --git a/core/WebUtils.inc b/core/WebUtils.inc new file mode 100644 index 00000000..778d12b1 --- /dev/null +++ b/core/WebUtils.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class that holds several web-specific methods and properties. + * + * @author coderkun + */ + class WebUtils + { + /** + * HTTP-statuscode 404: Not Found + * + * @var int + */ + const HTTP_NOT_FOUND = 404; + /** + * HTTP-statuscode 503: Service Unavailable + * + * @var int + */ + const HTTP_SERVICE_UNAVAILABLE = 503; + + /** + * HTTP-header strings + * + * @var array + */ + public static $httpStrings = array( + 200 => 'OK', + 304 => 'Not Modified', + 404 => 'Not Found', + 503 => 'Service Unavailable' + ); + + + + + /** + * Get the HTTP-header of a HTTP-statuscode + * + * @param int $httpStatusCode HTTP-statuscode + * @return string HTTP-header of HTTP-statuscode + */ + public static function getHttpHeader($httpStatusCode) + { + if(!array_key_exists($httpStatusCode, self::$httpStrings)) { + $httpStatusCode = 200; + } + + + return sprintf("HTTP/1.1 %d %s\n", $httpStatusCode, self::$httpStrings[$httpStatusCode]); + } + + } + +?> diff --git a/drivers/DatabaseDriver.inc b/drivers/DatabaseDriver.inc new file mode 100644 index 00000000..c69d6add --- /dev/null +++ b/drivers/DatabaseDriver.inc @@ -0,0 +1,81 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\drivers; + + + /** + * Abstract class for implementing a database driver. + * + * @author coderkun + */ + abstract class DatabaseDriver extends \nre\core\Driver + { + /** + * Connection and login settings + * + * @var array + */ + protected $config; + /** + * Connection resource + * + * @var resource + */ + protected $connection = null; + + + + + /** + * Execute a SQL-query. + * + * @param string $query Query to run + * @return array Result + */ + public abstract function query($query); + + + /** + * Return the last insert id (of the last insert-query). + * + * @return int Last insert id + */ + public abstract function getInsertId(); + + + /** + * Mask an input for using it in a SQL-query. + * + * @param mixed $input Input to mask + * @return mixed Masked input + */ + public abstract function mask($input); + + + + + /** + * Construct a new database driver. + * + * @param array $config Connection and login settings + */ + protected function __construct($config) + { + parent::__construct(); + + // Save values + $this->config = $config; + } + + } + +?> diff --git a/drivers/MysqlDriver.inc b/drivers/MysqlDriver.inc new file mode 100644 index 00000000..11122b38 --- /dev/null +++ b/drivers/MysqlDriver.inc @@ -0,0 +1,153 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\drivers; + + + /** + * Implementation of a database driver for MySQL-databases. + * + * @author coderkun + */ + class MysqlDriver extends \nre\drivers\DatabaseDriver + { + + + + + /** + * Construct a MySQL-driver. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + function __construct($config) + { + parent::__construct($config); + + // Connect + $this->connect(); + } + + + + + /** + * Execute a SQL-query. + * + * @param string $query Query to run + * @return array Result + */ + public function query($query) + { + // Return-array + $data = array(); + + + // Execute query + $result = mysql_query($query, $this->connection); + + // Check result + if(($errno = mysql_errno($this->connection)) > 0) { + throw new DatamodelException(mysql_error($this->connection), $errno); + } + + // Process result + if(is_resource($result)) + { + while($row = mysql_fetch_array($result, MYSQL_ASSOC)) { + $data[] = $row; + } + } + + + // Return data + return $data; + } + + + /** + * Return the last insert id (of the last insert-query). + * + * @return int Last insert id + */ + public function getInsertId() + { + return mysql_insert_id($this->connection); + } + + + /** + * Mask an input for using it in a SQL-query. + * + * @param mixed $input Input to mask + * @return mixed Masked input + */ + public function mask($input) + { + return mysql_real_escape_string($input, $this->connection); + } + + + + + /** + * Establish a connect to a MqSQL-database. + * + * @throws DatamodelException + */ + private function connect() + { + // Connect + $con = @mysql_connect( + $this->config['host'], + $this->config['user'], + $this->config['password'] + ); + + // Check connection + if($con === false) { + throw new \nre\exceptions\DatamodelException(mysql_error(), mysql_errno()); + } + + // Save connection + $this->connection = $con; + + + // Select database + $db = mysql_select_db( + $this->config['db'], + $this->connection + ); + + // Check database selection + if(!$db) { + throw new DatamodelException(mysql_error(), mysql_errno()); + } + + + // Configure connection + $this->configConnection(); + } + + + /** + * Configure the current connection + */ + private function configConnection() + { + // Set character encoding + $this->query("SET NAMES 'utf8'", $this->connection); + } + + } + +?> diff --git a/exceptions/ActionNotFoundException.inc b/exceptions/ActionNotFoundException.inc new file mode 100644 index 00000000..418dd49c --- /dev/null +++ b/exceptions/ActionNotFoundException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Action not found. + * + * @author coderkun + */ + class ActionNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 70; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'action not found'; + + /** + * Name of the action that was not found + * + * @var string + */ + private $action; + + + + + /** + * Construct a new exception. + * + * @param string $action Name of the action that was not found + */ + function __construct($action) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $action + ); + + // Store values + $this->action = $action; + } + + + + + /** + * Get the name of the action that was not found. + * + * @return string Name of the action that was not found + */ + public function getAction() + { + return $this->action; + } + + } + +?> diff --git a/exceptions/AgentNotFoundException.inc b/exceptions/AgentNotFoundException.inc new file mode 100644 index 00000000..f0b3a2a7 --- /dev/null +++ b/exceptions/AgentNotFoundException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Agent not found. + * + * @author coderkun + */ + class AgentNotFoundException extends \nre\exceptions\ClassNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 66; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'agent not found'; + + + + + /** + * Construct a new exception. + * + * @param string $agentName Name of the Agent that was not found + */ + function __construct($agentName) + { + parent::__construct( + $agentName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the Agent that was not found. + * + * @return string Name of the Agent that was not found + */ + public function getAgentName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/AgentNotValidException.inc b/exceptions/AgentNotValidException.inc new file mode 100644 index 00000000..1c752051 --- /dev/null +++ b/exceptions/AgentNotValidException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Agent not valid. + * + * @author coderkun + */ + class AgentNotValidException extends \nre\exceptions\ClassNotValidException + { + /** + * Error code + * + * @var int + */ + const CODE = 76; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'agent not valid'; + + + + + /** + * Construct a new exception. + * + * @param string $agentName Name of the invalid Agent + */ + function __construct($agentName) + { + parent::__construct( + $agentName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid Agent. + * + * @return string Name of the invalid Agent + */ + public function getAgentName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/ClassNotFoundException.inc b/exceptions/ClassNotFoundException.inc new file mode 100644 index 00000000..070f383f --- /dev/null +++ b/exceptions/ClassNotFoundException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Class not found. + * + * @author coderkun + */ + class ClassNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 64; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'class not found'; + + /** + * Name of the class that was not found + * + * @var string + */ + private $className; + + + + + /** + * Construct a new exception + * + * @param string $className Name of the class that was not found + */ + function __construct($className, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $className + ); + + // Store values + $this->className = $className; + } + + + + + /** + * Get the name of the class that was not found. + * + * @return string Name of the class that was not found + */ + public function getClassName() + { + return $this->className; + } + + } + +?> diff --git a/exceptions/ClassNotValidException.inc b/exceptions/ClassNotValidException.inc new file mode 100644 index 00000000..bdd36d5e --- /dev/null +++ b/exceptions/ClassNotValidException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Class not valid. + * + * @author coderkun + */ + class ClassNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 74; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'class not valid'; + + /** + * Name of the invalid class + * + * @var string + */ + private $className; + + + + + /** + * Construct a new exception. + * + * @param string $className Name of the invalid class + */ + function __construct($className, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $className + ); + + // Store value + $this->className = $className; + } + + + + + /** + * Get the name of the invalid class. + * + * @return string Name of the invalid class + */ + public function getClassName() + { + return $this->className; + } + + } + +?> diff --git a/exceptions/ControllerNotFoundException.inc b/exceptions/ControllerNotFoundException.inc new file mode 100644 index 00000000..56c4a3fd --- /dev/null +++ b/exceptions/ControllerNotFoundException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Controller not found. + * + * @author coderkun + */ + class ControllerNotFoundException extends \nre\exceptions\ClassNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 67; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'controller not found'; + + + + + /** + * Construct a new exception. + * + * @param string $controllerName Name of the Controller that was not found + */ + function __construct($controllerName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $controllerName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the Controller that was not found. + * + * @return string Name of the Controller that was not found + */ + public function getControllerName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/ControllerNotValidException.inc b/exceptions/ControllerNotValidException.inc new file mode 100644 index 00000000..e309469d --- /dev/null +++ b/exceptions/ControllerNotValidException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Controller not valid. + * + * @author coderkun + */ + class ControllerNotValidException extends \nre\exceptions\ClassNotValidException + { + /** + * Error code + * + * @var int + */ + const CODE = 77; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'controller not valid'; + + + + + /** + * Construct a new exception. + * + * @param string $controllerName Name of the invalid Controller + */ + function __construct($controllerName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $controllerName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid Controller. + * + * @return string Name of the invalid Controller + */ + public function getControllerName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/DatamodelException.inc b/exceptions/DatamodelException.inc new file mode 100644 index 00000000..7785cd21 --- /dev/null +++ b/exceptions/DatamodelException.inc @@ -0,0 +1,99 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Datamodel. + * + * This exception is thrown when an error occurred during the execution + * of a datamodel. + * + * @author coderkun + */ + class DatamodelException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 84; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'datamodel error'; + + /** + * Error message of datamodel + * + * @var string + */ + private $datamodelMessage; + /** + * Error code of datamodel + * + * @var int + */ + private $datamodelErrorNumber; + + + + + /** + * Consturct a new exception. + * + * @param string $datamodelMessage Error message of datamodel + * @param int $datamodelErrorNumber Error code of datamodel + */ + function __construct($datamodelMessage, $datamodelErrorNumber) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $datamodelMessage." ($datamodelErrorNumber)" + ); + + // Store values + $this->datamodelMessage = $datamodelMessage; + $this->datamodelErrorNumber = $datamodelErrorNumber; + } + + + + + /** + * Get the error message of datamodel. + * + * @return string Error message of datamodel + */ + public function getDatamodelMessage() + { + return $this->datamodelMessage; + } + + + /** + * Get the error code of datamodel. + * + * @return string Error code of datamodel + */ + public function getDatamodelErrorNumber() + { + return $this->datamodelErrorNumber; + } + + } + +?> diff --git a/exceptions/DriverNotFoundException.inc b/exceptions/DriverNotFoundException.inc new file mode 100644 index 00000000..9b218f29 --- /dev/null +++ b/exceptions/DriverNotFoundException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Driver not found. + * + * @author coderkun + */ + class DriverNotFoundException extends \nre\exceptions\ClassNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 71; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'driver not found'; + + + + + /** + * Construct a new exception. + * + * @param string $driverName Name of the driver that was not found + */ + function __construct($driverName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $driverName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the driver that was not found. + * + * @return string Name of the driver that was not found + */ + public function getDriverName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/DriverNotValidException.inc b/exceptions/DriverNotValidException.inc new file mode 100644 index 00000000..fa9022e8 --- /dev/null +++ b/exceptions/DriverNotValidException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Driver not valid. + * + * @author coderkun + */ + class DriverNotValidException extends \nre\exceptions\ClassNotValidException + { + /** + * Error code + * + * @var int + */ + const CODE = 81; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'driver not valid'; + + + + + /** + * Konstruktor. + * + * @param string $driverName Name of the invalid driver + */ + function __construct($driverName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $driverName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid driver. + * + * @return string Name of the invalid driver + */ + public function getDriverName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/FatalDatamodelException.inc b/exceptions/FatalDatamodelException.inc new file mode 100644 index 00000000..afd80b86 --- /dev/null +++ b/exceptions/FatalDatamodelException.inc @@ -0,0 +1,96 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Datamodel exception that is fatal for the application. + * + * @author coderkun + */ + class FatalDatamodelException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 85; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'fatal datamodel error'; + + /** + * Error message of datamodel + * + * @var string + */ + private $datamodelMessage; + /** + * Error code of datamodel + * + * @var int + */ + private $datamodelErrorNumber; + + + + + /** + * Consturct a new exception. + * + * @param string $datamodelMessage Error message of datamodel + * @param int $datamodelErrorNumber Error code of datamodel + */ + function __construct($datamodelMessage, $datamodelErrorNumber) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $datamodelMessage." ($datamodelErrorNumber)" + ); + + // Store values + $this->datamodelMessage = $datamodelMessage; + $this->datamodelErrorNumber = $datamodelErrorNumber; + } + + + + + /** + * Get the error message of datamodel. + * + * @return string Error message of datamodel + */ + public function getDatamodelMessage() + { + return $this->datamodelMessage; + } + + + /** + * Get the error code of datamodel. + * + * @return string Error code of datamodel + */ + public function getDatamodelErrorNumber() + { + return $this->datamodelErrorNumber; + } + + } + +?> diff --git a/exceptions/LayoutNotFoundException.inc b/exceptions/LayoutNotFoundException.inc new file mode 100644 index 00000000..0eb8c89c --- /dev/null +++ b/exceptions/LayoutNotFoundException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Layout not found. + * + * @author coderkun + */ + class LayoutNotFoundException extends \nre\exceptions\AgentNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 65; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'layout not found'; + + + + + /** + * Construct a new exception. + * + * @param string $layoutName Name of the Layout that was not found + */ + function __construct($layoutName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $layoutName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the Layout that was not found. + * + * @return string Name of the Layout that was not found + */ + public function getLayoutName() + { + return $this->getAgentName(); + } + + } + +?> diff --git a/exceptions/LayoutNotValidException.inc b/exceptions/LayoutNotValidException.inc new file mode 100644 index 00000000..b3af184f --- /dev/null +++ b/exceptions/LayoutNotValidException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Layout not valid. + * + * @author coderkun + */ + class LayoutNotValidException extends \nre\exceptions\AgentNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 75; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'layout not valid'; + + + + + /** + * Construct a new exception. + * + * @param string $layoutName Name of the invalid Layout + */ + function __construct($layoutName) + { + parent::__construct( + $layoutName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid Layout. + * + * @return string Name of the invalid Layout + */ + public function getLayoutName() + { + return $this->getAgentName(); + } + + } + +?> diff --git a/exceptions/ModelNotFoundException.inc b/exceptions/ModelNotFoundException.inc new file mode 100644 index 00000000..48e8c0df --- /dev/null +++ b/exceptions/ModelNotFoundException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Action not found. + * + * @author coderkun + */ + class ModelNotFoundException extends \nre\exceptions\ClassNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 68; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'model not found'; + + + + + /** + * Construct a new exception. + * + * @param string $modelName Name of the Model that was not found + */ + function __construct($modelName) + { + parent::__construct( + $modelName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the Model that was not found + * + * @return string Name of the Model that was not found + */ + public function getModelName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/ModelNotValidException.inc b/exceptions/ModelNotValidException.inc new file mode 100644 index 00000000..267e460e --- /dev/null +++ b/exceptions/ModelNotValidException.inc @@ -0,0 +1,68 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Action not found. + * + * @author coderkun + */ + class ModelNotValidException extends \nre\exceptions\ClassNotValidException + { + /** + * Error code + * + * @var int + */ + const CODE = 78; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'model not valid'; + + + + + /** + * Construct a new exception. + * + * @param string $modelName Name of the invalid Model + */ + function __construct($modelName) + { + // Elternkonstruktor aufrufen + parent::__construct( + $modelName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid Model + * + * @return string Name of the invalid Model + */ + public function getModelName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/ParamsNotValidException.inc b/exceptions/ParamsNotValidException.inc new file mode 100644 index 00000000..be650ce2 --- /dev/null +++ b/exceptions/ParamsNotValidException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception Parameters not valid. + * + * @author coderkun + */ + class ParamsNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 86; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'parameters not valid'; + + /** + * Invalid parameters. + * + * @var array + */ + private $params; + + + + + /** + * Construct a new exception. + * + * @param mixed $param1 Invalid parameters as argument list + */ + function __construct($param1) + { + parent::__construct( + self::MESSAGE, + self::CODE, + implode(', ', func_get_args()) + ); + + // Store values + $this->params = func_get_args(); + } + + + + + /** + * Get invalid parameters. + * + * @return array Invalid parameters + */ + public function getParams() + { + return $this->params; + } + + } + +?> diff --git a/exceptions/ServiceUnavailableException.inc b/exceptions/ServiceUnavailableException.inc new file mode 100644 index 00000000..bafc297f --- /dev/null +++ b/exceptions/ServiceUnavailableException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Service is unavailable. + * + * @author coderkun + */ + class ServiceUnavailableException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 84; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'service unavailable'; + + /** + * Throws exception + * + * @var Exception + */ + private $exception; + + + + + /** + * Construct a new exception. + * + * @param Exception $exception Exception that has occurred + */ + function __construct($exception) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $exception->getMessage() + ); + + // Store values + $this->exception = $exception; + } + + + + + /** + * Get the exception that hat occurred + * + * @return Exception Exception that has occurred + */ + public function getException() + { + return $this->exception; + } + + } + +?> diff --git a/exceptions/ViewNotFoundException.inc b/exceptions/ViewNotFoundException.inc new file mode 100644 index 00000000..30366201 --- /dev/null +++ b/exceptions/ViewNotFoundException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: View not found. + * + * @author coderkun + */ + class ViewNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 69; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'view not found'; + + /** + * Filename of the view that was not found + * + * @var string + */ + private $fileName; + + + + + /** + * Construct a new exception. + * + * @param string $fileName Filename of the view that was not found + */ + function __construct($fileName) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $fileName + ); + + // Save values + $this->fileName = $fileName; + } + + + + + /** + * Get the filename of the view that was not found. + * + * @return string Filename of the view that was not found + */ + public function getFileName() + { + return $this->fileName; + } + + } + +?> diff --git a/logs/empty b/logs/empty new file mode 100644 index 00000000..e69de29b diff --git a/models/DatabaseModel.inc b/models/DatabaseModel.inc new file mode 100644 index 00000000..8017f959 --- /dev/null +++ b/models/DatabaseModel.inc @@ -0,0 +1,129 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\models; + + + /** + * Default implementation of a database model. + * + * @author coderkun + */ + class DatabaseModel extends \nre\core\Model + { + + /** + * Database connection + * + * @static + * @var object + */ + private static $db = NULL; + + + + + /** + * Construct a new datamase model. + * + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @throws DatamodelException + * @param string $databaseType Database type + * @param array $config Connection settings + */ + function __construct($databaseType, $config) + { + parent::__construct(); + + // Load database driver + $this->loadDriver($databaseType); + + // Establish database connection + $this->connect($databaseType, $config); + } + + + + + /** + * Execute a SQL-query. + * + * @param string $query Query to run + * @param mixed … Query parameters + * @return array Result + */ + protected function query($query) + { + // Mask parameters + $args = array($query); + foreach(array_slice(func_get_args(), 1) as $arg) { + $args[] = self::$db->mask($arg); + } + + // Format query + $query = call_user_func_array( + 'sprintf', + $args + ); + + // Execute query + $data = self::$db->query($query); + + + // Return data + return $data; + } + + + /** + * Return the last insert id (of the last insert-query). + * + * @return int Last insert id + */ + protected function getInsertId() + { + return self::$db->getInsertId(); + } + + + + + /** + * Load the database driver. + * + * @throws DriverNotFoundException + * @throws DriverNotValidException + * @param string $driverName Name of the database driver + */ + private static function loadDriver($driverName) + { + \nre\core\Driver::load($driverName); + + } + + + /** + * Establish a connection to the database. + * + * @throws DatamodelException + * @param string $driverName Name of the database driver + */ + private static function connect($driverName, $config) + { + if(self::$db === NULL) { + self::$db = \nre\core\Driver::factory($driverName, $config); + } + } + + } + +?> diff --git a/requests/WebRequest.inc b/requests/WebRequest.inc new file mode 100644 index 00000000..c3208fb8 --- /dev/null +++ b/requests/WebRequest.inc @@ -0,0 +1,358 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\requests; + + + /** + * Representation of a web-request. + * + * @author coderkun + */ + class WebRequest extends \nre\core\Request + { + /** + * Passed GET-parameters + * + * @var array + */ + private $getParams = array(); + /** + * Passed POST-parameters + * + * @var array + */ + private $postParams = array(); + /** + * Stored routes + * + * @var array + */ + private $routes = array(); + /** + * Stored reverse-routes + * + * @var array + */ + private $reverseRoutes = array(); + + + + + /** + * Construct a new web-request. + */ + public function __construct() + { + // Detect current request + $this->detectRequest(); + + // Load GET-parameters + $this->loadGetParams(); + + // Load POST-parameters + $this->loadPostParams(); + } + + + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + if($index == 0) { + return $this->getGetParam('layout', $defaultIndex); + } + else { + return parent::getParam($index-1, $defaultIndex); + } + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameters + */ + public function getParams($offset=0) + { + if($offset == 0) + { + return array_merge( + array( + $this->getGetParam('layout', 'toplevel') + ), + parent::getParams() + ); + } + + + return array_slice($this->params, $offset-1); + } + + + /** + * Get a GET-parameter. + * + * @param string $key Key of GET-parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of GET-parameter + */ + public function getGetParam($key, $defaultIndex=null) + { + // Check key + if(array_key_exists($key, $this->getParams)) + { + // Return value + return $this->getParams[$key]; + } + + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all GET-parameters + * + * @return array GET-Parameters + */ + public function getGetParams() + { + return $this->getParams; + } + + + /** + * Get a POST-parameter. + * + * @param string $key Key of POST-parameter + * @param string $defaultValue Default value for this parameter + * @return string Value of POST-parameter + */ + public function getPostParam($key, $defaultValue=null) + { + // Check key + if(array_key_exists($key, $this->postParams)) + { + // Return value + return $this->postParams[$key]; + } + + + // Return default value + return $defaultValue; + } + + + /** + * Add a URL-route. + * + * @param string $pattern Regex-Pattern that defines the routing + * @param string $replacement Regex-Pattern for replacement + * @param bool $isLast Stop after that rule + */ + public function addRoute($pattern, $replacement, $isLast=false) + { + // Store route + $this->routes[] = $this->newRoute($pattern, $replacement, $isLast); + } + + + /** + * Add a reverse URL-route. + * + * @param string $pattern Regex-Pattern that defines the reverse routing + * @param string $replacement Regex-Pattern for replacement + * @param bool $isLast Stop after that rule + */ + public function addReverseRoute($pattern, $replacement, $isLast=false) + { + // Store reverse route + $this->reverseRoutes[] = $this->newRoute($pattern, $replacement, $isLast); + } + + + /** + * Apply stored reverse-routes to an URL + * + * @param string $url URL to apply reverse-routes to + * @return string Reverse-routed URL + */ + public function applyReverseRoutes($url) + { + return $this->applyRoutes($url, $this->reverseRoutes); + } + + + /** + * Revalidate the current request + */ + public function revalidate() + { + $this->detectRequest(); + } + + + /** + * Get a SERVER-parameter. + * + * @param string $key Key of SERVER-parameter + * @return string Value of SERVER-parameter + */ + public function getServerParam($key) + { + if(array_key_exists($key, $_SERVER)) { + return $_SERVER[$key]; + } + + + return null; + } + + + + + /** + * Detect the current HTTP-request. + */ + private function detectRequest() + { + // URL ermitteln + $url = isset($_GET) && array_key_exists('url', $_GET) ? $_GET['url'] : ''; + $url = trim($url, '/'); + + // Routes anwenden + $url = $this->applyRoutes($url, $this->routes); + + // URL splitten + $params = explode('/', $url); + if(empty($params[0])) { + $params = array(); + } + + + // Parameter speichern + $this->params = $params; + } + + + /** + * Determine parameters passed by GET. + */ + private function loadGetParams() + { + if(isset($_GET)) { + $this->getParams = $_GET; + } + } + + + /** + * Determine parameters passed by POST. + */ + private function loadPostParams() + { + if(isset($_POST)) { + $this->postParams = $_POST; + } + } + + + /** + * Create a new URL-route. + * + * @param string $pattern Regex-Pattern that defines the reverse routing + * @param string $replacement Regex-Pattern for replacement + * @param bool $isLast Stop after that rule + * @return array New URL-route + */ + private function newRoute($pattern, $replacement, $isLast=false) + { + return array( + 'pattern' => $pattern, + 'replacement' => $replacement, + 'isLast' => $isLast + ); + } + + + /** + * Apply given routes to an URL + * + * @param string $url URL to apply routes to + * @param array $routes Routes to apply + * @return string Routed URL + */ + private function applyRoutes($url, $routes) + { + // Traverse given routes + foreach($routes as &$route) + { + // Create and apply Regex + $urlR = preg_replace( + '>'.$route['pattern'].'>i', + $route['replacement'], + $url + ); + + // Split URL + $get = ''; + if(($gpos = strrpos($urlR, '?')) !== false) { + $get = substr($urlR, $gpos+1); + $urlR = substr($urlR, 0, $gpos); + } + + // Has current route changed anything? + if($urlR != $url || !empty($get)) + { + // Extract GET-parameters + if(strlen($get) > 0) + { + $gets = explode('&', $get); + foreach($gets as $get) + { + $get = explode('=', $get); + if(!array_key_exists($get[0], $this->getParams)) { + $this->getParams[$get[0]] = $get[1]; + } + } + } + + + // Stop when route “isLast” + if($route['isLast']) { + $url = $urlR; + break; + } + } + + + // Set new URL + $url = $urlR; + } + + + // Return routed URL + return $url; + } + + } + +?> diff --git a/responses/WebResponse.inc b/responses/WebResponse.inc new file mode 100644 index 00000000..2ca25079 --- /dev/null +++ b/responses/WebResponse.inc @@ -0,0 +1,250 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\responses; + + + /** + * Representation of a web-response. + * + * @author coderkun + */ + class WebResponse extends \nre\core\Response + { + /** + * Applied GET-parameters + * + * @var array + */ + private $getParams = array(); + /** + * Changed header lines + * + * @var array + */ + private $headers = array(); + + + + + /** + * Add a parameter. + * + * @param mixed $value Value of parameter + */ + public function addParam($value) + { + if(array_key_exists('layout', $this->getParams)) { + parent::addParam($value); + } + else { + $this->addGetParam('layout', $value); + } + } + + + /** + * Add multiple parameters. + * + * @param mixed $value1 Value of first parameter + * @param mixed … Values of further parameters + */ + public function addParams($value1) + { + $this->addParam($value1); + + $this->params = array_merge( + $this->params, + array_slice( + func_get_args(), + 1 + ) + ); + } + + + /** + * Delete all stored parameters (from offset on). + * + * @param int $offset Offset-index + */ + public function clearParams($offset=0) + { + if($offset == 0) { + unset($this->getParams['layout']); + } + + parent::clearParams(max(0, $offset-1)); + } + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + if($index == 0) { + return $this->getGetParam('layout', $defaultIndex); + } + else { + return parent::getParam($index-1, $defaultIndex); + } + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameter values + */ + public function getParams($offset=0) + { + if($offset == 0) + { + if(!array_key_exists('layout', $this->getParams)) { + return array(); + } + + return array_merge( + array( + $this->getParams['layout'] + ), + $this->params + ); + } + + + return array_slice($this->params, $offset-1); + } + + + /** + * Add a GET-parameter. + * + * @param string $key Key of GET-parameter + * @param mixed $value Value of GET-parameter + */ + public function addGetParam($key, $value) + { + $this->getParams[$key] = $value; + } + + + /** + * Add multiple GET-parameters. + * + * @param array $params Associative arary with key-value GET-parameters + */ + public function addGetParams($params) + { + $this->getParams = array_merge( + $this->getParams, + $params + ); + } + + + /** + * Get a GET-parameter. + * + * @param int $index Index of GET-parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of GET-parameter + */ + public function getGetParam($key, $defaultIndex=null) + { + // Check key + if(array_key_exists($key, $this->getParams)) + { + // Return value + return $this->getParams[$key]; + } + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all GET-parameters. + * + * @return array All GET-parameters + */ + public function getGetParams() + { + return $this->getParams; + } + + + /** + * Add a line to the response header. + * + * @param string $headerLine Header line + * @param bool $replace Replace existing header line + * @param int $http_response_code HTTP-response code + */ + public function addHeader($headerLine, $replace=true, $http_response_code=null) + { + $this->headers[] = $this->newHeader($headerLine, $replace, $http_response_code); + } + + + /** + * Clear all stored headers. + */ + public function clearHeaders() + { + $this->headers = array(); + } + + + /** + * Send stored headers. + */ + public function header() + { + foreach($this->headers as $header) + { + header( + $header['string'], + $header['replace'], + $header['responseCode'] + ); + } + } + + + + + /** + * Create a new header line. + * + * @param string $headerLine Header line + * @param bool $replace Replace existing header line + * @param int $http_response_code HTTP-response code + */ + private function newHeader($headerLine, $replace=true, $http_response_code=null) + { + return array( + 'string' => $headerLine, + 'replace' => $replace, + 'responseCode' => $http_response_code + ); + } + + } + +?> diff --git a/views/error.tpl b/views/error.tpl new file mode 100644 index 00000000..2f177be3 --- /dev/null +++ b/views/error.tpl @@ -0,0 +1,13 @@ + + + + + + Service Unavailable + + + +

Die Anwendung steht zur Zeit leider nicht zur Verfügung.

+ + + diff --git a/views/inlineerror.tpl b/views/inlineerror.tpl new file mode 100644 index 00000000..87a2b222 --- /dev/null +++ b/views/inlineerror.tpl @@ -0,0 +1 @@ +

Dieser Teil der Anwendung steht zur Zeit leider nicht zur Verfügung.

diff --git a/www/.htaccess b/www/.htaccess new file mode 100644 index 00000000..45d60053 --- /dev/null +++ b/www/.htaccess @@ -0,0 +1,8 @@ + + RewriteEngine On + + RewriteBase / + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php?url=$1 [QSA,L,NE] + diff --git a/www/index.php b/www/index.php new file mode 100644 index 00000000..2faa32fd --- /dev/null +++ b/www/index.php @@ -0,0 +1,45 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + /** + * Define constants + */ + // Directory separator + if(!defined('DS')) { + define('DS', DIRECTORY_SEPARATOR); + } + // Root directory + if(!defined('ROOT')) { + define('ROOT', dirname(dirname(__FILE__))); + } + + + /** + * De-/Activate error messages + */ + if($_SERVER['SERVER_ADDR'] == '127.0.0.1') { + error_reporting(E_ALL); + ini_set('display_errors', 1); + ini_set('log_errors', 0); + } + else { + error_reporting(E_ALL); + ini_set('display_errors', 0); + ini_set('log_errors', 1); + } + + + /** + * Run application + */ + require ROOT.DS.'bootstrap.inc'; + +?> From 7348ca080c09a8d1324afbba3929e25d289b1bb1 Mon Sep 17 00:00:00 2001 From: coderkun Date: Tue, 27 Aug 2013 14:24:31 +0200 Subject: [PATCH 02/34] correct namespaces --- agents/ToplevelAgent.inc | 23 +++++++++++++---------- apis/WebApi.inc | 2 +- core/Model.inc | 5 +++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/agents/ToplevelAgent.inc b/agents/ToplevelAgent.inc index af98c3d2..c545975a 100644 --- a/agents/ToplevelAgent.inc +++ b/agents/ToplevelAgent.inc @@ -116,17 +116,20 @@ try { return $this->_run($request, $response); } - catch(ParamsNotValidException $e) { - $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + catch(\nre\exceptions\AccessDeniedException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_FORBIDDEN, self::STAGE_RUN); } - catch(IdNotFoundException $e) { - $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + catch(\nre\exceptions\ParamsNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); } - catch(DatamodelException $e) { - $this->error($e, WebUtils::HTTP_SERVICE_UNAVAILABLE, self::STAGE_RUN); + catch(\nre\exceptions\IdNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); } - catch(ActionNotFoundException $e) { - $this->error($e, WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + catch(\nre\exceptions\DatamodelException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE, self::STAGE_RUN); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); } } @@ -173,8 +176,8 @@ func_get_args() ); } - catch(DatamodelException $e) { - throw new FatalDatamodelException($e->getDatamodelMessage(), $e->getDatamodelErrorNumber()); + catch(\nre\exceptions\DatamodelException $e) { + throw new \nre\exceptions\FatalDatamodelException($e->getDatamodelMessage(), $e->getDatamodelErrorNumber()); } } diff --git a/apis/WebApi.inc b/apis/WebApi.inc index 5d4ac7cd..28896a30 100644 --- a/apis/WebApi.inc +++ b/apis/WebApi.inc @@ -60,7 +60,7 @@ $this->errorService($e); } catch(\nre\exceptions\ActionNotFoundException $e) { - $this->error($e, WebUtils::HTTP_NOT_FOUND); + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); } catch(\nre\exceptions\FatalDatamodelException $e) { $this->errorService($e); diff --git a/core/Model.inc b/core/Model.inc index 2906c404..c0475b4a 100644 --- a/core/Model.inc +++ b/core/Model.inc @@ -74,7 +74,7 @@ */ private static function getClassName($modelName) { - $className = \nre\core\ClassLoader::concatClassNames($modelName, \nre\core\ClassLoader::stripNamespace(get_class())); + $className = ClassLoader::concatClassNames($modelName, ClassLoader::stripNamespace(get_class())); return \nre\configs\AppConfig::$app['namespace']."models\\$className"; @@ -131,7 +131,8 @@ Model::load($model); // Construct Model - $this->$model = Model::factory($model); + $modelName = ucfirst(strtolower($model)); + $this->$modelName = Model::factory($model); } } From 1779c3821898857f470e31e88b1bb0a76c27c7a4 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:39:53 +0200 Subject: [PATCH 03/34] correct namespaces --- core/Agent.inc | 6 +++--- core/Driver.inc | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/Agent.inc b/core/Agent.inc index 07bece26..00ec1a90 100644 --- a/core/Agent.inc +++ b/core/Agent.inc @@ -398,7 +398,7 @@ { try { // Load Agent - BottomlevelAgent::load($agentName); + \nre\agents\BottomlevelAgent::load($agentName); // Construct Agent $this->subAgents[] = call_user_func_array( @@ -468,7 +468,7 @@ return array( 'name' => strtolower($agentName), 'response' => $response, - 'object' => BottomlevelAgent::factory( + 'object' => \nre\agents\BottomlevelAgent::factory( $agentName, $this->request, $response, @@ -548,7 +548,7 @@ try { // Load Agenten - BottomlevelAgent::load($agentName); + \nre\agents\BottomlevelAgent::load($agentName); // Construct Agent $subAgent = $this->newSubAgent($agentName); diff --git a/core/Driver.inc b/core/Driver.inc index aa3096a6..bf9084d1 100644 --- a/core/Driver.inc +++ b/core/Driver.inc @@ -42,11 +42,11 @@ // Validate class ClassLoader::check($className, get_class()); } - catch(ClassNotValidException $e) { - throw new DriverNotValidException($e->getClassName()); + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\DriverNotValidException($e->getClassName()); } - catch(ClassNotFoundException $e) { - throw new DriverNotFoundException($e->getClassName()); + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\DriverNotFoundException($e->getClassName()); } } @@ -75,7 +75,7 @@ */ private static function getClassName($driverName) { - $className = \nre\core\ClassLoader::concatClassNames($driverName, \nre\core\ClassLoader::stripNamespace(get_class())); + $className = ClassLoader::concatClassNames($driverName, ClassLoader::stripNamespace(get_class())); return "\\nre\\drivers\\$className"; From 23346a78b5220ac6ccb73f945f9352e635df6964 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:41:38 +0200 Subject: [PATCH 04/34] correct trifles --- agents/BottomlevelAgent.inc | 28 ---------------------- core/Linker.inc | 2 +- exceptions/ControllerNotFoundException.inc | 1 - exceptions/ControllerNotValidException.inc | 1 - views/error.tpl | 2 +- www/.htaccess | 2 +- 6 files changed, 3 insertions(+), 33 deletions(-) diff --git a/agents/BottomlevelAgent.inc b/agents/BottomlevelAgent.inc index 95629e48..37816614 100644 --- a/agents/BottomlevelAgent.inc +++ b/agents/BottomlevelAgent.inc @@ -20,34 +20,6 @@ */ abstract class BottomlevelAgent extends \nre\core\Agent { - - - - - /** - * Load a BottomlevelAgent. - * - * @throws AgentNotFoundException - * @throws AgentNotValidException - * @param string $agentName BottomlevelAgent name - */ - public static function load($agentName) - { - // Load class - parent::load_agent($agentName, Autoloader::getClassName(get_class())); - - // Determine full classname - $className = Autoloader::concatClassNames($agentName, Autoloader::getClassType(get_class())); - - // Validate class - try { - ClassLoader::check($className, get_class()); - } - catch(ClassNotValidException $e) { - throw new AgentNotValidException($e->getClassName()); - } - } - } ?> diff --git a/core/Linker.inc b/core/Linker.inc index 61dd5fa8..5496d2b9 100644 --- a/core/Linker.inc +++ b/core/Linker.inc @@ -299,7 +299,7 @@ // Determine prefix $ppos = array(strlen($uri)); - if(($p = strpos($uri, '/'.$request->getParam(1, \nre\configs\AppConfig::$defaults['intermediate']))) !== false) { + if(($p = strpos($uri, '/'.$request->getParam(1, 'intermediate'))) !== false) { $ppos[] = $p; } $prefix = substr($uri, 0, min($ppos)); diff --git a/exceptions/ControllerNotFoundException.inc b/exceptions/ControllerNotFoundException.inc index 56c4a3fd..90859c49 100644 --- a/exceptions/ControllerNotFoundException.inc +++ b/exceptions/ControllerNotFoundException.inc @@ -42,7 +42,6 @@ */ function __construct($controllerName) { - // Elternkonstruktor aufrufen parent::__construct( $controllerName, self::MESSAGE, diff --git a/exceptions/ControllerNotValidException.inc b/exceptions/ControllerNotValidException.inc index e309469d..0c945bcb 100644 --- a/exceptions/ControllerNotValidException.inc +++ b/exceptions/ControllerNotValidException.inc @@ -42,7 +42,6 @@ */ function __construct($controllerName) { - // Elternkonstruktor aufrufen parent::__construct( $controllerName, self::MESSAGE, diff --git a/views/error.tpl b/views/error.tpl index 2f177be3..f45b01a0 100644 --- a/views/error.tpl +++ b/views/error.tpl @@ -2,7 +2,7 @@ - + Service Unavailable diff --git a/www/.htaccess b/www/.htaccess index 45d60053..63163a80 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -1,7 +1,7 @@ RewriteEngine On - RewriteBase / + RewriteBase / RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?url=$1 [QSA,L,NE] From 604e7c9bbad6c977f8b48d0848704dd71ce66cd9 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:43:17 +0200 Subject: [PATCH 05/34] load Models defined in parent classes --- core/Controller.inc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/Controller.inc b/core/Controller.inc index 2c2309c4..5dd25115 100644 --- a/core/Controller.inc +++ b/core/Controller.inc @@ -328,6 +328,15 @@ if(!is_array($models)) { $models = array($models); } + // Models of parent classes + $parent = $this; + while($parent = get_parent_class($parent)) + { + $properties = get_class_vars($parent); + if(array_key_exists('models', $properties)) { + $models = array_merge($models, $properties['models']); + } + } // Load Models foreach($models as &$model) @@ -337,7 +346,8 @@ Model::load($model); // Construct Model - $this->$model = Model::factory($model); + $modelName = ucfirst(strtolower($model)); + $this->$modelName = Model::factory($model); } catch(\nre\exceptions\ModelNotValidException $e) { if($explicit) { From 961c869c30fb225ec4d76b7e954850ad39e5e0dd Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:44:54 +0200 Subject: [PATCH 06/34] implement drivers as Singleton --- core/Driver.inc | 2 +- drivers/DatabaseDriver.inc | 62 +++++++------- drivers/MysqlDriver.inc | 153 --------------------------------- drivers/MysqliDriver.inc | 167 +++++++++++++++++++++++++++++++++++++ models/DatabaseModel.inc | 70 +++------------- 5 files changed, 214 insertions(+), 240 deletions(-) delete mode 100644 drivers/MysqlDriver.inc create mode 100644 drivers/MysqliDriver.inc diff --git a/core/Driver.inc b/core/Driver.inc index bf9084d1..eec59143 100644 --- a/core/Driver.inc +++ b/core/Driver.inc @@ -63,7 +63,7 @@ // Construct and return Driver - return new $className($config); + return $className::singleton($config); } diff --git a/drivers/DatabaseDriver.inc b/drivers/DatabaseDriver.inc index c69d6add..dfd5c0fd 100644 --- a/drivers/DatabaseDriver.inc +++ b/drivers/DatabaseDriver.inc @@ -20,11 +20,12 @@ abstract class DatabaseDriver extends \nre\core\Driver { /** - * Connection and login settings + * Driver class instance * - * @var array + * @static + * @var DatabaseDriver */ - protected $config; + protected static $driver = null; /** * Connection resource * @@ -36,31 +37,25 @@ /** - * Execute a SQL-query. + * Singleton-pattern. * - * @param string $query Query to run - * @return array Result + * @param array $config Database driver configuration + * @return DatabaseDriver Singleton-instance of database driver class */ - public abstract function query($query); - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - public abstract function getInsertId(); - - - /** - * Mask an input for using it in a SQL-query. - * - * @param mixed $input Input to mask - * @return mixed Masked input - */ - public abstract function mask($input); - - + public static function singleton($config) + { + // Singleton + if(self::$driver !== null) { + return self::$driver; + } + + // Construct + $className = get_called_class(); + self::$driver = new $className($config); + + + return self::$driver; + } /** @@ -72,10 +67,21 @@ { parent::__construct(); - // Save values - $this->config = $config; + // Establish connection + $this->connect($config); } + + + + /** + * Establish a connect to a MqSQL-database. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + protected abstract function connect($config); + } ?> diff --git a/drivers/MysqlDriver.inc b/drivers/MysqlDriver.inc deleted file mode 100644 index 11122b38..00000000 --- a/drivers/MysqlDriver.inc +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright 2013 coderkun (http://www.coderkun.de) - * @license http://www.gnu.org/licenses/gpl.html - * @link http://www.coderkun.de/projects/nre - */ - - namespace nre\drivers; - - - /** - * Implementation of a database driver for MySQL-databases. - * - * @author coderkun - */ - class MysqlDriver extends \nre\drivers\DatabaseDriver - { - - - - - /** - * Construct a MySQL-driver. - * - * @throws DatamodelException - * @param array $config Connection and login settings - */ - function __construct($config) - { - parent::__construct($config); - - // Connect - $this->connect(); - } - - - - - /** - * Execute a SQL-query. - * - * @param string $query Query to run - * @return array Result - */ - public function query($query) - { - // Return-array - $data = array(); - - - // Execute query - $result = mysql_query($query, $this->connection); - - // Check result - if(($errno = mysql_errno($this->connection)) > 0) { - throw new DatamodelException(mysql_error($this->connection), $errno); - } - - // Process result - if(is_resource($result)) - { - while($row = mysql_fetch_array($result, MYSQL_ASSOC)) { - $data[] = $row; - } - } - - - // Return data - return $data; - } - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - public function getInsertId() - { - return mysql_insert_id($this->connection); - } - - - /** - * Mask an input for using it in a SQL-query. - * - * @param mixed $input Input to mask - * @return mixed Masked input - */ - public function mask($input) - { - return mysql_real_escape_string($input, $this->connection); - } - - - - - /** - * Establish a connect to a MqSQL-database. - * - * @throws DatamodelException - */ - private function connect() - { - // Connect - $con = @mysql_connect( - $this->config['host'], - $this->config['user'], - $this->config['password'] - ); - - // Check connection - if($con === false) { - throw new \nre\exceptions\DatamodelException(mysql_error(), mysql_errno()); - } - - // Save connection - $this->connection = $con; - - - // Select database - $db = mysql_select_db( - $this->config['db'], - $this->connection - ); - - // Check database selection - if(!$db) { - throw new DatamodelException(mysql_error(), mysql_errno()); - } - - - // Configure connection - $this->configConnection(); - } - - - /** - * Configure the current connection - */ - private function configConnection() - { - // Set character encoding - $this->query("SET NAMES 'utf8'", $this->connection); - } - - } - -?> diff --git a/drivers/MysqliDriver.inc b/drivers/MysqliDriver.inc new file mode 100644 index 00000000..9520fa1e --- /dev/null +++ b/drivers/MysqliDriver.inc @@ -0,0 +1,167 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\drivers; + + + /** + * Implementation of a database driver for MySQL-databases. + * + * @author coderkun + */ + class MysqliDriver extends \nre\drivers\DatabaseDriver + { + + + + + /** + * Construct a MySQL-driver. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + function __construct($config) + { + parent::__construct($config); + } + + + + + /** + * Execute a SQL-query. + * + * @throws DatamodelException + * @param string $query Query to run + * @param mixed … Params + * @return array Result + */ + public function query($query) + { + // Prepare statement + if(!($stmt = $this->connection->prepare($query))) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + + try { + // Prepare data + $data = array(); + + // Bind parameters + $p = array_slice(func_get_args(), 1); + $params = array(); + foreach($p as $key => $value) { + $params[$key] = &$p[$key]; + } + if(count($params) > 0) + { + if(!(call_user_func_array(array($stmt, 'bind_param'), $params))) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + } + + // Execute query + if(!$stmt->execute()) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + + // Fetch result + if($result = $stmt->get_result()) { + while($row = $result->fetch_assoc()) { + $data[] = $row; + } + } + + + return $data; + } + finally { + $stmt->close(); + } + } + + + /** + * Return the last insert id (of the last insert-query). + * + * @return int Last insert id + */ + public function getInsertId() + { + return $this->connection->insert_id; + } + + + /** + * Enable/disable autocommit feature. + * + * @param boolean $autocommit Enable/disable autocommit + */ + public function setAutocommit($autocommit) + { + $this->connection->autocommit($autocommit); + } + + + /** + * Rollback the current transaction. + */ + public function rollback() + { + $this->connection->rollback(); + } + + + /** + * Commit the current transaction. + */ + public function commit() + { + $this->connection->commit(); + } + + + + + /** + * Establish a connect to a MqSQL-database. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + protected function connect($config) + { + // Connect + $con = @new \mysqli( + $config['host'], + $config['user'], + $config['password'], + $config['db'] + ); + + // Check connection + if($con->connect_error) { + throw new \nre\exceptions\DatamodelException($con->connect_error, $con->connect_errno); + } + + // Set character encoding + if(!$con->set_charset('utf8')) { + throw new \nre\exceptions\DatamodelException($con->connect_error, $con->connect_errno); + } + + // Save connection + $this->connection = $con; + } + + } + +?> diff --git a/models/DatabaseModel.inc b/models/DatabaseModel.inc index 8017f959..51259f4f 100644 --- a/models/DatabaseModel.inc +++ b/models/DatabaseModel.inc @@ -19,14 +19,13 @@ */ class DatabaseModel extends \nre\core\Model { - /** * Database connection * * @static - * @var object + * @var DatabaseDriver */ - private static $db = NULL; + protected $db = NULL; @@ -34,64 +33,21 @@ /** * Construct a new datamase model. * + * @throws DatamodelException * @throws DriverNotFoundException * @throws DriverNotValidException - * @throws DatamodelException - * @param string $databaseType Database type - * @param array $config Connection settings + * @param string $type Database type + * @param array $config Connection settings */ - function __construct($databaseType, $config) + function __construct($type, $config) { parent::__construct(); // Load database driver - $this->loadDriver($databaseType); + $this->loadDriver($type); // Establish database connection - $this->connect($databaseType, $config); - } - - - - - /** - * Execute a SQL-query. - * - * @param string $query Query to run - * @param mixed … Query parameters - * @return array Result - */ - protected function query($query) - { - // Mask parameters - $args = array($query); - foreach(array_slice(func_get_args(), 1) as $arg) { - $args[] = self::$db->mask($arg); - } - - // Format query - $query = call_user_func_array( - 'sprintf', - $args - ); - - // Execute query - $data = self::$db->query($query); - - - // Return data - return $data; - } - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - protected function getInsertId() - { - return self::$db->getInsertId(); + $this->connect($type, $config); } @@ -104,10 +60,9 @@ * @throws DriverNotValidException * @param string $driverName Name of the database driver */ - private static function loadDriver($driverName) + private function loadDriver($driverName) { \nre\core\Driver::load($driverName); - } @@ -116,12 +71,11 @@ * * @throws DatamodelException * @param string $driverName Name of the database driver + * @param array $config Connection settings */ - private static function connect($driverName, $config) + private function connect($driverName, $config) { - if(self::$db === NULL) { - self::$db = \nre\core\Driver::factory($driverName, $config); - } + $this->db = \nre\core\Driver::factory($driverName, $config); } } From 53d684d15127b561824220b5bb148e22b5172a51 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:46:41 +0200 Subject: [PATCH 07/34] implement Components --- controllers/components/empty | 0 core/Component.inc | 85 +++++++++++++++++++++++ core/Controller.inc | 33 +++++++++ exceptions/ComponentNotFoundException.inc | 67 ++++++++++++++++++ exceptions/ComponentNotValidException.inc | 67 ++++++++++++++++++ 5 files changed, 252 insertions(+) create mode 100644 controllers/components/empty create mode 100644 core/Component.inc create mode 100644 exceptions/ComponentNotFoundException.inc create mode 100644 exceptions/ComponentNotValidException.inc diff --git a/controllers/components/empty b/controllers/components/empty new file mode 100644 index 00000000..e69de29b diff --git a/core/Component.inc b/core/Component.inc new file mode 100644 index 00000000..a93363dc --- /dev/null +++ b/core/Component.inc @@ -0,0 +1,85 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class to implement a (Controller) Component. + * + * @author coderkun + */ + abstract class Component + { + + + + + /** + * Load the class of a Component. + * + * @throws ComponentNotFoundException + * @throws ComponentNotValidException + * @param string $componentName Name of the Component to load + */ + public static function load($componentName) + { + // Determine full classname + $className = self::getClassName($componentName); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + ClassLoader::check($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\ComponentNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\ComponentNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Component (Factory Pattern). + * + * @param string $componentName Name of the Component to instantiate + */ + public static function factory($componentName) + { + // Determine full classname + $className = self::getClassName($componentName); + + // Construct and return Controller + return new $className(); + } + + + /** + * Determine the classname for the given Component name. + * + * @param string $componentName Component name to get classname of + * @return string Classname for the Component name + */ + private static function getClassName($componentName) + { + $className = \nre\core\ClassLoader::concatClassNames($componentName, \nre\core\ClassLoader::stripNamespace(get_class())); + + + return \nre\configs\AppConfig::$app['namespace']."controllers\\components\\$className"; + } + + } + +?> diff --git a/core/Controller.inc b/core/Controller.inc index 5dd25115..55a7675a 100644 --- a/core/Controller.inc +++ b/core/Controller.inc @@ -138,6 +138,9 @@ // Store values $this->agent = $agent; + // Load Components + $this->loadComponents(); + // Load Models $this->loadModels(); @@ -306,6 +309,36 @@ + /** + * Load the Components of this Controller. + * + * @throws ComponentNotValidException + * @throws ComponentNotFoundException + */ + private function loadComponents() + { + // Determine components + $components = array(); + if(property_exists($this, 'components')) { + $components = $this->components; + } + if(!is_array($components)) { + $components = array($components); + } + + // Load components + foreach($components as &$component) + { + // Load class + Component::load($component); + + // Construct component + $componentName = ucfirst(strtolower($component)); + $this->$componentName = Component::factory($component); + } + } + + /** * Load the Models of this Controller. * diff --git a/exceptions/ComponentNotFoundException.inc b/exceptions/ComponentNotFoundException.inc new file mode 100644 index 00000000..5e75de44 --- /dev/null +++ b/exceptions/ComponentNotFoundException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Component not found. + * + * @author coderkun + */ + class ComponentNotFoundException extends \nre\exceptions\ClassNotFoundException + { + /** + * Error code + * + * @var int + */ + const CODE = 67; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'component not found'; + + + + + /** + * Construct a new exception. + * + * @param string $componentName Name of the Component that was not found + */ + function __construct($componentName) + { + parent::__construct( + $componentName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the Component that was not found. + * + * @return string Name of the Component that was not found + */ + public function getComponentName() + { + return $this->getClassName(); + } + + } + +?> diff --git a/exceptions/ComponentNotValidException.inc b/exceptions/ComponentNotValidException.inc new file mode 100644 index 00000000..a03b0c0d --- /dev/null +++ b/exceptions/ComponentNotValidException.inc @@ -0,0 +1,67 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Component not valid. + * + * @author coderkun + */ + class ComponentNotValidException extends \nre\exceptions\ClassNotValidException + { + /** + * Error code + * + * @var int + */ + const CODE = 77; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'component not valid'; + + + + + /** + * Construct a new exception. + * + * @param string $componentName Name of the invalid Component + */ + function __construct($componentName) + { + parent::__construct( + $componentName, + self::MESSAGE, + self::CODE + ); + } + + + + + /** + * Get the name of the invalid Component. + * + * @return string Name of the invalid Component + */ + public function getComponentName() + { + return $this->getClassName(); + } + + } + +?> From 996a501f4f8d8e46f50df04020722b3020d8bc1a Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:48:36 +0200 Subject: [PATCH 08/34] add access-properties --- core/WebUtils.inc | 7 ++++ exceptions/AccessDeniedException.inc | 51 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 exceptions/AccessDeniedException.inc diff --git a/core/WebUtils.inc b/core/WebUtils.inc index 778d12b1..5a4bb6f0 100644 --- a/core/WebUtils.inc +++ b/core/WebUtils.inc @@ -19,6 +19,12 @@ */ class WebUtils { + /** + * HTTP-statuscode 403: Forbidden + * + * @var int + */ + const HTTP_FORBIDDEN = 403; /** * HTTP-statuscode 404: Not Found * @@ -40,6 +46,7 @@ public static $httpStrings = array( 200 => 'OK', 304 => 'Not Modified', + 403 => 'Forbidden', 404 => 'Not Found', 503 => 'Service Unavailable' ); diff --git a/exceptions/AccessDeniedException.inc b/exceptions/AccessDeniedException.inc new file mode 100644 index 00000000..31bba929 --- /dev/null +++ b/exceptions/AccessDeniedException.inc @@ -0,0 +1,51 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: Access denied. + * + * @author coderkun + */ + class AccessDeniedException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 85; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'access denied'; + + + + + /** + * Consturct a new exception. + */ + function __construct() + { + parent::__construct( + self::MESSAGE, + self::CODE + ); + } + + } + +?> From 8508390c27f930cc161e627951f3ef28ebac7de7 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:48:56 +0200 Subject: [PATCH 09/34] extend request parameter handling --- requests/WebRequest.inc | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/requests/WebRequest.inc b/requests/WebRequest.inc index c3208fb8..cbb9da08 100644 --- a/requests/WebRequest.inc +++ b/requests/WebRequest.inc @@ -129,7 +129,7 @@ /** - * Get all GET-parameters + * Get all GET-parameters. * * @return array GET-Parameters */ @@ -161,6 +161,28 @@ } + /** + * Get all POST-parameters. + * + * @return array POST-parameters + */ + public function getPostParams() + { + return $this->postParams; + } + + + /** + * Get the method of the current request. + * + * @return string Current request method + */ + public function getRequestMethod() + { + return $_SERVER['REQUEST_METHOD']; + } + + /** * Add a URL-route. * From cc4bcac7f8c5c90718bef473550e868b8b9a773e Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:49:07 +0200 Subject: [PATCH 10/34] add IdNotFoundException --- exceptions/IdNotFoundException.inc | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 exceptions/IdNotFoundException.inc diff --git a/exceptions/IdNotFoundException.inc b/exceptions/IdNotFoundException.inc new file mode 100644 index 00000000..fc3315c3 --- /dev/null +++ b/exceptions/IdNotFoundException.inc @@ -0,0 +1,77 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\exceptions; + + + /** + * Exception: ID not found. + * + * @author coderkun + */ + class IdNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 85; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'id not found'; + + /** + * ID that was not found + * + * @var mixed + */ + private $id; + + + + + /** + * Consturct a new exception. + * + * @param mixed $id ID that was not found + */ + function __construct($id) + { + parent::__construct( + self::MESSAGE, + self::CODE, + $id + ); + + // Store values + $this->id = $id; + } + + + + + /** + * Get the ID that was not found. + * + * @return mixed ID that was not found + */ + public function getId() + { + return $this->id; + } + + } + +?> From d9d85e2306ab69d3b9c250946bfcb906cf78cf54 Mon Sep 17 00:00:00 2001 From: coderkun Date: Wed, 30 Oct 2013 12:16:39 +0100 Subject: [PATCH 11/34] detect AJAX request and set layout automatically --- requests/WebRequest.inc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/requests/WebRequest.inc b/requests/WebRequest.inc index cbb9da08..2e0f19b9 100644 --- a/requests/WebRequest.inc +++ b/requests/WebRequest.inc @@ -60,6 +60,9 @@ // Load POST-parameters $this->loadPostParams(); + + // Detect AJAX + $this->detectAJAX(); } @@ -297,6 +300,24 @@ } + /** + * Detect an AJAX-request by checking the X-Requested-With + * header and set the layout to 'ajax' in this case. + */ + private function detectAjax() + { + // Get request headers + $headers = apache_request_headers(); + + // Check X-Requested-With header and set layout + if(array_key_exists('X-Requested-With', $headers) && $headers['X-Requested-With'] == 'XMLHttpRequest') { + if(!array_key_exists('layout', $this->getParams)) { + $this->getParams['layout'] = 'ajax'; + } + } + } + + /** * Create a new URL-route. * From 0a45d90ba11d617fc4e4a1929987419a0d61fc28 Mon Sep 17 00:00:00 2001 From: coderkun Date: Wed, 30 Oct 2013 12:17:07 +0100 Subject: [PATCH 12/34] disable auto logging to screen for AJAX-requests --- apis/WebApi.inc | 5 +++++ core/Api.inc | 2 +- core/Logger.inc | 18 +++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/apis/WebApi.inc b/apis/WebApi.inc index 28896a30..6851ee2d 100644 --- a/apis/WebApi.inc +++ b/apis/WebApi.inc @@ -37,6 +37,11 @@ // Add routes $this->addRoutes(); + + // Disable screen logging for AJAX requests + if($this->request->getParam(0, 'toplevel') == 'ajax') { + $this->log->disableAutoLogToScreen(); + } } diff --git a/core/Api.inc b/core/Api.inc index 2623bba6..b89b12e7 100644 --- a/core/Api.inc +++ b/core/Api.inc @@ -45,7 +45,7 @@ * * @var Logger */ - private $log; + protected $log; diff --git a/core/Logger.inc b/core/Logger.inc index c96dff0a..b5ac7dc9 100644 --- a/core/Logger.inc +++ b/core/Logger.inc @@ -38,6 +38,13 @@ */ const LOGMODE_PHP = 2; + /** + * Do not auto-log to screen + * + * @var boolean + */ + private $autoLogToScreenDisabled = false; + @@ -76,6 +83,15 @@ } + /** + * Disable logging to screen when the log mode is automatically + * detected. + */ + public function disableAutoLogToScreen() + { + $this->autoLogToScreenDisabled = true; + } + /** @@ -108,7 +124,7 @@ */ private function getAutoLogMode() { - return ($_SERVER['SERVER_ADDR'] == '127.0.0.1') ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; + return ($_SERVER['SERVER_ADDR'] == '127.0.0.1' && !$this->autoLogToScreenDisabled) ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; } } From fdb115083e6aeb810b306452f9d10deb1fa66229 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:30:45 +0200 Subject: [PATCH 13/34] add support for Apache 2.4 --- .htaccess | 47 ++++++++++++++++++++++++++++++----------------- www/.htaccess | 1 - 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/.htaccess b/.htaccess index e5c5c191..69ec321e 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,3 @@ -Allow From All Options -Indexes -MultiViews ErrorDocument 403 /www/error403.html @@ -6,25 +5,39 @@ ErrorDocument 404 /www/error404.html ErrorDocument 500 /www/error500.html - - Order Deny,Allow - Deny From All - - - - Order Deny,Allow - Deny From All - - - - Order Deny,Allow - Deny From All - + + Require all granted + + + Require all denied + + + Require all denied + + + Require all denied + + + + Allow From All + + + Order Deny,Allow + Deny From All + + + Order Deny,Allow + Deny From All + + + Order Deny,Allow + Deny From All + + RewriteEngine On - RewriteBase / - RewriteRule ^(.*)$ www/$1 [L] + RewriteRule ^(.*)$ www/$1 [QSA,N] diff --git a/www/.htaccess b/www/.htaccess index 63163a80..29a1faa5 100644 --- a/www/.htaccess +++ b/www/.htaccess @@ -1,7 +1,6 @@ RewriteEngine On - RewriteBase / RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?url=$1 [QSA,L,NE] From 12ae8b180e042028b45273b4bd55b0911ee84598 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:33:11 +0200 Subject: [PATCH 14/34] add IPv6 support --- core/Logger.inc | 13 ++++++++++++- www/index.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/Logger.inc b/core/Logger.inc index b5ac7dc9..be2ce757 100644 --- a/core/Logger.inc +++ b/core/Logger.inc @@ -124,7 +124,18 @@ */ private function getAutoLogMode() { - return ($_SERVER['SERVER_ADDR'] == '127.0.0.1' && !$this->autoLogToScreenDisabled) ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; + return ($this->isLocalhost() && !$this->autoLogToScreenDisabled) ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; + } + + + /** + * Detect if the server is running as localhost without domain. + * + * @return boolean Wheather server is running as localhost or not + */ + private function isLocalhost() + { + return ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] = '::1'); } } diff --git a/www/index.php b/www/index.php index 2faa32fd..46301a31 100644 --- a/www/index.php +++ b/www/index.php @@ -25,7 +25,7 @@ /** * De-/Activate error messages */ - if($_SERVER['SERVER_ADDR'] == '127.0.0.1') { + if($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] == '::1') { error_reporting(E_ALL); ini_set('display_errors', 1); ini_set('log_errors', 0); From d746b62308fb966638ef3f2a8f147891835f41bb Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:33:58 +0200 Subject: [PATCH 15/34] add method to get current IntermediateAgent from ToplevelAgent() --- agents/ToplevelAgent.inc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/agents/ToplevelAgent.inc b/agents/ToplevelAgent.inc index c545975a..9d6d6f8a 100644 --- a/agents/ToplevelAgent.inc +++ b/agents/ToplevelAgent.inc @@ -153,6 +153,17 @@ } + /** + * Return the IntermediateAgent. + * + * @return IntermediateAgent IntermediateAgent + */ + public function getIntermediateAgent() + { + return $this->intermediateAgent; + } + + /** @@ -265,6 +276,7 @@ /** * Run the Controller of this Agent and its SubAgents. * + * @throws AccessDeniedException * @throws IdNotFoundException * @throws ServiceUnavailableException * @throws DatamodelException @@ -292,6 +304,7 @@ /** * Run IntermediateAgent. * + * @throws AccessDeniedException * @throws ParamsNotValidException * @throws IdNotFoundException * @throws ServiceUnavailableException From 200b1fe93778e7513b28947c5b8c62eafac8034f Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:35:32 +0200 Subject: [PATCH 16/34] change visibility of some properties and methods of core classes from private to protected --- core/Controller.inc | 6 +++--- core/View.inc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/Controller.inc b/core/Controller.inc index 55a7675a..c2814e99 100644 --- a/core/Controller.inc +++ b/core/Controller.inc @@ -30,7 +30,7 @@ * * @var View */ - private $view = null; + protected $view = null; /** * Data to pass to the View * @@ -348,7 +348,7 @@ * @throws ModelNotValidException * @throws ModelNotFoundException */ - private function loadModels() + protected function loadModels() { // Determine Models $explicit = false; @@ -403,7 +403,7 @@ * @param string $layoutName Name of the current Layout * @param string $action Current Action */ - private function loadView($layoutName, $action) + protected function loadView($layoutName, $action) { // Check Layout name if(is_null($layoutName)) { diff --git a/core/View.inc b/core/View.inc index 513bd953..546ddb6e 100644 --- a/core/View.inc +++ b/core/View.inc @@ -26,7 +26,7 @@ * * @var string */ - private $templateFilename; + protected $templateFilename; @@ -57,7 +57,7 @@ * @param string $action Current Action * @param bool $isToplevel Agent is a ToplevelAgent */ - private function __construct($layoutName, $agentName=null, $action=null, $isToplevel=false) + protected function __construct($layoutName, $agentName=null, $action=null, $isToplevel=false) { // Create template filename // LayoutName From 6a5f3739ccf4bc90c46f7db1072dbb778b1f831f Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:36:17 +0200 Subject: [PATCH 17/34] also load Components of parent classes --- core/Controller.inc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/core/Controller.inc b/core/Controller.inc index c2814e99..47b5e0a5 100644 --- a/core/Controller.inc +++ b/core/Controller.inc @@ -165,10 +165,6 @@ // Response speichern $this->response = $response; - - // Linker erstellen - $this->set('linker', new \nre\core\Linker($request)); - } @@ -325,6 +321,15 @@ if(!is_array($components)) { $components = array($components); } + // Components of parent classes + $parent = $this; + while($parent = get_parent_class($parent)) + { + $properties = get_class_vars($parent); + if(array_key_exists('components', $properties)) { + $components = array_merge($components, $properties['components']); + } + } // Load components foreach($components as &$component) From 32af66a3e7da2d8353f34550e0c81b2d2f8f23ba Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:36:55 +0200 Subject: [PATCH 18/34] correct string comparison for layout --- core/View.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/View.inc b/core/View.inc index 546ddb6e..554a8805 100644 --- a/core/View.inc +++ b/core/View.inc @@ -63,7 +63,7 @@ // LayoutName $fileName = ROOT.DS. \nre\configs\CoreConfig::getClassDir('views').DS. strtolower($layoutName).DS; // AgentName and Action - if(strtolower($agentName) != $layoutName || !$isToplevel) { + if(strtolower($agentName) != strtolower($layoutName) || !$isToplevel) { $fileName .= strtolower($agentName).DS.strtolower($action); } else { From fa8b0cadcdcddf4f8309bc6676aac47696b2453b Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:37:25 +0200 Subject: [PATCH 19/34] improve Linker --- core/Linker.inc | 93 ++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/core/Linker.inc b/core/Linker.inc index 5496d2b9..a29c5b81 100644 --- a/core/Linker.inc +++ b/core/Linker.inc @@ -43,72 +43,61 @@ /** - * Process a title and optional a date to create link parameters. + * Mask parameters to be used in an URL. * - * @param string $title Titel - * @param string $date Date - * @return string Created link parameters + * @param string $param1 First parameter + * @return string Masked parameters as string */ - public static function getLinkParams($title, $date=null) + public static function createLinkParam($param1) { - // Parameters - $param = ''; - - // Mask special sign seperately - $specials = array('/', '?', '&'); - foreach($specials as &$special) { - $title = str_replace($special, rawurlencode(rawurlencode($special)), $title); - } - - // Process title - $param .= str_replace( - ' ', - '-', - substr( - $title, - 0, - \nre\configs\CoreConfig::$classes['linker']['url']['length'] + return implode( + \nre\configs\CoreConfig::$classes['linker']['url']['delimiter'], + call_user_func_array( + '\nre\core\Linker::createLinkParams', + func_get_args() ) ); - - // Process date - if(!empty($date)) { - $param = substr($date, 0, 10).\nre\configs\CoreConfig::$classes['linker']['url']['delimiter'].$param; - } - - - // Mask and return parameters - return array(rawurlencode($param)); } /** - * Extract date and title from a parameter string. + * Mask parameters to be used in an URL. * - * @param string $dateTitle Parameter string with date and title - * @return array Extracted date and title as associative array + * @param string $param1 First parameter + * @return string Masked parameters as array */ - public static function extractDateTitle($dateTitle) + public static function createLinkParams($param1) { - // Get delimiter - $delimiter = \nre\configs\CoreConfig::$classes[strtolower(get_class())]['url']['delimiter']; + // Parameters + $linkParams = array(); + $params = func_get_args(); - // Split - $dateTitle = explode($delimiter, $dateTitle); - if(count($dateTitle) < 4) { - throw new IdNotFoundException(implode($delimiter, $dateTitle)); + foreach($params as $param) + { + // Delete critical signs + $specials = array('/', '?', '&', '#'); + foreach($specials as &$special) { + $param = str_replace($special, '', $param); + } + + // Process parameter + $param = str_replace( + ' ', + \nre\configs\CoreConfig::$classes['linker']['url']['delimiter'], + substr( + $param, + 0, + \nre\configs\CoreConfig::$classes['linker']['url']['length'] + ) + ); + + // Encode parameter + $linkParams[] = $param; } - - // Get parts - $date = urldecode(implode($delimiter, array_slice($dateTitle, 0, 3))); - $title = urldecode(implode($delimiter, array_slice($dateTitle, 3))); - // Return date and title - return array( - 'date' => $date, - 'title' => $title - ); + // Return link parameters + return $linkParams; } @@ -148,7 +137,6 @@ if(count($reqParams) < $offset && $offset > 1) { $reqParams[] = $this->request->getParam(2, 'action'); } - $params = array_map('rawurlencode', $params); $params = array_merge($reqParams, $params); // Use Layout @@ -170,6 +158,9 @@ ); } + // Encode parameters + $params = array_map('rawurlencode', $params); + // Set parameters call_user_func_array( array( From 4ee829ca3e0bd3089b4d058b4ef543838ec3072c Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:38:22 +0200 Subject: [PATCH 20/34] ignore logs --- .hgignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .hgignore diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..0f1ecac4 --- /dev/null +++ b/.hgignore @@ -0,0 +1,2 @@ +syntax: regexp +^logs/* From 2c0f540f90818c3e5c646445748c16ab6cb6d3b1 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:40:27 +0200 Subject: [PATCH 21/34] increase size of URL params --- configs/CoreConfig.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/CoreConfig.inc b/configs/CoreConfig.inc index a28b6dbc..45bc7e4a 100644 --- a/configs/CoreConfig.inc +++ b/configs/CoreConfig.inc @@ -103,7 +103,7 @@ public static $classes = array( 'linker' => array( 'url' => array( - 'length' => 50, + 'length' => 128, 'delimiter' => '-' ) ) From bf679e9decca9aa0a8bb4412161ed8bdf316a2a3 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sat, 9 Aug 2014 00:51:30 +0200 Subject: [PATCH 22/34] correct rewrite rule flags --- .htaccess | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index 69ec321e..e4f344e9 100644 --- a/.htaccess +++ b/.htaccess @@ -39,5 +39,5 @@ ErrorDocument 500 /www/error500.html RewriteEngine On - RewriteRule ^(.*)$ www/$1 [QSA,N] + RewriteRule ^(.*)$ www/$1 [L] From b8d4342926d2cc540f0d2b940f304fe3d5e869ab Mon Sep 17 00:00:00 2001 From: coderkun Date: Tue, 16 Sep 2014 12:42:19 +0200 Subject: [PATCH 23/34] correct typos in doc-tags and add missing tags --- agents/IntermediateAgent.inc | 3 ++- agents/ToplevelAgent.inc | 2 +- apis/WebApi.inc | 2 +- core/Agent.inc | 9 +++++---- core/Api.inc | 2 +- core/ClassLoader.inc | 2 +- core/Controller.inc | 1 + core/Driver.inc | 1 + exceptions/ClassNotFoundException.inc | 2 ++ exceptions/ClassNotValidException.inc | 2 ++ responses/WebResponse.inc | 2 +- www/index.php | 6 ++++++ 12 files changed, 24 insertions(+), 10 deletions(-) diff --git a/agents/IntermediateAgent.inc b/agents/IntermediateAgent.inc index 7139653d..05dab225 100644 --- a/agents/IntermediateAgent.inc +++ b/agents/IntermediateAgent.inc @@ -27,7 +27,8 @@ /** * Get the layout if it was explicitly defined. * - * @return string Layout of the IntermediateAgent + * @param string $agentName Name of Agent to get Layout for + * @return string Layout of the IntermediateAgent */ public static function getLayout($agentName) { diff --git a/agents/ToplevelAgent.inc b/agents/ToplevelAgent.inc index 9d6d6f8a..d8b21da5 100644 --- a/agents/ToplevelAgent.inc +++ b/agents/ToplevelAgent.inc @@ -74,7 +74,7 @@ * @throws ControllerNotValidException * @throws ControllerNotFoundException * @param Request $request Current request - * @param Response $respone Current response + * @param Response $response Current response * @param Logger $log Log-system */ protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) diff --git a/apis/WebApi.inc b/apis/WebApi.inc index 6851ee2d..3d6d1b8b 100644 --- a/apis/WebApi.inc +++ b/apis/WebApi.inc @@ -223,7 +223,7 @@ * Handle a error which cannot be handles by the system (and * HTTP 503). * - * $param Exception $exception Occurred exception + * @param \Exception $exception Occurred exception */ private function errorService($exception) { diff --git a/core/Agent.inc b/core/Agent.inc index 00ec1a90..64807338 100644 --- a/core/Agent.inc +++ b/core/Agent.inc @@ -107,7 +107,7 @@ * @throws ControllerNotFoundException * @param string $agentName Name of the Agent to instantiate * @param Request $request Current request - * @param Response $respone Current respone + * @param Response $response Current response * @param Logger $log Log-system */ public static function factory($agentName, Request $request, Response $response, Logger $log=null) @@ -165,7 +165,7 @@ * @throws ControllerNotValidException * @throws ControllerNotFoundException * @param Request $request Current request - * @param Response $respone Current response + * @param Response $response Current response * @param Logger $log Log-system */ protected function __construct(Request $request, Response $response, Logger $log=null) @@ -500,8 +500,9 @@ /** * Handle the exception of a SubAgent. * - * @param string $label Name of the original Agent - * @param Excepiton $exception Occurred exception + * @param Agent $subAgent SubAgent to handle error of + * @param Request $request Current request + * @param Exception $exception Occurred exception * @return array InlineError-SubAgent */ private function errorInline($subAgent, $request, $exception) diff --git a/core/Api.inc b/core/Api.inc index b89b12e7..89da30ba 100644 --- a/core/Api.inc +++ b/core/Api.inc @@ -54,7 +54,7 @@ * Construct a new API. * * @param Request $request Current request - * @param Response $respone Current response + * @param Response $response Current response */ public function __construct(Request $request, Response $response) { diff --git a/core/ClassLoader.inc b/core/ClassLoader.inc index 81cf537a..03570ea2 100644 --- a/core/ClassLoader.inc +++ b/core/ClassLoader.inc @@ -27,7 +27,7 @@ * Load a class. * * @throws ClassNotFoundException - * @param string $className Name of the class to load + * @param string $fullClassName Name of the class to load */ public static function load($fullClassName) { diff --git a/core/Controller.inc b/core/Controller.inc index 47b5e0a5..2a865d53 100644 --- a/core/Controller.inc +++ b/core/Controller.inc @@ -93,6 +93,7 @@ * @param string $controllerName Name of the Controller to instantiate * @param string $layoutName Name of the current Layout * @param string $action Current Action + * @param string $agent Name of Agent */ public static function factory($controllerName, $layoutName, $action, $agent) { diff --git a/core/Driver.inc b/core/Driver.inc index eec59143..8172e587 100644 --- a/core/Driver.inc +++ b/core/Driver.inc @@ -55,6 +55,7 @@ * Instantiate a Driver (Factory Pattern). * * @param string $driverName Name of the Driver to instantiate + * @param mixed $config Driver configuration */ public static function factory($driverName, $config) { diff --git a/exceptions/ClassNotFoundException.inc b/exceptions/ClassNotFoundException.inc index 070f383f..029c3c93 100644 --- a/exceptions/ClassNotFoundException.inc +++ b/exceptions/ClassNotFoundException.inc @@ -46,6 +46,8 @@ * Construct a new exception * * @param string $className Name of the class that was not found + * @param string $message Error message (superclass) + * @param int $code Error code (superclass) */ function __construct($className, $message=self::MESSAGE, $code=self::CODE) { diff --git a/exceptions/ClassNotValidException.inc b/exceptions/ClassNotValidException.inc index bdd36d5e..212f30df 100644 --- a/exceptions/ClassNotValidException.inc +++ b/exceptions/ClassNotValidException.inc @@ -46,6 +46,8 @@ * Construct a new exception. * * @param string $className Name of the invalid class + * @param string $message Error message (superclass) + * @param int $code Error code (superclass) */ function __construct($className, $message=self::MESSAGE, $code=self::CODE) { diff --git a/responses/WebResponse.inc b/responses/WebResponse.inc index 2ca25079..bfe13a9e 100644 --- a/responses/WebResponse.inc +++ b/responses/WebResponse.inc @@ -160,7 +160,7 @@ /** * Get a GET-parameter. * - * @param int $index Index of GET-parameter + * @param int $key Index of GET-parameter * @param string $defaultIndex Index of default configuration value for this parameter * @return string Value of GET-parameter */ diff --git a/www/index.php b/www/index.php index 46301a31..728c9ca4 100644 --- a/www/index.php +++ b/www/index.php @@ -14,10 +14,16 @@ */ // Directory separator if(!defined('DS')) { + /** + * @internal + */ define('DS', DIRECTORY_SEPARATOR); } // Root directory if(!defined('ROOT')) { + /** + * @internal + */ define('ROOT', dirname(dirname(__FILE__))); } From 1c48c6d10a6017a5b083f483763b3b5901f03f1a Mon Sep 17 00:00:00 2001 From: coderkun Date: Tue, 16 Sep 2014 12:44:30 +0200 Subject: [PATCH 24/34] add PHPDoc configuration --- doc/empty | 0 phpdoc.xml | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 doc/empty create mode 100644 phpdoc.xml diff --git a/doc/empty b/doc/empty new file mode 100644 index 00000000..e69de29b diff --git a/phpdoc.xml b/phpdoc.xml new file mode 100644 index 00000000..92acb2ed --- /dev/null +++ b/phpdoc.xml @@ -0,0 +1,33 @@ + + + + NRE + doc + + TODO + + php + inc + + + doc + + + info + + logs/phpdoc.log + logs/phpdoc.errors.log + + + + . + doc/* + logs/* + + + + + +