diff --git a/agents/intermediate/CharactergroupsachievementsAgent.inc b/agents/intermediate/CharactergroupsachievementsAgent.inc new file mode 100644 index 00000000..d247ff7f --- /dev/null +++ b/agents/intermediate/CharactergroupsachievementsAgent.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\agents\intermediate; + + + /** + * Agent to list Charactergroups Achievements. + * + * @author Oliver Hanraths + */ + class CharactergroupsachievementsAgent extends \nre\agents\IntermediateAgent + { + + + + + /** + * Action: achievement. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function achievement(\nre\core\Request $request, \nre\core\Response $response) + { + // Add Moodpic + $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), $request->getParam(1)); + } + + + /** + * 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), $request->getParam(1)); + } + + + /** + * 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), $request->getParam(1)); + } + + + /** + * Action: manage. + * + * @param \nre\core\Request $request Current request + * @param \nre\core\Response $response Current response + */ + public function manage(\nre\core\Request $request, \nre\core\Response $response) + { + // Add Moodpic + $this->addSubAgent('Moodpic', 'seminary', $request->getParam(3), $request->getParam(1)); + } + + + /** + * 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), $request->getParam(1)); + } + + } + +?> diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index a412bf7b..1e8a13f0 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -345,6 +345,9 @@ array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/create/?$', 'charactergroupsqueststations/create/$1/$2/$3', true), array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/([^/]+)/(edit|edittask|delete)/?$', 'charactergroupsqueststations/$5/$1/$2/$3/$4', true), array('^charactergroupsqueststations/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsqueststations/station/$1/$2/$3/$4', true), + array('^charactergroupsachievements/([^/]+)/([^/]+)/(create|manage)/?$', 'charactergroupsachievements/$3/$1/$2', true), + array('^charactergroupsachievements/([^/]+)/([^/]+)/([^/]+)/(edit|manage|moveup|movedown|delete)/?$', 'charactergroupsachievements/$4/$1/$2/$3', true), + array('^charactergroupsachievements/([^/]+)/([^/]+)/([^/]+)/?$', 'charactergroupsachievements/achievement/$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), @@ -403,6 +406,9 @@ array('^charactergroupsqueststations/index/(.*)$', 'charactergroupsqueststations/$1', true), array('^charactergroupsqueststations/station/(.*)$', 'charactergroupsqueststations/$1', true), array('^charactergroupsqueststations/(create|edit|edittask|delete)/(.*)$', 'charactergroupsqueststations/$2/$1', true), + array('^charactergroupsachievements/(create|manage)/(.*)$', 'charactergroupsachievements/$2/$1', true), + array('^charactergroupsachievements/(edit|moveup|movedown|delete)/(.*)$', 'charactergroupsachievements/$2/$1', true), + array('^charactergroupsachievements/achievement/(.*)$', 'charactergroupsachievements/$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/CharactergroupsachievementsController.inc b/controllers/CharactergroupsachievementsController.inc new file mode 100644 index 00000000..ca5b36e3 --- /dev/null +++ b/controllers/CharactergroupsachievementsController.inc @@ -0,0 +1,622 @@ + + * @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 Charactegroupsachievements. + * + * @author Oliver Hanraths + */ + class CharactergroupsachievementsController extends \hhu\z\controllers\SeminaryController + { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'charactergroupsachievements', 'charactergroups', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation', 'notification'); + /** + * User permissions + * + * @var array + */ + public $permissions = array( + 'achievement' => array('admin', 'moderator', 'user'), + 'create' => array('admin', 'moderator', 'user'), + 'moveup' => array('admin', 'moderator', 'user'), + 'movedown' => array('admin', 'moderator', 'user'), + 'edit' => array('admin', 'moderator', 'user'), + 'manage' => array('admin', 'moderator', 'user'), + 'delete' => array('admin', 'moderator', 'user') + ); + /** + * User seminary permissions + * + * @var array + */ + public $seminaryPermissions = array( + 'achievement' => array('admin', 'moderator', 'user'), + 'create' => array('admin'), + 'moveup' => array('admin', 'moderator'), + 'movedown' => array('admin', 'moderator'), + 'edit' => array('admin', 'moderator'), + 'manage' => array('admin', 'moderator'), + 'delete' => array('admin') + ); + + + + + /** + * Action: achievement. + * + * Let a Character group achieve an achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementHash Hash of Character groups achievement + */ + public function achievement($seminaryUrl, $groupsgroupUrl, $achievementHash) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByHash( + $achievementHash + ); + + // Get Character group(s) + $charactergroups = null; + $charactergroup = null; + $notify = true; + if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) { + $charactergroups = $this->Charactergroups->getGroupsForGroupsgroup($groupsgroup['id']); + $notify = false; + } + else + { + $character = $this->Characters->getCharacterForUserAndSeminary($this->Auth->getUserId(), $seminary['id']); + $charactergroups = $this->Charactergroups->getGroupsForCharacter($character['id']); + if(count($charactergroups) == 1) { + $charactergroup = $charactergroups[0]; + } + } + // Select group by parameter + $selectedCharactergroupId = $this->request->getPostParam('charactergroup'); + if(!is_null($selectedCharactergroupId)) + { + $selectedCharactergroupId = intval($selectedCharactergroupId); + foreach($charactergroups as &$group) { + if($group['id'] == $selectedCharactergroupId) { + $charactergroup = $group; + break; + } + } + } + + // Set Achievement achieved for Character group + if(!is_null($charactergroup)) + { + if(!$this->Charactergroupsachievements->hasCharactergroupAchievedAchievement( + $achievement['id'], + $charactergroup['id'] + )) { + // Set achieved-status + $this->Charactergroupsachievements->setAchievementAchieved( + $achievement['id'], + $charactergroup['id'] + ); + + // Set notification + if($notify) { + $this->Notification->addNotification( + \hhu\z\controllers\components\NotificationComponent::TYPE_CHARACTERGROUPSACHIEVEMENT, + $achievement['title'], + $this->linker->link( + array( + 'charactergroups', + 'group', + $seminary['url'], + $groupsgroup['url'], + $charactergroup['url'] + ), 0, true, null, true, 'achievements' + ), + (!is_null($achievement['achievementsmedia_id']) ? $this->linker->link( + array( + 'media', + 'charactergroupsachievement', + $seminary['url'], + $groupsgroup['url'], + $achievement['url'] + ) + ) : null) + ); + } + } + + // Redirect + $this->redirect( + $this->linker->link( + array( + 'charactergroups', + 'group', + $seminary['url'], + $groupsgroup['url'], + $charactergroup['url'] + ), 0, true, null, true, 'achievements' + ) + ); + } + + + // TODO Set title + $this->addTitle($achievement['title']); + $this->addTitle(sprintf(_('%s-Achievements'), $groupsgroup['name'])); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('achievement', $achievement); + $this->set('charactergroups', $charactergroups); + $this->set('charactergroup', $charactergroup); + } + + + /** + * Action: manage. + * + * Manage Achievements of a Seminary. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of Seminary + * @param string $groupsgroupUrl URL-title of Character groups-group + */ + public function manage($seminaryUrl, $groupsgroupUrl) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievements + $achievements = $this->Charactergroupsachievements->getAchievementsForCharactergroupsgroup( + $groupsgroup['id'] + ); + + + // TODO Set title + $this->addTitleLocalized('Manage Achievements'); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('achievements', $achievements); + } + + + /** + * Action: create. + * + * Create a new Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $groupsgroupUrl URL-title of 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 allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = ''; + $description = ''; + $fields = array('title'); + $validation = array(); + + // Create Achievement + 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->Charactergroupsachievements->achievementTitleExists($groupsgroup['id'], $title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $description = $this->request->getPostParam('description'); + + // 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 Achievement + if($validation === true) + { + $achievementId = $this->Charactergroupsachievements->createAchievement( + $this->Auth->getUserId(), + $groupsgroup['id'], + $title, + $description + ); + $achievement = $this->Charactergroupsachievements->getAchievementById($achievementId); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createAchievementMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsachievement-%d', $achievement['id']), + $achievement['title'], + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsachievements->setIconForAchievement( + $achievement['id'], + $mediaId + ); + } + } + + // Redirect to condition editing + $this->redirect( + $this->linker->link(array( + 'manage', + $seminary['url'], + $groupsgroup['url'] + ), 1, true, null, true, 'achievements' + )); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // TODO Set title + $this->addTitleLocalized('Create Achievement'); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('title', $title); + $this->set('description', $description); + $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 $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementUrl URL-title of Achievement + */ + public function moveup($seminaryUrl, $groupsgroupUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByUrl($groupsgroup['id'], $achievementUrl); + + // Set position + $this->Charactergroupsachievements->moveAchievement($achievement, true); + + + // Redirect + $this->redirect( + $this->linker->link( + array( + 'manage', + $seminary['url'], + $groupsgroup['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 $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementUrl URL-title of Achievement + */ + public function movedown($seminaryUrl, $groupsgroupUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByUrl($groupsgroup['id'], $achievementUrl); + + // Set position + $this->Charactergroupsachievements->moveAchievement($achievement, false); + + + // Redirect + $this->redirect( + $this->linker->link( + array( + 'manage', + $seminary['url'], + $groupsgroup['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 $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementUrl URL-title of Achievement to edit + */ + public function edit($seminaryUrl, $groupsgroupUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByUrl( + $groupsgroup['id'], + $achievementUrl + ); + + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['icons']; + + // Values + $title = $achievement['title']; + $description = $achievement['description']; + $fields = array('title'); + $validation = array(); + + // Edit 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->Charactergroupsachievements->achievementTitleExists($groupsgroup['id'], $title, $achievement['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $description = $this->request->getPostParam('description'); + + // 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 Achievement + if($validation === true) + { + $this->Charactergroupsachievements->editAchievement( + $achievement['id'], + $title, + $description + ); + + // Upload icon + if(!is_null($icon)) + { + $mediaId = $this->Media->createAchievementMedia( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('charactergroupsachievement-%d', $achievement['id']), + $achievement['title'], + $icon['mimetype'], + $icon['tmp_name'] + ); + if($mediaId !== false) { + $this->Charactergroupsachievements->setIconForAchievement( + $achievement['id'], + $mediaId + ); + } + } + + // Redirect + $this->redirect( + $this->linker->link( + array( + 'manage', + $seminary['url'], + $groupsgroup['url'] + ), 1, true, null, false, $achievement['url'] + ) + ); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; + } + + + // TODO Set title + $this->addTitleLocalized('Edit Achievement'); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('achievement', $achievement); + $this->set('title', $title); + $this->set('description', $description); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); + } + + + /** + * Action: delete. + * + * Delete an Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementUrl URL-title of Achievement + */ + public function delete($seminaryUrl, $groupsgroupUrl, $achievementUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByUrl($groupsgroup['id'], $achievementUrl); + + // Check request method + if($this->request->getRequestMethod() == 'POST') + { + // Check confirmation + if(!is_null($this->request->getPostParam('delete'))) + { + // Delete seminary + $this->Charactergroupsachievements->deleteAchievement($achievement); + } + + // Redirect to entry + $this->redirect( + $this->linker->link( + array( + 'manage', + $seminary['url'], + $groupsgroup['url'] + ), + 1 + ) + ); + } + + + // Set titile + $this->addTitleLocalized('Delete seminary'); + $this->addTitle($groupsgroup['name']); + $this->addTitle($seminary['title']); + + // Show confirmation + $this->set('seminary', $seminary); + $this->set('groupsgroup', $groupsgroup); + $this->set('achievement', $achievement); + } + } + +?> diff --git a/controllers/MediaController.inc b/controllers/MediaController.inc index 8a7afd3c..c4ba776b 100644 --- a/controllers/MediaController.inc +++ b/controllers/MediaController.inc @@ -33,7 +33,8 @@ 'achievement' => array('admin', 'moderator', 'user'), 'charactergroup' => array('admin', 'moderator', 'user'), 'charactergroupsquest' => array('admin', 'moderator', 'user'), - 'charactergroupsqueststation' => array('admin', 'moderator', 'user') + 'charactergroupsqueststation' => array('admin', 'moderator', 'user'), + 'charactergroupsachievements' => array('admin', 'moderator', 'user') ); /** * User seminary permissions @@ -45,14 +46,15 @@ 'achievement' => array('admin', 'moderator', 'user', 'guest'), 'charactergroup' => array('admin', 'moderator', 'user', 'guest'), 'charactergroupsquest' => array('admin', 'moderator', 'user', 'guest'), - 'charactergroupsqueststation' => array('admin', 'moderator', 'user', 'guest') + 'charactergroupsqueststation' => array('admin', 'moderator', 'user', 'guest'), + 'charactergroupsachievements' => array('admin', 'moderator', 'user', 'guest') ); /** * Required models * * @var array */ - public $models = array('seminaries', 'achievements', 'media', 'avatars', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'map'); + public $models = array('seminaries', 'achievements', 'media', 'avatars', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'charactergroupsachievements', 'map'); @@ -519,6 +521,51 @@ } + /** + * Action: charactergroupsachievement + * + * Display the achievement of a Character groups-group. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-title of Seminary + * @param string $groupsgroupUrl URL-title of Character groups-group + * @param string $achievementUrl URL-title of the Achievement + * @param string $action Action for processing the media + */ + public function charactergroupsachievement($seminaryUrl, $groupsgroupUrl, $achievementUrl, $locked=null) + { + // Get Seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Character groups-group + $groupsgroup = $this->Charactergroups->getGroupsgroupByUrl($seminary['id'], $groupsgroupUrl); + + // Get Character + //$character = SeminaryController::$character; + + // Get Achievement + $achievement = $this->Charactergroupsachievements->getAchievementByUrl($groupsgroup['id'], $achievementUrl); + + // Get media + $media = $this->Media->getSeminaryMediaById($achievement['achievementsmedia_id']); + + // Get file + $file = $this->getMediaFile( + $media, + false, + !is_null($locked) + ); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('media', $media); + $this->set('file', $file); + } + + /** diff --git a/controllers/components/NotificationComponent.inc b/controllers/components/NotificationComponent.inc index ecf17ac1..da1b508b 100644 --- a/controllers/components/NotificationComponent.inc +++ b/controllers/components/NotificationComponent.inc @@ -25,6 +25,12 @@ * @var string */ const TYPE_ACHIEVEMENT = 'achievement'; + /** + * Type: Character groups Achievement + * + * @var string + */ + const TYPE_CHARACTERGROUPSACHIEVEMENT = 'charactergroupsachievement'; /** * Type: Level-up * diff --git a/db/create.sql b/db/create.sql index 342287a2..2fc813f8 100644 --- a/db/create.sql +++ b/db/create.sql @@ -1,8 +1,8 @@ --- MySQL dump 10.16 Distrib 10.1.11-MariaDB, for Linux (x86_64) +-- MySQL dump 10.16 Distrib 10.1.12-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: z -- ------------------------------------------------------ --- Server version 10.1.11-MariaDB-log +-- Server version 10.1.12-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -374,6 +374,54 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; +-- +-- Table structure for table `charactergroupsachievements` +-- + +DROP TABLE IF EXISTS `charactergroupsachievements`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsachievements` ( + `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, + `pos` int(11) unsigned NOT NULL, + `title` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, + `url` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL, + `hash` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL, + `description` text COLLATE utf8mb4_unicode_ci NOT NULL, + `achievementsmedia_id` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `charactergroupsgroup_id_2` (`charactergroupsgroup_id`,`url`), + UNIQUE KEY `hash` (`hash`), + KEY `charactergroupsgroup_id` (`charactergroupsgroup_id`), + KEY `achievementsmedia_id` (`achievementsmedia_id`), + KEY `created_user_id` (`created_user_id`), + CONSTRAINT `charactergroupsachievements_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `charactergroupsachievements_ibfk_2` FOREIGN KEY (`charactergroupsgroup_id`) REFERENCES `charactergroupsgroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsachievements_ibfk_3` FOREIGN KEY (`achievementsmedia_id`) REFERENCES `achievementsmedia` (`seminarymedia_id`) ON DELETE SET NULL ON UPDATE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `charactergroupsachievements_charactergroups` +-- + +DROP TABLE IF EXISTS `charactergroupsachievements_charactergroups`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `charactergroupsachievements_charactergroups` ( + `charactergroupsachievement_id` int(11) NOT NULL, + `charactergroup_id` int(11) NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`charactergroupsachievement_id`,`charactergroup_id`), + KEY `charactergroup_id` (`charactergroup_id`), + CONSTRAINT `charactergroupsachievements_charactergroups_ibfk_1` FOREIGN KEY (`charactergroupsachievement_id`) REFERENCES `charactergroupsachievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `charactergroupsachievements_charactergroups_ibfk_2` FOREIGN KEY (`charactergroup_id`) REFERENCES `charactergroups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `charactergroupsgroups` -- @@ -2546,4 +2594,4 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2016-02-27 18:47:43 +-- Dump completed on 2016-03-12 15:57:07 diff --git a/models/CharactergroupsachievementsModel.inc b/models/CharactergroupsachievementsModel.inc new file mode 100644 index 00000000..cd030282 --- /dev/null +++ b/models/CharactergroupsachievementsModel.inc @@ -0,0 +1,453 @@ + + * @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; + + + /** + * Model to interact with Charactergroupsachievements-tables. + * + * @author Oliver Hanraths + */ + class CharactergroupsachievementsModel extends \hhu\z\Model + { + /** + * Required models + * + * @var array + */ + public $models = array('media'); + + + + + /** + * Construct a new CharactergroupsachievementsModel. + */ + public function __construct() + { + parent::__construct(); + } + + + + + /** + * Get an Achievement by its URL. + * + * @param int $groupsgroupId ID of Character groups-group + * @param string $achievementUrl URL-title of Achievement + * @return array Achievement data + */ + public function getAchievementByUrl($groupsgroupId, $achievementUrl) + { + $data = $this->db->query( + 'SELECT id, charactergroupsgroup_id, pos, title, url, hash, description, achievementsmedia_id '. + 'FROM charactergroupsachievements '. + 'WHERE charactergroupsgroup_id = ? AND url = ?', + 'is', + $groupsgroupId, $achievementUrl + ); + if(empty($data)) { + throw new \nre\exceptions\IdNotFoundException($achievementUrl); + } + + + return $data[0]; + } + + + /** + * Get an Achievement by its ID. + * + * @param int $achievementId ID of Achievement + * @return array Achievement data + */ + public function getAchievementById($achievementId) + { + $data = $this->db->query( + 'SELECT id, charactergroupsgroup_id, pos, title, url, hash, description, achievementsmedia_id '. + 'FROM charactergroupsachievements '. + 'WHERE id = ?', + 'i', + $achievementId + ); + if(empty($data)) { + throw new \nre\exceptions\IdNotFoundException($achievementId); + } + + + return $data[0]; + } + + + /** + * Get an Achievement by its hash. + * + * @param string $achievementHash Hash of Achievement + * @return array Achievement data + */ + public function getAchievementByHash($achievementHash) + { + $data = $this->db->query( + 'SELECT id, charactergroupsgroup_id, pos, title, url, hash, description, achievementsmedia_id '. + 'FROM charactergroupsachievements '. + 'WHERE hash = ?', + 's', + $achievementHash + ); + if(empty($data)) { + throw new \nre\exceptions\IdNotFoundException($achievementHash); + } + + + return $data[0]; + } + + + /** + * Get all achieved Achievements for a Character group. + * + * @param int $charactergroupId ID of Character group + * @return array Achievements data + */ + public function getAchievedAchievementsForGroup($charactergroupId) + { + return $this->db->query( + 'SELECT id, charactergroupsgroup_id, charactergroupsachievements_charactergroups.created, pos, title, url, hash, description, achievementsmedia_id '. + 'FROM charactergroupsachievements '. + 'INNER JOIN charactergroupsachievements_charactergroups ON charactergroupsachievements_charactergroups.charactergroupsachievement_id = charactergroupsachievements.id '. + 'WHERE charactergroupsachievements_charactergroups.charactergroup_id = ? '. + 'ORDER BY charactergroupsachievements_charactergroups.created DESC', + 'i', + $charactergroupId + ); + } + + + /** + * Get all Achievements for a Character groups-group. + * + * @param int $groupsgroupId ID of Character groups-group + * @return array List of Achievements + */ + public function getAchievementsForCharactergroupsgroup($groupsgroupId) + { + return $this->db->query( + 'SELECT id, charactergroupsgroup_id, pos, title, url, hash, description, achievementsmedia_id '. + 'FROM charactergroupsachievements '. + 'WHERE charactergroupsgroup_id = ? '. + 'ORDER BY pos ASC', + 'i', + $groupsgroupId + ); + } + + + /** + * Set an Achievement as achieved for a Character group. + * + * @param int $achievementId ID of Achievement + * @param int $charactergroupId ID of Character group + */ + public function setAchievementAchieved($achievementId, $charactergroupId) + { + $this->db->query( + 'INSERT INTO charactergroupsachievements_charactergroups '. + '(charactergroupsachievement_id, charactergroup_id) '. + 'VALUES '. + '(?, ?)', + 'ii', + $achievementId, $charactergroupId + ); + } + + + /** + * Check if a Character group has achieved an Achievement. + * + * @param int $achievementId ID of Achievement + * @param int $charactergroupId ID of Character group + * @return boolean Whether Character group has achieved the Achievement or not + */ + public function hasCharactergroupAchievedAchievement($achievementId, $charactergroupId) + { + $data = $this->db->query( + 'SELECT charactergroupsachievement_id, charactergroup_id, created '. + 'FROM charactergroupsachievements_charactergroups '. + 'WHERE charactergroupsachievement_id = ? AND charactergroup_id = ?', + 'ii', + $achievementId, $charactergroupId + ); + if(!empty($data)) { + return $data[0]; + } + + + return false; + } + + + /** + * Check if an Achievement title already exists. + * + * @param int $groupsgroupId ID of Character groups-group + * @param string $title Achievement title to check + * @param int $achievementId Do not check this ID (for editing) + * @return boolean Whether Achievement title exists or not + */ + public function achievementTitleExists($groupsgroupId, $title, $achievementId=null) + { + $data = $this->db->query( + 'SELECT id '. + 'FROM charactergroupsachievements '. + 'WHERE charactergroupsgroup_id = ? AND (title = ? OR url = ?)', + 'iss', + $groupsgroupId, + $title, + \nre\core\Linker::createLinkParam($title) + ); + + + return (!empty($data) && (is_null($achievementId) || $achievementId != $data[0]['id'])); + } + + + /** + * Create a new Achievement for a Character groups-group. + * + * @param int $userId ID of creating user + * @param int $groupsgroupId ID of Character groups->group + * @param string $title Title of new Achievement + * @param string $description Description of new Achievement + * @return int ID of newly created Achievement + */ + public function createAchievement($userId, $groupsgroupId, $title, $description) + { + // Get position + $pos = $this->db->query( + 'SELECT COALESCE(MAX(pos),0)+1 AS pos '. + 'FROM charactergroupsachievements '. + 'WHERE charactergroupsgroup_id = ?', + 'i', + $groupsgroupId + ); + $pos = $pos[0]['pos']; + + // Create Achievement + $this->db->query( + 'INSERT INTO charactergroupsachievements '. + '(created_user_id, charactergroupsgroup_id, pos, title, url, hash, description) '. + 'VALUES '. + '(?, ?, ?, ?, ?, ?, ?)', + 'iiissss', + $userId, + $groupsgroupId, + $pos, + $title, + \nre\core\Linker::createLinkParam($title), + \hhu\z\Utils::createRandomHash(), + $description + ); + + + // Return ID + return $this->db->getInsertId(); + } + + + /** + * Move an Achievement up (decrement position) or down (increment + * position). + * + * @param array $achievement Achievement to move + * @param boolean $up True for moving up, false for down + */ + public function moveAchievement($achievement, $up) + { + $this->db->setAutocommit(false); + try { + // Set temporary position + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET pos = 0 '. + 'WHERE id = ?', + 'i', + $achievement['id'] + ); + // Switch entry + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET pos = ? '. + 'WHERE charactergroupsgroup_id = ? AND pos = ?', + 'iii', + $achievement['pos'], + $achievement['charactergroupsgroup_id'], + $achievement['pos'] + ($up ? -1 : 1) + ); + // Set new position + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET pos = ? '. + 'WHERE id = ?', + 'ii', + $achievement['pos'] + ($up ? -1 : 1), + $achievement['id'] + ); + + $this->db->commit(); + } + catch(\nre\exceptions\DatamodelException $e) { + $this->db->rollback(); + $this->db->setAutocommit(true); + throw $e; + } + $this->db->setAutocommit(true); + } + + + /** + * Edit an Achievement of a Seminary. + * + * @param int $achievementId ID of Achievement to edit + * @param string $title New title of Achievement + * @param string $description New description of Achievement + */ + public function editAchievement($achievementId, $title, $description) + { + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET title = ?, url = ?, description = ? '. + 'WHERE id = ?', + 'sssi', + $title, + \nre\core\Linker::createLinkParam($title), + $description, + $achievementId + ); + } + + + /** + * Set the icon for an Achievement. + * + * @param int $achievementId ID of Achievement to set media for + * @param int $achievementsmediaId ID of achievementsmedia to set + */ + public function setIconForAchievement($achievementId, $achievementsmediaId) + { + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET achievementsmedia_id = ? '. + 'WHERE id = ?', + 'ii', + $achievementsmediaId, + $achievementId + ); + } + + + /** + * Copy all Achievements of a Seminary. + * + * @param int $userId ID of creating user + * @param int $sourceSeminaryId Seminary to copy from + * @param int $targetSeminaryId Seminary to copy to + * @param array $seminaryMediaIds Mapping of Seminarymedia-IDs from source Seminary to target Seminary + * @param array $questIds Mapping of Quest-IDs from source Seminary to target Seminary (optional) + */ + public function copyAchievementsOfSeminary($userId, $characterGroupsgroupIds, $seminaryMediaIds=null) + { + // Store target achievement-IDs + $achievementIds = array(); + + // Traverse each Character groups-group + foreach($characterGroupsgroupIds as $sourceGroupsgroupId => $targetGroupsgroupId) + { + // Get Achievements + $achievements = $this->getAchievementsForCharactergroupsgroup($sourceGroupsgroupId); + + // Copy each Achievements + foreach($achievements as &$achievement) + { + // Copy Achievement + $this->db->query( + 'INSERT INTO charactergroupsachievements '. + '(created_user_id, charactergroupsgroup_id, pos, title, url, hash, description) '. + 'SELECT ?, ?, pos, title, url, ?, description '. + 'FROM charactergroupsachievements '. + 'WHERE id = ?', + 'iisi', + $userId, $targetGroupsgroupId, + \hhu\z\Utils::createRandomHash(), + $achievement['id'] + ); + $achievementIds[$achievement['id']] = $this->db->getInsertId(); + + // Copy media + if(!is_null($seminaryMediaIds) && !is_null($achievement['achievementsmedia_id'])) + { + $this->Media->copyAchievementMedia($userId, $seminaryMediaIds[$achievement['achievementsmedia_id']]); + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET achievementsmedia_id = ? '. + 'WHERE id = ?', + 'ii', + $seminaryMediaIds[$achievement['achievementsmedia_id']], + $achievementIds[$achievement['id']] + ); + } + } + } + } + + + /** + * Delete an Achievement. + * + * @param array $achievement Achievement to delete + */ + public function deleteAchievement($achievement) + { + $this->db->setAutocommit(false); + try { + // Delete Achievement + $this->db->query( + 'DELETE FROM charactergroupsachievements '. + 'WHERE id = ?', + 'i', + $achievement['id'] + ); + + // Adjust positions + $this->db->query( + 'UPDATE charactergroupsachievements '. + 'SET pos = pos - 1 '. + 'WHERE charactergroupsgroup_id = ? AND pos > ?', + 'ii', + $achievement['charactergroupsgroup_id'], + $achievement['pos'] + ); + + $this->db->commit(); + } + catch(\Exception $e) { + $this->db->rollback(); + $this->db->setAutocommit(true); + throw $e; + } + + $this->db->setAutocommit(true); + } + + } + +?> diff --git a/views/binary/media/charactergroupsachievement.tpl b/views/binary/media/charactergroupsachievement.tpl new file mode 100644 index 00000000..0d6fb0df --- /dev/null +++ b/views/binary/media/charactergroupsachievement.tpl @@ -0,0 +1 @@ + diff --git a/views/html/charactergroupsachievements/achievement.tpl b/views/html/charactergroupsachievements/achievement.tpl new file mode 100644 index 00000000..271c688a --- /dev/null +++ b/views/html/charactergroupsachievements/achievement.tpl @@ -0,0 +1,29 @@ + + + +

+
    +
  • + + + +

    +
  • +
+ +
+
+ +
+ +
+ +
diff --git a/views/html/charactergroupsachievements/create.tpl b/views/html/charactergroupsachievements/create.tpl new file mode 100644 index 00000000..8eefa143 --- /dev/null +++ b/views/html/charactergroupsachievements/create.tpl @@ -0,0 +1,67 @@ + + + +

+ +
    + &$settings) : ?> +
  • +
      + $value) : ?> +
    • + +
    • + +
    +
  • + +
+ +
+
+ + +

:

+
    + +
  • 0) : ?>(  MiB)
  • + +
+
+
+ + />
+ +
+
+ +
diff --git a/views/html/charactergroupsachievements/delete.tpl b/views/html/charactergroupsachievements/delete.tpl new file mode 100644 index 00000000..2ef1336a --- /dev/null +++ b/views/html/charactergroupsachievements/delete.tpl @@ -0,0 +1,13 @@ + + + +

+ +
+ + +
diff --git a/views/html/charactergroupsachievements/edit.tpl b/views/html/charactergroupsachievements/edit.tpl new file mode 100644 index 00000000..a840586c --- /dev/null +++ b/views/html/charactergroupsachievements/edit.tpl @@ -0,0 +1,70 @@ + + + +

+ +
    + &$settings) : ?> +
  • +
      + $value) : ?> +
    • + +
    • + +
    +
  • + +
+ +
+
+ + + + + +

:

+
    + +
  • 0) : ?>(  MiB)
  • + +
+
+
+ + />
+ +
+
+ +
diff --git a/views/html/charactergroupsachievements/manage.tpl b/views/html/charactergroupsachievements/manage.tpl new file mode 100644 index 00000000..1a70eb26 --- /dev/null +++ b/views/html/charactergroupsachievements/manage.tpl @@ -0,0 +1,33 @@ + + + + +

+
    + &$achievement) : ?> +
  • + + + +

    +

    + +
  • + +
diff --git a/views/html/charactergroupsachievements/movedown.tpl b/views/html/charactergroupsachievements/movedown.tpl new file mode 100644 index 00000000..e69de29b diff --git a/views/html/charactergroupsachievements/moveup.tpl b/views/html/charactergroupsachievements/moveup.tpl new file mode 100644 index 00000000..e69de29b