From b88d39b3c025c636658335aeca4984b164a32869 Mon Sep 17 00:00:00 2001 From: coderkun Date: Wed, 9 Apr 2014 00:01:29 +0200 Subject: [PATCH] implement Character registration --- configs/AppConfig.inc | 9 +- controllers/CharactersController.inc | 132 +++++++++++++++++++++++- models/CharactersModel.inc | 64 ++++++++++-- models/CharactertypesModel.inc | 57 ++++++++++ models/SeminarycharacterfieldsModel.inc | 20 ++++ views/html/characters/register.tpl | 72 +++++++++++++ 6 files changed, 343 insertions(+), 11 deletions(-) create mode 100644 models/CharactertypesModel.inc create mode 100644 views/html/characters/register.tpl diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index f33044de..45ccb0fe 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -96,6 +96,11 @@ 'password' => array( 'minlength' => 5, 'maxlength' => 64 + ), + 'charactername' => array( + 'minlength' => 5, + 'maxlength' => 32, + 'regex' => '/^\w*$/' ) ); @@ -109,7 +114,7 @@ public static $routes = array( array('css/?(.*)', 'css/$1?layout=stylesheet', true), array('users/([^/]+)/(edit|delete)', 'users/$2/$1', true), - array('users/(?!(index|login|register|logout|create|edit|delete))', 'users/user/$1', true), + array('users/(?!(index|login|register|logout|create|edit|delete))', 'users/user/$1', true), array('seminaries/([^/]+)/(edit|delete)', 'seminaries/$2/$1', true), array('seminaries/(?!(index|create|edit|delete))', 'seminaries/seminary/$1', true), /*// z/ ⇒ z/seminaries/seminary/ @@ -118,7 +123,7 @@ array('^([^/]+)/([^/]+)/?$', 'questgropus/questgroup/$1/$2', true), // z/// ⇒ z/quests/quest/// array('^([^/]+)/([^/]+)/([^/]+)/?$', 'quests/quest/$1/$2/3', true)*/ - array('characters/(?!(index|character))', 'characters/index/$1', true), + array('characters/(?!(index|character|register))', 'characters/index/$1', true), array('charactergroups/(?!(index|groupsgroup|group))', 'charactergroups/index/$1', true), array('charactergroupsquests/(?!(quest))', 'charactergroupsquests/quest/$1', true), array('media/(.*)', 'media/$1?layout=binary', false), diff --git a/controllers/CharactersController.inc b/controllers/CharactersController.inc index e64cb63f..8486a2fc 100644 --- a/controllers/CharactersController.inc +++ b/controllers/CharactersController.inc @@ -19,6 +19,18 @@ */ class CharactersController extends \hhu\z\controllers\SeminaryRoleController { + /** + * Required models + * + * @var array + */ + public $models = array('seminaries', 'characters', 'users', 'charactergroups', 'charactertypes', 'seminarycharacterfields', 'avatars', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); /** * User permissions * @@ -26,14 +38,18 @@ */ public $permissions = array( 'index' => array('admin', 'moderator'), - 'character' => array('admin', 'moderator', 'user') + 'character' => array('admin', 'moderator', 'user'), + 'register' => array('admin', 'moderator', 'user') ); /** - * Required models + * User seminary permissions * * @var array */ - public $models = array('seminaries', 'characters', 'users', 'charactergroups', 'seminarycharacterfields'); + public $seminaryPermissions = array( + 'index' => array('admin', 'moderator'), + 'character' => array('admin', 'moderator', 'user') + ); @@ -50,6 +66,9 @@ { // Get Seminary $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + if(!is_null($seminary['media_id'])) { + $seminary['media'] = $this->Media->getMediaById($seminary['media_id']); + } // Get registered Characters $characters = $this->Characters->getCharactersForSeminary($seminary['id']); @@ -59,6 +78,12 @@ { // Level $character['xplevel'] = $this->Characters->getXPLevelOfCharacters($character['id']); + + // Avatar + $avatar = $this->Avatars->getAvatarById($character['avatar_id']); + if(!is_null($avatar['small_avatarpicture_id'])) { + $character['small_avatar'] = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); + } } @@ -82,6 +107,9 @@ // Get Seminary $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); $seminary['achievable_xps'] = $this->Seminaries->getTotalXPs($seminary['id']); + if(!is_null($seminary['media_id'])) { + $seminary['media'] = $this->Media->getMediaById($seminary['media_id']); + } // Get Character $character = $this->Characters->getCharacterByUrl($seminary['id'], $characterUrl); @@ -107,6 +135,104 @@ $this->set('groups', $groups); } + + /** + * Acton: register. + * + * Register a new character for a Seminary. + * + * @throws IdNotFoundException + * @throws ParamsNotValidException + * @param string $seminaryUrl URL-Title of a Seminary + */ + public function register($seminaryUrl) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // 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'); + + // 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)) { + throw new \nre\exceptions\ParamsNotValidException($characterType); + } + + // Validate fields + $fieldsValues = $this->request->getPostParam('fields'); + foreach($fields as &$field) + { + if(!array_key_exists($field['url'], $fieldsValues)) { + throw new \nre\exceptions\ParamsNotValidException($index); + } + 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); + + // Add Seminary fields + foreach($fields as &$field) { + if(!empty($fieldsValues[$field['url']])) { + $this->Characters->setSeminaryFieldOfCharacter($characterId, $field['id'], $fieldsValues[$field['url']]); + } + } + + // Redirect + $this->redirect($this->linker->link(array('seminaries'))); + } + } + + // Medium + $media = null; + if(!is_null($seminary['media_id'])) { + $media = $this->Media->getMediaById($seminary['media_id']); + } + + + // Pass data to view + $this->set('seminary', $seminary); + $this->set('types', $types); + $this->set('fields', $fields); + $this->set('media', $media); + $this->set('charactername', $charactername); + $this->set('validation', $validation); + $this->set('fieldsValidation', $fieldsValidation); + } + } ?> diff --git a/models/CharactersModel.inc b/models/CharactersModel.inc index 43406b0a..a502916a 100644 --- a/models/CharactersModel.inc +++ b/models/CharactersModel.inc @@ -43,7 +43,7 @@ public function getCharactersForUser($userId) { return $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminaries.id AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.xps, characters.xplevel, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '. 'FROM v_characters AS characters '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. 'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '. @@ -63,7 +63,7 @@ public function getCharactersForSeminary($seminaryId) { return $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminaries.id AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminaries.id AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '. 'FROM v_characters AS characters '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. 'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '. @@ -83,7 +83,7 @@ public function getCharactersForGroup($groupId) { return $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url '. 'FROM v_characters AS characters '. 'LEFT JOIN characters_charactergroups ON characters_charactergroups.character_id = characters.id '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. @@ -105,7 +105,7 @@ public function getCharacterForUserAndSeminary($userId, $seminaryId) { $data = $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url '. 'FROM v_characters AS characters '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. 'WHERE characters.user_id = ? AND charactertypes.seminary_id = ?', @@ -132,7 +132,7 @@ public function getCharacterByUrl($seminaryId, $characterUrl) { $data = $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminarymedia.url AS avatar_url, seminarymedia.description AS avatar_description '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminarymedia.url AS avatar_url, seminarymedia.description AS avatar_description '. 'FROM v_characters AS characters '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. 'LEFT JOIN avatars ON avatars.id = characters.avatar_id '. @@ -161,7 +161,7 @@ public function getCharacterById($characterId) { $data = $this->db->query( - 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminarymedia.url AS avatar_url, seminarymedia.description AS avatar_description '. + 'SELECT characters.id, characters.created, characters.charactertype_id, characters.name, characters.url, characters.user_id, characters.xps, characters.xplevel, characters.avatar_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertypes_url, seminarymedia.url AS avatar_url, seminarymedia.description AS avatar_description '. 'FROM v_characters AS characters '. 'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '. 'LEFT JOIN avatars ON avatars.id = characters.avatar_id '. @@ -336,6 +336,58 @@ ); } + + /** + * Create a new Character. + * + * @param int $userId User-ID that creates the new character + * @param int $charactertypeId ID of type of new Character + * @param string $characterName Name for the new Character + * @return int ID of Character + */ + public function createCharacter($userId, $charactertypeId, $characterName) + { + $this->db->query( + 'INSERT INTO characters '. + '(user_id, charactertype_id, name, url) '. + 'VALUES '. + '(?, ?, ?, ?)', + 'iiss', + $userId, + $charactertypeId, + $characterName, + \nre\core\Linker::createLinkParam($characterName) + ); + + + return $this->db->getInsertId(); + } + + + /** + * Set the value of a Seminary field for a Character. + * + * @param int $characterId ID of Character + * @param int $seminarycharacterfieldId ID of seminarycharacterfield to set value of + * @param string $value Value to set + */ + public function setSeminaryFieldOfCharacter($characterId, $seminarycharacterfieldId, $value) + { + $this->db->query( + 'INSERT INTO characters_seminarycharacterfields '. + '(character_id, seminarycharacterfield_id, value) '. + 'VALUES '. + '(?, ?, ?) '. + 'ON DUPLICATE KEY UPDATE '. + 'value = ?', + 'iiss', + $characterId, + $seminarycharacterfieldId, + $value, + $value + ); + } + } ?> diff --git a/models/CharactertypesModel.inc b/models/CharactertypesModel.inc new file mode 100644 index 00000000..07c8d5e9 --- /dev/null +++ b/models/CharactertypesModel.inc @@ -0,0 +1,57 @@ + + * @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 Charactertypes-table. + * + * @author Oliver Hanraths + */ + class CharactertypesModel extends \hhu\z\Model + { + + + + + /** + * Construct a new CharactertypesModel. + */ + public function __construct() + { + parent::__construct(); + } + + + + + /** + * Get all Character types of a Seminary. + * + * @param int $seminaryId ID of Seminary to get types of + * @return array Character types + */ + public function getCharacterTypesForSeminary($seminaryId) + { + return $this->db->query( + 'SELECT id, name, url '. + 'FROM charactertypes '. + 'WHERE seminary_id = ? '. + 'ORDER BY name ASC', + 'i', + $seminaryId + ); + } + + } + +?> diff --git a/models/SeminarycharacterfieldsModel.inc b/models/SeminarycharacterfieldsModel.inc index c881df2c..efad3bde 100644 --- a/models/SeminarycharacterfieldsModel.inc +++ b/models/SeminarycharacterfieldsModel.inc @@ -34,6 +34,26 @@ + /** + * Get all Character fields of a Seminary. + * + * @param int $seminaryId ID of Seminary to get fields of + * @param array Seminary Character fields + */ + public function getFieldsForSeminary($seminaryId) + { + return $this->db->query( + 'SELECT seminarycharacterfields.id, seminarycharacterfields.title, seminarycharacterfields.url, seminarycharacterfields.regex, seminarycharacterfields.required, seminarycharacterfieldtypes.id AS type_id, seminarycharacterfieldtypes.title AS type_title, seminarycharacterfieldtypes.url AS type_url '. + 'FROM seminarycharacterfields '. + 'LEFT JOIN seminarycharacterfieldtypes ON seminarycharacterfieldtypes.id = seminarycharacterfields.seminarycharacterfieldtype_id '. + 'WHERE seminarycharacterfields.seminary_id = ? '. + 'ORDER BY pos ASC', + 'i', + $seminaryId + ); + } + + /** * Get Seminary Character fields of a Character. * diff --git a/views/html/characters/register.tpl b/views/html/characters/register.tpl new file mode 100644 index 00000000..f6d2b15e --- /dev/null +++ b/views/html/characters/register.tpl @@ -0,0 +1,72 @@ + +
+ +
+ +

+

+ +
+ +
    + &$settings) : ?> +
  • +
      + $value) : ?> +
    • + +
    • + +
    +
  • + +
+ +
+ + +
+ + +
+ + +
    + &$settings) : ?> +
  • + +
+ +
+ + + + + required="required"/> + + + + +
+ +