current state as framework

This commit is contained in:
coderkun 2013-08-09 02:41:06 +02:00
commit b392eb9188
56 changed files with 5981 additions and 0 deletions

30
.htaccess Normal file
View file

@ -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
<Files ~ "\.inc$">
Order Deny,Allow
Deny From All
</Files>
<Files ~ "\.tpl$">
Order Deny,Allow
Deny From All
</Files>
<Files ~ "\.log$">
Order Deny,Allow
Deny From All
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^(.*)$ www/$1 [L]
</IfModule>

View file

@ -0,0 +1,53 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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());
}
}
}
?>

View file

@ -0,0 +1,48 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

379
agents/ToplevelAgent.inc Normal file
View file

@ -0,0 +1,379 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
}
?>

0
agents/bottomlevel/empty Normal file
View file

View file

0
agents/toplevel/empty Normal file
View file

245
apis/WebApi.inc Normal file
View file

@ -0,0 +1,245 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

0
app/empty Normal file
View file

33
bootstrap.inc Normal file
View file

@ -0,0 +1,33 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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();
?>

75
configs/AppConfig.inc Normal file
View file

@ -0,0 +1,75 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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('<pattern>', '<replace>', '<is_last>')
);
/**
* Reverse routes
*
* @static
* @var array
*/
public static $reverseRoutes = array(
//array('<pattern>', '<replace>', '<is_last>')
);
}
?>

167
configs/CoreConfig.inc Normal file
View file

@ -0,0 +1,167 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

0
controllers/empty Normal file
View file

607
core/Agent.inc Normal file
View file

@ -0,0 +1,607 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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');
}
}
?>

163
core/Api.inc Normal file
View file

@ -0,0 +1,163 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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
);
}
}
?>

98
core/Autoloader.inc Normal file
View file

@ -0,0 +1,98 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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));
}
}
?>

129
core/ClassLoader.inc Normal file
View file

@ -0,0 +1,129 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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()
));
}
}
?>

49
core/Config.inc Normal file
View file

@ -0,0 +1,49 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

381
core/Controller.inc Normal file
View file

@ -0,0 +1,381 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
?>

96
core/Driver.inc Normal file
View file

@ -0,0 +1,96 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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()
{
}
}
?>

65
core/Exception.inc Normal file
View file

@ -0,0 +1,65 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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";
}
}
?>

322
core/Linker.inc Normal file
View file

@ -0,0 +1,322 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

116
core/Logger.inc Normal file
View file

@ -0,0 +1,116 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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<br>\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;
}
}
?>

140
core/Model.inc Normal file
View file

@ -0,0 +1,140 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
}
?>

64
core/Request.inc Normal file
View file

@ -0,0 +1,64 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
?>

158
core/Response.inc Normal file
View file

@ -0,0 +1,158 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

124
core/View.inc Normal file
View file

@ -0,0 +1,124 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

68
core/WebUtils.inc Normal file
View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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]);
}
}
?>

View file

@ -0,0 +1,81 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

153
drivers/MysqlDriver.inc Normal file
View file

@ -0,0 +1,153 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,67 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,67 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,99 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,96 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,67 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,67 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,68 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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();
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

0
logs/empty Normal file
View file

129
models/DatabaseModel.inc Normal file
View file

@ -0,0 +1,129 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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);
}
}
}
?>

358
requests/WebRequest.inc Normal file
View file

@ -0,0 +1,358 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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;
}
}
?>

250
responses/WebResponse.inc Normal file
View file

@ -0,0 +1,250 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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 <olli@coderkun.de>
*/
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
);
}
}
?>

13
views/error.tpl Normal file
View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Service Unavailable</title>
</head>
<body>
<p>Die Anwendung steht zur Zeit leider nicht zur Verfügung.</p>
</body>
</html>

1
views/inlineerror.tpl Normal file
View file

@ -0,0 +1 @@
<p>Dieser Teil der Anwendung steht zur Zeit leider nicht zur Verfügung.</p>

8
www/.htaccess Normal file
View file

@ -0,0 +1,8 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L,NE]
</IfModule>

45
www/index.php Normal file
View file

@ -0,0 +1,45 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @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';
?>