This commit is contained in:
coderkun 2015-04-27 16:42:05 +02:00
commit 046a724272
4209 changed files with 1186656 additions and 0 deletions

1407
models/AchievementsModel.inc Normal file

File diff suppressed because it is too large Load diff

223
models/AvatarsModel.inc Normal file
View file

@ -0,0 +1,223 @@
<?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 Avatars-tables.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class AvatarsModel extends \hhu\z\Model
{
/**
* Required models
*
* @var array
*/
public $models = array('media');
/**
* Construct a new AvatarsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get an Avatar by its ID
*
* @param int $avatarId ID of Avatar
* @return array Avatar data
*/
public function getAvatarById($avatarId)
{
$data = $this->db->query(
'SELECT id, charactertype_id, xplevel_id, avatarpicture_id, small_avatarpicture_id '.
'FROM avatars '.
'WHERE id = ?',
'i',
$avatarId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get an Avatar by its Character type and XP-level.
*
* @param int $seminaryId ID of Seminary
* @param string $charactertypeUrl URL-title of Character type
* @param int $xplevel XP-level
* @return array Avatar data
*/
public function getAvatarByTypeAndLevel($seminaryId, $charactertypeUrl, $xplevel)
{
$data = $this->db->query(
'SELECT avatars.id, charactertype_id, xplevel_id, avatarpicture_id, small_avatarpicture_id '.
'FROM avatars '.
'INNER JOIN charactertypes ON charactertypes.id = avatars.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = avatars.xplevel_id AND xplevels.seminary_id = charactertypes.seminary_id '.
'WHERE charactertypes.seminary_id = ? AND charactertypes.url = ? AND xplevels.level = ?',
'isi',
$seminaryId,
$charactertypeUrl,
$xplevel
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($charactertypeUrl);
}
return $data[0];
}
/**
* Get an Avatar by its Character type and XP-level.
*
* @param int $charactertypeId ID of Character type
* @param int $xplevelId ID of XP-level
* @return array Avatar data
*/
public function getAvatarByTypeAndLevelId($charactertypeId, $xplevelId)
{
$data = $this->db->query(
'SELECT id, charactertype_id, xplevel_id, avatarpicture_id, small_avatarpicture_id '.
'FROM avatars '.
'WHERE charactertype_id = ? AND xplevel_id = ?',
'ii',
$charactertypeId,
$xplevelId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($charactertypeId.'-'.$xplevelId);
}
return $data[0];
}
/**
* Set the picture for an Avatar.
*
* @param int $userId ID of creating user
* @param int $charactertypeId ID of Charactertype of Avatar
* @param int $xplevelId ID of XP-level of Avatar
* @param int $avatarpictureId ID of Avatar picture to set
*/
public function setAvatarForTypeAndLevel($userId, $charactertypeId, $xplevelId, $avatarpictureId)
{
$this->db->query(
'INSERT INTO avatars '.
'(created_user_id, charactertype_id, xplevel_id, avatarpicture_id) '.
'VALUES '.
'(?, ?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'avatarpicture_id = ?',
'iiiii',
$userId,
$charactertypeId,
$xplevelId,
$avatarpictureId,
$avatarpictureId
);
}
/**
* Set the portrait picture for an Avatar.
*
* @param int $userId ID of creating user
* @param int $charactertypeId ID of Charactertype of Avatar
* @param int $xplevelId ID of XP-level of Avatar
* @param int $avatarpictureId ID of Avatar portrait picture to set
*/
public function setAvatarPortraitForTypeAndLevel($userId, $charactertypeId, $xplevelId, $avatarpictureId)
{
$this->db->query(
'INSERT INTO avatars '.
'(created_user_id, charactertype_id, xplevel_id, small_avatarpicture_id) '.
'VALUES '.
'(?, ?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'small_avatarpicture_id = ?',
'iiiii',
$userId,
$charactertypeId,
$xplevelId,
$avatarpictureId,
$avatarpictureId
);
}
/**
* Copy all Avatars from a Seminary.
*
* @param int $userId ID of copying user
* @param array $charactertypeIds Mapping of Charactertype-IDs from source Seminary to target Seminary
* @param array $xplevelIds Mapping of XP-level-IDs from source Seminary to targetSeminary
* @param array $seminaryMediaIds Mapping of Seminarymedia-IDs from source Seminary to target Seminary
*/
public function copyAvatars($userId, $charactertypeIds, $xplevelIds, $seminaryMediaIds)
{
// Copy Avatars
foreach($charactertypeIds as $sourceCharactertypeId => $targetCharactertypeId)
{
foreach($xplevelIds as $sourceXplevelId => $targetXplevelId)
{
try {
// Get Avatar
$avatar = $this->getAvatarByTypeAndLevelId($sourceCharactertypeId, $sourceXplevelId);
// Copy media
$this->Media->copyAvatarpicture($userId, $seminaryMediaIds[$avatar['avatarpicture_id']]);
$this->Media->copyAvatarpicture($userId, $seminaryMediaIds[$avatar['small_avatarpicture_id']]);
// Copy Avatar
$this->db->query(
'INSERT INTO avatars '.
'(created_user_id, charactertype_id, xplevel_id, avatarpicture_id, small_avatarpicture_id) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iiiii',
$userId,
$targetCharactertypeId,
$targetXplevelId,
$seminaryMediaIds[$avatar['avatarpicture_id']],
$seminaryMediaIds[$avatar['small_avatarpicture_id']]
);
}
catch(\nre\exceptions\IdNotFoundException $e) {
// Not all combinations of charactertypes and XP-levels exist
}
}
}
}
}
?>

View file

@ -0,0 +1,541 @@
<?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 of the CharactergroupsAgent to interact with
* Charactergroups-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class CharactergroupsModel extends \hhu\z\Model
{
/**
* Construct a new CharactergroupsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get Character groups-groups of a Seminary.
*
* @param int $seminaryId ID of the corresponding Seminary
* @return array Character groups-groups data
*/
public function getGroupsroupsForSeminary($seminaryId)
{
return $this->db->query(
'SELECT id, name, url, preferred '.
'FROM charactergroupsgroups '.
'WHERE seminary_id = ?',
'i',
$seminaryId
);
}
/**
* Get a Character groups-group by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of the corresponding Seminary
* @param string $groupsgroupUrl URL-name of the Character groups-group
* @return array Character groups-group data
*/
public function getGroupsgroupByUrl($seminaryId, $groupsgroupUrl)
{
$data = $this->db->query(
'SELECT id, name, url, preferred '.
'FROM charactergroupsgroups '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId, $groupsgroupUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($groupsgroupUrl);
}
return $data[0];
}
/**
* Get a Character groups-group by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $groupsgroupId ID of the Character groups-group
* @return array Character groups-group data
*/
public function getGroupsgroupById($groupsgroupId)
{
$data = $this->db->query(
'SELECT id, name, url, preferred '.
'FROM charactergroupsgroups '.
'WHERE id = ?',
'i',
$groupsgroupId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($groupsgroupId);
}
return $data[0];
}
/**
* Check if a Character groups-group name already exists.
*
* @param string $name Name to check
* @param int $groupsgroupId Do not check this ID (for editing)
* @return boolean Whether name exists or not
*/
public function characterGroupsgroupNameExists($name, $groupsgroupId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM charactergroupsgroups '.
'WHERE name = ? OR url = ?',
'ss',
$name,
\nre\core\Linker::createLinkParam($name)
);
return (!empty($data) && (is_null($groupsgroupId) || $groupsgroupId != $data[0]['id']));
}
/**
* Create a new Character groups-group.
*
* @param int $userId ID of user
* @param int $seminaryId ID of Seminary
* @param string $name Name of new groups-group
* @param boolean $preferred Whether groups-group is preferred or not
* @return int ID of newly created groups-group
*/
public function createGroupsgroup($userId, $seminaryId, $name, $preferred)
{
$this->db->query(
'INSERT INTO charactergroupsgroups '.
'(created_user_id, seminary_id, name, url, preferred) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iissd',
$userId,
$seminaryId,
$name,
\nre\core\Linker::createLinkParam($name),
$preferred
);
return $this->db->getInsertId();
}
/**
* Edit a Character groups-group.
*
* @param int $groupsgroupId ID of groups-group to edit
* @param string $name New name of groups-group
* @param boolean $preferred Whether groups-group is preferred or not
*/
public function editGroupsgroup($groupsgroupId, $name, $preferred)
{
$this->db->query(
'UPDATE charactergroupsgroups '.
'SET name = ?, url = ?, preferred = ? '.
'WHERE id = ?',
'ssdi',
$name,
\nre\core\Linker::createLinkParam($name),
$preferred,
$groupsgroupId
);
}
/**
* Copy all Character groups-groups of a Seminary.
*
* @param int $userId ID of creating user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
* @param array Mapping of Character groups-groups-IDs from source Seminary to target Seminary
*/
public function copyGroupsgroupsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId)
{
$groupsgroupIds = array();
// Get Character groups
$groupsgroups = $this->getGroupsroupsForSeminary($sourceSeminaryId);
// Copy each Groups-group
foreach($groupsgroups as &$group)
{
$this->db->query(
'INSERT INTO charactergroupsgroups '.
'(created_user_id, seminary_id, name, url, preferred) '.
'SELECT ?, ?, name, url, preferred '.
'FROM charactergroupsgroups '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$group['id']
);
$groupsgroupIds[$group['id']] = $this->db->getInsertId();
}
return $groupsgroupIds;
}
/**
* Delete a Character groups-group.
*
* @param int $groupsgroupId ID of groups-group to delete
*/
public function deleteGroupsgroup($groupsgroupId)
{
$this->db->query('DELETE FROM charactergroupsgroups WHERE id = ?', 'i', $groupsgroupId);
}
/**
* Get Character groups for a Character groups-group.
*
* @param int $groupsgroupId ID of the Character groups-group
* @param string $sortorder Field to sort by (optional)
* @return array Character groups
*/
public function getGroupsForGroupsgroup($groupsgroupId, $sortorder='name')
{
// Set sort order
switch($sortorder)
{
case 'xps':
$sortorder = 'xps DESC';
break;
case 'name':
default:
$sortorder = 'name ASC';
break;
}
// Get and return Character groups
return $this->db->query(
'SELECT '.
'charactergroups.id, charactergroups.name, charactergroups.url, charactergroups.motto, charactergroups.charactergroupsmedia_id, '.
'cache_charactergroups.xps '.
'FROM charactergroups '.
'LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = charactergroups.id '.
'WHERE charactergroups.charactergroupsgroup_id = ? '.
"ORDER BY $sortorder",
'i',
$groupsgroupId
);
}
/**
* Get Character groups for a Character.
*
* @param int $characterId ID of the Character
* @return array Character groups
*/
public function getGroupsForCharacter($characterId)
{
return $this->db->query(
'SELECT '.
'charactergroups.id, charactergroups.charactergroupsgroup_id, charactergroups.name, charactergroups.url, charactergroups.charactergroupsmedia_id, '.
'cache_charactergroups.xps, '.
'charactergroupsgroups.id AS charactergroupsgroup_id, charactergroupsgroups.name AS charactergroupsgroup_name, charactergroupsgroups.url AS charactergroupsgroup_url '.
'FROM characters_charactergroups '.
'LEFT JOIN charactergroups ON charactergroups.id = characters_charactergroups.charactergroup_id '.
'LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = charactergroups.id '.
'LEFT JOIN charactergroupsgroups ON charactergroupsgroups.id = charactergroups.charactergroupsgroup_id '.
'WHERE characters_charactergroups.character_id = ?',
'i',
$characterId
);
}
/**
* Get a Character group by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $groupsgroupId ID of the Character groups-group
* @param string $groupUrl URL-name of the Character group
* @return array Character group data
*/
public function getGroupByUrl($groupsgroupId, $groupUrl)
{
$data = $this->db->query(
'SELECT '.
'charactergroups.id, charactergroups.name, charactergroups.url, charactergroups.motto, charactergroups.charactergroupsmedia_id, '.
'cache_charactergroups.xps '.
'FROM charactergroups '.
'LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = charactergroups.id '.
'WHERE charactergroups.charactergroupsgroup_id = ? AND url = ?',
'is',
$groupsgroupId, $groupUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($groupUrl);
}
return $data[0];
}
/**
* Get a Character group by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $groupsgroupId ID of the Character group
* @return array Character group data
*/
public function getGroupById($groupId)
{
$data = $this->db->query(
'SELECT '.
'charactergroups.id, charactergroups.name, charactergroups.url, charactergroups.motto, charactergroups.charactergroupsmedia_id, '.
'cache_charactergroups.xps '.
'FROM charactergroups '.
'LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = charactergroups.id '.
'WHERE charactergroups.id = ?',
'i',
$groupId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($groupId);
}
return $data[0];
}
/**
* Get the Character groups for a Quest.
*
* @param int $questId ID of the Character groups Quest
* @return array Character groups
*/
public function getGroupsForQuest($questId)
{
$groups = $this->db->query(
'SELECT charactergroups.id, charactergroups.name, charactergroups.url, charactergroupsquests_groups.created, charactergroupsquests_groups.xps_factor, charactergroupsquests.xps '.
'FROM charactergroupsquests_groups '.
'LEFT JOIN charactergroups ON charactergroups.id = charactergroupsquests_groups.charactergroup_id '.
'LEFT JOIN charactergroupsquests ON charactergroupsquests.id = charactergroupsquests_groups.charactergroupsquest_id '.
'WHERE charactergroupsquests_groups.charactergroupsquest_id = ? '.
'ORDER BY xps_factor DESC',
'i',
$questId
);
foreach($groups as &$group) {
$group['xps'] = round($group['xps'] * $group['xps_factor'], 1);
}
return $groups;
}
/**
* Check if a Character group name already exists.
*
* @param string $name Name to check
* @param int $groupsgroupId Do not check this ID (for editing)
* @return boolean Whether name exists or not
*/
public function characterGroupNameExists($name, $groupId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM charactergroups '.
'WHERE name = ? OR url = ?',
'ss',
$name,
\nre\core\Linker::createLinkParam($name)
);
return (!empty($data) && (is_null($groupId) || $groupId != $data[0]['id']));
}
/**
* Create a new Character group.
*
* @param int $userId ID of user
* @param int $groupsgroupId ID of Character groups-group
* @param string $name Name of new group
* @param string $motto Motto of new group
* @return int ID of newly created group
*/
public function createGroup($userId, $groupsgroupId, $name, $motto)
{
$this->db->query(
'INSERT INTO charactergroups '.
'(created_user_id, charactergroupsgroup_id, name, url, motto) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iisss',
$userId,
$groupsgroupId,
$name,
\nre\core\Linker::createLinkParam($name),
$motto
);
return $this->db->getInsertId();
}
/**
* Set the media for a Character group.
*
* @param int $groupId ID of Character group to set media for
* @param int $mediaId ID of Character groups media
*/
public function setMediaForGroup($groupId, $mediaId)
{
$this->db->query(
'UPDATE charactergroups '.
'SET charactergroupsmedia_id = ? '.
'WHERE id = ?',
'ii',
$mediaId,
$groupId
);
}
/**
* Edit a Character group.
*
* @param int $groupId ID of Character group to edit
* @param string $name New name of group
* @param string $motto New motto of group
*/
public function editGroup($groupId, $name, $motto)
{
$this->db->query(
'UPDATE charactergroups '.
'SET name = ?, url = ?, motto = ? '.
'WHERE id = ?',
'sssi',
$name,
\nre\core\Linker::createLinkParam($name),
$motto,
$groupId
);
}
/**
* Delete a Character group.
*
* @param int $groupId ID of Character group to delete
*/
public function deleteGroup($groupId)
{
$this->db->query('DELETE FROM charactergroups WHERE id = ?', 'i', $groupId);
}
/**
* Get the rank of a XP-value of a Character.
*
* @param int $seminaryId ID of Seminary
* @param int $xps XP-value to get rank for
* @return int Rank of XP-value
*/
public function getXPRank($groupsgroupId, $xps)
{
$data = $this->db->query(
'SELECT count(charactergroups.id) AS c '.
'FROM charactergroups '.
'LEFT JOIN cache_charactergroups ON cache_charactergroups.charactergroup_id = charactergroups.id '.
'WHERE charactergroups.charactergroupsgroup_id = ? AND cache_charactergroups.xps > ?',
'id',
$groupsgroupId, $xps
);
if(!empty($data)) {
return $data[0]['c'] + 1;
}
return 1;
}
/**
* Add a Character to a Character group.
*
* @param int $groupId ID of Character group
* @param int $characterId ID of Character to add
*/
public function addCharacterToCharactergroup($groupId, $characterId)
{
$this->db->query(
'INSERT INTO characters_charactergroups '.
'(character_id, charactergroup_id) '.
'VALUES '.
'(?, ?)',
'ii',
$characterId,
$groupId
);
}
/**
* Remove a Character from a Character group.
*
* @param int $groupId ID of Character group
* @param int $characterId ID of Character to remove
*/
public function removeCharacterFromCharactergroup($groupId, $characterId)
{
$this->db->query(
'DELETE FROM characters_charactergroups '.
'WHERE charactergroup_id = ? AND character_id = ?',
'ii',
$groupId,
$characterId
);
}
}
?>

View file

@ -0,0 +1,440 @@
<?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 of the CharactergroupsquestsAgent to interact with
* Charactergroupsquests-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class CharactergroupsquestsModel extends \hhu\z\Model
{
/**
* Required models
*
* @var array
*/
public $models = array('uploads', 'media');
/**
* Construct a new CharactergroupsquestsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get Character groups Quests of a Character groups-groups.
*
* @param int $groupsgroupId ID of the Character groups-group
* @return array Character groups Quest data
*/
public function getQuestsForCharactergroupsgroup($groupsgroupId)
{
return $this->db->query(
'SELECT id, questgroups_id, title, url, xps, questsmedia_id '.
'FROM charactergroupsquests '.
'WHERE charactergroupsgroup_id = ? '.
'ORDER BY created ASC',
'i',
$groupsgroupId
);
}
/**
* Get a Character groups Quest by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $groupsgroupId ID of the Character groups-group
* @param string $questUrl URL-title of the Character groups Quest
* @return array Character groups Quest data
*/
public function getQuestByUrl($groupsgroupId, $questUrl)
{
$data = $this->db->query(
'SELECT id, questgroups_id, title, url, description, xps, rules, won_text, lost_text, questsmedia_id '.
'FROM charactergroupsquests '.
'WHERE charactergroupsgroup_id = ? AND url = ?',
'is',
$groupsgroupId,
$questUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questUrl);
}
return $data[0];
}
/**
* Get a Character groups Quest by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $questId ID of the Character groups Quest
* @return array Character groups Quest data
*/
public function getQuestById($questId)
{
$data = $this->db->query(
'SELECT id, questgroups_id, title, url, description, xps, rules, won_text, lost_text, questsmedia_id '.
'FROM charactergroupsquests '.
'WHERE id = ?',
'i',
$questId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questUrl);
}
return $data[0];
}
/**
* Get Character groups Quests for a Character group.
*
* @param int $groupId ID of the Character group
* @return array Character groups Quests
*/
public function getQuestsForGroup($groupId)
{
$quests = $this->db->query(
'SELECT charactergroupsquests.id, charactergroupsquests_groups.created, charactergroupsquests.title, charactergroupsquests.url, charactergroupsquests.xps, charactergroupsquests_groups.xps_factor '.
'FROM charactergroupsquests_groups '.
'LEFT JOIN charactergroupsquests ON charactergroupsquests.id = charactergroupsquests_groups.charactergroupsquest_id '.
'WHERE charactergroupsquests_groups.charactergroup_id = ? '.
'ORDER BY charactergroupsquests.created ASC',
'i',
$groupId
);
foreach($quests as &$quest) {
$quest['group_xps'] = round($quest['xps'] * $quest['xps_factor'], 1);
}
return $quests;
}
/**
* Get XPs of a Character group for a Character groups Quest.
*
* @param int $questId ID of Character groups Quest
* @param int $groupId ID of Character group to get XPs of
* @return array XP-record
*/
public function getXPsOfGroupForQuest($questId, $groupId)
{
$data = $this->db->query(
'SELECT charactergroupsquests_groups.created, charactergroupsquests_groups.xps_factor, charactergroupsquests.xps '.
'FROM charactergroupsquests_groups '.
'LEFT JOIN charactergroupsquests ON charactergroupsquests.id = charactergroupsquests_groups.charactergroupsquest_id '.
'WHERE charactergroupsquests_groups.charactergroupsquest_id = ? AND charactergroupsquests_groups.charactergroup_id = ?',
'ii',
$questId,
$groupId
);
if(empty($data)) {
return null;
}
$data = $data[0];
$data['xps'] = round($data['xps'] * $data['xps_factor'], 1);
return $data;
}
/**
* Set XPs of a Character group for a Character groups Quest.
*
* @param int $questId ID of Character groups Quest
* @param int $groupId ID of Character group to set XPs of
* @param float $xpsFactor XPs-factor
*/
public function setXPsOfGroupForQuest($questId, $groupId, $xpsFactor)
{
$this->db->query(
'INSERT INTO charactergroupsquests_groups '.
'(charactergroupsquest_id, charactergroup_id, xps_factor) '.
'VALUES '.
'(?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'xps_factor = ?',
'iidd',
$questId,
$groupId,
$xpsFactor,
$xpsFactor
);
}
/**
* Remove a Character group from a Character groups Quest.
*
* @param int $questId ID of Character groups Quest
* @param int $groupId ID of Character group to remove
*/
public function deleteGroupForQuest($questId, $groupId)
{
$this->db->query(
'DELETE FROM charactergroupsquests_groups '.
'WHERE charactergroupsquest_id = ? AND charactergroup_id = ?',
'ii',
$questId, $groupId
);
}
/**
* Check if a Character groups Quest title already exists.
*
* @param string $name Character groups Quest title to check
* @param int $questId Do not check this ID (for editing)
* @return boolean Whether Character groups Quest title exists or not
*/
public function characterGroupsQuestTitleExists($title, $questId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM charactergroupsquests '.
'WHERE title = ? OR url = ?',
'ss',
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($questId) || $questId != $data[0]['id']));
}
/**
* Set the media for a Character groups Quest.
*
* @param int $questId ID of Quest to upload media for
* @param int $mediaId ID of Quests media
*/
public function setMediaForQuest($questId, $mediaId)
{
$this->db->query(
'UPDATE charactergroupsquests '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$mediaId,
$questId
);
}
/**
* Upload a media for a Character groups Quest.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param int $questId ID of Quest to upload media for
* @param array $file File-array of file to upload
* @param string $filename Filename for media
* @return boolean Whether upload succeeded or not
*/
public function uploadMediaForQuest($userId, $seminaryId, $questId, $file, $filename)
{
// Save file on harddrive
$uploadId = $this->Uploads->uploadSeminaryFile($userId, $seminaryId, $file['name'], $filename, $file['tmp_name'], $file['type']);
if($uploadId === false) {
return false;
}
// Create database record
$this->db->query(
'INSERT INTO charactergroupsquests_seminaryuploads '.
'(seminaryupload_id, charactergroupsquest_id, created_user_id) '.
'VALUES '.
'(?, ?, ?) ',
'iii',
$uploadId, $questId, $userId
);
return true;
}
/**
* Get uploaded Medai for a Character groups Quest.
*
* @param int $questId ID of Quest to get media for
* @return array Seminary uploads
*/
public function getMediaForQuest($questId)
{
return $this->db->query(
'SELECT seminaryupload_id, created, created_user_id '.
'FROM charactergroupsquests_seminaryuploads '.
'WHERE charactergroupsquest_id = ?',
'i',
$questId
);
}
/**
* Create a new Character groups Quest.
*
* @param int $userId ID of user
* @param int $groupsgroupId ID of Character groups-group
* @param int $questgroupId ID of Quest group
* @param string $title Title of new Quest
* @param string $description Description of new Quset
* @param int $xps Amount of XPs for new Quest
* @param string $rules Rules of new Quest
* @param string $wonText Won-text of new Quset
* @param string $lostText Lost-text of new Quest
* @return int ID of newly created Quest
*/
public function createQuest($userId, $groupsgroupId, $questgroupId, $title, $description, $xps, $rules, $wonText, $lostText)
{
$this->db->query(
'INSERT INTO charactergroupsquests '.
'(created_user_id, charactergroupsgroup_id, questgroups_id, title, url, description, xps, rules, won_text, lost_text) '.
'VALUES '.
'(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
'iiisssdsss',
$userId,
$groupsgroupId,
$questgroupId,
$title,
\nre\core\Linker::createLinkParam($title),
$description,
$xps,
$rules,
$wonText,
$lostText
);
return $this->db->getInsertId();
}
/**
* Edit a Character groups Quest.
*
* @param int $questId ID of Character groups Quest to edit
* @param int $groupsgroupId ID of Character groups-group
* @param int $questgroupId ID of Quest group
* @param string $title Title of new Quest
* @param string $description Description of new Quset
* @param int $xps Amount of XPs for new Quest
* @param string $rules Rules of new Quest
* @param string $wonText Won-text of new Quset
* @param string $lostText Lost-text of new Quest
*/
public function editQuest($questId, $groupsgroupId, $questgroupId, $title, $description, $xps, $rules, $wonText, $lostText)
{
$this->db->query(
'UPDATE charactergroupsquests '.
'SET charactergroupsgroup_id = ?, questgroups_id = ?, title = ?, url = ?, description = ?, xps = ?, rules = ?, won_text = ?, lost_text= ? '.
'WHERE id = ?',
'iisssdsssi',
$groupsgroupId,
$questgroupId,
$title,
\nre\core\Linker::createLinkParam($title),
$description,
$xps,
$rules,
$wonText,
$lostText,
$questId
);
}
/**
* Copy all Character groups Quests from a Seminary.
*
* @param int $userId ID of copying user
* @param array $groupsgroupIds Mapping of Character groups-group-IDs from source Seminary to target Seminary
* @param array $questgroupIds Mapping of Questgroup-IDs from source Seminary to target Seminary
* @param array $seminaryMediaIds Mapping of Seminarymedia-IDs from source Seminary to target Seminary (optional)
*/
public function copyQuestsOfSeminary($userId, $groupsgroupIds, $questgroupIds, $seminaryMediaIds=null)
{
foreach($groupsgroupIds as $sourceGroupsgroupId => $targetGroupsgroupId)
{
// Get Quests
$quests = $this->getQuestsForCharactergroupsgroup($sourceGroupsgroupId);
// Copy each Quest
foreach($quests as &$quest)
{
// Copy Quest
$this->db->query(
'INSERT INTO charactergroupsquests '.
'(created_user_id, charactergroupsgroup_id, questgroups_id, title, url, description, xps, rules, won_text, lost_text) '.
'SELECT ?, ?, ?, title, url, description, xps, rules, won_text, lost_text '.
'FROM charactergroupsquests '.
'WHERE id = ?',
'iiii',
$userId, $targetGroupsgroupId, $questgroupIds[$quest['questgroups_id']],
$quest['id']
);
$targetQuestId = $this->db->getInsertId();
// Copy media
if(!is_null($seminaryMediaIds) && !is_null($quest['questsmedia_id']))
{
$this->Media->copyQuestsmedia($userId, $seminaryMediaIds[$quest['questsmedia_id']]);
$this->db->query(
'UPDATE charactergroupsquests '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaIds[$quest['questsmedia_id']],
$targetQuestId
);
}
}
}
}
/**
* Delete a Character groups Quest.
*
* @param int $questId ID of Character groups Quest to delete
*/
public function deleteQuest($questId)
{
$this->db->query('DELETE FROM charactergroupsquests WHERE id = ?', 'i', $questId);
}
}
?>

View file

@ -0,0 +1,100 @@
<?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 characterroles-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class CharacterrolesModel extends \hhu\z\Model
{
/**
* Construct a new CharacterrolesModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get all characterroles for a Character referenced by its ID.
*
* @param int $userId ID of an user
* @return array Characterroles for a Character
*/
public function getCharacterrolesForCharacterById($characterId)
{
return $this->db->query(
'SELECT characterroles.id, characterroles.created, characterroles.name '.
'FROM characters_characterroles '.
'LEFT JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id '.
'WHERE characters_characterroles.character_id = ?',
'i',
$characterId
);
}
/**
* Add a role to a Character.
*
* @param int $characterId ID of Character to add role to
* @param string $characterrole Role to add
*/
public function addCharacterroleToCharacter($characterId, $characterrole)
{
$this->db->query(
'INSERT IGNORE INTO characters_characterroles '.
'(character_id, characterrole_id) '.
'SELECT ?, id '.
'FROM characterroles '.
'WHERE name = ?',
'is',
$characterId,
$characterrole
);
}
/**
* Remove a role from a Character.
*
* @param int $characterId ID of Character to remove role from
* @param string $characterrole Role to remove
*/
public function removeCharacterroleFromCharacter($characterId, $characterrole)
{
$this->db->query(
'DELETE FROM characters_characterroles '.
'WHERE character_id = ? AND characterrole_id = ('.
'SELECT id '.
'FROM characterroles '.
'WHERE name = ?'.
')',
'is',
$characterId,
$characterrole
);
}
}
?>

697
models/CharactersModel.inc Normal file
View file

@ -0,0 +1,697 @@
<?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 Characters-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class CharactersModel extends \hhu\z\Model
{
/**
* Construct a new CharactersModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get all characters for an user.
*
* @param int $userId ID of the user
* @return array Characters
*/
public function getCharactersForUser($userId)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'WHERE characters.user_id = ?',
'i',
$userId
);
}
/**
* Get count of Characters for a Seminary.
*
* @param int $seminaryId ID of the Seminary
* @param string $charactername Only get Characters with the given name (optional)
* @return int Count of Characters
*/
public function getCharactersForSeminaryCount($seminaryId, $charactername=null)
{
$data = $this->db->query(
'SELECT count(DISTINCT characters.id) AS c '.
'FROM characters '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'WHERE seminaries.id = ? '.
(!is_null($charactername) ? sprintf('AND characters.name LIKE \'%%%s%%\'', $charactername) : null),
'i',
$seminaryId
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get Characters for a Seminary.
*
* @param int $seminaryId ID of the Seminary
* @param bool $onlyWithRole Only Characters that have at least one role assigned (optional)
* @return array Characters
*/
public function getCharactersForSeminary($seminaryId, $onlyWithRole=false)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'WHERE seminaries.id = ?'.
($onlyWithRole ? ' AND EXISTS (SELECT character_id FROM characters_characterroles WHERE character_id = characters.id)' : null),
'i',
$seminaryId
);
}
/**
* Get Characters for a Seminary sorted and optionally limited.
*
* @param int $seminaryId ID of the Seminary
* @param string $sort Field to sort by
* @param string $charactername Only get Characters with the given name (optional)
* @param int $limit Limit amount of Characters (optional)
* @param int $offset Offset (optional)
* @return array Characters
*/
public function getCharactersForSeminarySorted($seminaryId, $sort, $charactername='', $limit=null, $offset=0)
{
switch($sort)
{
case 'name':
case 'created':
case 'xps':
$orders = array(
'name' => 'ASC',
'created' => 'DESC',
'xps' => 'DESC'
);
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'WHERE seminaries.id = ? '.
(!is_null($charactername) ? sprintf(' AND characters.name LIKE \'%%%s%%\' ', $charactername) : null).
sprintf(
'ORDER BY %s.%s %s ',
($sort == 'xps' ? 'cache_characters' : 'characters'),
$sort,
$orders[$sort]
).
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null),
'i',
$seminaryId
);
break;
case 'role':
return $this->db->query(
'SELECT DISTINCT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'LEFT JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'LEFT JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id '.
'WHERE seminaries.id = ? '.
(!is_null($charactername) ? sprintf(' AND characters.name LIKE \'%%%s%%\' ', $charactername) : null).
'ORDER BY characterroles.id IS NULL, characterroles.id ASC '.
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null),
'i',
$seminaryId
);
break;
default:
return $this->db->query(
'SELECT DISTINCT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'LEFT JOIN characters_seminarycharacterfields ON characters_seminarycharacterfields.character_id = characters.id '.
'LEFT JOIN seminarycharacterfields ON seminarycharacterfields.id = characters_seminarycharacterfields.seminarycharacterfield_id AND seminarycharacterfields.url = ? '.
'WHERE seminaries.id = ? '.
(!is_null($charactername) ? sprintf(' AND characters.name LIKE \'%%%s%%\' ', $charactername) : null).
'ORDER BY characters_seminarycharacterfields.value ASC '.
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null),
'si',
$sort,
$seminaryId
);
break;
}
}
/**
* Get Characters for a Character group.
*
* @param int $groupId ID of the Character group
* @return array Characters
*/
public function getCharactersForGroup($groupId)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'LEFT JOIN characters_charactergroups ON characters_charactergroups.character_id = characters.id '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE characters_charactergroups.charactergroup_id = ? '.
'ORDER BY cache_characters.xps DESC',
'i',
$groupId
);
}
/**
* Get the character of a user for a Seminary.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $userId ID of the user
* @param int $seminaryId ID of the Seminary
* @return array Character data
*/
public function getCharacterForUserAndSeminary($userId, $seminaryId)
{
$data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE characters.user_id = ? AND charactertypes.seminary_id = ?',
'ii',
$userId, $seminaryId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($userId);
}
return $data[0];
}
/**
* Get a Character by its Url.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of the Seminary
* @param string $characterUrl URL-name of the Character
* @return array Character data
*/
public function getCharacterByUrl($seminaryId, $characterUrl)
{
$data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE charactertypes.seminary_id = ? AND characters.url = ?',
'is',
$seminaryId, $characterUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($characterUrl);
}
return $data[0];
}
/**
* Get a Character by its Id.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $characterId ID of the Character
* @return array Character data
*/
public function getCharacterById($characterId)
{
$data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE characters.id = ?',
'i',
$characterId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($characterUrl);
}
return $data[0];
}
/**
* Get Characters with the given Character role.
*
* @param string $characterrole Character role
* @return array List of Characters
*/
public function getCharactersWithRole($characterrole)
{
return $this->db->query(
'SELECT characters.id, characters.created, characters.user_id, characters.name, characters.url '.
'FROM characters '.
'LEFT JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'LEFT JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id '.
'WHERE characterroles.name = ? '.
'ORDER BY name ASC',
's',
$characterrole
);
}
/**
* Get Characters with the most amount of Achievements.
*
* @param int $seminaryId ID of Seminary
* @param int $conut Amount of Characters to retrieve
* @param bool $alsoWithDeadline Include Achievements with deadline (optional)
* @return array List of Characters
*/
public function getCharactersWithMostAchievements($seminaryId, $count, $alsoWithDeadline=true)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'count(DISTINCT achievement_id) AS c '.
'FROM achievements_characters '.
'INNER JOIN achievements ON achievements.id = achievements_characters.achievement_id '.
'INNER JOIN characters ON characters.id = achievements_characters.character_id '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'INNER JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'INNER JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id AND characterroles.name = ? '.
'WHERE achievements.seminary_id = ? AND deadline IS NULL '.
(!$alsoWithDeadline ? 'AND achievements.deadline IS NULL ' : null).
'GROUP BY achievements_characters.character_id '.
'ORDER BY count(DISTINCT achievements_characters.achievement_id) DESC '.
'LIMIT ?',
'sii',
'user',
$seminaryId,
$count
);
}
/**
* Get the rank of a XP-value of a Character.
*
* @param int $seminaryId ID of Seminary
* @param int $xps XP-value to get rank for
* @return int Rank of XP-value
*/
public function getXPRank($seminaryId, $xps)
{
$data = $this->db->query(
'SELECT count(characters.id) AS c '.
'FROM charactertypes '.
'INNER JOIN characters ON characters.charactertype_id = charactertypes.id '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'INNER JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id AND characterroles.name = ? '.
'WHERE seminary_id = ? AND cache_characters.xps > ?',
'sid',
'user',
$seminaryId, $xps
);
if(!empty($data)) {
return $data[0]['c'] + 1;
}
return 1;
}
/**
* Get the superior $count Characters in the ranking.
*
* @param int $seminaryId ID of Seminary
* @param int $xps XP-value of Character
* @param int $count Count of Characters to determine
* @return array List of superior Characters
*/
public function getSuperiorCharacters($seminaryId, $xps, $count)
{
$data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'INNER JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'INNER JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id AND characterroles.name = ? '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE charactertypes.seminary_id = ? AND cache_characters.xps > ? '.
'ORDER BY cache_characters.xps ASC, RAND() '.
'LIMIT ?',
'sidd',
'user',
$seminaryId, $xps, $count
);
$data = array_reverse($data);
return $data;
}
/**
* Get the inferior $count Characters in the ranking.
*
* @param int $seminaryId ID of Seminary
* @param int characterId ID of Character
* @param int $xps XP-value of Character
* @param int $count Count of Characters to determine
* @return array List of inferior Characters
*/
public function getInferiorCharacters($seminaryId, $characterId, $xps, $count)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel '.
'FROM characters '.
'INNER JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'INNER JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id AND characterroles.name = ? '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE charactertypes.seminary_id = ? AND cache_characters.xps <= ? AND characters.id <> ? '.
'ORDER BY cache_characters.xps DESC, RAND() '.
'LIMIT ?',
'sidid',
'user',
$seminaryId, $xps, $characterId, $count
);
}
/**
* Get Characters that solved a Quest.
*
* @param int $questId ID of Quest to get Characters for
* @return array Characters data
*/
public function getCharactersSolvedQuest($questId)
{
return $data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'quests_characters.created AS submission_created '.
'FROM quests_characters '.
'INNER JOIN characters ON characters.id = quests_characters.character_id '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE quests_characters.quest_id = ? AND quests_characters.status = ? AND NOT EXISTS ('.
'SELECT id '.
'FROM quests_characters AS qc '.
'WHERE qc.quest_id = quests_characters.quest_id AND qc.character_id = quests_characters.character_id AND qc.created > quests_characters.created'.
') '.
'ORDER BY quests_characters.created ASC',
'ii',
$questId, QuestsModel::QUEST_STATUS_SOLVED
);
}
/**
* Get Characters that did not solv a Quest.
*
* @param int $questId ID of Quest to get Characters for
* @return array Characters data
*/
public function getCharactersUnsolvedQuest($questId)
{
return $data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'quests_characters.created AS submission_created '.
'FROM quests_characters '.
'INNER JOIN characters ON characters.id = quests_characters.character_id '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE quests_characters.quest_id = ? AND quests_characters.status = ? AND NOT EXISTS ('.
'SELECT id '.
'FROM quests_characters AS qc '.
'WHERE qc.quest_id = quests_characters.quest_id AND qc.character_id = quests_characters.character_id AND qc.created > quests_characters.created'.
') '.
'ORDER BY quests_characters.created ASC',
'ii',
$questId, QuestsModel::QUEST_STATUS_UNSOLVED
);
}
/**
* Get Characters that sent a submission for a Quest.
*
* @param int $questId ID of Quest to get Characters for
* @return array Characters data
*/
public function getCharactersSubmittedQuest($questId)
{
return $data = $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps,cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'quests_characters.created AS submission_created '.
'FROM quests_characters '.
'INNER JOIN characters ON characters.id = quests_characters.character_id '.
'INNER JOIN cache_characters ON cache_characters.character_id = characters.id '.
'INNER JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'INNER JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'WHERE quests_characters.quest_id = ? AND quests_characters.status = ? AND NOT EXISTS ('.
'SELECT id '.
'FROM quests_characters AS qc '.
'WHERE qc.quest_id = quests_characters.quest_id AND qc.character_id = quests_characters.character_id AND qc.created > quests_characters.created'.
') '.
'ORDER BY quests_characters.created ASC',
'ii',
$questId, QuestsModel::QUEST_STATUS_SUBMITTED
);
}
/**
* Get Characters with the given Character role.
*
* @param int $seminaryId ID of Seminary
* @param string $characterrole Character role
* @return array List of users
*/
public function getCharactersWithCharacterRole($seminaryId, $characterrole)
{
return $this->db->query(
'SELECT '.
'characters.id, characters.created, characters.user_id, characters.name, characters.url, cache_characters.xps, cache_characters.quest_xps, cache_characters.avatar_id, '.
'charactertypes.id AS charactertype_id, charactertypes.name AS charactertype_name, charactertypes.url AS charactertype_url, '.
'xplevels.id AS xplevel_id, xplevels.level AS xplevel, '.
'seminaries.id AS seminary_id, seminaries.url AS seminary_url, seminaries.title AS seminary_title, seminaries.url AS seminary_url '.
'FROM characters '.
'LEFT JOIN cache_characters ON cache_characters.character_id = characters.id '.
'LEFT JOIN charactertypes ON charactertypes.id = characters.charactertype_id '.
'LEFT JOIN xplevels ON xplevels.id = cache_characters.xplevel_id '.
'LEFT JOIN seminaries ON seminaries.id = charactertypes.seminary_id '.
'LEFT JOIN characters_characterroles ON characters_characterroles.character_id = characters.id '.
'LEFT JOIN characterroles ON characterroles.id = characters_characterroles.characterrole_id '.
'WHERE seminaries.id = ? AND characterroles.name = ?',
'is',
$seminaryId, $characterrole
);
}
/**
* Check if a Character name already exists.
*
* @param string $name Character name to check
* @param int $characterId Do not check this ID (for editing)
* @return boolean Whether Character name exists or not
*/
public function characterNameExists($name, $characterId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM characters '.
'WHERE name = ? OR url = ?',
'ss',
$name,
\nre\core\Linker::createLinkParam($name)
);
return (!empty($data) && (is_null($characterId) || $characterId != $data[0]['id']));
}
/**
* 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();
}
/**
* Edit a new Character.
*
* @param int $characterId ID of the Character to edit
* @param int $charactertypeId ID of new type of Character
* @param string $characterName New name for Character
*/
public function editCharacter($characterId, $charactertypeId, $characterName)
{
$this->db->query(
'UPDATE characters '.
'SET charactertype_id = ?, name = ?, url = ? '.
'WHERE id = ?',
'issi',
$charactertypeId,
$characterName,
\nre\core\Linker::createLinkParam($characterName),
$characterId
);
}
/**
* Delete a Character.
*
* @param int $characterId ID of the Character to delete
*/
public function deleteCharacter($characterId)
{
$this->db->query('DELETE FROM characters WHERE id = ?', 'i', $characterId);
}
}
?>

View file

@ -0,0 +1,252 @@
<?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, seminary_id, name, url '.
'FROM charactertypes '.
'WHERE seminary_id = ? '.
'ORDER BY name ASC',
'i',
$seminaryId
);
}
/**
* Get Character type by its URL.
*
* @param int $seminaryId ID of Seminary
* @param string $charactretypeUrl URL-title of Character type
* @return array Character type data
*/
public function getCharactertypeByUrl($seminaryId, $charactertypeUrl)
{
$data = $this->db->query(
'SELECT id, seminary_id, name, url '.
'FROM charactertypes '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId,
$charactertypeUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($charactertypeUrl);
}
return $data[0];
}
/**
* Get Character type by its ID.
*
* @param string $charactertypeId ID of Character type
* @return array Character type data
*/
public function getCharactertypeById($charactertypeId)
{
$data = $this->db->query(
'SELECT id, seminary_id, name, url '.
'FROM charactertypes '.
'WHERE id = ?',
'i',
$charactertypeId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($charactertypeId);
}
return $data[0];
}
/**
* Check if a Charactertype name already exists.
*
* @param int $seminaryId ID of Seminary
* @param string $name Charactertype name to check
* @param int $charactertypeId Do not check this ID (for editing)
* @return boolean Whether Charactertype name exists or not
*/
public function charactertypeNameExists($seminaryId, $name, $charactertypeId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM charactertypes '.
'WHERE seminary_id = ? AND (name = ? OR url = ?)',
'iss',
$seminaryId,
$name,
\nre\core\Linker::createLinkParam($name)
);
return (!empty($data) && (is_null($charactertypeId) || $charactertypeId != $data[0]['id']));
}
/**
* Create a new Charactertype for a Seminary.
*
* @param int $userId ID of creating user
* @param int $seminaryId ID of Seminary
* @param string $name Name for new Charactertype
* @return int ID of newly created Charactertype
*/
public function createCharactertype($userId, $seminaryId, $name)
{
$charactertypeId = null;
$this->db->setAutocommit(false);
try {
// Create Charactertype
$this->db->query(
'INSERT INTO charactertypes '.
'(created_user_id, seminary_id, name, url) '.
'VALUES '.
'(?, ?, ?, ?) ',
'iiss',
$userId,
$seminaryId,
$name,
\nre\core\Linker::createLinkParam($name)
);
$charactertypeId = $this->db->getInsertId();
// Create avatars
$this->db->query(
'INSERT INTO avatars '.
'(created_user_id, charactertype_id, xplevel_id) '.
'SELECT ?, ?, xplevels.id '.
'FROM xplevels '.
'WHERE seminary_id = ?',
'iii',
$userId,
$charactertypeId,
$seminaryId
);
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
return $charactertypeId;
}
/**
* Edit a Charactertype.
*
* @param int $charactertypeId ID of Charactertype to edit
* @param string $name New name of Charactertype
*/
public function editCharactertype($charactertypeId, $name)
{
$this->db->query(
'UPDATE charactertypes '.
'SET name = ?, url = ? '.
'WHERE id = ?',
'ssi',
$name,
\nre\core\Linker::createLinkParam($name),
$charactertypeId
);
}
/**
* Copy all Charactertypes of a Seminary.
*
* @param int $userId ID of copying user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
* @param array Mapping of Charactertype-IDs from source Seminary to targetSeminary
*/
public function copyCharactertypesOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId)
{
$charactertypeIds = array();
// Get Charactertypes
$charactertypes = $this->getCharacterTypesForSeminary($sourceSeminaryId);
// Copy each Charactertype
foreach($charactertypes as &$type)
{
$this->db->query(
'INSERT INTO charactertypes '.
'(created_user_id, seminary_id, name, url) '.
'SELECT ?, ?, name, url '.
'FROM charactertypes '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$type['id']
);
$charactertypeIds[$type['id']] = $this->db->getInsertId();
}
return $charactertypeIds;
}
/**
* Delete a Charactertype.
*
* @param int $charactertypeId ID of Charactertype to delete
*/
public function deleteCharactertype($charactertypeId)
{
$this->db->query('DELETE FROM charactertypes WHERE id = ?', 'i', $charactertypeId);
}
}
?>

83
models/DatabaseModel.inc Normal file
View file

@ -0,0 +1,83 @@
<?php
/**
* NRE
*
* @author coderkun <olli@coderkun.de>
* @copyright 2013 coderkun (http://www.coderkun.de)
* @license http://www.gnu.org/licenses/gpl.html
* @link http://www.coderkun.de/projects/nre
*/
namespace nre\models;
/**
* Default implementation of a database model.
*
* @author coderkun <olli@coderkun.de>
*/
class DatabaseModel extends \nre\core\Model
{
/**
* Database connection
*
* @static
* @var \nre\drivers\DatabaseDriver
*/
protected $db = NULL;
/**
* Construct a new datamase model.
*
* @throws \nre\exceptions\DatamodelException
* @throws \nre\exceptions\DriverNotFoundException
* @throws \nre\exceptions\DriverNotValidException
* @param string $type Database type
* @param array $config Connection settings
*/
function __construct($type, $config)
{
parent::__construct();
// Load database driver
$this->loadDriver($type);
// Establish database connection
$this->connect($type, $config);
}
/**
* Load the database driver.
*
* @throws \nre\exceptions\DriverNotFoundException
* @throws \nre\exceptions\DriverNotValidException
* @param string $driverName Name of the database driver
*/
private function loadDriver($driverName)
{
\nre\core\Driver::load($driverName);
}
/**
* Establish a connection to the database.
*
* @throws \nre\exceptions\DatamodelException
* @param string $driverName Name of the database driver
* @param array $config Connection settings
*/
private function connect($driverName, $config)
{
$this->db = \nre\core\Driver::factory($driverName, $config);
}
}
?>

62
models/MapModel.inc Normal file
View file

@ -0,0 +1,62 @@
<?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 the maps-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class MapModel extends \hhu\z\Model
{
/**
* Construct a new MapModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get the map of a Seminary.
*
* @param int $seminaryId ID of Seminary to get map of
* @return array Map data
*/
public function getMapOfSeminary($seminaryId)
{
$data = $this->db->query(
'SELECT seminary_id, seminarymedia_id, width, height '.
'FROM maps '.
'WHERE seminary_id = ?',
'i',
$seminaryId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
}
?>

655
models/MediaModel.inc Normal file
View file

@ -0,0 +1,655 @@
<?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 the Media-tables.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class MediaModel extends \hhu\z\Model
{
/**
* Construct a new MediaModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get a medium by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $mediaURL URL-name of the Medium
* @return array Medium data
*/
public function getMediaByUrl($mediaUrl)
{
$data = $this->db->query(
'SELECT id, name, url, description, mimetype '.
'FROM media '.
'WHERE url = ?',
's',
$mediaUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($mediaUrl);
}
return $data[0];
}
/**
* Get a medium by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $mediaId ID of the Medium
* @return array Medium data
*/
public function getMediaById($mediaId)
{
$data = $this->db->query(
'SELECT id, name, url, description, mimetype '.
'FROM media '.
'WHERE id = ?',
'i',
$mediaId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($mediaId);
}
return $data[0];
}
/**
* Get a Seminary medium by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of the seminary
* @param string $seminaryMediaUrl URL-name of the Seminary medium
* @return array Seminary medium data
*/
public function getSeminaryMediaByUrl($seminaryId, $seminaryMediaUrl)
{
$data = $this->db->query(
'SELECT id, name, url, description, mimetype '.
'FROM seminarymedia '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId,
$seminaryMediaUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($seminaryId.': '.$seminaryMediaUrl);
}
return $data[0];
}
/**
* Get a Seminary medium by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryMediaId ID of the Seminary medium
* @return array Seminary medium data
*/
public function getSeminaryMediaById($mediaId)
{
$data = $this->db->query(
'SELECT id, name, url, description, mimetype '.
'FROM seminarymedia '.
'WHERE id = ?',
'i',
$mediaId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($mediaId);
}
return $data[0];
}
/**
* Copy all media from a Seminary.
*
* @param int $userId ID of creating user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
* @return array Mapping of Media-IDs from source Seminary to target Seminary
*/
public function copySeminaryMedia($userId, $sourceSeminaryId, $targetSeminaryId)
{
$seminaryMediaIds = array();
$copiedFiles = array();
// Get all media from a Seminary
$seminaryMedia = $this->db->query(
'SELECT id '.
'FROM seminarymedia '.
'WHERE seminary_id = ?',
'i',
$sourceSeminaryId
);
// Copy each medium
try {
foreach($seminaryMedia as &$medium)
{
// Copy database record
$this->db->query(
'INSERT INTO seminarymedia '.
'(created_user_id, seminary_id, name, url, description, mimetype) '.
'SELECT ?, ?, name, url, description, mimetype '.
'FROM seminarymedia '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$medium['id']
);
$seminaryMediaIds[$medium['id']] = $this->db->getInsertId();
// Copy file
$sourceFilename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$medium['id'];
$targetFilename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$seminaryMediaIds[$medium['id']];
if(!copy($sourceFilename, $targetFilename)) {
throw new \hhu\z\exceptions\FileCopyException(error_get_last());
}
$copiedFiles[] = $targetFilename;
}
}
catch(\hhu\z\exceptions\FileCopyException $e) {
// Cleanup
foreach($copiedFiles as $filename) {
unlink($filename);
}
throw $e;
}
// Return new media IDs
return $seminaryMediaIds;
}
/**
* Create a new moodpic.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createMoodpic($userId, $seminaryId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Upload file
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Create a new Avatar picture for a Charactertype by creating a new Seminarymedia and
* adding it to the list of Avatar pictures.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createAvatarpicture($userId, $seminaryId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Add media to Achievements media
$this->db->query(
'INSERT INTO avatarpictures '.
'(seminarymedia_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$mediaId,
$userId,
$userId
);
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Copy an Avatar picture.
*
* @param int $userId ID of creating user
* @param int $seminaryMediaId ID of Seminary media to copy
*/
public function copyAvatarpicture($userId, $avatarpictureId)
{
$this->db->query(
'INSERT INTO avatarpictures '.
'(seminarymedia_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$avatarpictureId,
$userId,
$userId
);
}
/**
* Create a new Questgroup picture (Moodpic).
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param int $questgroupId ID of Questgroup to create picture for
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createQuestgrouppicture($userId, $seminaryId, $questgroupId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Add media to Questgroups pictures
$this->db->query(
'INSERT INTO questgroupspictures '.
'(media_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$mediaId,
$userId,
$userId
);
// Upload file
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Copy a Questgroup picture.
*
* @param int $userId ID of creating user
* @param int $seminaryMediaId ID of Seminary media to copy
*/
public function copyQuestgroupspicture($userId, $questgroupspictureId)
{
$this->db->query(
'INSERT INTO questgroupspictures '.
'(media_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$questgroupspictureId,
$userId,
$userId
);
}
/**
* Create a new Quests media by creating a new Seminarymedia and
* adding it to the list of Quests media.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createQuestMedia($userId, $seminaryId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Add media to Quests media
$this->db->query(
'INSERT INTO questsmedia '.
'(media_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$mediaId,
$userId,
$userId
);
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
else {
$this->db->commit();
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Copy media of a Quest.
*
* @param int $userId ID of creating user
* @param int $seminaryMediaId ID of Quest media to copy
*/
public function copyQuestsmedia($userId, $seminaryMediaId)
{
$this->db->query(
'INSERT INTO questsmedia '.
'(media_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$seminaryMediaId,
$userId,
$userId
);
}
/**
* Create a new Character groups media by creating a new Seminarymedia and
* adding it to the list of media for Character groups.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createCharactergroupMedia($userId, $seminaryId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Add media to Character groups media
$this->db->query(
'INSERT INTO charactergroupsmedia '.
'(seminarymedia_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$mediaId,
$userId,
$userId
);
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Create a new Achievement media by creating a new Seminarymedia and
* adding it to the list of media for Achievements.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @param string $tmpFilename Name of temporary uploaded file
* @return mixed ID of media record or false if upload failed
*/
public function createAchievementMedia($userId, $seminaryId, $filename, $description, $mimetype, $tmpFilename)
{
$mediaId = false;
$this->db->setAutocommit(false);
try {
// Create Seminary media record
$mediaId = $this->createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype);
// Add media to Achievements media
$this->db->query(
'INSERT INTO achievementsmedia '.
'(seminarymedia_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$mediaId,
$userId,
$userId
);
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$mediaId;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$mediaId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $mediaId;
}
/**
* Copy Achievement media.
*
* @param int $userId ID of creating user
* @param int $seminaryMediaId ID of Seminary media to copy
*/
public function copyAchievementMedia($userId, $seminaryMediaId)
{
$this->db->query(
'INSERT INTO achievementsmedia '.
'(seminarymedia_id, created_user_id) '.
'VALUES '.
'(?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'created_user_id = ?',
'iii',
$seminaryMediaId,
$userId,
$userId
);
}
/**
* Create a new Seminary media.
*
* @param int $userId ID of user that does the upload
* @param int $seminaryId ID of Seminary
* @param string $filename Filename of uploading media
* @param string $description Description for media
* @param string $mimetype Mimetype of media
* @return mixed ID of media record or false if upload failed
*/
private function createSeminaryMedia($userId, $seminaryId, $filename, $description, $mimetype)
{
// Check for existing database record
$data = $this->db->query(
'SELECT id '.
'FROM seminarymedia '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId,
\nre\core\Linker::createLinkParam($filename)
);
if(!empty($data)) {
return $data[0]['id'];
}
// Create database record
$this->db->query(
'INSERT INTO seminarymedia '.
'(created_user_id, seminary_id, name, url, description, mimetype) '.
'VALUES '.
'(?, ? ,? ,?, ?, ?)',
'iissss',
$userId,
$seminaryId,
$filename,
\nre\core\Linker::createLinkParam($filename),
$description,
$mimetype
);
return $this->db->getInsertId();
}
}
?>

1002
models/QuestgroupsModel.inc Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,393 @@
<?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 Questgroupshierarchy-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuestgroupshierarchyModel extends \hhu\z\Model
{
/**
* Construct a new QuestgroupshierarchyModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get a Questgroup hierarchy by its ID.
*
* throws \nre\exceptions\IdNotFoundException
* @param int $questgroupshierarchyId ID of a Questgroup hierarchy
* @return array Questgroup hierarchy
*/
public function getHierarchyById($questgroupshierarchyId)
{
$data = $this->db->query(
'SELECT id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE questgroupshierarchy.id = ?',
'i',
$questgroupshierarchyId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questgroupshierarchyId);
}
return $data[0];
}
/**
* Get a Questgroup hierarchy by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of Seminary
* @param int $questgroupshierarchyURL URL of a Questgroup hierarchy
* @return array Questgroup hierarchy
*/
public function getHierarchyByUrl($seminaryId, $questgroupshierarchyUrl)
{
$data = $this->db->query(
'SELECT id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE questgroupshierarchy.seminary_id = ? AND questgroupshierarchy.url = ?',
'is',
$seminaryId,
$questgroupshierarchyUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questgroupshierarchyUrl);
}
return $data[0];
}
/**
* Get the toplevel hierarchy entries of a Seminary.
*
* @param int $seminaryId ID of the seminary to get hierarchy for
* @return array Toplevel hierarchy
*/
public function getHierarchyOfSeminary($seminaryId)
{
return $this->db->query(
'SELECT id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE '.
'questgroupshierarchy.seminary_id = ? AND '.
'questgroupshierarchy.parent_questgroupshierarchy_id IS NULL '.
'ORDER BY questgroupshierarchy.pos ASC',
'i',
$seminaryId
);
}
/**
* Get the Questgroup-Hierarchy for a Questgroup.
*
* @param int $questgroupId ID of Questgroup
* @return array Hierarchy for Questgroup
*/
public function getHierarchyForQuestgroup($questgroupId)
{
$data = $this->db->query(
'SELECT questgroups_questgroupshierarchy.parent_questgroup_id, questgroups_questgroupshierarchy.pos AS questgroup_pos, questgroupshierarchy.id, questgroupshierarchy.seminary_id, questgroupshierarchy.parent_questgroupshierarchy_id, questgroupshierarchy.pos, questgroupshierarchy.title_singular, questgroupshierarchy.title_plural, questgroupshierarchy.url '.
'FROM questgroups_questgroupshierarchy '.
'INNER JOIN questgroupshierarchy ON questgroupshierarchy.id = questgroups_questgroupshierarchy.questgroupshierarchy_id '.
'WHERE questgroups_questgroupshierarchy.questgroup_id = ?',
'i',
$questgroupId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get the child hierarchy entries of a Questgroup hierarchy.
*
* @param int $questgroupshierarchyId ID of a Questgroup hierarchy
* @return array Child Questgroup hierarchy entries
*/
public function getChildQuestgroupshierarchy($questgroupshierarchyId)
{
return $this->db->query(
'SELECT id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE questgroupshierarchy.parent_questgroupshierarchy_id = ? '.
'ORDER BY questgroupshierarchy.pos ASC',
'i',
$questgroupshierarchyId
);
}
/**
* Check if a title for a Questgroupshierarchy already exists
* for a Seminary.
*
* @param string $title
* @param int $seminaryId
* @param int $questgroupshierarchyId Do not check this Questgroupshierarchy (for editing)
* @return Whether title already exists or not
*/
public function questgroupshierarchyTitleSingularExists($title, $seminaryId, $questgroupshierarchyId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM questgroupshierarchy '.
'WHERE seminary_id = ? AND (title_singular = ? OR url = ?) ',
'iss',
$seminaryId,
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($questgroupshierarchyId) || $questgroupshierarchyId != $data[0]['id']));
}
/**
* Create a new Questgroupshierarchy for a Seminary
*
* @param int $userId ID of creating user
* @param int $seminaryId ID of Seminary
* @param int $parentQuestgroupsierarchyId ID of parent Questgroupshierarchy
* @param string $title Title (singular)
* @param string $course Title (plural)
*/
public function createQuestgroupshierarchy($userId, $seminaryId, $parentQuestgroupsierarchyId, $titleSingular, $titlePlural)
{
// Get last position
$pos = $this->db->query(
'SELECT COALESCE(MAX(pos),0) AS pos '.
'FROM questgroupshierarchy '.
'WHERE seminary_id = ? AND '.
'parent_questgroupshierarchy_id '.(!is_null($parentQuestgroupsierarchyId) ? sprintf('= %d', $parentQuestgroupsierarchyId) : 'IS NULL'),
'i',
$seminaryId
);
$pos = intval($pos[0]['pos']);
// Create Questgroupshierarchy
$this->db->query(
'INSERT INTO questgroupshierarchy '.
'(created_user_id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url) '.
'VALUES '.
'(?, ?, ?, ?, ?, ?, ?)',
'iiiisss',
$userId,
$seminaryId,
$parentQuestgroupsierarchyId,
$pos + 1,
$titleSingular,
$titlePlural,
\nre\core\Linker::createLinkParam($titleSingular)
);
return $this->db->getInsertId();
}
/**
* Edit a Questgroupshierarchy.
*
* @param int $questgroupshierarchyId ID of Questgroupshierarchy to edit
* @param string $title New title (singular)
* @param string $course New title (plural)
*/
public function editQuestgroupshierarchy($questgroupshierarchyId, $titleSingular, $titlePlural)
{
$this->db->query(
'UPDATE questgroupshierarchy '.
'SET title_singular = ?, title_plural = ?, url = ? '.
'WHERE id = ?',
'sssi',
$titleSingular,
$titlePlural,
\nre\core\Linker::createLinkParam($titleSingular),
$questgroupshierarchyId
);
}
/**
* Move a Questgroupshierarchy up (decrement position) or down
* (increment position).
*
* @param array $questgroupshierarchy Questgroupshierarchy to move
* @param boolean $up True for moving up, false for down
*/
public function moveQuestgroupshierarchy($questgroupshierarchy, $up)
{
$this->db->setAutocommit(false);
try {
// Set temporary position
$this->db->query(
'UPDATE questgroupshierarchy '.
'SET pos = 0 '.
'WHERE id = ?',
'i',
$questgroupshierarchy['id']
);
// Switch entry
if(is_null($questgroupshierarchy['parent_questgroupshierarchy_id'])) {
$this->db->query(
'UPDATE questgroupshierarchy '.
'SET pos = ? '.
'WHERE parent_questgroupshierarchy_id IS NULL AND pos = ?',
'ii',
$questgroupshierarchy['pos'],
$questgroupshierarchy['pos'] + ($up ? -1 : 1)
);
}
else {
$this->db->query(
'UPDATE questgroupshierarchy '.
'SET pos = ? '.
'WHERE parent_questgroupshierarchy_id = ? AND pos = ?',
'iii',
$questgroupshierarchy['pos'],
$questgroupshierarchy['parent_questgroupshierarchy_id'],
$questgroupshierarchy['pos'] + ($up ? -1 : 1)
);
}
// Set new position
$this->db->query(
'UPDATE questgroupshierarchy '.
'SET pos = ? '.
'WHERE id = ?',
'ii',
$questgroupshierarchy['pos'] + ($up ? -1 : 1),
$questgroupshierarchy['id']
);
$this->db->commit();
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
/**
* Copy complete Questgroupshierarchy of a Seminary.
*
* @param int $userId ID of creating user
* @param int $sourceSeminaryId ID of Seminary to copy hierarchy from
* @param int $targetSeminaryId ID of Seminary to copy hierarchy to
* @return array Mapping of hierarchy-IDs from source Seminary to target Seminary
*/
public function copyQuestgroupshierarchy($userId, $sourceSeminaryId, $targetSeminaryId)
{
// Get Hierarchy of Seminary
$questgroupshierarchy = $this->getHierarchyOfSeminary($sourceSeminaryId);
// Copy hierarchy
$hierarchyIds = array();
foreach($questgroupshierarchy as $hierarchy) {
$this->copyHierarchy($userId, $sourceSeminaryId, $targetSeminaryId, $hierarchy, $hierarchyIds);
}
return $hierarchyIds;
}
/**
* Delete a Questgroupshierarchy.
*
* @param int $seminaryId ID of the seminary to delete
*/
public function deleteQuestgroupshierarchy($questgroupshierarchyId)
{
$this->db->query('DELETE FROM questgroupshierarchy WHERE id = ?', 'i', $questgroupshierarchyId);
}
/**
* Copy a Questgroupshierarchy and its child hierarchy.
*
* @param int $userId ID of creating user
* @param int $sourceSeminaryId ID of Seminary to copy hierarchy from
* @param int $targetSeminaryId ID of Seminary to copy hierarchy to
* @param array $hierarchy Hierarchy to copy
* @return array $hierarchyIds Mapping of hierarchy IDs from source Seminary to target Seminary
*/
private function copyHierarchy($userId, $sourceSeminaryId, $targetSeminaryId, $hierarchy, &$hierarchyIds)
{
// insert for new seminary
if(is_null($hierarchy['parent_questgroupshierarchy_id']))
{
$this->db->query(
'INSERT INTO questgroupshierarchy '.
'(created_user_id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url) '.
'SELECT ?, ?, null, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$hierarchy['id']
);
}
else
{
$this->db->query(
'INSERT INTO questgroupshierarchy '.
'(created_user_id, seminary_id, parent_questgroupshierarchy_id, pos, title_singular, title_plural, url) '.
'SELECT ?, ?, ?, pos, title_singular, title_plural, url '.
'FROM questgroupshierarchy '.
'WHERE id = ?',
'iiii',
$userId, $targetSeminaryId, $hierarchyIds[$hierarchy['parent_questgroupshierarchy_id']],
$hierarchy['id']
);
}
$hierarchyIds[$hierarchy['id']] = $this->db->getInsertId();
// insert sub hierarchy
$childHierarchy = $this->getChildQuestgroupshierarchy($hierarchy['id']);
foreach($childHierarchy as $hierarchy) {
$this->copyHierarchy($userId, $sourceSeminaryId, $targetSeminaryId, $hierarchy, $hierarchyIds);
}
}
}
?>

View file

@ -0,0 +1,151 @@
<?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 Questgrouptexts-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuestgrouptextsModel extends \hhu\z\Model
{
/**
* Construct a new QuestgrouptextsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get texts of a Questgroup.
*
* @param int $questgroupId ID of a Questgroup
* @return array Texts of this Questgroup
*/
public function getQuestgroupTexts($questgroupId)
{
return $this->db->query(
'SELECT id, pos, text, questgroup_id '.
'FROM questgrouptexts '.
'WHERE questgroup_id = ? '.
'ORDER BY pos ASC',
'i',
$questgroupId
);
}
/**
* Add a Questgroup text to a Questgroup.
*
* @param int $userId ID of user
* @param int $questgroupId ID of Questgroup to add text to
* @param string $text Text to add
*/
public function addQuestgrouptextToQuestgroup($userId, $questgroupId, $text)
{
// Get position
$pos = $this->db->query(
'SELECT COALESCE(MAX(pos),0)+1 AS pos '.
'FROM questgrouptexts '.
'WHERE questgroup_id = ?',
'i',
$questgroupId
);
$pos = $pos[0]['pos'];
// Add Questgroup text
$this->db->query(
'INSERT INTO questgrouptexts '.
'(created_user_id, questgroup_id, pos, text) '.
'VALUES '.
'(?, ?, ?, ?)',
'iiis',
$userId, $questgroupId, $pos, $text
);
}
/**
* Edit a Questgroup text.
*
* @param int $questgrouptextId ID of Questgroup text to edit
* @param string $text New text
*/
public function editQuestgrouptext($questgrouptextId, $text)
{
$this->db->query(
'UPDATE questgrouptexts '.
'SET text = ? '.
'WHERE id = ?',
'si',
$text,
$questgrouptextId
);
}
/**
* Copy Questgroup texts from one Questgroup to another.
*
* @param $userId ID of copying user
* @param $sourceQuestgroupId ID of source Questgroup
* @param $targetQuestgroupId ID of target Questgroup
*/
public function copyQuestgrouptexts($userId, $sourceQuestgroupId, $targetQuestgroupId)
{
$this->db->query(
'INSERT INTO questgrouptexts '.
'(created_user_id, questgroup_id, pos, text) '.
'SELECT ?, ?, pos, text '.
'FROM questgrouptexts '.
'WHERE questgroup_id = ?',
'iii',
$userId, $targetQuestgroupId,
$sourceQuestgroupId
);
}
/**
* Delete a Questgroup text.
*
* @param array $questgrouptext Data of Questgroup text to delete
*/
public function deleteQuestgrouptext($questgrouptext)
{
// Delete Questgroup text
$this->db->query('DELETE FROM questgrouptexts WHERE id = ?', 'i', $questgrouptext['id']);
// Adjust positions
$this->db->query(
'UPDATE questgrouptexts '.
'SET pos = pos - 1 '.
'WHERE questgroup_id = ? AND pos > ?',
'ii',
$questgrouptext['questgroup_id'],
$questgrouptext['pos']
);
}
}
?>

818
models/QuestsModel.inc Normal file
View file

@ -0,0 +1,818 @@
<?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 Quests-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuestsModel extends \hhu\z\Model
{
/**
* Quest-status: Entered
*
* @var int;
*/
const QUEST_STATUS_ENTERED = 0;
/**
* Quest-status: submitted
*
* @var int;
*/
const QUEST_STATUS_SUBMITTED = 1;
/**
* Quest-status: Unsolved
*
* @var int;
*/
const QUEST_STATUS_UNSOLVED = 2;
/**
* Quest-status: Solved
*
* @var int;
*/
const QUEST_STATUS_SOLVED = 3;
/**
* Required models
*
* @var array
*/
public $models = array('questtypes', 'questtexts', 'media');
/**
* Construct a new QuestsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get a Quest and its data by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of the corresponding Seminary
* @param int $questgroupId ID of the corresponding Questgroup
* @param string $questURL URL-title of a Quest
* @return array Quest data
*/
public function getQuestByUrl($seminaryId, $questgroupId, $questUrl)
{
$data = $this->db->query(
'SELECT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.entry_text, quests.task, quests.wrong_text, quests.questsmedia_id '.
'FROM quests '.
'LEFT JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE questgroups.seminary_id = ? AND questgroups.id = ? AND quests.url = ?',
'iis',
$seminaryId, $questgroupId, $questUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questUrl);
}
return $data[0];
}
/**
* Get a Quest and its data by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $questId ID of a Quest
* @return array Quest data
*/
public function getQuestById($questId)
{
$data = $this->db->query(
'SELECT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.entry_text, quests.task, quests.wrong_text, quests.questsmedia_id '.
'FROM quests '.
'LEFT JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE quests.id = ?',
'i',
$questId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questId);
}
return $data[0];
}
/**
* Get the first Quest of a Qusetgroup.
*
* @param int $questId ID of Questgroup
* @return array Data of first Quest
*/
public function getFirstQuestOfQuestgroup($questgroupId)
{
$data = $this->db->query(
'SELECT id, questtype_id, title, url, xps, task '.
'FROM quests '.
'LEFT JOIN quests_previousquests ON quests_previousquests.quest_id = quests.id '.
'WHERE questgroup_id = ? AND quests_previousquests.previous_quest_id IS NULL',
'i',
$questgroupId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get all Quests a Qusetgroup that do not have a following
* Quest.
*
* @param int $questId ID of Questgroup
* @return array List of last Quests
*/
public function getLastQuestsOfQuestgroup($questgroupId)
{
return $this->db->query(
'SELECT id, questtype_id, title, url, xps, task '.
'FROM quests '.
'WHERE questgroup_id = ? AND NOT EXISTS ('.
'SELECT quest_id '.
'FROM quests_previousquests '.
'WHERE quests_previousquests.previous_quest_id = quests.id'.
')',
'i',
$questgroupId
);
}
/**
* Get Quests that follow-up a Quest.
*
* @param int $questId ID of Quest to get next Quests of
* @return array Quests data
*/
public function getNextQuests($questId)
{
return $this->db->query(
'SELECT quests.id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.entry_text, quests.task, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url '.
'FROM quests_previousquests '.
'INNER JOIN quests ON quests.id = quests_previousquests.quest_id '.
'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE quests_previousquests.previous_quest_id = ?',
'i',
$questId
);
}
/**
* Get Quests that the given Quests follows-up to.
*
* @param int $questId ID of Quest to get previous Quests of
* @return array Quests data
*/
public function getPreviousQuests($questId)
{
return $this->db->query(
'SELECT quests.id, quests.title, quests.url, quests.entry_text, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url '.
'FROM quests_previousquests '.
'INNER JOIN quests ON quests.id = quests_previousquests.previous_quest_id '.
'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE quests_previousquests.quest_id = ?',
'i',
$questId
);
}
/**
* Set the previous Quest for a Quest.
*
* @param int $questId ID of Quest to set previous Quest for
* @param int $previousQuestId Id of previous Quest
*/
public function setPreviousQuest($questId, $previousQuestId)
{
$this->db->query(
'REPLACE INTO quests_previousquests '.
'(quest_id, previous_quest_id) '.
'VALUES '.
'(?, ?)',
'ii',
$questId,
$previousQuestId
);
}
/**
* Mark a Quest as entered for a Character.
*
* @param int $questId ID of Quest to mark as entered
* @param int $characterId ID of Character that entered the Quest
*/
public function setQuestEntered($questId, $characterId)
{
$this->setQuestStatus($questId, $characterId, self::QUEST_STATUS_ENTERED, false);
}
/**
* Mark a Quest as submitted for a Character.
*
* @param int $questId ID of Quest to mark as unsolved
* @param int $characterId ID of Character that unsolved the Quest
*/
public function setQuestSubmitted($questId, $characterId)
{
$this->setQuestStatus($questId, $characterId, self::QUEST_STATUS_SUBMITTED);
}
/**
* Mark a Quest as unsolved for a Character.
*
* @param int $questId ID of Quest to mark as unsolved
* @param int $characterId ID of Character that unsolved the Quest
*/
public function setQuestUnsolved($questId, $characterId)
{
$this->setQuestStatus($questId, $characterId, self::QUEST_STATUS_UNSOLVED);
}
/**
* Mark a Quest as solved for a Character.
*
* @param int $questId ID of Quest to mark as solved
* @param int $characterId ID of Character that solved the Quest
*/
public function setQuestSolved($questId, $characterId)
{
$this->setQuestStatus($questId, $characterId, self::QUEST_STATUS_SOLVED, false);
}
/**
* Determine if the given Character has entered a Quest.
*
* @param int $questId ID of Quest to check
* @param int $characterId ID of Character to check
* @result boolean Whether Character has entered the Quest or not
*/
public function hasCharacterEnteredQuest($questId, $characterId)
{
$count = $this->db->query(
'SELECT count(id) AS c '.
'FROM quests_characters '.
'WHERE quest_id = ? AND character_id = ? AND status IN (?,?,?)',
'iiiii',
$questId,
$characterId,
self::QUEST_STATUS_ENTERED, self::QUEST_STATUS_SOLVED, self::QUEST_STATUS_UNSOLVED
);
return (!empty($count) && intval($count[0]['c']) > 0);
}
/**
* Determine if the given Character has tried to solve a Quest.
*
* @param int $questId ID of Quest to check
* @param int $characterId ID of Character to check
* @result boolean Whether Character has tried to solved the Quest or not
*/
public function hasCharacterTriedQuest($questId, $characterId)
{
$count = $this->db->query(
'SELECT count(id) AS c '.
'FROM quests_characters '.
'WHERE quest_id = ? AND character_id = ? AND status IN (?,?)',
'iiii',
$questId,
$characterId,
self::QUEST_STATUS_SOLVED, self::QUEST_STATUS_UNSOLVED
);
return (!empty($count) && intval($count[0]['c']) > 0);
}
/**
* Determine if the given Character has solved the given Quest.
*
* @param int $questId ID of Quest to check
* @param int $characterId ID of Character to check
* @result boolean Whether Character has solved the Quest or not
*/
public function hasCharacterSolvedQuest($questId, $characterId)
{
$count = $this->db->query(
'SELECT count(id) AS c '.
'FROM quests_characters '.
'WHERE quest_id = ? AND character_id = ? AND status = ?',
'iii',
$questId,
$characterId,
self::QUEST_STATUS_SOLVED
);
return (!empty($count) && intval($count[0]['c']) > 0);
}
/**
* Get the last Quests for a Character.
*
* @param int $characterId ID of Character
* @retrun array Quest data
*/
public function getLastQuestForCharacter($characterId)
{
$data = $this->db->query(
'SELECT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.wrong_text, quests.questsmedia_id '.
'FROM quests_characters '.
'LEFT JOIN quests ON quests.id = quests_characters.quest_id '.
'WHERE quests_characters.character_id = ? AND quests_characters.status IN (?, ?, ?) '.
'ORDER BY quests_characters.created desc '.
'LIMIT 1',
'iiii',
$characterId,
self::QUEST_STATUS_ENTERED, self::QUEST_STATUS_SUBMITTED, self::QUEST_STATUS_SOLVED
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get all Quests for a Seminary.
*
* @param int $seminaryId ID of Seminary
* @return array Quests for this Seminary
*/
public function getQuestsForSeminary($seminaryId)
{
return $this->db->query(
'SELECT DISTINCT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.wrong_text, quests.questsmedia_id, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url '.
'FROM questgroups '.
'INNER JOIN quests ON quests.questgroup_id = questgroups.id '.
'WHERE questgroups.seminary_id = ? '.
'ORDER BY quests.title ASC',
'i',
$seminaryId
);
}
/**
* Get count of all Quests for a Seminary.
*
* @param int $seminaryId ID of Seminary
* @param int $questgroupId ID of Questgroup (optional)
* @param int $questtypeId ID of Questtype (optional)
* @param string $title Part of the title to filter for (optional)
* @return int Count of Quests for this Seminary
*/
public function getCountForQuestsForSeminaryByOpenSubmissions($seminaryId, $questgroupId=null, $questtypeId=null, $title=null)
{
$data = $this->db->query(
'SELECT count(DISTINCT quests.id) AS c '.
'FROM questgroups '.
'INNER JOIN quests ON quests.questgroup_id = questgroups.id '.
'WHERE questgroups.seminary_id = ? '.
(!empty($questgroupId) ? sprintf('AND questgroups.id = %d ', $questgroupId) : null).
(!empty($questtypeId) ? sprintf('AND quests.questtype_id = %d ', $questtypeId) : null).
(!empty($title) ? sprintf('AND quests.title LIKE \'%%%s%%\' ', $title) : null),
'i',
$seminaryId
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get all Quests for a Seminary order by their count of open
* submissions.
*
* @param int $seminaryId ID of Seminary
* @param int $questgroupId ID of Questgroup (optional)
* @param int $questtypeId ID of Questtype (optional)
* @param string $title Part of title to filter for (optional)
* @param int $limit Limit amount of Quests (optional)
* @param int $offset Offset (optional)
* @return array Quests for this Seminary
*/
public function getQuestsForSeminaryByOpenSubmissions($seminaryId, $questgroupId=null, $questtypeId=null, $title=null, $limit=null, $offset=0)
{
return $this->db->query(
'SELECT DISTINCT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.wrong_text, quests.questsmedia_id, questgroups.title AS questgroup_title, questgroups.url AS questgroup_url, ('.
'SELECT count(DISTINCT quests_characters.character_id) '.
'FROM quests_characters '.
'WHERE quests_characters.quest_id = quests.id AND quests_characters.status = ? AND NOT EXISTS ('.
'SELECT id '.
'FROM quests_characters AS qc '.
'WHERE qc.quest_id = quests_characters.quest_id AND qc.character_id = quests_characters.character_id AND qc.created > quests_characters.created'.
')'.
') AS opensubmissionscount '.
'FROM questgroups '.
'INNER JOIN quests ON quests.questgroup_id = questgroups.id '.
'WHERE questgroups.seminary_id = ? '.
(!empty($questgroupId) ? sprintf('AND questgroups.id = %d ', $questgroupId) : null).
(!empty($questtypeId) ? sprintf('AND quests.questtype_id = %d ', $questtypeId) : null).
(!empty($title) ? sprintf('AND quests.title LIKE \'%%%s%%\' ', $title) : null).
'ORDER BY opensubmissionscount DESC '.
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null),
'ii',
self::QUEST_STATUS_SUBMITTED,
$seminaryId
);
}
/**
* Get all Quests that are linked to a Questtopic.
*
* @param int $questtopicId ID of Questtopic
* @return array Quests for this Questtopic
*/
public function getQuestsForQuesttopic($questtopicId)
{
return $this->db->query(
'SELECT DISTINCT quests.id, quests.questgroup_id, quests.questtype_id, quests.title, quests.url, quests.xps, quests.task, quests.wrong_text, quests.questsmedia_id, questgroups.url AS questgroup_url '.
'FROM quests_questsubtopics '.
'INNER JOIN questsubtopics ON questsubtopics.id = quests_questsubtopics.questsubtopic_id '.
'INNER JOIN quests ON quests.id = quests_questsubtopics.quest_id '.
'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE questsubtopics.questtopic_id = ? '.
'ORDER BY quests.title ASC',
'i',
$questtopicId
);
}
/**
* Mark a Quest for a Character.
*
* @param int $questId ID of Quest to mark
* @param int $characterId ID of Character to mark the Quest for
* @param int $status Quest status to mark
* @param boolean $repeated Insert although status is already set for this Quest and Character
*/
private function setQuestStatus($questId, $characterId, $status, $repeated=true)
{
// Check if status is already set
if(!$repeated)
{
$count = $this->db->query(
'SELECT count(*) AS c '.
'FROM quests_characters '.
'WHERE quest_id = ? AND character_id = ? AND status = ?',
'iii',
$questId,
$characterId,
$status
);
if(!empty($count) && intval($count[0]['c']) > 0) {
return;
}
}
// Set status
$this->db->query(
'INSERT INTO quests_characters '.
'(quest_id, character_id, status) '.
'VALUES '.
'(?, ?, ?) ',
'iii',
$questId,
$characterId,
$status
);
}
/**
* Get the last status of a Quest for a Character.
*
* @param int $questId ID of Quest
* @param int $characterId ID of Character to get status for
* @return int Last status
*/
public function getLastQuestStatus($questId, $characterId)
{
$data = $this->db->query(
'SELECT id, created, status '.
'FROM quests_characters '.
'WHERE quest_id = ? AND character_id = ? '.
'ORDER BY created DESC '.
'LIMIT 1',
'ii',
$questId, $characterId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Check if a Quest title already exists.
*
* @param string $title Quest title to check
* @param int $seminaryId ID of Seminary
* @param int $questId Do not check this ID (for editing)
* @return boolean Whether Quest title exists or not
*/
public function questTitleExists($title, $seminaryId, $questId=null)
{
$data = $this->db->query(
'SELECT quests.id '.
'FROM quests '.
'INNER JOIN questgroups ON questgroups.id = quests.questgroup_id '.
'WHERE questgroups.seminary_id = ? AND (quests.title = ? OR quests.url = ?)',
'iss',
$seminaryId,
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($questId) || $questId != $data[0]['id']));
}
/**
* Create a new Quest.
*
* @param int $userId User-ID that creates the new character
* @param int $questgroupId ID of Questgroup
* @param int $questtypeId ID of Questtype
* @param string $title Title for new Quest
* @param int $xps XPs for new Quest
* @param string $task Task for new Quest
* @param string $entrytext Entrytext for new Quest
* @param string $wrongtext Wrongtext for new Quest
* @return int ID of new Quest
*/
public function createQuest($userId, $questgroupId, $questtypeId, $title, $xps, $task, $entrytext, $wrongtext)
{
$questId = null;
$this->db->setAutocommit(false);
try {
// Get last Quests of Questgroup
$lastQuests = $this->getLastQuestsOfQuestgroup($questgroupId);
// Create Quest
$this->db->query(
'INSERT INTO quests '.
'(created_user_id, questgroup_id, questtype_id, title, url, xps, entry_text, wrong_text, task) '.
'VALUES '.
'(?, ?, ?, ?, ?, ?, ?, ?, ?)',
'iiississs',
$userId, $questgroupId, $questtypeId,
$title, \nre\core\Linker::createLinkParam($title),
$xps, $entrytext, $wrongtext, $task
);
$questId = $this->db->getInsertId();
// Set previous Quest
if(count($lastQuests) > 0) {
$this->setPreviousQuest($questId, $lastQuests[0]['id']);
}
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
return $questId;
}
/**
* Set the media for a Quest.
*
* @param int $questId ID of Quest to set media for
* @param int $questmediaId ID of Questsmedia to set
*/
public function setQuestmedia($questId, $questsmediaId)
{
$this->db->query(
'UPDATE quests '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$questsmediaId,
$questId
);
}
/**
* Edit a new Quest.
*
* @param int $questId ID of Quest to edit
* @param int $questtypeId ID of Questtype
* @param string $title New title for Quest
* @param int $xps XPs for Quest
* @param string $task New task for Quest
* @param string $entrytext New entrytext for Quest
* @param string $wrongtext New wrongtext for Quest
*/
public function editQuest($questId, $questtypeId, $title, $xps, $task, $entrytext, $wrongtext)
{
$this->db->query(
'UPDATE quests '.
'SET questtype_id = ?, title = ?, url = ?, xps = ?, entry_text = ?, wrong_text = ?, task = ? '.
'WHERE id = ?',
'ississsi',
$questtypeId,
$title,
\nre\core\Linker::createLinkParam($title),
$xps,
$entrytext,
$wrongtext,
$task,
$questId
);
}
/**
* Copy all Quests from a Seminary.
*
* @param int $userId ID of creating user
* @param int $seminaryId ID of Seminary to copy from
* @param array $questgroupIds Mapping of Questgroup-IDs from source Seminary to target Seminary
* @param array $seminaryMediaIds Mapping of Seminary-media-IDs from source Seminary to target Seminary (optional)
* @return array Mapping of Quest-IDs from source Seminary to target Seminary
*/
public function copyQuests($userId, $sourceSeminaryId, $questgroupIds, $seminaryMediaIds=null)
{
$questIds = array();
$questtextIds = array();
// Get Quests
$quests = $this->getQuestsForSeminary($sourceSeminaryId);
// Copy each Quest
foreach($quests as &$quest)
{
// Copy Quest
$this->db->query(
'INSERT INTO quests '.
'(created_user_id, questgroup_id, questtype_id, title, url, xps, entry_text, wrong_text, task) '.
'SELECT ?, ?, questtype_id, title, url, xps, entry_text, wrong_text, task '.
'FROM quests '.
'WHERE id = ?',
'iii',
$userId, $questgroupIds[$quest['questgroup_id']],
$quest['id']
);
$questIds[$quest['id']] = $this->db->getInsertId();
// Copy media
if(!is_null($seminaryMediaIds) && !is_null($quest['questsmedia_id']))
{
$this->Media->copyQuestsmedia($userId, $seminaryMediaIds[$quest['questsmedia_id']]);
$this->db->query(
'UPDATE quests '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaIds[$quest['questsmedia_id']],
$questIds[$quest['id']]
);
}
// Copy texts
$questtextIds = $questtextIds + $this->Questtexts->copyQuesttexts($userId, $quest['id'], $questIds[$quest['id']], $seminaryMediaIds);
// Copy content
$questtype = $this->Questtypes->getQuesttypeById($quest['questtype_id']);
if(!is_null($questtype['classname']))
{
// Load Questtype Model
\hhu\z\models\QuesttypeModel::load($questtype['classname']);
// Construct Questtype Model
$questtypeModel = \hhu\z\models\QuesttypeModel::factory($questtype['classname']);
// Copy content
$questtypeModel->copyQuest($userId, $quest['id'], $questIds[$quest['id']], $seminaryMediaIds);
}
}
// Copy flow
// Do this after copying the Quests themselves to ensure all Quests
// have their target IDs.
foreach($quests as &$quest)
{
$previousQuests = $this->db->query(
'SELECT previous_quest_id '.
'FROM quests_previousquests '.
'WHERE quest_id = ?',
'i',
$quest['id']
);
foreach($previousQuests as &$previousQuest)
{
$this->db->query(
'INSERT INTO quests_previousquests '.
'(quest_id, previous_quest_id) '.
'VALUES '.
'(?, ?)',
'ii',
$questIds[$quest['id']],
$questIds[$previousQuest['previous_quest_id']]
);
}
}
return array(
'quests' => $questIds,
'questtexts' => $questtextIds
);
}
/**
* Delete a Quest of a Seminary.
*
* @param int $questId ID of Quest to delete
*/
public function deleteQuest($questId)
{
$this->db->setAutocommit(false);
try {
// Set previous Quests of following Quests
$previousQuests = $this->getPreviousQuests($questId);
$nextQuests = $this->getNextQuests($questId);
foreach($nextQuests as &$nextQuest) {
foreach($previousQuests as &$previousQuest) {
$this->setPreviousQuest($nextQuest['id'], $previousQuest['id']);
}
}
// Delete Quest
$this->db->query('DELETE FROM quests WHERE id = ?', 'i', $questId);
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
}
?>

389
models/QuesttextsModel.inc Normal file
View file

@ -0,0 +1,389 @@
<?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 Questtexts-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuesttextsModel extends \hhu\z\Model
{
/**
* Required models
*
* @var array
*/
public $models = array('media');
/**
* Construct a new QuesttextsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get the first text of a Quest.
*
* @param int $questId ID of a Quest
* @return string First text of this Quest or NULL
*/
public function getFirstQuestText($questId)
{
$prolog = $this->getQuesttextsOfQuest($questId, 'Prolog');
if(!empty($prolog)) {
return $prolog[0]['text'];
}
return null;
}
/**
* Get all Questtexts for a Quest.
*
* @param int $questId ID of the Quest
* @param string $questtexttypeUrl URL of the Questtexttype
* @return array All Questtexts for a Quest
*/
public function getQuesttextsOfQuest($questId, $questtexttypeUrl=null)
{
if(is_null($questtexttypeUrl))
{
return $this->db->query(
'SELECT questtexts.id, questtexts.quest_id, questtexts.text, questtexts.pos, questtexts.out_text, questtexts.abort_text, questtexts.questsmedia_id, questtexttypes.id AS type_id, questtexttypes.type, questtexttypes.url AS type_url '.
'FROM questtexts '.
'LEFT JOIN questtexttypes ON questtexttypes.id = questtexts.questtexttype_id '.
'WHERE questtexts.quest_id = ?',
'i',
$questId
);
}
else
{
return $this->db->query(
'SELECT questtexts.id, questtexts.quest_id, questtexts.text, questtexts.pos, questtexts.out_text, questtexts.abort_text, questtexts.questsmedia_id, questtexttypes.id AS type_id, questtexttypes.type, questtexttypes.url AS type_url '.
'FROM questtexts '.
'LEFT JOIN questtexttypes ON questtexttypes.id = questtexts.questtexttype_id '.
'WHERE questtexts.quest_id = ? and questtexttypes.url = ?',
'is',
$questId,
$questtexttypeUrl
);
}
}
/**
* Get count of Questtexts for a Quest.
*
* @param int $questId ID of the Quest
* @param string $questtexttypeUrl URL of the Questtexttype
* @return int Amount of Questtexts for a Quest
*/
public function getQuesttextCountOfQuest($questId, $questtexttypeUrl=null)
{
if(is_null($questtexttypeUrl))
{
$data = $this->db->query(
'SELECT count(questtexts.id) AS c '.
'FROM questtexts '.
'LEFT JOIN questtexttypes ON questtexttypes.id = questtexts.questtexttype_id '.
'WHERE questtexts.quest_id = ?',
'i',
$questId
);
}
else
{
$data = $this->db->query(
'SELECT count(questtexts.id) AS c '.
'FROM questtexts '.
'LEFT JOIN questtexttypes ON questtexttypes.id = questtexts.questtexttype_id '.
'WHERE questtexts.quest_id = ? and questtexttypes.url = ?',
'is',
$questId,
$questtexttypeUrl
);
}
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get corresponding Questtexts for a Questgroup.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $questgroupId ID of Questgroup to get the Questtexst for
* @param array List of Questtexts
*/
public function getRelatedQuesttextsForQuestgroup($questgroupId)
{
return $this->db->query(
'SELECT questtexts.id, questtexts.text, questtexts.pos, questtexts.quest_id, questtexttypes.id AS type_id, questtexttypes.type, questtexttypes.url AS type_url '.
'FROM questgroups_questtexts '.
'LEFT JOIN questtexts ON questtexts.id = questgroups_questtexts.questtext_id '.
'LEFT JOIN questtexttypes ON questtexttypes.id = questtexts.questtexttype_id '.
'WHERE questgroups_questtexts.questgroup_id = ?',
'i',
$questgroupId
);
}
/**
* Get the Questtext that was last entered by a Character.
*
* @param int $characterId ID of Character
* @param array $questtexts List of Questtexts to look into
* @return array Questtext data
*/
public function pickQuesttextLastEnteredByCharacter($characterId, $questtexts)
{
if(count($questtexts) == 0) {
return null;
}
$data = $this->db->query(
sprintf(
'SELECT quest_id '.
'FROM quests_characters '.
'WHERE character_id = ? AND quest_id IN (%s) AND status = ? '.
'ORDER BY created DESC '.
'LIMIT 1',
implode(',', array_map(function($q) { return intval($q['quest_id']); }, $questtexts))
),
'ii',
$characterId,
\hhu\z\models\QuestsModel::QUEST_STATUS_ENTERED
);
if(count($data) == 0) {
return $questtexts[0];
}
foreach($questtexts as &$questtext) {
if($questtext['quest_id'] == $data[0]['quest_id']) {
return $questtext;
}
}
return null;
}
/**
* Get all registered Questtexttypes.
*
* @return array Registered Questtexttypes
*/
public function getQuesttexttypes()
{
return $this->db->query(
'SELECT id, type, url '.
'FROM questtexttypes'
);
}
/**
* Get a Questtexttype by its URL.
*
* @param string $questtexttypeUrl URL-type of Questtexttype
* @return array Questtexttype data
*/
public function getQuesttexttypeByUrl($questtexttypeUrl)
{
$data = $this->db->query(
'SELECT id, type, url '.
'FROM questtexttypes '.
'WHERE url = ?',
's',
$questtexttypeUrl
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Add a Questtexts to a Quest.
*
* @param int $userId ID of user
* @param int $questId ID of Quest to add texts to
* @param string $questtexttypeUrl URL-type of Questtexttype of texts
* @param string $text Text to add.
*/
public function addQuesttextToQuest($userId, $questId, $questtexttypeUrl, $text)
{
$questtexttype = $this->getQuesttexttypeByUrl($questtexttypeUrl);
if(is_null($questtexttype)) {
return;
}
// Get position
$pos = $this->db->query(
'SELECT COALESCE(MAX(pos),0)+1 AS pos '.
'FROM questtexts '.
'WHERE quest_id = ?',
'i',
$questId
);
$pos = $pos[0]['pos'];
// Add Questtext
$this->db->query(
'INSERT INTO questtexts '.
'(created_user_id, quest_id, questtexttype_id, pos, text) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iiiis',
$userId, $questId, $questtexttype['id'], $pos,
$text
);
// Return ID
return $this->db->getInsertId();
}
/**
* Set the media for a Quest text.
*
* @param int $questtextId ID of Quest text to set media for
* @param int $questmediaId ID of Questsmedia to set
*/
public function setQuestmedia($questtextId, $questsmediaId)
{
$this->db->query(
'UPDATE questtexts '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$questsmediaId,
$questtextId
);
}
/**
* Edit a Quest text.
*
* @param int $questtextId ID of Quest text to edit
* @param string $text New text
*/
public function editQuesttext($questtextId, $text)
{
$this->db->query(
'UPDATE questtexts '.
'SET text = ? '.
'WHERE id = ?',
'si',
$text,
$questtextId
);
}
/**
* Copy Quest texts from one Quest to another.
*
* @param int $userId ID of copying user
* @param int $sourceQuestId ID of source Quest
* @param int $targetQuestId ID of target Quest
* @param array $seminaryMediaIds Mapping of Seminary-media-IDs from source Seminary to target Seminary (optional)
*/
public function copyQuesttexts($userId, $sourceQuestId, $targetQuestId, $seminaryMediaIds=null)
{
$questtextIds = array();
// Get Questtexts
$questtexts = $this->getQuesttextsOfQuest($sourceQuestId);
// Copy each text
foreach($questtexts as &$text)
{
// Copy text
$this->db->query(
'INSERT INTO questtexts '.
'(created_user_id, quest_id, questtexttype_id, pos, text, out_text, abort_text) '.
'SELECT ?, ?, questtexttype_id, pos, text, out_text, abort_text '.
'FROM questtexts '.
'WHERE id = ?',
'iii',
$userId, $targetQuestId,
$text['id']
);
$questtextIds[$text['id']] = $this->db->getInsertId();
// Copy media
if(!is_null($seminaryMediaIds) && !is_null($text['questsmedia_id']))
{
$this->Media->copyQuestsmedia($userId, $seminaryMediaIds[$text['questsmedia_id']]);
$this->db->query(
'UPDATE questtexts '.
'SET questsmedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaIds[$text['questsmedia_id']],
$questtextIds[$text['id']]
);
}
}
return $questtextIds;
}
/**
* Delete a Quest text.
*
* @param array $questtext Data of Quest text to delete
*/
public function deleteQuesttext($questtext)
{
// Delete Quest text
$this->db->query('DELETE FROM questtexts WHERE id = ?', 'i', $questtext['id']);
// Adjust positions
$this->db->query(
'UPDATE questtexts '.
'SET pos = pos - 1 '.
'WHERE quest_id = ? AND pos > ?',
'ii',
$questtext['quest_id'],
$questtext['pos']
);
}
}
?>

475
models/QuesttopicsModel.inc Normal file
View file

@ -0,0 +1,475 @@
<?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 Questtopics-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuesttopicsModel extends \hhu\z\Model
{
/**
* Construct a new QuesttopicsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get a Questtopic by its URL.
*
* @param int $seminaryId ID of Seminary
* @param string $questtopicUrl URL-Title of Questtopic
* @return array Questtopic data
*/
public function getQuesttopicByUrl($seminaryId, $questtopicUrl)
{
$data = $this->db->query(
'SELECT id, title, url '.
'FROM questtopics '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId, $questtopicUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questtopicUrl);
}
return $data[0];
}
/**
* Get a Questtopic by its ID.
*
* @param int $questtopicId ID of Questtopic
* @return array Questtopic data
*/
public function getQuesttopicById($questtopicId)
{
$data = $this->db->query(
'SELECT id, title, url '.
'FROM questtopics '.
'WHERE id = ?',
'i',
$questtopicId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questtopicId);
}
return $data[0];
}
/**
* Get all Questtopics for a Seminary.
*
* @param int $seminaryId ID of Seminary
* @return array List of Questtopics
*/
public function getQuesttopicsForSeminary($seminaryId)
{
return $this->db->query(
'SELECT id, title, url '.
'FROM questtopics '.
'WHERE seminary_id = ? '.
'ORDER BY title ASC',
'i',
$seminaryId
);
}
/**
* Copy all Questtopics and their subtopics of a Seminary.
*
* @param int $userId ID of creating user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
* @param array $questIds Mapping of Quest-IDs from source Seminary to target Seminary
* @return array Mapping of Questsubtopic-IDs from source Seminary to targetSeminary
*/
public function copyQuesttopicsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId, $questIds)
{
$questsubtopicIds = array();
// Get Questtopics
$questtopics = $this->getQuesttopicsForSeminary($sourceSeminaryId);
foreach($questtopics as &$questtopic)
{
// Copy Questtopic
$this->db->query(
'INSERT INTO questtopics '.
'(created_user_id, seminary_id, title, url) '.
'SELECT ?, ?, title, url '.
'FROM questtopics '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$questtopic['id']
);
$targetQuesttopicId = $this->db->getInsertId();
// Get Questsubtopics
$questsubtopics = $this->getSubtopicsForQuesttopic($questtopic['id']);
foreach($questsubtopics as &$questsubtopic)
{
// Copy Questsubtopic
$this->db->query(
'INSERT INTO questsubtopics '.
'(created_user_id, questtopic_id, title, url) '.
'SELECT ?, ?, title, url '.
'FROM questsubtopics '.
'WHERE id = ?',
'iii',
$userId, $targetQuesttopicId,
$questsubtopic['id']
);
$questsubtopicIds[$questsubtopic['id']] = $this->db->getInsertId();
// Get Quest links
$quests = $this->db->query(
'SELECT quest_id '.
'FROM quests_questsubtopics '.
'WHERE questsubtopic_id = ?',
'i',
$questsubtopic['id']
);
foreach($quests as &$quest)
{
$this->db->query(
'INSERT INTO quests_questsubtopics '.
'(quest_id, questsubtopic_id) '.
'VALUES '.
'(?, ?)',
'ii',
$questIds[$quest['quest_id']],
$questsubtopicIds[$questsubtopic['id']]
);
}
}
}
return $questsubtopicIds;
}
/**
* Get count of Quests that are linked to a Questtopic.
*
* @param int $questtopicId ID of Questtopic
* @return int Count of Quests
*/
public function getQuestCountForQuesttopic($questtopicId)
{
$data = $this->db->query(
'SELECT count(DISTINCT quests_questsubtopics.quest_id) AS c ' .
'FROM questsubtopics '.
'LEFT JOIN quests_questsubtopics ON quests_questsubtopics.questsubtopic_id = questsubtopics.id '.
'WHERE questsubtopics.questtopic_id = ?',
'i',
$questtopicId
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get count of Quests that are linked to a Questtopic and are
* unlocked by a Character.
*
* @param int $questtopicId ID of Questtopic
* @param int $characterId ID of Character
* @return int Count of Quests
*/
public function getCharacterQuestCountForQuesttopic($questtopicId, $characterId)
{
$data = $this->db->query(
'SELECT count(DISTINCT quests_characters.quest_id) AS c '.
'FROM questsubtopics '.
'LEFT JOIN quests_questsubtopics ON quests_questsubtopics.questsubtopic_id = questsubtopics.id '.
'INNER JOIN quests_characters ON quests_characters.quest_id = quests_questsubtopics.quest_id AND quests_characters.character_id = ? AND quests_characters.status = 3 '.
'WHERE questsubtopics.questtopic_id = ?',
'ii',
$characterId,
$questtopicId
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get alle Questsubtopics for a Questtopic.
*
* @param int $questtopicId ID of Questtopic
* @return array List of Questsubtopics for this Questtopic
*/
public function getSubtopicsForQuesttopic($questtopicId)
{
return $this->db->query(
'SELECT id, questtopic_id, title, url '.
'FROM questsubtopics '.
'WHERE questsubtopics.questtopic_id = ? '.
'ORDER BY title ASC',
'i',
$questtopicId
);
}
/**
* Get all Questsubtopics for a Quest.
*
* @param int $questId ID of Quest
* @return array List of Questsubtopics
*/
public function getQuestsubtopicsForQuest($questId)
{
return $this->db->query(
'SELECT DISTINCT id, questtopic_id, title, url '.
'FROM quests_questsubtopics '.
'INNER JOIN questsubtopics ON questsubtopics.id = quests_questsubtopics.questsubtopic_id '.
'WHERE quests_questsubtopics.quest_id = ? '.
'ORDER BY questsubtopics.title ASC',
'i',
$questId
);
}
/**
* Set Questsubtopics for a Quest.
*
* @param int $questId ID of Quest to set subtopics for
* @param array $questsubtopicIds List of IDs of subtopics to set
*/
public function setQuestsubtopicsForQuest($questId, $questsubtopicIds)
{
$this->db->setAutocommit(false);
try {
// Remove Questsubtopics
$this->db->query(
'DELETE FROM quests_questsubtopics '.
'WHERE quest_id = ?',
'i',
$questId
);
// Add Questsubtopics
foreach($questsubtopicIds as &$questsubtopicId)
{
$this->db->query(
'INSERT INTO quests_questsubtopics '.
'(quest_id, questsubtopic_id) '.
'VALUES '.
'(?, ?)',
'ii',
$questId, $questsubtopicId
);
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
/**
* Check if a Questtopic title already exists.
*
* @param string $title Questtopic title to check
* @param int $questtopicId Do not check this ID (for editing)
* @return boolean Whether Questtopic title exists or not
*/
public function questtopicTitleExists($title, $questtopicId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM questtopics '.
'WHERE title = ? OR url = ?',
'ss',
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($questtopicId) || $questtopicId != $data[0]['id']));
}
/**
* Create a new Questtopic for a Seminary.
*
* @param int $userId ID of creating user
* @param int $seminaryId ID of Seminary
* @param string $title Title for new Questtopic
* @return int ID of newly created Questtopic
*/
public function createQuesttopic($userId, $seminaryId, $title)
{
$this->db->query(
'INSERT INTO questtopics '.
'(created_user_id, seminary_id, title, url) '.
'VALUES '.
'(?, ?, ?, ?) ',
'iiss',
$userId,
$seminaryId,
$title,
\nre\core\Linker::createLinkParam($title)
);
return $this->db->getInsertId();
}
/**
* Edit a Questtopic.
*
* @param int $questtopicId ID of Questtopic to edit
* @param string $title New title of Questtopic
*/
public function editQuesttopic($questtopicId, $title)
{
$this->db->query(
'UPDATE questtopics '.
'SET title = ?, url = ? '.
'WHERE id = ?',
'ssi',
$title,
\nre\core\Linker::createLinkParam($title),
$questtopicId
);
}
/**
* Delete a Questtopic.
*
* @param int $questtopicId ID of Questtopic to delete
*/
public function deleteQuesttopic($questtopicId)
{
$this->db->query('DELETE FROM questtopics WHERE id = ?', 'i', $questtopicId);
}
/**
* Check if a Questsubtopic title already exists.
*
* @param int $questtopicId ID of Questtopic
* @param string $title Questsubtopic title to check
* @param int $questsubtopicId Do not check this ID (for editing)
* @return boolean Whether Questsubtopic title exists or not
*/
public function questsubtopicTitleExists($questtopicId, $title, $questsubtopicId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM questsubtopics '.
'WHERE questtopic_id = ? AND (title = ? OR url = ?)',
'iss',
$questtopicId,
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($questsubtopicId) || $questsubtopicId != $data[0]['id']));
}
/**
* Create a new Questsubtopic for a Questtopic.
*
* @param int $userId ID of creating user
* @param int $questtopicId ID of Qusttopic
* @param string $title Title for new Questtopic
* @return int ID of newly created Questsubtopic
*/
public function createQuestsubtopic($userId, $questtopicId, $title)
{
$this->db->query(
'INSERT INTO questsubtopics '.
'(created_user_id, questtopic_id, title, url) '.
'VALUES '.
'(?, ?, ?, ?) ',
'iiss',
$userId,
$questtopicId,
$title,
\nre\core\Linker::createLinkParam($title)
);
return $this->db->getInsertId();
}
/**
* Edit a Questsubtopic.
*
* @param int $questsubtopicId ID of Questsubtopic to edit
* @param string $title New title of Questsubtopic
*/
public function editQuestsubtopic($questsubtopicId, $title)
{
$this->db->query(
'UPDATE questsubtopics '.
'SET title = ?, url = ? '.
'WHERE id = ?',
'ssi',
$title,
\nre\core\Linker::createLinkParam($title),
$questsubtopicId
);
}
/**
* Delete a Questsubtopic.
*
* @param int $questsubtopicId ID of Questsubtopic to delete
*/
public function deleteQuestsubtopic($questtopicId)
{
$this->db->query('DELETE FROM questsubtopics WHERE id = ?', 'i', $questtopicId);
}
}
?>

View file

@ -0,0 +1,77 @@
<?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 Questtypes-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class QuesttypesModel extends \hhu\z\Model
{
/**
* Construct a new QuesttypesModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get all registered Questtypes.
*
* @return array List of registered Questtypes
*/
public function getQuesttypes()
{
return $this->db->query(
'SELECT id, title, url, classname '.
'FROM questtypes '.
'ORDER BY title ASC'
);
}
/**
* Get a Questtype by its ID
*
* @param int $questtypeId ID of Questtype
* @return array Questtype data
*/
public function getQuesttypeById($questtypeId)
{
$data = $this->db->query(
'SELECT title, classname '.
'FROM questtypes '.
'WHERE id = ?',
'i',
$questtypeId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($questtypeId);
}
return $data = $data[0];
}
}
?>

456
models/SeminariesModel.inc Normal file
View file

@ -0,0 +1,456 @@
<?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 of the SeminariesAgent to list registered seminaries.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class SeminariesModel extends \hhu\z\Model
{
/**
* Required models
*
* @var array
*/
public $models = array('questgroupshierarchy', 'questgroups', 'quests', 'questtopics', 'media', 'charactertypes', 'xplevels', 'avatars', 'achievements', 'charactergroups', 'charactergroupsquests', 'seminarycharacterfields');
/**
* Construct a new SeminariesModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get registered seminaries.
*
* @return array Seminaries
*/
public function getSeminaries()
{
// Get seminaries
return $this->db->query(
'SELECT id, created, created_user_id, title, url, course, description, seminarymedia_id, charactergroups_seminarymedia_id, achievements_seminarymedia_id, library_seminarymedia_id, map_seminarymedia_id '.
'FROM seminaries '.
'ORDER BY created DESC'
);
}
/**
* Get a seminary and its data by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $seminaryId ID of a seminary
* @return array Seminary
*/
public function getSeminaryById($seminaryId)
{
$seminary = $this->db->query(
'SELECT id, created, created_user_id, title, url, course, description, seminarymedia_id, charactergroups_seminarymedia_id, achievements_seminarymedia_id, library_seminarymedia_id, map_seminarymedia_id '.
'FROM seminaries '.
'WHERE id = ?',
'i',
$seminaryId
);
if(empty($seminary)) {
throw new \nre\exceptions\IdNotFoundException($seminaryId);
}
return $seminary[0];
}
/**
* Get a seminary and its data by its URL-title.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $seminaryUrl URL-Title of a seminary
* @return array Seminary
*/
public function getSeminaryByUrl($seminaryUrl)
{
$seminary = $this->db->query(
'SELECT id, created, created_user_id, title, url, course, description, seminarymedia_id, charactergroups_seminarymedia_id, achievements_seminarymedia_id, library_seminarymedia_id, map_seminarymedia_id '.
'FROM seminaries '.
'WHERE url = ?',
's',
$seminaryUrl
);
if(empty($seminary)) {
throw new \nre\exceptions\IdNotFoundException($seminaryUrl);
}
return $seminary[0];
}
/**
* Calculate sum of XPs for a Seminary.
*
* @param int $seminaryId ID of Seminary
* @return int Total sum of XPs
*/
public function getTotalXPs($seminaryId)
{
$xps = 0;
// Questgroups
$questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyOfSeminary($seminaryId);
foreach($questgroupshierarchy as &$hierarchy)
{
// Get Questgroups
$questgroups = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']);
foreach($questgroups as &$questgroup) {
$xps += $questgroup['achievable_xps'];
}
}
return $xps;
}
/**
* Check if a Seminary title already exists.
*
* @param string $title Seminary title to check
* @param int $seminaryId Do not check this ID (for editing)
* @return boolean Whether Seminary title exists or not
*/
public function seminaryTitleExists($title, $seminaryId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM seminaries '.
'WHERE title = ? OR url = ?',
'ss',
$title,
\nre\core\Linker::createLinkParam($title)
);
return (!empty($data) && (is_null($seminaryId) || $seminaryId != $data[0]['id']));
}
/**
* Create a new Seminary.
*
* @param int $userId ID of creating user
* @param string $title Title of Seminary to create
* @param string $course Course of Seminary
* @param string $description Description of new Seminary
* @return int ID of the newly created Seminary
*/
public function createSeminary($userId, $title, $course, $description)
{
$this->db->query(
'INSERT INTO seminaries '.
'(created_user_id, title, url, course, description) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'issss',
$userId,
$title,
\nre\core\Linker::createLinkParam($title),
$course,
$description
);
return $this->db->getInsertId();
}
/**
* Set the moodpic for a Seminary.
*
* @param int $seminaryId ID of Seminary to set moodpic for
* @param int $mediaId ID of moodpic media
*/
public function setMoodpicForSeminary($seminaryId, $mediaId)
{
$this->db->query(
'UPDATE seminaries '.
'SET seminarymedia_id = ? '.
'WHERE id = ?',
'ii',
$mediaId,
$seminaryId
);
}
/**
* Set the moodpic for the Character groups of a Seminary.
*
* @param int $seminaryId ID of Seminary to set moodpic for Character groups for
* @param int $seminaryMediaId ID of Seminarymedia to set as moodpic
*/
public function setMoodpicForCharactergroups($seminaryId, $seminaryMediaId)
{
$this->db->query(
'UPDATE seminaries '.
'SET charactergroups_seminarymedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaId,
$seminaryId
);
}
/**
* Set the moodpic for the Achievements of a Seminary.
*
* @param int $seminaryId ID of Seminary to set moodpic for Achievements for
* @param int $seminaryMediaId ID of Seminarymedia to set as moodpic
*/
public function setMoodpicForAchievements($seminaryId, $seminaryMediaId)
{
$this->db->query(
'UPDATE seminaries '.
'SET achievements_seminarymedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaId,
$seminaryId
);
}
/**
* Set the moodpic for the library of a Seminary.
*
* @param int $seminaryId ID of Seminary to set moodpic for Library for
* @param int $seminaryMediaId ID of Seminarymedia to set as moodpic
*/
public function setMoodpicForLibrary($seminaryId, $seminaryMediaId)
{
$this->db->query(
'UPDATE seminaries '.
'SET library_seminarymedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaId,
$seminaryId
);
}
/**
* (Re-) Calculate the amount of achievable XPs for a Seminary.
*
* @param int $seminaryId ID of Seminary to calculate XPs for
*/
public function calculateXPsForSeminary($seminaryId)
{
// Questgrouphierarchy and Questgroups
$questgroupshierarchy = $this->Questgroupshierarchy->getHierarchyOfSeminary($seminaryId);
foreach($questgroupshierarchy as &$hierarchy)
{
// Get Questgroups
$hierarchy['questgroups'] = $this->Questgroups->getQuestgroupsForHierarchy($hierarchy['id']);
foreach($hierarchy['questgroups'] as &$questgroup)
{
// Calculate achievable XPs
$this->Questgroups->calculateXPsForQuestgroup($questgroup['id']);
}
}
}
/**
* Edit a seminary.
*
* @throws \nre\exceptions\DatamodelException
* @param int $seminaryId ID of Seminary to edit
* @param string $title New title of Seminary
* @param string $course New course of Seminary
* @param string $description New description of Seminary
*/
public function editSeminary($seminaryId, $title, $course, $description)
{
$this->db->query(
'UPDATE seminaries '.
'SET title = ?, url = ?, course = ?, description = ? '.
'WHERE id = ?',
'ssssi',
$title,
\nre\core\Linker::createLinkParam($title),
$course,
$description,
$seminaryId
);
}
/**
* Copy a Seminary and its content.
*
* @param int $userId ID of copying user
* @param int $sourceSeminaryId ID of Seminary to copy
* @param string $title Title of new Seminary
* @param string $course Course of now Seminary
* @param string $description Description of new Seminary
* @param boolean $copySeminaryfields Whether to copy Seminary Character fields of not
* @param boolean $copyMedia Whether to copy media or not
* @param boolean $copyQuestgroupshierarchy Whether to copy Questgroupshierarchy or not
* @param boolean $copyQuestgroups Whether to copy Questgroups or not
* @param boolean $copyQuests Whether to copy Quests or not
* @param boolean $copyQuesttopics Whether to copy Quest topics or not
* @param boolean $copyCharactertypes Whether to copy Charactertypes or not
* @param boolean $copyXPlevels Whether to copy XP-levels or not
* @param boolean $copyAvatars Whether to copy Avatars or not
* @param boolean $copyAchievements Whether to copy Achievements or not
* @param boolean $copyCharactergroupsgroups Whether to copy Character groups-groups or not
* @param boolean $copyCharactergroupsquests Whether to copy Character groups Quests or not
* @return ID of newly created Seminary
*/
public function copySeminary($userId, $sourceSeminaryId, $title, $course, $description, $copySeminaryfields, $copyMedia, $copyQuestgroupshierarchy, $copyQuestgroups, $copyQuests, $copyQuesttopics, $copyCharactertypes, $copyXPlevels, $copyAvatars, $copyAchievements, $copyCharactergroupsgroups, $copyCharactergroupsquests)
{
// Get Seminary
$seminary = $this->getSeminaryById($sourceSeminaryId);
// Copy Seminary
$this->db->setAutocommit(false);
try {
// Create new Seminary
$targetSeminaryId = $this->createSeminary($userId, $title, $course, $description);
// Copy Seminary fields
if($copySeminaryfields) {
$this->Seminarycharacterfields->copyFieldsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId);
}
// Copy media
$seminaryMediaIds = null;
if($copyMedia)
{
$seminaryMediaIds = $this->Media->copySeminaryMedia($userId, $sourceSeminaryId, $targetSeminaryId);
// Set Seminary media
if(!is_null($seminary['seminarymedia_id'])) {
$this->setMoodpicForSeminary($targetSeminaryId, $seminaryMediaIds[$seminary['seminarymedia_id']]);
}
if(!is_null($seminary['charactergroups_seminarymedia_id'])) {
$this->setMoodpicForCharactergroups($targetSeminaryId, $seminaryMediaIds[$seminary['charactergroups_seminarymedia_id']]);
}
if(!is_null($seminary['achievements_seminarymedia_id'])) {
$this->setMoodpicForAchievements($targetSeminaryId, $seminaryMediaIds[$seminary['achievements_seminarymedia_id']]);
}
if(!is_null($seminary['library_seminarymedia_id'])) {
$this->setMoodpicForLibrary($targetSeminaryId, $seminaryMediaIds[$seminary['library_seminarymedia_id']]);
}
}
// Copy Quest content
$questIds = null;
$questgroupIds = null;
// Questgroupshierarchy
if($copyQuestgroupshierarchy)
{
$questgroupshierarchyIds = $this->Questgroupshierarchy->copyQuestgroupshierarchy($userId, $sourceSeminaryId, $targetSeminaryId);
// Questgroups
if($copyQuestgroups)
{
$questgroupIds = $this->Questgroups->copyQuestgroupsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId, $questgroupshierarchyIds, $seminaryMediaIds);
$this->Questgroups->copyQuestgroupsHierarchy($questgroupshierarchyIds, $questgroupIds);
// Quests
if($copyQuests)
{
$questAndTextIds = $this->Quests->copyQuests($userId, $sourceSeminaryId, $questgroupIds, $seminaryMediaIds);
$questIds = $questAndTextIds['quests'];
$questtextIds = $questAndTextIds['questtexts'];
$this->Questgroups->copyRelatedQuestgroups($questgroupIds, $questtextIds);
// Questtopics
if($copyQuesttopics) {
$questsubtopicIds = $this->Questtopics->copyQuesttopicsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId, $questIds);
}
}
}
}
// Copy Character content
// Charactertypes
if($copyCharactertypes)
{
$charactertypeIds = $this->Charactertypes->copyCharactertypesOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId);
// XP-levels
if($copyXPlevels)
{
$xplevelIds = $this->Xplevels->copyXPLevelsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId);
// Avatars
if($copyAvatars && !is_null($seminaryMediaIds)) {
$this->Avatars->copyAvatars($userId, $charactertypeIds, $xplevelIds, $seminaryMediaIds);
}
}
}
// Copy Achievements
if($copyAchievements && !is_null($seminaryMediaIds)) {
$this->Achievements->copyAchievementsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId, $seminaryMediaIds, $questIds);
}
// Copy Charactergroups content
// Charactergroupsgroups
if($copyCharactergroupsgroups)
{
$characterGroupsgroupIds = $this->Charactergroups->copyGroupsgroupsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId);
// Copy Charactergroupsquests
if($copyCharactergroupsquests &!is_null($questgroupIds)) {
$this->Charactergroupsquests->copyQuestsOfSeminary($userId, $characterGroupsgroupIds, $questgroupIds, $seminaryMediaIds);
}
}
// Recalculate XPs
$this->calculateXPsForSeminary($targetSeminaryId);
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
return $targetSeminaryId;
}
/**
* Delete a seminary.
* TODO Delete media
*
* @param int $seminaryId ID of the seminary to delete
*/
public function deleteSeminary($seminaryId)
{
$this->db->query('DELETE FROM seminaries WHERE id = ?', 'i', $seminaryId);
}
}
?>

View file

@ -0,0 +1,151 @@
<?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 the Seminarycharacterfields-tables.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class SeminarycharacterfieldsModel extends \hhu\z\Model
{
/**
* Construct a new SeminarycharacterfieldsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* 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
);
}
/**
* 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($seminarycharacterfieldId, $characterId, $value)
{
$this->db->query(
'INSERT INTO characters_seminarycharacterfields '.
'(character_id, seminarycharacterfield_id, value) '.
'VALUES '.
'(?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'value = ?',
'iiss',
$characterId,
$seminarycharacterfieldId,
$value,
$value
);
}
/**
* Get Seminary Character fields of a Character.
*
* @param int $fieldId ID of Seminary Character field
* @param int $characterId ID of the Character
* @return array Seminary Character fields
*/
public function getSeminaryFieldOfCharacter($fieldId, $characterId)
{
$data = $this->db->query(
'SELECT created, value '.
'FROM characters_seminarycharacterfields '.
'WHERE seminarycharacterfield_id = ? AND character_id = ?',
'ii',
$fieldId,
$characterId
);
if(!empty($data)) {
return $data[0];
}
return null;
}
/**
* Get Seminary Character fields of a Character.
*
* @param int $characterId ID of the Character
* @return array Seminary Character fields
*/
public function getFieldsForCharacter($characterId)
{
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, characters_seminarycharacterfields.value '.
'FROM characters_seminarycharacterfields '.
'LEFT JOIN seminarycharacterfields ON seminarycharacterfields.id = characters_seminarycharacterfields.seminarycharacterfield_id '.
'LEFT JOIN seminarycharacterfieldtypes ON seminarycharacterfieldtypes.id = seminarycharacterfields.seminarycharacterfieldtype_id '.
'WHERE characters_seminarycharacterfields.character_id = ?',
'i',
$characterId
);
}
/**
* Copy all Character fields of a Seminary.
*
* @param int $userId ID of copying user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
*/
public function copyFieldsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId)
{
$this->db->query(
'INSERT INTO seminarycharacterfields '.
'(created_user_id, seminary_id, pos, title, url, seminarycharacterfieldtype_id, regex, required) '.
'SELECT ?, ?, pos, title, url, seminarycharacterfieldtype_id, regex, required '.
'FROM seminarycharacterfields '.
'WHERE seminary_id = ?',
'iii',
$userId, $targetSeminaryId,
$sourceSeminaryId
);
}
}
?>

175
models/UploadsModel.inc Normal file
View file

@ -0,0 +1,175 @@
<?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 handle files to upload.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class UploadsModel extends \hhu\z\Model
{
/**
* Construct a new UploadsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Upload a file and create a database record.
*
* @param int $userId ID of user that uploads the file
* @param int $seminaryId ID of Seminary
* @param string $name Name of file to upload
* @param string $filename Filename of file to upload
* @param string $tmpFilename Name of temporary uploaded file
* @param string $mimetype Mimetype of file to upload
* @return mixed ID of database record or false
*/
public function uploadSeminaryFile($userId, $seminaryId, $name, $filename, $tmpFilename, $mimetype)
{
$uploadId = false;
$this->db->setAutocommit(false);
try {
// Create database record
$this->db->query(
'INSERT INTO seminaryuploads '.
'(created_user_id, seminary_id, name, url, mimetype) '.
'VALUES '.
'(?, ? ,? ,?, ?)',
'iisss',
$userId,
$seminaryId,
$name,
\nre\core\Linker::createLinkParam($filename),
$mimetype
);
$uploadId = $this->db->getInsertId();
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminaryuploads'].DS.$filename;
if(!move_uploaded_file($tmpFilename, $filename))
{
$this->db->rollback();
$uploadId = false;
}
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
return $uploadId;
}
/**
* Get an upload by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $uploadId ID of the uploaded file
* @return array Upload data
*/
public function getSeminaryuploadById($seminaryuploadId)
{
$data = $this->db->query(
'SELECT id, created, created_user_id, seminary_id, name, url, mimetype, public '.
'FROM seminaryuploads '.
'WHERE id = ?',
'i',
$seminaryuploadId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($seminaryuploadId);
}
return $data[0];
}
/**
* Get an upload by its URL.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of Seminary
* @param int $uploadId ID of the uploaded file
* @return array Upload data
*/
public function getSeminaryuploadByUrl($seminaryId, $seminaryuploadUrl)
{
$data = $this->db->query(
'SELECT id, created, created_user_id, seminary_id, name, url, mimetype, public '.
'FROM seminaryuploads '.
'WHERE seminary_id = ? AND url = ?',
'is',
$seminaryId,
$seminaryuploadUrl
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($seminaryuploadUrl);
}
return $data[0];
}
/**
* Delete a Seminary upload.
*
* @param int $uploadId ID of Seminary upload to delete
*/
public function deleteSeminaryupload($uploadId)
{
$this->db->setAutocommit(false);
try {
// Get Upload
$upload = $this->getSeminaryuploadById($uploadId);
// Delete database record
$this->db->query(
'DELETE FROM seminaryuploads '.
'WHERE id = ?',
'i',
$uploadId
);
// Delete file
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminaryuploads'].DS.$upload['url'];
unlink($filename);
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
}
$this->db->setAutocommit(true);
}
}
?>

120
models/UserrolesModel.inc Normal file
View file

@ -0,0 +1,120 @@
<?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 userroles-table.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class UserrolesModel extends \hhu\z\Model
{
/**
* Construct a new UserrolesModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get all userroles for an user referenced by its ID.
*
* @param int $userId ID of an user
* @return array Userroles for an user
*/
public function getUserrolesForUserById($userId)
{
return $this->db->query(
'SELECT userroles.id, userroles.created, userroles.name '.
'FROM users_userroles '.
'LEFT JOIN userroles ON userroles.id = users_userroles.userrole_id '.
'WHERE users_userroles.user_id = ?',
'i',
$userId
);
}
/**
* Get all userroles for an user referenced by its URL-username.
*
* @param string $userUrl URL-Username of an user
* @return array Userroles for an user
*/
public function getUserrolesForUserByUrl($userUrl)
{
return $this->db->query(
'SELECT userroles.id, userroles.created, userroles.name '.
'FROM users '.
'LEFT JOIN users_userroles ON users_userroles.user_id = users.id '.
'LEFT JOIN userroles ON userroles.id = users_userroles.userrole_id '.
'WHERE users.url = ?',
's',
$userUrl
);
}
/**
* Add a role to a user.
*
* @param int $userId ID of user to add role to
* @param string $userrole Role to add
*/
public function addUserroleToUser($userId, $userrole)
{
$this->db->query(
'INSERT IGNORE INTO users_userroles '.
'(user_id, userrole_id) '.
'SELECT ?, id '.
'FROM userroles '.
'WHERE name = ?',
'is',
$userId,
$userrole
);
}
/**
* Remove a role from a user.
*
* @param int $userId ID of user to remove role from
* @param string $userrole Role to remove
*/
public function removeUserroleFromUser($userId, $userrole)
{
$this->db->query(
'DELETE FROM users_userroles '.
'WHERE user_id = ? AND userrole_id = ('.
'SELECT id '.
'FROM userroles '.
'WHERE name = ?'.
')',
'is',
$userId,
$userrole
);
}
}
?>

430
models/UsersModel.inc Normal file
View file

@ -0,0 +1,430 @@
<?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 of the UsersAgent to list users and get their data.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class UsersModel extends \hhu\z\Model
{
/**
* Construct a new UsersModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get count of registered users.
*
* @param string $username Only get users with the given username (optional)
* @return int Count of users
*/
public function getUsersCount($username=null, $name=null, $email=null)
{
// Create array of values
$values = array();
if(!is_null($username)) {
$values[] = sprintf('username LIKE \'%%%s%%\'', $username);
}
if(!is_null($name)) {
$values[] = sprintf('(surname LIKE \'%%%s%%\' OR prename LIKE \'%%%s%%\')', $name, $name);
}
if(!is_null($email)) {
$values[] = sprintf('email LIKE \'%%%s%%\'', $email);
}
// Execute query
$data = $this->db->query(
'SELECT count(DISTINCT id) AS c '.
'FROM users '.
(!empty($values) ? sprintf('WHERE %s', implode(' AND ', $values)) : null)
);
if(!empty($data)) {
return $data[0]['c'];
}
return 0;
}
/**
* Get registered users.
*
* @throws \nre\exceptions\ParamsNotValidException
* @param string $sort Field to sort by
* @param string $username Only get users with the given username (optional)
* @param int $limit Limit amount of Characters (optional)
* @param int $offset Offset (optional)
* @return array Users
*/
public function getUsers($sort, $username=null, $name=null, $email=null, $limit=null, $offset=0)
{
// Create array of values
$values = array();
if(!is_null($username)) {
$values[] = sprintf('username LIKE \'%%%s%%\'', $username);
}
if(!is_null($name)) {
$values[] = sprintf('(surname LIKE \'%%%s%%\' OR prename LIKE \'%%%s%%\')', $name, $name);
}
if(!is_null($email)) {
$values[] = sprintf('email LIKE \'%%%s%%\'', $email);
}
// Execute query
switch($sort)
{
case 'username':
case 'created':
$orders = array(
'username' => 'ASC',
'created' => 'DESC'
);
return $this->db->query(
'SELECT id, created, username, url, surname, prename, email, mailing '.
'FROM users '.
(!empty($values) ? sprintf('WHERE %s ', implode(' AND ', $values)) : null).
sprintf('ORDER BY %s %s ', $sort, $orders[$sort]).
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null)
);
break;
case 'role':
return $this->db->query(
'SELECT DISTINCT users.id, users.created, users.username, users.url, users.surname, users.prename, users.email, users.mailing '.
'FROM users '.
'LEFT JOIN users_userroles ON users_userroles.user_id = users.id '.
'LEFT JOIN userroles ON userroles.id = users_userroles.user_id '.
(!empty($values) ? sprintf('WHERE %s ', implode(' AND ', $values)) : null).
'ORDER BY userroles.id IS NULL, userroles.id ASC '.
(!empty($limit) ? sprintf('LIMIT %d, %d', $offset, $limit) : null)
);
break;
default:
throw new \nre\exceptions\ParamsNotValidException($sort);
break;
}
}
/**
* Get users with the given user role.
*
* @param string $userrole User role
* @return array List of users
*/
public function getUsersWithRole($userrole)
{
return $this->db->query(
'SELECT users.id, users.created, users.username, users.url, users.surname, users.prename, users.email, users.mailing '.
'FROM users '.
'LEFT JOIN users_userroles ON users_userroles.user_id = users.id '.
'LEFT JOIN userroles ON userroles.id = users_userroles.userrole_id '.
'WHERE userroles.name = ? '.
'ORDER BY username ASC',
's',
$userrole
);
}
/**
* Get a user and its data by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $userId ID of an user
* @return array Userdata
*/
public function getUserById($userId)
{
// Get user
$user = $this->db->query(
'SELECT id, created, username, url, surname, prename, email, mailing '.
'FROM users '.
'WHERE id = ?',
'i',
$userId
);
if(empty($user)) {
throw new \nre\exceptions\IdNotFoundException($userId);
}
return $user[0];
}
/**
* Get a user and its data by its URL-username.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $userUrl URL-Username of an user
* @return array Userdata
*/
public function getUserByUrl($userUrl)
{
// Get user
$user = $this->db->query(
'SELECT id, created, username, url, surname, prename, email, mailing '.
'FROM users '.
'WHERE url = ?',
's',
$userUrl
);
if(empty($user)) {
throw new \nre\exceptions\IdNotFoundException($userUrl);
}
return $user[0];
}
/**
* Log a user in if its credentials are valid.
*
* @throws \nre\exceptions\DatamodelException
* @param string $username The name of the user to log in
* @param string $password Plaintext password of the user to log in
*/
public function login($username, $password)
{
$data = $this->db->query('SELECT id, password FROM users WHERE username = ?', 's', $username);
if(!empty($data))
{
$data = $data[0];
if($this->verify($password, $data['password'])) {
return $data['id'];
}
}
return null;
}
/**
* Check if an username already exists.
*
* @param string $username Username to check
* @param int $userId Do not check this ID (for editing)
* @return boolean Whether username exists or not
*/
public function usernameExists($username, $userId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM users '.
'WHERE username = ? OR url = ?',
'ss',
$username,
\nre\core\Linker::createLinkParam($username)
);
return (!empty($data) && (is_null($userId) || $userId != $data[0]['id']));
}
/**
* Check if an email address already exists.
*
* @param string $email Email address to check
* @param int $userId Do not check this ID (for editing)
* @return boolean Whether email address exists or not
*/
public function emailExists($email, $userId=null)
{
$data = $this->db->query(
'SELECT id '.
'FROM users '.
'WHERE email = ?',
's',
$email
);
return (!empty($data) && (is_null($userId) || $userId != $data[0]['id']));
}
/**
* Create a new user.
*
* @param string $username Username of the user to create
* @param string $prename Prename of the user to create
* @param string $surname Surname of the user to create
* @param string $email EMail-Address of the user to create
* @param string $password Password of the user to create
* @return int ID of the newly created user
*/
public function createUser($username, $prename, $surname, $email, $password)
{
$userId = null;
$this->db->setAutocommit(false);
try {
// Create user
$this->db->query(
'INSERT INTO users '.
'(username, url, surname, prename, email, password) '.
'VALUES '.
'(?, ?, ?, ?, ?, ?)',
'ssssss',
$username,
\nre\core\Linker::createLinkParam($username),
$surname,
$prename,
$email,
$this->hash($password)
);
$userId = $this->db->getInsertId();
// Add role “user”
$this->db->query(
'INSERT INTO users_userroles '.
'(user_id, userrole_id) '.
'SELECT ?, userroles.id '.
'FROM userroles '.
'WHERE userroles.name = ?',
'is',
$userId,
'user'
);
}
catch(Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
return $userId;
}
/**
* Edit a user.
*
* @throws \nre\exceptions\DatamodelException
* @param int $userId ID of the user to delete
* @param string $username New name of user
* @param string $prename Prename of the user to create
* @param string $surname Surname of the user to create
* @param string $email Changed email-address of user
* @param string $password Changed plaintext password of user
* @param bool $mailing Whether to activate mailing or not
*/
public function editUser($userId, $username, $prename, $surname, $email, $password, $mailing)
{
$this->db->setAutocommit(false);
try {
// Update user data
$this->db->query(
'UPDATE users '.
'SET username = ?, url = ?, prename = ?, surname = ?, email = ?, mailing = ? '.
'WHERE id = ?',
'sssssii',
$username,
\nre\core\Linker::createLinkParam($username),
$prename,
$surname,
$email,
$mailing,
$userId
);
// Set new password
if(!empty($password))
{
$this->db->query(
'UPDATE users '.
'SET password = ? '.
'WHERE id = ?',
'si',
$this->hash($password),
$userId
);
}
}
catch(Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
/**
* Delete a user.
*
* @param int $userId ID of the user to delete
*/
public function deleteUser($userId)
{
$this->db->query('DELETE FROM users WHERE id = ?', 'i', $userId);
}
/**
* Hash a password.
*
* @param string $password Plaintext password
* @return string Hashed password
*/
public function hash($password)
{
if(!function_exists('password_hash')) {
\hhu\z\lib\Password::load();
}
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* Verify a password.
*
* @param string $password Plaintext password to verify
* @param string $hash Hashed password to match with
* @return boolean Verified
*/
private function verify($password, $hash)
{
if(!function_exists('password_verify')) {
\hhu\z\lib\Password::load();
}
return password_verify($password, $hash);
}
}
?>

236
models/XplevelsModel.inc Normal file
View file

@ -0,0 +1,236 @@
<?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 for XP-levels.
*
* @author Oliver Hanraths <oliver.hanraths@uni-duesseldorf.de>
*/
class XplevelsModel extends \hhu\z\Model
{
/**
* Construct a new XplevelsModel.
*/
public function __construct()
{
parent::__construct();
}
/**
* Get XP-level by its ID.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $xplevelId ID of XP-level
* @return array XP-level data
*/
public function getXPLevelById($xplevelId)
{
$data = $this->db->query(
'SELECT id, seminary_id, xps, level, name '.
'FROM xplevels '.
'WHERE id = ?',
'i',
$xplevelId
);
if(empty($data)) {
throw new \nre\exceptions\IdNotFoundException($xplevelId);
}
return $data[0];
}
/**
* Get all XP-levels for a Seminary.
*
* @throws \nre\exceptions\IdNotFoundException
* @param int $seminaryId ID of Seminary
* @return array List of XP-level
*/
public function getXPLevelsForSeminary($seminaryId)
{
return $this->db->query(
'SELECT id, seminary_id, xps, level, name '.
'FROM xplevels '.
'WHERE seminary_id = ? '.
'ORDER BY level ASC',
'i',
$seminaryId
);
}
/**
* Create a new XP-level for a Seminary.
*
* @param int $userId ID of creating user
* @param int $seminaryId ID of Seminary
* @param int $xps XPs of new XP-level
* @param string $name Name of new XP-level (optional)
*/
public function createXPLevel($userId, $seminaryId, $xps, $name=null)
{
// Get level
$level = $this->db->query(
'SELECT COALESCE(MAX(level),0)+1 AS level '.
'FROM xplevels '.
'WHERE seminary_id = ?',
'i',
$seminaryId
);
$level = $level[0]['level'];
$this->db->setAutocommit(false);
try {
// Create XP-level
$this->db->query(
'INSERT INTO xplevels '.
'(created_user_id, seminary_id, xps, level, name) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iiiis',
$userId,
$seminaryId,
$xps,
$level,
$name
);
$xplevelId = $this->db->getInsertId();
// Create avatars
$this->db->query(
'INSERT INTO avatars '.
'(created_user_id, charactertype_id, xplevel_id) '.
'SELECT ?, charactertypes.id, ? '.
'FROM charactertypes '.
'WHERE seminary_id = ?',
'iii',
$userId,
$xplevelId,
$seminaryId
);
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
/**
* Edit a XP-level.
*
* @param int $xplevelId ID of XP-level to edit
* @param int $xps New XPs of XP-level
* @param string $name New name of XP-level (optional)
*/
public function editXPLevel($xplevelId, $xps, $name=null)
{
$this->db->query(
'UPDATE xplevels '.
'SET xps = ?, name = ? '.
'WHERE id = ?',
'isi',
$xps,
$name,
$xplevelId
);
}
/**
* Copy all XP-levels of a Seminary.
*
* @param int $userId ID of copying user
* @param int $sourceSeminaryId ID of Seminary to copy from
* @param int $targetSeminaryId ID of Seminary to copy to
* @param array Mapping of XP-level-IDs from source Seminary to targetSeminary
*/
public function copyXPLevelsOfSeminary($userId, $sourceSeminaryId, $targetSeminaryId)
{
$xplevelIds = array();
// Get XP-levels
$xplevels = $this->getXPLevelsForSeminary($sourceSeminaryId);
// Copy each XP-level
foreach($xplevels as &$level)
{
$this->db->query(
'INSERT INTO xplevels '.
'(created_user_id, seminary_id, xps, level, name) '.
'SELECT ?, ?, xps, level, name '.
'FROM xplevels '.
'WHERE id = ?',
'iii',
$userId, $targetSeminaryId,
$level['id']
);
$xplevelIds[$level['id']] = $this->db->getInsertId();
}
return $xplevelIds;
}
/**
* Delete a XP-level.
*
* @param int $xplevel XP-level to delete
*/
public function deleteXPLevel($xplevel)
{
$this->db->setAutocommit(false);
try {
// Delete XP-level
$this->db->query('DELETE FROM xplevels WHERE id = ?', 'i', $xplevel['id']);
// Adjust levels
$this->db->query(
'UPDATE xplevels '.
'SET level = level - 1 '.
'WHERE seminary_id = ? AND level > ?',
'ii',
$xplevel['seminary_id'],
$xplevel['level']
);
$this->db->commit();
}
catch(\Exception $e) {
$this->db->rollback();
$this->db->setAutocommit(true);
throw $e;
}
$this->db->setAutocommit(true);
}
}
?>