Questtype ?Textinput?: add support for field sizes (Issue #252) and general improvements
This commit is contained in:
commit
8d903135a5
3476 changed files with 599099 additions and 0 deletions
607
core/Agent.inc
Normal file
607
core/Agent.inc
Normal 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
|
||||
\nre\agents\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' => \nre\agents\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
|
||||
\nre\agents\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');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue