diff --git a/agents/intermediate/CharactergroupsqueststationsAgent.inc b/agents/intermediate/CharactergroupsqueststationsAgent.inc index dfbe47ba..5799d070 100644 --- a/agents/intermediate/CharactergroupsqueststationsAgent.inc +++ b/agents/intermediate/CharactergroupsqueststationsAgent.inc @@ -35,7 +35,7 @@ /** - * Action: quest. + * Action: station. * * @param \nre\core\Request $request Current request * @param \nre\core\Response $response Current response @@ -46,6 +46,45 @@ $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), 'charactergroups'); } + + /** + * 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) + { + // Add Moodpic + $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), 'charactergroups'); + } + + + /** + * 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) + { + // Add Moodpic + $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), 'charactergroups'); + } + + + /** + * 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) + { + // Add Moodpic + $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), 'charactergroups'); + } + } ?> diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index 514b6ab0..28326f18 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -305,8 +305,10 @@ 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('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsqueststations/index/$1/$2/$3?layout=ajax', true), - array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsqueststations/station/$1/$2/$3/$4', true), + array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsqueststations/index/$1/$2/$3?layout=ajax', true), + array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/create/?$', 'charactergroupsqueststations/create/$1/$2/$3', true), + array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/([^/]+)/(edit|delete)/?$', 'charactergroupsqueststations/$5/$1/$2/$3/$4', true), + array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsqueststations/station/$1/$2/$3/$4', 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), @@ -362,8 +364,9 @@ 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('^charactergroupsqueststations/index/(.*)$', 'charactergroupsqueststations/$1', true), - array('^charactergroupsqueststations/station/(.*)$', 'charactergroupsqueststations/$1', true), + array('^charactergroupsqueststations/index/(.*)$', 'charactergroupsqueststations/$1', true), + array('^charactergroupsqueststations/station/(.*)$', 'charactergroupsqueststations/$1', true), + array('^charactergroupsqueststations/(create|edit|delete)/(.*)$', 'charactergroupsqueststations/$2/$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), diff --git a/controllers/CharactergroupsqueststationsController.inc b/controllers/CharactergroupsqueststationsController.inc index 4f436458..294dc05e 100644 --- a/controllers/CharactergroupsqueststationsController.inc +++ b/controllers/CharactergroupsqueststationsController.inc @@ -26,6 +26,12 @@ * @var array */ public $models = array('seminaries', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'stationtypes', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); /** * User permissions * @@ -194,6 +200,421 @@ } + /** + * Action: create. + * + * Create a new Character groups Quest Station for a Character + * groups Quest. + * + * @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 create($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 Quest types + $stationtypes = $this->Stationtypes->getStationtypes(); + foreach($stationtypes as &$stationtype) { + $stationtype['selected'] = false; + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = ''; + $task = ''; + $longitude = null; + $latitude = null; + $rightText = ''; + $wrongText = ''; + $fields = array('title'); + $validation = array(); + + // Create a new Station + 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->Charactergroupsqueststations->stationTitleExists($quest['id'], $title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $task = $this->request->getPostParam('task'); + $rightText = $this->request->getPostParam('rightText'); + $wrongText = $this->request->getPostParam('wrongText'); + + // Validate Stationtype + $stationtypeIndex = null; + foreach($stationtypes as $index => &$stationtype) + { + $stationtype['selected'] = ($stationtype['url'] == $this->request->getPostParam('stationtype')); + if($stationtype['selected']) { + $stationtypeIndex = $index; + } + } + if(is_null($stationtypeIndex)) { + throw new \nre\exceptions\ParamsNotValidException($stationtype); + } + + // 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 new Station + if($validation === true) + { + $stationId = $this->Charactergroupsqueststations->createStation( + $quest['id'], + $stationtypes[$stationtypeIndex]['id'], + $title, + $task, + $latitude, + $longitude, + $rightText, + $wrongText + ); + $station = $this->Charactergroupsqueststations->getStationById($stationId); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsqueststation-%s', $station['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsqueststations->setPictureForStation($station['id'], $mediaId); + } + } + + // Redirect to Station page + $this->redirect( + $this->linker->link( + array( + 'station', + $seminary['url'], + $groupsgroup['url'], + $quest['url'], + $station['url'] + ), + 1 + ) + ); + } + } + + + // Set title + $this->addTitle(_('Create Station')); + $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('title', $title); + $this->set('task', $task); + $this->set('longitude', $longitude); + $this->set('latitude', $latitude); + $this->set('righttext', $rightText); + $this->set('wrongtext', $wrongText); + $this->set('mimetypes', $mimetypes); + $this->set('stationtypes', $stationtypes); + $this->set('validation', $validation); + } + + + /** + * Action: edit. + * + * Edit a Station of a Character groups Quest. + * + * @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 + * @param string $stationUrl URL of station + */ + public function edit($seminaryUrl, $groupsgroupUrl, $questUrl, $stationUrl) + { + // 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 Station + $station = $this->Charactergroupsqueststations->getStationByUrl($quest['id'], $stationUrl); + + // Get Quest types + $stationtypes = $this->Stationtypes->getStationtypes(); + foreach($stationtypes as &$stationtype) { + $stationtype['selected'] = false; + } + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = $station['title']; + $task = $station['task']; + $longitude = $station['longitude']; + $latitude = $station['latitude']; + $rightText = $station['righttext']; + $wrongText = $station['wrongtext']; + $fields = array('title'); + $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->Charactergroupsqueststations->stationTitleExists($quest['id'], $title, $station['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $task = $this->request->getPostParam('task'); + $rightText = $this->request->getPostParam('rightText'); + $wrongText = $this->request->getPostParam('wrongText'); + + // Validate Stationtype + $stationtypeIndex = null; + foreach($stationtypes as $index => &$stationtype) + { + $stationtype['selected'] = ($stationtype['url'] == $this->request->getPostParam('stationtype')); + if($stationtype['selected']) { + $stationtypeIndex = $index; + } + } + if(is_null($stationtypeIndex)) { + throw new \nre\exceptions\ParamsNotValidException($stationtype); + } + + // 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 Station + if($validation === true) + { + $this->Charactergroupsqueststations->editStation( + $station['id'], + $stationtypes[$stationtypeIndex]['id'], + $title, + $task, + $latitude, + $longitude, + $rightText, + $wrongText + ); + $station = $this->Charactergroupsqueststations->getStationById($station['id']); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createQuestMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsqueststation-%s', $station['url']), + '', + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsqueststations->setPictureForStation($station['id'], $mediaId); + } + } + + // Redirect to Station page + $this->redirect( + $this->linker->link( + array( + 'station', + $seminary['url'], + $groupsgroup['url'], + $quest['url'], + $station['url'] + ), + 1 + ) + ); + } + } + + + // Set title + $this->addTitle(_('Edit Station')); + $this->addTitle($station['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('title', $title); + $this->set('task', $task); + $this->set('longitude', $longitude); + $this->set('latitude', $latitude); + $this->set('righttext', $rightText); + $this->set('wrongtext', $wrongText); + $this->set('mimetypes', $mimetypes); + $this->set('stationtypes', $stationtypes); + $this->set('validation', $validation); + } + + + /** + * Action: delete. + * + * Delete a Station of a Character groups Quest. + * + * @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 + * @param string $stationUrl URL of station + */ + public function delete($seminaryUrl, $groupsgroupUrl, $questUrl, $stationUrl) + { + // 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 Station + $station = $this->Charactergroupsqueststations->getStationByUrl($quest['id'], $stationUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Charactergroupsqueststations->deleteStation( + $station['id'] + ); + + // Redirect to overview + $this->redirect( + $this->linker->link( + array( + 'charactergroupsquests', + 'quest', + $seminary['url'], + $groupsgroup['url'], + $quest['url'] + ), + 0, true, null, true, 'stations' + ) + ); + } + + // Redirect to entry + $this->redirect( + $this->linker->link( + array( + 'station', + $seminary['url'], + $groupsgroup['url'], + $quest['url'], + $station['url'] + ), + 1 + ) + ); + } + + + // Set title + $this->addTitle(_('Delete Station')); + $this->addTitle($station['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('station', $station); + } + + /** diff --git a/models/CharactergroupsqueststationsModel.inc b/models/CharactergroupsqueststationsModel.inc index 63100e1a..15508747 100644 --- a/models/CharactergroupsqueststationsModel.inc +++ b/models/CharactergroupsqueststationsModel.inc @@ -239,6 +239,135 @@ } + /** + * Check if a Character groups Quest Station title already exists. + * + * @param int $questId ID of Character groups Quest + * @param string $title Station title to check + * @param int $stationId Do not check this ID (for editing) + * @return boolean Whether Station title exists or not + */ + public function stationTitleExists($questId, $title, $stationId=null) + { + $data = $this->db->query( + 'SELECT id '. + 'FROM charactergroupsqueststations '. + 'WHERE charactergroupsquest_id = ? AND (title = ? OR url = ?)', + 'iss', + $questId, + $title, + \nre\core\Linker::createLinkParam($title) + ); + + return (!empty($data) && (is_null($stationId) || $stationId != $data[0]['id'])); + } + + + /** + * Set the media for a Character groups Quest Station. + * + * @param int $stationId ID of Station to upload media for + * @param int $mediaId ID of Station media + */ + public function setPictureForStation($station, $mediaId) + { + $this->db->query( + 'UPDATE charactergroupsqueststations '. + 'SET stationpicture_id = ? '. + 'WHERE id = ?', + 'ii', + $mediaId, + $station + ); + } + + + /** + * Create a new Character groups Quest Station. + * + * @param int $questId ID of Quest to create the Station for + * @param int $stationtypeId ID of Station type + * @param string $title Title + * @param string $task Task description + * @param int $latitude GPS latitude + * @param int $longitude GPS longitude + * @param string $righttext Text for correctly solved task + * @param string $wrongtext Text for failed task + * @return int ID of newly created station + */ + public function createStation($questId, $stationtypeId, $title, $task, $latitude, $longitude, $righttext, $wrongtext) + { + // Get position + $pos = $this->db->query( + 'SELECT COALESCE(MAX(pos),0)+1 AS pos '. + 'FROM charactergroupsqueststations '. + 'WHERE charactergroupsquest_id = ?', + 'i', + $questId + ); + $pos = $pos[0]['pos']; + + // Create Station + $this->db->query( + 'INSERT INTO charactergroupsqueststations '. + '(charactergroupsquest_id, stationtype_id, title, url, pos, task, latitude, longitude, righttext, wrongtext) '. + 'VALUES '. + '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + 'iissisddss', + $questId, $stationtypeId, $title, + \nre\core\Linker::createLinkParam($title), $pos, + $task, $latitude, $longitude, $righttext, $wrongtext + ); + + + // Return ID of newly created Station + return $this->db->getInsertId(); + } + + + /** + * Edit a Character groups Quest Station. + * + * @param int $stationId ID of Station to edit + * @param int $stationtypeId ID of Station type + * @param string $title Title + * @param string $task Task description + * @param int $latitude GPS latitude + * @param int $longitude GPS longitude + * @param string $righttext Text for correctly solved task + * @param string $wrongtext Text for failed task + */ + public function editStation($stationId, $stationtypeId, $title, $task, $latitude, $longitude, $righttext, $wrongtext) + { + $this->db->query( + 'UPDATE charactergroupsqueststations '. + 'SET stationtype_id = ?, title = ?, url = ?, task = ?, latitude = ?, longitude = ?, righttext = ?, wrongtext = ? '. + 'WHERE id = ?', + 'isssddssi', + $stationtypeId, $title, + \nre\core\Linker::createLinkParam($title), + $task, $latitude, $longitude, $righttext, $wrongtext, + $stationId + ); + } + + + /** + * Delete a Character-group Quest station. + * + * @param int $stationId ID of Station to delete + */ + public function deleteStation($stationId) + { + $this->db->query( + 'DELETE FROM charactergroupsqueststations '. + 'WHERE ID = ?', + 'i', + $stationId + ); + } + + diff --git a/views/html/charactergroupsquests/quest.tpl b/views/html/charactergroupsquests/quest.tpl index a5c112b8..d2316f85 100644 --- a/views/html/charactergroupsquests/quest.tpl +++ b/views/html/charactergroupsquests/quest.tpl @@ -67,9 +67,8 @@ -
-

+

0) : ?> @@ -79,6 +78,7 @@ +
  1. @@ -96,8 +96,10 @@
+ +

.

+
-

diff --git a/views/html/charactergroupsqueststations/create.tpl b/views/html/charactergroupsqueststations/create.tpl new file mode 100644 index 00000000..af5be153 --- /dev/null +++ b/views/html/charactergroupsqueststations/create.tpl @@ -0,0 +1,99 @@ + + + +

+ + + +
+
+ + +

:

+
    + +
  • 0) : ?>(  MiB)
  • + +
+
+
+ +
+
+ + +
+
+ + /> +
+
+
+
+
+
+
+ +
+ diff --git a/views/html/charactergroupsqueststations/delete.tpl b/views/html/charactergroupsqueststations/delete.tpl new file mode 100644 index 00000000..700225f6 --- /dev/null +++ b/views/html/charactergroupsqueststations/delete.tpl @@ -0,0 +1,14 @@ + + + +

+ +
+ + +
diff --git a/views/html/charactergroupsqueststations/edit.tpl b/views/html/charactergroupsqueststations/edit.tpl new file mode 100644 index 00000000..3eb0737b --- /dev/null +++ b/views/html/charactergroupsqueststations/edit.tpl @@ -0,0 +1,99 @@ + + + +

+ + + +
+
+ + +

:

+
    + +
  • 0) : ?>(  MiB)
  • + +
+
+
+ +
+
+ + +
+
+ + /> +
+
+
+
+
+
+
+ +
+ diff --git a/views/html/charactergroupsqueststations/station.tpl b/views/html/charactergroupsqueststations/station.tpl index 9d0f1262..6a522536 100644 --- a/views/html/charactergroupsqueststations/station.tpl +++ b/views/html/charactergroupsqueststations/station.tpl @@ -8,9 +8,8 @@ 0) : ?>