commit 046a724272ae30596190ed39ddf07fdd222c8d14 Author: coderkun Date: Mon Apr 27 16:42:05 2015 +0200 merge diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..776ca1b5 --- /dev/null +++ b/.hgignore @@ -0,0 +1,9 @@ +syntax: regexp +^logs/* +^media/* +^tmp/* +^uploads/* +^seminarymedia/* +^seminaryuploads/* +^www/analytics/config/config.ini.php* +^www/analytics/temp/* diff --git a/.htaccess b/.htaccess new file mode 100644 index 00000000..c1167dbf --- /dev/null +++ b/.htaccess @@ -0,0 +1,44 @@ +Options -Indexes -MultiViews + +ErrorDocument 403 /www/error403.html +ErrorDocument 404 /www/error404.html +ErrorDocument 500 /www/error500.html + + + + Require all granted + + + Require all denied + + + Require all denied + + + Require all denied + + + + Allow From All + + + Order Deny,Allow + Deny From All + + + Order Deny,Allow + Deny From All + + + Order Deny,Allow + Deny From All + + + + + + RewriteEngine On + + RewriteBase / + RewriteRule ^(.*)$ www/$1 [L] + diff --git a/agents/BottomlevelAgent.inc b/agents/BottomlevelAgent.inc new file mode 100644 index 00000000..648c1fb7 --- /dev/null +++ b/agents/BottomlevelAgent.inc @@ -0,0 +1,25 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The BottomlevelAgent is the standard Agent and can have indefinite + * SubAgents. + * + * @author coderkun + */ + abstract class BottomlevelAgent extends \nre\core\Agent + { + } + +?> diff --git a/agents/IntermediateAgent.inc b/agents/IntermediateAgent.inc new file mode 100644 index 00000000..4828cfbb --- /dev/null +++ b/agents/IntermediateAgent.inc @@ -0,0 +1,49 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The IntermediateAgent assumes the task of a module. There is only one + * IntermediateAgent per request. + * + * @author coderkun + */ + abstract class IntermediateAgent extends \nre\core\Agent + { + + + + + /** + * Get the layout if it was explicitly defined. + * + * @param string $agentName Agent name + * @return string Layout of the IntermediateAgent + */ + public static function getLayout($agentName) + { + // Determine classname + $className = Autoloader::concatClassNames($agentName, 'Agent'); + + // Check property + if(isset($className::$layout)) { + return $className::$layout; + } + + + return null; + } + + } + +?> diff --git a/agents/ToplevelAgent.inc b/agents/ToplevelAgent.inc new file mode 100644 index 00000000..0c4e64ea --- /dev/null +++ b/agents/ToplevelAgent.inc @@ -0,0 +1,395 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\agents; + + + /** + * The ToplevelAgent assumes the task of a FrontController. There is + * only one per request. + * + * @author coderkun + */ + class ToplevelAgent extends \nre\core\Agent + { + /** + * Stage: Load + * + * @var string + */ + const STAGE_LOAD = 'load'; + /** + * Stage: Run + * + * @var string + */ + const STAGE_RUN = 'run'; + + /** + * Current request + * + * @var \nre\core\Request + */ + private $request; + /** + * Current response + * + * @var \nre\core\Response + */ + private $response; + /** + * Layout instace + * + * @var \nre\core\Layout + */ + private $layout = null; + /** + * IntermediateAgent instance + * + * @var IntermediateAgent + */ + private $intermediateAgent = null; + + + + + /** + * Construct a ToplevelAgent. + * + * @throws \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ControllerNotValidException + * @throws \nre\exceptions\ControllerNotFoundException + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\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 \nre\exceptions\ServiceUnavailableException + * @param \nre\core\Request $request Current request + * @param \nre\core\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(\nre\exceptions\AccessDeniedException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_FORBIDDEN, self::STAGE_RUN); + } + catch(\nre\exceptions\ParamsNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + catch(\nre\exceptions\IdNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE, self::STAGE_RUN); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND, self::STAGE_RUN); + } + } + + + /** + * 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); + } + + + /** + * Return the IntermediateAgent. + * + * @return \nre\agents\IntermediateAgent IntermediateAgent + */ + public function getIntermediateAgent() + { + return $this->intermediateAgent; + } + + + + + /** + * Load a SubAgent and add it. + * + * @throws \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\FatalDatamodelException + * @throws \nre\exceptions\AgentNotFoundException + * @throws \nre\exceptions\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(\nre\exceptions\DatamodelException $e) { + throw new \nre\exceptions\FatalDatamodelException($e->getDatamodelMessage(), $e->getDatamodelErrorNumber()); + } + } + + + + + /** + * Load IntermediateAgent defined by the current request. + * + * @throws \nre\exceptions\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 \nre\exceptions\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 \nre\exceptions\AccessDeniedException + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\DatamodelException + * @param \nre\core\Request $request Current request + * @param \nre\core\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 \nre\exceptions\AccessDeniedException + * @throws \nre\exceptions\ParamsNotValidException + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\DatamodelException + */ + private function runIntermediateAgent() + { + $this->intermediateAgent->run( + $this->request, + $this->response + ); + } + + + /** + * Handle an error that occurred during + * loading/cnostructing/running of the IntermediateAgent. + * + * @throws \nre\exceptions\ServiceUnavailableException + * @param \Exception $exception Occurred exception + * @param int $httpStatusCode HTTP-statuscode + * @param string $stage Stage of execution + */ + private function error($exception, $httpStatusCode, $stage=self::STAGE_LOAD) + { + // Log error + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + + try { + // Define ErrorAgent + $this->response->clearParams(1); + $this->response->addParams( + \nre\configs\AppConfig::$defaults['intermediate-error'], + \nre\configs\CoreConfig::$defaults['action'], + $httpStatusCode + ); + + // Load ErrorAgent + $this->_loadIntermediateAgent(); + + // Run ErrorAgent + if($stage == self::STAGE_RUN) { + $this->_run($this->request, $this->response); + } + } + catch(\nre\exceptions\ActionNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DatamodelException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DriverNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ModelNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\AgentNotValidException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + catch(Exception $e) { + throw new \nre\exceptions\ServiceUnavailableException($e); + } + } + + + } + +?> diff --git a/agents/bottomlevel/MailreceiverAgent.inc b/agents/bottomlevel/MailreceiverAgent.inc new file mode 100644 index 00000000..5ebffd3a --- /dev/null +++ b/agents/bottomlevel/MailreceiverAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to generate a mail receiver salutation. + * + * @author Oliver Hanraths + */ + class MailreceiverAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/bottomlevel/MenuAgent.inc b/agents/bottomlevel/MenuAgent.inc new file mode 100644 index 00000000..0f0dc60d --- /dev/null +++ b/agents/bottomlevel/MenuAgent.inc @@ -0,0 +1,40 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to display a menu. + * + * @author Oliver Hanraths + */ + class MenuAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + // Add Seminary menu + $this->addSubAgent('Seminarymenu'); + } + + } + +?> diff --git a/agents/bottomlevel/QuestgroupshierarchypathAgent.inc b/agents/bottomlevel/QuestgroupshierarchypathAgent.inc new file mode 100644 index 00000000..36b84474 --- /dev/null +++ b/agents/bottomlevel/QuestgroupshierarchypathAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to display the Questgroups hierarchy path. + * + * @author Oliver Hanraths + */ + class QuestgroupshierarchypathAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/bottomlevel/SeminarybarAgent.inc b/agents/bottomlevel/SeminarybarAgent.inc new file mode 100644 index 00000000..2f43e474 --- /dev/null +++ b/agents/bottomlevel/SeminarybarAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to display a sidebar with Seminary related information. + * + * @author Oliver Hanraths + */ + class SeminarybarAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/bottomlevel/SeminarymenuAgent.inc b/agents/bottomlevel/SeminarymenuAgent.inc new file mode 100644 index 00000000..1c55e419 --- /dev/null +++ b/agents/bottomlevel/SeminarymenuAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to display a menu with Seminary related links. + * + * @author Oliver Hanraths + */ + class SeminarymenuAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/bottomlevel/UserrolesAgent.inc b/agents/bottomlevel/UserrolesAgent.inc new file mode 100644 index 00000000..1186eff4 --- /dev/null +++ b/agents/bottomlevel/UserrolesAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\bottomlevel; + + + /** + * Agent to display and manage userroles. + * + * @author Oliver Hanraths + */ + class UserrolesAgent extends \nre\agents\BottomlevelAgent + { + + + + + /** + * Action: user. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function user(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/bottomlevel/empty b/agents/bottomlevel/empty new file mode 100644 index 00000000..e69de29b diff --git a/agents/intermediate/AchievementsAgent.inc b/agents/intermediate/AchievementsAgent.inc new file mode 100644 index 00000000..de829ee1 --- /dev/null +++ b/agents/intermediate/AchievementsAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to list Achievements. + * + * @author Oliver Hanraths + */ + class AchievementsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/CharactergroupsAgent.inc b/agents/intermediate/CharactergroupsAgent.inc new file mode 100644 index 00000000..02b8244a --- /dev/null +++ b/agents/intermediate/CharactergroupsAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to display Character groups. + * + * @author Oliver Hanraths + */ + class CharactergroupsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/CharactergroupsquestsAgent.inc b/agents/intermediate/CharactergroupsquestsAgent.inc new file mode 100644 index 00000000..3e5e17d1 --- /dev/null +++ b/agents/intermediate/CharactergroupsquestsAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to display Character groups Quests. + * + * @author Oliver Hanraths + */ + class CharactergroupsquestsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/CharactersAgent.inc b/agents/intermediate/CharactersAgent.inc new file mode 100644 index 00000000..0bbfa315 --- /dev/null +++ b/agents/intermediate/CharactersAgent.inc @@ -0,0 +1,49 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to list registered Characters and their data. + * + * @author Oliver Hanraths + */ + class CharactersAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + + /** + * Action: character. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function character(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/CharactertypesAgent.inc b/agents/intermediate/CharactertypesAgent.inc new file mode 100644 index 00000000..8c2693bb --- /dev/null +++ b/agents/intermediate/CharactertypesAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to handle Charactertyes of a Seminary. + * + * @author Oliver Hanraths + */ + class CharactertypesAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/ErrorAgent.inc b/agents/intermediate/ErrorAgent.inc new file mode 100644 index 00000000..5554c417 --- /dev/null +++ b/agents/intermediate/ErrorAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to show an error page. + * + * @author Oliver Hanraths + */ + class ErrorAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/IntroductionAgent.inc b/agents/intermediate/IntroductionAgent.inc new file mode 100644 index 00000000..1ee6483a --- /dev/null +++ b/agents/intermediate/IntroductionAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to show an introduction page. + * + * @author Oliver Hanraths + */ + class IntroductionAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/LibraryAgent.inc b/agents/intermediate/LibraryAgent.inc new file mode 100644 index 00000000..b3105be9 --- /dev/null +++ b/agents/intermediate/LibraryAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to list Quest topics. + * + * @author Oliver Hanraths + */ + class LibraryAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/MailAgent.inc b/agents/intermediate/MailAgent.inc new file mode 100644 index 00000000..34dcc512 --- /dev/null +++ b/agents/intermediate/MailAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to generate a mail-message. + * + * @author Oliver Hanraths + */ + class MailAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/MapAgent.inc b/agents/intermediate/MapAgent.inc new file mode 100644 index 00000000..1fd0eb00 --- /dev/null +++ b/agents/intermediate/MapAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to display a map. + * + * @author Oliver Hanraths + */ + class MapAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/MediaAgent.inc b/agents/intermediate/MediaAgent.inc new file mode 100644 index 00000000..550380a8 --- /dev/null +++ b/agents/intermediate/MediaAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to process and show media. + * + * @author Oliver Hanraths + */ + class MediaAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/QuestgroupsAgent.inc b/agents/intermediate/QuestgroupsAgent.inc new file mode 100644 index 00000000..7f71eafa --- /dev/null +++ b/agents/intermediate/QuestgroupsAgent.inc @@ -0,0 +1,99 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to display Questgroups. + * + * @author Oliver Hanraths + */ + class QuestgroupsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: questgroup. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function questgroup(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + + /** + * Action: edit. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function edit(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + + /** + * Action: edittexts. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function edittexts(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + + /** + * Action: moveup. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function moveup(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + + /** + * Action: movedown. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function movedown(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + + /** + * Action: delete. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function delete(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4)); + } + + } + +?> diff --git a/agents/intermediate/QuestgroupshierarchyAgent.inc b/agents/intermediate/QuestgroupshierarchyAgent.inc new file mode 100644 index 00000000..b84f3953 --- /dev/null +++ b/agents/intermediate/QuestgroupshierarchyAgent.inc @@ -0,0 +1,24 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to manage Questgroupshierarchy. + * + * @author Oliver Hanraths + */ + class QuestgroupshierarchyAgent extends \nre\agents\IntermediateAgent + { + } + +?> diff --git a/agents/intermediate/QuestsAgent.inc b/agents/intermediate/QuestsAgent.inc new file mode 100644 index 00000000..1485d090 --- /dev/null +++ b/agents/intermediate/QuestsAgent.inc @@ -0,0 +1,123 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to display Quests. + * + * @author Oliver Hanraths + */ + class QuestsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: quest. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function quest(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: submissions. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function submissions(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: submission. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function submission(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: create. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function create(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: edit. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function edit(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: edittask. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function edittask(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: edittexts. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function edittexts(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + + /** + * Action: delete. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function delete(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Questgroupshierarchypath', 'index', $request->getParam(3), $request->getParam(4), true); + } + + } + +?> diff --git a/agents/intermediate/SeminariesAgent.inc b/agents/intermediate/SeminariesAgent.inc new file mode 100644 index 00000000..79901cfe --- /dev/null +++ b/agents/intermediate/SeminariesAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to list registered seminaries. + * + * @author Oliver Hanraths + */ + class SeminariesAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/UploadsAgent.inc b/agents/intermediate/UploadsAgent.inc new file mode 100644 index 00000000..ef01077e --- /dev/null +++ b/agents/intermediate/UploadsAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to process and show user uploads. + * + * @author Oliver Hanraths + */ + class UploadsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/UsersAgent.inc b/agents/intermediate/UsersAgent.inc new file mode 100644 index 00000000..9ba74df3 --- /dev/null +++ b/agents/intermediate/UsersAgent.inc @@ -0,0 +1,50 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to list registered users and their data. + * + * @author Oliver Hanraths + */ + class UsersAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + + /** + * Action: user. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function user(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubAgent('Userroles', 'user'); + } + + } + +?> diff --git a/agents/intermediate/XplevelsAgent.inc b/agents/intermediate/XplevelsAgent.inc new file mode 100644 index 00000000..dff540f3 --- /dev/null +++ b/agents/intermediate/XplevelsAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\intermediate; + + + /** + * Agent to handle XP-levels of a Seminary. + * + * @author Oliver Hanraths + */ + class XplevelsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/intermediate/empty b/agents/intermediate/empty new file mode 100644 index 00000000..e69de29b diff --git a/agents/toplevel/AjaxAgent.inc b/agents/toplevel/AjaxAgent.inc new file mode 100644 index 00000000..1ced33f1 --- /dev/null +++ b/agents/toplevel/AjaxAgent.inc @@ -0,0 +1,80 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent to return a JSON-string used by AJAX. + * + * @author Oliver Hanraths + */ + class AjaxAgent extends \hhu\z\agents\ToplevelAgent + { + + + + + /** + * Construct a new AjaxAgent. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + + + $this->setLanguage($request); + } + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + + + + /** + * Set requested language. + * + * @param \nre\core\Request $request Current request + */ + private function setLanguage(\nre\core\Request $request) + { + // Set domain + $domain = \nre\configs\AppConfig::$app['genericname']; + + // Get language + $locale = $request->getGetParam('lang', 'language'); + if(is_null($locale)) { + return; + } + + // Load translation + putenv("LC_ALL=$locale"); + setlocale(LC_ALL, $locale); + bindtextdomain($domain, ROOT.DS.\nre\configs\AppConfig::$dirs['locale']); + textdomain($domain); + } + + } + +?> diff --git a/agents/toplevel/BinaryAgent.inc b/agents/toplevel/BinaryAgent.inc new file mode 100644 index 00000000..55d494e3 --- /dev/null +++ b/agents/toplevel/BinaryAgent.inc @@ -0,0 +1,51 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent to display binary data (e. g. images). + * + * @author Oliver Hanraths + */ + class BinaryAgent extends \hhu\z\agents\ToplevelAgent + { + + + + + /** + * Construct a new BinaryAgent. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + } + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/toplevel/FaultAgent.inc b/agents/toplevel/FaultAgent.inc new file mode 100644 index 00000000..d289c041 --- /dev/null +++ b/agents/toplevel/FaultAgent.inc @@ -0,0 +1,38 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent to display a toplevel error page. + * + * @author Oliver Hanraths + */ + class FaultAgent extends \nre\agents\ToplevelAgent + { + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + } + + } + +?> diff --git a/agents/toplevel/HtmlAgent.inc b/agents/toplevel/HtmlAgent.inc new file mode 100644 index 00000000..34abd31d --- /dev/null +++ b/agents/toplevel/HtmlAgent.inc @@ -0,0 +1,156 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent to display a HTML-page. + * + * @author Oliver Hanraths + */ + class HtmlAgent extends \hhu\z\agents\ToplevelAgent + { + + + + + /** + * Construct a new HtmlAgent. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + + + $this->setLanguage($request); + } + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + // Add menu + $this->addSubAgent('Menu'); + + // Add Seminary sidebar + $this->addSubAgent('Seminarybar'); + } + + + + + /** + * Set requested language. + * + * @param \nre\core\Request $request Current request + */ + private function setLanguage(\nre\core\Request $request) + { + // Set domain + $domain = \nre\configs\AppConfig::$app['genericname']; + + // Get language + $locale = $this->determineLanguage($request); + + // Set Locale and Load translation + if(!is_null($locale)) + { + //$locale = sprintf('%s_%s.UTF-8', $locale, strtoupper($locale)); + putenv("LC_ALL=$locale"); + setlocale(LC_ALL, $locale); + \Locale::setDefault($locale); + + bindtextdomain($domain, ROOT.DS.\nre\configs\AppConfig::$dirs['locale']); + textdomain($domain); + } + } + + + /** + * Determine which language is either requested directly or by browser + * setting. + * + * @param \nre\core\Request $request Current request + * @return string Requested language or default one + */ + private function determineLanguage(\nre\core\Request $request) + { + // Get supported languages + $supportedLanguages = \nre\configs\AppConfig::$app['languages']; + if(empty($supportedLanguages)) { + return null; + } + + // Get requested language + $language = $request->getGetParam('lang', 'language'); + if(!is_null($language) && array_key_exists($language, $supportedLanguages)) { + return $language; + } + + // Negotiate language + return $this->negotiateLanguage($supportedLanguages, $request->getBrowserLanguages()); + } + + + /** + * Negotiate which language the browser wants most out of the supported + * languages. + * + * @param array $supportedLanguages List of supported languages + * @param array $browserLanguages List of browser languages + * @return string Negotiated language or default one + */ + private function negotiateLanguage($supportedLanguages, $browserLanguages) + { + if(!is_null($browserLanguages)) + { + // Create array with languages and their ratings + $parsedLanguages = array(); + $languages = explode(',', $browserLanguages); + foreach($languages as &$language) + { + if(($pos = strpos($language, ';q=')) !== false) { + $parsedLanguages[substr($language, 1, min(2, $pos-1))] = floatval(substr($language, $pos+3)); + } + else { + $parsedLanguages[$language] = 1.0; + } + } + + // Sort languages by their ratings + arsort($parsedLanguages); + + // Get highest supported language + foreach($parsedLanguages as $language => $rating) { + if(array_key_exists($language, $supportedLanguages)) { + return $supportedLanguages[$language]; + } + } + } + + + // Return default language + return $supportedLanguages[array_keys($supportedLanguages)[0]]; + } + + } + +?> diff --git a/agents/toplevel/HtmlmailAgent.inc b/agents/toplevel/HtmlmailAgent.inc new file mode 100644 index 00000000..001886cd --- /dev/null +++ b/agents/toplevel/HtmlmailAgent.inc @@ -0,0 +1,52 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent for generating a HTML-mail message. + * + * @author Oliver Hanraths + */ + class HtmlmailAgent extends \hhu\z\agents\ToplevelAgent + { + + + + + /** + * Construct a new HtmlmailAgent. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + } + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubagent('mailreceiver', 'index', $request->getParam(3)); + } + + } + +?> diff --git a/agents/toplevel/TextmailAgent.inc b/agents/toplevel/TextmailAgent.inc new file mode 100644 index 00000000..ec4c34b2 --- /dev/null +++ b/agents/toplevel/TextmailAgent.inc @@ -0,0 +1,54 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents\toplevel; + + + /** + * Agent for generating a simple text-mail message. + * + * @author Oliver Hanraths + */ + class TextmailAgent extends \hhu\z\agents\ToplevelAgent + { + + + + + /** + * Construct a new TextmailAgent. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + } + + + + + /** + * Action: index. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function index(\nre\core\Request $request, \nre\core\Response $response) + { + $this->addSubagent('mailreceiver', 'index', $request->getParam(3)); + } + + } + +?> diff --git a/agents/toplevel/empty b/agents/toplevel/empty new file mode 100644 index 00000000..e69de29b diff --git a/apis/WebApi.inc b/apis/WebApi.inc new file mode 100644 index 00000000..eafde955 --- /dev/null +++ b/apis/WebApi.inc @@ -0,0 +1,250 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\apis; + + + /** + * WebApi-implementation. + * + * This class runs and renders an web-applictaion. + * + * @author coderkun + */ + class WebApi extends \nre\core\Api + { + + + + + /** + * Construct a new WebApi. + */ + public function __construct() + { + parent::__construct( + new \nre\requests\WebRequest(), + new \nre\responses\WebResponse() + ); + + // Add routes + $this->addRoutes(); + + // Disable screen logging for AJAX requests + if($this->request->getParam(0, 'toplevel') == 'ajax') { + $this->log->disableAutoLogToScreen(); + } + } + + + + + /** + * 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, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\FatalDatamodelException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\AgentNoaatValidException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_SERVICE_UNAVAILABLE); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + $this->error($e, \nre\core\WebUtils::HTTP_NOT_FOUND); + } + catch(\nre\exceptions\ClassNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + $this->errorService($e); + } + } + + + /** + * Render output. + */ + public function render() + { + // Generate output + parent::render(); + + + // Set HTTP-header + $this->response->header(); + + // Show output + echo $this->response->getOutput(); + } + + + + + /** + * Add routes (normal and reverse) defined in the AppConfig. + */ + private function addRoutes() + { + // Normal routes + if(property_exists('\nre\configs\AppConfig', 'routes')) { + foreach(\nre\configs\AppConfig::$routes as &$route) { + $this->request->addRoute($route[0], $route[1], $route[2]); + } + } + + // Reverse routes + if(property_exists('\nre\configs\AppConfig', 'reverseRoutes')) { + foreach(\nre\configs\AppConfig::$reverseRoutes as &$route) { + $this->request->addReverseRoute($route[0], $route[1], $route[2]); + } + } + + // Revalidate request + $this->request->revalidate(); + } + + + /** + * Handle an error that orrcurred during the + * loading/constructing/running of the ToplevelAgent. + * + * @param \Exception $exception Occurred exception + * @param int $httpStatusCode HTTP-statuscode + */ + private function error(\nre\core\Exception $exception, $httpStatusCode) + { + // Log error message + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + try { + // Set agent for handling errors + $this->response->clearParams(); + $this->response->addParams( + \nre\configs\AppConfig::$defaults['toplevel-error'], + \nre\configs\AppConfig::$defaults['intermediate-error'], + \nre\configs\CoreConfig::$defaults['action'], + $httpStatusCode + ); + + // Run this agent + parent::run(); + } + catch(\nre\exceptions\ServiceUnavailableException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DriverNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\DriverNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ModelNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ModelNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ControllerNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\ControllerNotFoundException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\AgentNotValidException $e) { + $this->errorService($e); + } + catch(\nre\exceptions\AgentNotFoundException $e) { + $this->errorService($e); + } + catch(Exception $e) { + $this->errorService($e); + } + } + + + /** + * Handle a error which cannot be handles by the system (and + * HTTP 503). + * + * @param \Exception $exception Occurred exception + */ + private function errorService($exception) + { + // Log error message + $this->log($exception, \nre\core\Logger::LOGMODE_AUTO); + + // Set HTTP-rtatuscode + $this->response->addHeader(\nre\core\WebUtils::getHttpHeader(503)); + + + // Read and print static error file + $fileName = ROOT.DS.\nre\configs\CoreConfig::getClassDir('views').DS.\nre\configs\CoreConfig::$defaults['errorFile'].\nre\configs\CoreConfig::getFileExt('views'); + ob_start(); + include($fileName); + $this->response->setOutput(ob_get_clean()); + + + // Prevent further execution + $this->response->setExit(); + } + + } + +?> diff --git a/app/Controller.inc b/app/Controller.inc new file mode 100644 index 00000000..3603db23 --- /dev/null +++ b/app/Controller.inc @@ -0,0 +1,134 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z; + + + /** + * Abstract class for implementing an application Controller. + * + * @author Oliver Hanraths + */ + abstract class Controller extends \nre\core\Controller + { + /** + * Required components + * + * @var array + */ + public $components = array('auth'); + + /** + * Logger instance + * + * @var \nre\core\Logger + */ + protected $log = null; + /** + * Linker instance + * + * @var \nre\core\Linker + */ + protected $linker = null; + + + + + /** + * Construct a new application Controller. + * + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param \nre\core\Agent $agent Corresponding Agent + */ + public function __construct($layoutName, $action, $agent) + { + parent::__construct($layoutName, $action, $agent); + + // Create logger + $this->log = new \nre\core\Logger(); + } + + + + /** + * Prefilter that is executed before running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Create linker + $this->linker = new \nre\core\Linker($request); + $this->set('linker', $this->linker); + + // Create text formatter + $this->set('t', new \hhu\z\TextFormatter($this->linker)); + + // Create date and time and number formatter + $this->set('dateFormatter', new \IntlDateFormatter( + //\nre\core\Config::getDefault('locale'), + \Locale::getDefault(), + \IntlDateFormatter::MEDIUM, + \IntlDateFormatter::NONE, + NULL + )); + $this->set('timeFormatter', new \IntlDateFormatter( + //\nre\core\Config::getDefault('locale'), + \Locale::getDefault(), + \IntlDateFormatter::NONE, + \IntlDateFormatter::SHORT, + NULL + )); + $this->set('numberFormatter', new \NumberFormatter( + //\nre\core\Config::getDefault('locale'), + \Locale::getDefault(), + \NumberFormatter::DEFAULT_STYLE + )); + } + + + /** + * Postfilter that is executed after running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function postFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::postFilter($request, $response); + } + + + + + /** + * Log an error. + * + * @param string $message Error message to log + * @param int $logMode Log mode (optional) + */ + protected function log($message, $logMode=\nre\core\Logger::LOGMODE_AUTO) + { + $this->log->log($message, $logMode); + } + + } + +?> diff --git a/app/Model.inc b/app/Model.inc new file mode 100644 index 00000000..84ccb7d7 --- /dev/null +++ b/app/Model.inc @@ -0,0 +1,42 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z; + + + /** + * Abstract class for implementing an application Model. + * + * @author Oliver Hanraths + */ + class Model extends \nre\models\DatabaseModel + { + + + + + /** + * Construct a new application Model. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + */ + public function __construct() + { + parent::__construct('mysqli', \nre\configs\AppConfig::$database); + } + + } + +?> diff --git a/app/TextFormatter.inc b/app/TextFormatter.inc new file mode 100644 index 00000000..71adba90 --- /dev/null +++ b/app/TextFormatter.inc @@ -0,0 +1,149 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z; + + + /** + * Class to format text with different syntax tags. + * + * @author Oliver Hanraths + */ + class TextFormatter + { + /** + * Linker to create links. + * + * @var \nre\core\Linker + */ + private $linker; + /** + * Media-Model to retrieve media data + * + * @static + * @var \nre\core\Model + */ + private static $Media = null; + + + + + /** + * Create a new text formatter. + * + * @param \nre\core\Linker $linker Linker to create links with + */ + public function __construct(\nre\core\Linker $linker) + { + $this->linker = $linker; + } + + + + + /** + * Format a string. + * + * @param string $string String to format + * @return string Formatted string + */ + public function t($string) + { + // Remove chars + $string = htmlspecialchars($string, ENT_NOQUOTES); + + // Important text + $string = str_replace('[strong]', '', $string); + $string = str_replace('[/strong]', '', $string); + + // Create tables + $string = preg_replace('/(\[table\])\s+/u', '$1', $string); + $string = preg_replace('/\s*(\[tr\])\s*/u', '$1', $string); + $string = preg_replace('%\s+(\[/table\])%u', '$1', $string); + $string = preg_replace('%\s*(\[/tr\])\s*%u', '$1', $string); + $string = str_replace('[table]', '

', $string); + $string = str_replace('[/table]', '

', $string); + $string = str_replace('[tr]', '', $string); + $string = str_replace('[/tr]', '', $string); + $string = str_replace('[th]', '', $string); + $string = str_replace('[/th]', '', $string); + $string = str_replace('[td]', '', $string); + $string = str_replace('[/td]', '', $string); + + // Create links + $string = preg_replace('!(^|\s)"([^"]+)":(https?://[^\s]+)(\s|$)!i', '$1$2$4', $string); + $string = preg_replace('!(^|\s)(https?://[^\s]+)(\s|$)!i', '$1$2$3', $string); + + // Handle Seminarymedia + $seminarymedia = array(); + preg_match_all('/\[seminarymedia:(\d+)\]/iu', $string, $matches); //, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); + $seminarymediaIds = array_unique($matches[1]); + foreach($seminarymediaIds as &$seminarymediaId) + { + $replacement = null; + if(!is_null(\hhu\z\controllers\SeminaryController::$seminary) && $this->loadMediaModel()) + { + try { + $medium = self::$Media->getSeminaryMediaById($seminarymediaId); + $replacement = sprintf( + '%s', + $this->linker->link(array('media','seminary', \hhu\z\controllers\SeminaryController::$seminary['url'],$medium['url'])), + $medium['description'] + ); + } + catch(\nre\exceptions\IdNotFoundException $e) { + } + } + + $seminarymedia[$seminarymediaId] = $replacement; + } + foreach($seminarymedia as $seminarymediaId => $replacement) { + $string = str_replace("[seminarymedia:$seminarymediaId]", $replacement, $string); + } + + + // Return processed string + return nl2br($string); + } + + + + + /** + * Load the Media-Model if it is not loaded + * + * @return boolean Whether the Media-Model has been loaded or not + */ + private function loadMediaModel() + { + // Do not load Model if it has already been loaded + if(!is_null(self::$Media)) { + return true; + } + + try { + // Load class + Model::load('media'); + + // Construct Model + self::$Media = Model::factory('media'); + } + catch(\Exception $e) { + } + + + // Return whether Media-Model has been loaded or not + return !is_null(self::$Media); + } + + } + +?> diff --git a/app/Utils.inc b/app/Utils.inc new file mode 100644 index 00000000..397eb029 --- /dev/null +++ b/app/Utils.inc @@ -0,0 +1,214 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z; + + + /** + * Class for implementing utility methods. + * + * @author Oliver Hanraths + */ + class Utils + { + + + /** + * Mask HTML-chars for save output. + * + * @static + * @param string $string String to be masked + * @return string Masked string + */ + public static function t($string) + { + return nl2br(htmlspecialchars($string)); + } + + + /** + * ‚htmlspecialchars‘ with support for UTF-8. + * + * @static + * @param string $string String to be masked + * @return string Masked string + */ + public static function htmlspecialchars_utf8($string) + { + return htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); + } + + + /** + * Cut a string to the given length but only word boundaries. + * + * @static + * @param string $string String to cut + * @param int $length Length to cut string + * @param int $scope Maximum length to cut string regardless word boundaries + * @return string Cutted string + */ + public static function shortenString($string, $length, $scope) + { + // Determine length + $length = min($length, strlen($string)); + + // Look for word boundary + if(($pos = strpos($string, ' ', $length)) !== false) + { + // Check if boundary is outside of scope + if($pos > $length + $scope) { + $pos = strrpos(substr($string, 0, $pos), ' '); + } + } + else { + $pos = strlen($string); + } + + + // Cut string and return it + return substr($string, 0, $pos); + } + + + /** + * Send an e‑mail. + * + * @throws \hhu\z\exceptions\MailingException + * @param mixed $to One (string) or many (array) receivers + * @param string $messageAction Message Action + * @param boolean $html Whether mail should be formatted as HTML or not + * @param array $params Parameters to pass + * @param \nre\core\Linker $linker Linker instance + */ + public static function sendMail($to, $messageAction, $html=false, $params=null, $linker=null) + { + // Check configuration + if( + empty(\nre\configs\AppConfig::$mail['host']) || + empty(\nre\configs\AppConfig::$mail['port']) || + empty(\nre\configs\AppConfig::$mail['username']) + ) { + return; + } + + // Load classes + \hhu\z\lib\PHPMailerAutoload::load(); + \hhu\z\lib\PHPMailer::load(); + \hhu\z\lib\SMTP::load(); + + // Create mailer + $mail = new \PHPMailer(); + + // Configure mailer + $mail->isSMTP(); + $mail->Host = \nre\configs\AppConfig::$mail['host']; + $mail->Port = \nre\configs\AppConfig::$mail['port']; + $mail->SMTPAuth = true; + $mail->Username = \nre\configs\AppConfig::$mail['username']; + $mail->Password = \nre\configs\AppConfig::$mail['password']; + $mail->SMTPSecure = \nre\configs\AppConfig::$mail['secure']; + + // Set properties + $mail->CharSet = 'UTF-8'; + $mail->From = \nre\configs\AppConfig::$app['mailsender']; + $mail->FromName = \nre\configs\AppConfig::$app['name']; + if(!is_array($to)) { + $to = array($to); + } + foreach($to as &$receiver) { + $mail->addAddress($receiver); + } + if($html) { + $mail->isHTML(true); + } + + // Create message + try { + // Create MailApi + $mailApi = new \hhu\z\apis\MailApi(); + if(!is_null($linker)) { + $mailApi->setLinker($linker); + } + $mailApi->setMessage($messageAction); + $mailApi->setParams($params); + if($html) { + $mailApi->setHTML(); + } + + // Render message + $exception = $mailApi->run(); + if(!is_null($exception)) { + return $exception; + } + $mail->Subject = $mailApi->getSubject(); + $mail->Body = $mailApi->render(); + + // Try to render alternativ plaintext message + if($html) + { + $mailApi->setHTML(false); + + // Render message + $exception = $mailApi->run(); + if(is_null($exception)) + { + try { + $mail->AltBody = $mailApi->render(); + } + catch(\nre\core\Exception $e) { + // No alternative plaintext available + } + } + } + } + catch(\nre\core\Exception $e) { + throw new \hhu\z\exceptions\MailingException($e->getMessage()); + } + + + // Return status + if(!$mail->send()) { + throw new \hhu\z\exceptions\MailingException($mail->ErrorInfo); + } + } + + + /** + * Detect Mimetype of a file. + * + * @param string $filename Name of file to detect Mimetype of + * @param string $defaultMimetype Default Mimetype to use + * @return string Detected Mimetype of file + */ + public static function getMimetype($filename, $defaultMimetype=null) + { + $mimetype = (!is_null($defaultMimetype)) ? $defaultMimetype : 'application/octet-stream'; + // Use Fileinfo + if(class_exists('\finfo')) + { + $finfo = new \finfo(FILEINFO_MIME_TYPE); + if(!is_null($finfo)) { + $mimetype = $finfo->file($filename); + } + } + // Use deprecated mime_content_type() + elseif(function_exists('mime_content_type')) { + $mimetype = mime_content_type($filename); + } + + + return $mimetype; + } + + } + +?> diff --git a/app/agents/QuesttypeAgent.inc b/app/agents/QuesttypeAgent.inc new file mode 100644 index 00000000..60a8d9ac --- /dev/null +++ b/app/agents/QuesttypeAgent.inc @@ -0,0 +1,268 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents; + + + /** + * Abstract class for implementing a QuesttypeAgent. + * + * @author Oliver Hanraths + */ + abstract class QuesttypeAgent extends \nre\agents\BottomlevelAgent + { + /** + * Current request + * + * @var \nre\core\Request + */ + private $request; + /** + * Current response + * + * @var \nre\core\Response + */ + private $response; + + + + + /** + * Load a QuesttypeAgent. + * + * @static + * @throws \hhu\z\exceptions\QuesttypeAgentNotFoundException + * @throws \hhu\z\exceptions\QuesttypeAgentNotValidException + * @param string $questtypeName Name of the QuesttypeAgent to load + */ + public static function load($questtypeName) + { + // Determine full classname + $className = self::getClassName($questtypeName); + + try { + // Load class + static::loadClass($questtypeName, $className); + + // Validate class + static::checkClass($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \hhu\z\exceptions\QuesttypeAgentNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \hhu\z\exceptions\QuesttypeAgentNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a QuesttypeAgent (Factory Pattern). + * + * @static + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeControllerNotValidException + * @throws \hhu\z\exceptions\QuesttypeControllerNotFoundException + * @param string $questtypeName Name of the QuesttypeAgent to instantiate + * @param Request $request Current request + * @param Response $response Current respone + * @param Logger $log Log-system + */ + public static function factory($questtypeName, \nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + // Determine full classname + $className = self::getClassName($questtypeName); + + // Construct and return Questmodule + return new $className($request, $response, $log); + } + + + /** + * Determine the Agent-classname for the given Questtype-name. + * + * @static + * @param string $questtypeName Questtype-name to get Agent-classname of + * @param string $agentType Agent type of given Agent name + * @return string Classname for the Questtype-name + */ + private static function getClassName($questtypeName, $agentType=null) + { + $className = \nre\core\ClassLoader::concatClassNames($questtypeName, \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripNamespace(get_class())), 'agent'); + + + return \nre\configs\AppConfig::$app['namespace']."questtypes\\$className"; + } + + + /** + * Load the class of a QuesttypeAgent. + * + * @static + * @throws \nre\exceptions\ClassNotFoundException + * @param string $questtypeName Name of the QuesttypeAgent to load + * @param string $fullClassName Name of the class to load + */ + private static function loadClass($questtypeName, $fullClassName) + { + // Determine folder to look in + $className = explode('\\', $fullClassName); + $className = array_pop($className); + + // Determine filename + $fileName = ROOT.DS.\nre\configs\AppConfig::$dirs['questtypes'].DS.strtolower($questtypeName).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 the QuesttypeAgent-class. + * + * @static + * @throws \nre\exceptions\ClassNotValidException + * @param string $className Name of the class to check + * @param string $parentClassName Name of the parent class + */ + public static function checkClass($className, $parentClassName) + { + // Check if class is subclass of parent class + if(!is_subclass_of($className, $parentClassName)) { + throw new \nre\exceptions\ClassNotValidException( + $className + ); + } + } + + + + + /** + * Construct a new QuesttypeAgent. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeControllerNotValidException + * @throws \hhu\z\exceptions\QuesttypeControllerNotFoundException + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\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; + + + // Call parent constructor + parent::__construct($request, $response, $log); + } + + + + + /** + * Save the answers of a Character for a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $answers Character answers for the Quest + */ + public function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers) + { + $this->controller->saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers); + } + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $answers Character answers for the Quest + */ + public function matchAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers) + { + return $this->controller->matchAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers); + } + + + + + /** + * Load the Controller of this Agent. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeControllerNotValidException + * @throws \hhu\z\exceptions\QuesttypeControllerNotFoundException + */ + protected function loadController() + { + // Determine Controller name + $controllerName = \nre\core\ClassLoader::stripClassType(\nre\core\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 + \hhu\z\controllers\QuesttypeController::load($controllerName); + + // Construct Controller + $this->controller = \hhu\z\controllers\QuesttypeController::factory($controllerName, $toplevelAgentName, $action, $this); + } + + } + +?> diff --git a/app/agents/ToplevelAgent.inc b/app/agents/ToplevelAgent.inc new file mode 100644 index 00000000..c77c8b21 --- /dev/null +++ b/app/agents/ToplevelAgent.inc @@ -0,0 +1,43 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\agents; + + + /** + * Abstract class for implementing an application Controller. + * + * @author Oliver Hanraths + */ + abstract class ToplevelAgent extends \nre\agents\ToplevelAgent + { + + + + + /** + * Construct a new ToplevlAgent + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param \nre\core\Logger $log Logger instance + */ + protected function __construct(\nre\core\Request $request, \nre\core\Response $response, \nre\core\Logger $log=null) + { + parent::__construct($request, $response, $log); + + + // Set timezone + date_default_timezone_set(\nre\configs\AppConfig::$app['timeZone']); + } + } + +?> diff --git a/app/apis/MailApi.inc b/app/apis/MailApi.inc new file mode 100644 index 00000000..721bc547 --- /dev/null +++ b/app/apis/MailApi.inc @@ -0,0 +1,202 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\apis; + + + /** + * MailApi-implementation. + * + * This class runs and renders e‑mail text and subject. + * + * @author Oliver Hanraths + */ + class MailApi extends \nre\core\Api + { + + + + + /** + * Construct a new MailApi. + */ + public function __construct() + { + parent::__construct( + new \hhu\z\requests\MailRequest(), + new \hhu\z\responses\MailResponse() + ); + + // Set ToplevelAgent + $this->request->addParam(\nre\configs\AppConfig::$defaults['toplevel-mail']); + $this->request->addParam(\nre\configs\AppConfig::$defaults['intermediate-mail']); + } + + + + + /** + * Set linker instance for creating links. + * + * @param \nre\core\Linker $linker Linker instance for creating links + */ + public function setLinker(\nre\core\Linker $linker) + { + $this->request->setLinker($linker); + } + + + /** + * Use a ToplevelAgent for HTML-mail + * + * @param bool $html Whether to use HTML or not + */ + public function setHTML($html=true) + { + // Save params + $params = $this->request->getParams(1); + + // Set ToplevelAgent + $this->request->clearParams(); + if($html) { + $this->request->addParam(\nre\configs\AppConfig::$defaults['toplevel-htmlmail']); + } + else { + $this->request->addParam(\nre\configs\AppConfig::$defaults['toplevel-mail']); + } + + // Restore params + if(!empty($params)) { + $this->addParams($params); + } + } + + + /** + * Set the Action for the message to render. + * + * @param string $messageAgent Agent to handle the message + */ + public function setMessage($messageAgent) + { + // Save params + $params = $this->request->getParams(3); + + // Set messageAgent + $this->request->clearParams(2); + $this->request->addParam($messageAgent); + + // Restore params + if(!empty($params)) { + $this->addParams($params); + } + } + + + /** + * Set additional params to pass to the Action. + * + * @param array $params Additional params to set + */ + public function setParams($params) + { + // Add placeholder params + for($i=3; $irequest->getParams()); $i++) { + $this->request->addParam(null); + } + + // Set params + call_user_func_array( + array( + $this->request, + 'addParams' + ), + $params + ); + } + + + /** + * Return the subject set by the Controller. + * + * @return string Subject set by Controller + */ + public function getSubject() + { + return $this->response->getSubject(); + } + + + /** + * Run mailtext generation. + * + * This method runs the generation of mailtext. + * + * @return \Exception Occured exception or null + */ + public function run() + { + // Set response + $this->response->clearParams(); + foreach($this->request->getParams() as $param) { + $this->response->addParam($param); + } + + // Run + try { + $exception = parent::run(); + + + return $exception; + } + catch(\nre\Exception $e) { + return $e; + } + } + + + /** + * Render output. + * + * @return string Rendered output + */ + public function render() + { + // Generate output + parent::render(); + + + // Return output + return $this->response->getOutput(); + } + + + + + /** + * Add multiple request params. + * + * @param array $params Request params to add + */ + private function addParams($params) + { + call_user_func_array( + array( + $this->request, + 'addParams' + ), + $params + ); + } + + } + +?> diff --git a/app/controllers/IntermediateController.inc b/app/controllers/IntermediateController.inc new file mode 100644 index 00000000..49da3fc2 --- /dev/null +++ b/app/controllers/IntermediateController.inc @@ -0,0 +1,197 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Abstract class for implementing a Controller of an IntermediateAgent. + * + * @author Oliver Hanraths + */ + abstract class IntermediateController extends \hhu\z\Controller + { + /** + * Required models + * + * @var array + */ + public $models = array('users', 'userroles', 'seminaries', 'characters'); + /** + * Current user + * + * @var array + */ + public static $user = null; + /** + * Title information + * + * @var array + */ + private $title = array(); + + + + + /** + * Construct a new IntermediateController. + * + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param \nre\core\Agent $agent Corresponding Agent + */ + public function __construct($layoutName, $action, $agent) + { + parent::__construct($layoutName, $action, $agent); + } + + + + /** + * Prefilter that is executed before running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Get userdata + try { + self::$user = $this->Users->getUserById($this->Auth->getUserId()); + self::$user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById(self::$user['id'])); + } + catch(\nre\exceptions\IdNotFoundException $e) { + } + + // Check permissions + $this->checkPermission($request, $response); + + // Set userdata + $this->set('loggedUser', self::$user); + } + + + /** + * Postfilter that is executed after running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function postFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::postFilter($request, $response); + } + + + /** + * Return current title information. + * + * @return string Title information + */ + public function getTitle() + { + return $this->title; + } + + + + + /** + * Add a piece of information to the current title. + * + * @param string $title Title information + */ + protected function addTitle($title) + { + $this->title[] = $title; + } + + + /** + * Add a piece of information to the current title and localize + * it. + * + * @param string $title Title information + */ + protected function addTitleLocalized($title) + { + $title = gettext($title); + + $args = func_get_args(); + if(count($args) > 0) { + $title = call_user_func_array( + 'sprintf', + array_merge( + array($title), + array_slice($args, 1) + ) + ); + } + + + $this->title[] = $title; + } + + + + + /** + * Check user permissions. + * + * @throws \nre\exceptions\AccessDeniedException + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + private function checkPermission(\nre\core\Request $request, \nre\core\Response $response) + { + // Determine user + $userRoles = array('guest'); + if(!is_null(self::$user)) { + $userRoles = self::$user['roles']; + } + + + // Do not check error pages + if($response->getParam(0, 'toplevel') == \nre\core\Config::getDefault('toplevel-error')) { + return; + } + if($response->getParam(1, 'intermediate') == \nre\core\Config::getDefault('intermediate-error')) { + return; + } + + // Determine permissions of Intermediate Controller for current action + $controller = $this->agent->controller; + $action = $this->request->getParam(2, 'action'); + if(!property_exists($controller, 'permissions')) { + return; // Allow if nothing is specified + } + if(!array_key_exists($action, $controller->permissions)) { + return; // Allow if Action is not specified + } + $permissions = $controller->permissions[$action]; + + + // Check permissions + if(count(array_intersect($userRoles, $permissions)) == 0) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + + } + +?> diff --git a/app/controllers/QuesttypeController.inc b/app/controllers/QuesttypeController.inc new file mode 100644 index 00000000..bdccb4cd --- /dev/null +++ b/app/controllers/QuesttypeController.inc @@ -0,0 +1,320 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Abstract class for implementing a QuesttypeController. + * + * @author Oliver Hanraths + */ + abstract class QuesttypeController extends \hhu\z\Controller + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'questgroups', 'quests', 'characters'); + + + + + /** + * Save the answers of a Character for a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $answers Character answers for the Quest + */ + public abstract function saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers); + + + /** + * Save additional data for the answers of a Character for a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $data Additional (POST-) data + */ + public abstract function saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $data); + + + /** + * Check if answers of a Character for a Quest match the correct ones. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param array $answers Character answers for the Quest + * @return boolean True/false for a right/wrong answer or null for moderator evaluation + */ + public abstract function matchAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers); + + + /** + * Action: quest. + * + * Show the task of a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + * @param \Exception $exception Character submission exception + */ + public abstract function quest($seminary, $questgroup, $quest, $character, $exception); + + + /** + * Action: submission. + * + * Show the submission of a Character for a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + * @param array $character Current Character data + */ + public abstract function submission($seminary, $questgroup, $quest, $character); + + + /** + * Action: edittask. + * + * Edit the task of a Quest. + * + * @param array $seminary Current Seminary data + * @param array $questgroup Current Questgroup data + * @param array $quest Current Quest data + */ + public abstract function edittask($seminary, $questgroup, $quest); + + + + + /** + * Load a QuesttypeController. + * + * @static + * @throws \hhu\z\exceptions\QuesttypeControllerNotFoundException + * @throws \hhu\z\exceptions\QuesttypeControllerNotValidException + * @param string $controllerName Name of the QuesttypeController to load + */ + public static function load($controllerName) + { + // Determine full classname + $className = self::getClassName($controllerName); + + try { + // Load class + static::loadClass($controllerName, $className); + + // Validate class + static::checkClass($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \hhu\z\exceptions\QuesttypeControllerNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \hhu\z\exceptions\QuesttypeControllerNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a QuesttypeController (Factory Pattern). + * + * @static + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @param string $controllerName Name of the QuesttypeController to instantiate + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param \nre\core\Agent $agent Corresponding Agent + */ + 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 Controller-classname for the given Questtype-name. + * + * @static + * @param string $questtypeName Questtype-name to get Controller-classname of + * @return string Classname for the Questtype-name + */ + private static function getClassName($questtypeName) + { + $className = \nre\core\ClassLoader::concatClassNames($questtypeName, \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripNamespace(get_class())), 'controller'); + + + return \nre\configs\AppConfig::$app['namespace']."questtypes\\$className"; + } + + + /** + * Load the class of a QuesttypeController + * + * @static + * @throws \nre\exceptions\ClassNotFoundException + * @param string $questtypeName Name of the QuesttypeController to load + * @param string $fullClassName Name of the class to load + */ + private static function loadClass($questtypeName, $fullClassName) + { + // Determine folder to look in + $className = explode('\\', $fullClassName); + $className = array_pop($className); + + // Determine filename + $fileName = ROOT.DS.\nre\configs\AppConfig::$dirs['questtypes'].DS.strtolower($questtypeName).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 the QuesttypeController-class. + * + * @static + * @throws \nre\exceptions\ClassNotValidException + * @param string $className Name of the class to check + * @param string $parentClassName Name of the parent class + */ + public static function checkClass($className, $parentClassName) + { + // Check if class is subclass of parent class + if(!is_subclass_of($className, $parentClassName)) { + throw new \nre\exceptions\ClassNotValidException( + $className + ); + } + } + + + + + /** + * Construct a new application Controller. + * + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param Agent $agent Corresponding Agent + */ + public function __construct($layoutName, $action, $agent) + { + parent::__construct($layoutName, $action, $agent); + } + + + + + /** + * Load the Models of this Controller. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + */ + protected function loadModels() + { + // Load default models + parent::loadModels(); + + // Load QuesttypeModel + $this->loadModel(); + } + + + /** + * Load the Model of the Questtype. + * + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + */ + private function loadModel() + { + // Determine Model + $model = \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripNamespace(get_class($this)))); + + // Load class + \hhu\z\models\QuesttypeModel::load($model); + + // Construct Model + $modelName = ucfirst(strtolower($model)); + $this->$modelName = \hhu\z\models\QuesttypeModel::factory($model); + } + + + /** + * Load the View of this QuesttypeController. + * + * @throws \nre\exceptions\ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + */ + protected function loadView($layoutName, $action) + { + // Check Layout name + if(is_null($layoutName)) { + return; + } + + // Determine controller name + $controllerName = \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::getClassName(get_class($this))); + + + // Load view + $this->view = \hhu\z\views\QuesttypeView::loadAndFactory($layoutName, $controllerName, $action); + } + + } + +?> diff --git a/app/controllers/SeminaryController.inc b/app/controllers/SeminaryController.inc new file mode 100644 index 00000000..34fbcb44 --- /dev/null +++ b/app/controllers/SeminaryController.inc @@ -0,0 +1,328 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Abstract class for implementing a Controller for a Seminary and its + * concepts. + * + * @author Oliver Hanraths + */ + abstract class SeminaryController extends \hhu\z\controllers\IntermediateController + { + /** + * Required components + * + * @var array + */ + public $components = array('achievement', 'auth', 'notification'); + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'characters', 'characterroles', 'xplevels', 'avatars', 'achievements'); + /** + * Current Seminary + * + * var array + */ + public static $seminary = null; + /** + * Character of current user and Seminary + * + * @var array + */ + public static $character = null; + + + + + /** + * Construct a new Seminary Controller. + * + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param \nre\core\Agent $agent Corresponding Agent + */ + public function __construct($layoutName, $action, $agent) + { + parent::__construct($layoutName, $action, $agent); + } + + + + /** + * Prefilter that is executed before running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Get Seminary and Character data + try { + self::$seminary = $this->Seminaries->getSeminaryByUrl($this->request->getParam(3)); + if(!is_null(self::$user)) + { + self::$character = $this->Characters->getCharacterForUserAndSeminary(self::$user['id'], self::$seminary['id']); + self::$character['characterroles'] = array_map(function($r) { return $r['name']; }, $this->Characterroles->getCharacterrolesForCharacterById(self::$character['id'])); + try { + self::$character['xplevel'] = $this->Xplevels->getXPLevelById(self::$character['xplevel_id']); + self::$character['avatar'] = $this->Avatars->getAvatarByTypeAndLevel(self::$seminary['id'], self::$character['charactertype_url'], self::$character['xplevel']['level']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No Avatar available + } + } + } + catch(\nre\exceptions\IdNotFoundException $e) { + } + + // Check permissions + $this->checkPermission($request, $response); + + // Check achievements + $this->checkAchievements($request, $response, 'date'); + $this->checkAchievements($request, $response, 'achievement'); + + // Set Seminary and Character data + $this->set('loggedSeminary', self::$seminary); + $this->set('loggedCharacter', self::$character); + } + + + /** + * Postfilter that is executed after running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function postFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::postFilter($request, $response); + } + + + + /** + * Check user permissions. + * + * @throws AccessDeniedException + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + private function checkPermission(\nre\core\Request $request, \nre\core\Response $response) + { + // Do not check index page + if(is_null($request->getParam(3))) { + return; + } + + + // Determine permissions for current action + $action = $this->request->getParam(2, 'action'); + if(!property_exists($this, 'seminaryPermissions')) { + return; // Allow if nothing is specified + } + if(!array_key_exists($action, $this->seminaryPermissions)) { + return; // Allow if Action is not specified + } + $permissions = $this->seminaryPermissions[$action]; + + + // Check permissions + if(is_null(self::$character) || !array_key_exists('characterroles', self::$character) || count(array_intersect(self::$character['characterroles'], $permissions)) == 0) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + + + /** + * Check for newly achieved Achievements. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + * @param array $checkConditions Conditions to check + */ + protected function checkAchievements(\nre\core\Request $request, \nre\core\Response $response, $checkConditions=null) + { + // Do not check MediaController + if($this->request->getParam(0, 'toplevel') != \nre\configs\AppConfig::$defaults['toplevel']) { + return; + } + + // Check if Character is present + if(is_null(self::$character)) { + return; + } + + // Set conditions to check + if(!is_null($checkConditions) && !is_array($checkConditions)) { + $checkConditions = array($checkConditions); + } + + // Get unachieved Achievments + $achievements = $this->Achievements->getUnachhievedAchievementsForCharacter(self::$seminary['id'], self::$character['id']); + if(in_array('user', self::$character['characterroles'])) { + $achievements = array_merge($achievements, $this->Achievements->getUnachievedOnlyOnceAchievementsForSeminary(self::$seminary['id'])); + } + + // Check conditions + foreach($achievements as &$achievement) + { + // Check condition to test + if(!is_null($checkConditions) && !in_array($achievement['condition'], $checkConditions)) { + continue; + } + + // Check deadline + if(!is_null($achievement['deadline']) && $achievement['deadline'] < date('Y-m-d H:i:s')) { + continue; + } + + // Get conditions + $conditions = array(); + $progress = 0; + switch($achievement['condition']) + { + // Date conditions + case 'date': + $conditionsDate = $this->Achievements->getAchievementConditionsDate($achievement['id']); + foreach($conditionsDate as &$condition) + { + $conditions[] = array( + 'func' => 'checkAchievementConditionDate', + 'params' => array( + $condition['select'] + ) + ); + } + break; + // Character conditions + case 'character': + $conditionsCharacter = $this->Achievements->getAchievementConditionsCharacter($achievement['id']); + foreach($conditionsCharacter as &$condition) + { + $conditions[] = array( + 'func' => 'checkAchievementConditionCharacter', + 'params' => array( + $condition['field'], + $condition['value'], + self::$character['id'] + ) + ); + } + break; + // Quest conditions + case 'quest': + $conditionsQuest = $this->Achievements->getAchievementConditionsQuest($achievement['id']); + foreach($conditionsQuest as &$condition) + { + $conditions[] = array( + 'func' => 'checkAchievementConditionQuest', + 'params' => array( + $condition['field'], + $condition['count'], + $condition['value'], + $condition['status'], + $condition['groupby'], + $condition['quest_id'], + self::$character['id'] + ) + ); + } + break; + // Achievement conditions + case 'achievement': + $conditionsAchievement = $this->Achievements->getAchievementConditionsAchievement($achievement['id']); + foreach($conditionsAchievement as &$condition) + { + $conditions[] = array( + 'func' => 'checkAchievementConditionAchievement', + 'params' => array( + $condition['field'], + $condition['count'], + $condition['value'], + $condition['groupby'], + $condition['meta_achievement_id'], + self::$character['id'] + ) + ); + } + break; + } + + // Do not achieve Achievements without conditions + if(empty($conditions)) { + continue; + } + + // Check conditions + $achieved = ($achievement['all_conditions'] == 1); + foreach($conditions as &$condition) + { + // Calculate result of condition + $result = call_user_func_array( + array( + $this->Achievements, + $condition['func'] + ), + $condition['params'] + ); + + // The overall result and abort if possible + if($achievement['all_conditions']) + { + if(!$result) { + $achieved = false; + break; + } + } + else + { + if($result) { + $achieved = true; + break; + } + } + + } + + // Achievement achieved + if($achieved) + { + // Set status + $this->Achievements->setAchievementAchieved($achievement['id'], self::$character['id']); + + // Add notification + $this->Notification->addNotification( + \hhu\z\controllers\components\NotificationComponent::TYPE_ACHIEVEMENT, + $achievement['title'], + $this->linker->link(array('achievements', 'index', self::$seminary['url']), 0, true, null, true, $achievement['url']), + (!is_null($achievement['achieved_achievementsmedia_id']) ? $this->linker->link(array('media','achievement',self::$seminary['url'],$achievement['url'])) : null) + ); + } + } + } + + } + +?> diff --git a/app/empty b/app/empty new file mode 100644 index 00000000..e69de29b diff --git a/app/exceptions/FileCopyException.inc b/app/exceptions/FileCopyException.inc new file mode 100644 index 00000000..898cb7b1 --- /dev/null +++ b/app/exceptions/FileCopyException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File copy went wrong + * + * @author Oliver Hanraths + */ + class FileCopyException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 204; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File copy went wrong'; + + /** + * Nested error + * + * @var array + */ + private $nestedError; + + + + + /** + * Construct a new exception. + * + * @param array $nestedError Nested error + * @param string $message Error message + * @param int $code Error code + */ + function __construct($nestedError, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $nestedError['message'] + ); + + // Store values + $this->nestedError = $nestedError; + } + + + + + /** + * Get nested error. + * + * @return Nested error + */ + public function getNestedError() + { + return $this->nestedError; + } + + } + +?> diff --git a/app/exceptions/FileUploadException.inc b/app/exceptions/FileUploadException.inc new file mode 100644 index 00000000..c4c6b922 --- /dev/null +++ b/app/exceptions/FileUploadException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File upload went wrong + * + * @author Oliver Hanraths + */ + class FileUploadException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 203; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File upload went wrong'; + + /** + * Nested message + * + * @var string + */ + private $nestedMessage; + + + + + /** + * Construct a new exception. + * + * @param string $nestedMessage Nested message + * @param string $message Error message + * @param int $code Error code + */ + function __construct($nestedMessage=null, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $nestedMessage + ); + + // Store values + $this->nestedMessage = $nestedMessage; + } + + + + + /** + * Get nested message. + * + * @return Nested message + */ + public function getNestedMessage() + { + return $this->nestedMessage; + } + + } + +?> diff --git a/app/exceptions/MailingException.inc b/app/exceptions/MailingException.inc new file mode 100644 index 00000000..d68f8149 --- /dev/null +++ b/app/exceptions/MailingException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception during sending of an e‑mail. + * + * @author Oliver Hanraths + */ + class MailingException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 300; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'Error sending e‑mail'; + + /** + * Nested error message + * + * @var string + */ + private $error; + + + + + /** + * Construct a new exception. + * + * @param int $error Nested error message + * @param string $message Error message + * @param int $code Error code + */ + function __construct($error, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $error + ); + + // Store values + $this->error = $error; + } + + + + + /** + * Get nested error message. + * + * @return string Nested error message + */ + public function getError() + { + return $this->error; + } + + } + +?> diff --git a/app/exceptions/MaxFilesizeException.inc b/app/exceptions/MaxFilesizeException.inc new file mode 100644 index 00000000..bc7a1383 --- /dev/null +++ b/app/exceptions/MaxFilesizeException.inc @@ -0,0 +1,54 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File exceeds size maximum. + * + * @author Oliver Hanraths + */ + class MaxFilesizeException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 202; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File exceeds size maximum'; + + + + + /** + * Construct a new exception. + * + * @param string $message Error message + * @param int $code Error code + */ + function __construct($message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code + ); + } + + } + +?> diff --git a/app/exceptions/QuesttypeAgentNotFoundException.inc b/app/exceptions/QuesttypeAgentNotFoundException.inc new file mode 100644 index 00000000..0aeaf298 --- /dev/null +++ b/app/exceptions/QuesttypeAgentNotFoundException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeAgent not found. + * + * @author Oliver Hanraths + */ + class QuesttypeAgentNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 101; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeAgent not found'; + + /** + * Name of the class that was not found + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the QuesttypeAgent that was not found + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store values + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the QuesttypeAgent that was not found. + * + * @return string Name of the QuesttypeAgent that was not found + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/QuesttypeAgentNotValidException.inc b/app/exceptions/QuesttypeAgentNotValidException.inc new file mode 100644 index 00000000..5efc8c3e --- /dev/null +++ b/app/exceptions/QuesttypeAgentNotValidException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeAgent not valid. + * + * @author Oliver Hanraths + */ + class QuesttypeAgentNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 102; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeAgent not valid'; + + /** + * Name of the invalid class + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the invalid QuesttypeAgent + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store value + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the invalid QuesttypeAgent. + * + * @return string Name of the invalid QuesttypeAgent + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/QuesttypeControllerNotFoundException.inc b/app/exceptions/QuesttypeControllerNotFoundException.inc new file mode 100644 index 00000000..e0447cc9 --- /dev/null +++ b/app/exceptions/QuesttypeControllerNotFoundException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeController not found. + * + * @author Oliver Hanraths + */ + class QuesttypeControllerNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 103; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeController not found'; + + /** + * Name of the class that was not found + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the QuesttypeController that was not found + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store values + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the QuesttypeController that was not found. + * + * @return string Name of the QuesttypeController that was not found + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/QuesttypeControllerNotValidException.inc b/app/exceptions/QuesttypeControllerNotValidException.inc new file mode 100644 index 00000000..f4ccbee1 --- /dev/null +++ b/app/exceptions/QuesttypeControllerNotValidException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeController not valid. + * + * @author Oliver Hanraths + */ + class QuesttypeControllerNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 104; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeController not valid'; + + /** + * Name of the invalid class + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the invalid QuesttypeController + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store value + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the invalid QuesttypeController. + * + * @return string Name of the invalid QuesttypeController + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/QuesttypeModelNotFoundException.inc b/app/exceptions/QuesttypeModelNotFoundException.inc new file mode 100644 index 00000000..9a6d2294 --- /dev/null +++ b/app/exceptions/QuesttypeModelNotFoundException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeModel not found. + * + * @author Oliver Hanraths + */ + class QuesttypeModelNotFoundException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 105; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeModel not found'; + + /** + * Name of the class that was not found + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the QuesttypeModel that was not found + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store values + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the QuesttypeModel that was not found. + * + * @return string Name of the QuesttypeModel that was not found + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/QuesttypeModelNotValidException.inc b/app/exceptions/QuesttypeModelNotValidException.inc new file mode 100644 index 00000000..911701e8 --- /dev/null +++ b/app/exceptions/QuesttypeModelNotValidException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: QuesttypeModel not valid. + * + * @author Oliver Hanraths + */ + class QuesttypeModelNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 106; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'QuesttypeModel not valid'; + + /** + * Name of the invalid class + * + * @var string + */ + private $questtypeName; + + + + + /** + * Construct a new exception. + * + * @param string $questtypeName Name of the invalid QuesttypeModel + * @param string $message Error message + * @param int $code Error code + */ + function __construct($questtypeName, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $questtypeName + ); + + // Store value + $this->questtypeName = $questtypeName; + } + + + + + /** + * Get the name of the invalid QuesttypeModel. + * + * @return string Name of the invalid QuesttypeModel + */ + public function getClassName() + { + return $this->questtypeName; + } + + } + +?> diff --git a/app/exceptions/SubmissionNotValidException.inc b/app/exceptions/SubmissionNotValidException.inc new file mode 100644 index 00000000..0902c78a --- /dev/null +++ b/app/exceptions/SubmissionNotValidException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: Character submission not valid. + * + * @author Oliver Hanraths + */ + class SubmissionNotValidException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 200; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'Character submission not valid'; + + /** + * Nested exception + * + * @var Exception + */ + private $nestedException; + + + + + /** + * Construct a new exception. + * + * @param string $nestedException Nested exception + * @param string $message Error message + * @param int $code Error code + */ + function __construct($nestedException, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $nestedException + ); + + // Store value + $this->nestedException = $nestedException; + } + + + + + /** + * Get Nested exception. + * + * @return string Nested exception + */ + public function getNestedException() + { + return $this->nestedException; + } + + } + +?> diff --git a/app/exceptions/WrongFiletypeException.inc b/app/exceptions/WrongFiletypeException.inc new file mode 100644 index 00000000..13eb91df --- /dev/null +++ b/app/exceptions/WrongFiletypeException.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\exceptions; + + + /** + * Exception: File has wrong filetype. + * + * @author Oliver Hanraths + */ + class WrongFiletypeException extends \nre\core\Exception + { + /** + * Error code + * + * @var int + */ + const CODE = 201; + /** + * Error message + * + * @var string + */ + const MESSAGE = 'File has wrong type “%s”'; + + /** + * Type of file + * + * @var string + */ + private $type; + + + + + /** + * Construct a new exception. + * + * @param string $type Type of file + * @param string $message Error message + * @param int $code Error code + */ + function __construct($type, $message=self::MESSAGE, $code=self::CODE) + { + parent::__construct( + $message, + $code, + $type + ); + + // Store values + $this->type = $type; + } + + + + + /** + * Get type of file. + * + * @return Type of file + */ + public function getType() + { + return $this->type; + } + + } + +?> diff --git a/app/lib/PHPMailer.inc b/app/lib/PHPMailer.inc new file mode 100644 index 00000000..157db77a --- /dev/null +++ b/app/lib/PHPMailer.inc @@ -0,0 +1,3453 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\lib + { + + + /** + * Class to ensure that Compatibility library below is loaded. + * + * @author Oliver Hanraths + */ + class PHPMailer + { + + /** + * Call this function to ensure this file is loaded. + */ + public static function load() + { + } + + } + + } + + namespace { + +/** + * PHPMailer - PHP email creation and transport class. + * PHP Version 5 + * @package PHPMailer + * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailer - PHP email creation and transport class. + * @package PHPMailer + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + */ +class PHPMailer +{ + /** + * The PHPMailer Version number. + * @type string + */ + public $Version = '5.2.8'; + + /** + * Email priority. + * Options: 1 = High, 3 = Normal, 5 = low. + * @type int + */ + public $Priority = 3; + + /** + * The character set of the message. + * @type string + */ + public $CharSet = 'iso-8859-1'; + + /** + * The MIME Content-type of the message. + * @type string + */ + public $ContentType = 'text/plain'; + + /** + * The message encoding. + * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable". + * @type string + */ + public $Encoding = '8bit'; + + /** + * Holds the most recent mailer error message. + * @type string + */ + public $ErrorInfo = ''; + + /** + * The From email address for the message. + * @type string + */ + public $From = 'root@localhost'; + + /** + * The From name of the message. + * @type string + */ + public $FromName = 'Root User'; + + /** + * The Sender email (Return-Path) of the message. + * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. + * @type string + */ + public $Sender = ''; + + /** + * The Return-Path of the message. + * If empty, it will be set to either From or Sender. + * @type string + * @deprecated Email senders should never set a return-path header; + * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything. + * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference + */ + public $ReturnPath = ''; + + /** + * The Subject of the message. + * @type string + */ + public $Subject = ''; + + /** + * An HTML or plain text message body. + * If HTML then call isHTML(true). + * @type string + */ + public $Body = ''; + + /** + * The plain-text message body. + * This body can be read by mail clients that do not have HTML email + * capability such as mutt & Eudora. + * Clients that can read HTML will view the normal Body. + * @type string + */ + public $AltBody = ''; + + /** + * An iCal message part body. + * Only supported in simple alt or alt_inline message types + * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator + * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ + * @link http://kigkonsult.se/iCalcreator/ + * @type string + */ + public $Ical = ''; + + /** + * The complete compiled MIME message body. + * @access protected + * @type string + */ + protected $MIMEBody = ''; + + /** + * The complete compiled MIME message headers. + * @type string + * @access protected + */ + protected $MIMEHeader = ''; + + /** + * Extra headers that createHeader() doesn't fold in. + * @type string + * @access protected + */ + protected $mailHeader = ''; + + /** + * Word-wrap the message body to this number of chars. + * @type int + */ + public $WordWrap = 0; + + /** + * Which method to use to send mail. + * Options: "mail", "sendmail", or "smtp". + * @type string + */ + public $Mailer = 'mail'; + + /** + * The path to the sendmail program. + * @type string + */ + public $Sendmail = '/usr/sbin/sendmail'; + + /** + * Whether mail() uses a fully sendmail-compatible MTA. + * One which supports sendmail's "-oi -f" options. + * @type bool + */ + public $UseSendmailOptions = true; + + /** + * Path to PHPMailer plugins. + * Useful if the SMTP class is not in the PHP include path. + * @type string + * @deprecated Should not be needed now there is an autoloader. + */ + public $PluginDir = ''; + + /** + * The email address that a reading confirmation should be sent to. + * @type string + */ + public $ConfirmReadingTo = ''; + + /** + * The hostname to use in Message-Id and Received headers + * and as default HELO string. + * If empty, the value returned + * by SERVER_NAME is used or 'localhost.localdomain'. + * @type string + */ + public $Hostname = ''; + + /** + * An ID to be used in the Message-Id header. + * If empty, a unique id will be generated. + * @type string + */ + public $MessageID = ''; + + /** + * The message Date to be used in the Date header. + * If empty, the current date will be added. + * @type string + */ + public $MessageDate = ''; + + /** + * SMTP hosts. + * Either a single hostname or multiple semicolon-delimited hostnames. + * You can also specify a different port + * for each host by using this format: [hostname:port] + * (e.g. "smtp1.example.com:25;smtp2.example.com"). + * Hosts will be tried in order. + * @type string + */ + public $Host = 'localhost'; + + /** + * The default SMTP server port. + * @type int + * @Todo Why is this needed when the SMTP class takes care of it? + */ + public $Port = 25; + + /** + * The SMTP HELO of the message. + * Default is $Hostname. + * @type string + * @see PHPMailer::$Hostname + */ + public $Helo = ''; + + /** + * The secure connection prefix. + * Options: "", "ssl" or "tls" + * @type string + */ + public $SMTPSecure = ''; + + /** + * Whether to use SMTP authentication. + * Uses the Username and Password properties. + * @type bool + * @see PHPMailer::$Username + * @see PHPMailer::$Password + */ + public $SMTPAuth = false; + + /** + * SMTP username. + * @type string + */ + public $Username = ''; + + /** + * SMTP password. + * @type string + */ + public $Password = ''; + + /** + * SMTP auth type. + * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5 + * @type string + */ + public $AuthType = ''; + + /** + * SMTP realm. + * Used for NTLM auth + * @type string + */ + public $Realm = ''; + + /** + * SMTP workstation. + * Used for NTLM auth + * @type string + */ + public $Workstation = ''; + + /** + * The SMTP server timeout in seconds. + * @type int + */ + public $Timeout = 10; + + /** + * SMTP class debug output mode. + * Options: + * 0: no output + * 1: commands + * 2: data and commands + * 3: as 2 plus connection status + * 4: low level data output + * @type int + * @see SMTP::$do_debug + */ + public $SMTPDebug = 0; + + /** + * How to handle debug output. + * Options: + * 'echo': Output plain-text as-is, appropriate for CLI + * 'html': Output escaped, line breaks converted to
, appropriate for browser output + * 'error_log': Output to error log as configured in php.ini + * @type string + * @see SMTP::$Debugoutput + */ + public $Debugoutput = 'echo'; + + /** + * Whether to keep SMTP connection open after each message. + * If this is set to true then to close the connection + * requires an explicit call to smtpClose(). + * @type bool + */ + public $SMTPKeepAlive = false; + + /** + * Whether to split multiple to addresses into multiple messages + * or send them all in one message. + * @type bool + */ + public $SingleTo = false; + + /** + * Storage for addresses when SingleTo is enabled. + * @type array + * @todo This should really not be public + */ + public $SingleToArray = array(); + + /** + * Whether to generate VERP addresses on send. + * Only applicable when sending via SMTP. + * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @link http://www.postfix.org/VERP_README.html Postfix VERP info + * @type bool + */ + public $do_verp = false; + + /** + * Whether to allow sending messages with an empty body. + * @type bool + */ + public $AllowEmpty = false; + + /** + * The default line ending. + * @note The default remains "\n". We force CRLF where we know + * it must be used via self::CRLF. + * @type string + */ + public $LE = "\n"; + + /** + * DKIM selector. + * @type string + */ + public $DKIM_selector = ''; + + /** + * DKIM Identity. + * Usually the email address used as the source of the email + * @type string + */ + public $DKIM_identity = ''; + + /** + * DKIM passphrase. + * Used if your key is encrypted. + * @type string + */ + public $DKIM_passphrase = ''; + + /** + * DKIM signing domain name. + * @example 'example.com' + * @type string + */ + public $DKIM_domain = ''; + + /** + * DKIM private key file path. + * @type string + */ + public $DKIM_private = ''; + + /** + * Callback Action function name. + * + * The function that handles the result of the send email action. + * It is called out by send() for each email sent. + * + * Value can be any php callable: http://www.php.net/is_callable + * + * Parameters: + * bool $result result of the send action + * string $to email address of the recipient + * string $cc cc email addresses + * string $bcc bcc email addresses + * string $subject the subject + * string $body the email body + * string $from email address of sender + * @type string + */ + public $action_function = ''; + + /** + * What to use in the X-Mailer header. + * Options: null for default, whitespace for none, or a string to use + * @type string + */ + public $XMailer = ''; + + /** + * An instance of the SMTP sender class. + * @type SMTP + * @access protected + */ + protected $smtp = null; + + /** + * The array of 'to' addresses. + * @type array + * @access protected + */ + protected $to = array(); + + /** + * The array of 'cc' addresses. + * @type array + * @access protected + */ + protected $cc = array(); + + /** + * The array of 'bcc' addresses. + * @type array + * @access protected + */ + protected $bcc = array(); + + /** + * The array of reply-to names and addresses. + * @type array + * @access protected + */ + protected $ReplyTo = array(); + + /** + * An array of all kinds of addresses. + * Includes all of $to, $cc, $bcc, $replyto + * @type array + * @access protected + */ + protected $all_recipients = array(); + + /** + * The array of attachments. + * @type array + * @access protected + */ + protected $attachment = array(); + + /** + * The array of custom headers. + * @type array + * @access protected + */ + protected $CustomHeader = array(); + + /** + * The most recent Message-ID (including angular brackets). + * @type string + * @access protected + */ + protected $lastMessageID = ''; + + /** + * The message's MIME type. + * @type string + * @access protected + */ + protected $message_type = ''; + + /** + * The array of MIME boundary strings. + * @type array + * @access protected + */ + protected $boundary = array(); + + /** + * The array of available languages. + * @type array + * @access protected + */ + protected $language = array(); + + /** + * The number of errors encountered. + * @type integer + * @access protected + */ + protected $error_count = 0; + + /** + * The S/MIME certificate file path. + * @type string + * @access protected + */ + protected $sign_cert_file = ''; + + /** + * The S/MIME key file path. + * @type string + * @access protected + */ + protected $sign_key_file = ''; + + /** + * The S/MIME password for the key. + * Used only if the key is encrypted. + * @type string + * @access protected + */ + protected $sign_key_pass = ''; + + /** + * Whether to throw exceptions for errors. + * @type bool + * @access protected + */ + protected $exceptions = false; + + /** + * Error severity: message only, continue processing + */ + const STOP_MESSAGE = 0; + + /** + * Error severity: message, likely ok to continue processing + */ + const STOP_CONTINUE = 1; + + /** + * Error severity: message, plus full stop, critical error reached + */ + const STOP_CRITICAL = 2; + + /** + * SMTP RFC standard line ending + */ + const CRLF = "\r\n"; + + /** + * Constructor + * @param bool $exceptions Should we throw external exceptions? + */ + public function __construct($exceptions = false) + { + $this->exceptions = ($exceptions == true); + //Make sure our autoloader is loaded + if (version_compare(PHP_VERSION, '5.1.2', '>=')) { + $autoload = spl_autoload_functions(); + if ($autoload === false or !in_array('PHPMailerAutoload', $autoload)) { + require 'PHPMailerAutoload.php'; + } + } + } + + /** + * Destructor. + */ + public function __destruct() + { + if ($this->Mailer == 'smtp') { //close any open SMTP connection nicely + $this->smtpClose(); + } + } + + /** + * Call mail() in a safe_mode-aware fashion. + * Also, unless sendmail_path points to sendmail (or something that + * claims to be sendmail), don't pass params (not a perfect fix, + * but it will do) + * @param string $to To + * @param string $subject Subject + * @param string $body Message Body + * @param string $header Additional Header(s) + * @param string $params Params + * @access private + * @return bool + */ + private function mailPassthru($to, $subject, $body, $header, $params) + { + //Check overloading of mail function to avoid double-encoding + if (ini_get('mbstring.func_overload') & 1) { + $subject = $this->secureHeader($subject); + } else { + $subject = $this->encodeHeader($this->secureHeader($subject)); + } + if (ini_get('safe_mode') || !($this->UseSendmailOptions)) { + $result = @mail($to, $subject, $body, $header); + } else { + $result = @mail($to, $subject, $body, $header, $params); + } + return $result; + } + + /** + * Output debugging info via user-defined method. + * Only if debug output is enabled. + * @see PHPMailer::$Debugoutput + * @see PHPMailer::$SMTPDebug + * @param string $str + */ + protected function edebug($str) + { + if (!$this->SMTPDebug) { + return; + } + switch ($this->Debugoutput) { + case 'error_log': + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking display that's HTML-safe + echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "
\n"; + break; + case 'echo': + default: + echo $str."\n"; + } + } + + /** + * Sets message type to HTML or plain. + * @param bool $ishtml True for HTML mode. + * @return void + */ + public function isHTML($ishtml = true) + { + if ($ishtml) { + $this->ContentType = 'text/html'; + } else { + $this->ContentType = 'text/plain'; + } + } + + /** + * Send messages using SMTP. + * @return void + */ + public function isSMTP() + { + $this->Mailer = 'smtp'; + } + + /** + * Send messages using PHP's mail() function. + * @return void + */ + public function isMail() + { + $this->Mailer = 'mail'; + } + + /** + * Send messages using $Sendmail. + * @return void + */ + public function isSendmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (!stristr($ini_sendmail_path, 'sendmail')) { + $this->Sendmail = '/usr/sbin/sendmail'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'sendmail'; + } + + /** + * Send messages using qmail. + * @return void + */ + public function isQmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (!stristr($ini_sendmail_path, 'qmail')) { + $this->Sendmail = '/var/qmail/bin/qmail-inject'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'qmail'; + } + + /** + * Add a "To" address. + * @param string $address + * @param string $name + * @return bool true on success, false if address already used + */ + public function addAddress($address, $name = '') + { + return $this->addAnAddress('to', $address, $name); + } + + /** + * Add a "CC" address. + * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return bool true on success, false if address already used + */ + public function addCC($address, $name = '') + { + return $this->addAnAddress('cc', $address, $name); + } + + /** + * Add a "BCC" address. + * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return bool true on success, false if address already used + */ + public function addBCC($address, $name = '') + { + return $this->addAnAddress('bcc', $address, $name); + } + + /** + * Add a "Reply-to" address. + * @param string $address + * @param string $name + * @return bool + */ + public function addReplyTo($address, $name = '') + { + return $this->addAnAddress('Reply-To', $address, $name); + } + + /** + * Add an address to one of the recipient arrays. + * Addresses that have been added already return false, but do not throw exceptions + * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' + * @param string $address The email address to send to + * @param string $name + * @throws phpmailerException + * @return bool true on success, false if address already used or invalid in some way + * @access protected + */ + protected function addAnAddress($kind, $address, $name = '') + { + if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { + $this->setError($this->lang('Invalid recipient array') . ': ' . $kind); + $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind); + if ($this->exceptions) { + throw new phpmailerException('Invalid recipient array: ' . $kind); + } + return false; + } + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!$this->validateAddress($address)) { + $this->setError($this->lang('invalid_address') . ': ' . $address); + $this->edebug($this->lang('invalid_address') . ': ' . $address); + if ($this->exceptions) { + throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + } + return false; + } + if ($kind != 'Reply-To') { + if (!isset($this->all_recipients[strtolower($address)])) { + array_push($this->$kind, array($address, $name)); + $this->all_recipients[strtolower($address)] = true; + return true; + } + } else { + if (!array_key_exists(strtolower($address), $this->ReplyTo)) { + $this->ReplyTo[strtolower($address)] = array($address, $name); + return true; + } + } + return false; + } + + /** + * Set the From and FromName properties. + * @param string $address + * @param string $name + * @param bool $auto Whether to also set the Sender address, defaults to true + * @throws phpmailerException + * @return bool + */ + public function setFrom($address, $name = '', $auto = true) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!$this->validateAddress($address)) { + $this->setError($this->lang('invalid_address') . ': ' . $address); + $this->edebug($this->lang('invalid_address') . ': ' . $address); + if ($this->exceptions) { + throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + } + return false; + } + $this->From = $address; + $this->FromName = $name; + if ($auto) { + if (empty($this->Sender)) { + $this->Sender = $address; + } + } + return true; + } + + /** + * Return the Message-ID header of the last email. + * Technically this is the value from the last time the headers were created, + * but it's also the message ID of the last sent message except in + * pathological cases. + * @return string + */ + public function getLastMessageID() + { + return $this->lastMessageID; + } + + /** + * Check that a string looks like an email address. + * @param string $address The email address to check + * @param string $patternselect A selector for the validation pattern to use : + * * `auto` Pick strictest one automatically; + * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14; + * * `pcre` Use old PCRE implementation; + * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; same as pcre8 but does not allow 'dotless' domains; + * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. + * * `noregex` Don't use a regex: super fast, really dumb. + * @return bool + * @static + * @access public + */ + public static function validateAddress($address, $patternselect = 'auto') + { + if (!$patternselect or $patternselect == 'auto') { + if (defined('PCRE_VERSION')) { //Check this constant so it works when extension_loaded() is disabled + if (version_compare(PCRE_VERSION, '8.0') >= 0) { + $patternselect = 'pcre8'; + } else { + $patternselect = 'pcre'; + } + } else { + //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension + if (version_compare(PHP_VERSION, '5.2.0') >= 0) { + $patternselect = 'php'; + } else { + $patternselect = 'noregex'; + } + } + } + switch ($patternselect) { + case 'pcre8': + /** + * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains. + * @link http://squiloople.com/2009/12/20/email-address-validation/ + * @copyright 2009-2010 Michael Rushton + * Feel free to use and redistribute this code. But please keep this copyright notice. + */ + return (bool)preg_match( + '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . + '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . + '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . + '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . + '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . + '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . + '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . + '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . + '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', + $address + ); + break; + case 'pcre': + //An older regex that doesn't need a recent PCRE + return (bool)preg_match( + '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' . + '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' . + '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' . + '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' . + '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' . + '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' . + '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' . + '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' . + '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' . + '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD', + $address + ); + break; + case 'html5': + /** + * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements. + * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email) + */ + return (bool)preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . + '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $address); + break; + case 'php': + default: + return (bool)filter_var($address, FILTER_VALIDATE_EMAIL); + break; + case 'noregex': + //No PCRE! Do something _very_ approximate! + //Check the address is 3 chars or longer and contains an @ that's not the first or last char + return (strlen($address) >= 3 + and strpos($address, '@') >= 1 + and strpos($address, '@') != strlen($address) - 1); + break; + } + } + + /** + * Create a message and send it. + * Uses the sending method specified by $Mailer. + * @throws phpmailerException + * @return bool false on error - See the ErrorInfo property for details of the error. + */ + public function send() + { + try { + if (!$this->preSend()) { + return false; + } + return $this->postSend(); + } catch (phpmailerException $exc) { + $this->mailHeader = ''; + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + } + + /** + * Prepare a message for sending. + * @throws phpmailerException + * @return bool + */ + public function preSend() + { + try { + $this->mailHeader = ''; + if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { + throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL); + } + + // Set whether the message is multipart/alternative + if (!empty($this->AltBody)) { + $this->ContentType = 'multipart/alternative'; + } + + $this->error_count = 0; // reset errors + $this->setMessageType(); + // Refuse to send an empty message unless we are specifically allowing it + if (!$this->AllowEmpty and empty($this->Body)) { + throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL); + } + + $this->MIMEHeader = $this->createHeader(); + $this->MIMEBody = $this->createBody(); + + // To capture the complete message when using mail(), create + // an extra header list which createHeader() doesn't fold in + if ($this->Mailer == 'mail') { + if (count($this->to) > 0) { + $this->mailHeader .= $this->addrAppend('To', $this->to); + } else { + $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + $this->mailHeader .= $this->headerLine( + 'Subject', + $this->encodeHeader($this->secureHeader(trim($this->Subject))) + ); + } + + // Sign with DKIM if enabled + if (!empty($this->DKIM_domain) + && !empty($this->DKIM_private) + && !empty($this->DKIM_selector) + && !empty($this->DKIM_domain) + && file_exists($this->DKIM_private)) { + $header_dkim = $this->DKIM_Add( + $this->MIMEHeader . $this->mailHeader, + $this->encodeHeader($this->secureHeader($this->Subject)), + $this->MIMEBody + ); + $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . + str_replace("\r\n", "\n", $header_dkim) . self::CRLF; + } + return true; + + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + } + + /** + * Actually send a message. + * Send the email via the selected mechanism + * @throws phpmailerException + * @return bool + */ + public function postSend() + { + try { + // Choose the mailer and send through it + switch ($this->Mailer) { + case 'sendmail': + case 'qmail': + return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody); + case 'smtp': + return $this->smtpSend($this->MIMEHeader, $this->MIMEBody); + case 'mail': + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + default: + $sendMethod = $this->Mailer.'Send'; + if (method_exists($this, $sendMethod)) { + return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody); + } + + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + } + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + } + return false; + } + + /** + * Send mail using the $Sendmail program. + * @param string $header The message headers + * @param string $body The message body + * @see PHPMailer::$Sendmail + * @throws phpmailerException + * @access protected + * @return bool + */ + protected function sendmailSend($header, $body) + { + if ($this->Sender != '') { + if ($this->Mailer == 'qmail') { + $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + } else { + $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + } + } else { + if ($this->Mailer == 'qmail') { + $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail)); + } else { + $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail)); + } + } + if ($this->SingleTo === true) { + foreach ($this->SingleToArray as $val) { + if (!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, 'To: ' . $val . "\n"); + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + if ($result != 0) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + } else { + if (!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + // implement call back function if it exists + $isSent = ($result == 0) ? 1 : 0; + $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + if ($result != 0) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + return true; + } + + /** + * Send mail using the PHP mail() function. + * @param string $header The message headers + * @param string $body The message body + * @link http://www.php.net/manual/en/book.mail.php + * @throws phpmailerException + * @access protected + * @return bool + */ + protected function mailSend($header, $body) + { + $toArr = array(); + foreach ($this->to as $toaddr) { + $toArr[] = $this->addrFormat($toaddr); + } + $to = implode(', ', $toArr); + + if (empty($this->Sender)) { + $params = ' '; + } else { + $params = sprintf('-f%s', $this->Sender); + } + if ($this->Sender != '' and !ini_get('safe_mode')) { + $old_from = ini_get('sendmail_from'); + ini_set('sendmail_from', $this->Sender); + } + $result = false; + if ($this->SingleTo === true && count($toArr) > 1) { + foreach ($toArr as $val) { + $result = $this->mailPassthru($val, $this->Subject, $body, $header, $params); + // implement call back function if it exists + $isSent = ($result == 1) ? 1 : 0; + $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + } + } else { + $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params); + // implement call back function if it exists + $isSent = ($result == 1) ? 1 : 0; + $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + } + if (isset($old_from)) { + ini_set('sendmail_from', $old_from); + } + if (!$result) { + throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL); + } + return true; + } + + /** + * Get an instance to use for SMTP operations. + * Override this function to load your own SMTP implementation + * @return SMTP + */ + public function getSMTPInstance() + { + if (!is_object($this->smtp)) { + $this->smtp = new SMTP; + } + return $this->smtp; + } + + /** + * Send mail via SMTP. + * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. + * Uses the PHPMailerSMTP class by default. + * @see PHPMailer::getSMTPInstance() to use a different class. + * @param string $header The message headers + * @param string $body The message body + * @throws phpmailerException + * @uses SMTP + * @access protected + * @return bool + */ + protected function smtpSend($header, $body) + { + $bad_rcpt = array(); + + if (!$this->smtpConnect()) { + throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); + } + $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; + if (!$this->smtp->mail($smtp_from)) { + $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); + throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL); + } + + // Attempt to send to all recipients + foreach ($this->to as $to) { + if (!$this->smtp->recipient($to[0])) { + $bad_rcpt[] = $to[0]; + $isSent = 0; + } else { + $isSent = 1; + } + $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body, $this->From); + } + foreach ($this->cc as $cc) { + if (!$this->smtp->recipient($cc[0])) { + $bad_rcpt[] = $cc[0]; + $isSent = 0; + } else { + $isSent = 1; + } + $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body, $this->From); + } + foreach ($this->bcc as $bcc) { + if (!$this->smtp->recipient($bcc[0])) { + $bad_rcpt[] = $bcc[0]; + $isSent = 0; + } else { + $isSent = 1; + } + $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body, $this->From); + } + + //Only send the DATA command if we have viable recipients + if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) { + throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL); + } + if ($this->SMTPKeepAlive == true) { + $this->smtp->reset(); + } else { + $this->smtp->quit(); + $this->smtp->close(); + } + if (count($bad_rcpt) > 0) { //Create error message for any bad addresses + throw new phpmailerException( + $this->lang('recipients_failed') . implode(', ', $bad_rcpt), + self::STOP_CONTINUE + ); + } + return true; + } + + /** + * Initiate a connection to an SMTP server. + * Returns false if the operation failed. + * @param array $options An array of options compatible with stream_context_create() + * @uses SMTP + * @access public + * @throws phpmailerException + * @return bool + */ + public function smtpConnect($options = array()) + { + if (is_null($this->smtp)) { + $this->smtp = $this->getSMTPInstance(); + } + + //Already connected? + if ($this->smtp->connected()) { + return true; + } + + $this->smtp->setTimeout($this->Timeout); + $this->smtp->setDebugLevel($this->SMTPDebug); + $this->smtp->setDebugOutput($this->Debugoutput); + $this->smtp->setVerp($this->do_verp); + $hosts = explode(';', $this->Host); + $lastexception = null; + + foreach ($hosts as $hostentry) { + $hostinfo = array(); + if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) { + //Not a valid host entry + continue; + } + //$hostinfo[2]: optional ssl or tls prefix + //$hostinfo[3]: the hostname + //$hostinfo[4]: optional port number + //The host string prefix can temporarily override the current setting for SMTPSecure + //If it's not specified, the default value is used + $prefix = ''; + $tls = ($this->SMTPSecure == 'tls'); + if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) { + $prefix = 'ssl://'; + $tls = false; //Can't have SSL and TLS at once + } elseif ($hostinfo[2] == 'tls') { + $tls = true; + //tls doesn't use a prefix + } + $host = $hostinfo[3]; + $port = $this->Port; + $tport = (integer)$hostinfo[4]; + if ($tport > 0 and $tport < 65536) { + $port = $tport; + } + if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { + try { + if ($this->Helo) { + $hello = $this->Helo; + } else { + $hello = $this->serverHostname(); + } + $this->smtp->hello($hello); + + if ($tls) { + if (!$this->smtp->startTLS()) { + throw new phpmailerException($this->lang('connect_host')); + } + //We must resend HELO after tls negotiation + $this->smtp->hello($hello); + } + if ($this->SMTPAuth) { + if (!$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, + $this->Workstation + ) + ) { + throw new phpmailerException($this->lang('authenticate')); + } + } + return true; + } catch (phpmailerException $exc) { + $lastexception = $exc; + //We must have connected, but then failed TLS or Auth, so close connection nicely + $this->smtp->quit(); + } + } + } + //If we get here, all connection attempts have failed, so close connection hard + $this->smtp->close(); + //As we've caught all exceptions, just report whatever the last one was + if ($this->exceptions and !is_null($lastexception)) { + throw $lastexception; + } + return false; + } + + /** + * Close the active SMTP session if one exists. + * @return void + */ + public function smtpClose() + { + if ($this->smtp !== null) { + if ($this->smtp->connected()) { + $this->smtp->quit(); + $this->smtp->close(); + } + } + } + + /** + * Set the language for error messages. + * Returns false if it cannot load the language file. + * The default language is English. + * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") + * @param string $lang_path Path to the language file directory, with trailing separator (slash) + * @return bool + * @access public + */ + public function setLanguage($langcode = 'en', $lang_path = '') + { + //Define full set of translatable strings in English + $PHPMAILER_LANG = array( + 'authenticate' => 'SMTP Error: Could not authenticate.', + 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', + 'data_not_accepted' => 'SMTP Error: data not accepted.', + 'empty_message' => 'Message body empty', + 'encoding' => 'Unknown encoding: ', + 'execute' => 'Could not execute: ', + 'file_access' => 'Could not access file: ', + 'file_open' => 'File Error: Could not open file: ', + 'from_failed' => 'The following From address failed: ', + 'instantiate' => 'Could not instantiate mail function.', + 'invalid_address' => 'Invalid address', + 'mailer_not_supported' => ' mailer is not supported.', + 'provide_address' => 'You must provide at least one recipient email address.', + 'recipients_failed' => 'SMTP Error: The following recipients failed: ', + 'signing' => 'Signing Error: ', + 'smtp_connect_failed' => 'SMTP connect() failed.', + 'smtp_error' => 'SMTP server error: ', + 'variable_set' => 'Cannot set or reset variable: ' + ); + if (empty($lang_path)) { + //Calculate an absolute path so it can work if CWD is not here + $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR; + } + $foundlang = true; + $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; + if ($langcode != 'en') { //There is no English translation file + //Make sure language file path is readable + if (!is_readable($lang_file)) { + $foundlang = false; + } else { + //Overwrite language-specific strings. + //This way we'll never have missing translations. + $foundlang = include $lang_file; + } + } + $this->language = $PHPMAILER_LANG; + return ($foundlang == true); //Returns false if language not found + } + + /** + * Get the array of strings for the current language. + * @return array + */ + public function getTranslations() + { + return $this->language; + } + + /** + * Create recipient headers. + * @access public + * @param string $type + * @param array $addr An array of recipient, + * where each recipient is a 2-element indexed array with element 0 containing an address + * and element 1 containing a name, like: + * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User')) + * @return string + */ + public function addrAppend($type, $addr) + { + $addresses = array(); + foreach ($addr as $address) { + $addresses[] = $this->addrFormat($address); + } + return $type . ': ' . implode(', ', $addresses) . $this->LE; + } + + /** + * Format an address for use in a message header. + * @access public + * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name + * like array('joe@example.com', 'Joe User') + * @return string + */ + public function addrFormat($addr) + { + if (empty($addr[1])) { // No name provided + return $this->secureHeader($addr[0]); + } else { + return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader( + $addr[0] + ) . '>'; + } + } + + /** + * Word-wrap message. + * For use with mailers that do not automatically perform wrapping + * and for quoted-printable encoded messages. + * Original written by philippe. + * @param string $message The message to wrap + * @param integer $length The line length to wrap to + * @param bool $qp_mode Whether to run in Quoted-Printable mode + * @access public + * @return string + */ + public function wrapText($message, $length, $qp_mode = false) + { + $soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $this->LE; + // If utf-8 encoding is used, we will need to make sure we don't + // split multibyte characters when we wrap + $is_utf8 = (strtolower($this->CharSet) == 'utf-8'); + $lelen = strlen($this->LE); + $crlflen = strlen(self::CRLF); + + $message = $this->fixEOL($message); + if (substr($message, -$lelen) == $this->LE) { + $message = substr($message, 0, -$lelen); + } + + $line = explode($this->LE, $message); // Magic. We know fixEOL uses $LE + $message = ''; + for ($i = 0; $i < count($line); $i++) { + $line_part = explode(' ', $line[$i]); + $buf = ''; + for ($e = 0; $e < count($line_part); $e++) { + $word = $line_part[$e]; + if ($qp_mode and (strlen($word) > $length)) { + $space_left = $length - strlen($buf) - $crlflen; + if ($e != 0) { + if ($space_left > 20) { + $len = $space_left; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == '=') { + $len--; + } elseif (substr($word, $len - 2, 1) == '=') { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= ' ' . $part; + $message .= $buf . sprintf('=%s', self::CRLF); + } else { + $message .= $buf . $soft_break; + } + $buf = ''; + } + while (strlen($word) > 0) { + if ($length <= 0) { + break; + } + $len = $length; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == '=') { + $len--; + } elseif (substr($word, $len - 2, 1) == '=') { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + + if (strlen($word) > 0) { + $message .= $part . sprintf('=%s', self::CRLF); + } else { + $buf = $part; + } + } + } else { + $buf_o = $buf; + $buf .= ($e == 0) ? $word : (' ' . $word); + + if (strlen($buf) > $length and $buf_o != '') { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + } + $message .= $buf . self::CRLF; + } + + return $message; + } + + /** + * Find the last character boundary prior to $maxLength in a utf-8 + * quoted (printable) encoded string. + * Original written by Colin Brown. + * @access public + * @param string $encodedText utf-8 QP text + * @param int $maxLength find last character boundary prior to this length + * @return int + */ + public function utf8CharBoundary($encodedText, $maxLength) + { + $foundSplitPos = false; + $lookBack = 3; + while (!$foundSplitPos) { + $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); + $encodedCharPos = strpos($lastChunk, '='); + if ($encodedCharPos !== false) { + // Found start of encoded character byte within $lookBack block. + // Check the encoded byte value (the 2 chars after the '=') + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); + $dec = hexdec($hex); + if ($dec < 128) { // Single byte character. + // If the encoded char was found at pos 0, it will fit + // otherwise reduce maxLength to start of the encoded char + $maxLength = ($encodedCharPos == 0) ? $maxLength : + $maxLength - ($lookBack - $encodedCharPos); + $foundSplitPos = true; + } elseif ($dec >= 192) { // First byte of a multi byte character + // Reduce maxLength to split at start of character + $maxLength = $maxLength - ($lookBack - $encodedCharPos); + $foundSplitPos = true; + } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back + $lookBack += 3; + } + } else { + // No encoded character found + $foundSplitPos = true; + } + } + return $maxLength; + } + + /** + * Set the body wrapping. + * @access public + * @return void + */ + public function setWordWrap() + { + if ($this->WordWrap < 1) { + return; + } + + switch ($this->message_type) { + case 'alt': + case 'alt_inline': + case 'alt_attach': + case 'alt_inline_attach': + $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->wrapText($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assemble message headers. + * @access public + * @return string The assembled headers + */ + public function createHeader() + { + $result = ''; + + // Set the boundaries + $uniq_id = md5(uniqid(time())); + $this->boundary[1] = 'b1_' . $uniq_id; + $this->boundary[2] = 'b2_' . $uniq_id; + $this->boundary[3] = 'b3_' . $uniq_id; + + if ($this->MessageDate == '') { + $this->MessageDate = self::rfcDate(); + } + $result .= $this->headerLine('Date', $this->MessageDate); + + + // To be created automatically by mail() + if ($this->SingleTo === true) { + if ($this->Mailer != 'mail') { + foreach ($this->to as $toaddr) { + $this->SingleToArray[] = $this->addrFormat($toaddr); + } + } + } else { + if (count($this->to) > 0) { + if ($this->Mailer != 'mail') { + $result .= $this->addrAppend('To', $this->to); + } + } elseif (count($this->cc) == 0) { + $result .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + } + + $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName))); + + // sendmail and mail() extract Cc from the header before sending + if (count($this->cc) > 0) { + $result .= $this->addrAppend('Cc', $this->cc); + } + + // sendmail and mail() extract Bcc from the header before sending + if (( + $this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail' + ) + and count($this->bcc) > 0 + ) { + $result .= $this->addrAppend('Bcc', $this->bcc); + } + + if (count($this->ReplyTo) > 0) { + $result .= $this->addrAppend('Reply-To', $this->ReplyTo); + } + + // mail() sets the subject itself + if ($this->Mailer != 'mail') { + $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); + } + + if ($this->MessageID != '') { + $this->lastMessageID = $this->MessageID; + } else { + $this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname()); + } + $result .= $this->HeaderLine('Message-ID', $this->lastMessageID); + $result .= $this->headerLine('X-Priority', $this->Priority); + if ($this->XMailer == '') { + $result .= $this->headerLine( + 'X-Mailer', + 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)' + ); + } else { + $myXmailer = trim($this->XMailer); + if ($myXmailer) { + $result .= $this->headerLine('X-Mailer', $myXmailer); + } + } + + if ($this->ConfirmReadingTo != '') { + $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); + } + + // Add custom headers + for ($index = 0; $index < count($this->CustomHeader); $index++) { + $result .= $this->headerLine( + trim($this->CustomHeader[$index][0]), + $this->encodeHeader(trim($this->CustomHeader[$index][1])) + ); + } + if (!$this->sign_key_file) { + $result .= $this->headerLine('MIME-Version', '1.0'); + $result .= $this->getMailMIME(); + } + + return $result; + } + + /** + * Get the message MIME type headers. + * @access public + * @return string + */ + public function getMailMIME() + { + $result = ''; + $ismultipart = true; + switch ($this->message_type) { + case 'inline': + $result .= $this->headerLine('Content-Type', 'multipart/related;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + case 'attach': + case 'inline_attach': + case 'alt_attach': + case 'alt_inline_attach': + $result .= $this->headerLine('Content-Type', 'multipart/mixed;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + case 'alt': + case 'alt_inline': + $result .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + default: + // Catches case 'plain': and case '': + $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet); + $ismultipart = false; + break; + } + //RFC1341 part 5 says 7bit is assumed if not specified + if ($this->Encoding != '7bit') { + //RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE + if ($ismultipart) { + if ($this->Encoding == '8bit') { + $result .= $this->headerLine('Content-Transfer-Encoding', '8bit'); + } + //The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible + } else { + $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding); + } + } + + if ($this->Mailer != 'mail') { + $result .= $this->LE; + } + + return $result; + } + + /** + * Returns the whole MIME message. + * Includes complete headers and body. + * Only valid post preSend(). + * @see PHPMailer::preSend() + * @access public + * @return string + */ + public function getSentMIMEMessage() + { + return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; + } + + + /** + * Assemble the message body. + * Returns an empty string on failure. + * @access public + * @throws phpmailerException + * @return string The assembled message body + */ + public function createBody() + { + $body = ''; + + if ($this->sign_key_file) { + $body .= $this->getMailMIME() . $this->LE; + } + + $this->setWordWrap(); + + $bodyEncoding = $this->Encoding; + $bodyCharSet = $this->CharSet; + if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) { + $bodyEncoding = '7bit'; + $bodyCharSet = 'us-ascii'; + } + $altBodyEncoding = $this->Encoding; + $altBodyCharSet = $this->CharSet; + if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) { + $altBodyEncoding = '7bit'; + $altBodyCharSet = 'us-ascii'; + } + switch ($this->message_type) { + case 'inline': + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[1]); + break; + case 'attach': + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'inline_attach': + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt': + $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + if (!empty($this->Ical)) { + $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', ''); + $body .= $this->encodeString($this->Ical, $this->Encoding); + $body .= $this->LE . $this->LE; + } + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_inline': + $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= $this->LE; + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_attach': + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->endBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt_inline_attach': + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->textLine('--' . $this->boundary[2]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[3]); + $body .= $this->LE; + $body .= $this->endBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + default: + // catch case 'plain' and case '' + $body .= $this->encodeString($this->Body, $bodyEncoding); + break; + } + + if ($this->isError()) { + $body = ''; + } elseif ($this->sign_key_file) { + try { + if (!defined('PKCS7_TEXT')) { + throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.'); + } + //TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1 + $file = tempnam(sys_get_temp_dir(), 'mail'); + file_put_contents($file, $body); //TODO check this worked + $signed = tempnam(sys_get_temp_dir(), 'signed'); + if (@openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), + null + ) + ) { + @unlink($file); + $body = file_get_contents($signed); + @unlink($signed); + } else { + @unlink($file); + @unlink($signed); + throw new phpmailerException($this->lang('signing') . openssl_error_string()); + } + } catch (phpmailerException $exc) { + $body = ''; + if ($this->exceptions) { + throw $exc; + } + } + } + return $body; + } + + /** + * Return the start of a message boundary. + * @access protected + * @param string $boundary + * @param string $charSet + * @param string $contentType + * @param string $encoding + * @return string + */ + protected function getBoundary($boundary, $charSet, $contentType, $encoding) + { + $result = ''; + if ($charSet == '') { + $charSet = $this->CharSet; + } + if ($contentType == '') { + $contentType = $this->ContentType; + } + if ($encoding == '') { + $encoding = $this->Encoding; + } + $result .= $this->textLine('--' . $boundary); + $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet); + $result .= $this->LE; + //RFC1341 part 5 says 7bit is assumed if not specified + if ($encoding != '7bit') { + $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); + } + $result .= $this->LE; + + return $result; + } + + /** + * Return the end of a message boundary. + * @access protected + * @param string $boundary + * @return string + */ + protected function endBoundary($boundary) + { + return $this->LE . '--' . $boundary . '--' . $this->LE; + } + + /** + * Set the message type. + * PHPMailer only supports some preset message types, + * not arbitrary MIME structures. + * @access protected + * @return void + */ + protected function setMessageType() + { + $this->message_type = array(); + if ($this->alternativeExists()) { + $this->message_type[] = 'alt'; + } + if ($this->inlineImageExists()) { + $this->message_type[] = 'inline'; + } + if ($this->attachmentExists()) { + $this->message_type[] = 'attach'; + } + $this->message_type = implode('_', $this->message_type); + if ($this->message_type == '') { + $this->message_type = 'plain'; + } + } + + /** + * Format a header line. + * @access public + * @param string $name + * @param string $value + * @return string + */ + public function headerLine($name, $value) + { + return $name . ': ' . $value . $this->LE; + } + + /** + * Return a formatted mail line. + * @access public + * @param string $value + * @return string + */ + public function textLine($value) + { + return $value . $this->LE; + } + + /** + * Add an attachment from a path on the filesystem. + * Returns false if the file could not be found or read. + * @param string $path Path to the attachment. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @param string $disposition Disposition to use + * @throws phpmailerException + * @return bool + */ + public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment') + { + try { + if (!@is_file($path)) { + throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE); + } + + //If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($path); + } + + $filename = basename($path); + if ($name == '') { + $name = $filename; + } + + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => 0 + ); + + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + return true; + } + + /** + * Return the array of attachments. + * @return array + */ + public function getAttachments() + { + return $this->attachment; + } + + /** + * Attach all file, string, and binary attachments to the message. + * Returns an empty string on failure. + * @access protected + * @param string $disposition_type + * @param string $boundary + * @return string + */ + protected function attachAll($disposition_type, $boundary) + { + // Return text of body + $mime = array(); + $cidUniq = array(); + $incl = array(); + + // Add all attachments + foreach ($this->attachment as $attachment) { + // Check if it is a valid disposition_filter + if ($attachment[6] == $disposition_type) { + // Check for string attachment + $string = ''; + $path = ''; + $bString = $attachment[5]; + if ($bString) { + $string = $attachment[0]; + } else { + $path = $attachment[0]; + } + + $inclhash = md5(serialize($attachment)); + if (in_array($inclhash, $incl)) { + continue; + } + $incl[] = $inclhash; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; + if ($disposition == 'inline' && isset($cidUniq[$cid])) { + continue; + } + $cidUniq[$cid] = true; + + $mime[] = sprintf('--%s%s', $boundary, $this->LE); + $mime[] = sprintf( + 'Content-Type: %s; name="%s"%s', + $type, + $this->encodeHeader($this->secureHeader($name)), + $this->LE + ); + //RFC1341 part 5 says 7bit is assumed if not specified + if ($encoding != '7bit') { + $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE); + } + + if ($disposition == 'inline') { + $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE); + } + + // If a filename contains any of these chars, it should be quoted, + // but not otherwise: RFC2183 & RFC2045 5.1 + // Fixes a warning in IETF's msglint MIME checker + // Allow for bypassing the Content-Disposition header totally + if (!(empty($disposition))) { + if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename="%s"%s', + $disposition, + $this->encodeHeader($this->secureHeader($name)), + $this->LE . $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Disposition: %s; filename=%s%s', + $disposition, + $this->encodeHeader($this->secureHeader($name)), + $this->LE . $this->LE + ); + } + } else { + $mime[] = $this->LE; + } + + // Encode as string attachment + if ($bString) { + $mime[] = $this->encodeString($string, $encoding); + if ($this->isError()) { + return ''; + } + $mime[] = $this->LE . $this->LE; + } else { + $mime[] = $this->encodeFile($path, $encoding); + if ($this->isError()) { + return ''; + } + $mime[] = $this->LE . $this->LE; + } + } + } + + $mime[] = sprintf('--%s--%s', $boundary, $this->LE); + + return implode('', $mime); + } + + /** + * Encode a file attachment in requested format. + * Returns an empty string on failure. + * @param string $path The full path to the file + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @throws phpmailerException + * @see EncodeFile(encodeFile + * @access protected + * @return string + */ + protected function encodeFile($path, $encoding = 'base64') + { + try { + if (!is_readable($path)) { + throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE); + } + $magic_quotes = get_magic_quotes_runtime(); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime(0); + } else { + ini_set('magic_quotes_runtime', 0); + } + } + $file_buffer = file_get_contents($path); + $file_buffer = $this->encodeString($file_buffer, $encoding); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime($magic_quotes); + } else { + ini_set('magic_quotes_runtime', $magic_quotes); + } + } + return $file_buffer; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + return ''; + } + } + + /** + * Encode a string in requested format. + * Returns an empty string on failure. + * @param string $str The text to encode + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @access public + * @return string + */ + public function encodeString($str, $encoding = 'base64') + { + $encoded = ''; + switch (strtolower($encoding)) { + case 'base64': + $encoded = chunk_split(base64_encode($str), 76, $this->LE); + break; + case '7bit': + case '8bit': + $encoded = $this->fixEOL($str); + //Make sure it ends with a line break + if (substr($encoded, -(strlen($this->LE))) != $this->LE) { + $encoded .= $this->LE; + } + break; + case 'binary': + $encoded = $str; + break; + case 'quoted-printable': + $encoded = $this->encodeQP($str); + break; + default: + $this->setError($this->lang('encoding') . $encoding); + break; + } + return $encoded; + } + + /** + * Encode a header string optimally. + * Picks shortest of Q, B, quoted-printable or none. + * @access public + * @param string $str + * @param string $position + * @return string + */ + public function encodeHeader($str, $position = 'text') + { + $matchcount = 0; + switch (strtolower($position)) { + case 'phrase': + if (!preg_match('/[\200-\377]/', $str)) { + // Can't use addslashes as we don't know the value of magic_quotes_sybase + $encoded = addcslashes($str, "\0..\37\177\\\""); + if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { + return ($encoded); + } else { + return ("\"$encoded\""); + } + } + $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); + break; + /** @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + $matchcount = preg_match_all('/[()"]/', $str, $matches); + // Intentional fall-through + case 'text': + default: + $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); + break; + } + + if ($matchcount == 0) { //There are no chars that need encoding + return ($str); + } + + $maxlen = 75 - 7 - strlen($this->CharSet); + // Try to select the encoding which should produce the shortest output + if ($matchcount > strlen($str) / 3) { + //More than a third of the content will need encoding, so B encoding will be most efficient + $encoding = 'B'; + if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) { + // Use a custom function which correctly encodes and wraps long + // multibyte strings without breaking lines within a character + $encoded = $this->base64EncodeWrapMB($str, "\n"); + } else { + $encoded = base64_encode($str); + $maxlen -= $maxlen % 4; + $encoded = trim(chunk_split($encoded, $maxlen, "\n")); + } + } else { + $encoding = 'Q'; + $encoded = $this->encodeQ($str, $position); + $encoded = $this->wrapText($encoded, $maxlen, true); + $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded)); + } + + $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded); + $encoded = trim(str_replace("\n", $this->LE, $encoded)); + + return $encoded; + } + + /** + * Check if a string contains multi-byte characters. + * @access public + * @param string $str multi-byte text to wrap encode + * @return bool + */ + public function hasMultiBytes($str) + { + if (function_exists('mb_strlen')) { + return (strlen($str) > mb_strlen($str, $this->CharSet)); + } else { // Assume no multibytes (we can't handle without mbstring functions anyway) + return false; + } + } + + /** + * Does a string contain any 8-bit chars (in any charset)? + * @param string $text + * @return bool + */ + public function has8bitChars($text) + { + return (bool)preg_match('/[\x80-\xFF]/', $text); + } + + /** + * Encode and wrap long multibyte strings for mail headers + * without breaking lines within a character. + * Adapted from a function by paravoid + * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 + * @access public + * @param string $str multi-byte text to wrap encode + * @param string $linebreak string to use as linefeed/end-of-line + * @return string + */ + public function base64EncodeWrapMB($str, $linebreak = null) + { + $start = '=?' . $this->CharSet . '?B?'; + $end = '?='; + $encoded = ''; + if ($linebreak === null) { + $linebreak = $this->LE; + } + + $mb_length = mb_strlen($str, $this->CharSet); + // Each line must have length <= 75, including $start and $end + $length = 75 - strlen($start) - strlen($end); + // Average multi-byte ratio + $ratio = $mb_length / strlen($str); + // Base64 has a 4:3 ratio + $avgLength = floor($length * $ratio * .75); + + for ($i = 0; $i < $mb_length; $i += $offset) { + $lookBack = 0; + do { + $offset = $avgLength - $lookBack; + $chunk = mb_substr($str, $i, $offset, $this->CharSet); + $chunk = base64_encode($chunk); + $lookBack++; + } while (strlen($chunk) > $length); + $encoded .= $chunk . $linebreak; + } + + // Chomp the last linefeed + $encoded = substr($encoded, 0, -strlen($linebreak)); + return $encoded; + } + + /** + * Encode a string in quoted-printable format. + * According to RFC2045 section 6.7. + * @access public + * @param string $string The text to encode + * @param integer $line_max Number of chars allowed on a line before wrapping + * @return string + * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment + */ + public function encodeQP($string, $line_max = 76) + { + if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3) + return $this->fixEOL(quoted_printable_encode($string)); + } + //Fall back to a pure PHP implementation + $string = str_replace( + array('%20', '%0D%0A.', '%0D%0A', '%'), + array(' ', "\r\n=2E", "\r\n", '='), + rawurlencode($string) + ); + $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string); + return $this->fixEOL($string); + } + + /** + * Backward compatibility wrapper for an old QP encoding function that was removed. + * @see PHPMailer::encodeQP() + * @access public + * @param string $string + * @param integer $line_max + * @param bool $space_conv + * @return string + * @deprecated Use encodeQP instead. + */ + public function encodeQPphp( + $string, + $line_max = 76, + /** @noinspection PhpUnusedParameterInspection */ $space_conv = false + ) { + return $this->encodeQP($string, $line_max); + } + + /** + * Encode a string using Q encoding. + * @link http://tools.ietf.org/html/rfc2047 + * @param string $str the text to encode + * @param string $position Where the text is going to be used, see the RFC for what that means + * @access public + * @return string + */ + public function encodeQ($str, $position = 'text') + { + //There should not be any EOL in the string + $pattern = ''; + $encoded = str_replace(array("\r", "\n"), '', $str); + switch (strtolower($position)) { + case 'phrase': + //RFC 2047 section 5.3 + $pattern = '^A-Za-z0-9!*+\/ -'; + break; + /** @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + //RFC 2047 section 5.2 + $pattern = '\(\)"'; + //intentional fall-through + //for this reason we build the $pattern without including delimiters and [] + case 'text': + default: + //RFC 2047 section 5.1 + //Replace every high ascii, control, =, ? and _ characters + $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; + break; + } + $matches = array(); + if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { + //If the string contains an '=', make sure it's the first thing we replace + //so as to avoid double-encoding + $eqkey = array_search('=', $matches[0]); + if ($eqkey !== false) { + unset($matches[0][$eqkey]); + array_unshift($matches[0], '='); + } + foreach (array_unique($matches[0]) as $char) { + $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); + } + } + //Replace every spaces to _ (more readable than =20) + return str_replace(' ', '_', $encoded); + } + + + /** + * Add a string or binary attachment (non-filesystem). + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * @param string $string String attachment data. + * @param string $filename Name of the attachment. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @param string $disposition Disposition to use + * @return void + */ + public function addStringAttachment( + $string, + $filename, + $encoding = 'base64', + $type = '', + $disposition = 'attachment' + ) { + //If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($filename); + } + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => basename($filename), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => 0 + ); + } + + /** + * Add an embedded (inline) attachment from a file. + * This can include images, sounds, and just about any other document type. + * These differ from 'regular' attachmants in that they are intended to be + * displayed inline with the message, not just attached for download. + * This is used in HTML messages that embed the images + * the HTML refers to using the $cid value. + * @param string $path Path to the attachment. + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File MIME type. + * @param string $disposition Disposition to use + * @return bool True on successfully adding an attachment + */ + public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') + { + if (!@is_file($path)) { + $this->setError($this->lang('file_access') . $path); + return false; + } + + //If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($path); + } + + $filename = basename($path); + if ($name == '') { + $name = $filename; + } + + // Append to $attachment array + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => $cid + ); + return true; + } + + /** + * Add an embedded stringified attachment. + * This can include images, sounds, and just about any other document type. + * Be sure to set the $type to an image type for images: + * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'. + * @param string $string The attachment binary data. + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML. + * @param string $name + * @param string $encoding File encoding (see $Encoding). + * @param string $type MIME type. + * @param string $disposition Disposition to use + * @return bool True on successfully adding an attachment + */ + public function addStringEmbeddedImage( + $string, + $cid, + $name = '', + $encoding = 'base64', + $type = '', + $disposition = 'inline' + ) { + //If a MIME type is not specified, try to work it out from the name + if ($type == '') { + $type = self::filenameToType($name); + } + + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $name, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => $cid + ); + return true; + } + + /** + * Check if an inline attachment is present. + * @access public + * @return bool + */ + public function inlineImageExists() + { + foreach ($this->attachment as $attachment) { + if ($attachment[6] == 'inline') { + return true; + } + } + return false; + } + + /** + * Check if an attachment (non-inline) is present. + * @return bool + */ + public function attachmentExists() + { + foreach ($this->attachment as $attachment) { + if ($attachment[6] == 'attachment') { + return true; + } + } + return false; + } + + /** + * Check if this message has an alternative body set. + * @return bool + */ + public function alternativeExists() + { + return !empty($this->AltBody); + } + + /** + * Clear all To recipients. + * @return void + */ + public function clearAddresses() + { + foreach ($this->to as $to) { + unset($this->all_recipients[strtolower($to[0])]); + } + $this->to = array(); + } + + /** + * Clear all CC recipients. + * @return void + */ + public function clearCCs() + { + foreach ($this->cc as $cc) { + unset($this->all_recipients[strtolower($cc[0])]); + } + $this->cc = array(); + } + + /** + * Clear all BCC recipients. + * @return void + */ + public function clearBCCs() + { + foreach ($this->bcc as $bcc) { + unset($this->all_recipients[strtolower($bcc[0])]); + } + $this->bcc = array(); + } + + /** + * Clear all ReplyTo recipients. + * @return void + */ + public function clearReplyTos() + { + $this->ReplyTo = array(); + } + + /** + * Clear all recipient types. + * @return void + */ + public function clearAllRecipients() + { + $this->to = array(); + $this->cc = array(); + $this->bcc = array(); + $this->all_recipients = array(); + } + + /** + * Clear all filesystem, string, and binary attachments. + * @return void + */ + public function clearAttachments() + { + $this->attachment = array(); + } + + /** + * Clear all custom headers. + * @return void + */ + public function clearCustomHeaders() + { + $this->CustomHeader = array(); + } + + /** + * Add an error message to the error container. + * @access protected + * @param string $msg + * @return void + */ + protected function setError($msg) + { + $this->error_count++; + if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { + $lasterror = $this->smtp->getError(); + if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) { + $msg .= '

' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "

\n"; + } + } + $this->ErrorInfo = $msg; + } + + /** + * Return an RFC 822 formatted date. + * @access public + * @return string + * @static + */ + public static function rfcDate() + { + //Set the time zone to whatever the default is to avoid 500 errors + //Will default to UTC if it's not set properly in php.ini + date_default_timezone_set(@date_default_timezone_get()); + return date('D, j M Y H:i:s O'); + } + + /** + * Get the server hostname. + * Returns 'localhost.localdomain' if unknown. + * @access protected + * @return string + */ + protected function serverHostname() + { + $result = 'localhost.localdomain'; + if (!empty($this->Hostname)) { + $result = $this->Hostname; + } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + $result = $_SERVER['SERVER_NAME']; + } elseif (function_exists('gethostname') && gethostname() !== false) { + $result = gethostname(); + } elseif (php_uname('n') !== false) { + $result = php_uname('n'); + } + return $result; + } + + /** + * Get an error message in the current language. + * @access protected + * @param string $key + * @return string + */ + protected function lang($key) + { + if (count($this->language) < 1) { + $this->setLanguage('en'); // set the default language + } + + if (isset($this->language[$key])) { + return $this->language[$key]; + } else { + return 'Language string failed to load: ' . $key; + } + } + + /** + * Check if an error occurred. + * @access public + * @return bool True if an error did occur. + */ + public function isError() + { + return ($this->error_count > 0); + } + + /** + * Ensure consistent line endings in a string. + * Changes every end of line from CRLF, CR or LF to $this->LE. + * @access public + * @param string $str String to fixEOL + * @return string + */ + public function fixEOL($str) + { + // Normalise to \n + $nstr = str_replace(array("\r\n", "\r"), "\n", $str); + // Now convert LE as needed + if ($this->LE !== "\n") { + $nstr = str_replace("\n", $this->LE, $nstr); + } + return $nstr; + } + + /** + * Add a custom header. + * $name value can be overloaded to contain + * both header name and value (name:value) + * @access public + * @param string $name Custom header name + * @param string $value Header value + * @return void + */ + public function addCustomHeader($name, $value = null) + { + if ($value === null) { + // Value passed in as name:value + $this->CustomHeader[] = explode(':', $name, 2); + } else { + $this->CustomHeader[] = array($name, $value); + } + } + + /** + * Create a message from an HTML string. + * Automatically makes modifications for inline images and backgrounds + * and creates a plain-text version by converting the HTML. + * Overwrites any existing values in $this->Body and $this->AltBody + * @access public + * @param string $message HTML message string + * @param string $basedir baseline directory for path + * @param bool $advanced Whether to use the advanced HTML to text converter + * @return string $message + */ + public function msgHTML($message, $basedir = '', $advanced = false) + { + preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images); + if (isset($images[2])) { + foreach ($images[2] as $imgindex => $url) { + // do not change urls for absolute images (thanks to corvuscorax) + if (!preg_match('#^[A-z]+://#', $url)) { + $filename = basename($url); + $directory = dirname($url); + if ($directory == '.') { + $directory = ''; + } + $cid = md5($url) . '@phpmailer.0'; //RFC2392 S 2 + if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { + $basedir .= '/'; + } + if (strlen($directory) > 1 && substr($directory, -1) != '/') { + $directory .= '/'; + } + if ($this->addEmbeddedImage( + $basedir . $directory . $filename, + $cid, + $filename, + 'base64', + self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION)) + ) + ) { + $message = preg_replace( + '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', + $images[1][$imgindex] . '="cid:' . $cid . '"', + $message + ); + } + } + } + } + $this->isHTML(true); + //Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better + $this->Body = $this->normalizeBreaks($message); + $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); + if (empty($this->AltBody)) { + $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . + self::CRLF . self::CRLF; + } + return $this->Body; + } + + /** + * Convert an HTML string into plain text. + * @param string $html The HTML text to convert + * @param bool $advanced Should this use the more complex html2text converter or just a simple one? + * @return string + */ + public function html2text($html, $advanced = false) + { + if ($advanced) { + require_once 'extras/class.html2text.php'; + $htmlconverter = new html2text($html); + return $htmlconverter->get_text(); + } + return html_entity_decode( + trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), + ENT_QUOTES, + $this->CharSet + ); + } + + /** + * Get the MIME type for a file extension. + * @param string $ext File extension + * @access public + * @return string MIME type of file. + * @static + */ + public static function _mime_types($ext = '') + { + $mimes = array( + 'xl' => 'application/excel', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'bin' => 'application/macbinary', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'class' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mpga' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'eml' => 'message/rfc822', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'log' => 'text/plain', + 'text' => 'text/plain', + 'txt' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'vcf' => 'text/vcard', + 'vcard' => 'text/vcard', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mov' => 'video/quicktime', + 'qt' => 'video/quicktime', + 'rv' => 'video/vnd.rn-realvideo', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie' + ); + return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)]: 'application/octet-stream'); + } + + /** + * Map a file name to a MIME type. + * Defaults to 'application/octet-stream', i.e.. arbitrary binary data. + * @param string $filename A file name or full path, does not need to exist as a file + * @return string + * @static + */ + public static function filenameToType($filename) + { + //In case the path is a URL, strip any query string before getting extension + $qpos = strpos($filename, '?'); + if ($qpos !== false) { + $filename = substr($filename, 0, $qpos); + } + $pathinfo = self::mb_pathinfo($filename); + return self::_mime_types($pathinfo['extension']); + } + + /** + * Multi-byte-safe pathinfo replacement. + * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe. + * Works similarly to the one in PHP >= 5.2.0 + * @link http://www.php.net/manual/en/function.pathinfo.php#107461 + * @param string $path A filename or path, does not need to exist as a file + * @param integer|string $options Either a PATHINFO_* constant, + * or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2 + * @return string|array + * @static + */ + public static function mb_pathinfo($path, $options = null) + { + $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => ''); + $pathinfo = array(); + preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo); + if (array_key_exists(1, $pathinfo)) { + $ret['dirname'] = $pathinfo[1]; + } + if (array_key_exists(2, $pathinfo)) { + $ret['basename'] = $pathinfo[2]; + } + if (array_key_exists(5, $pathinfo)) { + $ret['extension'] = $pathinfo[5]; + } + if (array_key_exists(3, $pathinfo)) { + $ret['filename'] = $pathinfo[3]; + } + switch ($options) { + case PATHINFO_DIRNAME: + case 'dirname': + return $ret['dirname']; + break; + case PATHINFO_BASENAME: + case 'basename': + return $ret['basename']; + break; + case PATHINFO_EXTENSION: + case 'extension': + return $ret['extension']; + break; + case PATHINFO_FILENAME: + case 'filename': + return $ret['filename']; + break; + default: + return $ret; + } + } + + /** + * Set or reset instance properties. + * + * Usage Example: + * $page->set('X-Priority', '3'); + * + * @access public + * @param string $name + * @param mixed $value + * NOTE: will not work with arrays, there are no arrays to set/reset + * @throws phpmailerException + * @return bool + * @todo Should this not be using __set() magic function? + */ + public function set($name, $value = '') + { + try { + if (isset($this->$name)) { + $this->$name = $value; + } else { + throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL); + } + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + if ($exc->getCode() == self::STOP_CRITICAL) { + return false; + } + } + return true; + } + + /** + * Strip newlines to prevent header injection. + * @access public + * @param string $str + * @return string + */ + public function secureHeader($str) + { + return trim(str_replace(array("\r", "\n"), '', $str)); + } + + /** + * Normalize line breaks in a string. + * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. + * Defaults to CRLF (for message bodies) and preserves consecutive breaks. + * @param string $text + * @param string $breaktype What kind of line break to use, defaults to CRLF + * @return string + * @access public + * @static + */ + public static function normalizeBreaks($text, $breaktype = "\r\n") + { + return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text); + } + + + /** + * Set the public and private key files and password for S/MIME signing. + * @access public + * @param string $cert_filename + * @param string $key_filename + * @param string $key_pass Password for private key + */ + public function sign($cert_filename, $key_filename, $key_pass) + { + $this->sign_cert_file = $cert_filename; + $this->sign_key_file = $key_filename; + $this->sign_key_pass = $key_pass; + } + + /** + * Quoted-Printable-encode a DKIM header. + * @access public + * @param string $txt + * @return string + */ + public function DKIM_QP($txt) + { + $line = ''; + for ($i = 0; $i < strlen($txt); $i++) { + $ord = ord($txt[$i]); + if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) { + $line .= $txt[$i]; + } else { + $line .= '=' . sprintf('%02X', $ord); + } + } + return $line; + } + + /** + * Generate a DKIM signature. + * @access public + * @param string $signheader Header + * @throws phpmailerException + * @return string + */ + public function DKIM_Sign($signheader) + { + if (!defined('PKCS7_TEXT')) { + if ($this->exceptions) { + throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.'); + } + return ''; + } + $privKeyStr = file_get_contents($this->DKIM_private); + if ($this->DKIM_passphrase != '') { + $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); + } else { + $privKey = $privKeyStr; + } + if (openssl_sign($signheader, $signature, $privKey)) { + return base64_encode($signature); + } + return ''; + } + + /** + * Generate a DKIM canonicalization header. + * @access public + * @param string $signheader Header + * @return string + */ + public function DKIM_HeaderC($signheader) + { + $signheader = preg_replace('/\r\n\s+/', ' ', $signheader); + $lines = explode("\r\n", $signheader); + foreach ($lines as $key => $line) { + list($heading, $value) = explode(':', $line, 2); + $heading = strtolower($heading); + $value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces + $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value + } + $signheader = implode("\r\n", $lines); + return $signheader; + } + + /** + * Generate a DKIM canonicalization body. + * @access public + * @param string $body Message Body + * @return string + */ + public function DKIM_BodyC($body) + { + if ($body == '') { + return "\r\n"; + } + // stabilize line endings + $body = str_replace("\r\n", "\n", $body); + $body = str_replace("\n", "\r\n", $body); + // END stabilize line endings + while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { + $body = substr($body, 0, strlen($body) - 2); + } + return $body; + } + + /** + * Create the DKIM header and body in a new message header. + * @access public + * @param string $headers_line Header lines + * @param string $subject Subject + * @param string $body Body + * @return string + */ + public function DKIM_Add($headers_line, $subject, $body) + { + $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body + $DKIMquery = 'dns/txt'; // Query method + $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) + $subject_header = "Subject: $subject"; + $headers = explode($this->LE, $headers_line); + $from_header = ''; + $to_header = ''; + $current = ''; + foreach ($headers as $header) { + if (strpos($header, 'From:') === 0) { + $from_header = $header; + $current = 'from_header'; + } elseif (strpos($header, 'To:') === 0) { + $to_header = $header; + $current = 'to_header'; + } else { + if ($current && strpos($header, ' =?') === 0) { + $current .= $header; + } else { + $current = ''; + } + } + } + $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); + $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); + $subject = str_replace( + '|', + '=7C', + $this->DKIM_QP($subject_header) + ); // Copied header fields (dkim-quoted-printable) + $body = $this->DKIM_BodyC($body); + $DKIMlen = strlen($body); // Length of body + $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body + $ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';'; + $dkimhdrs = 'DKIM-Signature: v=1; a=' . + $DKIMsignatureType . '; q=' . + $DKIMquery . '; l=' . + $DKIMlen . '; s=' . + $this->DKIM_selector . + ";\r\n" . + "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" . + "\th=From:To:Subject;\r\n" . + "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" . + "\tz=$from\r\n" . + "\t|$to\r\n" . + "\t|$subject;\r\n" . + "\tbh=" . $DKIMb64 . ";\r\n" . + "\tb="; + $toSign = $this->DKIM_HeaderC( + $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs + ); + $signed = $this->DKIM_Sign($toSign); + return $dkimhdrs . $signed . "\r\n"; + } + + /** + * Allows for public read access to 'to' property. + * @access public + * @return array + */ + public function getToAddresses() + { + return $this->to; + } + + /** + * Allows for public read access to 'cc' property. + * @access public + * @return array + */ + public function getCcAddresses() + { + return $this->cc; + } + + /** + * Allows for public read access to 'bcc' property. + * @access public + * @return array + */ + public function getBccAddresses() + { + return $this->bcc; + } + + /** + * Allows for public read access to 'ReplyTo' property. + * @access public + * @return array + */ + public function getReplyToAddresses() + { + return $this->ReplyTo; + } + + /** + * Allows for public read access to 'all_recipients' property. + * @access public + * @return array + */ + public function getAllRecipientAddresses() + { + return $this->all_recipients; + } + + /** + * Perform a callback. + * @param bool $isSent + * @param string $to + * @param string $cc + * @param string $bcc + * @param string $subject + * @param string $body + * @param string $from + */ + protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from = null) + { + if (!empty($this->action_function) && is_callable($this->action_function)) { + $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from); + call_user_func_array($this->action_function, $params); + } + } +} + +/** + * PHPMailer exception handler + * @package PHPMailer + */ +class phpmailerException extends Exception +{ + /** + * Prettify error message output + * @return string + */ + public function errorMessage() + { + $errorMsg = '' . $this->getMessage() . "
\n"; + return $errorMsg; + } +} + +} diff --git a/app/lib/PHPMailerAutoload.inc b/app/lib/PHPMailerAutoload.inc new file mode 100644 index 00000000..1bfc950e --- /dev/null +++ b/app/lib/PHPMailerAutoload.inc @@ -0,0 +1,86 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\lib + { + + + /** + * Class to ensure that Compatibility library below is loaded. + * + * @author Oliver Hanraths + */ + class PHPMailerAutoload + { + + /** + * Call this function to ensure this file is loaded. + */ + public static function load() + { + } + + } + + } + + namespace { + +/** + * PHPMailer SPL autoloader. + * PHP Version 5 + * @package PHPMailer + * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailer SPL autoloader. + * @param string $classname The name of the class to load + */ +function PHPMailerAutoload($classname) +{ + //Can't use __DIR__ as it's only in PHP 5.3+ + $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php'; + if (is_readable($filename)) { + require $filename; + } +} + +if (version_compare(PHP_VERSION, '5.1.2', '>=')) { + //SPL autoloading was introduced in PHP 5.1.2 + if (version_compare(PHP_VERSION, '5.3.0', '>=')) { + spl_autoload_register('PHPMailerAutoload', true, true); + } else { + spl_autoload_register('PHPMailerAutoload'); + } +} else { + /** + * Fall back to traditional autoload for old PHP versions + * @param string $classname The name of the class to load + */ + function __autoload($classname) + { + PHPMailerAutoload($classname); + } +} + +} diff --git a/app/lib/Password.inc b/app/lib/Password.inc new file mode 100644 index 00000000..f9acf7d5 --- /dev/null +++ b/app/lib/Password.inc @@ -0,0 +1,316 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\lib + { + + + /** + * Class to ensure that Compatibility library below is loaded. + * + * @author Oliver Hanraths + */ + class Password + { + + /** + * Call this function to ensure this file is loaded. + */ + public static function load() + { + } + + } + + } + + + + +/** + * A Compatibility library with PHP 5.5's simplified password hashing API. + * + * @author Anthony Ferrara + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @copyright 2012 The Authors + */ + +namespace { + +if (!defined('PASSWORD_DEFAULT')) { + + define('PASSWORD_BCRYPT', 1); + define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); + + /** + * Hash the password using the specified algorithm + * + * @param string $password The password to hash + * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) + * @param array $options The options for the algorithm to use + * + * @return string|false The hashed password, or false on error. + */ + function password_hash($password, $algo, array $options = array()) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); + return null; + } + if (!is_string($password)) { + trigger_error("password_hash(): Password must be a string", E_USER_WARNING); + return null; + } + if (!is_int($algo)) { + trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); + return null; + } + $resultLength = 0; + switch ($algo) { + case PASSWORD_BCRYPT: + // Note that this is a C constant, but not exposed to PHP, so we don't define it here. + $cost = 10; + if (isset($options['cost'])) { + $cost = $options['cost']; + if ($cost < 4 || $cost > 31) { + trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); + return null; + } + } + // The length of salt to generate + $raw_salt_len = 16; + // The length required in the final serialization + $required_salt_len = 22; + $hash_format = sprintf("$2y$%02d$", $cost); + // The expected length of the final crypt() output + $resultLength = 60; + break; + default: + trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); + return null; + } + $salt_requires_encoding = false; + if (isset($options['salt'])) { + switch (gettype($options['salt'])) { + case 'NULL': + case 'boolean': + case 'integer': + case 'double': + case 'string': + $salt = (string) $options['salt']; + break; + case 'object': + if (method_exists($options['salt'], '__tostring')) { + $salt = (string) $options['salt']; + break; + } + case 'array': + case 'resource': + default: + trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); + return null; + } + if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) { + trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING); + return null; + } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { + $salt_requires_encoding = true; + } + } else { + $buffer = ''; + $buffer_valid = false; + if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { + $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { + $buffer = openssl_random_pseudo_bytes($raw_salt_len); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && @is_readable('/dev/urandom')) { + $f = fopen('/dev/urandom', 'r'); + $read = PasswordCompat\binary\_strlen($buffer); + while ($read < $raw_salt_len) { + $buffer .= fread($f, $raw_salt_len - $read); + $read = PasswordCompat\binary\_strlen($buffer); + } + fclose($f); + if ($read >= $raw_salt_len) { + $buffer_valid = true; + } + } + if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) { + $bl = PasswordCompat\binary\_strlen($buffer); + for ($i = 0; $i < $raw_salt_len; $i++) { + if ($i < $bl) { + $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); + } else { + $buffer .= chr(mt_rand(0, 255)); + } + } + } + $salt = $buffer; + $salt_requires_encoding = true; + } + if ($salt_requires_encoding) { + // encode string with the Base64 variant used by crypt + $base64_digits = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + $bcrypt64_digits = + './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + $base64_string = base64_encode($salt); + $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits); + } + $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len); + + $hash = $hash_format . $salt; + + $ret = crypt($password, $hash); + + if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) { + return false; + } + + return $ret; + } + + /** + * Get information about the password hash. Returns an array of the information + * that was used to generate the password hash. + * + * array( + * 'algo' => 1, + * 'algoName' => 'bcrypt', + * 'options' => array( + * 'cost' => 10, + * ), + * ) + * + * @param string $hash The password hash to extract info from + * + * @return array The array of information about the hash. + */ + function password_get_info($hash) { + $return = array( + 'algo' => 0, + 'algoName' => 'unknown', + 'options' => array(), + ); + if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) { + $return['algo'] = PASSWORD_BCRYPT; + $return['algoName'] = 'bcrypt'; + list($cost) = sscanf($hash, "$2y$%d$"); + $return['options']['cost'] = $cost; + } + return $return; + } + + /** + * Determine if the password hash needs to be rehashed according to the options provided + * + * If the answer is true, after validating the password using password_verify, rehash it. + * + * @param string $hash The hash to test + * @param int $algo The algorithm used for new password hashes + * @param array $options The options array passed to password_hash + * + * @return boolean True if the password needs to be rehashed. + */ + function password_needs_rehash($hash, $algo, array $options = array()) { + $info = password_get_info($hash); + if ($info['algo'] != $algo) { + return true; + } + switch ($algo) { + case PASSWORD_BCRYPT: + $cost = isset($options['cost']) ? $options['cost'] : 10; + if ($cost != $info['options']['cost']) { + return true; + } + break; + } + return false; + } + + /** + * Verify a password against a hash using a timing attack resistant approach + * + * @param string $password The password to verify + * @param string $hash The hash to verify against + * + * @return boolean If the password matches the hash + */ + function password_verify($password, $hash) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); + return false; + } + $ret = crypt($password, $hash); + if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) { + return false; + } + + $status = 0; + for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) { + $status |= (ord($ret[$i]) ^ ord($hash[$i])); + } + + return $status === 0; + } +} + +} + +namespace PasswordCompat\binary { + /** + * Count the number of bytes in a string + * + * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension. + * In this case, strlen() will count the number of *characters* based on the internal encoding. A + * sequence of bytes might be regarded as a single multibyte character. + * + * @param string $binary_string The input string + * + * @internal + * @return int The number of bytes + */ + function _strlen($binary_string) { + if (function_exists('mb_strlen')) { + return mb_strlen($binary_string, '8bit'); + } + return strlen($binary_string); + } + + /** + * Get a substring based on byte limits + * + * @see _strlen() + * + * @param string $binary_string The input string + * @param int $start + * @param int $length + * + * @internal + * @return string The substring + */ + function _substr($binary_string, $start, $length) { + if (function_exists('mb_substr')) { + return mb_substr($binary_string, $start, $length, '8bit'); + } + return substr($binary_string, $start, $length); + } + +} diff --git a/app/lib/SMTP.inc b/app/lib/SMTP.inc new file mode 100644 index 00000000..b616373e --- /dev/null +++ b/app/lib/SMTP.inc @@ -0,0 +1,972 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\lib + { + + + /** + * Class to ensure that Compatibility library below is loaded. + * + * @author Oliver Hanraths + */ + class SMTP + { + + /** + * Call this function to ensure this file is loaded. + */ + public static function load() + { + } + + } + + } + + namespace { + +/** + * PHPMailer RFC821 SMTP email transport class. + * PHP Version 5 + * @package PHPMailer + * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project + * @author Marcus Bointon (Synchro/coolbru) + * @author Jim Jagielski (jimjag) + * @author Andy Prevost (codeworxtech) + * @author Brent R. Matzelle (original founder) + * @copyright 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailer RFC821 SMTP email transport class. + * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. + * @package PHPMailer + * @author Chris Ryan + * @author Marcus Bointon + */ +class SMTP +{ + /** + * The PHPMailer SMTP version number. + * @type string + */ + const VERSION = '5.2.8'; + + /** + * SMTP line break constant. + * @type string + */ + const CRLF = "\r\n"; + + /** + * The SMTP port to use if one is not specified. + * @type int + */ + const DEFAULT_SMTP_PORT = 25; + + /** + * The maximum line length allowed by RFC 2822 section 2.1.1 + * @type int + */ + const MAX_LINE_LENGTH = 998; + + /** + * The PHPMailer SMTP Version number. + * @type string + * @deprecated Use the constant instead + * @see SMTP::VERSION + */ + public $Version = '5.2.8'; + + /** + * SMTP server port number. + * @type int + * @deprecated This is only ever used as a default value, so use the constant instead + * @see SMTP::DEFAULT_SMTP_PORT + */ + public $SMTP_PORT = 25; + + /** + * SMTP reply line ending. + * @type string + * @deprecated Use the constant instead + * @see SMTP::CRLF + */ + public $CRLF = "\r\n"; + + /** + * Debug output level. + * Options: + * * `0` No output + * * `1` Commands + * * `2` Data and commands + * * `3` As 2 plus connection status + * * `4` Low-level data output + * @type int + */ + public $do_debug = 0; + + /** + * How to handle debug output. + * Options: + * * `echo` Output plain-text as-is, appropriate for CLI + * * `html` Output escaped, line breaks converted to
, appropriate for browser output + * * `error_log` Output to error log as configured in php.ini + * @type string + */ + public $Debugoutput = 'echo'; + + /** + * Whether to use VERP. + * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @link http://www.postfix.org/VERP_README.html Info on VERP + * @type bool + */ + public $do_verp = false; + + /** + * The timeout value for connection, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. + * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2 + * @type int + */ + public $Timeout = 300; + + /** + * The SMTP timelimit value for reads, in seconds. + * @type int + */ + public $Timelimit = 30; + + /** + * The socket for the server connection. + * @type resource + */ + protected $smtp_conn; + + /** + * Error message, if any, for the last call. + * @type string + */ + protected $error = ''; + + /** + * The reply the server sent to us for HELO. + * @type string + */ + protected $helo_rply = ''; + + /** + * The most recent reply received from the server. + * @type string + */ + protected $last_reply = ''; + + /** + * Constructor. + * @access public + */ + public function __construct() + { + $this->smtp_conn = 0; + $this->error = null; + $this->helo_rply = null; + $this->do_debug = 0; + } + + /** + * Output debugging info via a user-selected method. + * @param string $str Debug string to output + * @return void + */ + protected function edebug($str) + { + switch ($this->Debugoutput) { + case 'error_log': + //Don't output, just log + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking, HTML-safe output + echo htmlentities( + preg_replace('/[\r\n]+/', '', $str), + ENT_QUOTES, + 'UTF-8' + ) + . "
\n"; + break; + case 'echo': + default: + echo gmdate('Y-m-d H:i:s')."\t".trim($str)."\n"; + } + } + + /** + * Connect to an SMTP server. + * @param string $host SMTP server IP or host name + * @param int $port The port number to connect to + * @param int $timeout How long to wait for the connection to open + * @param array $options An array of options for stream_context_create() + * @access public + * @return bool + */ + public function connect($host, $port = null, $timeout = 30, $options = array()) + { + // Clear errors to avoid confusion + $this->error = null; + // Make sure we are __not__ connected + if ($this->connected()) { + // Already connected, generate error + $this->error = array('error' => 'Already connected to a server'); + return false; + } + if (empty($port)) { + $port = self::DEFAULT_SMTP_PORT; + } + // Connect to the SMTP server + if ($this->do_debug >= 3) { + $this->edebug('Connection: opening'); + } + $errno = 0; + $errstr = ''; + $socket_context = stream_context_create($options); + //Suppress errors; connection failures are handled at a higher level + $this->smtp_conn = @stream_socket_client( + $host . ":" . $port, + $errno, + $errstr, + $timeout, + STREAM_CLIENT_CONNECT, + $socket_context + ); + // Verify we connected properly + if (empty($this->smtp_conn)) { + $this->error = array( + 'error' => 'Failed to connect to server', + 'errno' => $errno, + 'errstr' => $errstr + ); + if ($this->do_debug >= 1) { + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] + . ": $errstr ($errno)" + ); + } + return false; + } + if ($this->do_debug >= 3) { + $this->edebug('Connection: opened'); + } + // SMTP server can take longer to respond, give longer timeout for first read + // Windows does not have support for this timeout function + if (substr(PHP_OS, 0, 3) != 'WIN') { + $max = ini_get('max_execution_time'); + if ($max != 0 && $timeout > $max) { // Don't bother if unlimited + @set_time_limit($timeout); + } + stream_set_timeout($this->smtp_conn, $timeout, 0); + } + // Get any announcement + $announce = $this->get_lines(); + if ($this->do_debug >= 2) { + $this->edebug('SERVER -> CLIENT: ' . $announce); + } + return true; + } + + /** + * Initiate a TLS (encrypted) session. + * @access public + * @return bool + */ + public function startTLS() + { + if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { + return false; + } + // Begin encrypted connection + if (!stream_socket_enable_crypto( + $this->smtp_conn, + true, + STREAM_CRYPTO_METHOD_TLS_CLIENT + )) { + return false; + } + return true; + } + + /** + * Perform SMTP authentication. + * Must be run after hello(). + * @see hello() + * @param string $username The user name + * @param string $password The password + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) + * @param string $realm The auth realm for NTLM + * @param string $workstation The auth workstation for NTLM + * @access public + * @return bool True if successfully authenticated. + */ + public function authenticate( + $username, + $password, + $authtype = 'LOGIN', + $realm = '', + $workstation = '' + ) { + if (empty($authtype)) { + $authtype = 'LOGIN'; + } + switch ($authtype) { + case 'PLAIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { + return false; + } + // Send encoded username and password + if (!$this->sendCommand( + 'User & Password', + base64_encode("\0" . $username . "\0" . $password), + 235 + ) + ) { + return false; + } + break; + case 'LOGIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { + return false; + } + if (!$this->sendCommand("Username", base64_encode($username), 334)) { + return false; + } + if (!$this->sendCommand("Password", base64_encode($password), 235)) { + return false; + } + break; + case 'NTLM': + /* + * ntlm_sasl_client.php + * Bundled with Permission + * + * How to telnet in windows: + * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx + * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication + */ + require_once 'extras/ntlm_sasl_client.php'; + $temp = new stdClass(); + $ntlm_client = new ntlm_sasl_client_class; + //Check that functions are available + if (!$ntlm_client->Initialize($temp)) { + $this->error = array('error' => $temp->error); + if ($this->do_debug >= 1) { + $this->edebug( + 'You need to enable some modules in your php.ini file: ' + . $this->error['error'] + ); + } + return false; + } + //msg1 + $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1 + + if (!$this->sendCommand( + 'AUTH NTLM', + 'AUTH NTLM ' . base64_encode($msg1), + 334 + ) + ) { + return false; + } + //Though 0 based, there is a white space after the 3 digit number + //msg2 + $challenge = substr($this->last_reply, 3); + $challenge = base64_decode($challenge); + $ntlm_res = $ntlm_client->NTLMResponse( + substr($challenge, 24, 8), + $password + ); + //msg3 + $msg3 = $ntlm_client->TypeMsg3( + $ntlm_res, + $username, + $realm, + $workstation + ); + // send encoded username + return $this->sendCommand('Username', base64_encode($msg3), 235); + break; + case 'CRAM-MD5': + // Start authentication + if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { + return false; + } + // Get the challenge + $challenge = base64_decode(substr($this->last_reply, 4)); + + // Build the response + $response = $username . ' ' . $this->hmac($challenge, $password); + + // send encoded credentials + return $this->sendCommand('Username', base64_encode($response), 235); + break; + } + return true; + } + + /** + * Calculate an MD5 HMAC hash. + * Works like hash_hmac('md5', $data, $key) + * in case that function is not available + * @param string $data The data to hash + * @param string $key The key to hash with + * @access protected + * @return string + */ + protected function hmac($data, $key) + { + if (function_exists('hash_hmac')) { + return hash_hmac('md5', $data, $key); + } + + // The following borrowed from + // http://php.net/manual/en/function.mhash.php#27225 + + // RFC 2104 HMAC implementation for php. + // Creates an md5 HMAC. + // Eliminates the need to install mhash to compute a HMAC + // Hacked by Lance Rushing + + $bytelen = 64; // byte length for md5 + if (strlen($key) > $bytelen) { + $key = pack('H*', md5($key)); + } + $key = str_pad($key, $bytelen, chr(0x00)); + $ipad = str_pad('', $bytelen, chr(0x36)); + $opad = str_pad('', $bytelen, chr(0x5c)); + $k_ipad = $key ^ $ipad; + $k_opad = $key ^ $opad; + + return md5($k_opad . pack('H*', md5($k_ipad . $data))); + } + + /** + * Check connection state. + * @access public + * @return bool True if connected. + */ + public function connected() + { + if (!empty($this->smtp_conn)) { + $sock_status = stream_get_meta_data($this->smtp_conn); + if ($sock_status['eof']) { + // the socket is valid but we are not connected + if ($this->do_debug >= 1) { + $this->edebug( + 'SMTP NOTICE: EOF caught while checking if connected' + ); + } + $this->close(); + return false; + } + return true; // everything looks good + } + return false; + } + + /** + * Close the socket and clean up the state of the class. + * Don't use this function without first trying to use QUIT. + * @see quit() + * @access public + * @return void + */ + public function close() + { + $this->error = null; // so there is no confusion + $this->helo_rply = null; + if (!empty($this->smtp_conn)) { + // close the connection and cleanup + fclose($this->smtp_conn); + if ($this->do_debug >= 3) { + $this->edebug('Connection: closed'); + } + $this->smtp_conn = 0; + } + } + + /** + * Send an SMTP DATA command. + * Issues a data command and sends the msg_data to the server, + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a with the message headers + * and the message body being separated by and additional . + * Implements rfc 821: DATA + * @param string $msg_data Message data to send + * @access public + * @return bool + */ + public function data($msg_data) + { + if (!$this->sendCommand('DATA', 'DATA', 354)) { + return false; + } + /* The server is ready to accept data! + * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) + * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into + * smaller lines to fit within the limit. + * We will also look for lines that start with a '.' and prepend an additional '.'. + * NOTE: this does not count towards line-length limit. + */ + + // Normalize line breaks before exploding + $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data)); + + /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field + * of the first line (':' separated) does not contain a space then it _should_ be a header and we will + * process all lines before a blank line as headers. + */ + + $field = substr($lines[0], 0, strpos($lines[0], ':')); + $in_headers = false; + if (!empty($field) && strpos($field, ' ') === false) { + $in_headers = true; + } + + foreach ($lines as $line) { + $lines_out = array(); + if ($in_headers and $line == '') { + $in_headers = false; + } + // ok we need to break this line up into several smaller lines + //This is a small micro-optimisation: isset($str[$len]) is equivalent to (strlen($str) > $len) + while (isset($line[self::MAX_LINE_LENGTH])) { + //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on + //so as to avoid breaking in the middle of a word + $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); + if (!$pos) { //Deliberately matches both false and 0 + //No nice break found, add a hard break + $pos = self::MAX_LINE_LENGTH - 1; + $lines_out[] = substr($line, 0, $pos); + $line = substr($line, $pos); + } else { + //Break at the found point + $lines_out[] = substr($line, 0, $pos); + //Move along by the amount we dealt with + $line = substr($line, $pos + 1); + } + /* If processing headers add a LWSP-char to the front of new line + * RFC822 section 3.1.1 + */ + if ($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + // Send the lines to the server + foreach ($lines_out as $line_out) { + //RFC2821 section 4.5.2 + if (!empty($line_out) and $line_out[0] == '.') { + $line_out = '.' . $line_out; + } + $this->client_send($line_out . self::CRLF); + } + } + + // Message data has been sent, complete the command + return $this->sendCommand('DATA END', '.', 250); + } + + /** + * Send an SMTP HELO or EHLO command. + * Used to identify the sending server to the receiving server. + * This makes sure that client and server are in a known state. + * Implements RFC 821: HELO + * and RFC 2821 EHLO. + * @param string $host The host name or IP to connect to + * @access public + * @return bool + */ + public function hello($host = '') + { + // Try extended hello first (RFC 2821) + return (bool)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host)); + } + + /** + * Send an SMTP HELO or EHLO command. + * Low-level implementation used by hello() + * @see hello() + * @param string $hello The HELO string + * @param string $host The hostname to say we are + * @access protected + * @return bool + */ + protected function sendHello($hello, $host) + { + $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); + $this->helo_rply = $this->last_reply; + return $noerror; + } + + /** + * Send an SMTP MAIL command. + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. + * Implements rfc 821: MAIL FROM: + * @param string $from Source address of this message + * @access public + * @return bool + */ + public function mail($from) + { + $useVerp = ($this->do_verp ? ' XVERP' : ''); + return $this->sendCommand( + 'MAIL FROM', + 'MAIL FROM:<' . $from . '>' . $useVerp, + 250 + ); + } + + /** + * Send an SMTP QUIT command. + * Closes the socket if there is no error or the $close_on_error argument is true. + * Implements from rfc 821: QUIT + * @param bool $close_on_error Should the connection close if an error occurs? + * @access public + * @return bool + */ + public function quit($close_on_error = true) + { + $noerror = $this->sendCommand('QUIT', 'QUIT', 221); + $err = $this->error; //Save any error + if ($noerror or $close_on_error) { + $this->close(); + $this->error = $err; //Restore any error from the quit command + } + return $noerror; + } + + /** + * Send an SMTP RCPT command. + * Sets the TO argument to $toaddr. + * Returns true if the recipient was accepted false if it was rejected. + * Implements from rfc 821: RCPT TO: + * @param string $toaddr The address the message is being sent to + * @access public + * @return bool + */ + public function recipient($toaddr) + { + return $this->sendCommand( + 'RCPT TO', + 'RCPT TO:<' . $toaddr . '>', + array(250, 251) + ); + } + + /** + * Send an SMTP RSET command. + * Abort any transaction that is currently in progress. + * Implements rfc 821: RSET + * @access public + * @return bool True on success. + */ + public function reset() + { + return $this->sendCommand('RSET', 'RSET', 250); + } + + /** + * Send a command to an SMTP server and check its return code. + * @param string $command The command name - not sent to the server + * @param string $commandstring The actual command to send + * @param int|array $expect One or more expected integer success codes + * @access protected + * @return bool True on success. + */ + protected function sendCommand($command, $commandstring, $expect) + { + if (!$this->connected()) { + $this->error = array( + 'error' => "Called $command without being connected" + ); + return false; + } + $this->client_send($commandstring . self::CRLF); + + $reply = $this->get_lines(); + $code = substr($reply, 0, 3); + + if ($this->do_debug >= 2) { + $this->edebug('SERVER -> CLIENT: ' . $reply); + } + + if (!in_array($code, (array)$expect)) { + $this->last_reply = null; + $this->error = array( + 'error' => "$command command failed", + 'smtp_code' => $code, + 'detail' => substr($reply, 4) + ); + if ($this->do_debug >= 1) { + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] . ': ' . $reply + ); + } + return false; + } + + $this->last_reply = $reply; + $this->error = null; + return true; + } + + /** + * Send an SMTP SAML command. + * Starts a mail transaction from the email address specified in $from. + * Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * Implements rfc 821: SAML FROM: + * @param string $from The address the message is from + * @access public + * @return bool + */ + public function sendAndMail($from) + { + return $this->sendCommand('SAML', "SAML FROM:$from", 250); + } + + /** + * Send an SMTP VRFY command. + * @param string $name The name to verify + * @access public + * @return bool + */ + public function verify($name) + { + return $this->sendCommand('VRFY', "VRFY $name", array(250, 251)); + } + + /** + * Send an SMTP NOOP command. + * Used to keep keep-alives alive, doesn't actually do anything + * @access public + * @return bool + */ + public function noop() + { + return $this->sendCommand('NOOP', 'NOOP', 250); + } + + /** + * Send an SMTP TURN command. + * This is an optional command for SMTP that this class does not support. + * This method is here to make the RFC821 Definition complete for this class + * and _may_ be implemented in future + * Implements from rfc 821: TURN + * @access public + * @return bool + */ + public function turn() + { + $this->error = array( + 'error' => 'The SMTP TURN command is not implemented' + ); + if ($this->do_debug >= 1) { + $this->edebug('SMTP NOTICE: ' . $this->error['error']); + } + return false; + } + + /** + * Send raw data to the server. + * @param string $data The data to send + * @access public + * @return int|bool The number of bytes sent to the server or false on error + */ + public function client_send($data) + { + if ($this->do_debug >= 1) { + $this->edebug("CLIENT -> SERVER: $data"); + } + return fwrite($this->smtp_conn, $data); + } + + /** + * Get the latest error. + * @access public + * @return array + */ + public function getError() + { + return $this->error; + } + + /** + * Get the last reply from the server. + * @access public + * @return string + */ + public function getLastReply() + { + return $this->last_reply; + } + + /** + * Read the SMTP server's response. + * Either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + * @access protected + * @return string + */ + protected function get_lines() + { + // If the connection is bad, give up straight away + if (!is_resource($this->smtp_conn)) { + return ''; + } + $data = ''; + $endtime = 0; + stream_set_timeout($this->smtp_conn, $this->Timeout); + if ($this->Timelimit > 0) { + $endtime = time() + $this->Timelimit; + } + while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { + $str = @fgets($this->smtp_conn, 515); + if ($this->do_debug >= 4) { + $this->edebug("SMTP -> get_lines(): \$data was \"$data\""); + $this->edebug("SMTP -> get_lines(): \$str is \"$str\""); + } + $data .= $str; + if ($this->do_debug >= 4) { + $this->edebug("SMTP -> get_lines(): \$data is \"$data\""); + } + // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen + if ((isset($str[3]) and $str[3] == ' ')) { + break; + } + // Timed-out? Log and break + $info = stream_get_meta_data($this->smtp_conn); + if ($info['timed_out']) { + if ($this->do_debug >= 4) { + $this->edebug( + 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)' + ); + } + break; + } + // Now check if reads took too long + if ($endtime and time() > $endtime) { + if ($this->do_debug >= 4) { + $this->edebug( + 'SMTP -> get_lines(): timelimit reached ('. + $this->Timelimit . ' sec)' + ); + } + break; + } + } + return $data; + } + + /** + * Enable or disable VERP address generation. + * @param bool $enabled + */ + public function setVerp($enabled = false) + { + $this->do_verp = $enabled; + } + + /** + * Get VERP address generation mode. + * @return bool + */ + public function getVerp() + { + return $this->do_verp; + } + + /** + * Set debug output method. + * @param string $method The function/method to use for debugging output. + */ + public function setDebugOutput($method = 'echo') + { + $this->Debugoutput = $method; + } + + /** + * Get debug output method. + * @return string + */ + public function getDebugOutput() + { + return $this->Debugoutput; + } + + /** + * Set debug output level. + * @param int $level + */ + public function setDebugLevel($level = 0) + { + $this->do_debug = $level; + } + + /** + * Get debug output level. + * @return int + */ + public function getDebugLevel() + { + return $this->do_debug; + } + + /** + * Set SMTP timeout. + * @param int $timeout + */ + public function setTimeout($timeout = 0) + { + $this->Timeout = $timeout; + } + + /** + * Get SMTP timeout. + * @return int + */ + public function getTimeout() + { + return $this->Timeout; + } +} + +} diff --git a/app/models/QuesttypeModel.inc b/app/models/QuesttypeModel.inc new file mode 100644 index 00000000..fdeafe81 --- /dev/null +++ b/app/models/QuesttypeModel.inc @@ -0,0 +1,165 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\models; + + + /** + * Abstract class for implementing a QuesttypeModel. + * + * @author Oliver Hanraths + */ + abstract class QuesttypeModel extends \hhu\z\Model + { + + + + + /** + * Copy a Quest. + * + * @param int $userId ID of creating user + * @param int $sourceQuestId ID of Quest to copy from + * @param int $targetQuestId ID of Quest to copy to + * @param int $seminaryMediaIds Mapping of SeminaryMedia-IDs from source Seminary to targetSeminary + */ + public abstract function copyQuest($userId, $sourceQuestId, $targetQuestId, $seminaryMediaIds); + + + /** + * Load a Model. + * + * @static + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @param string $modelName Name of the QuesttypeModel to load + */ + public static function load($modelName) + { + // Determine full classname + $className = self::getClassName($modelName); + + try { + // Load class + static::loadClass($modelName, $className); + + // Validate class + static::checkClass($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \hhu\z\exceptions\QuesttypeModelNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \hhu\z\exceptions\QuesttypeModelNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a QuesttypeModel (Factory Pattern). + * + * @static + * @param string $questtypeName Name of the QuesttypeModel to instantiate + */ + public static function factory($questtypeName) + { + // Determine full classname + $className = self::getClassName($questtypeName); + + // Construct and return Model + return new $className(); + } + + + /** + * Determine the Model-classname for the given Questtype-name. + * + * @static + * @param string $questtypeName Questtype-name to get Model-classname of + * @return string Classname for the Questtype-name + */ + private static function getClassName($questtypeName) + { + $className = \nre\core\ClassLoader::concatClassNames($questtypeName, \nre\core\ClassLoader::stripClassType(\nre\core\ClassLoader::stripNamespace(get_class())), 'model'); + + + return \nre\configs\AppConfig::$app['namespace']."questtypes\\$className"; + } + + + /** + * Load the class of a QuesttypeModel. + * + * @static + * @throws \nre\exceptions\ClassNotFoundException + * @param string $questtypeName Name of the QuesttypeModel to load + * @param string $fullClassName Name of the class to load + */ + private static function loadClass($questtypeName, $fullClassName) + { + // Determine folder to look in + $className = explode('\\', $fullClassName); + $className = array_pop($className); + + // Determine filename + $fileName = ROOT.DS.\nre\configs\AppConfig::$dirs['questtypes'].DS.strtolower($questtypeName).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 the QuesttypeModel-class. + * + * @static + * @throws \nre\exceptions\ClassNotValidException + * @param string $className Name of the class to check + * @param string $parentClassName Name of the parent class + */ + public static function checkClass($className, $parentClassName) + { + // Check if class is subclass of parent class + if(!is_subclass_of($className, $parentClassName)) { + throw new \nre\exceptions\ClassNotValidException( + $className + ); + } + } + + + + + /** + * Construct a new QuesttypeModel. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotValidException + * @throws \hhu\z\exceptions\QuesttypeModelNotFoundException + */ + public function __construct() + { + parent::__construct(); + } + + } + +?> diff --git a/app/requests/MailRequest.inc b/app/requests/MailRequest.inc new file mode 100644 index 00000000..baaf02ab --- /dev/null +++ b/app/requests/MailRequest.inc @@ -0,0 +1,92 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\requests; + + + /** + * Representation of a mail-request. + * + * @author Oliver Hanraths + */ + class MailRequest extends \nre\core\Request + { + /** + * Linker + * + * @var \nre\core\Linker + */ + private $linker = null; + + + + + /** + * 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); + } + + + /** + * Set linker instance for creating links. + * + * @param Linker $linker Linker instance for creating links + */ + public function setLinker(\nre\core\Linker $linker) + { + $this->linker = $linker; + } + + + /** + * Get linker instance for creating links. + * + * @return \nre\core\Linker Linker instance for creating links + */ + public function getLinker() + { + return $this->linker; + } + + } + +?> diff --git a/app/responses/MailResponse.inc b/app/responses/MailResponse.inc new file mode 100644 index 00000000..71ced1bc --- /dev/null +++ b/app/responses/MailResponse.inc @@ -0,0 +1,55 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\responses; + + + /** + * Representation of a mail-response. + * + * @author Oliver Hanraths + */ + class MailResponse extends \nre\core\Response + { + /** + * Mail subject + * + * @var string + */ + private $subject = null; + + + + + /** + * Set subject. + * + * @param string $subject Subject to set + */ + public function setSubject($subject) + { + $this->subject = $subject; + } + + + /** + * Get subject. + * + * @return string Subject + */ + public function getSubject() + { + return $this->subject; + } + + } + +?> diff --git a/app/views/QuesttypeView.inc b/app/views/QuesttypeView.inc new file mode 100644 index 00000000..234147be --- /dev/null +++ b/app/views/QuesttypeView.inc @@ -0,0 +1,76 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\views; + + + /** + * Abstract class for implementing a QuesttypeView. + * + * @author Oliver Hanraths + */ + class QuesttypeView extends \nre\core\View + { + + + + + /** + * Load and instantiate the QuesttypeView of a QuesttypeAgent. + * + * @throws \nre\exceptions\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 QuesttypeView($layoutName, $agentName, $action, $isToplevel); + } + + + + + /** + * Construct a new QuesttypeView. + * + * @throws \nre\exceptions\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 + */ + protected function __construct($layoutName, $agentName=null, $action=null, $isToplevel=false) + { + // Create template filename + // LayoutName + $fileName = ROOT.DS.\nre\configs\AppConfig::$dirs['questtypes'].DS.strtolower($agentName).DS.strtolower($layoutName).DS; + + // Action + $fileName .= strtolower($action); + + // 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; + } + + } + +?> diff --git a/bootstrap.inc b/bootstrap.inc new file mode 100644 index 00000000..667204b6 --- /dev/null +++ b/bootstrap.inc @@ -0,0 +1,33 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + // Include required classes + require_once(ROOT.DS.'configs'.DS.'CoreConfig.inc'); + require_once(ROOT.DS.\nre\configs\CoreConfig::getClassDir('core').DS.'Autoloader.inc'); + + + // Set PHP-logging + ini_set('error_log', ROOT.DS.\nre\configs\CoreConfig::getClassDir('logs').DS.'php'.\nre\configs\CoreConfig::getFileExt('logs')); + + // Register autoloader + \nre\core\Autoloader::register(); + + + // Initialize WebApi + $webApi = new \nre\apis\WebApi(); + + // Run WebApi + $webApi->run(); + + // Render output + $webApi->render(); + +?> diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc new file mode 100644 index 00000000..9e18237b --- /dev/null +++ b/configs/AppConfig.inc @@ -0,0 +1,373 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace nre\configs; + + + /** + * Application configuration. + * + * This class contains static variables with configuration values for + * the specific application. + * + * @author Oliver Hanraths + */ + final class AppConfig + { + + /** + * Application values + * + * @static + * @var array + */ + public static $app = array( + 'name' => 'Questlab', + 'genericname' => 'The Legend of Z', + 'namespace' => 'hhu\\z\\', + 'timeZone' => 'Europe/Berlin', + 'mailsender' => '', + 'mailcontact' => '', + 'registration_host' => '', + 'languages' => array( + 'de' => 'de_DE.utf8' + ) + ); + + + /** + * Default values + * + * @static + * @var array + */ + public static $defaults = array( + 'toplevel' => 'html', + 'toplevel-error' => 'fault', + 'toplevel-mail' => 'textmail', + 'toplevel-htmlmail' => 'htmlmail', + 'intermediate' => 'introduction', + 'intermediate-error' => 'error', + 'intermediate-mail' => 'mail' + ); + + + /** + * Directories + * + * @static + * @var array + */ + public static $dirs = array( + 'locale' => 'locale', + 'media' => 'media', + 'seminarymedia' => 'seminarymedia', + 'questtypes' => 'questtypes', + 'temporary' => 'tmp', + 'uploads' => 'uploads', + 'seminaryuploads' => 'seminaryuploads' + ); + + + /** + * Media sizes + * + * @static + * @var array + */ + public static $media = array( + 'questgroup' => array( + 'width' => 480, + 'height' => 5000 + ), + 'avatar' => array( + 'width' => 500, + 'height' => 500 + ), + 'charactergroup' => array( + 'width' => 80, + 'height' => 80 + ), + 'charactergroupsquest' => array( + 'width' => 80, + 'height' => 80 + ) + ); + + + /** + * Allowed mimetypes with sizes + * + * @static + * @var array + */ + public static $mimetypes = array( + 'icons' => array( + array( + 'mimetype' => 'image/jpeg', + 'size' => 102400 + ), + array( + 'mimetype' => 'image/png', + 'size' => 204800 + ) + ), + 'moodpics' => array( + array( + 'mimetype' => 'image/jpeg', + 'size' => 524288 + ), + array( + 'mimetype' => 'image/png', + 'size' => 1048576 + ) + ), + 'charactergroupsquests' => array( + array( + 'mimetype' => 'image/jpeg', + 'size' => 1048576 + ) + ) + ); + + + /** + * Miscellaneous settings + * + * @static + * @var array + */ + public static $misc = array( + 'ranking_range' => 2, + 'achievements_range' => 3, + 'title_delimiter' => ' – ', + 'lists_limit' => 10 + ); + + + /** + * Validation settings for user input + * + * @static + * @var array + */ + public static $validation = array( + 'username' => array( + 'minlength' => 5, + 'maxlength' => 12, + 'regex' => '/^\w*$/' + ), + 'email' => array( + 'regex' => '/^\S+@[\w\d.-]{2,}\.[\w]{2,6}$/iU' + ), + 'prename' => array( + 'minlength' => 2, + 'maxlength' => 32, + 'regex' => '/^(\S| )*$/' + ), + 'surname' => array( + 'minlength' => 2, + 'maxlength' => 32, + 'regex' => '/^\S*$/' + ), + 'password' => array( + 'minlength' => 5, + 'maxlength' => 64 + ), + 'charactername' => array( + 'minlength' => 5, + 'maxlength' => 12, + 'regex' => '/^\w*$/' + ), + 'charactergroupsgroupname' => array( + 'minlength' => 4, + 'maxlength' => 32, + 'regex' => '/^(\S| )*$/' + ), + 'preferred' => array( + 'regex' => '/^(0|1)$/' + ), + 'charactergroupname' => array( + 'minlength' => 4, + 'maxlength' => 32, + 'regex' => '/^(\S| )*$/' + ), + 'motto' => array( + 'maxlength' => 128 + ), + 'title' => array( + 'minlength' => 4, + 'maxlength' => 32, + 'regex' => '/^(\S| )*$/' + ), + 'xps' => array( + 'minlength' => 1, + 'regex' => '/^(\d*)$/' + ), + 'course' => array( + 'maxlength' => 128 + ), + 'charactertypename' => array( + 'minlength' => 1, + 'maxlength' => 32 + ), + 'questgroupshierarchytitle' => array( + 'minlength' => 1, + 'maxlength' => 64 + ), + 'deadline' => array( + 'regex' => '/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})?$/' + ), + 'choice' => array( + 'minlength' => 1, + 'maxlength' => 128 + ), + 'answer' => array( + 'minlength' => 1, + 'maxlength' => 255 + ) + ); + + + /** + * Routes + * + * @static + * @var array + */ + public static $routes = array( + array('^users/all/?$', 'users/index/all', true), + array('^users/([^/]+)/(edit|delete)/?$', 'users/$2/$1', true), + array('^users/(?!(index|login|register|logout|manage|create|edit|delete))/?', 'users/user/$1', true), + array('^seminaries/([^/]+)/(edit|copy|delete)/?$', 'seminaries/$2/$1', true), + array('^seminaries/(?!(index|create|edit|copy|delete|calculatexps))/?', 'seminaries/seminary/$1', true), + array('^xplevels/([^/]+)/(manage)/?$', 'xplevels/$2/$1', true), + array('^questgroupshierarchy/([^/]+)/create/?$', 'questgroupshierarchy/create/$1', true), + array('^questgroupshierarchy/([^/]+)/([^/]+)/(edit|delete|moveup|movedown)/?$', 'questgroupshierarchy/$3/$1/$2', true), + array('^questgroups/([^/]+)/create/?$', 'questgroups/create/$1', true), + array('^questgroups/([^/]+)/([^/]+)/(edit|edittexts|delete|moveup|movedown)/?$','questgroups/$3/$1/$2', true), + array('^questgroups/([^/]+)/([^/]+)/?$', 'questgroups/questgroup/$1/$2', true), + array('^quests/([^/]+)/?$', 'quests/index/$1', true), + array('^quests/([^/]+)/all/?$', 'quests/index/$1/all', true), + array('^quests/([^/]+)/([^/]+)/(create|createmedia)/?$', 'quests/$3/$1/$2', true), + array('^quests/([^/]+)/([^/]+)/([^/]+)/(submissions|edit|edittask|edittexts|delete)/?$','quests/$4/$1/$2/$3', true), + array('^quests/([^/]+)/([^/]+)/([^/]+)/(submission)/([^/]+)/?$', 'quests/$4/$1/$2/$3/$5', true), + array('^quests/(?!(index|create|createmedia))/?', 'quests/quest/$1', true), + array('^characters/([^/]+)/(register|manage)/?$', 'characters/$2/$1', true), + array('^characters/([^/]+)/?$', 'characters/index/$1', true), + array('^characters/([^/]+)/all/?$', 'characters/index/$1/all', true), + array('^characters/([^/]+)/([^/]+)/(edit|delete)/?$', 'characters/$3/$1/$2', true), + array('^characters/([^/]+)/(?!(index|register|manage))/?', 'characters/character/$1/$2', true), + array('^charactertypes/([^/]+)/?$', 'charactertypes/index/$1', true), + array('^charactertypes/([^/]+)/create/?$', 'charactertypes/create/$1', true), + array('^charactertypes/([^/]+)/([^/]+)/(edit|delete)/?$', 'charactertypes/$3/$1/$2', true), + array('^charactergroups/([^/]+)/?$', 'charactergroups/index/$1', true), + array('^charactergroups/([^/]+)/(create)/?$', 'charactergroups/creategroupsgroup/$1/$2', true), + array('^charactergroups/([^/]+)/([^/]+)/?$', 'charactergroups/groupsgroup/$1/$2', true), + array('^charactergroups/([^/]+)/([^/]+)/(edit|delete)/?$', 'charactergroups/$3groupsgroup/$1/$2', true), + array('^charactergroups/([^/]+)/([^/]+)/(create)/?$', 'charactergroups/creategroup/$1/$2/$3', true), + array('^charactergroups/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroups/group/$1/$2/$3', true), + array('^charactergroups/([^/]+)/([^/]+)/([^/]+)/(manage|edit|delete)/?$', 'charactergroups/$4group/$1/$2/$3', true), + array('^charactergroupsquests/([^/]+)/([^/]+)/create/?$', 'charactergroupsquests/create/$1/$2', true), + array('^charactergroupsquests/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsquests/quest/$1/$2/$3', true), + array('^charactergroupsquests/([^/]+)/([^/]+)/([^/]+)/(edit|delete|manage)/?$', 'charactergroupsquests/$4/$1/$2/$3', true), + array('^achievements/([^/]+)/(create|manage)/?$', 'achievements/$2/$1', true), + array('^achievements/([^/]+)/([^/]+)/(edit|conditions|moveup|movedown|delete)/?$', 'achievements/$3/$1/$2', true), + array('^achievements/([^/]+)/?$', 'achievements/index/$1', true), + array('^library/([^/]+)/?$', 'library/index/$1', true), + array('^library/([^/]+)/create/?$', 'library/create/$1', true), + array('^library/([^/]+)/([^/]+)/?$', 'library/topic/$1/$2', true), + array('^library/([^/]+)/([^/]+)/(edit|delete|manage)/?$', 'library/$3/$1/$2', true), + array('^media/(.*)$', 'media/$1?layout=binary', false), + array('^uploads/(.*)$', 'uploads/$1?layout=binary', false) + ); + + + /** + * Reverse routes + * + * @static + * @var array + */ + public static $reverseRoutes = array( + array('^users/index/all$', 'users/all', true), + array('^users/user/(.*)$', 'users/$1', true), + array('^users/([^/]+)/(.*)$', 'users/$2/$1', true), + array('^seminaries/seminary/(.*)$', 'seminaries/$1', false), + array('^xplevels/(manage)/(.*)$', 'xplevels/$2/$1', false), + array('^questgroupshierarchy/create/(.*)$', 'questgroupshierarchy/$1/create', true), + array('^questgroupshierarchy/([^/]+)/(.*)$', 'questgroupshierarchy/$2/$1', true), + array('^questgroups/create/(.*)$', 'questgroups/$1/create', true), + array('^questgroups/questgroup/(.*)$', 'questgroups/$1', true), + array('^questgroups/(edit|edittexts|delete|moveup|movedown)/(.*)$', 'questgroups/$2/$1', true), + array('^quests/index/(.+)$', 'quests/$1', true), + array('^quests/quest/(.*)$', 'quests/$1', true), + array('^quests/(create|createmedia)/(.*)$', 'quests/$2/$1', true), + array('^quests/(submissions|edit|edittask|edittexts|delete)/([^/]+)/([^/]+)/([^/]+)$', 'quests/$2/$3/$4/$1', true), + array('^quests/(submission)/([^/]+)/([^/]+)/([^/]+)/([^/]+)$', 'quests/$2/$3/$4/$1/$5', true), + array('^characters/(index|character)/(.*)$', 'characters/$2', true), + array('^characters/(register|manage)/([^/]+)$', 'characters/$2/$1', true), + array('^characters/(edit|delete)/([^/]+)/([^/]+)$', 'characters/$2/$3/$1', true), + array('^charactertypes/index/([^/]+)$', 'charactertypes/$1', true), + array('^charactertypes/create/([^/]+)$', 'charactertypes/$1/create', true), + array('^charactertypes/(edit|delete)/([^/]+)/([^/]+)$', 'charactertypes/$2/$3/$1', true), + array('^charactergroups/index/([^/]+)$', 'charactergroups/$1', true), + array('^charactergroups/creategroupsgroup/([^/]+)$', 'charactergroups/$1/create', true), + array('^charactergroups/groupsgroup/([^/]+)/([^/]+)$', 'charactergroups/$1/$2', true), + array('^charactergroups/(edit|delete)groupsgroup/([^/]+)/([^/]+)$', 'charactergroups/$2/$3/$1', true), + array('^charactergroups/creategroup/([^/]+)/([^/]+)$', 'charactergroups/$1/$2/create', true), + array('^charactergroups/group/([^/]+)/([^/]+)/([^/]+)$', 'charactergroups/$1/$2/$3', true), + array('^charactergroups/(manage|edit|delete)group/([^/]+)/([^/]+)/([^/]+)$', 'charactergroups/$2/$3/$4/$1', true), + array('^charactergroupsquests/create/([^/]+)/([^/]+)/?$', 'charactergroupsquests/$1/$2/create', true), + array('^charactergroupsquests/quest/(.*)$', 'charactergroupsquests/$1', true), + array('^charactergroupsquests/(edit|delete|manage)/([^/]+)/([^/]+)/([^/]+)$', 'charactergroupsquests/$2/$3/$4/$1', true), + array('^achievements/index/(.*)$', 'achievements/$1', true), + array('^achievements/(create|manage)/(.*)$', 'achievements/$2/$1', true), + array('^achievements/(edit|conditions|moveup|movedown|delete)/(.*)$', 'achievements/$2/$1', true), + array('^library/index/([^/]+)/?$', 'library/$1', true), + array('^library/create/([^/]+)/?$', 'library/$1/create', true), + array('^library/topic/([^/]+)/([^/]+)/?$', 'library/$1/$2', true), + array('^library/(edit|delete|manage)/([^/]+)/([^/]+)/?$', 'library/$2/$3/$1', true) + ); + + + /** + * Database connection settings + * + * @static + * @var array + */ + public static $database = array( + 'user' => 'z', + 'host' => 'localhost', + 'password' => 'legendofZ', + 'db' => 'z' + ); + + + /** + * Mailserver connection settings + * + * @static + * @var array + */ + public static $mail = array( + 'host' => '', + 'port' => 465, + 'username' => '', + 'password' => '', + 'secure' => '', + 'charset' => 'UTF-8' + ); + + } + +?> diff --git a/configs/CoreConfig.inc b/configs/CoreConfig.inc new file mode 100644 index 00000000..c2c2605d --- /dev/null +++ b/configs/CoreConfig.inc @@ -0,0 +1,167 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\configs; + + + /** + * Core configuration. + * + * This class contains static variables with configuration values. + * + * @author coderkun + */ + final class CoreConfig + { + + /** + * Core values + * + * @static + * @var array + */ + public static $core = array( + 'namespace' => 'nre\\', + ); + + + /** + * Directories + * + * @static + * @var array + */ + public static $dirs = array( + 'core' => 'core', + 'publicDir' => 'www' + ); + + + /** + * File extensions + * + * @static + * @var array + */ + public static $fileExts = array( + 'default' => 'inc', + 'views' => 'tpl', + 'logs' => 'log', + ); + + + /** + * Default values + * + * @static + * @var array + */ + public static $defaults = array( + 'action' => 'index', + 'errorFile' => 'error', + 'inlineErrorFile' => 'inlineerror' + ); + + + /** + * Miscellaneous settings + * + * @static + * @var array + */ + public static $misc = array( + 'fileExtDot' => '.' + ); + + + /** + * Logging settings + * + * @static + * @var array + */ + public static $log = array( + 'filename' => 'errors', + 'format' => 'Fehler %d: %s in %s, Zeile %d' + ); + + + /** + * Class-specific settings + * + * @static + * @var array + */ + public static $classes = array( + 'linker' => array( + 'url' => array( + 'length' => 128, + 'delimiter' => '-' + ) + ) + ); + + + + + /** + * Determine the directory for a specific classtype. + * + * @param string $classType Classtype to get directory of + * @return string Directory of given classtype + */ + public static function getClassDir($classType) + { + // Default directory (for core classes) + $classDir = self::$dirs['core']; + + // Configurable directory + if(array_key_exists($classType, self::$dirs)) { + $classDir = self::$dirs[$classType]; + } + else + { + // Default directory for classtype + if(is_dir(ROOT.DS.$classType)) { + $classDir = $classType; + } + } + + + // Return directory + return $classDir; + } + + + /** + * Determine the file extension for a specific filetype. + * + * @param string $fileType Filetype to get file extension of + * @return string File extension of given filetype + */ + public static function getFileExt($fileType) + { + // Default file extension + $fileExt = self::$fileExts['default']; + + // Configurable file extension + if(array_key_exists($fileType, self::$fileExts)) { + $fileExt = self::$fileExts[$fileType]; + } + + + // Return file extension + return self::$misc['fileExtDot'].$fileExt; + } + + } + +?> diff --git a/controllers/AchievementsController.inc b/controllers/AchievementsController.inc new file mode 100644 index 00000000..4f52b91d --- /dev/null +++ b/controllers/AchievementsController.inc @@ -0,0 +1,960 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to list Achievements. + * + * @author Oliver Hanraths + */ + class AchievementsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('achievements', 'seminaries', 'media', 'characters', 'quests'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'moveup' => array('admin', 'moderator', 'user'), + 'movedown' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'conditions' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'create' => array('admin'), + 'moveup' => array('admin', 'moderator'), + 'movedown' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator'), + 'conditions' => array('admin', 'moderator'), + 'delete' => array('admin') + ); + + + + + /** + * Action: index. + * + * List Achievements of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + */ + public function index($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = SeminaryController::$character; + + // Get seldom Achievements + $seldomAchievements = $this->Achievements->getSeldomAchievements($seminary['id'], \nre\configs\AppConfig::$misc['achievements_range'], false); + foreach($seldomAchievements as &$achievement) { + $achievement['achieved'] = $this->Achievements->hasCharacterAchievedAchievement($achievement['id'], $character['id']); + } + + // Get Characters with the most Achievements + $successfulCharacters = $this->Characters->getCharactersWithMostAchievements($seminary['id'], \nre\configs\AppConfig::$misc['achievements_range'], false); + + // Get total count of Achievements for Seminary + $achievementsCount = $this->Achievements->getAchievementsCountForSeminary($seminary['id'], false); + + // Get achieved Achievements + $achievedAchievements = $this->Achievements->getAchievedAchievementsForCharacter($character['id']); + + // Get unachieved Achievements + $unachievedAchievements = array_merge( + $this->Achievements->getUnachhievedAchievementsForCharacter($seminary['id'], $character['id'], false, false), + $this->Achievements->getUnachievedOnlyOnceAchievementsForSeminary($seminary['id']) + ); + usort($unachievedAchievements, function($a, $b) { + if($a['pos'] == $b['pos']) { + return 0; + } + return ($a['pos'] > $b['pos']) ? 1 : -1; + }); + foreach($unachievedAchievements as &$achievement) + { + // Get Character progress + if($achievement['progress']) + { + $conditions = array(); + switch($achievement['condition']) + { + // Character conditions + case 'character': + $conditionsCharacter = $this->Achievements->getAchievementConditionsCharacter($achievement['id']); + foreach($conditionsCharacter as &$condition) + { + $conditions[] = array( + 'func' => 'getAchievementConditionCharacterProgress', + 'params' => array( + $condition['field'], + $condition['value'], + $character['id'] + ) + ); + } + break; + // Quest conditions + case 'quest': + $conditionsQuest = $this->Achievements->getAchievementConditionsQuest($achievement['id']); + foreach($conditionsQuest as &$condition) + { + $conditions[] = array( + 'func' => 'getAchievementConditionQuestProgress', + 'params' => array( + $condition['field'], + $condition['count'], + $condition['value'], + $condition['status'], + $condition['groupby'], + $condition['quest_id'], + $character['id'] + ) + ); + } + break; + // Achievement conditions + case 'achievement': + $conditionsAchievement = $this->Achievements->getAchievementConditionsAchievement($achievement['id']); + foreach($conditionsAchievement as &$condition) + { + $conditions[] = array( + 'func' => 'getAchievementConditionAchievementProgress', + 'params' => array( + $condition['field'], + $condition['count'], + $condition['value'], + $condition['groupby'], + $condition['meta_achievement_id'], + $character['id'] + ) + ); + } + break; + } + + $characterProgresses = array(); + foreach($conditions as &$condition) + { + // Calculate progress of condition + $characterProgresses[] = call_user_func_array( + array( + $this->Achievements, + $condition['func'] + ), + $condition['params'] + ); + } + + $achievement['characterProgress'] = array_sum($characterProgresses) / count($characterProgresses); + } + } + + // Get ranking + $character['rank'] = $this->Achievements->getCountRank($seminary['id'], count($achievedAchievements)); + + + // Set title + $this->addTitleLocalized('Achievements'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('seldomAchievements', $seldomAchievements); + $this->set('successfulCharacters', $successfulCharacters); + $this->set('achievementsCount', $achievementsCount); + $this->set('achievedAchievements', $achievedAchievements); + $this->set('unachievedAchievements', $unachievedAchievements); + } + + + /** + * Action: manage. + * + * Manage Achievements of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + */ + public function manage($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievements + $achievements = $this->Achievements->getAchievementsForSeminary($seminary['id']); + + + // Set title + $this->addTitleLocalized('Manage Achievements'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('achievements', $achievements); + } + + + /** + * Action: create. + * + * Create a new Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + */ + public function create($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievements conditions + $conditions = $this->Achievements->getAchievementsConditions(); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = ''; + $description = ''; + $progress = 0; + $hidden = 0; + $onlyOnce = 0; + $allConditions = 1; + $deadline = ''; + $condition = $conditions[0]['condition']; + $fields = array('title', 'deadline'); + $validation = array(); + + // Create Achievement + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Achievements->achievementTitleExists($seminary['id'], $title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $description = $this->request->getPostParam('description'); + $progress = !is_null($this->request->getPostParam('progress')); + $hidden = !is_null($this->request->getPostParam('hidden')); + $onlyOnce = !is_null($this->request->getPostParam('only_once')); + $allConditions = !is_null($this->request->getPostParam('all_conditions')); + $deadline = $this->request->getPostParam('deadline'); + $condition = $this->request->getPostParam('condition'); + + // Validate condition + $conditionIndex = null; + foreach($conditions as $index => &$c) { + if($condition == $c['condition']) { + $conditionIndex = $index; + } + } + if(is_null($conditionIndex)) { + throw new \nre\exceptions\ParamsNotValidException($condition); + } + + // Validate images + $images = array( + 'unachieved_image' => null, + 'achieved_image' => null + ); + foreach($images as $key => $image) + { + if(!empty($_FILES) && array_key_exists($key, $_FILES) && $_FILES[$key]['error'] != UPLOAD_ERR_NO_FILE) + { + $images[$key] = $_FILES[$key]; + + // Check error + if($images[$key]['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'error', $image[$key]['error']); + } + + // Check mimetype + $mediaMimetype = null; + $images[$key]['mimetype'] = \hhu\z\Utils::getMimetype($images[$key]['tmp_name'], $images[$key]['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $images[$key]['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'mimetype', $images[$key]['mimetype']); + } + elseif($images[$key]['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'size', $mediaMimetype['size']); + } + } + } + + // Create Achievement + if($validation === true) + { + $achievementId = $this->Achievements->createAchievement( + $this->Auth->getUserId(), + $seminary['id'], + $conditions[$conditionIndex]['id'], + $title, + $description, + $progress, + $hidden, + $onlyOnce, + $allConditions, + (!empty($deadline)) ? $deadline : NULL + ); + $achievement = $this->Achievements->getAchievementById($achievementId); + + // Upload images + foreach($images as $key => &$image) + { + if(!is_null($image)) + { + $image['media_id'] = $this->Media->createAchievementMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('achievement-%d', $achievement['id']).(substr($key, 0, 2) == 'un' ? '-locked' : NULL), + '', + $image['mimetype'], + $image['tmp_name'] + ); + } + } + if(!is_null($images['unachieved_image']) && $images['unachieved_image']['media_id'] !== false) { + $this->Achievements->setUnachievedMediaForAchievement($achievement['id'], $images['unachieved_image']['media_id']); + } + if(!is_null($images['achieved_image']) && $images['achieved_image']['media_id'] !== false) { + $this->Achievements->setAchievedMediaForAchievement($achievement['id'], $images['achieved_image']['media_id']); + } + + // Redirect to condition editing + $this->redirect($this->linker->link(array('conditions', $seminary['url'], $achievement['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('Create Achievement'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('title', $title); + $this->set('description', $description); + $this->set('progress', $progress); + $this->set('hidden', $hidden); + $this->set('onlyOnce', $onlyOnce); + $this->set('allConditions', $allConditions); + $this->set('deadline', $deadline); + $this->set('condition', $condition); + $this->set('conditions', $conditions); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: moveup. + * + * Move an Achievement up (decrement position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $achievementUrl URL-title of Achievement + */ + public function moveup($seminaryUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Set position + $this->Achievements->moveAchievement($achievement, true); + + + // Redirect + $this->redirect($this->linker->link(array('manage', $seminary['url']), 1, true, null, false, $achievement['url'])); + } + + + /** + * Action: movedown. + * + * Move an Achievement down (increment position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $achievementUrl URL-title of Achievement + */ + public function movedown($seminaryUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Set position + $this->Achievements->moveAchievement($achievement, false); + + + // Redirect + $this->redirect($this->linker->link(array('manage', $seminary['url']), 1, true, null, false, $achievement['url'])); + } + + + /** + * Action: edit. + * + * Edit an Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $achievementUrl URL-title of Achievement to edit + */ + public function edit($seminaryUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Get Achievements conditions + $conditions = $this->Achievements->getAchievementsConditions(); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = $achievement['title']; + $description = $achievement['description']; + $progress = $achievement['progress']; + $hidden = $achievement['hidden']; + $onlyOnce = $achievement['only_once']; + $allConditions = $achievement['all_conditions']; + $deadline = $achievement['deadline']; + $condition = $achievement['condition']; + $fields = array('title', 'deadline'); + $validation = array(); + + // Edit Achievement + if($this->request->getRequestMethod() == 'POST' && (!is_null($this->request->getPostParam('edit')) || !is_null($this->request->getPostParam('edit-conditions')))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Achievements->achievementTitleExists($seminary['id'], $title, $achievement['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $description = $this->request->getPostParam('description'); + $progress = !is_null($this->request->getPostParam('progress')); + $hidden = !is_null($this->request->getPostParam('hidden')); + $onlyOnce = !is_null($this->request->getPostParam('only_once')); + $allConditions = !is_null($this->request->getPostParam('all_conditions')); + $deadline = $this->request->getPostParam('deadline'); + $condition = $this->request->getPostParam('condition'); + + // Validate condition + $conditionIndex = null; + foreach($conditions as $index => &$c) { + if($condition == $c['condition']) { + $conditionIndex = $index; + } + } + if(is_null($conditionIndex)) { + throw new \nre\exceptions\ParamsNotValidException($condition); + } + + // Validate images + $images = array( + 'unachieved_image' => null, + 'achieved_image' => null + ); + foreach($images as $key => $image) + { + if(!empty($_FILES) && array_key_exists($key, $_FILES) && $_FILES[$key]['error'] != UPLOAD_ERR_NO_FILE) + { + $images[$key] = $_FILES[$key]; + + // Check error + if($images[$key]['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'error', $image[$key]['error']); + } + + // Check mimetype + $mediaMimetype = null; + $images[$key]['mimetype'] = \hhu\z\Utils::getMimetype($images[$key]['tmp_name'], $images[$key]['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $images[$key]['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'mimetype', $images[$key]['mimetype']); + } + elseif($images[$key]['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'image', 'size', $mediaMimetype['size']); + } + } + } + + // Edit Achievement + if($validation === true) + { + $this->Achievements->editAchievement( + $achievement['id'], + $conditions[$conditionIndex]['id'], + $title, + $description, + $progress, + $hidden, + $onlyOnce, + $allConditions, + (!empty($deadline)) ? $deadline : NULL + ); + + // Remove old conditions + if($conditions[$conditionIndex]['condition'] != $achievement['condition']) + { + var_dump("remove"); + switch($achievement['condition']) + { + // Date conditions + case 'date': + foreach($this->Achievements->getAchievementConditionsDate($achievement['id']) as $c) { + $this->Achievements->deleteAchievementConditionDate($c['id']); + } + break; + // Character conditions + case 'character': + foreach($this->Achievements->getAchievementConditionsCharacter($achievement['id']) as $c) { + $this->Achievements->deleteAchievementConditionCharacter($c['id']); + } + break; + // Quest conditions + case 'quest': + foreach($this->Achievements->getAchievementConditionsQuest($achievement['id']) as $c) { + $this->Achievements->deleteAchievementConditionQuest($c['id']); + } + break; + // Achievement conditions + case 'achievement': + foreach($this->Achievements->getAchievementConditionsAchievement($achievement['id']) as $c) { + $this->Achievements->deleteAchievementConditionAchievement($c['id']); + } + break; + } + } + + // Upload images + foreach($images as $key => &$image) + { + if(!is_null($image)) + { + $image['media_id'] = $this->Media->createAchievementMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('achievement-%d', $achievement['id']).(substr($key, 0, 2) == 'un' ? '-locked' : NULL), + '', + $image['mimetype'], + $image['tmp_name'] + ); + } + } + if(!is_null($images['unachieved_image']) && $images['unachieved_image']['media_id'] !== false) { + $this->Achievements->setUnachievedMediaForAchievement($achievement['id'], $images['unachieved_image']['media_id']); + } + if(!is_null($images['achieved_image']) && $images['achieved_image']['media_id'] !== false) { + $this->Achievements->setAchievedMediaForAchievement($achievement['id'], $images['achieved_image']['media_id']); + } + + // Redirect + if(!is_null($this->request->getPostParam('edit-conditions'))) { + // To condition editing + $this->redirect($this->linker->link(array('conditions', $seminary['url'], $achievement['url']), 1)); + } + else { + // To overview + $this->redirect($this->linker->link(array('manage', $seminary['url']), 1, true, null, false, $achievement['url'])); + } + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('Edit Achievement'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('achievement', $achievement); + $this->set('title', $title); + $this->set('description', $description); + $this->set('progress', $progress); + $this->set('hidden', $hidden); + $this->set('onlyOnce', $onlyOnce); + $this->set('allConditions', $allConditions); + $this->set('deadline', $deadline); + $this->set('condition', $condition); + $this->set('conditions', $conditions); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: conditions. + * + * Edit conditions of an Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $achievementUrl URL-title of Achievement to edit + */ + public function conditions($seminaryUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Get conditions + $conditions = array(); + switch($achievement['condition']) + { + // Date conditions + case 'date': + $conditions = $this->Achievements->getAchievementConditionsDate($achievement['id']); + break; + // Character conditions + case 'character': + $conditions = $this->Achievements->getAchievementConditionsCharacter($achievement['id']); + break; + // Quest conditions + case 'quest': + $conditions = $this->Achievements->getAchievementConditionsQuest($achievement['id']); + break; + // Achievement conditions + case 'achievement': + $conditions = $this->Achievements->getAchievementConditionsAchievement($achievement['id']); + break; + } + + // Values + $characterFields = array( + 'id', 'created', 'user_id', 'name', 'url', 'xps', 'quest_xps', 'avatar_id', + 'charactertype_id', 'charactertype_name', 'charactertype_url', + 'xplevel_id', 'xplevel' + ); + $questFields = array( + 'id', 'quest_id', 'character_id', 'created', 'status' + ); + $achievementFields = array( + 'achievement_id', 'character_id', 'created' + ); + $quests = $this->Quests->getQuestsForSeminary($seminary['id']); + $achievements = $this->Achievements->getAchievementsForSeminary($seminary['id']); + $deletes = array(); + + // Save conditions + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get entered conditions + $selectedConditions = $this->request->getPostParam('conditions'); + $deletes = $this->request->getPostParam('deletes'); + if(!is_array($deletes)) { + $deletes = array(); + } + + // Edit or delete conditions + foreach($conditions as &$condition) + { + $selectedCondition = $selectedConditions[$condition['id']]; + switch($achievement['condition']) + { + // Date conditions + case 'date': + if(array_key_exists($condition['id'], $deletes)) { + $this->Achievements->deleteAchievementConditionDate($condition['id']); + } + else { + $this->Achievements->editAchievementConditionDate( + $condition['id'], + $selectedCondition['select'] + ); + } + break; + // Character conditions + case 'character': + if(array_key_exists($condition['id'], $deletes)) { + $this->Achievements->deleteAchievementConditionCharacter($condition['id']); + } + else { + $this->Achievements->editAchievementConditionCharacter( + $condition['id'], + $selectedCondition['field'], + $selectedCondition['value'] + ); + } + break; + // Quest conditions + case 'quest': + if(array_key_exists($condition['id'], $deletes)) { + $this->Achievements->deleteAchievementConditionQuest($condition['id']); + } + else + { + // Get selected Quest + $questIndex = null; + if(!empty($selectedCondition['quest'])) { + foreach($quests as $index => &$quest) { + if($quest['url'] == $selectedCondition['quest']) { + $questIndex = $index; + } + } + } + + // Edit condition + $this->Achievements->editAchievementConditionQuest( + $condition['id'], + $selectedCondition['field'], + array_key_exists('count', $selectedCondition), + $selectedCondition['value'], + (!is_null($questIndex)) ? $quests[$questIndex]['id'] : null, + ($selectedCondition['status'] != '') ? $selectedCondition['status'] : null, + (!empty($selectedCondition['groupby'])) ? $selectedCondition['groupby'] : null + ); + } + break; + // Achievement conditions + case 'achievement': + if(array_key_exists($condition['id'], $deletes)) { + $this->Achievements->deleteAchievementConditionAchievement($condition['id']); + } + else + { + // Get selected Achievement + $achievmentIndex = null; + if(!empty($selectedCondition['achievement'])) { + foreach($achievements as $index => &$a) { + if($a['url'] == $selectedCondition['achievement']) { + $achievementIndex = $index; + } + } + } + + // Edit condition + $this->Achievements->editAchievementConditionAchievement( + $condition['id'], + $selectedCondition['field'], + array_key_exists('count', $selectedCondition), + $selectedCondition['value'], + (!is_null($achievementIndex)) ? $achievements[$achievementIndex]['id'] : null, + (!empty($selectedCondition['groupby'])) ? $selectedCondition['groupby'] : null + ); + } + break; + } + } + + // Add new condition + if(array_key_exists('new', $selectedConditions)) + { + $condition = $selectedConditions['new']; + switch($achievement['condition']) + { + // Date conditions + case 'date': + if(!empty($condition['select'])) { + $this->Achievements->addAchievementConditionDate( + $this->Auth->getUserId(), + $achievement['id'], + $condition['select'] + ); + } + break; + // Character conditions + case 'character': + if(!empty($condition['value'])) { + $this->Achievements->addAchievementConditionCharacter( + $this->Auth->getUserId(), + $achievement['id'], + $condition['field'], + $condition['value'] + ); + } + break; + // Quest conditions + case 'quest': + if(!empty($condition['value'])) + { + // Get selected Quest + $questIndex = null; + if(!empty($condition['quest'])) { + foreach($quests as $index => &$quest) { + if($quest['url'] == $condition['quest']) { + $questIndex = $index; + } + } + } + + // Edit condition + $this->Achievements->addAchievementConditionQuest( + $this->Auth->getUserId(), + $achievement['id'], + $condition['field'], + array_key_exists('count', $condition), + $condition['value'], + (!is_null($questIndex)) ? $quests[$questIndex]['id'] : null, + ($condition['status'] != '') ? $condition['status'] : null, + (!empty($condition['groupby'])) ? $condition['groupby'] : null + ); + } + break; + // Achievement conditions + case 'achievement': + if(!empty($condition['value'])) + { + // Get selected Achievement + $achievmentIndex = null; + if(!empty($selectedCondition['achievement'])) { + foreach($achievements as $index => &$a) { + if($a['url'] == $selectedCondition['achievement']) { + $achievementIndex = $index; + } + } + } + + // Edit condition + $this->Achievements->addAchievementConditionAchievement( + $this->Auth->getUserId(), + $achievement['id'], + $condition['field'], + array_key_exists('count', $condition), + $condition['value'], + (!is_null($achievementIndex)) ? $achievements[$achievementIndex]['id'] : null, + (!empty($condition['groupby'])) ? $condition['groupby'] : null + ); + } + break; + } + } + + // Redirect to overview + $this->redirect($this->linker->link(array('manage', $seminary['url']), 1, true, null, false, $achievement['url'])); + } + + + // Set title + $this->addTitleLocalized('Edit Achievement conditions'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('achievement', $achievement); + $this->set('conditions', $conditions); + $this->set('characterFields', $characterFields); + $this->set('questFields', $questFields); + $this->set('quests', $quests); + $this->set('achievementFields', $achievementFields); + $this->set('achievements', $achievements); + $this->set('deletes', $deletes); + } + + + /** + * Action: delete. + * + * Delete an Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $achievementUrl URL-title of Achievement + */ + public function delete($seminaryUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Achievements->deleteAchievement($achievement); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('manage', $seminary['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete seminary'); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('achievement', $achievement); + } + } + +?> diff --git a/controllers/AjaxController.inc b/controllers/AjaxController.inc new file mode 100644 index 00000000..9ed801df --- /dev/null +++ b/controllers/AjaxController.inc @@ -0,0 +1,52 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the AjaxAgent to return a JSON-string used by AJAX. + * + * @author Oliver Hanraths + */ + class AjaxController extends \hhu\z\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set content-type + $this->response->addHeader("Content-type: application/json; charset=utf-8"); + } + + + /** + * Action: index. + * + * Create the JSON-string. + */ + public function index() + { + } + + } + +?> diff --git a/controllers/BinaryController.inc b/controllers/BinaryController.inc new file mode 100644 index 00000000..0d4396ef --- /dev/null +++ b/controllers/BinaryController.inc @@ -0,0 +1,37 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the BinaryAgent to show binary data. + * + * @author Oliver Hanraths + */ + class BinaryController extends \hhu\z\controllers\IntermediateController + { + + + + + /** + * Action: index. + * + * Create binary data. + */ + public function index() + { + } + + } + +?> diff --git a/controllers/CharactergroupsController.inc b/controllers/CharactergroupsController.inc new file mode 100644 index 00000000..e09e9487 --- /dev/null +++ b/controllers/CharactergroupsController.inc @@ -0,0 +1,759 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the CharactergroupsAgent to display Character groups. + * + * @author Oliver Hanraths + */ + class CharactergroupsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'charactergroups', 'charactergroupsquests', 'characters', 'avatars', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'groupsgroup' => array('admin', 'moderator', 'user'), + 'creategroupsgroup' => array('admin', 'moderator', 'user'), + 'editgroupsgroup' => array('admin', 'moderator', 'user'), + 'deletegroupsgroup' => array('admin', 'moderator', 'user'), + 'group' => array('admin', 'moderator', 'user'), + 'managegroup' => array('admin', 'moderator', 'user'), + 'creategroup' => array('admin', 'moderator', 'user'), + 'editgroup' => array('admin', 'moderator', 'user'), + 'deletegroup' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'groupsgroup' => array('admin', 'moderator', 'user'), + 'creategroupsgroup' => array('admin', 'moderator'), + 'editgroupsgroup' => array('admin', 'moderator'), + 'deletegroupsgroup' => array('admin', 'moderator'), + 'group' => array('admin', 'moderator', 'user'), + 'managegroup' => array('admin', 'moderator'), + 'creategroup' => array('admin', 'moderator'), + 'editgroup' => array('admin', 'moderator', 'user'), + 'deletegroup' => array('admin', 'moderator') + ); + + + + + /** + * Action: index. + * + * Show Character groups-groups for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function index($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-groups + $groupsgroups = $this->Charactergroups->getGroupsroupsForSeminary($seminary['id']); + + + // Set titile + $this->addTitleLocalized('Character Groups'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroups', $groupsgroups); + } + + + /** + * Action: groupsgroups. + * + * Show Character groups for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + */ + public function groupsgroup($seminaryUrl, $groupsgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups + $groups = $this->Charactergroups->getGroupsForGroupsgroup($groupsgroup['id'], 'xps'); + + // Get Character groups-group Quests + $quests = $this->Charactergroupsquests->getQuestsForCharactergroupsgroup($groupsgroup['id']); + + + // Set titile + $this->addTitle($groupsgroup['name']); + $this->addTitleLocalized('Character Groups'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('groups', $groups); + $this->set('quests', $quests); + } + + + /** + * Action: creategroupsgroups. + * + * Create a new Character groups-group for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function creategroupsgroup($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Values + $charactergroupsgroupname = ''; + $preferred = false; + $fields = array('charactergroupsgroupname'); + $validation = array(); + + // Create a new Character groups-group + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $charactergroupsgroupname = $this->request->getPostParam('charactergroupsgroupname'); + if($this->Charactergroups->characterGroupsgroupNameExists($charactergroupsgroupname)) { + $validation = $this->Validation->addValidationResult($validation, 'charactergroupsgroupname', 'exist', true); + } + $preferred = !is_null($this->request->getPostParam('preferred')); + + // Create groups-group + if($validation === true) + { + $groupsgroupId = $this->Charactergroups->createGroupsgroup( + $this->Auth->getUserId(), + $seminary['id'], + $charactergroupsgroupname, + $preferred + ); + + // Redirect to groups-group page + $groupsgroup = $this->Charactergroups->getGroupsgroupById($groupsgroupId); + $this->redirect($this->linker->link(array('groupsgroup', $seminary['url'], $groupsgroup['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('New Character groups-group'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('charactergroupsgroupname', $charactergroupsgroupname); + $this->set('preferred', $preferred); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: editgroupsgroups. + * + * Edit a Character groups-group of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + */ + public function editgroupsgroup($seminaryUrl, $groupsgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Values + $charactergroupsgroupname = $groupsgroup['name']; + $preferred = $groupsgroup['preferred']; + $fields = array('charactergroupsgroupname'); + $validation = array(); + + // Edit Character groups-group + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $charactergroupsgroupname = $this->request->getPostParam('charactergroupsgroupname'); + if($this->Charactergroups->characterGroupsgroupNameExists($charactergroupsgroupname, $groupsgroup['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'charactergroupsgroupname', 'exist', true); + } + $preferred = !is_null($this->request->getPostParam('preferred')); + + // Edit groups-group + if($validation === true) + { + $this->Charactergroups->editGroupsgroup( + $groupsgroup['id'], + $charactergroupsgroupname, + $preferred + ); + + // Redirect to user page + $groupsgroup = $this->Charactergroups->getGroupsgroupById($groupsgroup['id']); + $this->redirect($this->linker->link(array('groupsgroup', $seminary['url'], $groupsgroup['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Edit Character groups-group'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('charactergroupsgroupname', $charactergroupsgroupname); + $this->set('preferred', $preferred); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: deletegroupsgroups. + * + * Delete a Character groups-group of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + */ + public function deletegroupsgroup($seminaryUrl, $groupsgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Charactergroups->deleteGroupsgroup($groupsgroup['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('index', $seminary['url']), 1)); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('groupsgroup', $seminary['url'], $groupsgroup['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete Character groups-group'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + } + + + /** + * Action: group. + * + * Show a Character group for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function group($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + $group['characters'] = $this->Characters->getCharactersForGroup($group['id']); + $group['rank'] = $this->Charactergroups->getXPRank($groupsgroup['id'], $group['xps']); + + // Get Character avatars + foreach($group['characters'] as &$character) + { + $avatar = $this->Avatars->getAvatarById($character['avatar_id']); + if(!is_null($avatar['small_avatarpicture_id'])) { + $character['small_avatar'] = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); + } + } + + // Get Character groups Quests + $quests = $this->Charactergroupsquests->getQuestsForGroup($group['id']); + + + // Set titile + $this->addTitle($group['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('group', $group); + $this->set('quests', $quests); + } + + + /** + * Action: managegroup. + * + * Manage a Character group for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function managegroup($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + + // Manage + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('actions')) && count($this->request->getPostParam('actions')) > 0) // && !is_null($this->request->getPostParam('characters')) && count($this->request->getPostParam('characters')) > 0) + { + $actions = $this->request->getPostParam('actions'); + $action = array_keys($actions)[0]; + $selectedCharacters = $this->request->getPostParam('characters'); + + switch($action) + { + // Add Characters to group + case 'addcharacters': + foreach($selectedCharacters as &$characterId) { + $this->Charactergroups->addCharacterToCharactergroup($group['id'], $characterId); + } + break; + // Remove Characters from group + case 'removecharacters': + foreach($selectedCharacters as &$characterId) { + $this->Charactergroups->removeCharacterFromCharactergroup($group['id'], $characterId); + } + break; + } + } + + // Get additional data for group + $group['characters'] = $this->Characters->getCharactersForGroup($group['id']); + $group['rank'] = $this->Charactergroups->getXPRank($groupsgroup['id'], $group['xps']); + + // Get Character avatars + foreach($group['characters'] as &$character) + { + $avatar = $this->Avatars->getAvatarById($character['avatar_id']); + if(!is_null($avatar['small_avatarpicture_id'])) { + $character['small_avatar'] = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); + } + } + + // Get Character groups Quests + $quests = $this->Charactergroupsquests->getQuestsForGroup($group['id']); + + // Get all Characters of Seminary + $groupCharacterIds = array_map(function($c) { return $c['id']; }, $group['characters']); + $seminaryCharacters = $this->Characters->getCharactersForSeminary($seminary['id'], true); + $characters = array(); + foreach($seminaryCharacters as &$character) { + if(!in_array($character['id'], $groupCharacterIds)) { + $characters[] = $character; + } + } + + + // Set titile + $this->addTitle($group['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('group', $group); + $this->set('quests', $quests); + $this->set('characters', $characters); + } + + + /** + * Action: creategroup. + * + * Create a Character group for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + */ + public function creategroup($seminaryUrl, $groupsgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $charactergroupname = ''; + $motto = ''; + $fields = array('charactergroupname', 'motto'); + $validation = array(); + + // Create a new Character groups-group + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $charactergroupname = $this->request->getPostParam('charactergroupname'); + if($this->Charactergroups->characterGroupNameExists($charactergroupname)) { + $validation = $this->Validation->addValidationResult($validation, 'charactergroupname', 'exist', true); + } + $motto = $this->request->getPostParam('motto'); + + // Validate icon + $icon = null; + if(!empty($_FILES) && array_key_exists('icon', $_FILES) && $_FILES['icon']['error'] != UPLOAD_ERR_NO_FILE) + { + $icon = $_FILES['icon']; + + // Check error + if($icon['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'error', $icon['error']); + } + + // Check mimetype + $mediaMimetype = null; + $icon['mimetype'] = \hhu\z\Utils::getMimetype($icon['tmp_name'], $icon['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $icon['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'mimetype', $icon['mimetype']); + } + elseif($icon['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'size', $mediaMimetype['size']); + } + } + + // Create group + if($validation === true) + { + $groupId = $this->Charactergroups->createGroup( + $this->Auth->getUserId(), + $groupsgroup['id'], + $charactergroupname, + $motto + ); + $group = $this->Charactergroups->getGroupById($groupId); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createCharactergroupMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroup-%s', $group['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroups->setMediaForGroup($group['id'], $mediaId); + } + } + + // Redirect to group page + $this->redirect($this->linker->link(array('group', $seminary['url'], $groupsgroup['url'], $group['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('New %s Character group', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('charactergroupname', $charactergroupname); + $this->set('motto', $motto); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: editgroup. + * + * Edit a Character group for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function editgroup($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + $group['characters'] = $this->Characters->getCharactersForGroup($group['id']); + + // Check permission + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) == 0 && !in_array(\hhu\z\controllers\SeminaryController::$character['id'], array_map(function($c) { return $c['id']; }, $group['characters']))) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $charactergroupname = $group['name']; + $motto = $group['motto']; + $fields = array('charactergroupname', 'motto'); + $validation = array(); + + // Edit Character group + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $charactergroupname = (count(array_intersect(array('admin','moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) ? $this->request->getPostParam('charactergroupname') : $group['name']; + if($this->Charactergroups->characterGroupNameExists($charactergroupname, $group['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'charactergroupname', 'exist', true); + } + $motto = $this->request->getPostParam('motto'); + + // Validate icon + $icon = null; + if(!empty($_FILES) && array_key_exists('icon', $_FILES) && $_FILES['icon']['error'] != UPLOAD_ERR_NO_FILE) + { + $icon = $_FILES['icon']; + + // Check error + if($icon['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'error', $icon['error']); + } + + // Check mimetype + $mediaMimetype = null; + $icon['mimetype'] = \hhu\z\Utils::getMimetype($icon['tmp_name'], $icon['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $icon['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'mimetype', $icon['mimetype']); + } + elseif($icon['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'size', $mediaMimetype['size']); + } + } + + // Edit group + if($validation === true) + { + $this->Charactergroups->editGroup( + $group['id'], + $charactergroupname, + $motto + ); + $group = $this->Charactergroups->getGroupById($group['id']); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createCharactergroupMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroup-%s', $group['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroups->setMediaForGroup($group['id'], $mediaId); + } + } + + // Redirect to user page + $this->redirect($this->linker->link(array('group', $seminary['url'], $groupsgroup['url'], $group['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('Edit %s Character group', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('group', $group); + $this->set('charactergroupname', $charactergroupname); + $this->set('motto', $motto); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: deletegroup. + * + * Delete a Character group for a Character groups-group of a + * Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function deletegroup($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Charactergroups->deleteGroup($group['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('groupsgroup', $seminary['url'], $groupsgroup['url']), 1)); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('group', $seminary['url'], $groupsgroup['url'], $group['url']), 1)); + } + + + // Set title + $this->addTitleLocalized('Delete %s Character group', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('group', $group); + } + + } + +?> diff --git a/controllers/CharactergroupsquestsController.inc b/controllers/CharactergroupsquestsController.inc new file mode 100644 index 00000000..f4ba8916 --- /dev/null +++ b/controllers/CharactergroupsquestsController.inc @@ -0,0 +1,625 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the CharactergroupsquestsAgent to display Character + * groups Quests. + * + * @author Oliver Hanraths + */ + class CharactergroupsquestsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'charactergroups', 'charactergroupsquests', 'media', 'questgroups', 'uploads'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'quest' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'quest' => array('admin', 'moderator', 'user') + ); + + + + + /** + * Action: quest. + * + * Show a Character groups Quest for a Character groups-group + * of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $questUrl URL-Title of a Character groups Quest + */ + public function quest($seminaryUrl, $groupsgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups-group Quests + $quest = $this->Charactergroupsquests->getQuestByUrl($groupsgroup['id'], $questUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupById($quest['questgroups_id']); + $questgroup['entered'] = $this->Questgroups->hasCharacterEnteredQuestgroup($questgroup['id'], self::$character['id']); + + // Get Character groups-groups + $groups = $this->Charactergroups->getGroupsForQuest($quest['id']); + + // Get uploads + $uploads = $this->Charactergroupsquests->getMediaForQuest($quest['id']); + foreach($uploads as &$upload) { + $upload['upload'] = $this->Uploads->getSeminaryuploadById($upload['seminaryupload_id']); + } + + + // Set title + $this->addTitle($quest['title']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('quest', $quest); + $this->set('questgroup', $questgroup); + $this->set('groups', $groups); + $this->set('uploads', $uploads); + } + + + /** + * Action: manage. + * + * Manage a Character groups Quest for a Character groups-group + * of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $questUrl URL-Title of a Character groups Quest + */ + public function manage($seminaryUrl, $groupsgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups-group Quests + $quest = $this->Charactergroupsquests->getQuestByUrl($groupsgroup['id'], $questUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupById($quest['questgroups_id']); + $questgroup['entered'] = $this->Questgroups->hasCharacterEnteredQuestgroup($questgroup['id'], self::$character['id']); + + // Get Character groups + $groups = $this->Charactergroups->getGroupsForGroupsgroup($groupsgroup['id']); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['charactergroupsquests']; + + // Manage + $validation = array(); + if($this->request->getRequestMethod() == 'POST') + { + // Upload media + if(!is_null($this->request->getPostParam('setmedia'))) + { + $file = $_FILES['media']; + + // Check error + if($file['error'] !== 0 || empty($file['tmp_name'])) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'error', $file['error']); + } + + // Check mimetype + $mediaMimetype = null; + $file['mimetype'] = \hhu\z\Utils::getMimetype($file['tmp_name'], $file['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $file['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $file['mimetype']); + } + elseif($file['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']); + } + + // Upload media + if($validation === true || empty($valiadion)) + { + // Create filename + $filename = sprintf( + '%s-%d-%s.%s', + 'charactergroupsquest', + $quest['id'], + date('Ymd-His'), + mb_substr($file['name'], strrpos($file['name'], '.')+1) + ); + + // Upload file + $this->Charactergroupsquests->uploadMediaForQuest($this->Auth->getUserId(), $seminary['id'], $quest['id'], $file, $filename); + } + } + + // Delete media + if(!is_null($this->request->getPostParam('deletemedia'))) + { + $uploadIds = $this->request->getPostParam('uploads'); + var_dump($uploadIds); + foreach($uploadIds as $uploadId) { + $this->Uploads->deleteSeminaryupload($uploadId); + } + } + + // Set XPs of Character groups for this Character groups Quest + if(!is_null($this->request->getPostParam('setxps'))) + { + $xps = $this->request->getPostParam('xps'); + foreach($groups as &$group) + { + if(array_key_exists($group['url'], $xps) && $xps[$group['url']] != 'null') + { + $xpsFactor = intval($xps[$group['url']]) / $quest['xps']; + $this->Charactergroupsquests->setXPsOfGroupForQuest($quest['id'], $group['id'], $xpsFactor); + } + else { + $this->Charactergroupsquests->deleteGroupForQuest($quest['id'], $group['id']); + } + } + } + + // Redirect to Quest page + if($validation === true || empty($validation)) { + $this->redirect($this->linker->link(array('quest', $seminary['url'], $groupsgroup['url'], $quest['url']), 1)); + } + } + + // Get icon + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Get uploads + $uploads = $this->Charactergroupsquests->getMediaForQuest($quest['id']); + foreach($uploads as &$upload) { + $upload['upload'] = $this->Uploads->getSeminaryuploadById($upload['seminaryupload_id']); + } + + + // Set XPs for Groups + foreach($groups as &$group) { + $group['quest_group'] = $this->Charactergroupsquests->getXPsOfGroupForQuest($quest['id'], $group['id']); + } + + + // Set title + $this->addTitle($quest['title']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('quest', $quest); + $this->set('uploads', $uploads); + $this->set('mimetypes', $mimetypes); + $this->set('questgroup', $questgroup); + $this->set('groups', $groups); + $this->set('media', $questmedia); + $this->set('validation', $validation); + } + + + /** + * Action: create. + * + * Create a new Character groups Quest for a Character + * groups-group of a Seminary. + * + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + */ + public function create($seminaryUrl, $groupsgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Questgroups + $questgroups = $this->Questgroups->getQuestgroupsForSeminary($seminary['id']); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = ''; + $xps = 0; + $description = ''; + $rules = ''; + $wonText = ''; + $lostText = ''; + $fields = array('title', 'xps'); + $validation = array(); + + // Create a new Character groups Quest + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Charactergroupsquests->characterGroupsQuestTitleExists($title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $xps = $this->request->getPostParam('xps'); + $description = $this->request->getPostParam('description'); + $rules = $this->request->getPostParam('rules'); + $wonText = $this->request->getPostParam('wonText'); + $lostText = $this->request->getPostParam('lostText'); + + // Validate icon + $icon = null; + if(!empty($_FILES) && array_key_exists('icon', $_FILES) && $_FILES['icon']['error'] != UPLOAD_ERR_NO_FILE) + { + $icon = $_FILES['icon']; + + // Check error + if($icon['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'error', $icon['error']); + } + + // Check mimetype + $mediaMimetype = null; + $icon['mimetype'] = \hhu\z\Utils::getMimetype($icon['tmp_name'], $icon['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $icon['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'mimetype', $icon['mimetype']); + } + elseif($icon['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'size', $mediaMimetype['size']); + } + } + + // Validate Questgroup + $questgroupIndex = null; + foreach($questgroups as $index => &$questgroup) + { + $questgroup['selected'] = ($questgroup['url'] == $this->request->getPostParam('questgroup')); + if($questgroup['selected']) { + $questgroupIndex = $index; + } + } + if(is_null($questgroupIndex)) { + throw new \nre\exceptions\ParamsNotValidException($questgroup); + } + + // Create groups Quest + if($validation === true) + { + $questId = $this->Charactergroupsquests->createQuest( + $this->Auth->getUserId(), + $groupsgroup['id'], + $questgroups[$questgroupIndex]['id'], + $title, + $description, + $xps, + $rules, + $wonText, + $lostText + ); + $quest = $this->Charactergroupsquests->getQuestById($questId); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsquest-%s', $quest['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsquests->setMediaForQuest($quest['id'], $mediaId); + } + } + + // Redirect to Quest page + $this->redirect($this->linker->link(array('quest', $seminary['url'], $groupsgroup['url'], $quest['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('New %s-Quest', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('questgroups', $questgroups); + $this->set('title', $title); + $this->set('xps', $xps); + $this->set('description', $description); + $this->set('rules', $rules); + $this->set('wonText', $wonText); + $this->set('lostText', $lostText); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a Character groups Quest of a Character groups-group + * of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $questUrl URL-Title of a Character groups Quest + */ + public function edit($seminaryUrl, $groupsgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups-group Quests + $quest = $this->Charactergroupsquests->getQuestByUrl($groupsgroup['id'], $questUrl); + + // Get Questgroups + $questgroups = $this->Questgroups->getQuestgroupsForSeminary($seminary['id']); + foreach($questgroups as $index => &$questgroup) { + $questgroup['selected'] = ($questgroup['id'] == $quest['questgroups_id']); + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = $quest['title']; + $xps = $quest['xps']; + $description = $quest['description']; + $rules = $quest['rules']; + $wonText = $quest['won_text']; + $lostText = $quest['lost_text']; + $fields = array('title', 'xps'); + $validation = array(); + + // Edit Character group + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Charactergroupsquests->characterGroupsQuestTitleExists($title, $quest['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $xps = $this->request->getPostParam('xps'); + $description = $this->request->getPostParam('description'); + $rules = $this->request->getPostParam('rules'); + $wonText = $this->request->getPostParam('wonText'); + $lostText = $this->request->getPostParam('lostText'); + + // Validate icon + $icon = null; + if(!empty($_FILES) && array_key_exists('icon', $_FILES) && $_FILES['icon']['error'] != UPLOAD_ERR_NO_FILE) + { + $icon = $_FILES['icon']; + + // Check error + if($icon['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'error', $icon['error']); + } + + // Check mimetype + $mediaMimetype = null; + $icon['mimetype'] = \hhu\z\Utils::getMimetype($icon['tmp_name'], $icon['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $icon['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'mimetype', $icon['mimetype']); + } + elseif($icon['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'icon', 'size', $mediaMimetype['size']); + } + } + + // Validate Questgroup + $questgroupIndex = null; + foreach($questgroups as $index => &$questgroup) + { + $questgroup['selected'] = ($questgroup['url'] == $this->request->getPostParam('questgroup')); + if($questgroup['selected']) { + $questgroupIndex = $index; + } + } + if(is_null($questgroupIndex)) { + throw new \nre\exceptions\ParamsNotValidException($questgroup); + } + + // Edit groups Quest + if($validation === true) + { + $this->Charactergroupsquests->editQuest( + $quest['id'], + $groupsgroup['id'], + $questgroups[$questgroupIndex]['id'], + $title, + $description, + $xps, + $rules, + $wonText, + $lostText + ); + $quest = $this->Charactergroupsquests->getQuestById($quest['id']); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsquest-%s', $quest['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsquests->setMediaForQuest($quest['id'], $mediaId); + } + } + + // Redirect to Quest page + $this->redirect($this->linker->link(array('quest', $seminary['url'], $groupsgroup['url'], $quest['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('Edit %s-Quest', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('quest', $quest); + $this->set('questgroups', $questgroups); + $this->set('title', $title); + $this->set('xps', $xps); + $this->set('description', $description); + $this->set('rules', $rules); + $this->set('wonText', $wonText); + $this->set('lostText', $lostText); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: delete. + * + * Delete a Character groups Quest of a Character groups-group + * of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $questUrl URL-Title of a Character groups Quest + */ + public function delete($seminaryUrl, $groupsgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups-group Quests + $quest = $this->Charactergroupsquests->getQuestByUrl($groupsgroup['id'], $questUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Charactergroupsquests->deleteQuest($quest['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('charactergroups', 'groupsgroup', $seminary['url'], $groupsgroup['url']))); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('quest', $seminary['url'], $groupsgroup['url'], $quest['url']), 1)); + } + + + // Set title + $this->addTitleLocalized('Delete %s-Quest', $groupsgroup['name']); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('quest', $quest); + } + + } + +?> diff --git a/controllers/CharactersController.inc b/controllers/CharactersController.inc new file mode 100644 index 00000000..96eaedb3 --- /dev/null +++ b/controllers/CharactersController.inc @@ -0,0 +1,695 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to list registered users and their data. + * + * @author Oliver Hanraths + */ + class CharactersController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'characters', 'users', 'charactergroups', 'charactertypes', 'seminarycharacterfields', 'avatars', 'media', 'quests', 'questgroups', 'questtopics', 'xplevels'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'character' => array('admin', 'moderator', 'user'), + 'register' => array('admin', 'moderator', 'user'), + 'manage' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator'), + 'character' => array('admin', 'moderator', 'user'), + 'manage' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator') + ); + + + + + /** + * Action: index. + * + * List registered Characters for a Seminary + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $all Whether to list all Characters at once or not (optional) + */ + public function index($seminaryUrl, $all=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Seminarycharacterfields + $characterfields = $this->Seminarycharacterfields->getFieldsForSeminary($seminary['id']); + + // Set sort order and page + $sortorder = 'name'; + $charactername = null; + $page = 1; + if($this->request->getRequestMethod() == 'GET') + { + $sortorder = $this->request->getGetParam('sortorder'); + $sortorder = !empty($sortorder) ? $sortorder : 'name'; + $charactername = (!is_null($this->request->getGetParam('charactername'))) ? $this->request->getGetParam('charactername') : $charactername; + $page = $this->request->getGetParam('page'); + $page = !empty($page) ? intval($page) : 1; + } + + // Get registered Characters + $limit = ($all != 'all') ? \nre\configs\AppConfig::$misc['lists_limit'] : null; + $offset = ($all != 'all') ? max((intval($page) - 1), 0) * $limit : 0; + $charactersCount = $this->Characters->getCharactersForSeminaryCount($seminary['id'], $charactername); + $characters = $this->Characters->getCharactersForSeminarySorted($seminary['id'], $sortorder, $charactername, $limit, $offset); + foreach($characters as &$character) + { + $character['user'] = $this->Users->getUserById($character['user_id']); + $character['characterroles'] = array_map(function($r) { return $r['name']; }, $this->Characterroles->getCharacterrolesForCharacterById($character['id'])); + $character['characterfields'] = array(); + foreach($this->Seminarycharacterfields->getFieldsForCharacter($character['id']) as $value) { + $character['characterfields'][$value['url']] = $value; + } + try { + $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No XP-level + } + try { + $character['avatar'] = $this->Avatars->getAvatarByTypeAndLevel($seminary['id'], $character['charactertype_url'], $character['xplevel']['level']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No Avatar available + } + } + + + // Set titile + $this->addTitleLocalized('Characters'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('characters', $characters); + $this->set('charactersCount', $charactersCount); + $this->set('characterfields', $characterfields); + $this->set('sortorder', $sortorder); + $this->set('charactername', $charactername); + $this->set('all', $all); + $this->set('page', $page); + $this->set('limit', $limit); + } + + + /** + * Action: character. + * + * Show a Charater and its details. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $characterUrl URL-name of a Charater + */ + public function character($seminaryUrl, $characterUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + $seminary['achievable_xps'] = $this->Seminaries->getTotalXPs($seminary['id']); + + // Get Character + $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); + try { + $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No XP-level + } + $character['rank'] = $this->Characters->getXPRank($seminary['id'], $character['xps']); + + // Get User + $user = $this->Users->getUserById($character['user_id']); + + // Get Character groups + $groups = $this->Charactergroups->getGroupsForCharacter($character['id']); + foreach($groups as &$group) { + $group['groupsgroup'] = $this->Charactergroups->getGroupsgroupById($group['charactergroupsgroup_id']); + } + + // Get Achievements + $achievements = $this->Achievements->getAchievedAchievementsForCharacter($character['id']); + + // Get Achievements with deadline (milestones) + $milestones = $this->Achievements->getDeadlineAchievements($seminary['id']); + foreach($milestones as &$milestone) { + $milestone['achieved'] = $this->Achievements->hasCharacterAchievedAchievement($milestone['id'], $character['id']); + } + + // Get ranking + $ranking = array( + 'superior' => $this->Characters->getSuperiorCharacters($seminary['id'], $character['xps'], \nre\configs\AppConfig::$misc['ranking_range']), + 'inferior' => $this->Characters->getInferiorCharacters($seminary['id'], $character['id'], $character['xps'], \nre\configs\AppConfig::$misc['ranking_range']) + ); + + // Get Quest topics + $questtopics = $this->Questtopics->getQuesttopicsForSeminary($seminary['id']); + foreach($questtopics as &$questtopic) + { + $questtopic['questcount'] = $this->Questtopics->getQuestCountForQuesttopic($questtopic['id']); + $questtopic['characterQuestcount'] = $this->Questtopics->getCharacterQuestCountForQuesttopic($questtopic['id'], $character['id']); + } + + // Get “last” Quest + $lastQuest = null; + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) + { + $lastQuest = $this->Quests->getLastQuestForCharacter($character['id']); + if(!is_null($lastQuest)) { + $lastQuest['questgroup'] = $this->Questgroups->getQuestgroupById($lastQuest['questgroup_id']); + } + } + + + // Set titile + $this->addTitle($character['name']); + $this->addTitleLocalized('Characters'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('user', $user); + $this->set('groups', $groups); + $this->set('achievements', $achievements); + $this->set('milestones', $milestones); + $this->set('ranking', $ranking); + $this->set('questtopics', $questtopics); + $this->set('lastQuest', $lastQuest); + } + + + /** + * Acton: register. + * + * Register a new character for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\ParamsNotValidException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function register($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check for already existing Character + try { + $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + throw new \nre\exceptions\AccessDeniedException(); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // This should be the case + } + + + // Character types + $types = $this->Charactertypes->getCharacterTypesForSeminary($seminary['id']); + + // Character fields + $fields = $this->Seminarycharacterfields->getFieldsForSeminary($seminary['id']); + + // Register Character + $charactername = ''; + $validation = true; + $fieldsValidation = true; + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Validate Character properties + $validation = $this->Validation->validateParams($this->request->getPostParams(), array('charactername')); + $charactername = $this->request->getPostParam('charactername'); + if($this->Characters->characterNameExists($charactername)) { + $validation = $this->Validation->addValidationResult($validation, 'charactername', 'exist', true); + } + + // Validate type + $typeIndex = null; + foreach($types as $index => &$type) + { + $type['selected'] = ($type['url'] == $this->request->getPostParam('type')); + if($type['selected']) { + $typeIndex = $index; + } + } + if(is_null($typeIndex)) { + $validation = $this->Validation->addValidationResult($validation, 'type', 'exist', false); + } + + // Validate fields + $fieldsValues = $this->request->getPostParam('fields'); + foreach($fields as &$field) + { + if(!array_key_exists($field['url'], $fieldsValues)) { + throw new \nre\exceptions\ParamsNotValidException($index); + } + $field['uservalue'] = $fieldsValues[$field['url']]; + if($field['required']) + { + $fieldValidation = $this->Validation->validate($fieldsValues[$field['url']], array('regex'=>$field['regex'])); + if($fieldValidation !== true) + { + if(!is_array($fieldsValidation)) { + $fieldsValidation = array(); + } + $fieldsValidation[$field['url']] = $fieldValidation; + } + } + } + + // Register + if($validation === true && $fieldsValidation === true) + { + $characterId = $this->Characters->createCharacter($this->Auth->getUserId(), $types[$typeIndex]['id'], $charactername); + $character = $this->Characters->getCharacterById($characterId); + + // Add Seminary fields + foreach($fields as &$field) { + if(!empty($fieldsValues[$field['url']])) { + $this->Seminarycharacterfields->setSeminaryFieldOfCharacter($field['id'], $characterId, $fieldsValues[$field['url']]); + } + } + + // Set roles for owners and admins + if(in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles']) || $seminary['created_user_id'] == \hhu\z\controllers\IntermediateController::$user['id']) { + $this->Characterroles->addCharacterroleToCharacter($characterId, 'admin'); + } + + // Send mail + $this->sendRegistrationMail($character); + + // Redirect + $this->redirect($this->linker->link(array('seminaries'))); + } + } + + // Get XP-levels + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + + // Get Avatars + if(count($xplevels) > 0) + { + foreach($types as &$type) + { + try { + $type['avatar'] = $this->Avatars->getAvatarByTypeAndLevel($seminary['id'], $type['url'], $xplevels[0]['level']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No Avatar available + } + } + } + + + // Set titile + $this->addTitleLocalized('Create Character'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('types', $types); + $this->set('fields', $fields); + $this->set('charactername', $charactername); + $this->set('validation', $validation); + $this->set('fieldsValidation', $fieldsValidation); + $this->set('xplevels', $xplevels); + } + + + /** + * Action: manage. + * + * Manage Characters. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function manage($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Set sort order and page + + $selectedCharacters = array(); + $sortorder = 'name'; + if($this->request->getRequestMethod() == 'POST') + { + // Set sortorder + $sortorder = $this->request->getPostParam('sortorder'); + $sortorder = !empty($sortorder) ? $sortorder : 'name'; + + // Do action + $selectedCharacters = $this->request->getPostParam('characters'); + if(!is_array($selectedCharacters)) { + $selectedCharacters = array(); + } + if(!is_null($this->request->getPostParam('actions')) && count($this->request->getPostParam('actions')) > 0 && !is_null($this->request->getPostParam('characters')) && count($this->request->getPostParam('characters')) > 0) + { + $actions = $this->request->getPostParam('actions'); + $action = array_keys($actions)[0]; + + switch($action) + { + // Add/remove role to/from Characters + case 'addrole': + case 'removerole': + // Determine role and check permissions + $role = null; + switch($actions[$action]) + { + case _('Admin'): + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) <= 0 && !in_array('admin', \hhu\z\controllers\SeminaryController::$character['characterroles'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'admin'; + break; + case _('Moderator'): + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) <= 0 && !in_array('admin', \hhu\z\controllers\SeminaryController::$character['characterroles'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'moderator'; + break; + case _('User'): + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) <= 0 && count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) <= 0) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'user'; + break; + } + + // Add role + if($action == 'addrole') { + foreach($selectedCharacters as &$characterId) { + $this->Characterroles->addCharacterroleToCharacter($characterId, $role); + } + } + // Remove role + else { + foreach($selectedCharacters as &$characterId) { + $this->Characterroles->removeCharacterroleFromCharacter($characterId, $role); + } + } + break; + } + } + } + + // Get Seminarycharacterfields + $characterfields = $this->Seminarycharacterfields->getFieldsForSeminary($seminary['id']); + + // Get registered Characters + $characters = $this->Characters->getCharactersForSeminarySorted($seminary['id'], $sortorder); + foreach($characters as &$character) + { + $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + $character['user'] = $this->Users->getUserById($character['user_id']); + $character['characterroles'] = array_map(function($r) { return $r['name']; }, $this->Characterroles->getCharacterrolesForCharacterById($character['id'])); + $character['characterfields'] = array(); + foreach($this->Seminarycharacterfields->getFieldsForCharacter($character['id']) as $value) { + $character['characterfields'][$value['url']] = $value; + } + } + + + // Set titile + $this->addTitleLocalized('Manage Characters'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('characters', $characters); + $this->set('characterfields', $characterfields); + $this->set('selectedCharacters', $selectedCharacters); + $this->set('sortorder', $sortorder); + } + + + /** + * Acton: edit. + * + * Edit a new character for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\ParamsNotValidException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $characterUrl URL-name of a Charater + */ + public function edit($seminaryUrl, $characterUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); + + // Check permissions + if(count(array_intersect(array('admin','moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) == 0 && $character['id'] != \hhu\z\controllers\SeminaryController::$character['id']) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get User + $user = $this->Users->getUserById($character['user_id']); + + // Character types + $types = $this->Charactertypes->getCharacterTypesForSeminary($seminary['id']); + foreach($types as &$type) { + $type['selected'] = ($type['url'] == $character['charactertype_url']); + } + + // Character fields + $fields = $this->Seminarycharacterfields->getFieldsForSeminary($seminary['id']); + foreach($fields as &$field) + { + $userValue = $this->Seminarycharacterfields->getSeminaryFieldOfCharacter($field['id'], $character['id']); + if(!empty($userValue)) { + $field['uservalue'] = $userValue['value']; + } + } + + // Values + $charactername = $character['name']; + $validation = array(); + $fieldsValidation = true; + + // Edit Character + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Validate Character properties + $validation = $this->Validation->validateParams($this->request->getPostParams(), array('charactername')); + $charactername = (count(array_intersect(array('admin','moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) ? $this->request->getPostParam('charactername') : $character['name']; + if($this->Characters->characterNameExists($charactername, $character['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'charactername', 'exist', true); + } + + // Validate type + $typeIndex = null; + foreach($types as $index => &$type) + { + $type['selected'] = (count(array_intersect(array('admin','moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) ? ($type['url'] == $this->request->getPostParam('type')) : ($type['url'] == $character['charactertype_url']); + if($type['selected']) { + $typeIndex = $index; + } + } + if(is_null($typeIndex)) { + $validation = $this->Validation->addValidationResult($validation, 'type', 'exist', false); + } + + // Validate fields + $fieldsValues = $this->request->getPostParam('fields'); + foreach($fields as &$field) + { + if(!array_key_exists($field['url'], $fieldsValues)) { + throw new \nre\exceptions\ParamsNotValidException($index); + } + $field['uservalue'] = $fieldsValues[$field['url']]; + if($field['required']) + { + $fieldValidation = $this->Validation->validate($fieldsValues[$field['url']], array('regex'=>$field['regex'])); + if($fieldValidation !== true) + { + if(!is_array($fieldsValidation)) { + $fieldsValidation = array(); + } + $fieldsValidation[$field['url']] = $fieldValidation; + } + } + } + + // Edit + if($validation === true && $fieldsValidation === true) + { + $this->Characters->editCharacter( + $character['id'], + $types[$typeIndex]['id'], + $charactername + ); + + // Set Seminary fields + foreach($fields as &$field) { + if(!empty($fieldsValues[$field['url']])) { + $this->Seminarycharacterfields->setSeminaryFieldOfCharacter($field['id'], $character['id'], $fieldsValues[$field['url']]); + } + } + + // Redirect + $character = $this->Characters->getCharacterById($character['id']); + $this->redirect($this->linker->link(array('character', $seminary['url'], $character['url']), 1)); + } + } + + // Get XP-levels + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + + // Get validation settings + $validationSettings = array(); + $validationSettings['charactername'] = \nre\configs\AppConfig::$validation['charactername']; + + + // Set titile + $this->addTitleLocalized('Edit Character'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('types', $types); + $this->set('fields', $fields); + $this->set('charactername', $charactername); + $this->set('validation', $validation); + $this->set('fieldsValidation', $fieldsValidation); + $this->set('validationSettings', $validationSettings); + $this->set('xplevels', $xplevels); + } + + + /** + * Action: delete. + * + * Delete a Character. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $characterUrl URL-name of a Charater + */ + public function delete($seminaryUrl, $characterUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); + + // Get User + $user = $this->Users->getUserById($character['user_id']); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete Character + $this->Characters->deleteCharacter($character['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('index', $seminary['url']), 1)); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('index', $seminary['url'], $character['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete Character'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('user', $user); + } + + + + + /** + * Send mail for new Character registration. + * + * @param arary $newCharacter Newly registered Character + */ + private function sendRegistrationMail($newCharacter) + { + // Get Seminary moderators + $characters = $this->Characters->getCharactersWithCharacterRole(self::$seminary['id'], 'moderator'); + + // Send notification mail + try { + foreach($characters as &$character) + { + $moderator = $this->Users->getUserById($character['user_id']); + if($moderator['mailing']) { + \hhu\z\Utils::sendMail( + $moderator['email'], + 'characterregistration', + true, + array( + $moderator, + \hhu\z\controllers\SeminaryController::$seminary, + \hhu\z\controllers\IntermediateController::$user, + $newCharacter + ), + $this->linker + ); + } + } + } + catch(\hhu\z\exceptions\MailingException $e) { + $this->log($e->getMessage()); + } + } + + } + +?> diff --git a/controllers/CharactertypesController.inc b/controllers/CharactertypesController.inc new file mode 100644 index 00000000..60b3dbf3 --- /dev/null +++ b/controllers/CharactertypesController.inc @@ -0,0 +1,406 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the CharactertypesAgent to handle Charactertyes of a + * Seminary. + * + * @author Oliver Hanraths + */ + class CharactertypesController extends \hhu\z\controllers\SeminaryController + { + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * Required models + * + * @var array + */ + public $models = array('charactertypes', 'xplevels', 'avatars', 'media'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + + + + + /** + * Action: index. + * + * List Character types. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function index($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check permissions + if( + (is_null(self::$character) && count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) && + $seminary['created_user_id'] != self::$user['id'] + ) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get Character types + $charactertypes = $this->Charactertypes->getCharacterTypesForSeminary($seminary['id']); + + // Get Avatars + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + if(count($xplevels) > 0) + { + foreach($charactertypes as &$type) + { + try { + $type['avatar'] = $this->Avatars->getAvatarByTypeAndLevel($seminary['id'], $type['url'], $xplevels[0]['level']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No Avatar available + } + } + } + + + // Set titile + $this->addTitleLocalized('Charactertypes'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('xplevels', $xplevels); + $this->set('charactertypes', $charactertypes); + } + + + /** + * Action: create. + * + * Create new Character type for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function create($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check permissions + if( + $seminary['created_user_id'] != self::$user['id'] && + (is_null(self::$character) && count(array_intersect(array('admin'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) + ) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Values + $name = ''; + $fields = array('charactertypename'); + $validation = array(); + + // Create new Charactertype + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $name = $this->request->getPostParam('charactertypename'); + if($this->Charactertypes->charactertypeNameExists($seminary['id'], $name)) { + $validation = $this->Validation->addValidationResult($validation, 'charactertypename', 'exist', true); + } + + // Create new Charactertype + if($validation === true) + { + $charactertypeId = $this->Charactertypes->createCharactertype( + $this->Auth->getUserId(), + $seminary['id'], + $name + ); + $charactertype = $this->Charactertypes->getCharactertypeById($charactertypeId); + + // Redirect to editing + $this->redirect($this->linker->link(array('edit', $seminary['url'], $charactertype['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Create new Charactertype'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('name', $name); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit Character type for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of a Seminary + * @param string $charactertypeUrl URL-title of Character type + */ + public function edit($seminaryUrl, $charactertypeUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check permissions + if( + $seminary['created_user_id'] != self::$user['id'] && + (is_null(self::$character) && count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) + ) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get Character type + $charactertype = $this->Charactertypes->getCharactertypeByUrl($seminary['id'], $charactertypeUrl); + + // XP-levels + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + foreach($xplevels as &$xplevel) + { + try { + $xplevel['avatar'] = $this->Avatars->getAvatarByTypeAndLevel($seminary['id'], $charactertype['url'], $xplevel['level']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + // No Avatar available + } + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $name = $charactertype['name']; + $fields = array('charactertypename'); + $validation = array(); + $avatarVariants = array('portrait', 'avatar'); + $avatarsValidation = true; + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $name = $this->request->getPostParam('charactertypename'); + if($this->Charactertypes->charactertypeNameExists($seminary['id'], $name, $charactertype['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'charactertypename', 'exist', true); + } + + // Validate and upload avatars + if(array_key_exists('avatars', $_FILES)) + { + foreach($xplevels as &$xplevel) + { + if(array_key_exists($xplevel['id'], $_FILES['avatars']['error'])) + { + foreach($avatarVariants as &$variant) + { + if(array_key_exists($variant, $_FILES['avatars']['error'][$xplevel['id']]) && $_FILES['avatars']['error'][$xplevel['id']][$variant] !== UPLOAD_ERR_NO_FILE) + { + $avatar = array( + 'name' => $_FILES['avatars']['name'][$xplevel['id']][$variant], + 'type' => $_FILES['avatars']['type'][$xplevel['id']][$variant], + 'tmp_name' => $_FILES['avatars']['tmp_name'][$xplevel['id']][$variant], + 'error' => $_FILES['avatars']['error'][$xplevel['id']][$variant], + 'size' => $_FILES['avatars']['size'][$xplevel['id']][$variant] + ); + $avatarValidation = true; + + // Check error + if($avatar['error'] !== UPLOAD_ERR_OK) { + $avatarValidation = $this->Validation->addValidationResult($avatarValidation, 'avatar', 'error', $avatar['error']); + } + + // Check mimetype + $avatarMimetype = null; + $avatar['mimetype'] = \hhu\z\Utils::getMimetype($avatar['tmp_name'], $avatar['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $avatar['mimetype']) { + $avatarMimetype = $mimetype; + break; + } + } + if(is_null($avatarMimetype)) { + $avatarValidation = $this->Validation->addValidationResult($avatarValidation, 'avatar', 'mimetype', $avatar['mimetype']); + } + elseif($avatar['size'] > $avatarMimetype['size']) { + $avatarValidation = $this->Validation->addValidationResult($avatarValidation, 'avatar', 'size', $avatarMimetype['size']); + } + + // Add validation result + if(!$avatarValidation !== true) + { + if(!is_array($avatarsValidation)) { + $avatarsValidation = array(); + } + if(!array_key_exists($xplevel['id'], $avatarsValidation)) { + $avatarsValidation[$xplevel['id']] = array(); + } + $avatarsValidation[$xplevel['id']][$variant] = $avatarValidation; + } + + // Upload avatar + if($avatarValidation === true) + { + $avatar['media_id'] = $this->Media->createAvatarPicture( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('avatar-%d-%d-%s', $charactertype['id'], $xplevel['id'], $variant), + '', + $avatar['mimetype'], + $avatar['tmp_name'] + ); + + // Set avatar + if($variant == 'portrait') { + $this->Avatars->setAvatarPortraitForTypeAndLevel( + $this->Auth->getUserId(), + $charactertype['id'], + $xplevel['id'], + $avatar['media_id'] + ); + } + else { + $this->Avatars->setAvatarForTypeAndLevel( + $this->Auth->getUserId(), + $charactertype['id'], + $xplevel['id'], + $avatar['media_id'] + ); + } + } + } + } + } + } + } + + // Edit Charactertype + if($validation === true && $avatarsValidation === true) + { + $this->Charactertypes->editCharactertype( + $charactertype['id'], + $name + ); + $charactertype = $this->Charactertypes->getCharactertypeById($charactertype['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('index', $seminary['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Edit Charactertype'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('charactertype', $charactertype); + $this->set('xplevels', $xplevels); + $this->set('name', $name); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('avatarsValidation', $avatarsValidation); + $this->set('avatarVariants', $avatarVariants); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: delete. + * + * Delete Character type for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of a Seminary + * @param string $charactertypeUrl URL-title of Character type + */ + public function delete($seminaryUrl, $charactertypeUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check permissions + if( + $seminary['created_user_id'] != self::$user['id'] && + (is_null(self::$character) && count(array_intersect(array('admin'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) + ) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get Character type + $charactertype = $this->Charactertypes->getCharactertypeByUrl($seminary['id'], $charactertypeUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete Character type + $this->Charactertypes->deleteCharactertype($charactertype['id']); + } + + // Redirect to overview + $this->redirect($this->linker->link(array('index', $seminary['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete Charactertype'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('charactertype', $charactertype); + } + + } + +?> diff --git a/controllers/ErrorController.inc b/controllers/ErrorController.inc new file mode 100644 index 00000000..a27e3afd --- /dev/null +++ b/controllers/ErrorController.inc @@ -0,0 +1,51 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to show an error page. + * + * @author Oliver Hanraths + */ + class ErrorController extends \hhu\z\Controller + { + + + + + + + /** + * Action: index. + * + * Set HTTP-header and print an error message. + * + * @param int $httpStatusCode HTTP-statuscode of the error that occurred + */ + public function index($httpStatusCode) + { + // Set HTTP-header + if(!array_key_exists($httpStatusCode, \nre\core\WebUtils::$httpStrings)) { + $httpStatusCode = 200; + } + $this->response->addHeader(\nre\core\WebUtils::getHttpHeader($httpStatusCode)); + + // Display statuscode and message + $this->set('code', $httpStatusCode); + $this->set('string', \nre\core\WebUtils::$httpStrings[$httpStatusCode]); + $this->set('userId', $this->Auth->getUserId()); + } + + } + +?> diff --git a/controllers/FaultController.inc b/controllers/FaultController.inc new file mode 100644 index 00000000..be01fea7 --- /dev/null +++ b/controllers/FaultController.inc @@ -0,0 +1,37 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to display a toplevel error page. + * + * @author Oliver Hanraths + */ + class FaultController extends \nre\core\Controller + { + + + + + /** + * Action: index. + * + * Show the error message. + */ + public function index() + { + } + + } + +?> diff --git a/controllers/HtmlController.inc b/controllers/HtmlController.inc new file mode 100644 index 00000000..8c451441 --- /dev/null +++ b/controllers/HtmlController.inc @@ -0,0 +1,114 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the HtmlAgent to display a HTML-page. + * + * @author Oliver Hanraths + */ + class HtmlController extends \hhu\z\Controller + { + /** + * Required components + * + * @var array + */ + public $components = array('notification'); + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set content-type + $this->response->addHeader("Content-type: text/html; charset=utf-8"); + } + + + /** + * Postfilter that is executed after running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function postFilter(\nre\core\Request $request, \nre\core\Response $response) + { + // Get title + $this->set('title', $this->getTitle()); + } + + + /** + * Action: index. + * + * Create the HTML-structure. + */ + public function index() + { + // Set the name of the current IntermediateAgent as page title + $this->set('title', $this->request->getParam(1, 'intermediate')); + + // Set userdata + $this->set('loggedUser', IntermediateController::$user); + $this->set('loggedSeminary', SeminaryController::$seminary); + $this->set('loggedCharacter', SeminaryController::$character); + + // Set notifications + $this->set('notifications', $this->Notification->getNotifications()); + + // Set some application data + $this->set('mailcontact', \nre\configs\AppConfig::$app['mailcontact']); + } + + + + + /** + * Get title information from IntermediateController if possible + * and create a title. + * + * @return string Title for the current page + */ + private function getTitle() + { + $title = array(); + + // Get title of IntermediateController + $intermediateController = $this->agent->getIntermediateAgent()->controller; + if($intermediateController instanceof \hhu\z\controllers\IntermediateController) { + $title = $intermediateController->getTitle(); + } + if(!is_array($title)) { + $title = array($title); + } + + // Add application name + $title[] = \nre\configs\AppConfig::$app['name']; + + + // Return title with delimiter + return implode(\nre\configs\AppConfig::$misc['title_delimiter'], $title); + } + + } + +?> diff --git a/controllers/HtmlmailController.inc b/controllers/HtmlmailController.inc new file mode 100644 index 00000000..19640615 --- /dev/null +++ b/controllers/HtmlmailController.inc @@ -0,0 +1,54 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the HtmlmailAgent for generating a HTML-mail message. + * + * @author Oliver Hanraths + */ + class HtmlmailController extends \nre\core\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + + // Set linker + $this->set('linker', ($request instanceof \hhu\z\requests\MailRequest && !is_null($request->getLinker())) ? $request->getLinker() : null); + } + + + /** + * Action: index. + * + * Create HTML-structure of mail message. + */ + public function index() + { + $this->set('appname', \nre\configs\AppConfig::$app['name']); + } + + } + +?> diff --git a/controllers/IntroductionController.inc b/controllers/IntroductionController.inc new file mode 100644 index 00000000..c1a07f41 --- /dev/null +++ b/controllers/IntroductionController.inc @@ -0,0 +1,37 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to show an introduction page. + * + * @author Oliver Hanraths + */ + class IntroductionController extends \hhu\z\controllers\IntermediateController + { + + + + + /** + * Action: index. + */ + public function index() + { + // Pass data to view + $this->set('userId', $this->Auth->getUserId()); + } + + } + +?> diff --git a/controllers/LibraryController.inc b/controllers/LibraryController.inc new file mode 100644 index 00000000..0adfcdd8 --- /dev/null +++ b/controllers/LibraryController.inc @@ -0,0 +1,513 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the LibraryAgent to list Quest topics. + * + * @author Oliver Hanraths + */ + class LibraryController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('questtopics', 'seminaries', 'quests', 'questgroups'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'topic' => array('admin', 'moderator', 'user'), + 'manage' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator', 'user', 'guest'), + 'topic' => array('admin', 'moderator', 'user', 'guest'), + 'manage' => array('admin', 'moderator'), + 'create' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator'), + 'delete' => array('admin', 'moderator') + ); + + + + + /** + * Action: index. + * + * List Questtopics of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + */ + public function index($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = SeminaryController::$character; + + // Get Quest topics + $totalQuestcount = 0; + $totalCharacterQuestcount = 0; + $questtopics = $this->Questtopics->getQuesttopicsForSeminary($seminary['id']); + foreach($questtopics as &$questtopic) + { + // Get Quest count + $questtopic['questcount'] = $this->Questtopics->getQuestCountForQuesttopic($questtopic['id']); + $totalQuestcount += $questtopic['questcount']; + + // Get Character progress + $questtopic['characterQuestcount'] = $this->Questtopics->getCharacterQuestCountForQuesttopic($questtopic['id'], $character['id']); + $totalCharacterQuestcount += $questtopic['characterQuestcount']; + } + + + // Set title + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('totalQuestcount', $totalQuestcount); + $this->set('totalCharacterQuestcount', $totalCharacterQuestcount); + $this->set('questtopics', $questtopics); + } + + + /** + * Action: topic. + * + * Show a Questtopic and its Quests with Questsubtopics. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $eminaryUrl URL-Title of Seminary + * @param string $questtopicUrl URL-Title of Questtopic + */ + public function topic($seminaryUrl, $questtopicUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = SeminaryController::$character; + + // Get Questtopic + $questtopic = $this->Questtopics->getQuesttopicByUrl($seminary['id'], $questtopicUrl); + $questtopic['questcount'] = $this->Questtopics->getQuestCountForQuesttopic($questtopic['id']); + $questtopic['characterQuestcount'] = $this->Questtopics->getCharacterQuestCountForQuesttopic($questtopic['id'], $character['id']); + + // Get Quests + $quests = array(); + foreach($this->Quests->getQuestsForQuesttopic($questtopic['id']) as $quest) + { + if($this->Quests->hasCharacterEnteredQuest($quest['id'], $character['id']) || count(array_intersect(array('admin', 'moderator'), self::$character['characterroles'])) > 0) + { + // Get Subtopics + $quest['subtopics'] = $this->Questtopics->getQuestsubtopicsForQuest($quest['id']); + + $quests[] = $quest; + } + } + + + // Set title + $this->addTitle($questtopic['title']); + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questtopic', $questtopic); + $this->set('quests', $quests); + } + + + /** + * Action: manage. + * + * Manage a Questtopic and its Quests with Questsubtopics. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $eminaryUrl URL-Title of Seminary + * @param string $questtopicUrl URL-Title of Questtopic + */ + public function manage($seminaryUrl, $questtopicUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questtopic + $questtopic = $this->Questtopics->getQuesttopicByUrl($seminary['id'], $questtopicUrl); + + // Get Questsubtopics + $questsubtopics = $this->Questtopics->getSubtopicsForQuesttopic($questtopic['id']); + + // Set Questsubtopics for Quests + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('questsubtopics'))) + { + $selectedSubtopics = $this->request->getPostParam('questsubtopics'); + + // Set subtopics of Quests + $quests = $this->Quests->getQuestsForQuesttopic($questtopic['id']); + foreach($quests as &$quest) + { + $subtopics = (array_key_exists($quest['id'], $selectedSubtopics)) ? $selectedSubtopics[$quest['id']] : array(); + $this->Questtopics->setQuestsubtopicsForQuest($quest['id'], array_keys($subtopics)); + } + + // Add Quest + $addQuestId = $this->request->getPostParam('addquest'); + if(!empty($addQuestId)) + { + $subtopics = (array_key_exists('addquest', $selectedSubtopics)) ? $selectedSubtopics['addquest'] : array(); + if(!empty($subtopics)) { + $this->Questtopics->setQuestsubtopicsForQuest($addQuestId, array_keys($subtopics)); + } + } + + // Redirect + $this->redirect($this->linker->link(array('topic', $seminary['url'], $questtopic['url']), 1)); + } + + // Get Quests + $quests = $this->Quests->getQuestsForQuesttopic($questtopic['id']); + foreach($quests as &$quest) + { + // Get Subtopics + $quest['subtopics'] = $this->Questtopics->getQuestsubtopicsForQuest($quest['id']); + $quest['subtopics'] = array_map(function($t) { return $t['id']; }, $quest['subtopics']); + } + + // Get all Quests + $allQuests = $this->Quests->getQuestsForSeminary($seminary['id']); + + + // Set title + $this->addTitle($questtopic['title']); + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questtopic', $questtopic); + $this->set('questsubtopics', $questsubtopics); + $this->set('quests', $quests); + $this->set('allQuests', $allQuests); + } + + + /** + * Action: create. + * + * Create a new Questtopic for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + */ + public function create($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Values + $title = ''; + $fields = array('title'); + $validation = array(); + + // Create new Questtopic + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Questtopics->questtopicTitleExists($title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + + // Create + if($validation === true) + { + $questtopicId = $this->Questtopics->createQuesttopic( + $this->Auth->getUserId(), + $seminary['id'], + $title + ); + $questtopic = $this->Questtopics->getQuesttopicById($questtopicId); + + // Redirect to Questtopic + $this->redirect($this->linker->link(array('topic', $seminary['url'], $questtopic['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set title + $this->addTitleLocalized('New Questtopic'); + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('title', $title); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a Questtopic of a Seminary and its Questsubtopics. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $eminaryUrl URL-Title of Seminary + * @param string $questtopicUrl URL-Title of Questtopic + */ + public function edit($seminaryUrl, $questtopicUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questtopic + $questtopic = $this->Questtopics->getQuesttopicByUrl($seminary['id'], $questtopicUrl); + + // Get Questsubtopics + $questsubtopics = $this->Questtopics->getSubtopicsForQuesttopic($questtopic['id']); + + // Values + $questtopicTitle = $questtopic['title']; + $subtopicsTitles = array(); + foreach($questsubtopics as &$questsubtopic) { + $subtopicsTitles[$questsubtopic['id']] = $questsubtopic['title']; + } + $deleteSubtopics = null; + $subtopicTitle = ''; + $validations = array( + 'edit' => true, + 'edit-subtopics' => true, + 'create-subtopic' => true + ); + + // Edit + $action = null; + if($this->request->getRequestMethod() == 'POST') + { + // Edit Questtopic + if(!is_null($this->request->getPostParam('edit'))) + { + $action = 'edit'; + + // Get params and validate them + $validations[$action] = $this->Validation->validateParams($this->request->getPostParams(), array('title')); + $questtopicTitle = $this->request->getPostParam('title'); + if($this->Questtopics->questsubtopicTitleExists($questtopicTitle, $questtopic['id'])) { + $validations[$action] = $this->Validation->addValidationResult($validations[$action], 'title', 'exist', true); + } + + // Edit + if($validations[$action] === true) + { + $this->Questtopics->editQuesttopic( + $questtopic['id'], + $questtopicTitle + ); + $questtopic = $this->Questtopics->getQuesttopicById($questtopic['id']); + + // Redirect + $this->redirect($this->linker->link(array('topic', $seminary['url'], $questtopic['url']), 1)); + } + } + + // Edit and delete Questsubtopics + elseif(!is_null($this->request->getPostParam('edit-subtopics'))) + { + $action = 'edit-subtopics'; + + // Get params and validate them + $subtopicsTitles = $this->request->getPostParam('subtopics'); + $deleteSubtopics = $this->request->getPostParam('delete-subtopics'); + foreach($questsubtopics as &$questsubtopic) + { + if(!is_null($deleteSubtopics) && array_key_exists($questsubtopic['id'], $deleteSubtopics)) { + continue; + } + + $title = $subtopicsTitles[$questsubtopic['id']]; + $subtopicValidation = $this->Validation->validate($title, \nre\configs\AppConfig::$validation['title']); + if($subtopicValidation !== true) + { + if(!is_array($validations['edit-subtopics'])) { + $validations['edit-subtopics'] = array(); + } + if(!array_key_exists($questsubtopic['id'], $validations['edit-subtopics']) || !is_array($validations['edit-subtopics'][$questsubtopic['id']])) { + $validations['edit-subtopics'][$questsubtopic['id']] = array(); + } + //$validations['edit-subtopics'][$questsubtopic['id']]['title'] = $subtopicValidation; + $validations['edit-subtopics'][$questsubtopic['id']] = $this->Validation->addValidationResults($validations['edit-subtopics'][$questsubtopic['id']], 'title', $subtopicValidation); + } + if($this->Questtopics->questsubtopicTitleExists($questtopic['id'], $title, $questsubtopic['id'])) + { + if(!is_array($validations['edit-subtopics'])) { + $validations['edit-subtopics'] = array(); + } + if(!array_key_exists($questsubtopic['id'], $validations['edit-subtopics']) || !is_array($validations['edit-subtopics'][$questsubtopic['id']])) { + $validations['edit-subtopics'][$questsubtopic['id']] = array(); + } + $validations['edit-subtopics'][$questsubtopic['id']] = $this->Validation->addValidationResult($validations['edit-subtopics'][$questsubtopic['id']], 'title', 'exist', true); + } + } + + // Edit and delete + if($validations['edit-subtopics'] === true) + { + foreach($questsubtopics as &$questsubtopic) + { + // Delete + if(!is_null($deleteSubtopics) && array_key_exists($questsubtopic['id'], $deleteSubtopics)) { + $this->Questtopics->deleteQuestsubtopic($questsubtopic['id']); + } + // Edit + elseif(!is_null($subtopicsTitles) && array_key_exists($questsubtopic['id'], $subtopicsTitles)) + { + $title = $subtopicsTitles[$questsubtopic['id']]; + $this->Questtopics->editQuestsubtopic($questsubtopic['id'], $title); + } + } + + // Redirect + $this->redirect($this->linker->link(array($seminary['url'], $questtopic['url']), 2)); + } + } + + // Create Questsubtopic + elseif(!is_null($this->request->getPostParam('create-subtopic'))) + { + $action = 'create-subtopic'; + + // Get params and validate them + $validations[$action] = $this->Validation->validateParams($this->request->getPostParams(), array('title')); + $subtopicTitle = $this->request->getPostParam('title'); + if($this->Questtopics->questsubtopicTitleExists($questtopic['id'], $subtopicTitle)) { + $validations[$action] = $this->Validation->addValidationResult($validations[$action], 'title', 'exist', true); + } + + // Create + if($validations[$action] === true) + { + $this->Questtopics->createQuestsubtopic( + $this->Auth->getUserId(), + $questtopic['id'], + $subtopicTitle + ); + $subtopicTitle = ''; + + // Redirect + $this->redirect($this->linker->link(null, 4)); + } + } + } + + // Get validation settings + $validationSettings = array( + 'title' => \nre\configs\AppConfig::$validation['title'] + ); + + + // Set title + $this->addTitleLocalized('Edit Questtopic'); + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questtopicTitle', $questtopicTitle); + $this->set('subtopicsTitles', $subtopicsTitles); + $this->set('deleteSubtopics', $deleteSubtopics); + $this->set('subtopicTitle', $subtopicTitle); + $this->set('action', $action); + $this->set('validations', $validations); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: delete. + * + * Delete a Questtopic of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $eminaryUrl URL-Title of Seminary + * @param string $questtopicUrl URL-Title of Questtopic + */ + public function delete($seminaryUrl, $questtopicUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questtopic + $questtopic = $this->Questtopics->getQuesttopicByUrl($seminary['id'], $questtopicUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Questtopics->deleteQuesttopic($questtopic['id']); + + // Redirect to overview + $this->redirect($this->linker->link(array('index', $seminary['url']), 1)); + } + } + + + // Set title + $this->addTitleLocalized('Delete Questtopic'); + $this->addTitleLocalized('Library'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questtopic', $questtopic); + } + + } + +?> diff --git a/controllers/MailController.inc b/controllers/MailController.inc new file mode 100644 index 00000000..904a907f --- /dev/null +++ b/controllers/MailController.inc @@ -0,0 +1,136 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the MailAgent to generate a mail message. + * + * @author Oliver Hanraths + */ + class MailController extends \nre\core\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + + // Set linker + $this->set('linker', ($request instanceof \hhu\z\requests\MailRequest && !is_null($request->getLinker())) ? $request->getLinker() : null); + } + + + /** + * Action: userregistration. + * + * Generate a mail message to notify of a new user registration. + * + * @param array $receiver User that the message will be send to + * @param array $neUser Newly registered user + */ + public function userregistration($receiver, $newUser) + { + // Set subject + $this->response->setSubject(_('New user registration')); + + + // Pass data to view + $this->set('user', $newUser); + } + + + /** + * Action: characterregistration. + * + * Generate a mail message to notify of a new Character + * registration. + * + * @param array $receiver User that the message will be send to + * @param array $seminary Seminary which the Character was created for + * @param arary $user User of the newly registered Character + * @param array $newCharacter Newly registered Character + */ + public function characterregistration($receiver, $seminary, $user, $newCharacter) + { + // Set subject + $this->response->setSubject(_('New Character registration')); + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('user', $user); + $this->set('character', $newCharacter); + } + + + /** + * Action: charactersubmission. + * + * Generate a mail message to notify of a new Character + * submission for a Quest that needs to be valuated. + * + * @param array $receiver User that the message will be send to + * @param array $seminary Seminary which the Quest belongs to + * @param array $questgroup Questgroup of Quest + * @param array $quest Quest the answer has been submitted for + * @param array $character Character that send the submission + */ + public function charactersubmission($receiver, $seminary, $questgroup, $quest, $character) + { + // Set subject + $this->response->setSubject(_('New Character submission')); + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('character', $character); + } + + + /** + * Action: charactersubmissionapproved. + * + * Generate a mail message to notify a Character that its + * submission has been approved. + * + * @param array $receiver User that the message will be send to + * @param array $seminary Seminary which the Quest belongs to + * @param array $questgroup Questgroup of Quest + * @param array $quest Quest the answer has been submitted for + */ + public function charactersubmissionapproved($receiver, $seminary, $questgroup, $quest) + { + // Set subject + $this->response->setSubject(_('Character submission approved')); + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + } + + } + +?> diff --git a/controllers/MailreceiverController.inc b/controllers/MailreceiverController.inc new file mode 100644 index 00000000..7ae92470 --- /dev/null +++ b/controllers/MailreceiverController.inc @@ -0,0 +1,39 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the MailreceiverAgent to generate a mail receiver + * salutation. + * + * @author Oliver Hanraths + */ + class MailreceiverController extends \nre\core\Controller + { + + + + + /** + * Action: index. + * + * @param $array $user User receiving mail + */ + public function index($user) + { + $this->set('user', $user); + } + + } + +?> diff --git a/controllers/MapController.inc b/controllers/MapController.inc new file mode 100644 index 00000000..7dbb6ab4 --- /dev/null +++ b/controllers/MapController.inc @@ -0,0 +1,72 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the MapAgent to display a map. + * + * @author Oliver Hanraths + */ + class MapController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'map'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator', 'user') + ); + + + + + /** + * Action: index. + * + * Draw the map. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + */ + public function index($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get map + $map = $this->Map->getMapOfSeminary($seminary['id']); + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('map', $map); + } + + } + +?> diff --git a/controllers/MediaController.inc b/controllers/MediaController.inc new file mode 100644 index 00000000..a55cd94a --- /dev/null +++ b/controllers/MediaController.inc @@ -0,0 +1,597 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the MediaAgent to process and show Media. + * + * @author Oliver Hanraths + */ + class MediaController extends \hhu\z\controllers\SeminaryController + { + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user', 'guest'), + 'seminarymoodpic' => array('admin', 'moderator', 'user'), + 'seminarymap' => array('admin', 'moderator', 'user'), + 'seminary' => array('admin', 'moderator', 'user'), + 'avatar' => array('admin', 'moderator', 'user'), + 'achievement' => array('admin', 'moderator', 'user'), + 'charactergroup' => array('admin', 'moderator', 'user'), + 'charactergroupsquest' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'seminary' => array('admin', 'moderator', 'user', 'guest'), + 'achievement' => array('admin', 'moderator', 'user', 'guest'), + 'charactergroup' => array('admin', 'moderator', 'user', 'guest'), + 'charactergroupsquest' => array('admin', 'moderator', 'user', 'guest') + ); + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'achievements', 'media', 'avatars', 'charactergroups', 'charactergroupsquests', 'map'); + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set headers for caching control + $response->addHeader("Pragma: public"); + $response->addHeader("Cache-control: must-revalidate"); + $response->addHeader("Date: ".gmdate(\DateTime::RFC822)); + } + + + /** + * Action: index + * + * Display a medium. + * + * @param string $mediaUrl URL-name of the medium + * @param string $action Action for processing the media + */ + public function index($mediaUrl, $action=null) + { + // Get Media + $media = $this->Media->getMediaByUrl($mediaUrl); + + // Get file + $file = $this->getMediaFile($media, $action); + if(is_null($media)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: seminarymoodpic + * + * Display the moodpic for a category of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of the Seminary + * @param string $category Category to show moodpic of + * @param string $action Action for processing the media + */ + public function seminarymoodpic($seminaryUrl, $category=null, $action=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Set index + switch($category) + { + case null: + $index = 'seminarymedia_id'; + break; + case 'charactergroups': + $index = 'charactergroups_seminarymedia_id'; + break; + case 'achievements': + $index = 'achievements_seminarymedia_id'; + break; + case 'library': + $index = 'library_seminarymedia_id'; + break; + } + + // Get media + $media = $this->Media->getSeminaryMediaById($seminary[$index]); + + // Get file + $file = $this->getMediaFile($media, $action); + if(is_null($file)) { + return; + } + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: seminarymap + * + * Display the map of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of the Seminary + */ + public function seminarymap($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get map + $map = $this->Map->getMapOfSeminary($seminary['id']); + if(is_null($map)) { + throw new \nre\exceptions\IdNotFoundException($seminaryUrl); + } + + // Get media + $media = $this->Media->getSeminaryMediaById($map['seminarymedia_id']); + + // Get file + $file = $this->getMediaFile($media); + if(is_null($file)) { + return; + } + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: seminary. + * + * Display a Seminary medium. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of the Seminary + * @param string $mediaUrl URL-name of the medium + * @param string $action Action for processing the media + */ + public function seminary($seminaryUrl, $mediaUrl, $action=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Media + $media = $this->Media->getSeminaryMediaByUrl($seminary['id'], $mediaUrl); + + // Get file + $file = $this->getMediaFile($media, $action); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: avatar. + * + * Display an Avatar as full size or portrait. + * + * @throws \nre\exceptions\ParamsNotValidException + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of the Seminary + * @param string $charactertypeUrl URL-title of Character type + * @param int $xplevel XP-level + * @param string $action Size to show (avatar or portrait) + */ + public function avatar($seminaryUrl, $charactertypeUrl, $xplevel, $action='avatar') + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Avatar + $avatar = $this->Avatars->getAvatarByTypeAndLevel($seminary['id'], $charactertypeUrl, $xplevel); + + // Get media + switch($action) + { + case null: + case 'avatar': + $media = $this->Media->getSeminaryMediaById($avatar['avatarpicture_id']); + $file = $this->getMediaFile($media, 'avatar'); + break; + case 'portrait': + $media = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); + $file = $this->getMediaFile($media); + break; + default: + throw new \nre\exceptions\ParamsNotValidException($action); + break; + } + + // Get file + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: achievement + * + * Display the achievement of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of the Seminary + * @param string $achievementUrl URL-title of the Achievement + * @param string $action Action for processing the media + */ + public function achievement($seminaryUrl, $achievementUrl, $locked=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character + $character = SeminaryController::$character; + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl($seminary['id'], $achievementUrl); + + // Get media + switch($locked) + { + case null: + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) == 0) { + if(is_null($character) || !$this->Achievements->hasCharacterAchievedAchievement($achievement['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + $index = 'achieved_achievementsmedia_id'; + break; + case 'locked': + $index = 'unachieved_achievementsmedia_id'; + break; + default: + throw new \nre\exceptions\ParamsNotValidException($locked); + break; + } + if(is_null($achievement[$index])) { + throw new \nre\exceptions\IdNotFoundException($achievementUrl); + } + $media = $this->Media->getSeminaryMediaById($achievement[$index]); + + // Get file + $file = $this->getMediaFile($media, null); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: charactergroup + * + * Display the icon for a Character group of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function charactergroup($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + + // Check media + if(is_null($group['charactergroupsmedia_id'])) { + $this->redirect($this->linker->link(array('grafics','charactergroup.jpg'))); + } + + // Get media + $media = $this->Media->getSeminaryMediaById($group['charactergroupsmedia_id']); + + // Get file + $file = $this->getMediaFile($media, 'charactergroup'); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + /** + * Action: charactergroupsquest + * + * Display the icon for a Character groups Quest of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $questUrl URL-Title of a Character groups Quest + */ + public function charactergroupsquest($seminaryUrl, $groupsgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character groups Quests + $quest = $this->Charactergroupsquests->getQuestByUrl($groupsgroup['id'], $questUrl); + + // Check media + if(is_null($quest['questsmedia_id'])) { + $this->redirect($this->linker->link(array('grafics','charactergroup.jpg'))); + } + + // Get media + $media = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + + // Get file + $file = $this->getMediaFile($media, 'charactergroupsquest'); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + + + + /** + * Determine file information and set the HTTP-header for + * caching accordingly. + * + * @param string $fileName Filename + * @return boolean HTTP-status 304 was set (in cache) + */ + private function setCacheHeaders($fileName) + { + // Determine last change of file + $fileLastModified = gmdate('r', filemtime($fileName)); + + // Generate E-Tag + $fileEtag = hash('sha256', $fileLastModified.$fileName); + + + // Set header + $this->response->addHeader("Last-Modified: ".$fileLastModified); + $this->response->addHeader("Etag: ".$fileEtag); + // HTTP-status + $headerModifiedSince = $this->request->getServerParam('HTTP_IF_MODIFIED_SINCE'); + $headerNoneMatch = $this->request->getServerParam('HTTP_IF_NONE_MATCH'); + if( + !is_null($headerModifiedSince) && strtotime($fileLastModified) <= strtotime($headerModifiedSince) && + !is_null($headerNoneMatch) && $headerNoneMatch == $fileEtag + ) { + $this->response->setExit(true); + $this->response->addHeader(\nre\core\WebUtils::getHttpHeader(304)); + + return true; + } + + + return false; + } + + + /** + * Determine the file for a medium and process it if necessary. + * + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\ParamsNotValidException + * @param array $media Medium to get file for + * @param string $action Action for processing the media + * @return object File for the medium (or null if medium is cached) + */ + private function getMediaFile($media, $action=null) + { + // Get format + $format = explode('/', $media['mimetype']); + $format = $format[1]; + + // Set content-type + $this->response->addHeader("Content-type: ".$media['mimetype'].""); + + // Set filename + $media['filename'] = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$media['id']; + if(!file_exists($media['filename'])) { + throw new \nre\exceptions\IdNotFoundException($media['id'].': '.$media['url']); + } + + // Cache + if($this->setCacheHeaders($media['filename'])) { + return null; + } + + // Load and process file + $file = null; + switch($action) + { + // No action + case null: + // Do not process the file + $file = file_get_contents($media['filename']); + break; + case 'questgroup': + if(!in_array(strtoupper($format), self::getImageTypes())) { + $file = file_get_contents($media['filename']); + } + else + { + $file = self::resizeImage( + $media['filename'], + $format, + \nre\configs\AppConfig::$media['questgroup']['width'], + \nre\configs\AppConfig::$media['questgroup']['height'] + ); + } + break; + case 'avatar': + $file = self::resizeImage( + $media['filename'], + $format, + \nre\configs\AppConfig::$media['avatar']['width'], + \nre\configs\AppConfig::$media['avatar']['height'] + ); + break; + case 'charactergroup': + $file = self::resizeImage( + $media['filename'], + $format, + \nre\configs\AppConfig::$media['charactergroup']['width'], + \nre\configs\AppConfig::$media['charactergroup']['height'] + ); + break; + case 'charactergroupsquest': + $file = self::resizeImage( + $media['filename'], + $format, + \nre\configs\AppConfig::$media['charactergroupsquest']['width'], + \nre\configs\AppConfig::$media['charactergroupsquest']['height'] + ); + break; + default: + throw new ParamsNotValidException($action); + break; + } + + + // Return file + return $file; + } + + + /** + * Get supported image types. + * + * @return array List of supported image types + */ + private static function getImageTypes() + { + $im = new \Imagick(); + + + return $im->queryFormats(); + } + + + /** + * Resize an image. + * + * @param string $fileName Absolute pathname of image to resize + * @param string $mimeType Mimetype of target image + * @param int $width Max. width to resize to + * @param int $height Max. height to resize to + * @return mixed Resized image + */ + private static function resizeImage($fileName, $mimeType, $width, $height) + { + // Read image from cache + $tempFileName = ROOT.DS.\nre\configs\AppConfig::$dirs['temporary'].DS.'media-'.basename($fileName).'-'.$width.'x'.$height; + if(file_exists($tempFileName)) + { + // Check age of file + if(filemtime($fileName) > filemtime($tempFileName)) { + // Too old, delete + unlink($tempFileName); + } + else { + // Valid, read and return + return file_get_contents($tempFileName); + } + } + + + // ImageMagick + $im = new \Imagick($fileName); + + // Calculate new size + $geometry = $im->getImageGeometry(); + if($geometry['width'] < $width) { + $width = $geometry['width']; + } + if($geometry['height'] < $height) { + $height = $geometry['width']; + } + + // Process + $im->thumbnailImage($width, $height, true); + $im->contrastImage(1); + $im->setImageFormat($mimeType); + + // Save temporary file + $im->writeImage($tempFileName); + + + // Return resized image + return $im; + } + + } + +?> diff --git a/controllers/MenuController.inc b/controllers/MenuController.inc new file mode 100644 index 00000000..2a506d71 --- /dev/null +++ b/controllers/MenuController.inc @@ -0,0 +1,52 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to display a menu. + * + * @author Oliver Hanraths + */ + class MenuController extends \hhu\z\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set userdata + $this->set('loggedUser', IntermediateController::$user); + $this->set('loggedCharacter', SeminaryController::$character); + $this->set('loggedSeminary', SeminaryController::$seminary); + } + + + /** + * Action: index. + */ + public function index() + { + } + + } + +?> diff --git a/controllers/QuestgroupsController.inc b/controllers/QuestgroupsController.inc new file mode 100644 index 00000000..b73b8e8d --- /dev/null +++ b/controllers/QuestgroupsController.inc @@ -0,0 +1,757 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the QuestgroupsAgent to display Questgroups. + * + * @author Oliver Hanraths + */ + class QuestgroupsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'questgroupshierarchy', 'questgroups', 'questgrouptexts', 'quests', 'questtexts', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'questgroup' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'edittexts' => array('admin', 'moderator', 'user'), + 'moveup' => array('admin', 'moderator', 'user'), + 'movedown' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'questgroup' => array('admin', 'moderator', 'user'), + 'create' => array('admin'), + 'edit' => array('admin', 'moderator'), + 'edittexts' => array('admin', 'moderator'), + 'moveup' => array('admin'), + 'movedown' => array('admin'), + 'delete' => array('admin') + ); + + + + + /** + * Action: questgroup. + * + * Display a Questgroup and its data. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $questgroupUrl URL-Title of a Questgroup + */ + public function questgroup($seminaryUrl, $questgroupUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get Questgrouphierarchy + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Check permission + if(count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) == 0) + { + // Only check permissions if Character has not entered Quest before + if(!$this->Questgroups->hasCharacterEnteredQuestgroup($questgroup['id'], $character['id'])) + { + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($seminary['id'], $questgroup['id']); + if(!is_null($previousQuestgroup)) { + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + } + } + + // Set status “entered” + $this->Questgroups->setQuestgroupEntered($questgroup['id'], $character['id']); + + // Get child Questgroupshierarchy + $childQuestgroupshierarchy = null; + if(!empty($questgroup['hierarchy'])) + { + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroup['hierarchy']['id']); + foreach($childQuestgroupshierarchy as &$hierarchy) + { + // Get Questgroups + $hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id'], $questgroup['id']); + + // Get additional data + foreach($hierarchy['questgroups'] as $i => &$group) + { + $group['solved'] = $this->Questgroups->hasCharacterSolvedQuestgroup($group['id'], $character['id']); + + // Check permission of Questgroups + if($i >= 1 && count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) == 0) + { + if(!$hierarchy['questgroups'][$i-1]['solved']) + { + $hierarchy['questgroups'] = array_slice($hierarchy['questgroups'], 0, $i); + break; + } + } + + // Get Character XPs + $group['character_xps'] = $this->Questgroups->getAchievedXPsForQuestgroup($group['id'], $character['id']); + + // Attach related Questgroups + $group['relatedQuestgroups'] = array(); + $relatedQuestgroups = $this->Questgroups->getRelatedQuestsgroupsOfQuestgroup($group['id']); + foreach($relatedQuestgroups as &$relatedQuestgroup) { + if($this->Questgroups->hasCharacterEnteredQuestgroup($relatedQuestgroup['id'], $character['id'])) { + $group['relatedQuestgroups'][] = $this->Questgroups->getQuestgroupById($relatedQuestgroup['id']); + } + + } + } + } + } + + // Get texts + $questgroupTexts = $this->Questgrouptexts->getQuestgroupTexts($questgroup['id']); + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) + { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + + // Get Quests + $quests = array(); + if(count($childQuestgroupshierarchy) == 0) + { + $currentQuest = null; + do { + // Get next Quest + if(is_null($currentQuest)) { + $currentQuest = $this->Quests->getFirstQuestOfQuestgroup($questgroup['id']); + } + else { + $nextQuests = $this->Quests->getNextQuests($currentQuest['id']); + $currentQuest = null; + foreach($nextQuests as &$nextQuest) { + if($this->Quests->hasCharacterEnteredQuest($nextQuest['id'], $character['id'])) { + $currentQuest = $nextQuest; + break; + } + } + } + + // Add additional data + if(!is_null($currentQuest)) + { + // Set status + $currentQuest['solved'] = $this->Quests->hasCharacterSolvedQuest($currentQuest['id'], $character['id']); + + // Attach related Questgroups + $currentQuest['relatedQuestgroups'] = array(); + $relatedQuestgroups = $this->Questgroups->getRelatedQuestsgroupsOfQuest($currentQuest['id']); + foreach($relatedQuestgroups as &$relatedQuestgroup) + { + if($this->Questgroups->hasCharacterEnteredQuestgroup($relatedQuestgroup['id'], $character['id'])) { + $currentQuest['relatedQuestgroups'][] = $this->Questgroups->getQuestgroupById($relatedQuestgroup['id']); + } + } + + // Add Quest to Quests + $quests[] = $currentQuest; + } + } + while(!is_null($currentQuest) && ($currentQuest['solved'] || count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) > 0)); + } + + + // Set titile + if(!is_null($questgroup['hierarchy'])) { + $this->addTitle(sprintf('%s %d: %s', $questgroup['hierarchy']['title_singular'], $questgroup['hierarchy']['questgroup_pos'], $questgroup['title'])); + } + else { + $this->addTitle($questgroup['title']); + } + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('childquestgroupshierarchy', $childQuestgroupshierarchy); + $this->set('texts', $questgroupTexts); + $this->set('picture', $picture); + $this->set('quests', $quests); + } + + + /** + * Action: create. + * + * Create a new Questgroup. + * + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function create($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $selectedQuestgroupshierarchy = null; + $selectedQuestgroup = null; + $title = ''; + $fields = array('title'); + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Questgroups->questgroupTitleExists($seminary['id'], $title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + + // Validate Questgroupshierarchy + try { + $selectedQuestgroupshierarchy = $this->Questgroupshierarchy->getHierarchyByUrl($seminary['id'], $this->request->getPostParam('questgroupshierarchy')); + } + catch(\nre\exceptions\IdNotFoundException $e) { + throw new \nre\exceptions\ParamsNotValidException($this->request->getPostParam('questgroupshierarchy')); + } + + // Validate Questgroup + if(!is_null($selectedQuestgroupshierarchy['parent_questgroupshierarchy_id'])) { + try { + $selectedQuestgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $this->request->getPostParam('questgroup')); + } + catch(\nre\exceptions\IdNotFoundException $e) { + throw new \nre\exceptions\ParamsNotValidException($this->request->getPostParam('questgroups')); + } + } + + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) + { + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } + } + + // Create new Questgroup + if($validation === true) + { + $questgroupId = $this->Questgroups->createQuestgroup( + $this->Auth->getUserId(), + $seminary['id'], + $title + ); + $questgroup = $this->Questgroups->getQuestgroupById($questgroupId); + + // Add to Hierarchy + $this->Questgroups->addQuestgroupToHierarchy( + $questgroupId, + $selectedQuestgroupshierarchy['id'], + (!is_null($selectedQuestgroup)) ? $selectedQuestgroup['id'] : null + ); + + // Upload moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createQuestgrouppicture( + $this->Auth->getUserId(), + $seminary['id'], + $questgroup['id'], + sprintf('questgroupmoodpic-%s', $questgroup['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Questgroups->setMoodpicForQuestgroup($questgroup['id'], $mediaId); + } + } + + + // Redirect to new Questgroup + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $questgroup['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Create Questgroup'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('mimetypes', $mimetypes); + $this->set('questgroupshierarchy', $selectedQuestgroupshierarchy); + $this->set('questgroup', $selectedQuestgroup); + $this->set('title', $title); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a Questgroup. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of a Seminary + * @param string $questgroupUrl URL-title of Questgroup to edit + */ + public function edit($seminaryUrl, $questgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = $questgroup['title']; + $fields = array('title'); + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Questgroups->questgroupTitleExists($seminary['id'], $title, $questgroup['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) + { + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } + } + + // Edit Questgroup + if($validation === true) + { + $this->Questgroups->editQuestgroup( + $questgroup['id'], + $title + ); + $questgroup = $this->Questgroups->getQuestgroupById($questgroup['id']); + + // Upload moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createQuestgrouppicture( + $this->Auth->getUserId(), + $seminary['id'], + $questgroup['id'], + sprintf('questgroupmoodpic-%s', $questgroup['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Questgroups->setMoodpicForQuestgroup($questgroup['id'], $mediaId); + } + } + + + // Redirect to new Questgroup + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $questgroup['url']), 1)); + } + } + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Edit Questgroup'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('picture', $picture); + $this->set('title', $title); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edittexts. + * + * Edit the texts of a Questgroup. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of a Seminary + * @param string $questgroupUrl URL-title of Questgroup to edit + */ + public function edittexts($seminaryUrl, $questgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get Questgroup texts + $questgroupTexts = $this->Questgrouptexts->getQuestgroupTexts($questgroup['id']); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + $texts = $this->request->getPostParam('questgrouptexts'); + $deleteTexts = $this->request->getPostParam('deletes'); + if(!is_array($deleteTexts)) { + $deleteTexts = array(); + } + + // Edit or delete texts + foreach($questgroupTexts as $text) + { + if(array_key_exists($text['id'], $deleteTexts)) + { + $this->Questgrouptexts->deleteQuestgrouptext($text); + unset($texts[$text['id']]); + } + elseif(array_key_exists($text['id'], $texts)) + { + $this->Questgrouptexts->editQuestgrouptext($text['id'], $texts[$text['id']]); + unset($texts[$text['id']]); + } + } + + // Add new texts + foreach($texts as $text) { + if(!empty($text)) { + $this->Questgrouptexts->addQuestgrouptextToQuestgroup($this->Auth->getUserId(), $questgroup['id'], $text); + } + } + + // Redirect to Questgroup + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $questgroup['url']), 1)); + } + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + + // Set titile + $this->addTitleLocalized('Edit Questgroup texts'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('questgrouptexts', $questgroupTexts); + $this->set('picture', $picture); + $this->set('mimetypes', $mimetypes); + } + + + /** + * Action: moveup. + * + * Move a Questgroup up (decrement position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupUrl URL-title of Questgroup + */ + public function moveup($seminaryUrl, $questgroupUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('move'))) + { + // Set position + $this->Questgroups->moveQuestgroup($questgroup, true); + } + + // Redirect + $referer = $this->request->getGetParam('referer'); + if(!is_null($referer)) + { + try { + $questgroup = $this->Questgroups->getQuestgroupById($referer); + $this->redirect($this->linker->link(array('questgroups', 'questgroup', $seminary['url'], $questgroup['url']))); + } + catch(IdNotFoundException $e) { + } + } + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + + // Set titile + $this->addTitleLocalized('Move Questgroup'); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('picture', $picture); + } + + + /** + * Action: movedown + * + * Move a Questgroup down (increment position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupUrl URL-title of Questgroup + */ + public function movedown($seminaryUrl, $questgroupUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('move'))) + { + // Set position + $this->Questgroups->moveQuestgroup($questgroup, false); + } + + // Redirect + $referer = $this->request->getGetParam('referer'); + if(!is_null($referer)) + { + try { + $questgroup = $this->Questgroups->getQuestgroupById($referer); + $this->redirect($this->linker->link(array('questgroups', 'questgroup', $seminary['url'], $questgroup['url']))); + } + catch(IdNotFoundException $e) { + } + } + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + + // Set titile + $this->addTitleLocalized('Move Questgroup'); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('picture', $picture); + } + + + /** + * Action: delete. + * + * Delete a Questgroup. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $questgroupUrl URL-Title of a Questgroup + */ + public function delete($seminaryUrl, $questgroupUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + + // Get Questgrouphierarchy + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete Questgroup + $this->Questgroups->deleteQuestgroup($questgroup['id']); + + // Redirect + if(!is_null($questgroup['hierarchy'])) + { + // Parent Questgroup + if(is_null($questgroup['hierarchy']['parent_questgroup_id'])) { + $this->redirect($this->linker->link(array('simenaries', 'seminary', $seminary['url']))); + } + else + { + $parentQuestgroup = $this->Questgroups->getQuestgroupById($questgroup['hierarchy']['parent_questgroup_id']); + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $parentQuestgroup['url']), 1)); + } + } + else + { + // Related Questgroup + $questtexts = $this->Questtexts->getRelatedQuesttextsForQuestgroup($questgroup['id']); + $questtext = $this->Questtexts->pickQuesttextLastEnteredByCharacter(\hhu\z\controllers\SeminaryController::$character['id'], $questtexts); + $quest = $this->Quests->getQuestById($questtext['quest_id']); + $relatedQuestgroup = $this->Questgroups->getQuestgroupById($quest['questgroup_id']); + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $relatedQuestgroup['url']), 1)); + } + } + + // Redirect to entry + $this->redirect($this->linker->link(array('questgroup', $seminary['url'], $questgroup['url']), 1)); + } + + // Media + $picture = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $picture = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + + // Set titile + $this->addTitleLocalized('Delete Questgroup'); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('picture', $picture); + } + + } + +?> diff --git a/controllers/QuestgroupshierarchyController.inc b/controllers/QuestgroupshierarchyController.inc new file mode 100644 index 00000000..b50cad5e --- /dev/null +++ b/controllers/QuestgroupshierarchyController.inc @@ -0,0 +1,346 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the QuestgroupsAgent to display Questgroups. + * + * @author Oliver Hanraths + */ + class QuestgroupshierarchyController extends \hhu\z\controllers\SeminaryController + { + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'questgroupshierarchy', 'questgroups'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'create' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'moveup' => array('admin', 'moderator', 'user'), + 'movedown' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'create' => array('admin'), + 'edit' => array('admin'), + 'moveup' => array('admin'), + 'movedown' => array('admin'), + 'delete' => array('admin') + ); + + + + + /** + * Action: create. + * + * Create a new Questgroupshierarchy. + * + * @param string $seminaryUrl URL-title of a Seminary + */ + public function create($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get parent Questgroupshierarchy + $parentQuestgroupshierarchy = $this->Questgroupshierarchy->getHierarchyOfSeminary($seminary['id']); + + // Values + $titleSingular = ''; + $titlePlural = ''; + $validation = array(); + + // Create Questgroupshierarchy + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $titleSingular = $this->request->getPostParam('title_singular'); + $validation = $this->Validation->addValidationResults( + $validation, + 'titleSingular', + $this->Validation->validate($titleSingular, \nre\configs\AppConfig::$validation['questgroupshierarchytitle']) + ); + if($this->Questgroupshierarchy->questgroupshierarchyTitleSingularExists($titleSingular, $seminary['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'titleSingular', 'exist', true); + } + $titlePlural = $this->request->getPostParam('title_plural'); + $validation = $this->Validation->addValidationResults( + $validation, + 'titlePlural', + $this->Validation->validate($titlePlural, \nre\configs\AppConfig::$validation['questgroupshierarchytitle']) + ); + if($this->Questgroupshierarchy->questgroupshierarchyTitleSingularExists($titlePlural, $seminary['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'titlePlural', 'exist', true); + } + + // Validate parent Questgroupshierarchy + $parentQuestgroupshierarchyIndex = null; + foreach($parentQuestgroupshierarchy as $index => &$parentHierarchy) + { + $parentHierarchy['selected'] = ($parentHierarchy['url'] == $this->request->getPostParam('parent')); + if($parentHierarchy['selected']) { + $parentQuestgroupshierarchyIndex = $index; + } + } + + // Create new Questgroupshierarchy + if($validation === true) + { + $questgroupshierarchyId = $this->Questgroupshierarchy->createQuestgroupshierarchy( + $this->Auth->getUserId(), + $seminary['id'], + (!is_null($parentQuestgroupshierarchyIndex) ? $parentQuestgroupshierarchy[$parentQuestgroupshierarchyIndex]['id'] : null), + $titleSingular, + $titlePlural + ); + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyById($questgroupshierarchyId); + + // Redirect + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + } + + // Get validation settings + $validationSettings = array( + 'title' => \nre\configs\AppConfig::$validation['title'] + ); + + + // Set titile + $this->addTitleLocalized('Create Questgroupshierarchy'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('titleSingular', $titleSingular); + $this->set('titlePlural', $titlePlural); + $this->set('parentQuestgroupshierarchy', $parentQuestgroupshierarchy); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a Questgroupshierarchy. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupshierarchyUrl URL-title of Questgroupshierarchy + */ + public function edit($seminaryUrl, $questgroupshierarchyUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroupshierarchy + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyByUrl($seminary['id'], $questgroupshierarchyUrl); + + // Values + $titleSingular = $questgroupshierarchy['title_singular']; + $titlePlural = $questgroupshierarchy['title_plural']; + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $titleSingular = $this->request->getPostParam('title_singular'); + $validation = $this->Validation->addValidationResults( + $validation, + 'titleSingular', + $this->Validation->validate($titleSingular, \nre\configs\AppConfig::$validation['questgroupshierarchytitle']) + ); + if($this->Questgroupshierarchy->questgroupshierarchyTitleSingularExists($titleSingular, $seminary['id'], $questgroupshierarchy['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'titleSingular', 'exist', true); + } + $titlePlural = $this->request->getPostParam('title_plural'); + $validation = $this->Validation->addValidationResults( + $validation, + 'titlePlural', + $this->Validation->validate($titlePlural, \nre\configs\AppConfig::$validation['questgroupshierarchytitle']) + ); + if($this->Questgroupshierarchy->questgroupshierarchyTitleSingularExists($titlePlural, $seminary['id'], $questgroupshierarchy['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'titlePlural', 'exist', true); + } + + + // Edit Questgroup + if($validation === true) + { + $this->Questgroupshierarchy->editQuestgroupshierarchy( + $questgroupshierarchy['id'], + $titleSingular, + $titlePlural + ); + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyById($questgroupshierarchy['id']); + + // Redirect to Seminary page + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + } + + // Get validation settings + $validationSettings = array( + 'title' => \nre\configs\AppConfig::$validation['title'] + ); + + + // Set titile + $this->addTitleLocalized('Edit Questgroupshierarchy'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('titleSingular', $titleSingular); + $this->set('titlePlural', $titlePlural); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: moveup. + * + * Move a Questgroupshierarchy up (decrement position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupshierarchyUrl URL-title of Questgroupshierarchy + */ + public function moveup($seminaryUrl, $questgroupshierarchyUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroupshierarchy + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyByUrl($seminary['id'], $questgroupshierarchyUrl); + + // Set position + $this->Questgroupshierarchy->moveQuestgroupshierarchy($questgroupshierarchy, true); + + + // Redirect + $referer = $this->request->getGetParam('referer'); + if(!is_null($referer)) + { + try { + $questgroup = $this->Questgroups->getQuestgroupById($referer); + $this->redirect($this->linker->link(array('questgroups', 'questgroup', $seminary['url'], $questgroup['url']))); + } + catch(IdNotFoundException $e) { + } + } + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + + + /** + * Action: movedown. + * + * Move a Questgroupshierarchy down (increment position). + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupshierarchyUrl URL-title of Questgroupshierarchy + */ + public function movedown($seminaryUrl, $questgroupshierarchyUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroupshierarchy + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyByUrl($seminary['id'], $questgroupshierarchyUrl); + + // Set position + $this->Questgroupshierarchy->moveQuestgroupshierarchy($questgroupshierarchy, false); + + + // Redirect + $referer = $this->request->getGetParam('referer'); + if(!is_null($referer)) + { + try { + $questgroup = $this->Questgroups->getQuestgroupById($referer); + $this->redirect($this->linker->link(array('questgroups', 'questgroup', $seminary['url'], $questgroup['url']))); + } + catch(IdNotFoundException $e) { + } + } + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + + + /** + * Action: delete. + * + * Delete a Questgroupshierarchy. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $questgroupshierarchyUrl URL-title of Questgroupshierarchy + */ + public function delete($seminaryUrl, $questgroupshierarchyUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroupshierarchy + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyByUrl($seminary['id'], $questgroupshierarchyUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete Questgroupshierarchy + $this->Questgroupshierarchy->deleteQuestgroupshierarchy($questgroupshierarchy['id']); + } + + // Redirect to Seminary page + $this->redirect($this->linker->link(array('seminaries', 'seminary', $seminary['url']))); + } + + + // Set titile + $this->addTitleLocalized('Delete Questgroupshierarchy'); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('questgroupshierarchy', $questgroupshierarchy); + } + + } + +?> diff --git a/controllers/QuestgroupshierarchypathController.inc b/controllers/QuestgroupshierarchypathController.inc new file mode 100644 index 00000000..907017d5 --- /dev/null +++ b/controllers/QuestgroupshierarchypathController.inc @@ -0,0 +1,91 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of QuestgroupshierarchypathAgent to display the + * Questgroups hierarchy path. + * + * @author Oliver Hanraths + */ + class QuestgroupshierarchypathController extends \hhu\z\Controller + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'questgroups', 'questgroupshierarchy', 'quests', 'questtexts'); + + + + + /** + * Action: index. + * + * Calculate and show the hierarchy path of a Questgroup. + * + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $questgroupUrl URL-Title of a Questgroup + * @param boolean $showGroup Show the current group itself + */ + public function index($seminaryUrl, $questgroupUrl, $showGroup=false) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + + // Get parent Questgrouphierarchy + $currentQuestgroup = $questgroup; + $parentQuestgroupshierarchy = array(); + if($showGroup) { + array_unshift($parentQuestgroupshierarchy, $currentQuestgroup); + } + if(is_null($questgroup['hierarchy'])) + { + // Get related Questgroup + $questtexts = $this->Questtexts->getRelatedQuesttextsForQuestgroup($currentQuestgroup['id']); + $questtext = $this->Questtexts->pickQuesttextLastEnteredByCharacter(\hhu\z\controllers\SeminaryController::$character['id'], $questtexts); + $quest = $this->Quests->getQuestById($questtext['quest_id']); + $currentQuestgroup = $this->Questgroups->getQuestgroupById($quest['questgroup_id']); + $currentQuestgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($currentQuestgroup['id']); + $quest['questgroup'] = $currentQuestgroup; + + // Use Hierarchy name for optional Questgroup + if(!empty($parentQuestgroupshierarchy)) { + $parentQuestgroupshierarchy[0]['hierarchy'] = $currentQuestgroup['hierarchy']; + unset($parentQuestgroupshierarchy[0]['hierarchy']['questgroup_pos']); + } + + array_unshift($parentQuestgroupshierarchy, $quest); + array_unshift($parentQuestgroupshierarchy, $currentQuestgroup); + } + while(!empty($currentQuestgroup['hierarchy']) && !is_null($currentQuestgroup['hierarchy']['parent_questgroup_id'])) + { + $currentQuestgroup = $this->Questgroups->GetQuestgroupById($currentQuestgroup['hierarchy']['parent_questgroup_id']); + $currentQuestgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($currentQuestgroup['id']); + array_unshift($parentQuestgroupshierarchy, $currentQuestgroup); + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('parentquestgroupshierarchy', $parentQuestgroupshierarchy); + } + + } + +?> diff --git a/controllers/QuestsController.inc b/controllers/QuestsController.inc new file mode 100644 index 00000000..cc345b1f --- /dev/null +++ b/controllers/QuestsController.inc @@ -0,0 +1,1506 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the QuestsAgent to display Quests. + * + * @author Oliver Hanraths + */ + class QuestsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'questgroups', 'quests', 'questtexts', 'media', 'questtypes', 'questgroupshierarchy', 'xplevels'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'quest' => array('admin', 'moderator', 'user'), + 'submissions' => array('admin', 'moderator', 'user'), + 'submission' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'edittexts' => array('admin', 'moderator', 'user'), + 'edittask' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator'), + 'quest' => array('admin', 'moderator', 'user'), + 'submissions' => array('admin', 'moderator'), + 'submission' => array('admin', 'moderator'), + 'create' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator'), + 'edittexts' => array('admin', 'moderator'), + 'edittask' => array('admin', 'moderator'), + 'delete' => array('admin') + ); + + + + + /** + * Prefilter that is executed before running the Controller. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + $this->checkAchievements($request, $response, array('character', 'quest')); + $this->checkAchievements($request, $response, 'achievement'); + } + + + /** + * Action: index. + * + * List all Quests for a Seminary. + * + * @param string $seminaryUrl URL-Title of Seminary + * @param string $all Show all Quests + */ + public function index($seminaryUrl, $all=null) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Set filters + $selectedQuestgroup = null; + $selectedQuesttype = null; + $selectedTitle = null; + $page = 1; + if($this->request->getRequestMethod() == 'GET') + { + $selectedQuestgroup = $this->request->getGetParam('questgroup'); + $selectedQuestgroup = !empty($selectedQuestgroup) ? $selectedQuestgroup : null; + $selectedQuesttype = $this->request->getGetParam('questtype'); + $selectedQuesttype = !empty($selectedQuesttype) ? $selectedQuesttype : null; + $selectedTitle = $this->request->getGetParam('title'); + $selectedTitle = !empty($selectedTitle) ? $selectedTitle : null; + $page = $this->request->getGetParam('page'); + $page = !empty($page) ? intval($page) : 1; + } + + // Get Quests + $limit = ($all != 'all') ? \nre\configs\AppConfig::$misc['lists_limit'] : null; + $offset = ($all != 'all') ? max((intval($page) - 1), 0) * $limit : 0; + $questsCount = $this->Quests->getCountForQuestsForSeminaryByOpenSubmissions($seminary['id'], $selectedQuestgroup, $selectedQuesttype, $selectedTitle); + $quests = $this->Quests->getQuestsForSeminaryByOpenSubmissions($seminary['id'], $selectedQuestgroup, $selectedQuesttype, $selectedTitle, $limit, $offset); + foreach($quests as &$quest) + { + // Get Questtype + $quest['questtype'] = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + } + + // Get filter values + $questgroups = $this->Questgroups->getQuestgroupsForSeminary($seminary['id']); + $questtypes = $this->Questtypes->getQuesttypes(); + + + // Set titile + $this->addTitleLocalized('Quests'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroups', $questgroups); + $this->set('questtypes', $questtypes); + $this->set('selectedQuestgroup', $selectedQuestgroup); + $this->set('selectedQuesttype', $selectedQuesttype); + $this->set('selectedTitle', $selectedTitle); + $this->set('quests', $quests); + $this->set('questsCount', $questsCount); + $this->set('all', $all); + $this->set('page', $page); + $this->set('limit', $limit); + } + + + /** + * Action: quest. + * + * Show a quest and its task. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + * @param string $questtexttypeUrl URL-Title of Questtexttype + * @param int $questtextPos Position of Questtext + */ + public function quest($seminaryUrl, $questgroupUrl, $questUrl, $questtexttypeUrl=null, $questtextPos=1) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['picture'] = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $questgroup['picture'] = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Check permissions + if(count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) == 0) + { + $previousQuests = $this->Quests->getPreviousQuests($quest['id']); + if(count($previousQuests) == 0) + { + // Previous Questgroup + $previousQuestgroup = $this->Questgroups->getPreviousQuestgroup($seminary['id'], $questgroup['id']); + if(!is_null($previousQuestgroup) && !$this->Questgroups->hasCharacterSolvedQuestgroup($previousQuestgroup['id'], $character['id'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + else + { + // Previous Quests + // One previous Quest has to be solved and no other + // following Quest of ones has to be tried + // except it is also an previous Quest of the current Quest + $solved = false; + $tried = false; + foreach($previousQuests as &$previousQuest) + { + // Check previous Quest + if($this->Quests->hasCharacterSolvedQuest($previousQuest['id'], $character['id'])) + { + $solved = true; + + // Check following Quests + $followingQuests = $this->Quests->getNextQuests($previousQuest['id']); + foreach($followingQuests as $followingQuest) + { + // Check following Quest + if($followingQuest['id'] != $quest['id'] && $this->Quests->hasCharacterTriedQuest($followingQuest['id'], $character['id'])) + { + $followingFollowingQuests = $this->Quests->getNextQuests($followingQuest['id']); + if(!in_array($quest['id'], array_map(function($q) { return $q['id']; }, $followingFollowingQuests))) + { + $tried = true; + break; + } + } + } + + break; + } + } + if(!$solved || $tried) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + } + + // Set status “entered” + $this->Quests->setQuestEntered($quest['id'], $character['id']); + + // Has Character solved quest? + $solved = $this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id']); + + // Get Questtexts + $questtexts = array(); + $questtexts['Prolog'] = $this->Questtexts->getQuesttextsOfQuest($quest['id'], 'Prolog'); + if($solved || count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) > 0) { + $questtexts['Epilog'] = $this->Questtexts->getQuesttextsOfQuest($quest['id'], 'Epilog'); + } + foreach($questtexts as &$questtextList) + { + foreach($questtextList as &$questtext) + { + // Questtext media + if(!is_null($questtext['questsmedia_id'])) { + $questtext['media'] = $this->Media->getSeminaryMediaById($questtext['questsmedia_id']); + } + + // Related Questgroups + $questtext['relatedQuestsgroups'] = $this->Questgroups->getRelatedQuestsgroupsOfQuesttext($questtext['id']); + } + } + + // Quest status + $questStatus = $this->request->getGetParam('status'); + + // Quest media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Task + $task = null; + $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + if(!is_null($questtype['classname'])) { + $task = $this->renderTask($questtype['classname'], $seminary, $questgroup, $quest, $character); + } + else + { + // Mark Quest as solved + $this->Quests->setQuestSolved($quest['id'], $character['id']); + $solved = true; + } + + // Get (related) Questtexts + $relatedQuesttexts = $this->Questtexts->getRelatedQuesttextsForQuestgroup($questgroup['id']); + $relatedQuesttext = $this->Questtexts->pickQuesttextLastEnteredByCharacter($character['id'], $relatedQuesttexts); + if(!is_null($relatedQuesttext)) { + $relatedQuesttext['quest'] = $this->Quests->getQuestById($relatedQuesttext['quest_id']); + if(!empty($relatedQuesttext['quest'])) { + $relatedQuesttext['quest']['questgroup_url'] = $this->Questgroups->getQuestgroupById($relatedQuesttext['quest']['questgroup_id'])['url']; + } + } + + // Next Quest/Questgroup + $nextQuests = null; + $charactedHasChoosenNextQuest = false; + $nextQuestgroup = null; + if($solved || count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) > 0) + { + // Next Quest + $nextQuests = $this->Quests->getNextQuests($quest['id']); + foreach($nextQuests as &$nextQuest) + { + // Set entered status of Quest + $nextQuest['entered'] = $this->Quests->hasCharacterEnteredQuest($nextQuest['id'], $character['id']); + if($nextQuest['entered']) { + $charactedHasChoosenNextQuest = true; + } + } + + // Next Questgroup + if(empty($nextQuests)) + { + if(is_null($relatedQuesttext)) + { + $nextQuestgroup = $this->Questgroups->getNextQuestgroup($seminary['id'], $questgroup['id']); + if(!is_null($nextQuestgroup)) { + $nextQuestgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($nextQuestgroup['id']); + } + } + else + { + // Related (Main-) Quest + $nextQuest = $relatedQuesttext['quest']; + $nextQuest['entered'] = true; + $nextQuests = array($nextQuest); + } + } + } + + + // Set titile + $this->addTitle($quest['title']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('questtexts', $questtexts); + $this->set('quest', $quest); + $this->set('queststatus', $questStatus); + $this->set('relatedquesttext', $relatedQuesttext); + $this->set('nextquests', $nextQuests); + $this->set('charactedHasChoosenNextQuest', $charactedHasChoosenNextQuest); + $this->set('nextquestgroup', $nextQuestgroup); + $this->set('task', $task); + $this->set('media', $questmedia); + $this->set('solved', $solved); + } + + + /** + * List Character submissions for a Quest. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function submissions($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['picture'] = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $questgroup['picture'] = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Get submitted Character submissions waiting for approval + $submittedSubmissionCharacters = $this->Characters->getCharactersSubmittedQuest($quest['id']); + + // Get unsolved Character submissions + $unsolvedSubmissionCharacters = $this->Characters->getCharactersUnsolvedQuest($quest['id']); + + // Get solved Character submissions + $solvedSubmissionCharacters = $this->Characters->getCharactersSolvedQuest($quest['id']); + + + // Set titile + $this->addTitleLocalized('Submissions'); + $this->addTitle($quest['title']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('media', $questmedia); + $this->set('submittedSubmissionCharacters', $submittedSubmissionCharacters); + $this->set('unsolvedSubmissionCharacters', $unsolvedSubmissionCharacters); + $this->set('solvedSubmissionCharacters', $solvedSubmissionCharacters); + } + + + /** + * Show and handle the submission of a Character for a Quest. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + * @param string $characterUrl URL-Title of Character + */ + public function submission($seminaryUrl, $questgroupUrl, $questUrl, $characterUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['picture'] = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $questgroup['picture'] = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Character + $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); + + // Media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Questtype + $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + + // Render Questtype output + $output = $this->renderTaskSubmission($questtype['classname'], $seminary, $questgroup, $quest, $character); + + + // Set titile + $this->addTitleLocalized('Submission of %s', $character['name']); + $this->addTitle($quest['title']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('character', $character); + $this->set('media', $questmedia); + $this->set('output', $output); + } + + + /** + * Action: create. + * + * Create a new Quest. + * + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $questgroupUrl URL-Title of Questgroup + */ + public function create($seminaryUrl, $questgroupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + $questgroup['picture'] = (!is_null($questgroup['questgroupspicture_id'])) ? $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']) : null; + + // Get Quest types + $questtypes = $this->Questtypes->getQuesttypes(); + foreach($questtypes as &$questtype) { + $questtype['selected'] = false; + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = ''; + $xps = 0; + $task = ''; + $entryText = ''; + $wrongText = ''; + $fields = array('title', 'xps'); + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Quests->questTitleExists($title, $seminary['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $xps = $this->request->getPostParam('xps'); + $task = $this->request->getPostParam('task'); + $entryText = $this->request->getPostParam('entrytext'); + $wrongText = $this->request->getPostParam('wrongtext'); + + // Validate Questtype + $questtypeIndex = null; + foreach($questtypes as $index => &$questtype) + { + $questtype['selected'] = ($questtype['url'] == $this->request->getPostParam('questtype')); + if($questtype['selected']) { + $questtypeIndex = $index; + } + } + if(is_null($questtypeIndex)) { + throw new \nre\exceptions\ParamsNotValidException($questtype); + } + + // Validate media + $media = null; + if(!empty($_FILES) && array_key_exists('media', $_FILES) && $_FILES['media']['error'] != UPLOAD_ERR_NO_FILE) + { + $media = $_FILES['media']; + + // Check error + if($media['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'error', $media['error']); + } + + // Check mimetype + $mediaMimetype = null; + $media['mimetype'] = \hhu\z\Utils::getMimetype($media['tmp_name'], $media['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $media['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $media['mimetype']); + } + elseif($media['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']); + } + } + + // Create new Quest + if($validation === true) + { + $questId = $this->Quests->createQuest( + $this->Auth->getUserId(), + $questgroup['id'], + $questtypes[$questtypeIndex]['id'], + $title, + $xps, + $task, + $entryText, + $wrongText + ); + $quest = $this->Quests->getQuestById($questId); + + // Update picture + if(!is_null($media)) + { + $questsmediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + $media['name'], + $title, + $media['type'], + $media['tmp_name'] + ); + if($questsmediaId > 0) { + $this->Quests->setQuestmedia($quest['id'], $questsmediaId); + } + } + + // Redirect + $this->redirect($this->linker->link(array('quest', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Create Quest'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('mimetypes', $mimetypes); + $this->set('questtypes', $questtypes); + $this->set('title', $title); + $this->set('task', $task); + $this->set('entryText', $entryText); + $this->set('wrongText', $wrongText); + $this->set('xps', $xps); + $this->set('questtype_id', $questtype); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a Quest of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function edit($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + $questgroup['picture'] = (!is_null($questgroup['questgroupspicture_id'])) ? $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']) : null; + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + $quest['type'] = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + + // Get Quest media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Get Quest types + $questtypes = $this->Questtypes->getQuesttypes(); + foreach($questtypes as &$questtype) { + $questtype['selected'] = ($questtype['id'] == $quest['questtype_id']); + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = $quest['title']; + $xps = $quest['xps']; + $task = $quest['task']; + $entryText = $quest['entry_text']; + $wrongText = $quest['wrong_text']; + $fields = array('title', 'xps'); + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && (!is_null($this->request->getPostParam('edit')) || !is_null($this->request->getPostParam('edit-task')))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Quests->questTitleExists($title, $seminary['id'], $quest['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $xps = $this->request->getPostParam('xps'); + $task = $this->request->getPostParam('task'); + $entryText = $this->request->getPostParam('entrytext'); + $wrongText = $this->request->getPostParam('wrongtext'); + + // Validate Questtype + $questtypeIndex = null; + foreach($questtypes as $index => &$questtype) + { + $questtype['selected'] = ($questtype['url'] == $this->request->getPostParam('questtype')); + if($questtype['selected']) { + $questtypeIndex = $index; + } + } + if(is_null($questtypeIndex)) { + throw new \nre\exceptions\ParamsNotValidException($questtype); + } + + // Validate media + $media = null; + if(!empty($_FILES) && array_key_exists('media', $_FILES) && $_FILES['media']['error'] != UPLOAD_ERR_NO_FILE) + { + $media = $_FILES['media']; + + // Check error + if($media['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'error', $media['error']); + } + + // Check mimetype + $mediaMimetype = null; + $media['mimetype'] = \hhu\z\Utils::getMimetype($media['tmp_name'], $media['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $media['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $media['mimetype']); + } + elseif($media['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']); + } + } + + // Edit Quest + if($validation === true) + { + $this->Quests->editQuest( + $quest['id'], + $questtypes[$questtypeIndex]['id'], + $title, + $xps, + $task, + $entryText, + $wrongText + ); + $quest = $this->Quests->getQuestById($quest['id']); + + // Update picture + if(!is_null($media)) + { + $questsmediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + $media['name'], + $title, + $media['type'], + $media['tmp_name'] + ); + if($questsmediaId > 0) { + $this->Quests->setQuestmedia($quest['id'], $questsmediaId); + } + } + + // Redirect + if(!is_null($this->request->getPostParam('edit-task'))) { + // To task editing + $this->redirect($this->linker->link(array('edittask', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + else { + // To entry + $this->redirect($this->linker->link(array('quest', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Edit Quest'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('media', $questmedia); + $this->set('mimetypes', $mimetypes); + $this->set('questtypes', $questtypes); + $this->set('title', $title); + $this->set('task', $task); + $this->set('entryText', $entryText); + $this->set('wrongText', $wrongText); + $this->set('xps', $xps); + $this->set('questtype_id', $questtype); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edittask. + * + * Edit the task of a Quest of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function edittask($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + $questgroup['picture'] = (!is_null($questgroup['questgroupspicture_id'])) ? $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']) : null; + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Get Quest media + $questmedia = null; + if(!is_null($quest['questsmedia_id'])) { + $questmedia = $this->Media->getSeminaryMediaById($quest['questsmedia_id']); + } + + // Render editing task + $task = null; + $questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']); + if(!is_null($questtype['classname'])) { + $task = $this->renderTaskEditing($questtype['classname'], $seminary, $questgroup, $quest); + } + + + // Set titile + $this->addTitleLocalized('Edit Quest task'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('media', $questmedia); + $this->set('task', $task); + } + + + /** + * Action: edittexts. + * + * Edit the texts of a Quest of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function edittexts($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['hierarchy'] = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroup['id']); + $questgroup['picture'] = (!is_null($questgroup['questgroupspicture_id'])) ? $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']) : null; + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Get Questtexts + $questtextTypes = $this->Questtexts->getQuesttexttypes(); + foreach($questtextTypes as &$questtextType) + { + $questtextType['texts'] = $this->Questtexts->getQuesttextsOfQuest($quest['id'], $questtextType['url']); + foreach($questtextType['texts'] as &$questtext) + { + if(!is_null($questtext['questsmedia_id'])) { + $questtext['media'] = $this->Media->getSeminaryMediaById($questtext['questsmedia_id']); + } + } + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Check request method + $validations = array(); + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + $media = $_FILES['media']; + $texts = $this->request->getPostParam('questtexts'); + $deleteTexts = $this->request->getPostParam('deletes'); + if(!is_array($deleteTexts)) { + $deleteTexts = array(); + } + + foreach($questtextTypes as &$type) + { + // Edit or delete texts + if(!array_key_exists($type['url'], $texts)) { + continue; + } + foreach($type['texts'] as &$text) + { + if(array_key_exists($type['url'], $deleteTexts) && array_key_exists($text['id'], $deleteTexts[$type['url']])) + { + // Delete text + $this->Questtexts->deleteQuesttext($text); + //unset($texts[$type['url']][$text['id']]); + } + elseif(array_key_exists($type['url'], $texts) && array_key_exists($text['id'], $texts[$type['url']])) + { + // Edit text + $this->Questtexts->editQuesttext($text['id'], $texts[$type['url']][$text['id']]); + + // Validate medium + $medium = null; + $validation = true; + if(!empty($media) && array_key_exists($type['url'], $media['error']) && array_key_exists($text['id'], $media['error'][$type['url']]) && $media['error'][$type['url']][$text['id']] != UPLOAD_ERR_NO_FILE) + { + $medium = array( + 'name' => $media['name'][$type['url']][$text['id']], + 'tmp_name' => $media['tmp_name'][$type['url']][$text['id']], + 'type' => $media['type'][$type['url']][$text['id']], + 'size' => $media['size'][$type['url']][$text['id']], + 'error' => $media['error'][$type['url']][$text['id']] + ); + + // Check error + if($medium['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'error', $medium); + } + + // Check mimetype + $mediaMimetype = null; + $medium['mimetype'] = \hhu\z\Utils::getMimetype($medium['tmp_name'], $medium['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $medium['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $medium['mimetype']); + } + elseif($medium['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']); + } + } + $validations[$type['url']][$text['id']] = $validation; + + // Upload medium + if(!is_null($medium) && $validation === true) + { + $questsmediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('questtext-%d-%d', $quest['id'], $text['id']), + $medium['name'], + $medium['type'], + $medium['tmp_name'] + ); + if($questsmediaId > 0) { + $this->Questtexts->setQuestmedia($text['id'], $questsmediaId); + } + } + + // Remove text from list + //unset($texts[$type['url']][$text['id']]); + } + } + + // Add new text + if(array_key_exists($type['url'], $texts) && array_key_exists('new', $texts[$type['url']])) + { + $text = $texts[$type['url']]['new']; + if(!empty($text)) + { + // Add text + $questtextId = $this->Questtexts->addQuesttextToQuest( + $this->Auth->getUserId(), + $quest['id'], + $type['url'], + $text + ); + + // Validate medium + $medium = null; + $validation = true; + if(!empty($media) && array_key_exists($type['url'], $media['error']) && array_key_exists('new', $media['error'][$type['url']]) && $media['error'][$type['url']]['new'] != UPLOAD_ERR_NO_FILE) + { + $medium = array( + 'name' => $media['name'][$type['url']]['new'], + 'tmp_name' => $media['tmp_name'][$type['url']]['new'], + 'type' => $media['type'][$type['url']]['new'], + 'size' => $media['size'][$type['url']]['new'], + 'error' => $media['error'][$type['url']]['new'] + ); + + // Check error + if($medium['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'error', $medium); + } + + // Check mimetype + $mediaMimetype = null; + $medium['mimetype'] = \hhu\z\Utils::getMimetype($medium['tmp_name'], $medium['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $medium['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $medium['mimetype']); + } + elseif($medium['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']); + } + } + $validations[$type['url']]['new'] = $validation; + + // Upload medium + if(!is_null($medium) && $validation === true) + { + $questsmediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('questtext-%d-%d', $quest['id'], $questtextId), + $medium['name'], + $medium['type'], + $medium['tmp_name'] + ); + if($questsmediaId > 0) { + $this->Questtexts->setQuestmedia($questtextId, $questsmediaId); + } + } + } + } + + // Reload texts + $type['texts'] = $this->Questtexts->getQuesttextsOfQuest($quest['id'], $type['url']); + foreach($type['texts'] as &$questtext) + { + if(!is_null($questtext['questsmedia_id'])) { + $questtext['media'] = $this->Media->getSeminaryMediaById($questtext['questsmedia_id']); + } + } + } + } + + + // Set titile + $this->addTitleLocalized('Edit Quest texts'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + $this->set('questtexttypes', $questtextTypes); + $this->set('mimetypes', $mimetypes); + $this->set('validations', $validations); + } + + + + /** + * Action: delete. + * + * Delete a Quest of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $questgroupUrl URL-Title of Questgroup + * @param string $questUrl URL-Title of Quest + */ + public function delete($seminaryUrl, $questgroupUrl, $questUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Questgroup + $questgroup = $this->Questgroups->getQuestgroupByUrl($seminary['id'], $questgroupUrl); + $questgroup['picture'] = null; + if(!is_null($questgroup['questgroupspicture_id'])) { + $questgroup['picture'] = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + + // Get Quest + $quest = $this->Quests->getQuestByUrl($seminary['id'], $questgroup['id'], $questUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Quests->deleteQuest($quest['id']); + + // Redirect to Questgroup + $this->redirect($this->linker->link(array('questgroups', 'questgroup', $seminary['url'], $questgroup['url']))); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete Quest'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroup', $questgroup); + $this->set('quest', $quest); + } + + + + + /** + * Render and handle the task of a Quest. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param array $seminary Seminary data + * @param array $questgroup Questgroup data + * @param array $quest Quest data + * @param array $character Character data + * @return string Rendered output + */ + private function renderTask($questtypeClassname, $seminary, $questgroup, $quest, $character) + { + $task = null; + try { + // Generate request and response + $request = clone $this->request; + $response = $this->createQuesttypeResponse('quest', $seminary, $questgroup, $quest, $character); + + // Load Questtype Agent + $questtypeAgent = $this->loadQuesttypeAgent($questtypeClassname, $request, $response); + + // Solve Quest + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) + { + // Get user answers + $answers = $this->request->getPostParam('answers'); + + // Save answers in database + try { + if(!$this->Quests->hasCharacterSolvedQuest($quest['id'], $character['id'])) { + $questtypeAgent->saveAnswersOfCharacter($seminary, $questgroup, $quest, $character, $answers); + } + + // Match answers with correct ones + $status = $questtypeAgent->matchAnswersofCharacter($seminary, $questgroup, $quest, $character, $answers); + if($status === true) + { + // Mark Quest as solved + $this->Quests->setQuestSolved($quest['id'], $character['id']); + + // Notify of XP-level change + $newXPLevel = $this->Xplevels->getXPLevelById($character['xplevel_id']); + if($newXPLevel['level'] > $character['xplevel']) { + $this->Notification->addNotification( + \hhu\z\controllers\components\NotificationComponent::TYPE_LEVELUP, + $newXPLevel['level'], + $this->linker->link(array('characters', 'character', $seminary['url'], $character['url'])) + ); + } + + // Redirect + $this->redirect($this->linker->link(array(), 5, true, array('status'=>'solved'), false, 'task')); + } + elseif($status === false) + { + // Mark Quest as unsolved + $this->Quests->setQuestUnsolved($quest['id'], $character['id']); + + // Redirect + $this->redirect($this->linker->link(array(), 5, true, array('status'=>'unsolved'), false, 'task')); + } + else { + // Mark Quest as submitted + $this->Quests->setQuestSubmitted($quest['id'], $character['id']); + + // Send notification mail + $this->sendSubmissionMail($seminary, $questgroup, $quest, $character); + + // Redirect + $this->redirect($this->linker->link(array(), 5, true, null, false, 'task')); + } + } + catch(\hhu\z\exceptions\SubmissionNotValidException $e) { + $response->addParam($e); + } + } + + // Render Task + $task = $this->runQuesttypeAgent($questtypeAgent, $request, $response); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotFoundException $e) { + $task = $e->getMessage(); + } + + + // Return rendered output + return $task; + } + + + /** + * Render and handle a Character submission for a Quest. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param array $seminary Seminary data + * @param array $questgroup Questgroup data + * @param array $quest Quest data + * @param array $character Character data + * @return string Rendered output + */ + private function renderTaskSubmission($questtypeClassname, $seminary, $questgroup, $quest, $character) + { + $task = null; + try { + // Generate request and response + $request = clone $this->request; + $response = $this->createQuesttypeResponse('submission', $seminary, $questgroup, $quest, $character); + + // Load Questtype Agent + $questtypeAgent = $this->loadQuesttypeAgent($questtypeClassname, $request, $response); + + // Solve Quest + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('submit'))) + { + // Set status + if($this->request->getPostParam('submit') == _('solved')) + { + // Mark Quest as solved + $this->Quests->setQuestSolved($quest['id'], $character['id']); + } + else + { + // Mark Quest as unsolved + $this->Quests->setQuestUnsolved($quest['id'], $character['id']); + } + + // Save additional data for Character answers + $questtypeAgent->controller->saveDataForCharacterAnswers($seminary, $questgroup, $quest, $character, $this->request->getPostParam('characterdata')); + + // Send notification + $this->sendSubmissionApprovedMail($character, $seminary, $questgroup, $quest); + + // Redirect + $this->redirect($this->linker->link(array('submissions', $seminary['url'], $questgroup['url'], $quest['url']), 1)); + } + + // Render task submissions + $task = $this->runQuesttypeAgent($questtypeAgent, $request, $response); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotFoundException $e) { + $task = $e->getMessage(); + } + + + // Return rendered output + return $task; + } + + + /** + * Render editing of a Quest. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param array $seminary Seminary data + * @param array $questgroup Questgroup data + * @param array $quest Quest data + * @return string Rendered output + */ + private function renderTaskEditing($questtypeClassname, $seminary, $questgroup, $quest) + { + $task = null; + try { + // Generate request and response + $request = clone $this->request; + $response = $this->createQuesttypeResponse('edittask', $seminary, $questgroup, $quest); + + // Load Questtype Agent + $questtypeAgent = $this->loadQuesttypeAgent($questtypeClassname, $request, $response); + + // Render Task + $task = $this->runQuesttypeAgent($questtypeAgent, $request, $response); + } + catch(\nre\exceptions\ViewNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\nre\exceptions\ActionNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeModelNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeControllerNotFoundException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotValidException $e) { + $task = $e->getMessage(); + } + catch(\hhu\z\exceptions\QuesttypeAgentNotFoundException $e) { + $task = $e->getMessage(); + } + + + // Return rendered output + return $task; + } + + + /** + * Create a response for the Questtype rendering. + * + * @param string $action Action to run + * @param mixed $param Additional parameters to add to the response + * @return \nre\core\Response Generated response + */ + private function createQuesttypeResponse($action, $param1) + { + // Clone current response + $response = clone $this->response; + // Clear parameters + $response->clearParams(1); + + // Add Action + $response->addParams( + null, + $action + ); + + // Add additional parameters + foreach(array_slice(func_get_args(), 1) as $param) { + $response->addParam($param); + } + + + // Return response + return $response; + } + + + /** + * Load and construct the QuesttypeAgent for a Questtype. + * + * @param string $questtypeClassname Name of the class for the Questtype of a Quest + * @param \nre\core\Request $request Request + * @param \nre\core\Response $response Response + * @return \hhu\z\agents\QuesttypeAgent Questtype Agent + */ + private function loadQuesttypeAgent($questtypeClassname, $request, $response) + { + // Load Agent + \hhu\z\agents\QuesttypeAgent::load($questtypeClassname); + + + // Construct and return Agent + return \hhu\z\agents\QuesttypeAgent::factory($questtypeClassname, $request, $response); + } + + + /** + * Run and render the Agent for a QuesttypeAgent and return ist output. + * + * @param \nre\core\Agent $questtypeAgent QuesttypeAgent to run and render + * @param \nre\core\Request $request Request + * @param \nre\core\Response $response Response + * @return string Rendered output + */ + private function runQuesttypeAgent($questtypeAgent, $request, $response) + { + // Run Agent + $questtypeAgent->run($request, $response); + + + // Render and return output + return $questtypeAgent->render(); + } + + + /** + * Send mail for new Character submission. + * + * @param array $seminary Seminary which the Quest belongs to + * @param array $questgroup Questgroup of Quest + * @param array $quest Quest the answer has been submitted for + * @param array $character Character that send the submission + */ + private function sendSubmissionMail($seminary, $questgroup, $quest, $character) + { + // Get system moderators + $moderators = $this->Characters->getCharactersWithCharacterRole($seminary['id'], 'moderator'); + + // Send notification mail + try { + foreach($moderators as &$moderator) + { + $user = $this->Users->getUserById($moderator['user_id']); + if($user['mailing']) { + \hhu\z\Utils::sendMail( + $user['email'], + 'charactersubmission', + true, + array( + $user, + $seminary, + $questgroup, + $quest, + $character + ), + $this->linker + ); + } + } + } + catch(\hhu\z\exceptions\MailingException $e) { + $this->log($e->getMessage()); + } + } + + + /** + * Send mail for approval of a Character submission. + * + * @param array $character Character of submission that has been approved + * @param array $seminary Seminary which the Quest belongs to + * @param array $questgroup Questgroup of Quest + * @param array $quest Quest the submission has been approved for + */ + private function sendSubmissionApprovedMail($character, $seminary, $questgroup, $quest) + { + // Get user + $user = $this->Users->getUserById($character['user_id']); + if(!$user['mailing']) { + return; + } + + // Send notification mail + try { + \hhu\z\Utils::sendMail( + $user['email'], + 'charactersubmissionapproved', + true, + array( + $user, + $seminary, + $questgroup, + $quest + ), + $this->linker + ); + } + catch(\hhu\z\exceptions\MailingException $e) { + $this->log($e->getMessage()); + } + } + + } + +?> diff --git a/controllers/SeminariesController.inc b/controllers/SeminariesController.inc new file mode 100644 index 00000000..3be361a5 --- /dev/null +++ b/controllers/SeminariesController.inc @@ -0,0 +1,601 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to list registered seminaries. + * + * @author Oliver Hanraths + */ + class SeminariesController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('users', 'seminaries', 'characterroles', 'charactertypes', 'xplevels', 'questgroupshierarchy', 'questgroups', 'questgrouptexts', 'quests', 'questtexts', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator', 'user'), + 'seminary' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator', 'user'), + 'copy' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user'), + 'calculatexps' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'seminary' => array('admin', 'moderator', 'user', 'guest'), + 'edit' => array('admin'), + 'copy' => array('admin'), + 'delete' => array('admin'), + 'calculatexps' => array('admin', 'moderator') + ); + + + + + /** + * Action: index. + * + * List registered seminaries. + */ + public function index() + { + // Get seminaries + $seminaries = $this->Seminaries->getSeminaries(); + + // Get additional data + foreach($seminaries as &$seminary) + { + $description = \hhu\z\Utils::shortenString($seminary['description'], 100, 120); + $seminary['description'] = $description.(strlen($description) < strlen($seminary['description']) ? ' …' : null); + $seminary['creator'] = $this->Users->getUserById($seminary['created_user_id']); + $seminary['charactertypes'] = $this->Charactertypes->getCharacterTypesForSeminary($seminary['id']); + $seminary['xplevels'] = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + + // Character of currently logged-in user + try { + $seminary['usercharacter'] = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + $seminary['usercharacter']['characterroles'] = $this->Characterroles->getCharacterrolesForCharacterById($seminary['usercharacter']['id']); + $seminary['xps'] = $this->Seminaries->getTotalXPs($seminary['id']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + } + + } + + + // Set titile + $this->addTitleLocalized('Seminaries'); + + // Pass data to view + $this->set('seminaries', $seminaries); + } + + + /** + * Action: seminary. + * + * Show a seminary and its details. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a seminary + */ + public function seminary($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Created user + $seminary['creator'] = $this->Users->getUserById($seminary['created_user_id']); + + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + + // Questgrouphierarchy and Questgroups + $questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyOfSeminary($seminary['id']); + foreach($questgroupshierarchy as &$hierarchy) + { + // Get Questgroups + $hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']); + + // Get additional data + foreach($hierarchy['questgroups'] as $i => &$questgroup) + { + // Check permission of Questgroups + if($i >= 1 && count(array_intersect(array('admin','moderator'), SeminaryController::$character['characterroles'])) == 0) + { + if(!$this->Questgroups->hasCharacterSolvedQuestgroup($hierarchy['questgroups'][$i-1]['id'], $character['id'])) + { + $hierarchy['questgroups'] = array_slice($hierarchy['questgroups'], 0, $i); + break; + } + } + + // Get first Questgroup text + $text = $this->getFirstQuestgroupText($questgroup['id']); + if(!is_null($text)) + { + $questgroup['text'] = \hhu\z\Utils::shortenString($text, 100, 120).' …'; + } + + // Get Character XPs + $questgroup['character_xps'] = $this->Questgroups->getAchievedXPsForQuestgroup($questgroup['id'], $character['id']); + + // Get Media + $questgroup['picture'] = null; + try { + $questgroup['picture'] = $this->Media->getSeminaryMediaById($questgroup['questgroupspicture_id']); + } + catch(\nre\exceptions\IdNotFoundException $e) { + } + } + } + + + // Set titile + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('questgroupshierarchy', $questgroupshierarchy); + } + + + /** + * Action: create. + * + * Create a new Seminary. + */ + public function create() + { + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = ''; + $course = ''; + $description = ''; + $fields = array('title', 'course'); + $validation = array(); + + // Create a new Seminary + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Seminaries->seminaryTitleExists($title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $course = $this->request->getPostParam('course'); + $description = $this->request->getPostParam('description'); + + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) + { + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } + } + + // Create new Seminary + if($validation === true) + { + $seminaryId = $this->Seminaries->createSeminary( + $this->Auth->getUserId(), + $title, + $course, + $description + ); + $seminary = $this->Seminaries->getSeminaryById($seminaryId); + + // Upload moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createMoodpic( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('seminarymoodpic-%s', $seminary['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Seminaries->setMoodpicForSeminary($seminary['id'], $mediaId); + } + } + + // Redirect to Seminary overview + $this->redirect($this->linker->link('index', 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('New seminary'); + + // Pass data to view + $this->set('title', $title); + $this->set('course', $course); + $this->set('description', $description); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a seminary + */ + public function edit($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = $seminary['title']; + $course = $seminary['course']; + $description = $seminary['description']; + $fields = array('title', 'course'); + $validation = array(); + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Seminaries->seminaryTitleExists($title, $seminary['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $course = $this->request->getPostParam('course'); + $description = $this->request->getPostParam('description'); + + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) + { + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } + } + + // Edit Seminary + if($validation === true) + { + $this->Seminaries->editSeminary( + $seminary['id'], + $title, + $course, + $description + ); + $seminary = $this->Seminaries->getSeminaryById($seminary['id']); + + // Update moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createMoodpic( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('seminarymoodpic-%s', $seminary['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Seminaries->setMoodpicForSeminary($seminary['id'], $mediaId); + } + } + + // Redirect to entry + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Edit seminary'); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('title', $title); + $this->set('course', $course); + $this->set('description', $description); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Copy a Seminary and selected content. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a seminary + */ + public function copy($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Values + $title = sprintf('%s (%s)', $seminary['title'], _('Copy')); + $course = $seminary['course']; + $description = $seminary['description']; + $elements = array(); + $fields = array('title', 'course'); + $validation = array(); + $exception = null; + + // Check request method + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Seminaries->seminaryTitleExists($title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $course = $this->request->getPostParam('course'); + $description = $this->request->getPostParam('description'); + $elements = $this->request->getPostParam('elements'); + if(!is_array($elements)) { + $elements = array(); + } + + // Copy Seminary + if($validation === true) + { + try { + $seminaryId = $this->Seminaries->copySeminary( + $this->Auth->getUserId(), + $seminary['id'], + $title, + $course, + $description, + array_key_exists('seminaryfields', $elements), + array_key_exists('media', $elements), + array_key_exists('questgroupshierarchy', $elements), + array_key_exists('questgroups', $elements), + array_key_exists('quests', $elements), + array_key_exists('questtopics', $elements), + array_key_exists('charactertypes', $elements), + array_key_exists('xplevels', $elements), + array_key_exists('avatars', $elements), + array_key_exists('achievements', $elements), + array_key_exists('charactergroupsgroups', $elements), + array_key_exists('charactergroupsquests', $elements) + ); + $seminary = $this->Seminaries->getSeminaryById($seminaryId); + + // Redirect to overview + $this->redirect($this->linker->link('index', 1)); + } + catch(\hhu\z\exceptions\QuesttypeModelNotValidException $e) { + $exception = $e; + } + catch(\hhu\z\exceptions\QuesttypeModelNotFoundException $e) { + $exception = $e; + } + catch(\hhu\z\exceptions\FileCopyException $e) { + $exception = $e; + } + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('title', $title); + $this->set('course', $course); + $this->set('description', $description); + $this->set('elements', $elements); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + $this->set('exception', $exception); + } + + + /** + * Action: delete. + * + * Delete a seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a seminary + */ + public function delete($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Seminaries->deleteSeminary($seminary['id']); + + // Redirect to overview + $this->redirect($this->linker->link(null, 1)); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete seminary'); + + // Show confirmation + $this->set('seminary', $seminary); + } + + + /** + * Action: calculatexps. + * + * (Re-) Calculate the amount of achievable XPs for a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function calculatexps($seminaryUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // (Re-) Calculate XPs + $this->Seminaries->calculateXPsForSeminary($seminary['id']); + + // Redirect to Questgroup + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + + + + + /** + * Get the first text of a Questgroup. + * + * @param int $questgroupId ID of a Questgroup + * @return string First text of this Questgroup or NULL + */ + private function getFirstQuestgroupText($questgroupId) + { + // Text of Questgroup itself + $questgroupTexts = $this->Questgrouptexts->getQuestgroupTexts($questgroupId); + if(!empty($questgroupTexts)) { + return $questgroupTexts[0]['text']; + } + + // Text of first Quest + $quest = $this->Quests->getFirstQuestOfQuestgroup($questgroupId); + if(!is_null($quest)) + { + $questText = $this->Questtexts->getFirstQuestText($quest['id']); + if(!is_null($questText)) { + return $questText; + } + } + + // Text of ChildQuestgroups + $questgroupHierarchy = $this->Questgroupshierarchy->getHierarchyForQuestgroup($questgroupId); + $childQuestgroupshierarchy = $this->Questgroupshierarchy->getChildQuestgroupshierarchy($questgroupHierarchy['id']); + foreach($childQuestgroupshierarchy as &$hierarchy) + { + // Get Questgroups + $questgroups = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id'], $questgroupId); + foreach($questgroups as &$group) + { + $childQuestgroupText = $this->getFirstQuestgroupText($group['id']); + if(!is_null($childQuestgroupText)) { + return $childQuestgroupText; + } + } + } + + + // No text found + return null; + } + + } + +?> diff --git a/controllers/SeminarybarController.inc b/controllers/SeminarybarController.inc new file mode 100644 index 00000000..00e7ee70 --- /dev/null +++ b/controllers/SeminarybarController.inc @@ -0,0 +1,89 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to display a sidebar with Seminary related + * information. + * + * @author Oliver Hanraths + */ + class SeminarybarController extends \hhu\z\Controller + { + /** + * Required models + * + * @var array + */ + public $models = array('characters', 'quests', 'questgroups', 'achievements', 'charactergroups', 'avatars', 'media', 'xplevels'); + + + + + /** + * Action: index. + */ + public function index() + { + // Do not render at first + $this->set('render', false); + + // Get Seminary + $seminary = SeminaryController::$seminary; + if(is_null($seminary)) { + return; + } + + // Get Character + $character = SeminaryController::$character; + if(is_null($character)) { + return; + } + $character['rank'] = $this->Characters->getXPRank($seminary['id'], $character['xps']); + + // Get “last” Quest + $lastQuest = $this->Quests->getLastQuestForCharacter($character['id']); + if(!is_null($lastQuest)) { + $lastQuest['questgroup'] = $this->Questgroups->getQuestgroupById($lastQuest['questgroup_id']); + } + + // Get last achieved Achievement + $achievements = $this->Achievements->getAchievedAchievementsForCharacter($character['id'], false); + $lastAchievement = array_shift($achievements); + + // Get Character group members + $characterGroups = array(); + foreach($this->Charactergroups->getGroupsForCharacter($character['id']) as $group) + { + $groupsgroup = $this->Charactergroups->getGroupsgroupById($group['charactergroupsgroup_id']); + if($groupsgroup['preferred']) + { + $group['members'] = $this->Characters->getCharactersForGroup($group['id']); + $characterGroups[] = $group; + } + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('character', $character); + $this->set('lastQuest', $lastQuest); + $this->set('lastAchievement', $lastAchievement); + $this->set('characterGroups', $characterGroups); + // Render now + $this->set('render', true); + } + + } + +?> diff --git a/controllers/SeminarymenuController.inc b/controllers/SeminarymenuController.inc new file mode 100644 index 00000000..ff9d34d5 --- /dev/null +++ b/controllers/SeminarymenuController.inc @@ -0,0 +1,53 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to display a menu with Seminary related + * links. + * + * @author Oliver Hanraths + */ + class SeminarymenuController extends \hhu\z\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set userdata + $this->set('loggedUser', \hhu\z\controllers\IntermediateController::$user); + $this->set('loggedSeminary', \hhu\z\controllers\SeminaryController::$seminary); + $this->set('loggedCharacter', \hhu\z\controllers\SeminaryController::$character); + } + + + /** + * Action: index. + */ + public function index() + { + } + + } + +?> diff --git a/controllers/TextmailController.inc b/controllers/TextmailController.inc new file mode 100644 index 00000000..d6b28068 --- /dev/null +++ b/controllers/TextmailController.inc @@ -0,0 +1,55 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the TextmailAgent for generating a simple text-mail + * message. + * + * @author Oliver Hanraths + */ + class TextmailController extends \nre\core\Controller + { + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + + // Set linker + $this->set('linker', ($request instanceof \hhu\z\requests\MailRequest && !is_null($request->getLinker())) ? $request->getLinker() : null); + } + + + /** + * Action: index. + * + * Create simple text-mail message. + */ + public function index() + { + $this->set('appname', \nre\configs\AppConfig::$app['name']); + } + + } + +?> diff --git a/controllers/UploadsController.inc b/controllers/UploadsController.inc new file mode 100644 index 00000000..eb208b4d --- /dev/null +++ b/controllers/UploadsController.inc @@ -0,0 +1,318 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the UploadsAgent to process and show user uploads. + * + * @author Oliver Hanraths + */ + class UploadsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('uploads', 'users', 'userroles', 'characterroles', 'seminaries', 'charactergroups'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'seminary' => array('admin', 'moderator', 'user', 'guest'), + 'charactergroup' => array('admin', 'moderator', 'user', 'guest') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'seminary' => array('admin', 'moderator', 'user', 'guest'), + 'charactergroup' => array('admin', 'moderator', 'user') + ); + + + + + /** + * Prefilter. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function preFilter(\nre\core\Request $request, \nre\core\Response $response) + { + parent::preFilter($request, $response); + + // Set headers for caching control + $response->addHeader("Pragma: public"); + $response->addHeader("Cache-control: public, max-age=".(60*60*24)); + $response->addHeader("Expires: ".gmdate('r', time()+(60*60*24))); + $response->addHeader("Date: ".gmdate(\DateTime::RFC822)); + } + + + /** + * Action: seminary. + * + * Display a Seminary upload. + * + * @throws \nre\exceptions\AccessDeniedException + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $uploadUrl URL-name of the upload + * @param string $action Current action (optional) + */ + public function seminary($seminaryUrl, $uploadUrl, $action=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Upload + $upload = $this->Uploads->getSeminaryuploadByUrl($seminary['id'], $uploadUrl); + + // Check permissions + if(!$upload['public']) + { + $user = $this->Users->getUserById($this->Auth->getUserId()); + $user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById($user['id'])); + + // System roles + if(count(array_intersect(array('admin', 'moderator'), $user['roles'])) == 0) + { + // Owner of file + if($upload['created_user_id'] != $user['id']) + { + // Seminary permissions + $characterRoles = array_map(function($r) { return $r['name']; }, $this->Characterroles->getCharacterrolesForCharacterById($character['id'])); + if(count(array_intersect(array('admin', 'moderator'), $characterRoles)) == 0) { + throw new \nre\exceptions\AccessDeniedException(); + } + } + } + } + + // Get file + switch($action) + { + case null: + $file = $this->getUploadFile($upload); + break; + case 'thumbnail': + $file = $this->createThumbnail($upload); + break; + default: + throw new \nre\exceptions\ParamsNotValidException($action); + break; + } + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('upload', $upload); + $this->set('file', $file); + } + + + /** + * Action: charactergroup. + * + * Display the icon of a Character group. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $groupUrl URL-Title of a Character group + */ + public function charactergroup($seminaryUrl, $groupsgroupUrl, $groupUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character group + $group = $this->Charactergroups->getGroupByUrl($groupsgroup['id'], $groupUrl); + + // Get Upload + $upload = $this->Uploads->getSeminaryuploadById($group['seminaryupload_id']); + + // Get file + $file = $this->getUploadFile($upload); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('upload', $upload); + $this->set('file', $file); + } + + + + + /** + * Determine the file for an upload. + * + * @throws \nre\exceptions\IdNotFoundException + * @param array $upload Upload to get file for + * @return object File for the upload (or null if upload is cached) + */ + private function getUploadFile($upload) + { + // Set content-type + $this->response->addHeader("Content-type: ".$upload['mimetype'].""); + + // Set filename + $upload['filename'] = ROOT.DS.\nre\configs\AppConfig::$dirs['seminaryuploads'].DS.$upload['url']; + if(!file_exists($upload['filename'])) { + throw new \nre\exceptions\IdNotFoundException($uploadUrl); + } + + // Cache + if($this->setCacheHeaders($upload['filename'])) { + return null; + } + + + return file_get_contents($upload['filename']); + } + + + /** + * Create a thumbnail from an upload. + * + * @param array $upload Upload to create thumbnail for + * @return object Thumbnail for the upload (or null if thumbnail is cached) + */ + private function createThumbnail($upload) + { + // Set filename + $upload['filename'] = ROOT.DS.\nre\configs\AppConfig::$dirs['seminaryuploads'].DS.$upload['url']; + + // Set content-type + $this->response->addHeader("Content-type: image/jpeg"); + + // Check file + if(!file_exists($upload['filename'])) { + throw new \nre\exceptions\IdNotFoundException($upload['url']); + } + + // Cache + if($this->setCacheHeaders($upload['filename'])) { + return null; + } + + // Set geometry + $width = 100; + $height = 100; + + switch($upload['mimetype']) + { + case 'image/jpeg': + case 'image/png': + // Read image from cache + $tempFileName = ROOT.DS.\nre\configs\AppConfig::$dirs['temporary'].DS.$upload['url'].'-'.$width.'x'.$height; + if(file_exists($tempFileName)) + { + // Check age of file + if(date('r', filemtime($tempFileName)+(60*60*24)) > date('r', time())) { + // Too old, delete + unlink($tempFileName); + } + else { + // Valid, read and return + return file_get_contents($tempFileName); + } + } + + // ImageMagick + $im = new \Imagick($upload['filename']); + + // Calculate new size + $geometry = $im->getImageGeometry(); + if($geometry['width'] < $width) { + $width = $geometry['width']; + } + if($geometry['height'] < $height) { + $height = $geometry['width']; + } + + // Process + $im->thumbnailImage($width, $height, true); + $im->contrastImage(1); + $im->setImageFormat('jpeg'); + + // Save temporary file + $im->writeImage($tempFileName); + + + // Return resized image + return $im; + break; + default: + throw new \nre\exceptions\ParamsNotValidException('thumbnail'); + break; + } + + + return $this->getUploadFile($upload); + } + + + /** + * Determine file information and set the HTTP-header for + * caching accordingly. + * + * @param string $fileName Filename + * @return boolean HTTP-status 304 was set (in cache) + */ + private function setCacheHeaders($fileName) + { + // Determine last change of file + $fileLastModified = gmdate('r', filemtime($fileName)); + + // Generate E-Tag + $fileEtag = hash('sha256', $fileLastModified.$fileName); + + + // Set header + $this->response->addHeader("Last-Modified: ".$fileLastModified); + $this->response->addHeader("Etag: ".$fileEtag); + // HTTP-status + $headerModifiedSince = $this->request->getServerParam('HTTP_IF_MODIFIED_SINCE'); + $headerNoneMatch = $this->request->getServerParam('HTTP_IF_NONE_MATCH'); + if( + !is_null($headerModifiedSince) && $fileLastModified < strtotime($headerModifiedSince) && + !is_null($headerNoneMatch) && $headerNoneMatch == $fileEtag + ) { + $this->response->setExit(true); + $this->response->addHeader(\nre\core\WebUtils::getHttpHeader(304)); + + return true; + } + + + return false; + } + + } + +?> diff --git a/controllers/UserrolesController.inc b/controllers/UserrolesController.inc new file mode 100644 index 00000000..238f189b --- /dev/null +++ b/controllers/UserrolesController.inc @@ -0,0 +1,47 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to display and manage userroles. + * + * @author Oliver Hanraths + */ + class UserrolesController extends \hhu\z\Controller + { + + + + + /** + * Action: user. + * + * Show a user and its details. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $userUrl URL-Username of an user + */ + public function user($userUrl) + { + // Get userroles + $roles = $this->Userroles->getUserrolesForUserByUrl($userUrl); + + + // Pass data to view + $this->set('roles', $roles); + } + + + } + +?> diff --git a/controllers/UsersController.inc b/controllers/UsersController.inc new file mode 100644 index 00000000..f0e254fd --- /dev/null +++ b/controllers/UsersController.inc @@ -0,0 +1,641 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the Agent to list registered users and their data. + * + * @author Oliver Hanraths + */ + class UsersController extends \hhu\z\controllers\IntermediateController + { + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'index' => array('admin', 'moderator'), + 'user' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator', 'user'), + 'delete' => array('admin') + ); + /** + * Required models + * + * @var array + */ + public $models = array('users', 'userroles', 'characters', 'characterroles', 'avatars', 'media', 'xplevels'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + + + + + /** + * Action: index. + * + * @param string $all Whether to list all users at once or not (optional) + */ + public function index($all=null) + { + // Set filters + $sortorder = 'username'; + $username = null; + $name = null; + $email = null; + $page = 1; + if($this->request->getRequestMethod() == 'GET') + { + $sortorder = $this->request->getGetParam('sortorder'); + $sortorder = !empty($sortorder) ? $sortorder : 'username'; + $username = (!is_null($this->request->getGetParam('username'))) ? $this->request->getGetParam('username') : $username; + $name = (!is_null($this->request->getGetParam('name'))) ? $this->request->getGetParam('name') : $name; + $email = (!is_null($this->request->getGetParam('email'))) ? $this->request->getGetParam('email') : $email; + $page = $this->request->getGetParam('page'); + $page = !empty($page) ? intval($page) : 1; + } + + // Get registered users + $limit = ($all != 'all') ? \nre\configs\AppConfig::$misc['lists_limit'] : null; + $offset = ($all != 'all') ? max((intval($page) - 1), 0) * $limit : 0; + $usersCount = $this->Users->getUsersCount($username, $name, $email); + $users = $this->Users->getUsers($sortorder, $username, $name, $email, $limit, $offset); + foreach($users as &$user) { + $user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById($user['id'])); + } + + + // Set titile + $this->addTitleLocalized('Users'); + + // Pass data to view + $this->set('users', $users); + $this->set('usersCount', $usersCount); + $this->set('sortorder', $sortorder); + $this->set('username', $username); + $this->set('name', $name); + $this->set('email', $email); + $this->set('all', $all); + $this->set('page', $page); + $this->set('limit', $limit); + } + + + /** + * Action: user. + * + * Show a user and its details. + * + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\AccessDeniedException + * @param string $userUrl URL-Username of an user + */ + public function user($userUrl) + { + // Get user + $user = $this->Users->getUserByUrl($userUrl); + + // Check permissions + if(count(array_intersect(array('admin','moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0 && $user['id'] != IntermediateController::$user['id']) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get Characters + $characters = $this->Characters->getCharactersForUser($user['id']); + + // Additional Character information + foreach($characters as &$character) + { + // Seminary roles + $character['characterroles'] = $this->Characterroles->getCharacterrolesForCharacterById($character['id']); + $character['characterroles'] = array_map(function($a) { return $a['name']; }, $character['characterroles']); + + // Level + try { + $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); + } + catch(\nre\Exceptions\IdNotFoundException $e) { + // No XP-level + } + + // Avatar + $avatar = $this->Avatars->getAvatarById($character['avatar_id']); + if(!is_null($avatar['small_avatarpicture_id'])) + { + //$character['seminary'] = + $character['small_avatar'] = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); + } + } + + + // Set titile + $this->addTitleLocalized($user['username']); + $this->addTitleLocalized('Users'); + + // Pass data to view + $this->set('user', $user); + $this->set('characters', $characters); + } + + + /** + * Action: login. + * + * Log in a user. + */ + public function login() + { + $username = ''; + $referrer = null; + + // Log the user in + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('login'))) + { + $username = $this->request->getPostParam('username'); + $referrer = $this->request->getPostParam('referrer'); + $userId = $this->Users->login( + $username, + $this->request->getPostParam('password') + ); + + if(!is_null($userId)) + { + $this->Auth->setUserId($userId); + $user = $this->Users->getUserById($userId); + + if(!empty($referrer)) { + $this->redirect($referrer); + } + else { + $this->redirect($this->linker->link(array($user['url']), 1)); + } + } + } + + + // Set titile + $this->addTitleLocalized('Login'); + + // Pass data to view + $this->set('username', $username); + $this->set('referrer', $referrer); + $this->set('failed', ($this->request->getRequestMethod() == 'POST')); + } + + + /** + * Action: register. + * + * Register a new user. + */ + public function register() + { + $username = ''; + $prename = ''; + $surname = ''; + $email = ''; + + $fields = array('username', 'prename', 'surname', 'email', 'password'); + $validation = array(); + $emailhost = \nre\configs\AppConfig::$app['registration_host']; + + // Register a new user + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('register'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $username = $this->request->getPostParam('username'); + if($this->Users->usernameExists($username)) { + $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); + } + $prename = $this->request->getPostParam('prename'); + $surname = $this->request->getPostParam('surname'); + $email = $this->request->getPostParam('email'); + if(!empty($emailhost)) { + if(substr_compare($email, $emailhost, max(0, strlen($email)-strlen($emailhost)), strlen($emailhost)) !== 0) { + $validation = $this->Validation->addValidationResult($validation, 'email', 'host', 'invalid'); + } + } + if($this->Users->emailExists($email)) { + $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); + } + $password = $this->request->getPostParam('password'); + if($password != $this->request->getPostParam('passwordrepeat')) { + $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); + } + + + // Register + if($validation === true) + { + $userId = $this->Users->createUser( + $username, + $prename, + $surname, + $email, + $password + ); + $user = $this->Users->getUserById($userId); + + // Send mail + $this->sendRegistrationMail($user); + + // Login + $this->Auth->setUserId($userId); + + + // Redirect to user page + $this->redirect($this->linker->link(array($user['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('Registration'); + + // Pass data to view + $this->set('username', $username); + $this->set('prename', $prename); + $this->set('surname', $surname); + $this->set('email', $email); + $this->set('emailhost', $emailhost); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: logout. + * + * Log out a user. + */ + public function logout() + { + // Unset the currently logged in user + $this->Auth->setUserId(null); + + // Redirect + $this->redirect($this->linker->link(array())); + } + + + /** + * Action: manage. + * + * Manage users. + */ + public function manage() + { + $selectedUsers = array(); + //global $sortorder; + $sortorder = 'username'; + + if($this->request->getRequestMethod() == 'POST') + { + // Set sortorder + $sortorder = $this->request->getPostParam('sortorder'); + + // Do action + $selectedUsers = $this->request->getPostParam('users'); + if(!is_array($selectedUsers)) { + $selectedUsers = array(); + } + if(!is_null($this->request->getPostParam('actions')) && count($this->request->getPostParam('actions')) > 0 && !is_null($this->request->getPostParam('users')) && count($this->request->getPostParam('users')) > 0) + { + $actions = $this->request->getPostParam('actions'); + $action = array_keys($actions)[0]; + + switch($action) + { + // Add/remove role to/from Characters + case 'addrole': + case 'removerole': + // Determine role and check permissions + $role = null; + switch($actions[$action]) + { + case _('Admin'): + if(!in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'admin'; + break; + case _('Moderator'): + if(!in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles'])) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'moderator'; + break; + case _('User'): + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) <= 0) { + throw new \nre\exceptions\AccessDeniedException(); + } + $role = 'user'; + break; + } + + // Add role + if($action == 'addrole') { + foreach($selectedUsers as &$userId) { + $this->Userroles->addUserroleToUser($userId, $role); + } + } + // Remove role + else { + foreach($selectedUsers as &$userId) { + $this->Userroles->removeUserroleFromUser($userId, $role); + } + } + break; + } + } + } + + // Get registered users + $users = $this->Users->getUsers($sortorder); + foreach($users as &$user) { + $user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById($user['id'])); + } + + + // Set titile + $this->addTitleLocalized('Manage users'); + + // Pass data to view + $this->set('users', $users); + $this->set('selectedUsers', $selectedUsers); + $this->set('sortorder', $sortorder); + } + + + /** + * Action: create. + * + * Create a new user. + */ + public function create() + { + // Values + $username = ''; + $prename = ''; + $surname = ''; + $email = ''; + $fields = array('username', 'prename', 'surname', 'email', 'password'); + $validation = array(); + + // Create new user + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $username = $this->request->getPostParam('username'); + if($this->Users->usernameExists($username)) { + $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); + } + $prename = $this->request->getPostParam('prename'); + $surname = $this->request->getPostParam('surname'); + $email = $this->request->getPostParam('email'); + if($this->Users->emailExists($email)) { + $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); + } + $password = $this->request->getPostParam('password'); + if($password != $this->request->getPostParam('passwordrepeat')) { + $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); + } + + // Create + if($validation === true) + { + $userId = $this->Users->createUser( + $this->request->getPostParam('username'), + $this->request->getPostParam('prename'), + $this->request->getPostParam('surname'), + $this->request->getPostParam('email'), + $this->request->getPostParam('password') + ); + + // Redirect to user + $user = $this->Users->getUserById($userId); + $this->redirect($this->linker->link(array($user['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // Set titile + $this->addTitleLocalized('New user'); + + // Pass data to view + $this->set('username', $username); + $this->set('prename', $prename); + $this->set('surname', $surname); + $this->set('email', $email); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: edit. + * + * Edit a user. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $userUrl URL-Username of an user + */ + public function edit($userUrl) + { + // User + $user = $this->Users->getUserByUrl($userUrl); + + // Check permissions + if(count(array_intersect(array('admin','moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0 && $user['id'] != \hhu\z\controllers\IntermediateController::$user['id']) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Values + $username = $user['username']; + $prename = $user['prename']; + $surname = $user['surname']; + $email = $user['email']; + $mailing = $user['mailing']; + $fields = array('username', 'prename', 'surname', 'email'); + $validation = array(); + + // Edit user + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('save'))) + { + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $username = $this->request->getPostParam('username'); + if($this->Users->usernameExists($username, $user['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); + } + $password = $this->request->getPostParam('password'); + if(!empty($password)) + { + $validation = $this->Validation->addValidationResults($validation, + 'password', + $this->Validation->validateParam( + $this->request->getPostParams(), + 'password' + ) + ); + if($password != $this->request->getPostParam('passwordrepeat')) { + $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); + } + } + $prename = $this->request->getPostParam('prename'); + $surname = $this->request->getPostParam('surname'); + $email = $this->request->getPostParam('email'); + if($this->Users->emailExists($email, $user['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); + } + $mailing = !is_null($this->request->getPostParam('mailing')); + + // Save changes + if($validation === true) + { + // Edit user + $this->Users->editUser( + $user['id'], + (count(array_intersect(array('admin','moderator'),\hhu\z\controllers\IntermediateController::$user['roles'])) > 0) ? $this->request->getPostParam('username') : $user['username'], + $prename, + $surname, + $email, + $password, + $mailing + ); + + // Redirect to entry + $user = $this->Users->getUserById($user['id']); + $this->redirect($this->linker->link(array('user', $user['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + $validationSettings['password'] = \nre\configs\AppConfig::$validation['password']; + + + // Set titile + $this->addTitleLocalized('Edit user'); + + // Pass data to view + $this->set('username', $username); + $this->set('prename', $prename); + $this->set('surname', $surname); + $this->set('email', $email); + $this->set('mailing', $mailing); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: delete. + * + * Delete a user. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $userUrl URL-Username of an user + */ + public function delete($userUrl) + { + // User + $user = $this->Users->getUserByUrl($userUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete user + $this->Users->deleteUser($user['id']); + + // Redirect to overview + $this->redirect($this->linker->link(null, 1)); + } + + // Redirect to entry + $this->redirect($this->linker->link(array('user', $user['url']), 1)); + } + + + // Set titile + $this->addTitleLocalized('Delete user'); + + // Show confirmation + $this->set('user', $user); + } + + + + + /** + * Send mail for new user registration. + * + * @param array $user Newly registered user + */ + private function sendRegistrationMail($user) + { + // Get system moderators + $moderators = $this->Users->getUsersWithRole('moderator'); + + // Send notification mail + try { + foreach($moderators as &$moderator) + { + if($moderator['mailing']) { + \hhu\z\Utils::sendMail( + $moderator['email'], + 'userregistration', + true, + array( + $moderator, + $user + ), + $this->linker + ); + } + } + } + catch(\hhu\z\exceptions\MailingException $e) { + $this->log($e->getMessage()); + } + } + + } + +?> diff --git a/controllers/XplevelsController.inc b/controllers/XplevelsController.inc new file mode 100644 index 00000000..91bb32f5 --- /dev/null +++ b/controllers/XplevelsController.inc @@ -0,0 +1,188 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers; + + + /** + * Controller of the XplevelsAgent to handle XP-levels of a + * Seminary. + * + * @author Oliver Hanraths + */ + class XplevelsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required components + * + * @var array + */ + public $components = array('validation'); + /** + * Required models + * + * @var array + */ + public $models = array('xplevels'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'manage' => array('admin', 'moderator', 'user') + ); + + + + + /** + * Action: manage. + * + * Manage XP-levels. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function manage($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Check permissions + if( + (is_null(self::$character) && count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) && + $seminary['created_user_id'] != self::$user['id'] + ) { + throw new \nre\exceptions\AccessDeniedException(); + } + + // Get XP-levels + $xplevels = $this->Xplevels->getXPLevelsForSeminary($seminary['id']); + + // Values + $xplevelsValues = array(); + foreach($xplevels as &$xplevel) { + $xplevelsValues[$xplevel['id']] = $xplevel; + } + $deletes = array(); + $validations = array( + 'edit' => true, + 'create' => true + ); + + // Edit + $action = null; + if($this->request->getRequestMethod() == 'POST') + { + // Edit and delete XP-levels + if(!is_null($this->request->getPostParam('edit'))) + { + $action = 'edit'; + + // Get params + $xplevelsValues = $this->request->getPostParam('xplevels'); + $deletes = $this->request->getPostParam('deletes'); + + // Validate params + if(!is_array($deletes)) { + $deletes = array(); + } + foreach($xplevels as &$xplevel) + { + if(array_key_exists($xplevel['id'], $deletes)) { + continue; + } + + $xplevelValidation = $this->Validation->validateParams($xplevelsValues[$xplevel['id']], array('xps')); + if($xplevelValidation !== true) + { + if(!is_array($validations['edit'])) { + $validations['edit'] = array(); + } + if(!array_key_exists($xplevel['id'], $validations['edit']) || !is_array($validations['edit'][$xplevel['id']])) { + $validations['edit'][$xplevel['id']] = array(); + } + $validations['edit'][$xplevel['id']] = $this->Validation->addValidationResults($validations['edit'][$xplevel['id']], 'xps', $xplevelValidation); + } + } + + // Edit and delete + if($validations['edit'] === true) + { + foreach($xplevels as &$xplevel) + { + // Delete + if(array_key_exists($xplevel['id'], $deletes)) { + $this->Xplevels->deleteXPLevel($xplevel); + } + // Edit + elseif(array_key_exists($xplevel['id'], $xplevelsValues)) + { + $this->Xplevels->editXPLevel( + $xplevel['id'], + $xplevelsValues[$xplevel['id']]['xps'] + ); + } + } + + // Redirect + $this->redirect($this->linker->link(null, 3)); + } + } + + // Create XP-level + if(!is_null($this->request->getPostParam('create'))) + { + $action = 'create'; + + // Get params and validate them + $xplevelnew = $this->request->getPostParam('xplevelnew'); + $validations[$action] = $this->Validation->validateParams($xplevelnew, array('xps')); + + // Create + if($validations[$action] === true) + { + $this->Xplevels->createXPLevel( + $this->Auth->getUserId(), + $seminary['id'], + $xplevelnew['xps'] + ); + + // Redirect + $this->redirect($this->linker->link(null, 3)); + } + } + } + + // Get validation settings + $validationSettings = array( + 'xps' => \nre\configs\AppConfig::$validation['xps'] + ); + + + // Set titile + $this->addTitleLocalized('Manage XP-levels'); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('xplevels', $xplevels); + $this->set('xplevelsValues', $xplevelsValues); + $this->set('deletes', $deletes); + $this->set('action', $action); + $this->set('validations', $validations); + $this->set('validationSettings', $validationSettings); + } + + } + +?> diff --git a/controllers/components/AchievementComponent.inc b/controllers/components/AchievementComponent.inc new file mode 100644 index 00000000..70601543 --- /dev/null +++ b/controllers/components/AchievementComponent.inc @@ -0,0 +1,41 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers\components; + + + /** + * Component to handle achievements. + * + * @author Oliver Hanraths + */ + class AchievementComponent extends \nre\core\Component + { + /** + * Required models + * + * @var array + */ + public $models = array('achievements'); + + + + + /** + * Construct a new Achievements-component. + */ + public function __construct() + { + } + + } + +?> diff --git a/controllers/components/AuthComponent.inc b/controllers/components/AuthComponent.inc new file mode 100644 index 00000000..0db6c69d --- /dev/null +++ b/controllers/components/AuthComponent.inc @@ -0,0 +1,79 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers\components; + + + /** + * Component to handle authentication and authorization. + * + * @author Oliver Hanraths + */ + class AuthComponent extends \nre\core\Component + { + /** + * Key to save a user-ID as + * + * @var string + */ + const KEY_USER_ID = 'user_id'; + + + + + /** + * Construct a new Auth-component. + */ + public function __construct() + { + // Start session + if(session_id() === '') { + session_start(); + } + } + + + + + /** + * Set the ID of the user that is currently logged in. + * + * @param int $userId ID of the currently logged in user + */ + public function setUserId($userId) + { + if(is_null($userId)) { + unset($_SESSION[self::KEY_USER_ID]); + } + else { + $_SESSION[self::KEY_USER_ID] = $userId; + } + } + + + /** + * Get the ID of the user that is currently logged in. + * + * @return int ID of the currently logged in user + */ + public function getUserId() + { + if(array_key_exists(self::KEY_USER_ID, $_SESSION)) { + return $_SESSION[self::KEY_USER_ID]; + } + + + return null; + } + + } + +?> diff --git a/controllers/components/NotificationComponent.inc b/controllers/components/NotificationComponent.inc new file mode 100644 index 00000000..bddffc80 --- /dev/null +++ b/controllers/components/NotificationComponent.inc @@ -0,0 +1,108 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers\components; + + + /** + * Component to handle user notifications + * + * @author Oliver Hanraths + */ + class NotificationComponent extends \nre\core\Component + { + /** + * Type: Achievement + * + * @var string + */ + const TYPE_ACHIEVEMENT = 'achievement'; + /** + * Type: Level-up + * + * @var string + */ + const TYPE_LEVELUP = 'levelup'; + /** + * Key for Session-Array to store notifications in + * + * @var string + */ + const SESSION_KEY = 'notifications'; + + + + + /** + * Construct a new Notification-component. + */ + public function __construct() + { + // Start session + if(session_id() === '') { + session_start(); + } + + // Prepare array + if(!array_key_exists(self::SESSION_KEY, $_SESSION)) { + $_SESSION[self::SESSION_KEY] = array(); + } + } + + + + + /** + * Add a notification. + * + * @param string $type Type of notification + * @param string $message Message to display + * @param string $link Optional URL to link to + * @param string $image Optional URL of image to display + */ + public function addNotification($type, $message, $link=null, $image=null) + { + $_SESSION[self::SESSION_KEY][] = array( + 'type' => $type, + 'message' => $message, + 'link' => $link, + 'image' => $image + ); + } + + + /** + * Get all registered notifiactions and clear them. + * + * @return array List of existing notifications + */ + public function getNotifications() + { + $notifications = $_SESSION[self::SESSION_KEY]; + $this->clearNotifications(); + + + return $notifications; + } + + + /** + * Clear all notifications currently registered + */ + public function clearNotifications() + { + unset($_SESSION[self::SESSION_KEY]); + $_SESSION[self::SESSION_KEY] = array(); + } + + } + +?> diff --git a/controllers/components/QuesttypedataComponent.inc b/controllers/components/QuesttypedataComponent.inc new file mode 100644 index 00000000..6c23e4f6 --- /dev/null +++ b/controllers/components/QuesttypedataComponent.inc @@ -0,0 +1,89 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers\components; + + + /** + * Component to handle data for Questtypes between different Quest states. + * + * @author Oliver Hanraths + */ + class QuesttypedataComponent extends \nre\core\Component + { + /** + * Session key + * + * @var string + */ + const SESSION_KEY = 'questtypes'; + + + + + /** + * Construct a new QuesttypesData-component. + */ + public function __construct() + { + // Construct session place + if(!array_key_exists(self::SESSION_KEY, $_SESSION)) { + $_SESSION[self::SESSION_KEY] = array(); + } + } + + + + + /** + * Set data with a key-value pair. + * + * @param int $questId ID of Quest to set data for + * @param mixed $key Key + * @param mixed $value Value + */ + public function set($questId, $key, $value) + { + // Construct array + if(!array_key_exists($questId, $_SESSION[self::SESSION_KEY])) { + $_SESSION[self::SESSION_KEY][$questId] = array(); + } + + // Set data + $_SESSION[self::SESSION_KEY][$questId][$key] = $value; + } + + + /** + * Get data by a key. + * + * @param int $questId ID of Quest to set data for + * @param mixed $key Key + * @return mixed Value + */ + public function get($questId, $key) + { + // Check array + if(!array_key_exists($questId, $_SESSION[self::SESSION_KEY])) { + return null; + } + if(!array_key_exists($key, $_SESSION[self::SESSION_KEY][$questId])) { + return null; + } + + + // Return data + return $_SESSION[self::SESSION_KEY][$questId][$key]; + } + + } + +?> diff --git a/controllers/components/ValidationComponent.inc b/controllers/components/ValidationComponent.inc new file mode 100644 index 00000000..33f7963d --- /dev/null +++ b/controllers/components/ValidationComponent.inc @@ -0,0 +1,183 @@ + + * @copyright 2014 Heinrich-Heine-Universität Düsseldorf + * @license http://www.gnu.org/licenses/gpl.html + * @link https://bitbucket.org/coderkun/the-legend-of-z + */ + + namespace hhu\z\controllers\components; + + + /** + * Component to validate user input. + * + * @author Oliver Hanraths + */ + class ValidationComponent extends \nre\core\Component + { + /** + * Validation settings + * + * @var array + */ + private $config; + + + + + /** + * Construct a new Validation-component. + */ + public function __construct() + { + // Get validation settings from configuration + $this->config = \nre\configs\AppConfig::$validation; + } + + + + + /** + * Validate an user input. + * + * @param mixed $input User input to validate + * @param array $settings Validation setting + * @return mixed True or the settings the validation fails on + */ + public function validate($input, $settings) + { + $validation = array(); + + // Min string length + if(array_key_exists('minlength', $settings) && strlen($input) < $settings['minlength']) { + $validation['minlength'] = $settings['minlength']; + } + // Max string length + if(array_key_exists('maxlength', $settings) && strlen($input) > $settings['maxlength']) { + $validation['maxlength'] = $settings['maxlength']; + } + + // Regex + if(array_key_exists('regex', $settings) && !preg_match($settings['regex'], $input)) { + $validation['regex'] = $settings['regex']; + } + + + // Return true or the failed fields + if(empty($validation)) { + return true; + } + return $validation; + } + + + /** + * Validate an user input parameter. + * + * @param array $params User input parameters + * @param array $index Names of parameter to validate and to validate against + * @return mixed True or the parameter with settings the validation failed on + */ + public function validateParam($params, $index) + { + // Check parameter + if(!array_key_exists($index, $params)) { + throw new \nre\exceptions\ParamsNotValidException($index); + } + // Check settings + if(!array_key_exists($index, $this->config)) { + return true; + } + + + // Validate parameter and return result + return $this->validate($params[$index], $this->config[$index]); + } + + + /** + * Validate user input parameters. + * + * @param array $params User input parameters + * @param array $indices Names of parameters to validate and to validate against + * @return mixed True or the parameters with settings the validation failed on + */ + public function validateParams($params, $indices) + { + // Validate parameters + $validation = true; + foreach($indices as $index) { + $validation = $this->addValidationResults($validation, $index, $this->validateParam($params, $index)); + } + + + // Return validation results + return $validation; + } + + + /** + * Add a custom determined validation result to a validation + * array. + * + * @param mixed $validation Validation array to add result to + * @param string $index Name of parameter of the custom validation result + * @param string $setting Name of setting of the custom validation result + * @param mixed $result Validation result + * @return mixed The altered validation array + */ + public function addValidationResult($validation, $index, $setting, $result) + { + // Create validation array + if(!is_array($validation)) { + $validation = array(); + } + + // Add validation results + if(!array_key_exists($index, $validation)) { + $validation[$index] = array(); + } + $validation[$index][$setting] = $result; + + + // Return new validation result + return $validation; + } + + + /** + * Add custom determined validation results to a validation + * arary. + * + * @param mixed $validation Validation array to add result to + * @param string $index Name of parameter of the custom validation result + * @param mixed $result Validation result + * @return mixed The altered validation array + */ + public function addValidationResults($validation, $index, $results) + { + // Create validation array + if(!is_array($validation)) { + $validation = array(); + } + + // Add validation results + if($results !== true) { + $validation[$index] = $results; + } + + + // Return new validation result + if(empty($validation)) { + return true; + } + return $validation; + } + + } + +?> diff --git a/controllers/components/empty b/controllers/components/empty new file mode 100644 index 00000000..e69de29b diff --git a/controllers/empty b/controllers/empty new file mode 100644 index 00000000..e69de29b diff --git a/core/Agent.inc b/core/Agent.inc new file mode 100644 index 00000000..fb8fe8ac --- /dev/null +++ b/core/Agent.inc @@ -0,0 +1,608 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for the implementation af an Agent. + * + * @author coderkun + */ + abstract class Agent + { + /** + * Name of BottomlevelAgent for showing inline errors + * + * @var string + */ + const INLINEERROR_AGENT = 'inlineerror'; + + /** + * Current request + * + * @var Request + */ + private $request; + /** + * Current response + * + * @var Response + */ + private $response; + /** + * Log-system + * + * @var Logger + */ + protected $log; + /** + * SubAgents + * + * @var array + */ + protected $subAgents = array(); + /** + * Controller of this Agent + * + * @var Controller + */ + public $controller = null; + + + + + /** + * Load the class of an Agent. + * + * @static + * @throws \nre\exceptions\AgentNotFoundException + * @throws \nre\exceptions\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 \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ControllerNotValidException + * @throws \nre\exceptions\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 \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ControllerNotValidException + * @throws \nre\exceptions\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 \nre\exceptions\ParamsNotValidException + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\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 \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ControllerNotValidException + * @throws \nre\exceptions\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 \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\AgentNotFoundException + * @throws \nre\exceptions\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 \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\AgentNotFoundException + * @throws \nre\exceptions\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 \nre\exceptions\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 array $subAgent Original (Sub-) Agent + * @param Request $request Current request + * @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'); + } + + } + +?> diff --git a/core/Api.inc b/core/Api.inc new file mode 100644 index 00000000..9cd1cfdc --- /dev/null +++ b/core/Api.inc @@ -0,0 +1,163 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class to implement an API. + * + * The API is the center of each application and specifies how and what + * to run and render. + * + * @author coderkun + */ + abstract class Api + { + /** + * Die aktuelle Anfrage + * + * @var Request + */ + protected $request; + /** + * Der Toplevelagent + * + * @var \nre\agents\ToplevelAgent + */ + private $toplevelAgent = null; + /** + * Die aktuelle Antwort + * + * @var Response + */ + protected $response; + /** + * Log-System + * + * @var Logger + */ + protected $log; + + + + + /** + * Construct a new API. + * + * @param Request $request Current request + * @param Response $response 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 \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ControllerNotValidException + * @throws \nre\exceptions\ControllerNotFoundException + * @throws \nre\exceptions\AgentNotValidException + * @throws \nre\exceptions\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 \nre\exceptions\ServiceUnavailableException + * @throws \nre\exceptions\AgentNotValidException + * @throws \nre\exceptions\AgentNotFoundException + */ + private function loadToplevelAgent() + { + // Determine agent + $agentName = $this->response->getParam(0); + if(is_null($agentName)) { + $agentName = $this->request->getParam(0, 'toplevel'); + $this->response->addParam($agentName); + } + + // Load agent + \nre\agents\ToplevelAgent::load($agentName); + + // Construct agent + $this->toplevelAgent = \nre\agents\ToplevelAgent::factory( + $agentName, + $this->request, + $this->response, + $this->log + ); + } + + } + +?> diff --git a/core/Autoloader.inc b/core/Autoloader.inc new file mode 100644 index 00000000..fdbf73bc --- /dev/null +++ b/core/Autoloader.inc @@ -0,0 +1,98 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Autoloader. + * + * This class tries to load not yet used classes. + * + * @author coderkun + */ + class Autoloader + { + /** + * Private construct(). + */ + private function __construct() {} + + /** + * Private clone(). + */ + private function __clone() {} + + + + + /** + * Register load-method. + */ + public static function register() + { + spl_autoload_register( + array( + get_class(), + 'load' + ) + ); + } + + + /** + * Look for the given class and try to load it. + * + * @param string $fullClassName Name of class to load + */ + public static function load($fullClassName) + { + $fullClassNameA = explode('\\', $fullClassName); + + if(strpos($fullClassName, \nre\configs\CoreConfig::$core['namespace']) !== 0) + { + // App + $className = array_slice($fullClassNameA, substr_count(\nre\configs\AppConfig::$app['namespace'], '\\')); + array_unshift($className, \nre\configs\CoreConfig::getClassDir('app')); + $filename = ROOT.DS.implode(DS, $className).\nre\configs\CoreConfig::getFileExt('includes'); + if(file_exists($filename)) { + require_once($filename); + } + } + else + { + // Core + $className = array_slice($fullClassNameA, substr_count(\nre\configs\CoreConfig::$core['namespace'], '\\')); + $filename = ROOT.DS.implode(DS, $className).\nre\configs\CoreConfig::getFileExt('includes'); + if(file_exists($filename)) { + require_once($filename); + } + } + + + } + + + /** + * Determine classtype of a class. + * + * @param string $className Name of the class to determine the classtype of + * @return string Classtype of the given class + */ + public static function getClassType($className) + { + // CamelCase + return strtolower(preg_replace('/^.*([A-Z][^A-Z]+)$/', '$1', $className)); + } + + } + +?> diff --git a/core/ClassLoader.inc b/core/ClassLoader.inc new file mode 100644 index 00000000..e999568a --- /dev/null +++ b/core/ClassLoader.inc @@ -0,0 +1,129 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class for safely loading classes. + * + * @author coderkun + */ + class ClassLoader + { + + + + + /** + * Load a class. + * + * @throws \nre\exceptions\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 \nre\exceptions\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 string 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 string 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 string Only the name of the given class + */ + public static function getClassName($class) + { + return self::stripClassType(self::stripNamespace($class)); + } + + + /** + * Concatenate strings to a class name following the CamelCase + * pattern. + * + * @param string $className1 Arbitrary number of strings to concat + * @return string Class name as CamelCase + */ + public static function concatClassNames($className1) + { + return implode('', array_map( + function($arg) { + return ucfirst(strtolower($arg)); + }, + func_get_args() + )); + } + + } + +?> diff --git a/core/Component.inc b/core/Component.inc new file mode 100644 index 00000000..ae219970 --- /dev/null +++ b/core/Component.inc @@ -0,0 +1,85 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class to implement a (Controller) Component. + * + * @author coderkun + */ + abstract class Component + { + + + + + /** + * Load the class of a Component. + * + * @throws \nre\exceptions\ComponentNotFoundException + * @throws \nre\exceptions\ComponentNotValidException + * @param string $componentName Name of the Component to load + */ + public static function load($componentName) + { + // Determine full classname + $className = self::getClassName($componentName); + + try { + // Load class + ClassLoader::load($className); + + // Validate class + ClassLoader::check($className, get_class()); + } + catch(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\ComponentNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\ComponentNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Component (Factory Pattern). + * + * @param string $componentName Name of the Component to instantiate + */ + public static function factory($componentName) + { + // Determine full classname + $className = self::getClassName($componentName); + + // Construct and return Controller + return new $className(); + } + + + /** + * Determine the classname for the given Component name. + * + * @param string $componentName Component name to get classname of + * @return string Classname for the Component name + */ + private static function getClassName($componentName) + { + $className = \nre\core\ClassLoader::concatClassNames($componentName, \nre\core\ClassLoader::stripNamespace(get_class())); + + + return \nre\configs\AppConfig::$app['namespace']."controllers\\components\\$className"; + } + + } + +?> diff --git a/core/Config.inc b/core/Config.inc new file mode 100644 index 00000000..adf858cd --- /dev/null +++ b/core/Config.inc @@ -0,0 +1,49 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Configuration. + * + * This class does not hold any configuration value but helps to + * determine values that can be hold by AppConfig or CoreConfig. + * + * @author coderkun + */ + final class Config + { + + + + + /** + * Get a default value. + * + * @param string $index Index of value to get + */ + public static function getDefault($index) + { + if(array_key_exists($index, \nre\configs\AppConfig::$defaults)) { + return \nre\configs\AppConfig::$defaults[$index]; + } + if(array_key_exists($index, \nre\configs\CoreConfig::$defaults)) { + return \nre\configs\CoreConfig::$defaults[$index]; + } + + + return null; + } + + } + +?> diff --git a/core/Controller.inc b/core/Controller.inc new file mode 100644 index 00000000..fd74a79f --- /dev/null +++ b/core/Controller.inc @@ -0,0 +1,431 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Controller. + * + * @author coderkun + */ + abstract class Controller + { + /** + * Corresponding Agent + * + * @var Agent + */ + protected $agent; + /** + * View of the Controller + * + * @var View + */ + protected $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 \nre\exceptions\ControllerNotFoundException + * @throws \nre\exceptions\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 \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\ViewNotFoundException + * @param string $controllerName Name of the Controller to instantiate + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + * @param string $agent Corresponding Agent + */ + 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 \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\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 Components + $this->loadComponents(); + + // 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; + + } + + + /** + * 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 \nre\exceptions\ParamsNotValidException + * @throws \nre\exceptions\IdNotFoundException + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\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 Components of this Controller. + * + * @throws \nre\exceptions\ComponentNotValidException + * @throws \nre\exceptions\ComponentNotFoundException + */ + private function loadComponents() + { + // Determine components + $components = array(); + if(property_exists($this, 'components')) { + $components = $this->components; + } + if(!is_array($components)) { + $components = array($components); + } + // Components of parent classes + $parent = $this; + while($parent = get_parent_class($parent)) + { + $properties = get_class_vars($parent); + if(array_key_exists('components', $properties)) { + $components = array_merge($components, $properties['components']); + } + } + + // Load components + foreach($components as &$component) + { + // Load class + Component::load($component); + + // Construct component + $componentName = ucfirst(strtolower($component)); + $this->$componentName = Component::factory($component); + } + } + + + /** + * Load the Models of this Controller. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + */ + protected 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); + } + // Models of parent classes + $parent = $this; + while($parent = get_parent_class($parent)) + { + $properties = get_class_vars($parent); + if(array_key_exists('models', $properties)) { + $models = array_merge($models, $properties['models']); + } + } + $models = array_unique($models); + + // Load Models + foreach($models as &$model) + { + try { + // Load class + Model::load($model); + + // Construct Model + $modelName = ucfirst(strtolower($model)); + $this->$modelName = 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 \nre\exceptions\ViewNotFoundException + * @param string $layoutName Name of the current Layout + * @param string $action Current Action + */ + protected function loadView($layoutName, $action) + { + // Check Layout name + if(is_null($layoutName)) { + return; + } + + // Determine controller name + $controllerName = \nre\core\ClassLoader::getClassName(get_class($this)); + + + // Load view + $isToplevel = is_subclass_of($this->agent, '\nre\agents\ToplevelAgent'); + $this->view = View::loadAndFactory($layoutName, $controllerName, $action, $isToplevel); + } + + } + +?> diff --git a/core/Driver.inc b/core/Driver.inc new file mode 100644 index 00000000..ac2fa050 --- /dev/null +++ b/core/Driver.inc @@ -0,0 +1,97 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Driver. + * + * @author coderkun + */ + abstract class Driver + { + + + + + /** + * Load the class of a Driver. + * + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\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(\nre\exceptions\ClassNotValidException $e) { + throw new \nre\exceptions\DriverNotValidException($e->getClassName()); + } + catch(\nre\exceptions\ClassNotFoundException $e) { + throw new \nre\exceptions\DriverNotFoundException($e->getClassName()); + } + } + + + /** + * Instantiate a Driver (Factory Pattern). + * + * @param string $driverName Name of the Driver to instantiate + * @param array $config Configuration settings + */ + public static function factory($driverName, $config) + { + // Determine full classname + $className = self::getClassName($driverName); + + + // Construct and return Driver + return $className::singleton($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 = ClassLoader::concatClassNames($driverName, ClassLoader::stripNamespace(get_class())); + + + return "\\nre\\drivers\\$className"; + } + + + + + /** + * Construct a new Driver. + */ + protected function __construct() + { + } + + } + +?> diff --git a/core/Exception.inc b/core/Exception.inc new file mode 100644 index 00000000..21ed842b --- /dev/null +++ b/core/Exception.inc @@ -0,0 +1,65 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Exception class. + * + * @author coderkun + */ + class Exception extends \Exception + { + + + + + /** + * Construct a new exception. + * + * @param string $message Error message + * @param int $code Error code + * @param string $name Name to insert + */ + function __construct($message, $code, $name=null) + { + parent::__construct( + $this->concat( + $message, + $name + ), + $code + ); + } + + + + + /** + * Insert the name in a message + * + * @param string $message Error message + * @param string $name Name to insert + */ + private function concat($message, $name) + { + if(is_null($name)) { + return $message; + } + + + return "$message: $name"; + } + + } + +?> diff --git a/core/Linker.inc b/core/Linker.inc new file mode 100644 index 00000000..68c1902f --- /dev/null +++ b/core/Linker.inc @@ -0,0 +1,313 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class to create web links based on the current request. + * + * @author coderkun + */ + class Linker + { + /** + * Current request + * + * @var Request + */ + private $request; + + + + + /** + * Construct a new linker. + * + * @param Request $request Current request + */ + function __construct(\nre\requests\WebRequest $request) + { + $this->request = $request; + } + + + + + /** + * Mask parameters to be used in an URL. + * + * @param string $param1 First parameter + * @return string Masked parameters as string + */ + public static function createLinkParam($param1) + { + return implode( + \nre\configs\CoreConfig::$classes['linker']['url']['delimiter'], + call_user_func_array( + '\nre\core\Linker::createLinkParams', + func_get_args() + ) + ); + } + + + /** + * Mask parameters to be used in an URL. + * + * @param string $param1 First parameter + * @return string Masked parameters as array + */ + public static function createLinkParams($param1) + { + // Parameters + $linkParams = array(); + $params = func_get_args(); + + foreach($params as $param) + { + // Delete critical signs + $specials = array('/', '?', '&', '#'); + foreach($specials as &$special) { + $param = str_replace($special, '', $param); + } + + // Process parameter + $param = str_replace( + ' ', + \nre\configs\CoreConfig::$classes['linker']['url']['delimiter'], + substr( + $param, + 0, + \nre\configs\CoreConfig::$classes['linker']['url']['length'] + ) + ); + + // Encode parameter + $linkParams[] = $param; + } + + + // Return link parameters + return $linkParams; + } + + + + + /** + * 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_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) + ) + ); + } + + // Encode parameters + $params = array_map('rawurlencode', $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 string $anchor Anchor on target + * @param bool $absolute Create absolute link + * @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, 'intermediate'))) !== false) { + $ppos[] = $p; + } + $prefix = substr($uri, 0, min($ppos)); + + // Create absolute URL + if($absolute) { + $prefix = "http://$server/".trim($prefix, '/'); + } + + // Put URL together + $url = rtrim($prefix, '/').'/'.ltrim($url, '/'); + + + // Return URL + return $url; + } + + } + +?> diff --git a/core/Logger.inc b/core/Logger.inc new file mode 100644 index 00000000..0ea34757 --- /dev/null +++ b/core/Logger.inc @@ -0,0 +1,143 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class to log messages to different targets. + * + * @author coderkun + */ + class Logger + { + /** + * Log mode: Detect automatic + * + * @var int + */ + const LOGMODE_AUTO = 0; + /** + * Log mode: Print to screen + * + * @var int + */ + const LOGMODE_SCREEN = 1; + /** + * Log mode: Use PHP-logging mechanism + * + * @var int + */ + const LOGMODE_PHP = 2; + + /** + * Do not auto-log to screen + * + * @var boolean + */ + private $autoLogToScreenDisabled = false; + + + + + /** + * 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); + } + } + + + /** + * Disable logging to screen when the log mode is automatically + * detected. + */ + public function disableAutoLogToScreen() + { + $this->autoLogToScreenDisabled = true; + } + + + + /** + * Print a message to screen. + * + * @param string $message Message to print + */ + private function logToScreen($message) + { + echo "$message
\n"; + } + + + /** + * Log a message by using PHP-logging mechanism. + * + * @param string $message Message to log + */ + private function logToPhp($message) + { + error_log($message, 0); + } + + + /** + * Detect log mode automatically by distinguishing between + * production and test environment. + * + * @return int Automatically detected log mode + */ + private function getAutoLogMode() + { + return ($this->isLocalhost() && !$this->autoLogToScreenDisabled) ? self::LOGMODE_SCREEN : self::LOGMODE_PHP; + } + + + /** + * Detect if the server is running as localhost without domain. + * + * @return boolean Wheather server is running as localhost or not + */ + private function isLocalhost() + { + return ($_SERVER['SERVER_ADDR'] == '127.0.0.1' || $_SERVER['SERVER_ADDR'] = '::1'); + } + + } + +?> diff --git a/core/Model.inc b/core/Model.inc new file mode 100644 index 00000000..0ede5369 --- /dev/null +++ b/core/Model.inc @@ -0,0 +1,141 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Abstract class for implementing a Model. + * + * @author coderkun + */ + abstract class Model + { + + + + + /** + * Load the class of a Model. + * + * @throws \nre\exceptions\ModelNotFoundException + * @throws \nre\exceptions\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 = ClassLoader::concatClassNames($modelName, ClassLoader::stripNamespace(get_class())); + + + return \nre\configs\AppConfig::$app['namespace']."models\\$className"; + } + + + + + /** + * Construct a new Model. + * + * TODO Catch exception + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\ModelNotFoundException + */ + protected function __construct() + { + // Load Models + $this->loadModels(); + } + + + + + /** + * Load the Models of this Model. + * + * @throws \nre\exceptions\DatamodelException + * @throws \nre\exceptions\DriverNotFoundException + * @throws \nre\exceptions\DriverNotValidException + * @throws \nre\exceptions\ModelNotValidException + * @throws \nre\exceptions\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 + $modelName = ucfirst(strtolower($model)); + $this->$modelName = Model::factory($model); + } + } + + } + +?> diff --git a/core/Request.inc b/core/Request.inc new file mode 100644 index 00000000..efd9c834 --- /dev/null +++ b/core/Request.inc @@ -0,0 +1,64 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Base class to represent a request. + * + * @author coderkun + */ + class Request + { + /** + * Passed parameters + * + * @var array + */ + protected $params = array(); + + + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + // Return parameter + if(count($this->params) > $index) { + return $this->params[$index]; + } + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameter values + */ + public function getParams($offset=0) + { + return array_slice($this->params, $offset); + } + + } + +?> diff --git a/core/Response.inc b/core/Response.inc new file mode 100644 index 00000000..e273cba4 --- /dev/null +++ b/core/Response.inc @@ -0,0 +1,158 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Base class to represent a response. + * + * @author coderkun + */ + class Response + { + /** + * Applied parameters + * + * @var array + */ + protected $params = array(); + /** + * Generated output + * + * @var string + */ + private $output = ''; + /** + * Abort futher execution + * + * @var bool + */ + private $exit = false; + + + + + /** + * Add a parameter. + * + * @param mixed $value Value of parameter + */ + public function addParam($value) + { + $this->params[] = $value; + } + + + /** + * Add multiple parameters. + * + * @param mixed $value1 Value of first parameter + * @param mixed … Values of further parameters + */ + public function addParams($value1) + { + $this->params = array_merge( + $this->params, + func_get_args() + ); + } + + + /** + * Delete all stored parameters (from offset on). + * + * @param int $offset Offset-index + */ + public function clearParams($offset=0) + { + $this->params = array_slice($this->params, 0, $offset); + } + + + /** + * Get a parameter. + * + * @param int $index Index of parameter + * @param string $defaultIndex Index of default configuration value for this parameter + * @return string Value of parameter + */ + public function getParam($index, $defaultIndex=null) + { + // Return parameter + if(count($this->params) > $index) { + return $this->params[$index]; + } + + + // Return default value + return \nre\core\Config::getDefault($defaultIndex); + } + + + /** + * Get all parameters from index on. + * + * @param int $offset Offset-index + * @return array Parameter values + */ + public function getParams($offset=0) + { + return array_slice($this->params, $offset); + } + + + /** + * Set output. + * + * @param string $output Generated output + */ + public function setOutput($output) + { + $this->output = $output; + } + + + /** + * Get generated output. + * + * @return string Generated output + */ + public function getOutput() + { + return $this->output; + } + + + /** + * Set exit-state. + * + * @param bool $exit Abort further execution + */ + public function setExit($exit=true) + { + $this->exit = $exit; + } + + + /** + * Get exit-state. + * + * @return bool Abort further execution + */ + public function getExit() + { + return $this->exit; + } + + } + +?> diff --git a/core/View.inc b/core/View.inc new file mode 100644 index 00000000..386d37f8 --- /dev/null +++ b/core/View.inc @@ -0,0 +1,124 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * View. + * + * Class to encapsulate a template file and to provide rendering methods. + * + * @author coderkun + */ + class View + { + /** + * Template filename + * + * @var string + */ + protected $templateFilename; + + + + + /** + * Load and instantiate the View of an Agent. + * + * @throws \nre\exceptions\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 \nre\exceptions\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 + */ + protected 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) != strtolower($layoutName) || !$isToplevel) { + $fileName .= strtolower($agentName).DS.strtolower($action); + } + else { + $fileName .= strtolower($layoutName); + } + // File extension + $fileName .= \nre\configs\CoreConfig::getFileExt('views'); + + + // Check template file + if(!file_exists($fileName)) { + throw new \nre\exceptions\ViewNotFoundException($fileName); + } + + // Save filename + $this->templateFilename = $fileName; + } + + + + + /** + * Generate output + * + * @param array $data Data to have available in the template file + */ + public function render($data) + { + // Extract data + if(!is_null($data)) { + extract($data, EXTR_SKIP); + } + + // Buffer output + ob_start(); + + // Include template + include($this->templateFilename); + + + // Return buffered output + return ob_get_clean(); + } + + + /** + * Get template filename. + * + * @return string Template filename + */ + public function getTemplateFilename() + { + return $this->templateFilename; + } + + } + +?> diff --git a/core/WebUtils.inc b/core/WebUtils.inc new file mode 100644 index 00000000..ed726576 --- /dev/null +++ b/core/WebUtils.inc @@ -0,0 +1,75 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\core; + + + /** + * Class that holds several web-specific methods and properties. + * + * @author coderkun + */ + class WebUtils + { + /** + * HTTP-statuscode 403: Forbidden + * + * @var int + */ + const HTTP_FORBIDDEN = 403; + /** + * 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', + 403 => 'Forbidden', + 404 => 'Not Found', + 503 => 'Service Unavailable' + ); + + + + + /** + * Get the HTTP-header of a HTTP-statuscode + * + * @param int $httpStatusCode HTTP-statuscode + * @return string HTTP-header of HTTP-statuscode + */ + public static function getHttpHeader($httpStatusCode) + { + if(!array_key_exists($httpStatusCode, self::$httpStrings)) { + $httpStatusCode = 200; + } + + + return sprintf("HTTP/1.1 %d %s\n", $httpStatusCode, self::$httpStrings[$httpStatusCode]); + } + + } + +?> diff --git a/db/create.sql b/db/create.sql new file mode 100644 index 00000000..57551f36 --- /dev/null +++ b/db/create.sql @@ -0,0 +1,1956 @@ +-- MySQL dump 10.15 Distrib 10.0.17-MariaDB, for Linux (x86_64) +-- +-- Host: localhost Database: z +-- ------------------------------------------------------ +-- Server version 10.0.17-MariaDB-log + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `achievementconditions` +-- + +DROP TABLE IF EXISTS `achievementconditions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `condition` varchar(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievementconditions_achievement` +-- + +DROP TABLE IF EXISTS `achievementconditions_achievement`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions_achievement` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `achievement_id` int(11) NOT NULL, + `field` varchar(128) NOT NULL, + `count` tinyint(1) NOT NULL DEFAULT '0', + `value` int(11) NOT NULL, + `meta_achievement_id` int(11) DEFAULT NULL, + `groupby` varchar(128) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `achievement_id` (`achievement_id`), + KEY `meta_achievement_id` (`meta_achievement_id`), + CONSTRAINT `achievementconditions_achievement_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievementconditions_achievement_ibfk_2` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `achievementconditions_achievement_ibfk_3` FOREIGN KEY (`meta_achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievementconditions_character` +-- + +DROP TABLE IF EXISTS `achievementconditions_character`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions_character` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `achievement_id` int(11) NOT NULL, + `field` varchar(128) NOT NULL, + `value` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `achievement_id` (`achievement_id`), + CONSTRAINT `achievementconditions_character_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievementconditions_character_ibfk_2` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievementconditions_date` +-- + +DROP TABLE IF EXISTS `achievementconditions_date`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions_date` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `achievement_id` int(11) NOT NULL, + `select` varchar(512) NOT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `achievement_id` (`achievement_id`), + CONSTRAINT `achievementconditions_date_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievementconditions_date_ibfk_2` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievementconditions_quest` +-- + +DROP TABLE IF EXISTS `achievementconditions_quest`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions_quest` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `achievement_id` int(11) NOT NULL, + `field` varchar(128) NOT NULL, + `count` tinyint(1) NOT NULL DEFAULT '0', + `value` int(11) NOT NULL, + `quest_id` int(11) DEFAULT NULL, + `status` tinyint(3) unsigned DEFAULT NULL, + `groupby` varchar(128) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `achievement_id` (`achievement_id`), + KEY `quest_id` (`quest_id`), + CONSTRAINT `achievementconditions_quest_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievementconditions_quest_ibfk_2` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `achievementconditions_quest_ibfk_3` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievements` +-- + +DROP TABLE IF EXISTS `achievements`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievements` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `achievementcondition_id` int(11) NOT NULL, + `pos` int(10) unsigned NOT NULL DEFAULT '1', + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `description` text NOT NULL, + `progress` tinyint(1) NOT NULL, + `hidden` tinyint(1) NOT NULL DEFAULT '0', + `only_once` tinyint(1) NOT NULL DEFAULT '0', + `all_conditions` tinyint(1) NOT NULL DEFAULT '1', + `deadline` datetime DEFAULT NULL, + `unachieved_achievementsmedia_id` int(11) DEFAULT NULL, + `achieved_achievementsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `url` (`seminary_id`,`url`), + UNIQUE KEY `pos` (`seminary_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + KEY `achieved_seminarymedia_id` (`achieved_achievementsmedia_id`), + KEY `unachieved_seminarymedia_id` (`unachieved_achievementsmedia_id`), + KEY `achievementcondition_id` (`achievementcondition_id`), + CONSTRAINT `achievements_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievements_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `achievements_ibfk_3` FOREIGN KEY (`unachieved_achievementsmedia_id`) REFERENCES `achievementsmedia` (`seminarymedia_id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `achievements_ibfk_4` FOREIGN KEY (`achieved_achievementsmedia_id`) REFERENCES `achievementsmedia` (`seminarymedia_id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `achievements_ibfk_5` FOREIGN KEY (`achievementcondition_id`) REFERENCES `achievementconditions` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievements_characters` +-- + +DROP TABLE IF EXISTS `achievements_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievements_characters` ( + `achievement_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`achievement_id`,`character_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `achievements_characters_ibfk_1` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `achievements_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `achievementsmedia` +-- + +DROP TABLE IF EXISTS `achievementsmedia`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementsmedia` ( + `seminarymedia_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`seminarymedia_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `achievementsmedia_ibfk_1` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `achievementsmedia_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `avatarpictures` +-- + +DROP TABLE IF EXISTS `avatarpictures`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `avatarpictures` ( + `seminarymedia_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`seminarymedia_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `avatarpictures_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `avatarpictures_ibfk_3` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `avatars` +-- + +DROP TABLE IF EXISTS `avatars`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `avatars` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `charactertype_id` int(11) NOT NULL, + `xplevel_id` int(11) NOT NULL, + `avatarpicture_id` int(11) DEFAULT NULL, + `small_avatarpicture_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `charactertype_id_2` (`charactertype_id`,`xplevel_id`), + KEY `created_user_id` (`created_user_id`), + KEY `charactertype_id` (`charactertype_id`), + KEY `xplevel_id` (`xplevel_id`), + KEY `avatarpicture_id` (`avatarpicture_id`), + KEY `small_avatarpicture_id` (`small_avatarpicture_id`), + CONSTRAINT `avatars_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `avatars_ibfk_2` FOREIGN KEY (`charactertype_id`) REFERENCES `charactertypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `avatars_ibfk_3` FOREIGN KEY (`xplevel_id`) REFERENCES `xplevels` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `avatars_ibfk_4` FOREIGN KEY (`avatarpicture_id`) REFERENCES `avatarpictures` (`seminarymedia_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `avatars_ibfk_5` FOREIGN KEY (`small_avatarpicture_id`) REFERENCES `avatarpictures` (`seminarymedia_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `cache_charactergroups` +-- + +DROP TABLE IF EXISTS `cache_charactergroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cache_charactergroups` ( + `charactergroup_id` int(11) NOT NULL, + `xps` int(10) unsigned NOT NULL, + PRIMARY KEY (`charactergroup_id`), + CONSTRAINT `cache_charactergroups_ibfk_1` FOREIGN KEY (`charactergroup_id`) REFERENCES `charactergroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_cache_charactergroups_insert` AFTER INSERT ON `cache_charactergroups` FOR EACH ROW BEGIN + CALL update_cache_characters_charactergroup(NEW.charactergroup_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_cache_charactergroups_update` AFTER UPDATE ON `cache_charactergroups` FOR EACH ROW BEGIN + CALL update_cache_characters_charactergroup(NEW.charactergroup_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `cache_characters` +-- + +DROP TABLE IF EXISTS `cache_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `cache_characters` ( + `character_id` int(11) NOT NULL, + `xps` int(10) unsigned NOT NULL, + `quest_xps` int(10) unsigned NOT NULL, + `xplevel_id` int(11) NOT NULL, + `avatar_id` int(11) NOT NULL, + PRIMARY KEY (`character_id`), + KEY `xplevel_id` (`xplevel_id`), + KEY `avatar_id` (`avatar_id`), + CONSTRAINT `cache_characters_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `cache_characters_ibfk_2` FOREIGN KEY (`xplevel_id`) REFERENCES `xplevels` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `cache_characters_ibfk_3` FOREIGN KEY (`avatar_id`) REFERENCES `avatars` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `charactergroups` +-- + +DROP TABLE IF EXISTS `charactergroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `charactergroupsgroup_id` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(128) NOT NULL, + `motto` varchar(255) NOT NULL, + `charactergroupsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `charactergroupsgroup_id_2` (`charactergroupsgroup_id`,`name`), + UNIQUE KEY `charactergroupsgroup_id_3` (`charactergroupsgroup_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `charactergroupsgroup_id` (`charactergroupsgroup_id`), + KEY `charactergroupsmedia_id` (`charactergroupsmedia_id`), + CONSTRAINT `charactergroups_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `charactergroups_ibfk_3` FOREIGN KEY (`charactergroupsgroup_id`) REFERENCES `charactergroupsgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroups_ibfk_4` FOREIGN KEY (`charactergroupsmedia_id`) REFERENCES `charactergroupsmedia` (`seminarymedia_id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Charaktergruppen'; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_charactergroups_insert` AFTER INSERT ON `charactergroups` FOR EACH ROW BEGIN + CALL update_cache_charactergroups(NEW.id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `charactergroupsgroups` +-- + +DROP TABLE IF EXISTS `charactergroupsgroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsgroups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `preferred` tinyint(1) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `seminary_id_3` (`seminary_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + KEY `seminary_id_2` (`seminary_id`), + CONSTRAINT `charactergroupsgroups_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `charactergroupsgroups_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `charactergroupsmedia` +-- + +DROP TABLE IF EXISTS `charactergroupsmedia`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsmedia` ( + `seminarymedia_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`seminarymedia_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `charactergroupsmedia_ibfk_1` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsmedia_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `charactergroupsquests` +-- + +DROP TABLE IF EXISTS `charactergroupsquests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsquests` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `charactergroupsgroup_id` int(11) NOT NULL, + `questgroups_id` int(11) NOT NULL, + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `description` text NOT NULL, + `xps` int(10) unsigned NOT NULL, + `rules` text NOT NULL, + `won_text` text NOT NULL, + `lost_text` text NOT NULL, + `questsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `charactergroupsgroup_id_2` (`charactergroupsgroup_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `charactergroupsgroup_id` (`charactergroupsgroup_id`), + KEY `questgroups_id` (`questgroups_id`), + KEY `questsmedia_id` (`questsmedia_id`), + CONSTRAINT `charactergroupsquests_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `charactergroupsquests_ibfk_2` FOREIGN KEY (`charactergroupsgroup_id`) REFERENCES `charactergroupsgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsquests_ibfk_3` FOREIGN KEY (`questgroups_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsquests_ibfk_4` FOREIGN KEY (`questsmedia_id`) REFERENCES `questsmedia` (`media_id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_charactergroupsquests_update` AFTER UPDATE ON `charactergroupsquests` FOR EACH ROW BEGIN + CALL update_cache_charactergroups_charactergroupsquest(NEW.id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `charactergroupsquests_groups` +-- + +DROP TABLE IF EXISTS `charactergroupsquests_groups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsquests_groups` ( + `charactergroupsquest_id` int(11) NOT NULL, + `charactergroup_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `xps_factor` float NOT NULL, + PRIMARY KEY (`charactergroupsquest_id`,`charactergroup_id`), + KEY `charactergroup_id` (`charactergroup_id`), + CONSTRAINT `charactergroupsquests_groups_ibfk_1` FOREIGN KEY (`charactergroupsquest_id`) REFERENCES `charactergroupsquests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsquests_groups_ibfk_2` FOREIGN KEY (`charactergroup_id`) REFERENCES `charactergroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_charactergroupsquests_groups_insert` AFTER INSERT ON `charactergroupsquests_groups` FOR EACH ROW BEGIN + CALL update_cache_charactergroups(NEW.charactergroup_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_charactergroupsquests_groups_update` AFTER UPDATE ON `charactergroupsquests_groups` FOR EACH ROW BEGIN + CALL update_cache_charactergroups(OLD.charactergroup_id); + CALL update_cache_charactergroups(NEW.charactergroup_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_charactergroupsquests_groups_delete` AFTER DELETE ON `charactergroupsquests_groups` FOR EACH ROW BEGIN + CALL update_cache_charactergroups(OLD.charactergroup_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `charactergroupsquests_seminaryuploads` +-- + +DROP TABLE IF EXISTS `charactergroupsquests_seminaryuploads`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsquests_seminaryuploads` ( + `seminaryupload_id` int(11) NOT NULL, + `charactergroupsquest_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`seminaryupload_id`), + KEY `charactergroupsquest_id` (`charactergroupsquest_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `charactergroupsquests_seminaryuploads_ibfk_1` FOREIGN KEY (`seminaryupload_id`) REFERENCES `seminaryuploads` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsquests_seminaryuploads_ibfk_2` FOREIGN KEY (`charactergroupsquest_id`) REFERENCES `charactergroupsquests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsquests_seminaryuploads_ibfk_3` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `characterroles` +-- + +DROP TABLE IF EXISTS `characterroles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `characterroles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(32) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `characters` +-- + +DROP TABLE IF EXISTS `characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `characters` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` int(11) NOT NULL, + `charactertype_id` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), + KEY `charactertype_id` (`charactertype_id`), + KEY `user_id` (`user_id`), + CONSTRAINT `characters_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `characters_ibfk_2` FOREIGN KEY (`charactertype_id`) REFERENCES `charactertypes` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Charaktere'; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_insert` AFTER INSERT ON `characters` FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `characters_charactergroups` +-- + +DROP TABLE IF EXISTS `characters_charactergroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `characters_charactergroups` ( + `character_id` int(11) NOT NULL, + `charactergroup_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`character_id`,`charactergroup_id`), + KEY `charactergroup_id` (`charactergroup_id`), + CONSTRAINT `characters_charactergroups_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `characters_charactergroups_ibfk_2` FOREIGN KEY (`charactergroup_id`) REFERENCES `charactergroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_charactergroups_insert` AFTER INSERT ON `characters_charactergroups` FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_charactergroups_update` AFTER UPDATE ON `characters_charactergroups` FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); + CALL update_cache_characters(NEW.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_characters_charactergroups_delete` AFTER DELETE ON `characters_charactergroups` FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `characters_characterroles` +-- + +DROP TABLE IF EXISTS `characters_characterroles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `characters_characterroles` ( + `character_id` int(11) NOT NULL, + `characterrole_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`character_id`,`characterrole_id`), + KEY `userseminaryrole_id` (`characterrole_id`), + CONSTRAINT `characters_characterroles_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `characters_characterroles_ibfk_2` FOREIGN KEY (`characterrole_id`) REFERENCES `characterroles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `characters_seminarycharacterfields` +-- + +DROP TABLE IF EXISTS `characters_seminarycharacterfields`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `characters_seminarycharacterfields` ( + `character_id` int(11) NOT NULL, + `seminarycharacterfield_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `value` varchar(256) NOT NULL, + PRIMARY KEY (`character_id`,`seminarycharacterfield_id`), + KEY `seminarycharacterfield_id` (`seminarycharacterfield_id`), + CONSTRAINT `characters_seminarycharacterfields_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `characters_seminarycharacterfields_ibfk_2` FOREIGN KEY (`seminarycharacterfield_id`) REFERENCES `seminarycharacterfields` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `charactertypes` +-- + +DROP TABLE IF EXISTS `charactertypes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactertypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `name` varchar(128) NOT NULL, + `url` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`,`seminary_id`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `charactertypes_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `charactertypes_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Charaktertypen'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `maps` +-- + +DROP TABLE IF EXISTS `maps`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `maps` ( + `seminary_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `seminarymedia_id` int(11) NOT NULL, + `width` int(10) unsigned NOT NULL, + `height` int(10) unsigned NOT NULL, + PRIMARY KEY (`seminary_id`), + KEY `seminarymedia_id` (`seminarymedia_id`), + CONSTRAINT `maps_ibfk_1` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`), + CONSTRAINT `maps_ibfk_2` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `media` +-- + +DROP TABLE IF EXISTS `media`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `media` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `description` varchar(128) NOT NULL, + `mimetype` varchar(32) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `seminary_id_2` (`name`), + UNIQUE KEY `seminary_id_3` (`url`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `media_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroups` +-- + +DROP TABLE IF EXISTS `questgroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `title` varchar(128) NOT NULL, + `url` varchar(128) NOT NULL, + `questgroupspicture_id` int(11) DEFAULT NULL, + `achievable_xps` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `title` (`seminary_id`,`title`), + KEY `created_user_id` (`created_user_id`), + KEY `questgroupspicture_id` (`questgroupspicture_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `questgroups_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questgroups_ibfk_4` FOREIGN KEY (`questgroupspicture_id`) REFERENCES `questgroupspictures` (`media_id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `questgroups_ibfk_5` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Aufgabengruppen'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroups_characters` +-- + +DROP TABLE IF EXISTS `questgroups_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroups_characters` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questgroup_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `status` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `questgroup_id` (`questgroup_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questgroups_characters_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroups_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroups_questgroupshierarchy` +-- + +DROP TABLE IF EXISTS `questgroups_questgroupshierarchy`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroups_questgroupshierarchy` ( + `questgroup_id` int(11) NOT NULL, + `questgroupshierarchy_id` int(11) NOT NULL, + `parent_questgroup_id` int(11) DEFAULT NULL, + `pos` int(10) unsigned NOT NULL, + PRIMARY KEY (`questgroup_id`), + UNIQUE KEY `pos` (`parent_questgroup_id`,`pos`), + KEY `parent_questgoup_id` (`parent_questgroup_id`), + KEY `questgroupshierarchy_id` (`questgroupshierarchy_id`), + CONSTRAINT `questgroups_questgroupshierarchy_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroups_questgroupshierarchy_ibfk_2` FOREIGN KEY (`questgroupshierarchy_id`) REFERENCES `questgroupshierarchy` (`id`), + CONSTRAINT `questgroups_questgroupshierarchy_ibfk_3` FOREIGN KEY (`parent_questgroup_id`) REFERENCES `questgroups` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroups_questtexts` +-- + +DROP TABLE IF EXISTS `questgroups_questtexts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroups_questtexts` ( + `questgroup_id` int(11) NOT NULL, + `questtext_id` int(11) NOT NULL, + `entry_text` text NOT NULL, + PRIMARY KEY (`questgroup_id`,`questtext_id`), + KEY `questtext_id` (`questtext_id`), + CONSTRAINT `questgroups_questtexts_ibfk_1` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`), + CONSTRAINT `questgroups_questtexts_ibfk_2` FOREIGN KEY (`questtext_id`) REFERENCES `questtexts` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroupshierarchy` +-- + +DROP TABLE IF EXISTS `questgroupshierarchy`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroupshierarchy` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `parent_questgroupshierarchy_id` int(11) DEFAULT NULL, + `pos` int(10) unsigned NOT NULL, + `title_singular` varchar(128) NOT NULL, + `title_plural` varchar(128) NOT NULL, + `url` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `pos` (`parent_questgroupshierarchy_id`,`pos`), + UNIQUE KEY `url` (`seminary_id`,`parent_questgroupshierarchy_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + KEY `parent_questhierarchy_id` (`parent_questgroupshierarchy_id`), + CONSTRAINT `questgroupshierarchy_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questgroupshierarchy_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroupshierarchy_ibfk_3` FOREIGN KEY (`parent_questgroupshierarchy_id`) REFERENCES `questgroupshierarchy` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Aufgabengruppenhierarchie'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgroupspictures` +-- + +DROP TABLE IF EXISTS `questgroupspictures`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgroupspictures` ( + `media_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`media_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `questgroupspictures_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES `seminarymedia` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questgroupspictures_ibfk_3` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questgrouptexts` +-- + +DROP TABLE IF EXISTS `questgrouptexts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questgrouptexts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questgroup_id` int(11) NOT NULL, + `pos` int(11) NOT NULL DEFAULT '1', + `text` text NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questgroup_id_2` (`questgroup_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `questgroup_id` (`questgroup_id`), + CONSTRAINT `questgrouptexts_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questgrouptexts_ibfk_2` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quests` +-- + +DROP TABLE IF EXISTS `quests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `quests` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questgroup_id` int(11) NOT NULL, + `questtype_id` int(11) NOT NULL, + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `xps` int(11) unsigned NOT NULL, + `entry_text` text, + `wrong_text` text NOT NULL, + `task` text NOT NULL, + `questsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questgroup_id_url` (`questgroup_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `questtype_id` (`questtype_id`), + KEY `questmedia_id` (`questsmedia_id`), + KEY `questgroup_id` (`questgroup_id`), + CONSTRAINT `quests_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `quests_ibfk_2` FOREIGN KEY (`questtype_id`) REFERENCES `questtypes` (`id`), + CONSTRAINT `quests_ibfk_4` FOREIGN KEY (`questgroup_id`) REFERENCES `questgroups` (`id`), + CONSTRAINT `quests_ibfk_5` FOREIGN KEY (`questsmedia_id`) REFERENCES `questsmedia` (`media_id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_quests_update` AFTER UPDATE ON `quests` FOR EACH ROW BEGIN + CALL update_cache_characters_quest(NEW.id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `quests_characters` +-- + +DROP TABLE IF EXISTS `quests_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `quests_characters` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `quest_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `status` tinyint(4) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `quest_id` (`quest_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `quests_characters_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `quests_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_quests_characters_insert` AFTER INSERT ON `quests_characters` FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_quests_characters_update` AFTER UPDATE ON `quests_characters` FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); + CALL update_cache_characters(NEW.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb4 */ ; +/*!50003 SET character_set_results = utf8mb4 */ ; +/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = '' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`z`@`%`*/ /*!50003 TRIGGER `update_cache_quests_characters_delete` AFTER DELETE ON `quests_characters` FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); +END */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; + +-- +-- Table structure for table `quests_previousquests` +-- + +DROP TABLE IF EXISTS `quests_previousquests`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `quests_previousquests` ( + `quest_id` int(11) NOT NULL, + `previous_quest_id` int(11) NOT NULL, + PRIMARY KEY (`quest_id`,`previous_quest_id`), + KEY `previous_quest_id` (`previous_quest_id`), + CONSTRAINT `quests_previousquests_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `quests_previousquests_ibfk_2` FOREIGN KEY (`previous_quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Vorherige Aufgaben'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `quests_questsubtopics` +-- + +DROP TABLE IF EXISTS `quests_questsubtopics`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `quests_questsubtopics` ( + `quest_id` int(11) NOT NULL, + `questsubtopic_id` int(11) NOT NULL, + PRIMARY KEY (`quest_id`,`questsubtopic_id`), + KEY `questsubtopic_id` (`questsubtopic_id`), + CONSTRAINT `quests_questsubtopics_ibfk_3` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `quests_questsubtopics_ibfk_4` FOREIGN KEY (`questsubtopic_id`) REFERENCES `questsubtopics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questsmedia` +-- + +DROP TABLE IF EXISTS `questsmedia`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questsmedia` ( + `media_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`media_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `questsmedia_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES `seminarymedia` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questsmedia_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questsubtopics` +-- + +DROP TABLE IF EXISTS `questsubtopics`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questsubtopics` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questtopic_id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `url` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `title` (`title`,`questtopic_id`), + KEY `created_user_id` (`created_user_id`), + KEY `questtopic_id` (`questtopic_id`), + CONSTRAINT `questsubtopics_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questsubtopics_ibfk_2` FOREIGN KEY (`questtopic_id`) REFERENCES `questtopics` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Aufgabenbereiche'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtexts` +-- + +DROP TABLE IF EXISTS `questtexts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtexts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `quest_id` int(11) NOT NULL, + `questtexttype_id` int(11) NOT NULL, + `pos` int(11) NOT NULL DEFAULT '1', + `text` text NOT NULL, + `out_text` text NOT NULL, + `abort_text` text NOT NULL, + `questsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `quest_id_2` (`quest_id`,`questtexttype_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `quest_id` (`quest_id`), + KEY `questtexttype_id` (`questtexttype_id`), + KEY `questsmedia_id` (`questsmedia_id`), + CONSTRAINT `questtexts_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtexts_ibfk_3` FOREIGN KEY (`questtexttype_id`) REFERENCES `questtexttypes` (`id`), + CONSTRAINT `questtexts_ibfk_4` FOREIGN KEY (`questsmedia_id`) REFERENCES `questsmedia` (`media_id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `questtexts_ibfk_5` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtexttypes` +-- + +DROP TABLE IF EXISTS `questtexttypes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtexttypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `type` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `type` (`type`), + UNIQUE KEY `url` (`url`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtopics` +-- + +DROP TABLE IF EXISTS `questtopics`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtopics` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `url` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `url` (`seminary_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `questtopics_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtopics_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Aufgabenbereiche'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes` +-- + +DROP TABLE IF EXISTS `questtypes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `classname` varchar(64) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `title` (`title`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_bossfight` +-- + +DROP TABLE IF EXISTS `questtypes_bossfight`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_bossfight` ( + `quest_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `bossname` varchar(64) NOT NULL, + `boss_seminarymedia_id` int(11) NOT NULL, + `lives_character` smallint(5) unsigned NOT NULL, + `lives_boss` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`quest_id`), + KEY `created_user_id` (`created_user_id`), + KEY `boss_seminarymedia_id` (`boss_seminarymedia_id`), + CONSTRAINT `questtypes_bossfight_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_bossfight_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_bossfight_ibfk_3` FOREIGN KEY (`boss_seminarymedia_id`) REFERENCES `seminarymedia` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_bossfight_stages` +-- + +DROP TABLE IF EXISTS `questtypes_bossfight_stages`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_bossfight_stages` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questtypes_bossfight_quest_id` int(11) NOT NULL, + `parent_stage_id` int(11) DEFAULT NULL, + `text` text NOT NULL, + `question` varchar(255) NOT NULL, + `livedrain_character` smallint(6) NOT NULL, + `livedrain_boss` smallint(6) NOT NULL, + PRIMARY KEY (`id`), + KEY `parent_stage_id` (`parent_stage_id`), + KEY `questtypes_bossfight_quest_id` (`questtypes_bossfight_quest_id`), + CONSTRAINT `questtypes_bossfight_stages_ibfk_1` FOREIGN KEY (`questtypes_bossfight_quest_id`) REFERENCES `questtypes_bossfight` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_bossfight_stages_ibfk_2` FOREIGN KEY (`parent_stage_id`) REFERENCES `questtypes_bossfight_stages` (`id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_bossfight_stages_characters` +-- + +DROP TABLE IF EXISTS `questtypes_bossfight_stages_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_bossfight_stages_characters` ( + `questtypes_bossfight_stage_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`questtypes_bossfight_stage_id`,`character_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questtypes_bossfight_stages_characters_ibfk_1` FOREIGN KEY (`questtypes_bossfight_stage_id`) REFERENCES `questtypes_bossfight_stages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_bossfight_stages_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_choiceinput` +-- + +DROP TABLE IF EXISTS `questtypes_choiceinput`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_choiceinput` ( + `quest_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `text` text NOT NULL, + PRIMARY KEY (`quest_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `questtypes_choiceinput_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_choiceinput_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_choiceinput_choices` +-- + +DROP TABLE IF EXISTS `questtypes_choiceinput_choices`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_choiceinput_choices` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questtypes_choiceinput_list_id` int(11) NOT NULL, + `pos` int(10) unsigned NOT NULL DEFAULT '1', + `text` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questtypes_choiceinput_list_id` (`questtypes_choiceinput_list_id`,`pos`), + CONSTRAINT `questtypes_choiceinput_choices_ibfk_1` FOREIGN KEY (`questtypes_choiceinput_list_id`) REFERENCES `questtypes_choiceinput_lists` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_choiceinput_lists` +-- + +DROP TABLE IF EXISTS `questtypes_choiceinput_lists`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_choiceinput_lists` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questtypes_choiceinput_quest_id` int(11) NOT NULL, + `number` int(10) unsigned NOT NULL, + `questtypes_choiceinput_choice_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questtypes_textinput_quest_id` (`questtypes_choiceinput_quest_id`,`number`), + KEY `questtypes_choiceinput_choice_id` (`questtypes_choiceinput_choice_id`), + CONSTRAINT `questtypes_choiceinput_lists_ibfk_1` FOREIGN KEY (`questtypes_choiceinput_quest_id`) REFERENCES `questtypes_choiceinput` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_choiceinput_lists_ibfk_2` FOREIGN KEY (`questtypes_choiceinput_choice_id`) REFERENCES `questtypes_choiceinput_choices` (`id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_choiceinput_lists_characters` +-- + +DROP TABLE IF EXISTS `questtypes_choiceinput_lists_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_choiceinput_lists_characters` ( + `character_id` int(11) NOT NULL, + `questtypes_choiceinput_list_id` int(11) NOT NULL, + `questtypes_choiceinput_choice_id` int(11) DEFAULT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`character_id`,`questtypes_choiceinput_list_id`), + KEY `questtypes_choiceinput_choice_id` (`questtypes_choiceinput_choice_id`), + KEY `questtypes_choiceinput_list_id` (`questtypes_choiceinput_list_id`), + CONSTRAINT `questtypes_choiceinput_lists_characters_ibfk_1` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_choiceinput_lists_characters_ibfk_2` FOREIGN KEY (`questtypes_choiceinput_list_id`) REFERENCES `questtypes_choiceinput_lists` (`id`), + CONSTRAINT `questtypes_choiceinput_lists_characters_ibfk_3` FOREIGN KEY (`questtypes_choiceinput_choice_id`) REFERENCES `questtypes_choiceinput_choices` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_crossword_words` +-- + +DROP TABLE IF EXISTS `questtypes_crossword_words`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_crossword_words` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `quest_id` int(11) NOT NULL, + `question` text NOT NULL, + `word` varchar(64) NOT NULL, + `vertical` tinyint(1) NOT NULL, + `pos_x` int(10) unsigned NOT NULL, + `pos_y` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `quest_id_2` (`quest_id`,`vertical`,`pos_x`,`pos_y`), + KEY `quest_id` (`quest_id`), + CONSTRAINT `questtypes_crossword_words_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_crossword_words_characters` +-- + +DROP TABLE IF EXISTS `questtypes_crossword_words_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_crossword_words_characters` ( + `questtypes_crossword_word_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `answer` varchar(64) NOT NULL, + PRIMARY KEY (`questtypes_crossword_word_id`,`character_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questtypes_crossword_words_characters_ibfk_1` FOREIGN KEY (`questtypes_crossword_word_id`) REFERENCES `questtypes_crossword_words` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_crossword_words_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_dragndrop` +-- + +DROP TABLE IF EXISTS `questtypes_dragndrop`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_dragndrop` ( + `quest_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questmedia_id` int(11) NOT NULL, + `width` int(10) unsigned NOT NULL, + `height` int(10) unsigned NOT NULL, + PRIMARY KEY (`quest_id`), + KEY `questmedia_id` (`questmedia_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `questtypes_dragndrop_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_dragndrop_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_dragndrop_ibfk_3` FOREIGN KEY (`questmedia_id`) REFERENCES `questsmedia` (`media_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_dragndrop_drags` +-- + +DROP TABLE IF EXISTS `questtypes_dragndrop_drags`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_dragndrop_drags` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `questtypes_dragndrop_id` int(11) NOT NULL, + `questmedia_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `questtypes_dragndrop_id` (`questtypes_dragndrop_id`), + KEY `questmedia_id` (`questmedia_id`), + CONSTRAINT `questtypes_dragndrop_drags_ibfk_1` FOREIGN KEY (`questtypes_dragndrop_id`) REFERENCES `questtypes_dragndrop` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_dragndrop_drags_ibfk_2` FOREIGN KEY (`questmedia_id`) REFERENCES `questsmedia` (`media_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_dragndrop_drops` +-- + +DROP TABLE IF EXISTS `questtypes_dragndrop_drops`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_dragndrop_drops` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questtypes_dragndrop_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `top` int(11) NOT NULL, + `left` int(11) NOT NULL, + `width` int(10) unsigned NOT NULL, + `height` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `questtypes_dragndrop_id` (`questtypes_dragndrop_id`), + CONSTRAINT `questtypes_dragndrop_drops_ibfk_4` FOREIGN KEY (`questtypes_dragndrop_id`) REFERENCES `questtypes_dragndrop` (`quest_id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_dragndrop_drops_characters` +-- + +DROP TABLE IF EXISTS `questtypes_dragndrop_drops_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_dragndrop_drops_characters` ( + `questtypes_dragndrop_drop_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `questtypes_dragndrop_drag_id` int(11) NOT NULL, + PRIMARY KEY (`questtypes_dragndrop_drop_id`,`character_id`), + KEY `questtypes_dragndrop_drag_id` (`questtypes_dragndrop_drag_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questtypes_dragndrop_drops_characters_ibfk_1` FOREIGN KEY (`questtypes_dragndrop_drop_id`) REFERENCES `questtypes_dragndrop_drops` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_dragndrop_drops_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_dragndrop_drops_characters_ibfk_3` FOREIGN KEY (`questtypes_dragndrop_drag_id`) REFERENCES `questtypes_dragndrop_drags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_dragndrop_drops_drags` +-- + +DROP TABLE IF EXISTS `questtypes_dragndrop_drops_drags`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_dragndrop_drops_drags` ( + `questtypes_dragndrop_drop_id` int(11) NOT NULL, + `questtypes_dragndrop_drag_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + PRIMARY KEY (`questtypes_dragndrop_drop_id`,`questtypes_dragndrop_drag_id`), + KEY `created_user_id` (`created_user_id`), + KEY `questtypes_dragndrop_drag_id` (`questtypes_dragndrop_drag_id`), + CONSTRAINT `questtypes_dragndrop_drops_drags_ibfk_1` FOREIGN KEY (`questtypes_dragndrop_drop_id`) REFERENCES `questtypes_dragndrop_drops` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_dragndrop_drops_drags_ibfk_3` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_dragndrop_drops_drags_ibfk_4` FOREIGN KEY (`questtypes_dragndrop_drag_id`) REFERENCES `questtypes_dragndrop_drags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_multiplechoice` +-- + +DROP TABLE IF EXISTS `questtypes_multiplechoice`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_multiplechoice` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `quest_id` int(11) NOT NULL, + `pos` int(10) unsigned NOT NULL DEFAULT '1', + `question` text NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `quest_id_2` (`quest_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `quest_id` (`quest_id`), + CONSTRAINT `questtypes_multiplechoice_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_multiplechoice_ibfk_2` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_multiplechoice_answers` +-- + +DROP TABLE IF EXISTS `questtypes_multiplechoice_answers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_multiplechoice_answers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questtypes_multiplechoice_id` int(11) NOT NULL, + `pos` int(11) NOT NULL, + `answer` varchar(255) NOT NULL, + `tick` tinyint(1) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questtypes_multiplechoice_id_2` (`questtypes_multiplechoice_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `questtypes_multiplechoice_id` (`questtypes_multiplechoice_id`), + CONSTRAINT `questtypes_multiplechoice_answers_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_multiplechoice_answers_ibfk_2` FOREIGN KEY (`questtypes_multiplechoice_id`) REFERENCES `questtypes_multiplechoice` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_multiplechoice_characters` +-- + +DROP TABLE IF EXISTS `questtypes_multiplechoice_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_multiplechoice_characters` ( + `questtypes_multiplechoice_answer_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `ticked` tinyint(1) NOT NULL, + PRIMARY KEY (`questtypes_multiplechoice_answer_id`,`character_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questtypes_multiplechoice_characters_ibfk_1` FOREIGN KEY (`questtypes_multiplechoice_answer_id`) REFERENCES `questtypes_multiplechoice_answers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_multiplechoice_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_submit_characters` +-- + +DROP TABLE IF EXISTS `questtypes_submit_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_submit_characters` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `quest_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `upload_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `character_id` (`character_id`), + KEY `upload_id` (`upload_id`), + KEY `quest_id` (`quest_id`), + CONSTRAINT `questtypes_submit_characters_ibfk_3` FOREIGN KEY (`upload_id`) REFERENCES `seminaryuploads` (`id`), + CONSTRAINT `questtypes_submit_characters_ibfk_4` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_submit_characters_ibfk_5` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_submit_characters_comments` +-- + +DROP TABLE IF EXISTS `questtypes_submit_characters_comments`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_submit_characters_comments` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `questtypes_submit_character_id` int(11) NOT NULL, + `comment` text NOT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `questtypes_submit_character_id` (`questtypes_submit_character_id`), + CONSTRAINT `questtypes_submit_characters_comments_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_submit_characters_comments_ibfk_2` FOREIGN KEY (`questtypes_submit_character_id`) REFERENCES `questtypes_submit_characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_submit_mimetypes` +-- + +DROP TABLE IF EXISTS `questtypes_submit_mimetypes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_submit_mimetypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `mimetype` varchar(32) NOT NULL, + `size` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `mimetype` (`mimetype`,`seminary_id`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `questtypes_submit_mimetypes_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `questtypes_submit_mimetypes_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_textinput` +-- + +DROP TABLE IF EXISTS `questtypes_textinput`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_textinput` ( + `quest_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `text` text NOT NULL, + PRIMARY KEY (`quest_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `questtypes_textinput_ibfk_1` FOREIGN KEY (`quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_textinput_ibfk_2` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_textinput_fields` +-- + +DROP TABLE IF EXISTS `questtypes_textinput_fields`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_textinput_fields` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `questtypes_textinput_quest_id` int(11) NOT NULL, + `number` int(10) unsigned NOT NULL, + `questtypes_textinput_fieldsize_id` int(11) NOT NULL DEFAULT '1', + `regex` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `questtypes_textinput_quest_id` (`questtypes_textinput_quest_id`,`number`), + KEY `questtypes_textinput_fieldsize_id` (`questtypes_textinput_fieldsize_id`), + CONSTRAINT `questtypes_textinput_fields_ibfk_1` FOREIGN KEY (`questtypes_textinput_quest_id`) REFERENCES `quests` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_textinput_fields_ibfk_2` FOREIGN KEY (`questtypes_textinput_fieldsize_id`) REFERENCES `questtypes_textinput_fieldsizes` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_textinput_fields_characters` +-- + +DROP TABLE IF EXISTS `questtypes_textinput_fields_characters`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_textinput_fields_characters` ( + `questtypes_textinput_field_id` int(11) NOT NULL, + `character_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `value` varchar(255) NOT NULL, + PRIMARY KEY (`questtypes_textinput_field_id`,`character_id`), + KEY `character_id` (`character_id`), + CONSTRAINT `questtypes_textinput_fields_characters_ibfk_2` FOREIGN KEY (`character_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `questtypes_textinput_fields_characters_ibfk_3` FOREIGN KEY (`questtypes_textinput_field_id`) REFERENCES `questtypes_textinput_fields` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `questtypes_textinput_fieldsizes` +-- + +DROP TABLE IF EXISTS `questtypes_textinput_fieldsizes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `questtypes_textinput_fieldsizes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `size` varchar(32) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `size` (`size`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `seminaries` +-- + +DROP TABLE IF EXISTS `seminaries`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `seminaries` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `url` varchar(128) NOT NULL, + `course` varchar(255) NOT NULL, + `description` text NOT NULL, + `seminarymedia_id` int(11) DEFAULT NULL, + `charactergroups_seminarymedia_id` int(11) DEFAULT NULL, + `achievements_seminarymedia_id` int(11) DEFAULT NULL, + `library_seminarymedia_id` int(11) DEFAULT NULL, + `map_seminarymedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `title` (`title`), + UNIQUE KEY `url` (`url`), + KEY `created_user_id` (`created_user_id`), + KEY `media_id` (`seminarymedia_id`), + KEY `charactergroups_seminarymedia_id` (`charactergroups_seminarymedia_id`), + KEY `achievements_seminarymedia_id` (`achievements_seminarymedia_id`), + KEY `library_seminarymedia_id` (`library_seminarymedia_id`), + KEY `map_seminarymedia_id` (`map_seminarymedia_id`), + CONSTRAINT `seminaries_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `seminaries_ibfk_2` FOREIGN KEY (`seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `seminaries_ibfk_3` FOREIGN KEY (`charactergroups_seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `seminaries_ibfk_4` FOREIGN KEY (`achievements_seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `seminaries_ibfk_5` FOREIGN KEY (`library_seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, + CONSTRAINT `seminaries_ibfk_6` FOREIGN KEY (`map_seminarymedia_id`) REFERENCES `seminarymedia` (`id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Lehrveranstaltungen'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `seminarycharacterfields` +-- + +DROP TABLE IF EXISTS `seminarycharacterfields`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `seminarycharacterfields` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `pos` int(10) unsigned NOT NULL, + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `seminarycharacterfieldtype_id` int(11) NOT NULL, + `regex` varchar(512) NOT NULL, + `required` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `url` (`seminary_id`,`url`), + UNIQUE KEY `seminary_id_2` (`seminary_id`,`pos`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + KEY `seminarycharacterfieldtype_id` (`seminarycharacterfieldtype_id`), + CONSTRAINT `seminarycharacterfields_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `seminarycharacterfields_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `seminarycharacterfields_ibfk_3` FOREIGN KEY (`seminarycharacterfieldtype_id`) REFERENCES `seminarycharacterfieldtypes` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `seminarycharacterfieldtypes` +-- + +DROP TABLE IF EXISTS `seminarycharacterfieldtypes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `seminarycharacterfieldtypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `title` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `seminarymedia` +-- + +DROP TABLE IF EXISTS `seminarymedia`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `seminarymedia` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(64) NOT NULL, + `description` varchar(128) NOT NULL, + `mimetype` varchar(32) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `seminary_id_2` (`seminary_id`,`name`), + UNIQUE KEY `seminary_id_3` (`seminary_id`,`url`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `seminarymedia_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `seminarymedia_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `seminaryuploads` +-- + +DROP TABLE IF EXISTS `seminaryuploads`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `seminaryuploads` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) DEFAULT NULL, + `name` varchar(64) NOT NULL, + `url` varchar(255) NOT NULL, + `mimetype` varchar(32) NOT NULL, + `public` tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`), + UNIQUE KEY `url` (`url`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `seminaryuploads_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `seminaryuploads_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `userroles` +-- + +DROP TABLE IF EXISTS `userroles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `userroles` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `name` varchar(32) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `username` varchar(32) NOT NULL, + `url` varchar(128) NOT NULL, + `surname` varchar(128) NOT NULL, + `prename` varchar(128) NOT NULL, + `email` varchar(64) NOT NULL, + `password` varchar(64) NOT NULL, + `mailing` tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`), + UNIQUE KEY `username` (`username`), + UNIQUE KEY `email` (`email`), + UNIQUE KEY `url` (`url`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Benutzer'; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `users_userroles` +-- + +DROP TABLE IF EXISTS `users_userroles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `users_userroles` ( + `user_id` int(11) NOT NULL, + `userrole_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`user_id`,`userrole_id`), + KEY `userrole_id` (`userrole_id`), + CONSTRAINT `users_userroles_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `users_userroles_ibfk_3` FOREIGN KEY (`userrole_id`) REFERENCES `userroles` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `xplevels` +-- + +DROP TABLE IF EXISTS `xplevels`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `xplevels` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `seminary_id` int(11) NOT NULL, + `xps` int(10) unsigned NOT NULL, + `level` int(11) NOT NULL, + `name` varchar(64) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `xps` (`seminary_id`,`xps`), + UNIQUE KEY `level` (`level`,`seminary_id`), + KEY `created_user_id` (`created_user_id`), + KEY `seminary_id` (`seminary_id`), + CONSTRAINT `xplevels_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `xplevels_ibfk_2` FOREIGN KEY (`seminary_id`) REFERENCES `seminaries` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2015-04-26 13:28:31 diff --git a/db/import.sql b/db/import.sql new file mode 100644 index 00000000..da3199f6 --- /dev/null +++ b/db/import.sql @@ -0,0 +1,717 @@ +-- MySQL dump 10.15 Distrib 10.0.17-MariaDB, for Linux (x86_64) +-- +-- Host: localhost Database: z_default +-- ------------------------------------------------------ +-- Server version 10.0.17-MariaDB-log + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Dumping data for table `achievementconditions` +-- + +LOCK TABLES `achievementconditions` WRITE; +/*!40000 ALTER TABLE `achievementconditions` DISABLE KEYS */; +INSERT INTO `achievementconditions` VALUES (1,'2014-04-16 19:36:54','date'),(2,'2014-04-16 19:36:54','character'),(3,'2014-04-16 19:36:59','quest'),(4,'2014-04-16 19:36:59','achievement'); +/*!40000 ALTER TABLE `achievementconditions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievementconditions_achievement` +-- + +LOCK TABLES `achievementconditions_achievement` WRITE; +/*!40000 ALTER TABLE `achievementconditions_achievement` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievementconditions_achievement` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievementconditions_character` +-- + +LOCK TABLES `achievementconditions_character` WRITE; +/*!40000 ALTER TABLE `achievementconditions_character` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievementconditions_character` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievementconditions_date` +-- + +LOCK TABLES `achievementconditions_date` WRITE; +/*!40000 ALTER TABLE `achievementconditions_date` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievementconditions_date` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievementconditions_quest` +-- + +LOCK TABLES `achievementconditions_quest` WRITE; +/*!40000 ALTER TABLE `achievementconditions_quest` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievementconditions_quest` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievements` +-- + +LOCK TABLES `achievements` WRITE; +/*!40000 ALTER TABLE `achievements` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievements` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievements_characters` +-- + +LOCK TABLES `achievements_characters` WRITE; +/*!40000 ALTER TABLE `achievements_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievements_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `achievementsmedia` +-- + +LOCK TABLES `achievementsmedia` WRITE; +/*!40000 ALTER TABLE `achievementsmedia` DISABLE KEYS */; +/*!40000 ALTER TABLE `achievementsmedia` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `avatarpictures` +-- + +LOCK TABLES `avatarpictures` WRITE; +/*!40000 ALTER TABLE `avatarpictures` DISABLE KEYS */; +/*!40000 ALTER TABLE `avatarpictures` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `avatars` +-- + +LOCK TABLES `avatars` WRITE; +/*!40000 ALTER TABLE `avatars` DISABLE KEYS */; +/*!40000 ALTER TABLE `avatars` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `cache_charactergroups` +-- + +LOCK TABLES `cache_charactergroups` WRITE; +/*!40000 ALTER TABLE `cache_charactergroups` DISABLE KEYS */; +/*!40000 ALTER TABLE `cache_charactergroups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `cache_characters` +-- + +LOCK TABLES `cache_characters` WRITE; +/*!40000 ALTER TABLE `cache_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `cache_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroups` +-- + +LOCK TABLES `charactergroups` WRITE; +/*!40000 ALTER TABLE `charactergroups` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroupsgroups` +-- + +LOCK TABLES `charactergroupsgroups` WRITE; +/*!40000 ALTER TABLE `charactergroupsgroups` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroupsgroups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroupsmedia` +-- + +LOCK TABLES `charactergroupsmedia` WRITE; +/*!40000 ALTER TABLE `charactergroupsmedia` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroupsmedia` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroupsquests` +-- + +LOCK TABLES `charactergroupsquests` WRITE; +/*!40000 ALTER TABLE `charactergroupsquests` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroupsquests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroupsquests_groups` +-- + +LOCK TABLES `charactergroupsquests_groups` WRITE; +/*!40000 ALTER TABLE `charactergroupsquests_groups` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroupsquests_groups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactergroupsquests_seminaryuploads` +-- + +LOCK TABLES `charactergroupsquests_seminaryuploads` WRITE; +/*!40000 ALTER TABLE `charactergroupsquests_seminaryuploads` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactergroupsquests_seminaryuploads` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `characterroles` +-- + +LOCK TABLES `characterroles` WRITE; +/*!40000 ALTER TABLE `characterroles` DISABLE KEYS */; +INSERT INTO `characterroles` VALUES (1,'2014-04-16 14:42:54','admin'),(2,'2014-04-16 14:42:54','moderator'),(3,'2014-04-16 14:43:00','user'),(4,'2014-04-16 14:43:00','guest'); +/*!40000 ALTER TABLE `characterroles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `characters` +-- + +LOCK TABLES `characters` WRITE; +/*!40000 ALTER TABLE `characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `characters_charactergroups` +-- + +LOCK TABLES `characters_charactergroups` WRITE; +/*!40000 ALTER TABLE `characters_charactergroups` DISABLE KEYS */; +/*!40000 ALTER TABLE `characters_charactergroups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `characters_characterroles` +-- + +LOCK TABLES `characters_characterroles` WRITE; +/*!40000 ALTER TABLE `characters_characterroles` DISABLE KEYS */; +/*!40000 ALTER TABLE `characters_characterroles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `characters_seminarycharacterfields` +-- + +LOCK TABLES `characters_seminarycharacterfields` WRITE; +/*!40000 ALTER TABLE `characters_seminarycharacterfields` DISABLE KEYS */; +/*!40000 ALTER TABLE `characters_seminarycharacterfields` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `charactertypes` +-- + +LOCK TABLES `charactertypes` WRITE; +/*!40000 ALTER TABLE `charactertypes` DISABLE KEYS */; +/*!40000 ALTER TABLE `charactertypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `maps` +-- + +LOCK TABLES `maps` WRITE; +/*!40000 ALTER TABLE `maps` DISABLE KEYS */; +/*!40000 ALTER TABLE `maps` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `media` +-- + +LOCK TABLES `media` WRITE; +/*!40000 ALTER TABLE `media` DISABLE KEYS */; +/*!40000 ALTER TABLE `media` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroups` +-- + +LOCK TABLES `questgroups` WRITE; +/*!40000 ALTER TABLE `questgroups` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroups` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroups_characters` +-- + +LOCK TABLES `questgroups_characters` WRITE; +/*!40000 ALTER TABLE `questgroups_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroups_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroups_questgroupshierarchy` +-- + +LOCK TABLES `questgroups_questgroupshierarchy` WRITE; +/*!40000 ALTER TABLE `questgroups_questgroupshierarchy` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroups_questgroupshierarchy` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroups_questtexts` +-- + +LOCK TABLES `questgroups_questtexts` WRITE; +/*!40000 ALTER TABLE `questgroups_questtexts` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroups_questtexts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroupshierarchy` +-- + +LOCK TABLES `questgroupshierarchy` WRITE; +/*!40000 ALTER TABLE `questgroupshierarchy` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroupshierarchy` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgroupspictures` +-- + +LOCK TABLES `questgroupspictures` WRITE; +/*!40000 ALTER TABLE `questgroupspictures` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgroupspictures` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questgrouptexts` +-- + +LOCK TABLES `questgrouptexts` WRITE; +/*!40000 ALTER TABLE `questgrouptexts` DISABLE KEYS */; +/*!40000 ALTER TABLE `questgrouptexts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `quests` +-- + +LOCK TABLES `quests` WRITE; +/*!40000 ALTER TABLE `quests` DISABLE KEYS */; +/*!40000 ALTER TABLE `quests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `quests_characters` +-- + +LOCK TABLES `quests_characters` WRITE; +/*!40000 ALTER TABLE `quests_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `quests_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `quests_previousquests` +-- + +LOCK TABLES `quests_previousquests` WRITE; +/*!40000 ALTER TABLE `quests_previousquests` DISABLE KEYS */; +/*!40000 ALTER TABLE `quests_previousquests` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `quests_questsubtopics` +-- + +LOCK TABLES `quests_questsubtopics` WRITE; +/*!40000 ALTER TABLE `quests_questsubtopics` DISABLE KEYS */; +/*!40000 ALTER TABLE `quests_questsubtopics` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questsmedia` +-- + +LOCK TABLES `questsmedia` WRITE; +/*!40000 ALTER TABLE `questsmedia` DISABLE KEYS */; +/*!40000 ALTER TABLE `questsmedia` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questsubtopics` +-- + +LOCK TABLES `questsubtopics` WRITE; +/*!40000 ALTER TABLE `questsubtopics` DISABLE KEYS */; +/*!40000 ALTER TABLE `questsubtopics` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtexts` +-- + +LOCK TABLES `questtexts` WRITE; +/*!40000 ALTER TABLE `questtexts` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtexts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtexttypes` +-- + +LOCK TABLES `questtexttypes` WRITE; +/*!40000 ALTER TABLE `questtexttypes` DISABLE KEYS */; +INSERT INTO `questtexttypes` VALUES (1,'2014-04-17 09:24:21','Prolog','Prolog'),(2,'2014-04-17 09:24:21','Hint','Hint'),(3,'2014-04-17 09:24:27','Epilog','Epilog'); +/*!40000 ALTER TABLE `questtexttypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtopics` +-- + +LOCK TABLES `questtopics` WRITE; +/*!40000 ALTER TABLE `questtopics` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtopics` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes` +-- + +LOCK TABLES `questtypes` WRITE; +/*!40000 ALTER TABLE `questtypes` DISABLE KEYS */; +INSERT INTO `questtypes` VALUES (1,'2014-04-16 18:44:44','Empty','Empty',NULL),(2,'2014-04-16 18:44:44','Boss Fight','Boss-Fight','bossfight'),(3,'2014-04-16 18:45:19','Choice Input','Choice-Input','choiceinput'),(4,'2014-04-16 18:46:02','Crossword','Crossword','crossword'),(5,'2014-04-16 18:46:02','Drag&Drop','Drag&Drop','dragndrop'),(6,'2014-04-16 18:46:23','Multiple Choice','Multiple-Choice','multiplechoice'),(7,'2014-04-16 18:46:23','Submit','Submit','submit'),(8,'2014-04-16 18:46:43','Text Input','Text-Input','textinput'); +/*!40000 ALTER TABLE `questtypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_bossfight` +-- + +LOCK TABLES `questtypes_bossfight` WRITE; +/*!40000 ALTER TABLE `questtypes_bossfight` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_bossfight` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_bossfight_stages` +-- + +LOCK TABLES `questtypes_bossfight_stages` WRITE; +/*!40000 ALTER TABLE `questtypes_bossfight_stages` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_bossfight_stages` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_bossfight_stages_characters` +-- + +LOCK TABLES `questtypes_bossfight_stages_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_bossfight_stages_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_bossfight_stages_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_choiceinput` +-- + +LOCK TABLES `questtypes_choiceinput` WRITE; +/*!40000 ALTER TABLE `questtypes_choiceinput` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_choiceinput` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_choiceinput_choices` +-- + +LOCK TABLES `questtypes_choiceinput_choices` WRITE; +/*!40000 ALTER TABLE `questtypes_choiceinput_choices` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_choiceinput_choices` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_choiceinput_lists` +-- + +LOCK TABLES `questtypes_choiceinput_lists` WRITE; +/*!40000 ALTER TABLE `questtypes_choiceinput_lists` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_choiceinput_lists` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_choiceinput_lists_characters` +-- + +LOCK TABLES `questtypes_choiceinput_lists_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_choiceinput_lists_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_choiceinput_lists_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_crossword_words` +-- + +LOCK TABLES `questtypes_crossword_words` WRITE; +/*!40000 ALTER TABLE `questtypes_crossword_words` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_crossword_words` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_crossword_words_characters` +-- + +LOCK TABLES `questtypes_crossword_words_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_crossword_words_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_crossword_words_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_dragndrop` +-- + +LOCK TABLES `questtypes_dragndrop` WRITE; +/*!40000 ALTER TABLE `questtypes_dragndrop` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_dragndrop` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_dragndrop_drags` +-- + +LOCK TABLES `questtypes_dragndrop_drags` WRITE; +/*!40000 ALTER TABLE `questtypes_dragndrop_drags` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_dragndrop_drags` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_dragndrop_drops` +-- + +LOCK TABLES `questtypes_dragndrop_drops` WRITE; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_dragndrop_drops_characters` +-- + +LOCK TABLES `questtypes_dragndrop_drops_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_dragndrop_drops_drags` +-- + +LOCK TABLES `questtypes_dragndrop_drops_drags` WRITE; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops_drags` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_dragndrop_drops_drags` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_multiplechoice` +-- + +LOCK TABLES `questtypes_multiplechoice` WRITE; +/*!40000 ALTER TABLE `questtypes_multiplechoice` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_multiplechoice` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_multiplechoice_answers` +-- + +LOCK TABLES `questtypes_multiplechoice_answers` WRITE; +/*!40000 ALTER TABLE `questtypes_multiplechoice_answers` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_multiplechoice_answers` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_multiplechoice_characters` +-- + +LOCK TABLES `questtypes_multiplechoice_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_multiplechoice_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_multiplechoice_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_submit_characters` +-- + +LOCK TABLES `questtypes_submit_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_submit_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_submit_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_submit_characters_comments` +-- + +LOCK TABLES `questtypes_submit_characters_comments` WRITE; +/*!40000 ALTER TABLE `questtypes_submit_characters_comments` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_submit_characters_comments` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_submit_mimetypes` +-- + +LOCK TABLES `questtypes_submit_mimetypes` WRITE; +/*!40000 ALTER TABLE `questtypes_submit_mimetypes` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_submit_mimetypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_textinput` +-- + +LOCK TABLES `questtypes_textinput` WRITE; +/*!40000 ALTER TABLE `questtypes_textinput` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_textinput` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_textinput_fields` +-- + +LOCK TABLES `questtypes_textinput_fields` WRITE; +/*!40000 ALTER TABLE `questtypes_textinput_fields` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_textinput_fields` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_textinput_fields_characters` +-- + +LOCK TABLES `questtypes_textinput_fields_characters` WRITE; +/*!40000 ALTER TABLE `questtypes_textinput_fields_characters` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_textinput_fields_characters` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `questtypes_textinput_fieldsizes` +-- + +LOCK TABLES `questtypes_textinput_fieldsizes` WRITE; +/*!40000 ALTER TABLE `questtypes_textinput_fieldsizes` DISABLE KEYS */; +/*!40000 ALTER TABLE `questtypes_textinput_fieldsizes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `seminaries` +-- + +LOCK TABLES `seminaries` WRITE; +/*!40000 ALTER TABLE `seminaries` DISABLE KEYS */; +/*!40000 ALTER TABLE `seminaries` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `seminarycharacterfields` +-- + +LOCK TABLES `seminarycharacterfields` WRITE; +/*!40000 ALTER TABLE `seminarycharacterfields` DISABLE KEYS */; +/*!40000 ALTER TABLE `seminarycharacterfields` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `seminarycharacterfieldtypes` +-- + +LOCK TABLES `seminarycharacterfieldtypes` WRITE; +/*!40000 ALTER TABLE `seminarycharacterfieldtypes` DISABLE KEYS */; +INSERT INTO `seminarycharacterfieldtypes` VALUES (1,'2014-04-16 18:50:16','Number','Number'),(2,'2014-04-16 18:50:16','Varchar','Varchar'),(3,'2014-04-16 18:50:24','Text','Text'),(4,'2014-04-16 18:50:24','List','List'); +/*!40000 ALTER TABLE `seminarycharacterfieldtypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `seminarymedia` +-- + +LOCK TABLES `seminarymedia` WRITE; +/*!40000 ALTER TABLE `seminarymedia` DISABLE KEYS */; +/*!40000 ALTER TABLE `seminarymedia` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `seminaryuploads` +-- + +LOCK TABLES `seminaryuploads` WRITE; +/*!40000 ALTER TABLE `seminaryuploads` DISABLE KEYS */; +/*!40000 ALTER TABLE `seminaryuploads` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `userroles` +-- + +LOCK TABLES `userroles` WRITE; +/*!40000 ALTER TABLE `userroles` DISABLE KEYS */; +INSERT INTO `userroles` VALUES (1,'2014-04-16 14:42:54','admin'),(2,'2014-04-16 14:42:54','moderator'),(3,'2014-04-16 14:43:00','user'),(4,'2014-04-16 14:43:00','guest'); +/*!40000 ALTER TABLE `userroles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `users` +-- + +LOCK TABLES `users` WRITE; +/*!40000 ALTER TABLE `users` DISABLE KEYS */; +INSERT INTO `users` VALUES (1,'2015-04-26 11:24:04','admin','admin','Admin','Admin','','$2y$10$1zCozXcIGak552mkv/K3vOPddrisvPlokJvUjHtHj6VBBRcmznXCG',1); +/*!40000 ALTER TABLE `users` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `users_userroles` +-- + +LOCK TABLES `users_userroles` WRITE; +/*!40000 ALTER TABLE `users_userroles` DISABLE KEYS */; +INSERT INTO `users_userroles` VALUES (1,1,'2015-04-26 11:33:36'); +/*!40000 ALTER TABLE `users_userroles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Dumping data for table `xplevels` +-- + +LOCK TABLES `xplevels` WRITE; +/*!40000 ALTER TABLE `xplevels` DISABLE KEYS */; +/*!40000 ALTER TABLE `xplevels` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2015-04-26 13:34:20 diff --git a/db/procedures.sql b/db/procedures.sql new file mode 100644 index 00000000..a9a1724e --- /dev/null +++ b/db/procedures.sql @@ -0,0 +1,151 @@ +DROP PROCEDURE IF EXISTS update_cache_characters_quest; +DELIMITER $$ +CREATE PROCEDURE update_cache_characters_quest( + IN QUESTID INT(11) +) +BEGIN + DECLARE CHARACTERID INT; + DECLARE done INT DEFAULT FALSE; + DECLARE characters_cursor CURSOR FOR + SELECT character_id + FROM quests_characters + WHERE quest_id = QUESTID AND status = 3; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + SET done = 0; + OPEN characters_cursor; + get_characters: LOOP + FETCH characters_cursor INTO CHARACTERID; + IF done = TRUE THEN + LEAVE get_characters; + END IF; + CALL update_cache_characters(CHARACTERID); + END LOOP get_characters; +END $$ +DELIMITER ; + + +DROP PROCEDURE IF EXISTS update_cache_characters_charactergroup; +DELIMITER $$ +CREATE PROCEDURE update_cache_characters_charactergroup( + IN CHARACTERGROUPID INT(11) +) +BEGIN + DECLARE CHARACTERID INT; + DECLARE done INT DEFAULT FALSE; + DECLARE characters_cursor CURSOR FOR + SELECT character_id + FROM characters_charactergroups + WHERE charactergroup_id = CHARACTERGROUPID; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + SET done = 0; + OPEN characters_cursor; + get_characters: LOOP + FETCH characters_cursor INTO CHARACTERID; + IF done = TRUE THEN + LEAVE get_characters; + END IF; + CALL update_cache_characters(CHARACTERID); + END LOOP get_characters; +END $$ +DELIMITER ; + + +DROP PROCEDURE IF EXISTS update_cache_characters; +DELIMITER $$ +CREATE PROCEDURE update_cache_characters( + IN CHARACTERID INT(11) +) +BEGIN + DECLARE QUESTXPS INT UNSIGNED; + DECLARE GROUPSXPS INT UNSIGNED; + DECLARE TOTALXPS INT UNSIGNED; + DECLARE XPLEVELID INT; + DECLARE AVATARID INT; + + /* XPs */ + SELECT IFNULL(SUM(quests.xps),0) INTO QUESTXPS + FROM quests_characters + LEFT JOIN quests ON quests.id = quests_characters.quest_id + WHERE quests_characters.character_id = CHARACTERID AND quests_characters.status = 3; + SELECT IFNULL(SUM(cache_charactergroups.xps),0) INTO GROUPSXPS + FROM characters_charactergroups + LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = characters_charactergroups.charactergroup_id + WHERE characters_charactergroups.character_id = CHARACTERID; + SET TOTALXPS = QUESTXPS + GROUPSXPS; + + /* XP-level */ + SELECT ( + SELECT id + FROM xplevels + WHERE seminary_id = charactertypes.seminary_id AND xps = ( + SELECT MAX(xps) + FROM xplevels AS xplevels_sub + WHERE xps <= TOTALXPS + ) + ) INTO XPLEVELID + FROM characters + LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id + WHERE characters.id = CHARACTERID; + + /* Avatar */ + SELECT avatars.id INTO AVATARID + FROM characters + LEFT JOIN avatars ON avatars.charactertype_id = characters.charactertype_id AND avatars.xplevel_id = XPLEVELID + WHERE characters.id = CHARACTERID; + + /* Set values */ + REPLACE INTO cache_characters + (character_id, xps, quest_xps, xplevel_id, avatar_id) + VALUES + (CHARACTERID, TOTALXPS, QUESTXPS, XPLEVELID, AVATARID); +END $$ +DELIMITER ; + + + + +DROP PROCEDURE IF EXISTS update_cache_charactergroups_charactergroupsquest; +DELIMITER $$ +CREATE PROCEDURE update_cache_charactergroups_charactergroupsquest( + IN CHARACTERGROUPSQUESTID INT(11) +) +BEGIN + DECLARE CHARACTERGROUPID INT; + DECLARE done INT DEFAULT FALSE; + DECLARE charactergroups_cursor CURSOR FOR + SELECT charactergroup_id + FROM charactergroupsquests_groups + WHERE charactergroupsquest_id = CHARACTERGROUPSQUESTID; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + SET done = 0; + OPEN charactergroups_cursor; + get_charactergroups: LOOP + FETCH charactergroups_cursor INTO CHARACTERGROUPID; + IF done = TRUE THEN + LEAVE get_charactergroups; + END IF; + CALL update_cache_charactergroups(CHARACTERGROUPID); + END LOOP get_charactergroups; +END $$ +DELIMITER ; + + +DROP PROCEDURE IF EXISTS update_cache_charactergroups; +DELIMITER $$ +CREATE PROCEDURE update_cache_charactergroups( + IN CHARACTERGROUPID INT(11) +) +BEGIN + /* XPs */ + REPLACE INTO cache_charactergroups + (charactergroup_id, xps) + SELECT charactergroups.id, IFNULL(SUM(ROUND(charactergroupsquests.xps * charactergroupsquests_groups.xps_factor)),0) AS xps + FROM charactergroups + LEFT JOIN charactergroupsquests_groups ON charactergroupsquests_groups.charactergroup_id = charactergroups.id + LEFT JOIN charactergroupsquests ON charactergroupsquests.id = charactergroupsquests_groups.charactergroupsquest_id + WHERE charactergroups.id = CHARACTERGROUPID; +END $$ +DELIMITER ; diff --git a/db/triggers.sql b/db/triggers.sql new file mode 100644 index 00000000..ea8b44ad --- /dev/null +++ b/db/triggers.sql @@ -0,0 +1,155 @@ +/** Characters +Quests **/ + +DROP TRIGGER IF EXISTS update_cache_characters_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_characters_insert` +AFTER INSERT ON characters +FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_quests_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_quests_update` +AFTER UPDATE ON quests +FOR EACH ROW BEGIN + CALL update_cache_characters_quest(NEW.id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_quests_characters_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_quests_characters_insert` +AFTER INSERT ON quests_characters +FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.character_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_quests_characters_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_quests_characters_update` +AFTER UPDATE ON quests_characters +FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); + CALL update_cache_characters(NEW.character_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_quests_characters_delete; +DELIMITER $$ +CREATE TRIGGER `update_cache_quests_characters_delete` +AFTER DELETE ON quests_characters +FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); +END $$ +DELIMITER ; + + + + +/** Charactergroups +Charactergroupsquests **/ + +DROP TRIGGER IF EXISTS update_cache_charactergroups_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_charactergroups_insert` +AFTER INSERT ON charactergroups +FOR EACH ROW BEGIN + CALL update_cache_charactergroups(NEW.id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_charactergroupsquests_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_charactergroupsquests_update` +AFTER UPDATE ON charactergroupsquests +FOR EACH ROW BEGIN + CALL update_cache_charactergroups_charactergroupsquest(NEW.id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_charactergroupsquests_groups_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_charactergroupsquests_groups_insert` +AFTER INSERT ON charactergroupsquests_groups +FOR EACH ROW BEGIN + CALL update_cache_charactergroups(NEW.charactergroup_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_charactergroupsquests_groups_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_charactergroupsquests_groups_update` +AFTER UPDATE ON charactergroupsquests_groups +FOR EACH ROW BEGIN + CALL update_cache_charactergroups(OLD.charactergroup_id); + CALL update_cache_charactergroups(NEW.charactergroup_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_charactergroupsquests_groups_delete; +DELIMITER $$ +CREATE TRIGGER `update_cache_charactergroupsquests_groups_delete` +AFTER DELETE ON charactergroupsquests_groups +FOR EACH ROW BEGIN + CALL update_cache_charactergroups(OLD.charactergroup_id); +END $$ +DELIMITER ; + + + + +/** Characters → Charactergroups **/ + +DROP TRIGGER IF EXISTS update_cache_characters_charactergroups_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_characters_charactergroups_insert` +AFTER INSERT ON characters_charactergroups +FOR EACH ROW BEGIN + CALL update_cache_characters(NEW.character_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_characters_charactergroups_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_characters_charactergroups_update` +AFTER UPDATE ON characters_charactergroups +FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); + CALL update_cache_characters(NEW.character_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_characters_charactergroups_delete; +DELIMITER $$ +CREATE TRIGGER `update_cache_characters_charactergroups_delete` +AFTER DELETE ON characters_charactergroups +FOR EACH ROW BEGIN + CALL update_cache_characters(OLD.character_id); +END $$ +DELIMITER ; + + + + +/** Cache Charactergroups **/ + +DROP TRIGGER IF EXISTS update_cache_cache_charactergroups_insert; +DELIMITER $$ +CREATE TRIGGER `update_cache_cache_charactergroups_insert` +AFTER INSERT ON cache_charactergroups +FOR EACH ROW BEGIN + CALL update_cache_characters_charactergroup(NEW.charactergroup_id); +END $$ +DELIMITER ; + +DROP TRIGGER IF EXISTS update_cache_cache_charactergroups_update; +DELIMITER $$ +CREATE TRIGGER `update_cache_cache_charactergroups_update` +AFTER UPDATE ON cache_charactergroups +FOR EACH ROW BEGIN + CALL update_cache_characters_charactergroup(NEW.charactergroup_id); +END $$ +DELIMITER ; + diff --git a/doc/.htaccess b/doc/.htaccess new file mode 100644 index 00000000..7b01f9bf --- /dev/null +++ b/doc/.htaccess @@ -0,0 +1,5 @@ +# Fixes a vulnerability in CentOS: http://stackoverflow.com/questions/20533279/prevent-php-from-parsing-non-php-files-such-as-somefile-php-txt + + RemoveHandler .php + ForceType text/plain + \ No newline at end of file diff --git a/doc/classes/PHPMailer.html b/doc/classes/PHPMailer.html new file mode 100644 index 00000000..b5d80bfc --- /dev/null +++ b/doc/classes/PHPMailer.html @@ -0,0 +1,7052 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\PHPMailer

+

PHPMailer - PHP email creation and transport class.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ __construct()
+ __destruct()
+ isHTML()
+ isSMTP()
+ isMail()
+ isSendmail()
+ isQmail()
+ addAddress()
+ addCC()
+ addBCC()
+ addReplyTo()
+ setFrom()
+ getLastMessageID()
+ validateAddress()
+ send()
+ preSend()
+ postSend()
+ getSMTPInstance()
+ smtpConnect()
+ smtpClose()
+ setLanguage()
+ getTranslations()
+ addrAppend()
+ addrFormat()
+ wrapText()
+ utf8CharBoundary()
+ setWordWrap()
+ createHeader()
+ getMailMIME()
+ getSentMIMEMessage()
+ createBody()
+ headerLine()
+ textLine()
+ addAttachment()
+ getAttachments()
+ encodeString()
+ encodeHeader()
+ hasMultiBytes()
+ has8bitChars()
+ base64EncodeWrapMB()
+ encodeQP()
+ encodeQPphp()
+ encodeQ()
+ addStringAttachment()
+ addEmbeddedImage()
+ addStringEmbeddedImage()
+ inlineImageExists()
+ attachmentExists()
+ alternativeExists()
+ clearAddresses()
+ clearCCs()
+ clearBCCs()
+ clearReplyTos()
+ clearAllRecipients()
+ clearAttachments()
+ clearCustomHeaders()
+ rfcDate()
+ isError()
+ fixEOL()
+ addCustomHeader()
+ msgHTML()
+ html2text()
+ _mime_types()
+ filenameToType()
+ mb_pathinfo()
+ set()
+ secureHeader()
+ normalizeBreaks()
+ sign()
+ DKIM_QP()
+ DKIM_Sign()
+ DKIM_HeaderC()
+ DKIM_BodyC()
+ DKIM_Add()
+ getToAddresses()
+ getCcAddresses()
+ getBccAddresses()
+ getReplyToAddresses()
+ getAllRecipientAddresses()
+
+
+ $Version
+ $Priority
+ $CharSet
+ $ContentType
+ $Encoding
+ $ErrorInfo
+ $From
+ $FromName
+ $Sender
+ $ReturnPath
+ $Subject
+ $Body
+ $AltBody
+ $Ical
+ $WordWrap
+ $Mailer
+ $Sendmail
+ $UseSendmailOptions
+ $PluginDir
+ $ConfirmReadingTo
+ $Hostname
+ $MessageID
+ $MessageDate
+ $Host
+ $Port
+ $Helo
+ $SMTPSecure
+ $SMTPAuth
+ $Username
+ $Password
+ $AuthType
+ $Realm
+ $Workstation
+ $Timeout
+ $SMTPDebug
+ $Debugoutput
+ $SMTPKeepAlive
+ $SingleTo
+ $SingleToArray
+ $do_verp
+ $AllowEmpty
+ $LE
+ $DKIM_selector
+ $DKIM_identity
+ $DKIM_passphrase
+ $DKIM_domain
+ $DKIM_private
+ $action_function
+ $XMailer
+
+
+ STOP_MESSAGE
+ STOP_CONTINUE
+ STOP_CRITICAL
+ CRLF
+
+
+
+
+ edebug()
+ addAnAddress()
+ sendmailSend()
+ mailSend()
+ smtpSend()
+ getBoundary()
+ endBoundary()
+ setMessageType()
+ attachAll()
+ encodeFile()
+ setError()
+ serverHostname()
+ lang()
+ doCallback()
+
+
+ $MIMEBody
+ $MIMEHeader
+ $mailHeader
+ $smtp
+ $to
+ $cc
+ $bcc
+ $ReplyTo
+ $all_recipients
+ $attachment
+ $CustomHeader
+ $lastMessageID
+ $message_type
+ $boundary
+ $language
+ $error_count
+ $sign_cert_file
+ $sign_key_file
+ $sign_key_pass
+ $exceptions
+
+
+ N/A +
+
+
+
+ mailPassthru()
+
+
+ No private properties found +
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

STOP_MESSAGE

+
STOP_MESSAGE
+

Error severity: message only, continue processing

+ +
+
+ +
+ +
+
+ +
+

STOP_CONTINUE

+
STOP_CONTINUE
+

Error severity: message, likely ok to continue processing

+ +
+
+ +
+ +
+
+ +
+

STOP_CRITICAL

+
STOP_CRITICAL
+

Error severity: message, plus full stop, critical error reached

+ +
+
+ +
+ +
+
+ +
+

CRLF

+
CRLF
+

SMTP RFC standard line ending

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$Version

+
$Version : 
+

The PHPMailer Version number.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Priority

+
$Priority : 
+

Email priority.

+

Options: 1 = High, 3 = Normal, 5 = low.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$CharSet

+
$CharSet : 
+

The character set of the message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$ContentType

+
$ContentType : 
+

The MIME Content-type of the message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Encoding

+
$Encoding : 
+

The message encoding.

+

Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$ErrorInfo

+
$ErrorInfo : 
+

Holds the most recent mailer error message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$From

+
$From : 
+

The From email address for the message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$FromName

+
$FromName : 
+

The From name of the message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Sender

+
$Sender : 
+

The Sender email (Return-Path) of the message.

+

If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$ReturnPath

+
$ReturnPath : 
+

The Return-Path of the message.

+

If empty, it will be set to either From or Sender.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Subject

+
$Subject : 
+

The Subject of the message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Body

+
$Body : 
+

An HTML or plain text message body.

+

If HTML then call isHTML(true).

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$AltBody

+
$AltBody : 
+

The plain-text message body.

+

This body can be read by mail clients that do not have HTML email +capability such as mutt & Eudora. +Clients that can read HTML will view the normal Body.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Ical

+
$Ical : 
+

An iCal message part body.

+

Only supported in simple alt or alt_inline message types +To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$WordWrap

+
$WordWrap : 
+

Word-wrap the message body to this number of chars.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Mailer

+
$Mailer : 
+

Which method to use to send mail.

+

Options: "mail", "sendmail", or "smtp".

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Sendmail

+
$Sendmail : 
+

The path to the sendmail program.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$UseSendmailOptions

+
$UseSendmailOptions : 
+

Whether mail() uses a fully sendmail-compatible MTA.

+

One which supports sendmail's "-oi -f" options.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$PluginDir

+
$PluginDir : 
+

Path to PHPMailer plugins.

+

Useful if the SMTP class is not in the PHP include path.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$ConfirmReadingTo

+
$ConfirmReadingTo : 
+

The email address that a reading confirmation should be sent to.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Hostname

+
$Hostname : 
+

The hostname to use in Message-Id and Received headers +and as default HELO string.

+

If empty, the value returned +by SERVER_NAME is used or 'localhost.localdomain'.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$MessageID

+
$MessageID : 
+

An ID to be used in the Message-Id header.

+

If empty, a unique id will be generated.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$MessageDate

+
$MessageDate : 
+

The message Date to be used in the Date header.

+

If empty, the current date will be added.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Host

+
$Host : 
+

SMTP hosts.

+

Either a single hostname or multiple semicolon-delimited hostnames. +You can also specify a different port +for each host by using this format: [hostname:port] +(e.g. "smtp1.example.com:25;smtp2.example.com"). +Hosts will be tried in order.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Port

+
$Port : 
+

The default SMTP server port.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Helo

+
$Helo : 
+

The SMTP HELO of the message.

+

Default is $Hostname.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$SMTPSecure

+
$SMTPSecure : 
+

The secure connection prefix.

+

Options: "", "ssl" or "tls"

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$SMTPAuth

+
$SMTPAuth : 
+

Whether to use SMTP authentication.

+

Uses the Username and Password properties.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Username

+
$Username : 
+

SMTP username.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Password

+
$Password : 
+

SMTP password.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$AuthType

+
$AuthType : 
+

SMTP auth type.

+

Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Realm

+
$Realm : 
+

SMTP realm.

+

Used for NTLM auth

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Workstation

+
$Workstation : 
+

SMTP workstation.

+

Used for NTLM auth

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Timeout

+
$Timeout : 
+

The SMTP server timeout in seconds.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$SMTPDebug

+
$SMTPDebug : 
+

SMTP class debug output mode.

+

Options: +0: no output +1: commands +2: data and commands +3: as 2 plus connection status +4: low level data output

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Debugoutput

+
$Debugoutput : 
+

How to handle debug output.

+

Options: +'echo': Output plain-text as-is, appropriate for CLI +'html': Output escaped, line breaks converted to
, appropriate for browser output +'error_log': Output to error log as configured in php.ini

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$SMTPKeepAlive

+
$SMTPKeepAlive : 
+

Whether to keep SMTP connection open after each message.

+

If this is set to true then to close the connection +requires an explicit call to smtpClose().

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$SingleTo

+
$SingleTo : 
+

Whether to split multiple to addresses into multiple messages +or send them all in one message.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$SingleToArray

+
$SingleToArray : 
+

Storage for addresses when SingleTo is enabled.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$do_verp

+
$do_verp : 
+

Whether to generate VERP addresses on send.

+

Only applicable when sending via SMTP.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$AllowEmpty

+
$AllowEmpty : 
+

Whether to allow sending messages with an empty body.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$LE

+
$LE : 
+

The default line ending.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$DKIM_selector

+
$DKIM_selector : 
+

DKIM selector.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$DKIM_identity

+
$DKIM_identity : 
+

DKIM Identity.

+

Usually the email address used as the source of the email

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$DKIM_passphrase

+
$DKIM_passphrase : 
+

DKIM passphrase.

+

Used if your key is encrypted.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$DKIM_domain

+
$DKIM_domain : 
+

DKIM signing domain name.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$DKIM_private

+
$DKIM_private : 
+

DKIM private key file path.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$action_function

+
$action_function : 
+

Callback Action function name.

+

The function that handles the result of the send email action. +It is called out by send() for each email sent.

+

Value can be any php callable: http://www.php.net/is_callable

+

Parameters: +bool $result result of the send action +string $to email address of the recipient +string $cc cc email addresses +string $bcc bcc email addresses +string $subject the subject +string $body the email body +string $from email address of sender

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$XMailer

+
$XMailer : 
+

What to use in the X-Mailer header.

+

Options: null for default, whitespace for none, or a string to use

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$MIMEBody

+
$MIMEBody : 
+

The complete compiled MIME message body.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$MIMEHeader

+
$MIMEHeader : 
+

The complete compiled MIME message headers.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$mailHeader

+
$mailHeader : 
+

Extra headers that createHeader() doesn't fold in.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$smtp

+
$smtp : 
+

An instance of the SMTP sender class.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$to

+
$to : 
+

The array of 'to' addresses.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$cc

+
$cc : 
+

The array of 'cc' addresses.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$bcc

+
$bcc : 
+

The array of 'bcc' addresses.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$ReplyTo

+
$ReplyTo : 
+

The array of reply-to names and addresses.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$all_recipients

+
$all_recipients : 
+

An array of all kinds of addresses.

+

Includes all of $to, $cc, $bcc, $replyto

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$attachment

+
$attachment : 
+

The array of attachments.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$CustomHeader

+
$CustomHeader : 
+

The array of custom headers.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$lastMessageID

+
$lastMessageID : 
+

The most recent Message-ID (including angular brackets).

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$message_type

+
$message_type : 
+

The message's MIME type.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$boundary

+
$boundary : 
+

The array of MIME boundary strings.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$language

+
$language : 
+

The array of available languages.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$error_count

+
$error_count : 
+

The number of errors encountered.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$sign_cert_file

+
$sign_cert_file : 
+

The S/MIME certificate file path.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$sign_key_file

+
$sign_key_file : 
+

The S/MIME key file path.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$sign_key_pass

+
$sign_key_pass : 
+

The S/MIME password for the key.

+

Used only if the key is encrypted.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$exceptions

+
$exceptions : 
+

Whether to throw exceptions for errors.

+ + +

Type

+ +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

__construct()

+ +
__construct(boolean  $exceptions = false) 
+

Constructor

+ + +

Parameters

+ + + + + + +
boolean$exceptions

Should we throw external exceptions?

+ + + +
+
+ +
+ +
+
+ +
+

__destruct()

+ +
__destruct() 
+

Destructor.

+ + + + + +
+
+ +
+ +
+
+ +
+

isHTML()

+ +
isHTML(boolean  $ishtml = true) : void
+

Sets message type to HTML or plain.

+ + +

Parameters

+ + + + + + +
boolean$ishtml

True for HTML mode.

+ + + +
+
+ +
+ +
+
+ +
+

isSMTP()

+ +
isSMTP() : void
+

Send messages using SMTP.

+ + + + + +
+
+ +
+ +
+
+ +
+

isMail()

+ +
isMail() : void
+

Send messages using PHP's mail() function.

+ + + + + +
+
+ +
+ +
+
+ +
+

isSendmail()

+ +
isSendmail() : void
+

Send messages using $Sendmail.

+ + + + + +
+
+ +
+ +
+
+ +
+

isQmail()

+ +
isQmail() : void
+

Send messages using qmail.

+ + + + + +
+
+ +
+ +
+
+ +
+

addAddress()

+ +
addAddress(string  $address, string  $name = '') : boolean
+

Add a "To" address.

+ + +

Parameters

+ + + + + + + + + + + +
string$address
string$name
+ + +

Returns

+ boolean + —

true on success, false if address already used

+ +
+
+ +
+ +
+
+ +
+

addCC()

+ +
addCC(string  $address, string  $name = '') : boolean
+

Add a "CC" address.

+ + +

Parameters

+ + + + + + + + + + + +
string$address
string$name
+ + +

Returns

+ boolean + —

true on success, false if address already used

+ +
+
+ +
+ +
+
+ +
+

addBCC()

+ +
addBCC(string  $address, string  $name = '') : boolean
+

Add a "BCC" address.

+ + +

Parameters

+ + + + + + + + + + + +
string$address
string$name
+ + +

Returns

+ boolean + —

true on success, false if address already used

+ +
+
+ +
+ +
+
+ +
+

addReplyTo()

+ +
addReplyTo(string  $address, string  $name = '') : boolean
+

Add a "Reply-to" address.

+ + +

Parameters

+ + + + + + + + + + + +
string$address
string$name
+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

setFrom()

+ +
setFrom(string  $address, string  $name = '', boolean  $auto = true) : boolean
+

Set the From and FromName properties.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$address
string$name
boolean$auto

Whether to also set the Sender address, defaults to true

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

getLastMessageID()

+ +
getLastMessageID() : string
+

Return the Message-ID header of the last email.

+

Technically this is the value from the last time the headers were created, +but it's also the message ID of the last sent message except in +pathological cases.

+ + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

validateAddress()

+ +
validateAddress(string  $address, string  $patternselect = 'auto') : boolean
+

Check that a string looks like an email address.

+ + +

Parameters

+ + + + + + + + + + + +
string$address

The email address to check

string$patternselect

A selector for the validation pattern to use :

+
    +
  • auto Pick strictest one automatically;
  • +
  • pcre8 Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
  • +
  • pcre Use old PCRE implementation;
  • +
  • php Use PHP built-in FILTER_VALIDATE_EMAIL; same as pcre8 but does not allow 'dotless' domains;
  • +
  • html5 Use the pattern given by the HTML5 spec for 'email' type form input elements.
  • +
  • noregex Don't use a regex: super fast, really dumb.
  • +
+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

send()

+ +
send() : boolean
+

Create a message and send it.

+

Uses the sending method specified by $Mailer.

+ + +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + —

false on error - See the ErrorInfo property for details of the error.

+ +
+
+ +
+ +
+
+ +
+

preSend()

+ +
preSend() : boolean
+

Prepare a message for sending.

+ + + +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

postSend()

+ +
postSend() : boolean
+

Actually send a message.

+

Send the email via the selected mechanism

+ + +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

getSMTPInstance()

+ +
getSMTPInstance() : \SMTP
+

Get an instance to use for SMTP operations.

+

Override this function to load your own SMTP implementation

+ + + +

Returns

+ \SMTP + +
+
+ +
+ +
+
+ +
+

smtpConnect()

+ +
smtpConnect(array  $options = array()) : boolean
+

Initiate a connection to an SMTP server.

+

Returns false if the operation failed.

+ +

Parameters

+ + + + + + +
array$options

An array of options compatible with stream_context_create()

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

smtpClose()

+ +
smtpClose() : void
+

Close the active SMTP session if one exists.

+ + + + + +
+
+ +
+ +
+
+ +
+

setLanguage()

+ +
setLanguage(string  $langcode = 'en', string  $lang_path = '') : boolean
+

Set the language for error messages.

+

Returns false if it cannot load the language file. +The default language is English.

+ +

Parameters

+ + + + + + + + + + + +
string$langcode

ISO 639-1 2-character language code (e.g. French is "fr")

string$lang_path

Path to the language file directory, with trailing separator (slash)

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

getTranslations()

+ +
getTranslations() : array
+

Get the array of strings for the current language.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

addrAppend()

+ +
addrAppend(string  $type, array  $addr) : string
+

Create recipient headers.

+ + +

Parameters

+ + + + + + + + + + + +
string$type
array$addr

An array of recipient, +where each recipient is a 2-element indexed array with element 0 containing an address +and element 1 containing a name, like: +array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User'))

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

addrFormat()

+ +
addrFormat(array  $addr) : string
+

Format an address for use in a message header.

+ + +

Parameters

+ + + + + + +
array$addr

A 2-element indexed array, element 0 containing an address, element 1 containing a name +like array('joe@example.com', 'Joe User')

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

wrapText()

+ +
wrapText(string  $message, integer  $length, boolean  $qp_mode = false) : string
+

Word-wrap message.

+

For use with mailers that do not automatically perform wrapping +and for quoted-printable encoded messages. +Original written by philippe.

+ +

Parameters

+ + + + + + + + + + + + + + + + +
string$message

The message to wrap

integer$length

The line length to wrap to

boolean$qp_mode

Whether to run in Quoted-Printable mode

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

utf8CharBoundary()

+ +
utf8CharBoundary(string  $encodedText, integer  $maxLength) : integer
+

Find the last character boundary prior to $maxLength in a utf-8 +quoted (printable) encoded string.

+

Original written by Colin Brown.

+ +

Parameters

+ + + + + + + + + + + +
string$encodedText

utf-8 QP text

integer$maxLength

find last character boundary prior to this length

+ + +

Returns

+ integer + +
+
+ +
+ +
+
+ +
+

setWordWrap()

+ +
setWordWrap() : void
+

Set the body wrapping.

+ + + + + +
+
+ +
+ +
+
+ +
+

createHeader()

+ +
createHeader() : string
+

Assemble message headers.

+ + + + +

Returns

+ string + —

The assembled headers

+ +
+
+ +
+ +
+
+ +
+

getMailMIME()

+ +
getMailMIME() : string
+

Get the message MIME type headers.

+ + + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

getSentMIMEMessage()

+ +
getSentMIMEMessage() : string
+

Returns the whole MIME message.

+

Includes complete headers and body. +Only valid post preSend().

+ + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

createBody()

+ +
createBody() : string
+

Assemble the message body.

+

Returns an empty string on failure.

+ + +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ string + —

The assembled message body

+ +
+
+ +
+ +
+
+ +
+

headerLine()

+ +
headerLine(string  $name, string  $value) : string
+

Format a header line.

+ + +

Parameters

+ + + + + + + + + + + +
string$name
string$value
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

textLine()

+ +
textLine(string  $value) : string
+

Return a formatted mail line.

+ + +

Parameters

+ + + + + + +
string$value
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

addAttachment()

+ +
addAttachment(string  $path, string  $name = '', string  $encoding = 'base64', string  $type = '', string  $disposition = 'attachment') : boolean
+

Add an attachment from a path on the filesystem.

+

Returns false if the file could not be found or read.

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
string$path

Path to the attachment.

string$name

Overrides the attachment name.

string$encoding

File encoding (see $Encoding).

string$type

File extension (MIME) type.

string$disposition

Disposition to use

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

getAttachments()

+ +
getAttachments() : array
+

Return the array of attachments.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

encodeString()

+ +
encodeString(string  $str, string  $encoding = 'base64') : string
+

Encode a string in requested format.

+

Returns an empty string on failure.

+ +

Parameters

+ + + + + + + + + + + +
string$str

The text to encode

string$encoding

The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

encodeHeader()

+ +
encodeHeader(string  $str, string  $position = 'text') : string
+

Encode a header string optimally.

+

Picks shortest of Q, B, quoted-printable or none.

+ +

Parameters

+ + + + + + + + + + + +
string$str
string$position
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

hasMultiBytes()

+ +
hasMultiBytes(string  $str) : boolean
+

Check if a string contains multi-byte characters.

+ + +

Parameters

+ + + + + + +
string$str

multi-byte text to wrap encode

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

has8bitChars()

+ +
has8bitChars(string  $text) : boolean
+

Does a string contain any 8-bit chars (in any charset)?

+ + +

Parameters

+ + + + + + +
string$text
+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

base64EncodeWrapMB()

+ +
base64EncodeWrapMB(string  $str, string  $linebreak = null) : string
+

Encode and wrap long multibyte strings for mail headers +without breaking lines within a character.

+

Adapted from a function by paravoid

+ +

Parameters

+ + + + + + + + + + + +
string$str

multi-byte text to wrap encode

string$linebreak

string to use as linefeed/end-of-line

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

encodeQP()

+ +
encodeQP(string  $string, integer  $line_max = 76) : string
+

Encode a string in quoted-printable format.

+

According to RFC2045 section 6.7.

+ +

Parameters

+ + + + + + + + + + + +
string$string

The text to encode

integer$line_max

Number of chars allowed on a line before wrapping

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

encodeQPphp()

+ +
encodeQPphp(string  $string, integer  $line_max = 76, boolean  $space_conv = false) : string
+

Backward compatibility wrapper for an old QP encoding function that was removed.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$string
integer$line_max
boolean$space_conv
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

encodeQ()

+ +
encodeQ(string  $str, string  $position = 'text') : string
+

Encode a string using Q encoding.

+ + +

Parameters

+ + + + + + + + + + + +
string$str

the text to encode

string$position

Where the text is going to be used, see the RFC for what that means

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

addStringAttachment()

+ +
addStringAttachment(string  $string, string  $filename, string  $encoding = 'base64', string  $type = '', string  $disposition = 'attachment') : void
+

Add a string or binary attachment (non-filesystem).

+

This method can be used to attach ascii or binary data, +such as a BLOB record from a database.

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
string$string

String attachment data.

string$filename

Name of the attachment.

string$encoding

File encoding (see $Encoding).

string$type

File extension (MIME) type.

string$disposition

Disposition to use

+ + + +
+
+ +
+ +
+
+ +
+

addEmbeddedImage()

+ +
addEmbeddedImage(string  $path, string  $cid, string  $name = '', string  $encoding = 'base64', string  $type = '', string  $disposition = 'inline') : boolean
+

Add an embedded (inline) attachment from a file.

+

This can include images, sounds, and just about any other document type. +These differ from 'regular' attachmants in that they are intended to be +displayed inline with the message, not just attached for download. +This is used in HTML messages that embed the images +the HTML refers to using the $cid value.

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string$path

Path to the attachment.

string$cid

Content ID of the attachment; Use this to reference +the content when using an embedded image in HTML.

string$name

Overrides the attachment name.

string$encoding

File encoding (see $Encoding).

string$type

File MIME type.

string$disposition

Disposition to use

+ + +

Returns

+ boolean + —

True on successfully adding an attachment

+ +
+
+ +
+ +
+
+ +
+

addStringEmbeddedImage()

+ +
addStringEmbeddedImage(string  $string, string  $cid, string  $name = '', string  $encoding = 'base64', string  $type = '', string  $disposition = 'inline') : boolean
+

Add an embedded stringified attachment.

+

This can include images, sounds, and just about any other document type. +Be sure to set the $type to an image type for images: +JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string$string

The attachment binary data.

string$cid

Content ID of the attachment; Use this to reference +the content when using an embedded image in HTML.

string$name
string$encoding

File encoding (see $Encoding).

string$type

MIME type.

string$disposition

Disposition to use

+ + +

Returns

+ boolean + —

True on successfully adding an attachment

+ +
+
+ +
+ +
+
+ +
+

inlineImageExists()

+ +
inlineImageExists() : boolean
+

Check if an inline attachment is present.

+ + + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

attachmentExists()

+ +
attachmentExists() : boolean
+

Check if an attachment (non-inline) is present.

+ + + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

alternativeExists()

+ +
alternativeExists() : boolean
+

Check if this message has an alternative body set.

+ + + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

clearAddresses()

+ +
clearAddresses() : void
+

Clear all To recipients.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearCCs()

+ +
clearCCs() : void
+

Clear all CC recipients.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearBCCs()

+ +
clearBCCs() : void
+

Clear all BCC recipients.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearReplyTos()

+ +
clearReplyTos() : void
+

Clear all ReplyTo recipients.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearAllRecipients()

+ +
clearAllRecipients() : void
+

Clear all recipient types.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearAttachments()

+ +
clearAttachments() : void
+

Clear all filesystem, string, and binary attachments.

+ + + + + +
+
+ +
+ +
+
+ +
+

clearCustomHeaders()

+ +
clearCustomHeaders() : void
+

Clear all custom headers.

+ + + + + +
+
+ +
+ +
+
+ +
+

rfcDate()

+ +
rfcDate() : string
+

Return an RFC 822 formatted date.

+ + + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

isError()

+ +
isError() : boolean
+

Check if an error occurred.

+ + + + +

Returns

+ boolean + —

True if an error did occur.

+ +
+
+ +
+ +
+
+ +
+

fixEOL()

+ +
fixEOL(string  $str) : string
+

Ensure consistent line endings in a string.

+

Changes every end of line from CRLF, CR or LF to $this->LE.

+ +

Parameters

+ + + + + + +
string$str

String to fixEOL

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

addCustomHeader()

+ +
addCustomHeader(string  $name, string  $value = null) : void
+

Add a custom header.

+

$name value can be overloaded to contain +both header name and value (name:value)

+ +

Parameters

+ + + + + + + + + + + +
string$name

Custom header name

string$value

Header value

+ + + +
+
+ +
+ +
+
+ +
+

msgHTML()

+ +
msgHTML(string  $message, string  $basedir = '', boolean  $advanced = false) : string
+

Create a message from an HTML string.

+

Automatically makes modifications for inline images and backgrounds +and creates a plain-text version by converting the HTML. +Overwrites any existing values in $this->Body and $this->AltBody

+ +

Parameters

+ + + + + + + + + + + + + + + + +
string$message

HTML message string

string$basedir

baseline directory for path

boolean$advanced

Whether to use the advanced HTML to text converter

+ + +

Returns

+ string + —

$message

+ +
+
+ +
+ +
+
+ +
+

html2text()

+ +
html2text(string  $html, boolean  $advanced = false) : string
+

Convert an HTML string into plain text.

+ + +

Parameters

+ + + + + + + + + + + +
string$html

The HTML text to convert

boolean$advanced

Should this use the more complex html2text converter or just a simple one?

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

_mime_types()

+ +
_mime_types(string  $ext = '') : string
+

Get the MIME type for a file extension.

+ + +

Parameters

+ + + + + + +
string$ext

File extension

+ + +

Returns

+ string + —

MIME type of file.

+ +
+
+ +
+ +
+
+ +
+

filenameToType()

+ +
filenameToType(string  $filename) : string
+

Map a file name to a MIME type.

+

Defaults to 'application/octet-stream', i.e.. arbitrary binary data.

+ +

Parameters

+ + + + + + +
string$filename

A file name or full path, does not need to exist as a file

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

mb_pathinfo()

+ +
mb_pathinfo(string  $path, integer|string  $options = null) : string|array
+

Multi-byte-safe pathinfo replacement.

+

Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe. +Works similarly to the one in PHP >= 5.2.0

+ +

Parameters

+ + + + + + + + + + + +
string$path

A filename or path, does not need to exist as a file

integer|string$options

Either a PATHINFO_* constant, +or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2

+ + +

Returns

+ string|array + +
+
+ +
+ +
+
+ +
+

set()

+ +
set(string  $name, mixed  $value = '') : boolean
+

Set or reset instance properties.

+

Usage Example: +$page->set('X-Priority', '3');

+ +

Parameters

+ + + + + + + + + + + +
string$name
mixed$value

NOTE: will not work with arrays, there are no arrays to set/reset

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

secureHeader()

+ +
secureHeader(string  $str) : string
+

Strip newlines to prevent header injection.

+ + +

Parameters

+ + + + + + +
string$str
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

normalizeBreaks()

+ +
normalizeBreaks(string  $text, string  $breaktype = "\r\n") : string
+

Normalize line breaks in a string.

+

Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. +Defaults to CRLF (for message bodies) and preserves consecutive breaks.

+ +

Parameters

+ + + + + + + + + + + +
string$text
string$breaktype

What kind of line break to use, defaults to CRLF

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

sign()

+ +
sign(string  $cert_filename, string  $key_filename, string  $key_pass) 
+

Set the public and private key files and password for S/MIME signing.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$cert_filename
string$key_filename
string$key_pass

Password for private key

+ + + +
+
+ +
+ +
+
+ +
+

DKIM_QP()

+ +
DKIM_QP(string  $txt) : string
+

Quoted-Printable-encode a DKIM header.

+ + +

Parameters

+ + + + + + +
string$txt
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

DKIM_Sign()

+ +
DKIM_Sign(string  $signheader) : string
+

Generate a DKIM signature.

+ + +

Parameters

+ + + + + + +
string$signheader

Header

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

DKIM_HeaderC()

+ +
DKIM_HeaderC(string  $signheader) : string
+

Generate a DKIM canonicalization header.

+ + +

Parameters

+ + + + + + +
string$signheader

Header

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

DKIM_BodyC()

+ +
DKIM_BodyC(string  $body) : string
+

Generate a DKIM canonicalization body.

+ + +

Parameters

+ + + + + + +
string$body

Message Body

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

DKIM_Add()

+ +
DKIM_Add(string  $headers_line, string  $subject, string  $body) : string
+

Create the DKIM header and body in a new message header.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$headers_line

Header lines

string$subject

Subject

string$body

Body

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

getToAddresses()

+ +
getToAddresses() : array
+

Allows for public read access to 'to' property.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

getCcAddresses()

+ +
getCcAddresses() : array
+

Allows for public read access to 'cc' property.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

getBccAddresses()

+ +
getBccAddresses() : array
+

Allows for public read access to 'bcc' property.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

getReplyToAddresses()

+ +
getReplyToAddresses() : array
+

Allows for public read access to 'ReplyTo' property.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

getAllRecipientAddresses()

+ +
getAllRecipientAddresses() : array
+

Allows for public read access to 'all_recipients' property.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

edebug()

+ +
edebug(string  $str) 
+

Output debugging info via user-defined method.

+

Only if debug output is enabled.

+ +

Parameters

+ + + + + + +
string$str
+ + + +
+
+ +
+ +
+
+ +
+

addAnAddress()

+ +
addAnAddress(string  $kind, string  $address, string  $name = '') : boolean
+

Add an address to one of the recipient arrays.

+

Addresses that have been added already return false, but do not throw exceptions

+ +

Parameters

+ + + + + + + + + + + + + + + + +
string$kind

One of 'to', 'cc', 'bcc', 'ReplyTo'

string$address

The email address to send to

string$name
+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + —

true on success, false if address already used or invalid in some way

+ +
+
+ +
+ +
+
+ +
+

sendmailSend()

+ +
sendmailSend(string  $header, string  $body) : boolean
+

Send mail using the $Sendmail program.

+ + +

Parameters

+ + + + + + + + + + + +
string$header

The message headers

string$body

The message body

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

mailSend()

+ +
mailSend(string  $header, string  $body) : boolean
+

Send mail using the PHP mail() function.

+ + +

Parameters

+ + + + + + + + + + + +
string$header

The message headers

string$body

The message body

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

smtpSend()

+ +
smtpSend(string  $header, string  $body) : boolean
+

Send mail via SMTP.

+

Returns false if there is a bad MAIL FROM, RCPT, or DATA input. +Uses the PHPMailerSMTP class by default.

+ +

Parameters

+ + + + + + + + + + + +
string$header

The message headers

string$body

The message body

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

getBoundary()

+ +
getBoundary(string  $boundary, string  $charSet, string  $contentType, string  $encoding) : string
+

Return the start of a message boundary.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$boundary
string$charSet
string$contentType
string$encoding
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

endBoundary()

+ +
endBoundary(string  $boundary) : string
+

Return the end of a message boundary.

+ + +

Parameters

+ + + + + + +
string$boundary
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

setMessageType()

+ +
setMessageType() : void
+

Set the message type.

+

PHPMailer only supports some preset message types, +not arbitrary MIME structures.

+ + + + +
+
+ +
+ +
+
+ +
+

attachAll()

+ +
attachAll(string  $disposition_type, string  $boundary) : string
+

Attach all file, string, and binary attachments to the message.

+

Returns an empty string on failure.

+ +

Parameters

+ + + + + + + + + + + +
string$disposition_type
string$boundary
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

encodeFile()

+ +
encodeFile(string  $path, string  $encoding = 'base64') : string
+

Encode a file attachment in requested format.

+

Returns an empty string on failure.

+ +

Parameters

+ + + + + + + + + + + +
string$path

The full path to the file

string$encoding

The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'

+ +

Throws

+
+
\phpmailerException
+
+
+ +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

setError()

+ +
setError(string  $msg) : void
+

Add an error message to the error container.

+ + +

Parameters

+ + + + + + +
string$msg
+ + + +
+
+ +
+ +
+
+ +
+

serverHostname()

+ +
serverHostname() : string
+

Get the server hostname.

+

Returns 'localhost.localdomain' if unknown.

+ + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

lang()

+ +
lang(string  $key) : string
+

Get an error message in the current language.

+ + +

Parameters

+ + + + + + +
string$key
+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

doCallback()

+ +
doCallback(boolean  $isSent, string  $to, string  $cc, string  $bcc, string  $subject, string  $body, string  $from = null) 
+

Perform a callback.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
boolean$isSent
string$to
string$cc
string$bcc
string$subject
string$body
string$from
+ + + +
+
+ +
+ +
+
+ +
+

mailPassthru()

+ +
mailPassthru(string  $to, string  $subject, string  $body, string  $header, string  $params) : boolean
+

Call mail() in a safe_mode-aware fashion.

+

Also, unless sendmail_path points to sendmail (or something that +claims to be sendmail), don't pass params (not a perfect fix, +but it will do)

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
string$to

To

string$subject

Subject

string$body

Message Body

string$header

Additional Header(s)

string$params

Params

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/SMTP.html b/doc/classes/SMTP.html new file mode 100644 index 00000000..1f1811c9 --- /dev/null +++ b/doc/classes/SMTP.html @@ -0,0 +1,2653 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\SMTP

+

PHPMailer RFC821 SMTP email transport class.

+

Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.

+ + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ __construct()
+ connect()
+ startTLS()
+ authenticate()
+ connected()
+ close()
+ data()
+ hello()
+ mail()
+ quit()
+ recipient()
+ reset()
+ sendAndMail()
+ verify()
+ noop()
+ turn()
+ client_send()
+ getError()
+ getLastReply()
+ setVerp()
+ getVerp()
+ setDebugOutput()
+ getDebugOutput()
+ setDebugLevel()
+ getDebugLevel()
+ setTimeout()
+ getTimeout()
+
+
+ $Version
+ $SMTP_PORT
+ $CRLF
+ $do_debug
+ $Debugoutput
+ $do_verp
+ $Timeout
+ $Timelimit
+
+
+ VERSION
+ CRLF
+ DEFAULT_SMTP_PORT
+ MAX_LINE_LENGTH
+
+
+
+
+ edebug()
+ hmac()
+ sendHello()
+ sendCommand()
+ get_lines()
+
+
+ $smtp_conn
+ $error
+ $helo_rply
+ $last_reply
+
+
+ N/A +
+
+
+
+ No private methods found +
+
+ No private properties found +
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

VERSION

+
VERSION
+

The PHPMailer SMTP version number.

+ +
+
+ +
+ +
+
+ +
+

CRLF

+
CRLF
+

SMTP line break constant.

+ +
+
+ +
+ +
+
+ +
+

DEFAULT_SMTP_PORT

+
DEFAULT_SMTP_PORT
+

The SMTP port to use if one is not specified.

+ +
+
+ +
+ +
+
+ +
+

MAX_LINE_LENGTH

+
MAX_LINE_LENGTH
+

The maximum line length allowed by RFC 2822 section 2.1.1

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$Version

+
$Version : 
+

The PHPMailer SMTP Version number.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$SMTP_PORT

+
$SMTP_PORT : 
+

SMTP server port number.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$CRLF

+
$CRLF : 
+

SMTP reply line ending.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$do_debug

+
$do_debug : 
+

Debug output level.

+

Options:

+
    +
  • 0 No output
  • +
  • 1 Commands
  • +
  • 2 Data and commands
  • +
  • 3 As 2 plus connection status
  • +
  • 4 Low-level data output
  • +
+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Debugoutput

+
$Debugoutput : 
+

How to handle debug output.

+

Options:

+
    +
  • echo Output plain-text as-is, appropriate for CLI
  • +
  • html Output escaped, line breaks converted to
    , appropriate for browser output
  • +
  • error_log Output to error log as configured in php.ini
  • +
+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$do_verp

+
$do_verp : 
+

Whether to use VERP.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$Timeout

+
$Timeout : 
+

The timeout value for connection, in seconds.

+

Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 +This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.

+ +

Type

+ +
+
+ +
+ +
+
+ +
+

$Timelimit

+
$Timelimit : 
+

The SMTP timelimit value for reads, in seconds.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$smtp_conn

+
$smtp_conn : 
+

The socket for the server connection.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$error

+
$error : 
+

Error message, if any, for the last call.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$helo_rply

+
$helo_rply : 
+

The reply the server sent to us for HELO.

+ + +

Type

+ +
+
+ +
+ +
+
+ +
+

$last_reply

+
$last_reply : 
+

The most recent reply received from the server.

+ + +

Type

+ +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

__construct()

+ +
__construct() 
+

Constructor.

+ + + + + +
+
+ +
+ +
+
+ +
+

connect()

+ +
connect(string  $host, integer  $port = null, integer  $timeout = 30, array  $options = array()) : boolean
+

Connect to an SMTP server.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$host

SMTP server IP or host name

integer$port

The port number to connect to

integer$timeout

How long to wait for the connection to open

array$options

An array of options for stream_context_create()

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

startTLS()

+ +
startTLS() : boolean
+

Initiate a TLS (encrypted) session.

+ + + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

authenticate()

+ +
authenticate(string  $username, string  $password, string  $authtype = 'LOGIN', string  $realm = '', string  $workstation = '') : boolean
+

Perform SMTP authentication.

+

Must be run after hello().

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
string$username

The user name

string$password

The password

string$authtype

The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5)

string$realm

The auth realm for NTLM

string$workstation

The auth workstation for NTLM

+ + +

Returns

+ boolean + —

True if successfully authenticated.

+ +
+
+ +
+ +
+
+ +
+

connected()

+ +
connected() : boolean
+

Check connection state.

+ + + + +

Returns

+ boolean + —

True if connected.

+ +
+
+ +
+ +
+
+ +
+

close()

+ +
close() : void
+

Close the socket and clean up the state of the class.

+

Don't use this function without first trying to use QUIT.

+ + + + +
+
+ +
+ +
+
+ +
+

data()

+ +
data(string  $msg_data) : boolean
+

Send an SMTP DATA command.

+

Issues a data command and sends the msg_data to the server, +finializing the mail transaction. $msg_data is the message +that is to be send with the headers. Each header needs to be +on a single line followed by a with the message headers +and the message body being separated by and additional . +Implements rfc 821: DATA

+ +

Parameters

+ + + + + + +
string$msg_data

Message data to send

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

hello()

+ +
hello(string  $host = '') : boolean
+

Send an SMTP HELO or EHLO command.

+

Used to identify the sending server to the receiving server. +This makes sure that client and server are in a known state. +Implements RFC 821: HELO +and RFC 2821 EHLO.

+ +

Parameters

+ + + + + + +
string$host

The host name or IP to connect to

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

mail()

+ +
mail(string  $from) : boolean
+

Send an SMTP MAIL command.

+

Starts a mail transaction from the email address specified in +$from. Returns true if successful or false otherwise. If True +the mail transaction is started and then one or more recipient +commands may be called followed by a data command. +Implements rfc 821: MAIL FROM:

+ +

Parameters

+ + + + + + +
string$from

Source address of this message

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

quit()

+ +
quit(boolean  $close_on_error = true) : boolean
+

Send an SMTP QUIT command.

+

Closes the socket if there is no error or the $close_on_error argument is true. +Implements from rfc 821: QUIT

+ +

Parameters

+ + + + + + +
boolean$close_on_error

Should the connection close if an error occurs?

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

recipient()

+ +
recipient(string  $toaddr) : boolean
+

Send an SMTP RCPT command.

+

Sets the TO argument to $toaddr. +Returns true if the recipient was accepted false if it was rejected. +Implements from rfc 821: RCPT TO:

+ +

Parameters

+ + + + + + +
string$toaddr

The address the message is being sent to

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

reset()

+ +
reset() : boolean
+

Send an SMTP RSET command.

+

Abort any transaction that is currently in progress. +Implements rfc 821: RSET

+ + + +

Returns

+ boolean + —

True on success.

+ +
+
+ +
+ +
+
+ +
+

sendAndMail()

+ +
sendAndMail(string  $from) : boolean
+

Send an SMTP SAML command.

+

Starts a mail transaction from the email address specified in $from. +Returns true if successful or false otherwise. If True +the mail transaction is started and then one or more recipient +commands may be called followed by a data command. This command +will send the message to the users terminal if they are logged +in and send them an email. +Implements rfc 821: SAML FROM:

+ +

Parameters

+ + + + + + +
string$from

The address the message is from

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

verify()

+ +
verify(string  $name) : boolean
+

Send an SMTP VRFY command.

+ + +

Parameters

+ + + + + + +
string$name

The name to verify

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

noop()

+ +
noop() : boolean
+

Send an SMTP NOOP command.

+

Used to keep keep-alives alive, doesn't actually do anything

+ + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

turn()

+ +
turn() : boolean
+

Send an SMTP TURN command.

+

This is an optional command for SMTP that this class does not support. +This method is here to make the RFC821 Definition complete for this class +and may be implemented in future +Implements from rfc 821: TURN

+ + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

client_send()

+ +
client_send(string  $data) : integer|boolean
+

Send raw data to the server.

+ + +

Parameters

+ + + + + + +
string$data

The data to send

+ + +

Returns

+ integer|boolean + —

The number of bytes sent to the server or false on error

+ +
+
+ +
+ +
+
+ +
+

getError()

+ +
getError() : array
+

Get the latest error.

+ + + + +

Returns

+ array + +
+
+ +
+ +
+
+ +
+

getLastReply()

+ +
getLastReply() : string
+

Get the last reply from the server.

+ + + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

setVerp()

+ +
setVerp(boolean  $enabled = false) 
+

Enable or disable VERP address generation.

+ + +

Parameters

+ + + + + + +
boolean$enabled
+ + + +
+
+ +
+ +
+
+ +
+

getVerp()

+ +
getVerp() : boolean
+

Get VERP address generation mode.

+ + + + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

setDebugOutput()

+ +
setDebugOutput(string  $method = 'echo') 
+

Set debug output method.

+ + +

Parameters

+ + + + + + +
string$method

The function/method to use for debugging output.

+ + + +
+
+ +
+ +
+
+ +
+

getDebugOutput()

+ +
getDebugOutput() : string
+

Get debug output method.

+ + + + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

setDebugLevel()

+ +
setDebugLevel(integer  $level) 
+

Set debug output level.

+ + +

Parameters

+ + + + + + +
integer$level
+ + + +
+
+ +
+ +
+
+ +
+

getDebugLevel()

+ +
getDebugLevel() : integer
+

Get debug output level.

+ + + + +

Returns

+ integer + +
+
+ +
+ +
+
+ +
+

setTimeout()

+ +
setTimeout(integer  $timeout) 
+

Set SMTP timeout.

+ + +

Parameters

+ + + + + + +
integer$timeout
+ + + +
+
+ +
+ +
+
+ +
+

getTimeout()

+ +
getTimeout() : integer
+

Get SMTP timeout.

+ + + + +

Returns

+ integer + +
+
+ +
+ +
+
+ +
+

edebug()

+ +
edebug(string  $str) : void
+

Output debugging info via a user-selected method.

+ + +

Parameters

+ + + + + + +
string$str

Debug string to output

+ + + +
+
+ +
+ +
+
+ +
+

hmac()

+ +
hmac(string  $data, string  $key) : string
+

Calculate an MD5 HMAC hash.

+

Works like hash_hmac('md5', $data, $key) +in case that function is not available

+ +

Parameters

+ + + + + + + + + + + +
string$data

The data to hash

string$key

The key to hash with

+ + +

Returns

+ string + +
+
+ +
+ +
+
+ +
+

sendHello()

+ +
sendHello(string  $hello, string  $host) : boolean
+

Send an SMTP HELO or EHLO command.

+

Low-level implementation used by hello()

+ +

Parameters

+ + + + + + + + + + + +
string$hello

The HELO string

string$host

The hostname to say we are

+ + +

Returns

+ boolean + +
+
+ +
+ +
+
+ +
+

sendCommand()

+ +
sendCommand(string  $command, string  $commandstring, integer|array  $expect) : boolean
+

Send a command to an SMTP server and check its return code.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$command

The command name - not sent to the server

string$commandstring

The actual command to send

integer|array$expect

One or more expected integer success codes

+ + +

Returns

+ boolean + —

True on success.

+ +
+
+ +
+ +
+
+ +
+

get_lines()

+ +
get_lines() : string
+

Read the SMTP server's response.

+

Either before eof or socket timeout occurs on the operation. +With SMTP we can tell if we have more lines to read if the +4th character is '-' symbol. If it is a space then we don't +need to read anything else.

+ + + +

Returns

+ string + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.Controller.html b/doc/classes/hhu.z.Controller.html new file mode 100644 index 00000000..10c09301 --- /dev/null +++ b/doc/classes/hhu.z.Controller.html @@ -0,0 +1,1870 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\zController

+

Abstract class for implementing an application Controller.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ __construct()
+ preFilter()
+ postFilter()
+ run()
+ render()
+
+
+ $components
+
+
+ No constants found +
+
+
+
+ set()
+ redirect()
+ checkModels()
+ getView()
+ loadModels()
+ loadView()
+ log()
+
+
+ $agent
+ $view
+ $viewData
+ $request
+ $response
+ $log
+ $linker
+
+
+ N/A +
+
+
+
+ getClassName()
+ loadComponents()
+
+
+ No private properties found +
+
+ N/A +
+
+
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$components

+
$components : array
+

Required components

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$agent

+
$agent : \nre\core\Agent
+

Corresponding Agent

+ + +

Type

+ \nre\core\Agent +
+
+ +
+ +
+
+ +
+

$view

+
$view : \nre\core\View
+

View of the Controller

+ + +

Type

+ \nre\core\View +
+
+ +
+ +
+
+ +
+

$viewData

+
$viewData : array
+

Data to pass to the View

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ +
+
+ +
+

$log

+
$log : \nre\core\Logger
+

Logger instance

+ + +

Type

+ \nre\core\Logger +
+
+ +
+ +
+
+ +
+

$linker

+
$linker : \nre\core\Linker
+

Linker instance

+ + +

Type

+ \nre\core\Linker +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $controllerName) 
+

Load the class of a Controller.

+ + +

Parameters

+ + + + + + +
string$controllerName

Name of the Controller to load

+ +

Throws

+
+
\nre\exceptions\ControllerNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $controllerName, string  $layoutName, string  $action, string  $agent) 
+

Instantiate a Controller (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$controllerName

Name of the Controller to instantiate

string$layoutName

Name of the current Layout

string$action

Current Action

string$agent

Corresponding Agent

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(string  $layoutName, string  $action, \nre\core\Agent  $agent) 
+

Construct a new application Controller.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$layoutName

Name of the current Layout

string$action

Current Action

\nre\core\Agent$agent

Corresponding Agent

+ +

Throws

+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

preFilter()

+ +
preFilter(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Prefilter that is executed before running the Controller.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

postFilter()

+ +
postFilter(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Postfilter that is executed after running the Controller.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Run the Controller.

+

This method executes the Action of the Controller defined by +the current Request.

+ +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $viewData = null) : string
+

Generate the output.

+ + +

Parameters

+ + + + + + +
array$viewData

Data to pass to the View

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

set()

+ +
set(string  $name, mixed  $data) 
+

Set data for the View.

+ + +

Parameters

+ + + + + + + + + + + +
string$name

Key

mixed$data

Value

+ + + +
+
+ +
+ +
+
+ +
+

redirect()

+ +
redirect(string  $url) 
+

Redirect to the given URL.

+ + +

Parameters

+ + + + + + +
string$url

Relative URL

+ + + +
+
+ +
+ +
+
+ +
+

checkModels()

+ +
checkModels(string  $modelName) : boolean
+

Check if Models of this Controller are loaded and available.

+ + +

Parameters

+ + + + + + +
string$modelName

Arbitrary number of Models to check

+ + +

Returns

+ boolean + —

All given Models are loaded and available

+ +
+
+ +
+ +
+
+ +
+

getView()

+ +
getView() : \nre\core\View
+

Get the View of the Controller

+ + + + +

Returns

+ \nre\core\View + —

View of the Controller

+ +
+
+ +
+ +
+
+ +
+

loadModels()

+ +
loadModels() 
+

Load the Models of this Controller.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

loadView()

+ +
loadView(string  $layoutName, string  $action) 
+

Load the View of this Controller.

+ + +

Parameters

+ + + + + + + + + + + +
string$layoutName

Name of the current Layout

string$action

Current Action

+ +

Throws

+
+
\nre\exceptions\ViewNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(string  $message, integer  $logMode = \nre\core\Logger::LOGMODE_AUTO) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
string$message

Error message to log

integer$logMode

Log mode (optional)

+ + + +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $controllerName) : string
+

Determine the classname for the given Controller name.

+ + +

Parameters

+ + + + + + +
string$controllerName

Controller name to get classname of

+ + +

Returns

+ string + —

Classname for the Controller name

+ +
+
+ +
+ +
+
+ +
+

loadComponents()

+ +
loadComponents() 
+

Load the Components of this Controller.

+ + + +

Throws

+
+
\nre\exceptions\ComponentNotValidException
+
+
\nre\exceptions\ComponentNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.Model.html b/doc/classes/hhu.z.Model.html new file mode 100644 index 00000000..666c68b6 --- /dev/null +++ b/doc/classes/hhu.z.Model.html @@ -0,0 +1,1292 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\zModel

+

Abstract class for implementing an application Model.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ __construct()
+ load()
+ factory()
+
+
+ No public properties found +
+
+ No constants found +
+
+
+
+ No protected methods found +
+
+ $db
+
+
+ N/A +
+
+
+
+ loadDriver()
+ connect()
+ getClassName()
+ loadModels()
+
+
+ No private properties found +
+
+ N/A +
+
+
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$db

+
$db : \nre\models\DatabaseDriver
+

Database connection

+ + +

Type

+ \nre\models\DatabaseDriver +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

__construct()

+ +
__construct() 
+

Construct a new application Model.

+

TODO Catch exception

+ + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $modelName) 
+

Load the class of a Model.

+ + +

Parameters

+ + + + + + +
string$modelName

Name of the Model to load

+ +

Throws

+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $modelName) 
+

Instantiate a Model (Factory Pattern).

+ + +

Parameters

+ + + + + + +
string$modelName

Name of the Model to instantiate

+ + + +
+
+ +
+ +
+
+ +
+

loadDriver()

+ +
loadDriver(string  $driverName) 
+

Load the database driver.

+ + +

Parameters

+ + + + + + +
string$driverName

Name of the database driver

+ +

Throws

+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

connect()

+ +
connect(string  $driverName, array  $config) 
+

Establish a connection to the database.

+ + +

Parameters

+ + + + + + + + + + + +
string$driverName

Name of the database driver

array$config

Connection settings

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $modelName) : string
+

Determine the classname for the given Model name.

+ + +

Parameters

+ + + + + + +
string$modelName

Model name to get classname of

+ + +

Returns

+ string + —

Classname fore the Model name

+ +
+
+ +
+ +
+
+ +
+

loadModels()

+ +
loadModels() 
+

Load the Models of this Model.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.TextFormatter.html b/doc/classes/hhu.z.TextFormatter.html new file mode 100644 index 00000000..e5d900e1 --- /dev/null +++ b/doc/classes/hhu.z.TextFormatter.html @@ -0,0 +1,1117 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\zTextFormatter

+

Class to format text with different syntax tags.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ __construct()
+ t()
+
+
+ No public properties found +
+
+ No constants found +
+
+
+
+ No protected methods found +
+
+ No protected properties found +
+
+ N/A +
+
+
+
+ loadMediaModel()
+
+
+ $linker
+ $Media
+
+
+ N/A +
+
+
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$linker

+
$linker : \nre\core\Linker
+

Linker to create links.

+ + +

Type

+ \nre\core\Linker +
+
+ +
+ +
+
+ +
+

$Media

+
$Media : \nre\core\Model
+

Media-Model to retrieve media data

+ + +

Type

+ \nre\core\Model +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Linker  $linker) 
+

Create a new text formatter.

+ + +

Parameters

+ + + + + + +
\nre\core\Linker$linker

Linker to create links with

+ + + +
+
+ +
+ +
+
+ +
+

t()

+ +
t(string  $string) : string
+

Format a string.

+ + +

Parameters

+ + + + + + +
string$string

String to format

+ + +

Returns

+ string + —

Formatted string

+ +
+
+ +
+ +
+
+ +
+

loadMediaModel()

+ +
loadMediaModel() : boolean
+

Load the Media-Model if it is not loaded

+ + + + +

Returns

+ boolean + —

Whether the Media-Model has been loaded or not

+ +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.Utils.html b/doc/classes/hhu.z.Utils.html new file mode 100644 index 00000000..38a7b5a4 --- /dev/null +++ b/doc/classes/hhu.z.Utils.html @@ -0,0 +1,1204 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\zUtils

+

Class for implementing utility methods.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ t()
+ htmlspecialchars_utf8()
+ shortenString()
+ sendMail()
+ getMimetype()
+
+
+ No public properties found +
+
+ No constants found +
+
+
+
+ No protected methods found +
+
+ No protected properties found +
+
+ N/A +
+
+
+
+ No private methods found +
+
+ No private properties found +
+
+ N/A +
+
+
+
+ +
+ + + + +
+

Methods

+ +
+ +
+
+ +
+

t()

+ +
t(string  $string) : string
+

Mask HTML-chars for save output.

+ + +

Parameters

+ + + + + + +
string$string

String to be masked

+ + +

Returns

+ string + —

Masked string

+ +
+
+ +
+ +
+
+ +
+

htmlspecialchars_utf8()

+ +
htmlspecialchars_utf8(string  $string) : string
+

‚htmlspecialchars‘ with support for UTF-8.

+ + +

Parameters

+ + + + + + +
string$string

String to be masked

+ + +

Returns

+ string + —

Masked string

+ +
+
+ +
+ +
+
+ +
+

shortenString()

+ +
shortenString(string  $string, integer  $length, integer  $scope) : string
+

Cut a string to the given length but only word boundaries.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
string$string

String to cut

integer$length

Length to cut string

integer$scope

Maximum length to cut string regardless word boundaries

+ + +

Returns

+ string + —

Cutted string

+ +
+
+ +
+ +
+
+ +
+

sendMail()

+ +
sendMail(mixed  $to, string  $messageAction, boolean  $html = false, array  $params = null, \nre\core\Linker  $linker = null) 
+

Send an e‑mail.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
mixed$to

One (string) or many (array) receivers

string$messageAction

Message Action

boolean$html

Whether mail should be formatted as HTML or not

array$params

Parameters to pass

\nre\core\Linker$linker

Linker instance

+ +

Throws

+
+
\hhu\z\exceptions\MailingException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getMimetype()

+ +
getMimetype(string  $filename, string  $defaultMimetype = null) : string
+

Detect Mimetype of a file.

+ + +

Parameters

+ + + + + + + + + + + +
string$filename

Name of file to detect Mimetype of

string$defaultMimetype

Default Mimetype to use

+ + +

Returns

+ string + —

Detected Mimetype of file

+ +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.QuesttypeAgent.html b/doc/classes/hhu.z.agents.QuesttypeAgent.html new file mode 100644 index 00000000..14dcbe21 --- /dev/null +++ b/doc/classes/hhu.z.agents.QuesttypeAgent.html @@ -0,0 +1,2142 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agentsQuesttypeAgent

+

Abstract class for implementing a QuesttypeAgent.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ checkClass()
+ saveAnswersOfCharacter()
+ matchAnswersOfCharacter()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+ loadClass()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $questtypeName) 
+

Load a QuesttypeAgent.

+ + +

Parameters

+ + + + + + +
string$questtypeName

Name of the QuesttypeAgent to load

+ +

Throws

+
+
\hhu\z\exceptions\QuesttypeAgentNotFoundException
+
+
\hhu\z\exceptions\QuesttypeAgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $questtypeName, \hhu\z\agents\Request  $request, \hhu\z\agents\Response  $response, \hhu\z\agents\Logger  $log = null) 
+

Instantiate a QuesttypeAgent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$questtypeName

Name of the QuesttypeAgent to instantiate

\hhu\z\agents\Request$request

Current request

\hhu\z\agents\Response$response

Current respone

\hhu\z\agents\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\hhu\z\exceptions\QuesttypeModelNotValidException
+
+
\hhu\z\exceptions\QuesttypeModelNotFoundException
+
+
\hhu\z\exceptions\QuesttypeControllerNotValidException
+
+
\hhu\z\exceptions\QuesttypeControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

checkClass()

+ +
checkClass(string  $className, string  $parentClassName) 
+

Check inheritance of the QuesttypeAgent-class.

+ + +

Parameters

+ + + + + + + + + + + +
string$className

Name of the class to check

string$parentClassName

Name of the parent class

+ +

Throws

+
+
\nre\exceptions\ClassNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

saveAnswersOfCharacter()

+ +
saveAnswersOfCharacter(array  $seminary, array  $questgroup, array  $quest, array  $character, array  $answers) 
+

Save the answers of a Character for a Quest.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
array$seminary

Current Seminary data

array$questgroup

Current Questgroup data

array$quest

Current Quest data

array$character

Current Character data

array$answers

Character answers for the Quest

+ + + +
+
+ +
+ +
+
+ +
+

matchAnswersOfCharacter()

+ +
matchAnswersOfCharacter(array  $seminary, array  $questgroup, array  $quest, array  $character, array  $answers) 
+

Check if answers of a Character for a Quest match the correct ones.

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
array$seminary

Current Seminary data

array$questgroup

Current Questgroup data

array$quest

Current Quest data

array$character

Current Character data

array$answers

Character answers for the Quest

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new QuesttypeAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\hhu\z\exceptions\QuesttypeModelNotValidException
+
+
\hhu\z\exceptions\QuesttypeModelNotFoundException
+
+
\hhu\z\exceptions\QuesttypeControllerNotValidException
+
+
\hhu\z\exceptions\QuesttypeControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\hhu\z\exceptions\QuesttypeModelNotValidException
+
+
\hhu\z\exceptions\QuesttypeModelNotFoundException
+
+
\hhu\z\exceptions\QuesttypeControllerNotValidException
+
+
\hhu\z\exceptions\QuesttypeControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $questtypeName, string  $agentType = null) : string
+

Determine the Agent-classname for the given Questtype-name.

+ + +

Parameters

+ + + + + + + + + + + +
string$questtypeName

Questtype-name to get Agent-classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Questtype-name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ +
+

loadClass()

+ +
loadClass(string  $questtypeName, string  $fullClassName) 
+

Load the class of a QuesttypeAgent.

+ + +

Parameters

+ + + + + + + + + + + +
string$questtypeName

Name of the QuesttypeAgent to load

string$fullClassName

Name of the class to load

+ +

Throws

+
+
\nre\exceptions\ClassNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.ToplevelAgent.html b/doc/classes/hhu.z.agents.ToplevelAgent.html new file mode 100644 index 00000000..2ad9720a --- /dev/null +++ b/doc/classes/hhu.z.agents.ToplevelAgent.html @@ -0,0 +1,2264 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agentsToplevelAgent

+

Abstract class for implementing an application Controller.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ run()
+ render()
+ getIntermediateAgent()
+ load()
+ factory()
+
+
+ $controller
+
+
+ STAGE_LOAD
+ STAGE_RUN
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ addSubAgent()
+ actionConstruct()
+ loadController()
+ log()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ loadIntermediateAgent()
+ _loadIntermediateAgent()
+ _run()
+ runIntermediateAgent()
+ error()
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+ $layout
+ $intermediateAgent
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

STAGE_LOAD

+
STAGE_LOAD
+

Stage: Load

+ +
+
+ +
+ +
+
+ +
+

STAGE_RUN

+
STAGE_RUN
+

Stage: Run

+ +
+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ +
+
+ +
+

$layout

+
$layout : \nre\core\Layout
+

Layout instace

+ + +

Type

+ \nre\core\Layout +
+
+ +
+ +
+
+ +
+

$intermediateAgent

+
$intermediateAgent : \nre\agents\IntermediateAgent
+

IntermediateAgent instance

+ + +

Type

+ \nre\agents\IntermediateAgent +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

getIntermediateAgent()

+ +
getIntermediateAgent() : \nre\agents\IntermediateAgent
+

Return the IntermediateAgent.

+ + + + +

Returns

+ \nre\agents\IntermediateAgent + —

IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new ToplevlAgent

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

\nre\core\Logger$log

Logger instance

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

loadIntermediateAgent()

+ +
loadIntermediateAgent() 
+

Load IntermediateAgent defined by the current request.

+ + + +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_loadIntermediateAgent()

+ +
_loadIntermediateAgent() 
+

Load IntermediateAgent defined by the current request.

+ + + +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_run()

+ +
_run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\AccessDeniedException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

runIntermediateAgent()

+ +
runIntermediateAgent() 
+

Run IntermediateAgent.

+ + + +

Throws

+
+
\nre\exceptions\AccessDeniedException
+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
+ + +
+
+ +
+ +
+
+ +
+

error()

+ +
error(\Exception  $exception, integer  $httpStatusCode, string  $stage = self::STAGE_LOAD) 
+

Handle an error that occurred during +loading/cnostructing/running of the IntermediateAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$httpStatusCode

HTTP-statuscode

string$stage

Stage of execution

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.MailreceiverAgent.html b/doc/classes/hhu.z.agents.bottomlevel.MailreceiverAgent.html new file mode 100644 index 00000000..70ad0804 --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.MailreceiverAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelMailreceiverAgent

+

Agent to generate a mail receiver salutation.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.MenuAgent.html b/doc/classes/hhu.z.agents.bottomlevel.MenuAgent.html new file mode 100644 index 00000000..7bedee57 --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.MenuAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelMenuAgent

+

Agent to display a menu.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.QuestgroupshierarchypathAgent.html b/doc/classes/hhu.z.agents.bottomlevel.QuestgroupshierarchypathAgent.html new file mode 100644 index 00000000..0f8575a4 --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.QuestgroupshierarchypathAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelQuestgroupshierarchypathAgent

+

Agent to display the Questgroups hierarchy path.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.SeminarybarAgent.html b/doc/classes/hhu.z.agents.bottomlevel.SeminarybarAgent.html new file mode 100644 index 00000000..46cc35f9 --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.SeminarybarAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelSeminarybarAgent

+

Agent to display a sidebar with Seminary related information.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.SeminarymenuAgent.html b/doc/classes/hhu.z.agents.bottomlevel.SeminarymenuAgent.html new file mode 100644 index 00000000..4bd07065 --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.SeminarymenuAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelSeminarymenuAgent

+

Agent to display a menu with Seminary related links.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.bottomlevel.UserrolesAgent.html b/doc/classes/hhu.z.agents.bottomlevel.UserrolesAgent.html new file mode 100644 index 00000000..74030f3e --- /dev/null +++ b/doc/classes/hhu.z.agents.bottomlevel.UserrolesAgent.html @@ -0,0 +1,1971 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\bottomlevelUserrolesAgent

+

Agent to display and manage userroles.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ load()
+ factory()
+ run()
+ render()
+ user()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

user()

+ +
user(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: user.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.AchievementsAgent.html b/doc/classes/hhu.z.agents.intermediate.AchievementsAgent.html new file mode 100644 index 00000000..e3f78376 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.AchievementsAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateAchievementsAgent

+

Agent to list Achievements.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.CharactergroupsAgent.html b/doc/classes/hhu.z.agents.intermediate.CharactergroupsAgent.html new file mode 100644 index 00000000..7c43eaec --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.CharactergroupsAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateCharactergroupsAgent

+

Agent to display Character groups.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.CharactergroupsquestsAgent.html b/doc/classes/hhu.z.agents.intermediate.CharactergroupsquestsAgent.html new file mode 100644 index 00000000..d42a9971 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.CharactergroupsquestsAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateCharactergroupsquestsAgent

+

Agent to display Character groups Quests.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.CharactersAgent.html b/doc/classes/hhu.z.agents.intermediate.CharactersAgent.html new file mode 100644 index 00000000..2d3e3f9a --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.CharactersAgent.html @@ -0,0 +1,2052 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateCharactersAgent

+

Agent to list registered Characters and their data.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+ character()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

character()

+ +
character(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: character.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.CharactertypesAgent.html b/doc/classes/hhu.z.agents.intermediate.CharactertypesAgent.html new file mode 100644 index 00000000..c3b552ff --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.CharactertypesAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateCharactertypesAgent

+

Agent to handle Charactertyes of a Seminary.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.ErrorAgent.html b/doc/classes/hhu.z.agents.intermediate.ErrorAgent.html new file mode 100644 index 00000000..b63ed165 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.ErrorAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateErrorAgent

+

Agent to show an error page.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.IntroductionAgent.html b/doc/classes/hhu.z.agents.intermediate.IntroductionAgent.html new file mode 100644 index 00000000..5fa8154d --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.IntroductionAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateIntroductionAgent

+

Agent to show an introduction page.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.LibraryAgent.html b/doc/classes/hhu.z.agents.intermediate.LibraryAgent.html new file mode 100644 index 00000000..5197a5b2 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.LibraryAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateLibraryAgent

+

Agent to list Quest topics.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.MailAgent.html b/doc/classes/hhu.z.agents.intermediate.MailAgent.html new file mode 100644 index 00000000..475e1b34 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.MailAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateMailAgent

+

Agent to generate a mail-message.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.MediaAgent.html b/doc/classes/hhu.z.agents.intermediate.MediaAgent.html new file mode 100644 index 00000000..eb726f1f --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.MediaAgent.html @@ -0,0 +1,2012 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateMediaAgent

+

Agent to process and show media.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ index()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

index()

+ +
index(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: index.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.QuestgroupsAgent.html b/doc/classes/hhu.z.agents.intermediate.QuestgroupsAgent.html new file mode 100644 index 00000000..dd07c9b0 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.QuestgroupsAgent.html @@ -0,0 +1,2132 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateQuestgroupsAgent

+

Agent to display Questgroups.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ questgroup()
+ edit()
+ edittexts()
+ delete()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

questgroup()

+ +
questgroup(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: questgroup.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

edit()

+ +
edit(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: edit.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

edittexts()

+ +
edittexts(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: edittexts.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

delete()

+ +
delete(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: delete.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.QuestgroupshierarchyAgent.html b/doc/classes/hhu.z.agents.intermediate.QuestgroupshierarchyAgent.html new file mode 100644 index 00000000..52aaebe7 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.QuestgroupshierarchyAgent.html @@ -0,0 +1,1972 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateQuestgroupshierarchyAgent

+

Agent to manage Questgroupshierarchy.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+ +
+ +
+
+ +
+

newInlineErrorService()

+ +
newInlineErrorService() 
+

Handle a hardcore error that could not be handled by the +system.

+ + + + + +
+
+ +
+ +
+
+ + + + +
+ + + diff --git a/doc/classes/hhu.z.agents.intermediate.QuestsAgent.html b/doc/classes/hhu.z.agents.intermediate.QuestsAgent.html new file mode 100644 index 00000000..4a35e7d0 --- /dev/null +++ b/doc/classes/hhu.z.agents.intermediate.QuestsAgent.html @@ -0,0 +1,2292 @@ + + + + + + Questlab + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ + + +

\hhu\z\agents\intermediateQuestsAgent

+

Agent to display Quests.

+ + + +
+

Summary

+
+
+ Methods +
+
+ Properties +
+
+ Constants +
+
+
+
+ getLayout()
+ load()
+ factory()
+ run()
+ render()
+ quest()
+ submissions()
+ submission()
+ create()
+ edit()
+ edittask()
+ edittexts()
+ delete()
+
+
+ $controller
+
+
+ INLINEERROR_AGENT
+
+
+
+
+ __construct()
+ actionConstruct()
+ loadController()
+ log()
+ addSubAgent()
+ _addSubAgent()
+
+
+ $log
+ $subAgents
+
+
+ N/A +
+
+
+
+ getAgentType()
+ getClassName()
+ newSubAgent()
+ renderSubAgent()
+ errorInline()
+ newInlineError()
+ newInlineErrorService()
+
+
+ $request
+ $response
+
+
+ N/A +
+
+
+
+ +
+ + +
+
+

Constants

+
+ +
+ +
+
+ +
+

INLINEERROR_AGENT

+
INLINEERROR_AGENT
+

Name of BottomlevelAgent for showing inline errors

+ +
+
+ +
+ + + +
+
+

Properties

+
+ +
+ +
+
+ +
+

$controller

+
$controller : \nre\core\Controller
+

Controller of this Agent

+ + +

Type

+ \nre\core\Controller +
+
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+

$subAgents

+
$subAgents : array
+

SubAgents

+ + +

Type

+ array +
+
+ +
+ +
+
+ +
+

$request

+
$request : \nre\core\Request
+

Current request

+ + +

Type

+ \nre\core\Request +
+
+ +
+ +
+
+ +
+

$response

+
$response : \nre\core\Response
+

Current response

+ + +

Type

+ \nre\core\Response +
+
+ +
+ + + +
+

Methods

+ +
+ +
+
+ +
+

getLayout()

+ +
getLayout(string  $agentName) : string
+

Get the layout if it was explicitly defined.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ + +

Returns

+ string + —

Layout of the IntermediateAgent

+ +
+
+ +
+ +
+
+ +
+

load()

+ +
load(string  $agentName) 
+

Load the class of an Agent.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

factory()

+ +
factory(string  $agentName, \nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Instantiate an Agent (Factory Pattern).

+ + +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
string$agentName

Name of the Agent to instantiate

\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

run()

+ +
run(\nre\core\Request  $request, \nre\core\Response  $response) : \Exception
+

Run the Controller of this Agent and its SubAgents.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ +

Throws

+
+
\nre\exceptions\ParamsNotValidException
+
+
\nre\exceptions\IdNotFoundException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\ActionNotFoundException
+
+
+ +

Returns

+ \Exception + —

Last occurred exception of SubAgents

+ +
+
+ +
+ +
+
+ +
+

render()

+ +
render(array  $data = array()) : string
+

Generate output of the Controller of this Agent and its +SubAgents.

+ + +

Parameters

+ + + + + + +
array$data

View data

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

quest()

+ +
quest(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: quest.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

submissions()

+ +
submissions(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: submissions.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

submission()

+ +
submission(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: submission.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

create()

+ +
create(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: create.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

edit()

+ +
edit(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: edit.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

edittask()

+ +
edittask(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: edittask.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

edittexts()

+ +
edittexts(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: edittexts.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

delete()

+ +
delete(\nre\core\Request  $request, \nre\core\Response  $response) 
+

Action: delete.

+ + +

Parameters

+ + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response

Current response

+ + + +
+
+ +
+ +
+
+ +
+

__construct()

+ +
__construct(\nre\core\Request  $request, \nre\core\Response  $response, \nre\core\Logger  $log = null) 
+

Construct a new Agent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
\nre\core\Request$request

Current request

\nre\core\Response$response
\nre\core\Logger$log

Log-system

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

actionConstruct()

+ +
actionConstruct() 
+

Construct SubAgents (per Action).

+ + + + + +
+
+ +
+ +
+
+ +
+

loadController()

+ +
loadController() 
+

Load the Controller of this Agent.

+ + + +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\DriverNotValidException
+
+
\nre\exceptions\DriverNotFoundException
+
+
\nre\exceptions\ViewNotFoundException
+
+
\nre\exceptions\ModelNotValidException
+
+
\nre\exceptions\ModelNotFoundException
+
+
\nre\exceptions\ControllerNotValidException
+
+
\nre\exceptions\ControllerNotFoundException
+
+
+ + +
+
+ +
+ +
+
+ +
+

log()

+ +
log(\Exception  $exception, integer  $logMode) 
+

Log an error.

+ + +

Parameters

+ + + + + + + + + + + +
\Exception$exception

Occurred exception

integer$logMode

Log mode

+ + + +
+
+ +
+ +
+
+ +
+

addSubAgent()

+ +
addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

_addSubAgent()

+ +
_addSubAgent(string  $agentName) 
+

Load a SubAgent and add it.

+ + +

Parameters

+ + + + + + +
string$agentName

Name of the Agent to load

+ +

Throws

+
+
\nre\exceptions\ServiceUnavailableException
+
+
\nre\exceptions\DatamodelException
+
+
\nre\exceptions\AgentNotFoundException
+
+
\nre\exceptions\AgentNotValidException
+
+
+ + +
+
+ +
+ +
+
+ +
+

getAgentType()

+ +
getAgentType() : string
+

Determine the type of an Agent.

+ + + + +

Returns

+ string + —

Agent type

+ +
+
+ +
+ +
+
+ +
+

getClassName()

+ +
getClassName(string  $agentName, string  $agentType) : string
+

Determine the classname for the given Agent name.

+ + +

Parameters

+ + + + + + + + + + + +
string$agentName

Agent name to get classname of

string$agentType

Agent type of given Agent name

+ + +

Returns

+ string + —

Classname for the Agent name

+ +
+
+ +
+ +
+
+ +
+

newSubAgent()

+ +
newSubAgent(string  $agentName) : array
+

Create a new SubAgent.

+ + +

Parameters

+ + + + + + +
string$agentName

Agent name

+ +

Throws

+
+
\nre\exceptions\DatamodelException
+
+
+ +

Returns

+ array + —

SubAgent

+ +
+
+ +
+ +
+
+ +
+

renderSubAgent()

+ +
renderSubAgent(array  $subAgent) : string
+

Render a SubAgent.

+ + +

Parameters

+ + + + + + +
array$subAgent

SubAgent to render

+ + +

Returns

+ string + —

Generated output

+ +
+
+ +
+ +
+
+ +
+

errorInline()

+ +
errorInline(array  $subAgent, \nre\core\Request  $request, \nre\core\Excepiton  $exception) : array
+

Handle the exception of a SubAgent.

+ + +

Parameters

+ + + + + + + + + + + + + + + + +
array$subAgent

Original (Sub-) Agent

\nre\core\Request$request

Current request

\nre\core\Excepiton$exception

Occurred exception

+ + +

Returns

+ array + —

InlineError-SubAgent

+ +
+
+ +
+ +
+
+ +
+

newInlineError()

+ +
newInlineError(string  $label, \Exception  $exception) 
+

Create a new InlineError.

+ + +

Parameters

+ + + + + + + + + + + +
string$label

Name of the original Agent

\Exception$exception

Occurred exception

+ + + +
+
+