improve map implementation including edit functionality

This commit is contained in:
oliver 2015-05-17 20:53:00 +02:00
parent d561cc78ed
commit 1f1d91850e
10 changed files with 341 additions and 10 deletions

View file

@ -145,6 +145,16 @@
'mimetype' => 'image/png',
'size' => 1048576
)
),
'map' => array(
array(
'mimetype' => 'image/jpeg',
'size' => 5242880
),
array(
'mimetype' => 'image/png',
'size' => 10485760
)
)
);
@ -296,6 +306,8 @@
array('^library/([^/]+)/create/?$', 'library/create/$1', true),
array('^library/([^/]+)/([^/]+)/?$', 'library/topic/$1/$2', true),
array('^library/([^/]+)/([^/]+)/(edit|delete|manage)/?$', 'library/$3/$1/$2', true),
array('^map/([^/]+)/?$', 'map/index/$1', true),
array('^map/([^/]+)/(edit)/?$', 'map/$2/$1', true),
array('^media/(.*)$', 'media/$1?layout=binary', false),
array('^uploads/(.*)$', 'uploads/$1?layout=binary', false)
);
@ -345,7 +357,9 @@
array('^library/index/([^/]+)/?$', 'library/$1', true),
array('^library/create/([^/]+)/?$', 'library/$1/create', true),
array('^library/topic/([^/]+)/([^/]+)/?$', 'library/$1/$2', true),
array('^library/(edit|delete|manage)/([^/]+)/([^/]+)/?$', 'library/$2/$3/$1', true)
array('^library/(edit|delete|manage)/([^/]+)/([^/]+)/?$', 'library/$2/$3/$1', true),
array('^map/index/(.*)$', 'map/$1', true),
array('^map/(edit)/(.*)$', 'map/$2/$1', true)
);

View file

@ -24,14 +24,21 @@
*
* @var array
*/
public $models = array('seminaries', 'map');
public $models = array('seminaries', 'map', 'media');
/**
* Required components
*
* @var array
*/
public $components = array('validation');
/**
* User permissions
*
* @var array
*/
public $permissions = array(
'index' => array('admin', 'moderator', 'user')
'index' => array('admin', 'moderator', 'user'),
'edit' => array('admin', 'moderator', 'user')
);
/**
* User seminary permissions
@ -39,7 +46,8 @@
* @var array
*/
public $seminaryPermissions = array(
'index' => array('admin', 'moderator', 'user')
'index' => array('admin', 'moderator', 'user'),
'edit' => array('admin', 'moderator')
);
@ -51,7 +59,7 @@
* Draw the map.
*
* @throws \nre\exceptions\IdNotFoundException
* @param string $seminaryUrl URL-Title of Seminary
* @param string $seminaryUrl URL-Title of Seminary
*/
public function index($seminaryUrl)
{
@ -61,12 +69,106 @@
// Get map
$map = $this->Map->getMapOfSeminary($seminary['id']);
// Check permissions
if(is_null($map) && count(array_intersect(array('admin','moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0) {
throw new \nre\exceptions\IdNotFoundException($seminaryUrl);
}
// Pass data to view
$this->set('seminary', $seminary);
$this->set('map', $map);
}
/**
* Action: edit.
*
* Edit the map of a Seminary.
*
* @param string $seminaryUrl URL-Title of Seminary
*/
public function edit($seminaryUrl)
{
// Get Seminary
$seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl);
// Get map
$map = $this->Map->getMapOfSeminary($seminary['id']);
// Get allowed mimetypes
$mimetypes = \nre\configs\AppConfig::$mimetypes['map'];
// Values
$validation = true;
// Check request method
if($this->request->getRequestMethod() == 'POST')
{
// Validate media (map file)
$media = null;
if(!empty($_FILES) && array_key_exists('media', $_FILES) && $_FILES['media']['error'] != UPLOAD_ERR_NO_FILE)
{
$media = $_FILES['media'];
// Check error
if($media['error'] !== UPLOAD_ERR_OK) {
$validation = $this->Validation->addValidationResult($validation, 'media', 'error', $media['error']);
}
// Check mimetype
$mediaMimetype = null;
$media['mimetype'] = \hhu\z\Utils::getMimetype($media['tmp_name'], $media['type']);
foreach($mimetypes as &$mimetype) {
if($mimetype['mimetype'] == $media['mimetype']) {
$mediaMimetype = $mimetype;
break;
}
}
if(is_null($mediaMimetype)) {
$validation = $this->Validation->addValidationResult($validation, 'media', 'mimetype', $media['mimetype']);
}
elseif($media['size'] > $mediaMimetype['size']) {
$validation = $this->Validation->addValidationResult($validation, 'media', 'size', $mediaMimetype['size']);
}
}
// Edit map
if($validation === true)
{
// Update media
if(!is_null($media))
{
$seminarymediaId = $this->Media->createMapMedia(
$this->Auth->getUserId(),
$seminary['id'],
$media['name'],
sprintf('map of %s', $seminary['title']),
$media['type'],
$media['tmp_name']
);
if($seminarymediaId > 0) {
$this->Map->setMapOfSeminary($seminary['id'], $seminarymediaId);
}
}
// Redirect
$this->redirect($this->linker->link(array('index', $seminary['url']), 1));
}
}
// Set titile
//$this->addTitleLocalized('Delete Quest');
//$this->addTitle($seminary['title']);
// Pass data to view
$this->set('seminary', $seminary);
$this->set('map', $map);
$this->set('mimetypes', $mimetypes);
$this->set('validation', $validation);
}
}
?>

View file

@ -128,6 +128,9 @@
case 'library':
$index = 'library_seminarymedia_id';
break;
case 'map':
$index = 'map_seminarymedia_id';
break;
}
// Get media

View file

@ -451,7 +451,8 @@
array_key_exists('avatars', $elements),
array_key_exists('achievements', $elements),
array_key_exists('charactergroupsgroups', $elements),
array_key_exists('charactergroupsquests', $elements)
array_key_exists('charactergroupsquests', $elements),
array_key_exists('map', $elements)
);
$seminary = $this->Seminaries->getSeminaryById($seminaryId);

View file

@ -19,6 +19,12 @@
*/
class MapModel extends \hhu\z\Model
{
/**
* Required models
*
* @var array
*/
public $models = array('media');
@ -57,6 +63,85 @@
return null;
}
/**
* Set map of a Seminary.
*
* @param int $seminaryId ID of Seminary to set map of
* @param int $seminarymediaId ID of Seminary media of map to set
*/
public function setMapOfSeminary($seminaryId, $seminarymediaId)
{
// Get image measurements
$infos = $this->Media->getSeminarymediaInfos($seminarymediaId);
// Insert record
$this->db->query(
'INSERT INTO maps '.
'(seminary_id, seminarymedia_id, width, height) '.
'VALUES '.
'(?, ?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'seminarymedia_id = ?, width = ?, height = ?',
'iiiiiii',
$seminaryId, $seminarymediaId, $infos['width'], $infos['height'],
$seminarymediaId, $infos['width'], $infos['height']
);
}
/**
* Copy the map of a Seminary.
*
* @param int $sourceSeminaryId Seminary to copy from
* @param int $targetSeminaryId Seminary to copy to
* @param array $seminaryMediaIds Mapping of Seminarymedia-IDs from source Seminary to target Seminary
*/
public function copyMapOfSeminary($sourceSeminaryId, $targetSeminaryId, $seminaryMediaIds)
{
// Get map of source Seminary
$map = $this->getMapOfSeminary($sourceSeminaryId);
// Set map of targetSeminary
$this->setMapOfSeminary($targetSeminaryId, $seminaryMediaIds[$map['seminarymedia_id']]);
}
/**
* Delete the map of a Seminary.
*
* @param int $seminaryId ID of Seminary to delete map of
*/
public function deleteMapOfSeminary($seminaryId)
{
// Get map
$map = $this->getMap($seminaryId);
if(is_null($map)) {
return;
}
// Delete map
$this->db->setAutocommit(false);
try {
// Delete map record
$this->db->query(
'DELETE FROM maps '.
'WHERE seminary_id = ?',
'i',
$seminaryId
);
// Delete Seminary media
$this->Media->deleteSeminaryMedia($map['seminarymedia_id']);
$this->db->commit();
}
catch(\nre\exceptions\DatamodelException $e) {
$this->db->rollback();
}
$this->db->setAutocommit(true);
}
}
?>

View file

@ -603,6 +603,45 @@
}
/**
* Create a new map medium.
*
* @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 createMapMedia($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;
}
/**
* Gather some information about a Seminary medium.
*

View file

@ -24,7 +24,7 @@
*
* @var array
*/
public $models = array('questgroupshierarchy', 'questgroups', 'quests', 'questtopics', 'media', 'charactertypes', 'xplevels', 'avatars', 'achievements', 'charactergroups', 'charactergroupsquests', 'seminarycharacterfields');
public $models = array('questgroupshierarchy', 'questgroups', 'quests', 'questtopics', 'media', 'charactertypes', 'xplevels', 'avatars', 'achievements', 'charactergroups', 'charactergroupsquests', 'seminarycharacterfields', 'map');
@ -259,6 +259,25 @@
}
/**
* Set the moodpic for the map of a Seminary.
*
* @param int $seminaryId ID of Seminary to set moodpic for Map for
* @param int $seminaryMediaId ID of Seminarymedia to set as moodpic
*/
public function setMoodpicForMap($seminaryId, $seminaryMediaId)
{
$this->db->query(
'UPDATE seminaries '.
'SET map_seminarymedia_id = ? '.
'WHERE id = ?',
'ii',
$seminaryMediaId,
$seminaryId
);
}
/**
* (Re-) Calculate the amount of achievable XPs for a Seminary.
*
@ -326,9 +345,10 @@
* @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
* @param boolean $copyMap Whether to copy Map 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)
public function copySeminary($userId, $sourceSeminaryId, $title, $course, $description, $copySeminaryfields, $copyMedia, $copyQuestgroupshierarchy, $copyQuestgroups, $copyQuests, $copyQuesttopics, $copyCharactertypes, $copyXPlevels, $copyAvatars, $copyAchievements, $copyCharactergroupsgroups, $copyCharactergroupsquests, $copyMap)
{
// Get Seminary
$seminary = $this->getSeminaryById($sourceSeminaryId);
@ -362,6 +382,9 @@
if(!is_null($seminary['library_seminarymedia_id'])) {
$this->setMoodpicForLibrary($targetSeminaryId, $seminaryMediaIds[$seminary['library_seminarymedia_id']]);
}
if(!is_null($seminary['map_seminarymedia_id'])) {
$this->setMoodpicForMap($targetSeminaryId, $seminaryMediaIds[$seminary['map_seminarymedia_id']]);
}
}
// Copy Quest content
@ -423,6 +446,11 @@
}
}
// Copy Map
if($copyMap && !is_null($seminaryMediaIds)) {
$this->Map->copyMapOfSeminary($sourceSeminaryId, $targetSeminaryId, $seminaryMediaIds);
}
// Recalculate XPs
$this->calculateXPsForSeminary($targetSeminaryId);

51
views/html/map/edit.tpl Normal file
View file

@ -0,0 +1,51 @@
<?php if(!is_null($seminary['seminarymedia_id'])) : ?>
<div class="moodpic">
<img src="<?=$linker->link(array('media','seminarymoodpic',$seminary['url'], 'map'))?>">
</div>
<?php endif ?>
<ul class="breadcrumbs">
<li><a href="<?=$linker->link(array('seminaries',$seminary['url']))?>"><?=$seminary['title']?></a></li>
<li><i class="fa fa-chevron-right fa-fw"></i><a href="<?=$linker->link(array('index',$seminary['url']),1)?>"><?=_('Map')?></a></li>
</ul>
<h1><i class="fa fa-map-marker fa-fw"></i><?=_('Map')?></h1>
<?php if($validation !== true && !empty($validation)) : ?>
<ul class="validation">
<?php foreach($validation as $field => &$settings) : ?>
<li>
<ul>
<?php foreach($settings as $setting => $value) : ?>
<li>
<?php switch($field) {
case 'media':
switch($setting) {
case 'error': printf(_('Error during file upload: %s'), $value);
break;
case 'mimetype': printf(_('File has wrong type “%s”'), $value);
break;
case 'size': echo _('File exceeds size maximum');
break;
default: echo _('File invalid');
}
break;
} ?>
</li>
<?php endforeach ?>
</ul>
</li>
<?php endforeach ?>
</ul>
<?php endif ?>
<form method="post" enctype="multipart/form-data">
<fieldset>
<input type="file" name="media" accept="<?=implode(',', array_map(function($m) { return $m['mimetype']; }, $mimetypes))?>" />
<p><?=_('Allowed file types')?>:</p>
<ul>
<?php foreach($mimetypes as &$mimetype) : ?>
<li><?=sprintf(_('%s-files'), strtoupper(explode('/',$mimetype['mimetype'])[1]))?> <?php if($mimetype['size'] > 0) : ?>(<?=_('max.')?> <?=round($mimetype['size']/(1024*1024),2)?>MiB)<?php endif ?></li>
<?php endforeach ?>
</ul>
</fieldset>
<input type="submit" name="edit" value="<?=_('save')?>" />
</form>

View file

@ -1,13 +1,19 @@
<?php if(!is_null($seminary['seminarymedia_id'])) : ?>
<div class="moodpic">
<img src="<?=$linker->link(array('media','seminarymoodpic',$seminary['url']))?>">
<img src="<?=$linker->link(array('media','seminarymoodpic',$seminary['url'], 'map'))?>">
</div>
<?php endif ?>
<ul class="breadcrumbs">
<li><a href="<?=$linker->link(array('seminaries',$seminary['url']))?>"><?=$seminary['title']?></a></li>
</ul>
<h1><i class="fa fa-map-marker fa-fw"></i><?=_('Map')?></h1>
<?php if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\SeminaryController::$character['characterroles'])) > 0) : ?>
<nav class="admin">
<li><a href="<?=$linker->link(array('edit',$seminary['url']), 1)?>"><?=_('Edit Map')?></a></li>
<li><a href="<?=$linker->link(array('delete',$seminary['url']), 1)?>"><?=_('Delete Map')?></a></li>
</nav>
<?php endif ?>
<div id="map" class="map" style="background-image:url('<?=$linker->link(array('grafics','paper.jpg'))?>')"></div>
<script type="text/javascript">
var extent = [0, 0, <?=$map['width']?>, <?=$map['height']?>];

View file

@ -111,6 +111,8 @@
<input type="checkbox" id="elements_charactergroupsquests" name="elements[charactergroupsquests]" <?php if(array_key_exists('charactergroupsquests', $elements)) : ?>checked="checked"<?php endif ?> />
<label for="elements_charactergroupsquests"><?=_('Character Groups Quests')?></label>
</div>
<input type="checkbox" id="elements_map" name="elements[map]" <?php if(array_key_exists('map', $elements)) : ?>checked="checked"<?php endif ?> />
<label for="elements_map"><?=_('Map')?></label>
</fieldset>
<input type="submit" name="edit" value="<?=_('copy')?>" />
</form>