This commit is contained in:
coderkun 2015-04-30 18:50:27 +02:00
commit 50c38e0efa
9 changed files with 980 additions and 103 deletions

View file

@ -135,6 +135,16 @@
'mimetype' => 'image/jpeg',
'size' => 1048576
)
),
'questtypes' => array(
array(
'mimetype' => 'image/jpeg',
'size' => 524288
),
array(
'mimetype' => 'image/png',
'size' => 1048576
)
)
);

View file

@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: The Legend of Z\n"
"POT-Creation-Date: 2015-04-19 14:15+0100\n"
"PO-Revision-Date: 2015-04-20 21:06+0100\n"
"POT-Creation-Date: 2015-04-30 18:44+0100\n"
"PO-Revision-Date: 2015-04-30 18:45+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: de_DE\n"
@ -18,31 +18,31 @@ msgstr ""
"X-Poedit-SearchPath-2: controllers\n"
#: controllers/CharactersController.inc:402
#: controllers/UsersController.inc:333 views/ajax/characters/index.tpl:10
#: controllers/UsersController.inc:339 views/ajax/characters/index.tpl:10
#: views/ajax/users/index.tpl:10 views/html/characters/index.tpl:48
#: views/html/characters/manage.tpl:35 views/html/characters/manage.tpl:50
#: views/html/characters/manage.tpl:58 views/html/userroles/user.tpl:5
#: views/html/users/index.tpl:29 views/html/users/manage.tpl:28
#: views/html/users/index.tpl:33 views/html/users/manage.tpl:28
#: views/html/users/manage.tpl:41 views/html/users/manage.tpl:49
msgid "Admin"
msgstr "Administrator"
#: controllers/CharactersController.inc:408
#: controllers/UsersController.inc:339 views/ajax/characters/index.tpl:12
#: controllers/UsersController.inc:345 views/ajax/characters/index.tpl:12
#: views/ajax/users/index.tpl:12 views/html/characters/index.tpl:49
#: views/html/characters/manage.tpl:36 views/html/characters/manage.tpl:51
#: views/html/characters/manage.tpl:59 views/html/userroles/user.tpl:7
#: views/html/users/index.tpl:30 views/html/users/manage.tpl:29
#: views/html/users/index.tpl:34 views/html/users/manage.tpl:29
#: views/html/users/manage.tpl:42 views/html/users/manage.tpl:50
msgid "Moderator"
msgstr "Moderator"
#: controllers/CharactersController.inc:414
#: controllers/UsersController.inc:345 views/ajax/characters/index.tpl:14
#: controllers/UsersController.inc:351 views/ajax/characters/index.tpl:14
#: views/ajax/users/index.tpl:14 views/html/characters/index.tpl:50
#: views/html/characters/manage.tpl:37 views/html/characters/manage.tpl:53
#: views/html/characters/manage.tpl:61 views/html/userroles/user.tpl:9
#: views/html/users/index.tpl:31 views/html/users/manage.tpl:30
#: views/html/users/index.tpl:35 views/html/users/manage.tpl:30
#: views/html/users/manage.tpl:44 views/html/users/manage.tpl:52
msgid "User"
msgstr "Benutzer"
@ -101,6 +101,7 @@ msgstr ""
#: questtypes/bossfight/html/edittask.tpl:17
#: questtypes/choiceinput/html/edittask.tpl:83
#: questtypes/dragndrop/html/edittask.tpl:144
#: questtypes/multiplechoice/html/edittask.tpl:79
#: questtypes/textinput/html/edittask.tpl:44
#: views/html/achievements/conditions.tpl:151
@ -190,6 +191,137 @@ msgstr "vertikal"
msgid "horizontal"
msgstr "horizontal"
#: questtypes/dragndrop/html/edittask.tpl:11
#: questtypes/dragndrop/html/edittask.tpl:104
#: questtypes/submit/html/quest.tpl:8
#: views/html/charactergroupsquests/manage.tpl:37
#, php-format
msgid "Error during file upload: %s"
msgstr "Fehler beim Dateiupload: %s"
#: questtypes/dragndrop/html/edittask.tpl:13
#: questtypes/dragndrop/html/edittask.tpl:106
#: questtypes/submit/html/quest.tpl:4
#: views/html/charactergroupsquests/manage.tpl:39
#, php-format
msgid "File has wrong type “%s”"
msgstr "Der Dateityp „%s“ ist nicht erlaubt"
#: questtypes/dragndrop/html/edittask.tpl:15
#: questtypes/dragndrop/html/edittask.tpl:108
#: questtypes/submit/html/quest.tpl:6
#: views/html/charactergroupsquests/manage.tpl:41
msgid "File exceeds size maximum"
msgstr "Die Datei ist zu groß"
#: questtypes/dragndrop/html/edittask.tpl:17
#: questtypes/dragndrop/html/edittask.tpl:110
#: views/html/charactergroupsquests/manage.tpl:43
msgid "File invalid"
msgstr "Die Datei ist ungültig"
#: questtypes/dragndrop/html/edittask.tpl:31
#, php-format
msgid "Step %d"
msgstr "Schritt %d"
#: questtypes/dragndrop/html/edittask.tpl:31
#: views/html/achievements/conditions.tpl:22
#: views/html/achievements/conditions.tpl:31
#: views/html/achievements/conditions.tpl:59
#: views/html/achievements/conditions.tpl:89
#: views/html/achievements/conditions.tpl:98
#: views/html/achievements/conditions.tpl:126
msgid "Field"
msgstr "Feld"
#: questtypes/dragndrop/html/edittask.tpl:36
msgid "Upload background image"
msgstr "Hintergrundbild hochladen"
#: questtypes/dragndrop/html/edittask.tpl:38
#: questtypes/dragndrop/html/edittask.tpl:136
#: questtypes/submit/html/quest.tpl:17 views/html/achievements/create.tpl:66
#: views/html/achievements/edit.tpl:68
#: views/html/charactergroups/creategroup.tpl:64
#: views/html/charactergroups/editgroup.tpl:65
#: views/html/charactergroupsquests/create.tpl:66
#: views/html/charactergroupsquests/edit.tpl:67
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:135 views/html/questgroups/create.tpl:65
#: views/html/questgroups/edit.tpl:53 views/html/quests/create.tpl:62
#: views/html/quests/edit.tpl:65 views/html/seminaries/create.tpl:60
#: views/html/seminaries/edit.tpl:62
msgid "Allowed file types"
msgstr "Erlaubte Dateiformate"
#: questtypes/dragndrop/html/edittask.tpl:41
#: questtypes/dragndrop/html/edittask.tpl:139
#: questtypes/submit/html/quest.tpl:20 views/html/achievements/create.tpl:69
#: views/html/achievements/edit.tpl:71
#: views/html/charactergroups/creategroup.tpl:67
#: views/html/charactergroups/editgroup.tpl:68
#: views/html/charactergroupsquests/create.tpl:69
#: views/html/charactergroupsquests/edit.tpl:70
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:138 views/html/questgroups/create.tpl:68
#: views/html/questgroups/edit.tpl:56 views/html/quests/create.tpl:65
#: views/html/quests/edit.tpl:68 views/html/seminaries/create.tpl:63
#: views/html/seminaries/edit.tpl:65
#, php-format
msgid "%s-files"
msgstr "%s-Dateien"
#: questtypes/dragndrop/html/edittask.tpl:41
#: questtypes/dragndrop/html/edittask.tpl:139
#: questtypes/submit/html/quest.tpl:20 views/html/achievements/create.tpl:69
#: views/html/achievements/edit.tpl:71
#: views/html/charactergroups/creategroup.tpl:67
#: views/html/charactergroups/editgroup.tpl:68
#: views/html/charactergroupsquests/create.tpl:69
#: views/html/charactergroupsquests/edit.tpl:70
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:138 views/html/questgroups/create.tpl:68
#: views/html/questgroups/edit.tpl:56 views/html/quests/create.tpl:65
#: views/html/quests/edit.tpl:68 views/html/seminaries/create.tpl:63
#: views/html/seminaries/edit.tpl:65
msgid "max."
msgstr "max."
#: questtypes/dragndrop/html/edittask.tpl:45
#: questtypes/dragndrop/html/edittask.tpl:80
msgid "next step"
msgstr "nächster Schritt"
#: questtypes/dragndrop/html/edittask.tpl:48
#: questtypes/dragndrop/html/edittask.tpl:83
#, php-format
msgid "Step %d:"
msgstr "Schritt %d"
#: questtypes/dragndrop/html/edittask.tpl:48
msgid "Drop-items"
msgstr "Drop-Elemente"
#: questtypes/dragndrop/html/edittask.tpl:63
#: questtypes/dragndrop/html/edittask.tpl:184
msgid "Size"
msgstr "Größe"
#: questtypes/dragndrop/html/edittask.tpl:67
#: questtypes/dragndrop/html/edittask.tpl:188
msgid "Position"
msgstr "Position"
#: questtypes/dragndrop/html/edittask.tpl:79
#: questtypes/dragndrop/html/edittask.tpl:143
msgid "previous step"
msgstr "vorheriger Schritt"
#: questtypes/dragndrop/html/edittask.tpl:83
msgid "Drag-items"
msgstr "Drag-Elemente"
#: questtypes/multiplechoice/html/edittask.tpl:12
#: questtypes/multiplechoice/html/edittask.tpl:44
#, php-format
@ -234,66 +366,6 @@ msgstr "Frage %d von %d"
msgid "solve Question"
msgstr "Frage lösen"
#: questtypes/submit/html/quest.tpl:4
#: views/html/charactergroupsquests/manage.tpl:39
#, php-format
msgid "File has wrong type “%s”"
msgstr "Der Dateityp „%s“ ist nicht erlaubt"
#: questtypes/submit/html/quest.tpl:6
#: views/html/charactergroupsquests/manage.tpl:41
msgid "File exceeds size maximum"
msgstr "Die Datei ist zu groß"
#: questtypes/submit/html/quest.tpl:8
#: views/html/charactergroupsquests/manage.tpl:37
#, php-format
msgid "Error during file upload: %s"
msgstr "Fehler beim Dateiupload: %s"
#: questtypes/submit/html/quest.tpl:17 views/html/achievements/create.tpl:66
#: views/html/achievements/edit.tpl:68
#: views/html/charactergroups/creategroup.tpl:64
#: views/html/charactergroups/editgroup.tpl:65
#: views/html/charactergroupsquests/create.tpl:66
#: views/html/charactergroupsquests/edit.tpl:67
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:135 views/html/questgroups/create.tpl:65
#: views/html/questgroups/edit.tpl:53 views/html/quests/create.tpl:62
#: views/html/quests/edit.tpl:65 views/html/seminaries/create.tpl:60
#: views/html/seminaries/edit.tpl:62
msgid "Allowed file types"
msgstr "Erlaubte Dateiformate"
#: questtypes/submit/html/quest.tpl:20 views/html/achievements/create.tpl:69
#: views/html/achievements/edit.tpl:71
#: views/html/charactergroups/creategroup.tpl:67
#: views/html/charactergroups/editgroup.tpl:68
#: views/html/charactergroupsquests/create.tpl:69
#: views/html/charactergroupsquests/edit.tpl:70
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:138 views/html/questgroups/create.tpl:68
#: views/html/questgroups/edit.tpl:56 views/html/quests/create.tpl:65
#: views/html/quests/edit.tpl:68 views/html/seminaries/create.tpl:63
#: views/html/seminaries/edit.tpl:65
#, php-format
msgid "%s-files"
msgstr "%s-Dateien"
#: questtypes/submit/html/quest.tpl:20 views/html/achievements/create.tpl:69
#: views/html/achievements/edit.tpl:71
#: views/html/charactergroups/creategroup.tpl:67
#: views/html/charactergroups/editgroup.tpl:68
#: views/html/charactergroupsquests/create.tpl:69
#: views/html/charactergroupsquests/edit.tpl:70
#: views/html/charactergroupsquests/manage.tpl:72
#: views/html/charactertypes/edit.tpl:138 views/html/questgroups/create.tpl:68
#: views/html/questgroups/edit.tpl:56 views/html/quests/create.tpl:65
#: views/html/quests/edit.tpl:68 views/html/seminaries/create.tpl:63
#: views/html/seminaries/edit.tpl:65
msgid "max."
msgstr "max."
#: questtypes/submit/html/quest.tpl:28
msgid "Your submissions"
msgstr "Deine Lösungsvorschläge"
@ -411,7 +483,7 @@ msgstr "Texteingabe"
msgid "%dXPs"
msgstr "%d XP"
#: views/ajax/users/index.tpl:20 views/html/users/index.tpl:28
#: views/ajax/users/index.tpl:20 views/html/users/index.tpl:32
#: views/html/users/manage.tpl:31 views/html/users/user.tpl:22
#, php-format
msgid "registered on %s"
@ -443,15 +515,6 @@ msgstr "Bedingungen"
msgid "Date"
msgstr "Datum"
#: views/html/achievements/conditions.tpl:22
#: views/html/achievements/conditions.tpl:31
#: views/html/achievements/conditions.tpl:59
#: views/html/achievements/conditions.tpl:89
#: views/html/achievements/conditions.tpl:98
#: views/html/achievements/conditions.tpl:126
msgid "Field"
msgstr "Feld"
#: views/html/achievements/conditions.tpl:28
#: views/html/achievements/conditions.tpl:29
#: views/html/achievements/conditions.tpl:39
@ -973,6 +1036,7 @@ msgstr "Icon"
#: views/html/charactertypes/create.tpl:41
#: views/html/charactertypes/create.tpl:42
#: views/html/charactertypes/edit.tpl:41 views/html/charactertypes/edit.tpl:42
#: views/html/users/index.tpl:21 views/html/users/index.tpl:22
#: views/html/users/user.tpl:23
msgid "Name"
msgstr "Name"
@ -1193,10 +1257,6 @@ msgstr "%s-Quest bearbeiten"
msgid "Media"
msgstr "Medien"
#: views/html/charactergroupsquests/manage.tpl:43
msgid "File invalid"
msgstr "Die Datei ist ungültig"
#: views/html/charactergroupsquests/manage.tpl:68
msgid "delete selected"
msgstr "markierte löschen"
@ -1345,17 +1405,17 @@ msgid "Date of registration"
msgstr "Registrierungsdatum"
#: views/html/characters/index.tpl:37 views/html/quests/index.tpl:50
#: views/html/users/index.tpl:22
#: views/html/users/index.tpl:26
msgid "Apply filters"
msgstr "Filter anwenden"
#: views/html/characters/index.tpl:61 views/html/quests/index.tpl:82
#: views/html/users/index.tpl:39
#: views/html/users/index.tpl:48
msgid "Show more"
msgstr "Weitere anzeigen"
#: views/html/characters/index.tpl:62 views/html/quests/index.tpl:83
#: views/html/users/index.tpl:40
#: views/html/users/index.tpl:49
msgid "Show all"
msgstr "Alle anzeigen"
@ -2112,6 +2172,7 @@ msgstr "Nachname"
#: views/html/users/create.tpl:92 views/html/users/create.tpl:93
#: views/html/users/edit.tpl:100 views/html/users/edit.tpl:101
#: views/html/users/index.tpl:23 views/html/users/index.tpl:24
#: views/html/users/register.tpl:93 views/html/users/register.tpl:94
#: views/html/users/user.tpl:24
msgid "Email address"

View file

@ -580,7 +580,6 @@
}
/**
* Copy Achievement media.
*
@ -602,6 +601,32 @@
$userId
);
}
/**
* Gather some information about a Seminary medium.
*
* The infos are organized in an associative array and contain the
* following keys: width and height
*
* @param int $seminarymediaId ID of Seminary media to get infos for
* @return array List of infos for Seminary medium
*/
public function getSeminarymediaInfos($seminarymediaId)
{
// Create filename
$filename = ROOT.DS.\nre\configs\AppConfig::$dirs['seminarymedia'].DS.$seminarymediaId;
// Get infos
$infos = array();
$im = new \Imagick($filename);
$infos['width'] = $im->getImageWidth();
$infos['height'] = $im->getImageHeight();
// Return infos
return $infos;
}

View file

@ -25,6 +25,12 @@
* @var array
*/
public $models = array('media');
/**
* Required components
*
* @var array
*/
public $components = array('validation');
@ -222,19 +228,304 @@
}
/**
* TODO Action: edittask.
*
* Edit the task of a Quest.
*
* @param array $seminary Current Seminary data
* @param array $questgroup Current Questgroup data
* @param array $quest Current Quest data
*/
public function edittask($seminary, $questgroup, $quest)
{
}
}
/**
* Action: edittask.
*
* Edit the task of a Quest.
*
* @param array $seminary Current Seminary data
* @param array $questgroup Current Questgroup data
* @param array $quest Current Quest data
*/
public function edittask($seminary, $questgroup, $quest)
{
// Get Drag&Drop field
$dndField = $this->Dragndrop->getDragndrop($quest['id']);
if(!is_null($dndField)) {
$dndField['media'] = $this->Media->getSeminaryMediaById($dndField['questmedia_id']);
}
// Get Drop-items
$drops = array();
if(!is_null($dndField)) {
$drops = $this->Dragndrop->getDrops($dndField['quest_id']);
}
// Get Drag-items
$drags = array();
if(!is_null($dndField))
{
$drags = $this->Dragndrop->getDrags($dndField['quest_id']);
foreach($drags as &$drag)
{
$drag['media'] = $this->Media->getSeminaryMediaById($drag['questmedia_id']);
$drag['drops'] = array_map(function($d) { return $d['id']; }, $this->Dragndrop->getDropsForDrag($drag['id']));
}
}
// Get allowed mimetypes
$mimetypes = \nre\configs\AppConfig::$mimetypes['questtypes'];
// Values
$step = 0;
$steps = 2;
$validation = true;
$dragsValidation = true;
// Save submitted data
if($this->request->getRequestMethod() == 'POST')
{
// Get current step
$step = max(0, min(2, intval($this->request->getPostParam('step'))));
// Drag&Drop-field (background image)
if($step == 0)
{
// Validate zone
$zone = null;
if(!empty($_FILES) && array_key_exists('zone', $_FILES) && $_FILES['zone']['error'] != UPLOAD_ERR_NO_FILE)
{
$zone = $_FILES['zone'];
// Check error
if($zone['error'] !== UPLOAD_ERR_OK) {
$validation = $this->Validation->addValidationResult($validation, 'zone', 'error', $zone['error']);
}
// Check mimetype
$mediaMimetype = null;
$zone['mimetype'] = \hhu\z\Utils::getMimetype($zone['tmp_name'], $zone['type']);
foreach($mimetypes as &$mimetype) {
if($mimetype['mimetype'] == $zone['mimetype']) {
$mediaMimetype = $mimetype;
break;
}
}
if(is_null($mediaMimetype)) {
$validation = $this->Validation->addValidationResult($validation, 'zone', 'mimetype', $zone['mimetype']);
}
elseif($zone['size'] > $mediaMimetype['size']) {
$validation = $this->Validation->addValidationResult($validation, 'zone', 'size', $mediaMimetype['size']);
}
}
// Set zone
if($validation === true)
{
// Upload background image
$mediaId = $this->Media->createQuestMedia(
$this->Auth->getUserId(),
$seminary['id'],
sprintf('quest-dnd-%s', $quest['url']),
'',
$zone['mimetype'],
$zone['tmp_name']
);
if($mediaId !== false)
{
// Create Drag&Drop zone
$this->Dragndrop->createDragndrop(
$this->Auth->getUserId(),
$quest['id'],
$mediaId
);
}
// Reload Drag&Drop field
$dndField = $this->Dragndrop->getDragndrop($quest['id']);
$dndField['media'] = $this->Media->getSeminaryMediaById($dndField['questmedia_id']);
}
}
// Drop-items
elseif($step == 1)
{
// Get new Drop-items and organize them
$dropsNew = array();
$dropsUpdate = array();
foreach($this->request->getPostParam('drops') as $drop)
{
if(array_key_exists('id', $drop)) {
$dropsUpdate[$drop['id']] = $drop;
}
else {
$dropsNew[] = $drop;
}
}
// Update Drop-items
foreach($drops as $drop)
{
if(array_key_exists($drop['id'], $dropsUpdate))
{
$drop = $dropsUpdate[$drop['id']];
$this->Dragndrop->editDrop($drop['id'], $drop['width'], $drop['height'], $drop['x'], $drop['y']);
}
else {
$this->Dragndrop->deleteDrop($drop['id']);
}
}
// Add new Drop-items
foreach($dropsNew as $drop) {
$this->Dragndrop->addDrop($dndField['quest_id'], $drop['width'], $drop['height'], $drop['x'], $drop['y']);
}
// Reload Drop-items
$drops = $this->Dragndrop->getDrops($dndField['quest_id']);
}
// Drag-items
elseif($step == 2)
{
// Get new Drop-items and organize them
$dragsNew = array();
$dragsUpdate = array();
foreach($this->request->getPostParam('drags') as $index => $drag)
{
// Get file
if(array_key_exists($index, $_FILES['drags']['error']) && $_FILES['drags']['error'][$index] !== UPLOAD_ERR_NO_FILE)
{
$drag['file'] = array(
'name' => $_FILES['drags']['name'][$index],
'type' => $_FILES['drags']['type'][$index],
'tmp_name' => $_FILES['drags']['tmp_name'][$index],
'error' => $_FILES['drags']['error'][$index],
'size' => $_FILES['drags']['size'][$index]
);
// Validate file
$dragValidation = true;
// Check error
if($drag['file']['error'] !== UPLOAD_ERR_OK) {
$dragValidation = $this->Validation->addValidationResult($dragValidation, 'file', 'error', $drag['file']['error']);
}
// Check mimetype
$dragMimetype = null;
$drag['file']['mimetype'] = \hhu\z\Utils::getMimetype($drag['file']['tmp_name'], $drag['file']['type']);
foreach($mimetypes as &$mimetype) {
if($mimetype['mimetype'] == $drag['file']['mimetype']) {
$dragMimetype = $mimetype;
break;
}
}
if(is_null($dragMimetype)) {
$dragValidation = $this->Validation->addValidationResult($dragValidation, 'file', 'mimetype', $drag['file']['mimetype']);
}
elseif($drag['file']['size'] > $dragMimetype['size']) {
$dragValidation = $this->Validation->addValidationResult($dragValidation, 'file', 'size', $dragMimetype['size']);
}
// Add validation result
if($dragValidation !== true)
{
if(!is_array($dragsValidation)) {
$dragsValidation = array();
}
$dragsValidation[$index] = $dragValidation;
}
// Upload Drag-item file
if($dragValidation === true)
{
$drag['file']['media_id'] = $this->Media->createQuestMedia(
$this->Auth->getUserId(),
$seminary['id'],
sprintf('quest-dnd-%s-%s', substr($quest['url'], 0, 25), substr($drag['file']['name'], 0, 25)),
'',
$drag['file']['mimetype'],
$drag['file']['tmp_name']
);
}
}
// Add to array
if(array_key_exists('id', $drag)) {
$dragsUpdate[$drag['id']] = $drag;
}
else {
$dragsNew[] = $drag;
}
}
// Update Drag-items
foreach($drags as $drag)
{
if(array_key_exists($drag['id'], $dragsUpdate))
{
$drag = $dragsUpdate[$drag['id']];
// Edit Drag-items
if(array_key_exists('file', $drag) && array_key_exists('media_id', $drag['file'])) {
$this->Dragndrop->editDrag($drag['id'], $drag['file']['media_id']);
}
// Set correct Drop-items for Drag-item
$this->Dragndrop->setDropsForDrag(
$this->Auth->getUserId(),
$drag['id'],
array_key_exists('drops', $drag) ? array_keys($drag['drops']) : array()
);
}
else {
$this->Dragndrop->deleteDrag($drag['id']);
}
}
// Add new Drag-items
foreach($dragsNew as $drag)
{
if(array_key_exists('file', $drag) && array_key_exists('media_id', $drag['file']))
{
// Create Drag-item
$dragId = $this->Dragndrop->addDrag($dndField['quest_id'], $drag['file']['media_id']);
// Set Drop-items for Drag-item
$this->Dragndrop->setDropsForDrag(
$this->Auth->getUserId(),
$dragId,
array_key_exists('drops', $drag) ? array_keys($drag['drops']) : array()
);
}
}
// Reload Drag-items
$drags = $this->Dragndrop->getDrags($dndField['quest_id']);
foreach($drags as &$drag)
{
$drag['media'] = $this->Media->getSeminaryMediaById($drag['questmedia_id']);
$drag['drops'] = array_map(function($d) { return $d['id']; }, $this->Dragndrop->getDropsForDrag($drag['id']));
}
}
// Go to next/previous step
if(!is_null($this->request->getPostParam('prev'))) {
$step--;
}
else {
$step++;
}
// Redirect after last step
if($step > $steps)
{
if($validation === true && $dragsValidation === true) {
$this->redirect($this->linker->link(array('quest', $seminary['url'], $questgroup['url'], $quest['url']), 1));
}
else {
$step--;
}
}
}
// Pass data to view
$this->set('seminary', $seminary);
$this->set('zone', $dndField);
$this->set('drops', $drops);
$this->set('drags', $drags);
$this->set('mimetypes', $mimetypes);
$this->set('step', $step);
$this->set('validation', $validation);
$this->set('dragsValidation', $dragsValidation);
}
}
?>

View file

@ -128,6 +128,33 @@
/**
* Create a new Drag&Drop field for a Quest.
*
* @param int $userId ID of creating user
* @param int $questId ID of Quest to create Drag&Drop field for
* @param int $questmediaId ID of Questmedia to use for the field
*/
public function createDragndrop($userId, $questId, $questmediaId)
{
// Get image measurements
$infos = $this->Media->getSeminarymediaInfos($questmediaId);
// Create field
$this->db->query(
'INSERT INTO questtypes_dragndrop '.
'(quest_id, created_user_id, questmedia_id, width, height) '.
'VALUES '.
'(?, ?, ?, ?, ?) '.
'ON DUPLICATE KEY UPDATE '.
'questmedia_id = ?, width = ?, height = ?',
'iiiiiiii',
$questId, $userId, $questmediaId, $infos['width'], $infos['height'],
$questmediaId, $infos['width'], $infos['height']
);
}
/**
* Get Drag&Drop-field.
*
@ -161,13 +188,151 @@
public function getDrops($dragndropId)
{
return $this->db->query(
'SELECT id, top, `left`, width, height '. //, questtypes_dragndrop_drag_id '.
'SELECT id, top, `left`, width, height '.
'FROM questtypes_dragndrop_drops '.
'WHERE questtypes_dragndrop_id = ?',
'i',
$dragndropId
);
}
/**
* Get Drop-items for a Drag-item
*
* @param int $dragId ID of Drag-item to get Drop-items for
* @return array List of Drop-items
*/
public function getDropsForDrag($dragId)
{
return $this->db->query(
'SELECT drops.id, top, `left`, width, height '.
'FROM questtypes_dragndrop_drops_drags AS drops_drags '.
'INNER JOIN questtypes_dragndrop_drops AS drops ON drops.id = drops_drags.questtypes_dragndrop_drop_id '.
'WHERE drops_drags.questtypes_dragndrop_drag_id = ?',
'i',
$dragId
);
}
/**
* Set correct Drop-items for a Drag-item.
*
* @param int $userId ID of creating user
* @param int $dragId ID of Drag-item to set Drop-items for
* @param array $dropIds List of Drop-items to set for Drag-item
*/
public function setDropsForDrag($userId, $dragId, $dropIds)
{
// Set new Drop-items
if(!empty($dropIds))
{
$this->db->query(
sprintf(
'INSERT INTO questtypes_dragndrop_drops_drags '.
'(questtypes_dragndrop_drop_id, questtypes_dragndrop_drag_id, created_user_id) '.
'SELECT questtypes_dragndrop_drops.id, ?, ? '.
'FROM questtypes_dragndrop_drops '.
'WHERE questtypes_dragndrop_drops.questtypes_dragndrop_id = ('.
'SELECT questtypes_dragndrop_drags.questtypes_dragndrop_id '.
'FROM questtypes_dragndrop_drags '.
'WHERE questtypes_dragndrop_drags.id = ?'.
') AND questtypes_dragndrop_drops.id IN (%s) '.
'ON DUPLICATE KEY UPDATE '.
'questtypes_dragndrop_drops_drags.created = questtypes_dragndrop_drops_drags.created',
implode(',', array_map(function($id) { return intval($id); }, $dropIds))
),
'iii',
$dragId, $userId,
$dragId
);
// Remove old Drop-items
$this->db->query(
sprintf(
'DELETE FROM questtypes_dragndrop_drops_drags '.
'WHERE questtypes_dragndrop_drag_id = ? AND questtypes_dragndrop_drop_id NOT IN (%s)',
implode(',', array_map(function($id) { return intval($id); }, $dropIds))
),
'i',
$dragId
);
}
else
{
// Remove all Drop-items
$this->db->query(
'DELETE FROM questtypes_dragndrop_drops_drags '.
'WHERE questtypes_dragndrop_drag_id = ?',
'i',
$dragId
);
}
}
/**
* Create a new Drop-item for a Drag&Drop-field.
*
* @param int $dragndropId ID of Drag&Drop-field to create Drop-item for
* @param int $width Width of Drop-item
* @param int $height Height of Drop-item
* @param int $x X-coordinate of Drop-item
* @param int $y Y-coordinate of Drop-item
* @return int ID of newly created Drop-item
*/
public function addDrop($dragndropId, $width, $height, $x, $y)
{
$this->db->query(
'INSERT INTO questtypes_dragndrop_drops '.
'(questtypes_dragndrop_id, top, `left`, width, height) '.
'VALUES '.
'(?, ?, ?, ?, ?)',
'iiiii',
$dragndropId, $y, $x, $width, $height
);
return $this->db->getInsertId();
}
/**
* Edit Drop-item.
*
* @param int $dropId ID of Drop-item to edit
* @param int $width New width of Drop-item
* @param int $height New height of Drop-item
* @param int $x New X-coordinate of Drop-item
* @param int $y New Y-coordinate of Drop-item
*/
public function editDrop($dropId, $width, $height, $x, $y)
{
$this->db->query(
'UPDATE questtypes_dragndrop_drops '.
'SET top = ?, `left` = ?, width = ?, height = ? '.
'WHERE id = ?',
'iiiii',
$y, $x, $width, $height,
$dropId
);
}
/**
* Delete a Drop-item.
*
* @param int $dropId ID of Drop-item to delete
*/
public function deleteDrop($dropId)
{
$this->db->query(
'DELETE FROM questtypes_dragndrop_drops '.
'WHERE id = ?',
'i',
$dropId
);
}
/**
@ -195,6 +360,63 @@
$dragndropId
);
}
/**
* Create a new Drag-item.
*
* @param int $dragndropId ID of Drag&Drop-field to add Drag-item for
* @param int $questmediaId ID of Questmedia to use for this Drag-item
* @return int ID of newly created Drag-item
*/
public function addDrag($dragndropId, $questmediaId)
{
$this->db->query(
'INSERT INTO questtypes_dragndrop_drags '.
'(questtypes_dragndrop_id, questmedia_id) '.
'VALUES '.
'(?, ?) ',
'ii',
$dragndropId, $questmediaId
);
return $this->db->getInsertId();
}
/**
* Edit Drag-item.
*
* @param int $dragId ID of Drag-item to edit
* @param int $questmediaId ID of new Questmedia to use for this Drag-item
*/
public function editDrag($dragId, $questmediaId)
{
$this->db->query(
'UPDATE questtypes_dragndrop_drags '.
'SET questmedia_id = ? '.
'WHERE id = ?',
'ii',
$questmediaId,
$dragId
);
}
/**
* Delete a Drag-item.
*
* @param int $dragId ID of Drag-item to delete
*/
public function deleteDrag($dragId)
{
$this->db->query(
'DELETE FROM questtypes_dragndrop_drags '.
'WHERE id = ?',
'i',
$dragId
);
}
/**

View file

@ -1 +1,254 @@
<p>TODO</p>
<?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 'zone':
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">
<?php if($step == 0) : ?>
<fieldset>
<legend><?=sprintf(_('Step %d'), 1)?> <?=_('Field')?>:</legend>
<?php if(!is_null($zone)) : ?>
<div id="dropZone" style="width:<?=$zone['width']?>px; height:<?=$zone['height']?>px; background-image:url('<?=$linker->link(array('media','seminary',$seminary['url'],$zone['media']['url']))?>')">
</div>
<?php endif ?>
<label for="zone"><?=_('Upload background image')?>:</label>
<input type="file" id="zone" name="zone" />
<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="next" value="<?=_('next step')?>" />
<?php elseif($step == 1) : ?>
<fieldset>
<legend><?=sprintf(_('Step %d:'), 2)?> <?=_('Drop-items')?></legend>
<div id="dropZone" class="dev" style="position:relative; width:<?=$zone['width']?>px; height:<?=$zone['height']?>px; background-image:url('<?=$linker->link(array('media','seminary',$seminary['url'],$zone['media']['url']))?>')">
<?php foreach($drops as $index => &$drop) : ?>
<div id="drop<?=$index?>" ondragenter="onDragEnter(event)" ondragover="onDragOver(event)" ondragleave="onDragLeave(event)" ondrop="onDrop(event)" style="position:absolute; width:<?=$drop['width']?>px; height:<?=$drop['height']?>px; top:<?=$drop['top']?>px; left:<?=$drop['left']?>px;">
<?=$index+1?>
<i class="fa fa-arrows move"></i>
<i class="fa fa-expand resize"></i>
</div>
<?php endforeach ?>
</div>
<ol id="drops">
<?php foreach($drops as $index => &$drop) : ?>
<li id="drop<?=$index?>-p">
<span class="lstidx"><?=$index+1?></span>
<input type="hidden" name="drops[<?=$index?>][id]" value="<?=$drop['id']?>" />
<label><?=_('Size')?>:</label>
<input type="number" id="drop<?=$index?>-w" name="drops[<?=$index?>][width]" value="<?=$drop['width']?>" min="45" max="<?=$zone['width']?>" /> x
<input type="number" id="drop<?=$index?>-h" name="drops[<?=$index?>][height]" value="<?=$drop['height']?>" min="25" max="<?=$zone['height']?>" /> px
<br />
<label><?=_('Position')?>:</label>
<input type="number" id="drop<?=$index?>-x" name="drops[<?=$index?>][x]" value="<?=$drop['left']?>" min="0" max="<?=$zone['width']?>" /> x
<input type="number" id="drop<?=$index?>-y" name="drops[<?=$index?>][y]" value="<?=$drop['top']?>" min="0" max="<?=$zone['height']?>" /> px
<br />
<input type="button" class="remove-drop" value="" />
</li>
<?php endforeach ?>
<li>
<input type="button" class="add-drop" value="+" />
</li>
</ol>
</fieldset>
<input type="submit" name="prev" value="<?=_('previous step')?>" />
<input type="submit" name="next" value="<?=_('next step')?>" />
<?php elseif($step == 2) : ?>
<fieldset>
<legend><?=sprintf(_('Step %d:'), 3)?> <?=_('Drag-items')?></legend>
<div id="dropZone" class="dev" style="position:relative; width:<?=$zone['width']?>px; height:<?=$zone['height']?>px; background-image:url('<?=$linker->link(array('media','seminary',$seminary['url'],$zone['media']['url']))?>')">
<?php foreach($drops as $index => &$drop) : ?>
<div id="drop<?=$index?>" ondragenter="onDragEnter(event)" ondragover="onDragOver(event)" ondragleave="onDragLeave(event)" ondrop="onDrop(event)" style="position:absolute; width:<?=$drop['width']?>px; height:<?=$drop['height']?>px; top:<?=$drop['top']?>px; left:<?=$drop['left']?>px;">
<?=$index+1?>
</div>
<?php endforeach ?>
</div>
<ul id="drags">
<?php foreach($drags as $dragIndex => &$drag) : ?>
<li id="drag<?=$dragIndex?>">
<?php if($dragsValidation !== true && array_key_exists($dragIndex, $dragsValidation) && $dragsValidation[$dragIndex] !== true) : ?>
<ul class="validation">
<?php foreach($dragsValidation[$dragIndex] as $field => &$settings) : ?>
<li>
<ul>
<?php foreach($settings as $setting => $value) : ?>
<li>
<?php switch($field) {
case 'file':
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 ?>
<input type="hidden" name="drags[<?=$dragIndex?>][id]" value="<?=$drag['id']?>" />
<img id="drag<?=$dragIndex?>" src="<?=$linker->link(array('media','seminary',$seminary['url'],$drag['media']['url']))?>" />
<input type="file" name="drags[<?=$dragIndex?>]" />
<?php foreach($drops as $dropIndex => &$drop) : ?>
<input type="checkbox" id="drag<?=$dragIndex?>-drop<?=$dropIndex?>" name="drags[<?=$dragIndex?>][drops][<?=$drop['id']?>]" <?php if(in_array($drop['id'], $drag['drops'])) : ?>checked="checked"<?php endif ?> />
<label for="drag<?=$dragIndex?>-drop<?=$dropIndex?>"><?=$dropIndex+1?></label>
<?php endforeach ?>
<br />
<input type="button" class="remove-drag" value="" />
</li>
<?php endforeach?>
<li>
<input type="button" class="add-drag" value="+" />
</li>
</ul>
<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="prev" value="<?=_('previous step')?>" />
<input type="submit" name="next" value="<?=_('save')?>" />
<?php endif ?>
<input type="hidden" name="step" value="<?=$step?>" />
</form>
<script src="/js/jquery-ui.min.js"></script>
<script>
var dropIndex = <?=count($drops)?>;
var dragIndex = <?=count($drags)?>;
var cssProps = {w: "width", h: "height", x: "left", y: "top"};
var draggable = {
containment: "parent",
handle: 'i.move',
drag: function(event, ui) {
var id = ui.helper.prop('id').substr(4);
$('#drop' + id + '-x').prop('value', ui.position.left);
$('#drop' + id + '-y').prop('value', ui.position.top);
}
};
var resizable = {
minWidth: 45,
minHeight: 25,
handles: {
se: 'i.resize'
},
resize: function(event, ui) {
var id = ui.helper.prop('id').substr(4);
$('#drop' + id + '-w').prop('value', ui.size.width);
$('#drop' + id + '-h').prop('value', ui.size.height);
}
};
var dropElement =
'<div id="dropDROPINDEX" style="position:absolute; width:75px; height:50px; top:0; left:0;">' +
'DROPINDEX1' +
'<i class="fa fa-arrows move"></i>' +
'<i class="fa fa-expand resize"></i>' +
'</div>';
var dropPropElement =
'<li id="dropDROPINDEX-p">' +
'<span class="lstidx">DROPINDEX1</span>' +
"<label><?=_('Size')?>:</label>" +
'<input type="number" id="dropDROPINDEX-w" name="drops[DROPINDEX][width]" value="45" min="45" max="<?=$zone['width']?>" /> x' +
'<input type="number" id="dropDROPINDEX-h" name="drops[DROPINDEX][height]" value="25" min="25" max="<?=$zone['height']?>" /> px' +
'<br />' +
"<label><?=_('Position')?>:</label>" +
'<input type="number" id="dropDROPINDEX-x" name="drops[DROPINDEX][x]" value="0" min="0" max="<?=$zone['width']?>" /> x' +
'<input type="number" id="dropDROPINDEX-y" name="drops[DROPINDEX][y]" value="0" min="0" max="<?=$zone['height']?>" /> px' +
'<br /><input type="button" class="remove-drop" value="" />' +
'</li>';
var dragElement =
'<li id="dragDRAGINDEX">' +
'<input type="file" name="drags[DRAGINDEX]" />' +
<?php foreach($drops as $dropIndex => &$drop) : ?>
'<input type="checkbox" id="dragDRAGINDEX-drop<?=$dropIndex?>" name="drags[DRAGINDEX][drops][<?=$drop['id']?>]" />\n' +
'<label for="dragDRAGINDEX-drop<?=$dropIndex?>"><?=$dropIndex+1?></label>\n' +
<?php endforeach ?>
'<br /><input type="button" class="remove-drag" value="" /></li>';
function addDrop(event) {
var element = dropElement.replace(/DROPINDEX1/g, dropIndex+1).replace(/DROPINDEX/g, dropIndex);
$("#dropZone").append(element);
var propElement = dropPropElement.replace(/DROPINDEX1/g, dropIndex+1).replace(/DROPINDEX/g, dropIndex);
$(event.target).parent().before(propElement);
$("#drop"+dropIndex).draggable(draggable);
$("#drop"+dropIndex).resizable(resizable);
$("#drop"+dropIndex+"-p").change(changeDrop);
$("#drop"+dropIndex+"-p .remove-drop").click(removeDrop);
event.preventDefault();
dropIndex++;
}
function changeDrop(event) {
var id = event.target.id.substring(4, event.target.id.length-2);
var type = event.target.id.substr(event.target.id.length-1);
$("#drop" + id).css(cssProps[type], $(event.target).val()+'px');
}
function removeDrop(event) {
var element = $(event.target).parent();
var id = element.attr('id').substring(4, element.attr('id').length-2);
$("#drop" + id).remove();
element.remove();
event.preventDefault();
}
function addDrag(event) {
var element = dragElement.replace(/DRAGINDEX/g, dragIndex);
$(event.target).parent().before(element);
$("#drag"+dragIndex+" .remove-drag").click(removeDrag);
event.preventDefault();
dragIndex++;
}
function removeDrag(event) {
var element = $(event.target).parent();
element.remove();
event.preventDefault();
}
$(function() {
$("#dropZone.dev div").draggable(draggable);
$("#dropZone.dev div").resizable(resizable);
$("#drops li").change(changeDrop);
$(".add-drop").click(addDrop);
$(".remove-drop").click(removeDrop);
$(".add-drag").click(addDrag);
$(".remove-drag").click(removeDrag);
});
</script>

View file

@ -355,8 +355,16 @@ input[type="submit"][disabled]{text-shadow:1px 2px #d48c4e;background:#f9ac69;bo
.opponent .fa{font-size:1.25em;color:#c7135b;padding-right:0}
.bossfight .option{background:#fff;margin-bottom:10px;padding:15px 15px 5px;border-radius:3px}
#dragZone{background:#eae8e4;box-sizing:border-box;padding:5px 5px 0 5px}
#dropZone.dev div{text-align:center;background-color:rgba(255,255,0,0.6)}
#dropZone.dev i.move{cursor:grab}
#dropZone.dev i.resize{position:absolute;right:0;bottom:0;padding:0;cursor:nwse-resize}
.drop{background:#eae8e4}
#drops li{position:relative;margin:10px 0 10px 30px}
#drops span.lstidx{position:absolute;top:2px;left:-30px}
#drops span.lstidx:after{content:'.'}
#drops input[type="number"]{width:70px}
#dragZone{background:#eae8e4;box-sizing:border-box;padding:5px 5px 0 5px}
#drags > li{list-style-type:initial;margin:10px 0 10px 30px}
/** Media Queries **/

7
www/js/jquery-ui.min.js vendored Normal file

File diff suppressed because one or more lines are too long