implement Character registration

This commit is contained in:
coderkun 2014-04-09 00:01:29 +02:00
commit b88d39b3c0
6 changed files with 343 additions and 11 deletions

View file

@ -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/<Seminary> z/seminaries/seminary/<Seminary>
@ -118,7 +123,7 @@
array('^([^/]+)/([^/]+)/?$', 'questgropus/questgroup/$1/$2', true),
// z/<Seminary>/<Questgroup>/<Quest> ⇒ z/quests/quest/<Seminary>/<Questgroup>/<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),

View file

@ -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);
}
}
?>

View file

@ -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
);
}
}
?>

View file

@ -0,0 +1,57 @@
<?php
/**
* The Legend of Z
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
* @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 <oliver.hanraths@uni-duesseldorf.de>
*/
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
);
}
}
?>

View file

@ -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.
*

View file

@ -0,0 +1,72 @@
<?php if(!is_null($media)) : ?>
<div class="moodpic">
<img src="<?=$linker->link(array('media','index',$media['url']))?>">
</div>
<?php endif ?>
<h1><?=$seminary['title']?></h1>
<h2><?=_('Create Character')?></h2>
<form method="post" action="">
<?php if($validation !== true) : ?>
<ul>
<?php foreach($validation as $field => &$settings) : ?>
<li>
<ul>
<?php foreach($settings as $setting => $value) : ?>
<li>
<?php switch($field) {
case 'charactername':
switch($setting) {
case 'minlength': printf(_('Character name is too short (min. %d chars)'), $value);
break;
case 'maxlength': printf(_('Character name is too long (max. %d chars)'), $value);
break;
case 'regex': echo _('Character name contains illegal characters');
break;
default: echo _('Character name invalid');
}
break;
} ?>
</li>
<?php endforeach ?>
</ul>
</li>
<?php endforeach ?>
</ul>
<?php endif ?>
<fieldset>
<legend><?=_('Character properties')?></legend>
<label for="charactername"><?=_('Character name')?>:</label>
<input type="text" name="charactername" placeholder="<?=_('Character name')?>" required="required" value="<?=$charactername?>" /><br />
<label for="type"><?=_('Character type')?>:</label>
<select name="type" required="required">
<?php foreach($types as &$type) : ?>
<option value="<?=$type['url']?>" <?php if(array_key_exists('selected', $type) && $type['selected']) : ?>selected="selected"<?php endif ?>><?=$type['name']?></option>
<?php endforeach ?>
</select>
</fieldset>
<?php if($fieldsValidation !== true) : ?>
<ul>
<?php foreach($fieldsValidation as $field => &$settings) : ?>
<li><?=sprintf(_('The Seminary field “%s” is invalid'), $field)?></li>
<?php endforeach ?>
</ul>
<?php endif ?>
<fieldset>
<legend><?=_('Seminary fields')?></legend>
<?php foreach($fields as &$field) : ?>
<label for="fields[<?=$field['url']?>]"><?=$field['title']?>:</label>
<?php switch($field['type_title']) {
case 'Number':
case 'Varchar': ?>
<input type="text" name="fields[<?=$field['url']?>]" pattern="<?=(!empty($field['regex'])) ? substr($field['regex'],1,strrpos($field['regex'],$field['regex'][0])-1) : ''?>" <?php if($field['required']) : ?>required="required"<?php endif ?>/>
<?php break;
case 'Text': ?>
<textarea name="fields[<?=$field['url']?>]"></textarea>
<?php break;
} ?>
<?php endforeach ?>
</fieldset>
<input type="submit" name="create" value="<?=_('create')?>" />
</form>