diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index 0e7678b0..b68c5458 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -117,6 +117,16 @@ 'size' => 204800 ) ), + 'moodpics' => array( + array( + 'mimetype' => 'image/jpeg', + 'size' => 524288 + ), + array( + 'mimetype' => 'image/png', + 'size' => 1048576 + ) + ), 'charactergroupsquests' => array( array( 'mimetype' => 'image/jpeg', @@ -198,6 +208,9 @@ 'xps' => array( 'minlength' => 1, 'regex' => '/^(\d*)$/' + ), + 'course' => array( + 'maxlength' => 128 ) ); diff --git a/controllers/CharactersController.inc b/controllers/CharactersController.inc index f0dca5c5..5ea6ff9d 100644 --- a/controllers/CharactersController.inc +++ b/controllers/CharactersController.inc @@ -292,6 +292,11 @@ } } + // Set roles for owners and admins + if(in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles']) || $seminary['created_user_id'] == \hhu\z\controllers\IntermediateController::$user['id']) { + $this->Characterroles->addCharacterroleToCharacter($characterId, 'admin'); + } + // Send mail $this->sendRegistrationMail($character); diff --git a/controllers/SeminariesController.inc b/controllers/SeminariesController.inc index 0c392a87..a0bd8a84 100644 --- a/controllers/SeminariesController.inc +++ b/controllers/SeminariesController.inc @@ -25,6 +25,12 @@ * @var array */ public $models = array('seminaries', 'users', 'characterroles', 'questgroupshierarchy', 'questgroups', 'media'); + /** + * Required components + * + * @var array + */ + public $components = array('validation'); /** * User permissions * @@ -162,26 +168,109 @@ /** * Action: create. * - * Create a new seminary. + * Create a new Seminary. */ public function create() { + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = ''; + $course = ''; + $description = ''; + $fields = array('title', 'course'); + $validation = array(); + + // Create a new Seminary if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) { - // Create new seminary - $seminaryId = $this->Seminaries->createSeminary( - $this->request->getPostParam('title'), - $this->Auth->getUserId() - ); + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Seminaries->seminaryTitleExists($title)) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $course = $this->request->getPostParam('course'); + $description = $this->request->getPostParam('description'); - // Redirect to seminary - $user = $this->Seminaries->getSeminaryById($seminaryId); - $this->redirect($this->linker->link(array($seminary['url']), 1)); + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) + { + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } + } + + // Create new Seminary + if($validation === true) + { + $seminaryId = $this->Seminaries->createSeminary( + $this->Auth->getUserId(), + $title, + $course, + $description + ); + $seminary = $this->Seminaries->getSeminaryById($seminaryId); + + // Upload moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createMoodpic( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('seminarymoodpic-%s', $seminary['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Seminaries->setMoodpicForSeminary($seminary['id'], $mediaId); + } + } + + // Redirect to Seminary overview + $this->redirect($this->linker->link('index', 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; } // Set titile $this->addTitleLocalized('New seminary'); + + // Pass data to view + $this->set('title', $title); + $this->set('course', $course); + $this->set('description', $description); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); } @@ -198,23 +287,92 @@ // Get seminary $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + // Get allowed mimetypes + $mimetypes = \nre\configs\AppConfig::$mimetypes['moodpics']; + + // Values + $title = $seminary['title']; + $course = $seminary['course']; + $description = $seminary['description']; + $fields = array('title', 'course'); + $validation = array(); + // Check request method - if($this->request->getRequestMethod() == 'POST') + if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('edit'))) { - // Save changes - if(!is_null($this->request->getPostParam('save'))) + // Get params and validate them + $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); + $title = $this->request->getPostParam('title'); + if($this->Seminaries->seminaryTitleExists($title, $seminary['id'])) { + $validation = $this->Validation->addValidationResult($validation, 'title', 'exist', true); + } + $course = $this->request->getPostParam('course'); + $description = $this->request->getPostParam('description'); + + // Validate moodpic + $moodpic = null; + if(!empty($_FILES) && array_key_exists('moodpic', $_FILES) && $_FILES['moodpic']['error'] != UPLOAD_ERR_NO_FILE) { - // Edit seminary - $this->Seminaries->editSeminary( - $seminary['id'], - $this->request->getPostParam('title') - ); - $seminary = $this->Seminaries->getSeminaryById($seminary['id']); + $moodpic = $_FILES['moodpic']; + + // Check error + if($moodpic['error'] !== UPLOAD_ERR_OK) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'error', $moodpic['error']); + } + + // Check mimetype + $mediaMimetype = null; + $moodpic['mimetype'] = \hhu\z\Utils::getMimetype($moodpic['tmp_name'], $moodpic['type']); + foreach($mimetypes as &$mimetype) { + if($mimetype['mimetype'] == $moodpic['mimetype']) { + $mediaMimetype = $mimetype; + break; + } + } + if(is_null($mediaMimetype)) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'mimetype', $moodpic['mimetype']); + } + elseif($moodpic['size'] > $mediaMimetype['size']) { + $validation = $this->Validation->addValidationResult($validation, 'moodpic', 'size', $mediaMimetype['size']); + } } - - // Redirect to entry - $this->redirect($this->linker->link(array($seminary['url']), 1)); + // Edit Seminary + if($validation === true) + { + $this->Seminaries->editSeminary( + $seminary['id'], + $title, + $course, + $description + ); + $seminary = $this->Seminaries->getSeminaryById($seminary['id']); + + // Update moodpic + if(!is_null($moodpic)) + { + $mediaId = $this->Media->createMoodpic( + $this->Auth->getUserId(), + $seminary['id'], + sprintf('seminarymoodpic-%s', $seminary['url']), + '', + $moodpic['mimetype'], + $moodpic['tmp_name'] + ); + if($mediaId !== false) { + $this->Seminaries->setMoodpicForSeminary($seminary['id'], $mediaId); + } + } + + // Redirect to entry + $this->redirect($this->linker->link(array('seminary', $seminary['url']), 1)); + } + } + + // Get validation settings + $validationSettings = array(); + foreach($fields as &$field) { + $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; } @@ -223,6 +381,12 @@ // Pass data to view $this->set('seminary', $seminary); + $this->set('title', $title); + $this->set('course', $course); + $this->set('description', $description); + $this->set('mimetypes', $mimetypes); + $this->set('validation', $validation); + $this->set('validationSettings', $validationSettings); } diff --git a/locale/de_DE/LC_MESSAGES/The Legend of Z.mo b/locale/de_DE/LC_MESSAGES/The Legend of Z.mo index a81cb049..ee0b8d63 100644 Binary files a/locale/de_DE/LC_MESSAGES/The Legend of Z.mo and b/locale/de_DE/LC_MESSAGES/The Legend of Z.mo differ diff --git a/locale/de_DE/LC_MESSAGES/The Legend of Z.po b/locale/de_DE/LC_MESSAGES/The Legend of Z.po index bfd8b046..ad6d3818 100644 --- a/locale/de_DE/LC_MESSAGES/The Legend of Z.po +++ b/locale/de_DE/LC_MESSAGES/The Legend of Z.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: The Legend of Z\n" -"POT-Creation-Date: 2014-05-27 11:27+0100\n" -"PO-Revision-Date: 2014-05-27 11:28+0100\n" +"POT-Creation-Date: 2014-05-28 10:27+0100\n" +"PO-Revision-Date: 2014-05-28 10:29+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: de_DE\n" @@ -17,7 +17,7 @@ msgstr "" "X-Poedit-SearchPath-1: questtypes\n" "X-Poedit-SearchPath-2: controllers\n" -#: controllers/CharactersController.inc:368 +#: controllers/CharactersController.inc:373 #: controllers/UsersController.inc:312 views/ajax/characters/index.tpl:10 #: views/ajax/users/index.tpl:10 views/html/characters/index.tpl:39 #: views/html/characters/manage.tpl:35 views/html/characters/manage.tpl:50 @@ -27,7 +27,7 @@ msgstr "" msgid "Admin" msgstr "Administrator" -#: controllers/CharactersController.inc:374 +#: controllers/CharactersController.inc:379 #: controllers/UsersController.inc:318 views/ajax/characters/index.tpl:12 #: views/ajax/users/index.tpl:12 views/html/characters/index.tpl:40 #: views/html/characters/manage.tpl:36 views/html/characters/manage.tpl:51 @@ -37,7 +37,7 @@ msgstr "Administrator" msgid "Moderator" msgstr "Moderator" -#: controllers/CharactersController.inc:380 +#: controllers/CharactersController.inc:385 #: controllers/UsersController.inc:324 views/ajax/characters/index.tpl:14 #: views/ajax/users/index.tpl:14 views/html/characters/index.tpl:41 #: views/html/characters/manage.tpl:37 views/html/characters/manage.tpl:53 @@ -131,6 +131,7 @@ msgstr "Fehler beim Dateiupload: %s" #: views/html/charactergroupsquests/create.tpl:66 #: views/html/charactergroupsquests/edit.tpl:67 #: views/html/charactergroupsquests/manage.tpl:63 +#: views/html/seminaries/create.tpl:60 views/html/seminaries/edit.tpl:62 msgid "Allowed file types" msgstr "Erlaubte Dateiformate" @@ -140,6 +141,7 @@ msgstr "Erlaubte Dateiformate" #: views/html/charactergroupsquests/create.tpl:69 #: views/html/charactergroupsquests/edit.tpl:70 #: views/html/charactergroupsquests/manage.tpl:63 +#: views/html/seminaries/create.tpl:63 views/html/seminaries/edit.tpl:65 #, php-format msgid "%s-files" msgstr "%s-Dateien" @@ -150,6 +152,7 @@ msgstr "%s-Dateien" #: views/html/charactergroupsquests/create.tpl:69 #: views/html/charactergroupsquests/edit.tpl:70 #: views/html/charactergroupsquests/manage.tpl:63 +#: views/html/seminaries/create.tpl:63 views/html/seminaries/edit.tpl:65 msgid "max." msgstr "max." @@ -455,7 +458,7 @@ msgstr "Motto" #: views/html/charactergroupsquests/create.tpl:93 #: views/html/characters/register.tpl:94 views/html/library/create.tpl:46 #: views/html/library/edit.tpl:124 views/html/questgroups/create.tpl:17 -#: views/html/quests/create.tpl:43 views/html/seminaries/create.tpl:14 +#: views/html/quests/create.tpl:43 views/html/seminaries/create.tpl:75 #: views/html/users/create.tpl:96 msgid "create" msgstr "erstellen" @@ -516,7 +519,7 @@ msgstr "%s-Gruppe bearbeiten" #: views/html/charactergroups/editgroup.tpl:83 #: views/html/charactergroups/editgroupsgroup.tpl:50 #: views/html/charactergroupsquests/edit.tpl:94 -#: views/html/characters/edit.tpl:108 +#: views/html/characters/edit.tpl:108 views/html/seminaries/edit.tpl:77 msgid "edit" msgstr "bearbeiten" @@ -609,6 +612,7 @@ msgstr "Neue %s-Quest" #: views/html/charactergroupsquests/edit.tpl:34 #: views/html/library/create.tpl:22 views/html/library/edit.tpl:22 #: views/html/library/edit.tpl:62 views/html/library/edit.tpl:100 +#: views/html/seminaries/create.tpl:30 views/html/seminaries/edit.tpl:32 #, php-format msgid "Title is too short (min. %d chars)" msgstr "Der Titel ist zu kurz (min. %d Zeichen)" @@ -617,6 +621,7 @@ msgstr "Der Titel ist zu kurz (min. %d Zeichen)" #: views/html/charactergroupsquests/edit.tpl:36 #: views/html/library/create.tpl:24 views/html/library/edit.tpl:24 #: views/html/library/edit.tpl:64 views/html/library/edit.tpl:102 +#: views/html/seminaries/create.tpl:32 views/html/seminaries/edit.tpl:34 #, php-format msgid "Title is too long (max. %d chars)" msgstr "Der Titel ist zu lang (max. %d Zeichen)" @@ -625,6 +630,7 @@ msgstr "Der Titel ist zu lang (max. %d Zeichen)" #: views/html/charactergroupsquests/edit.tpl:38 #: views/html/library/create.tpl:26 views/html/library/edit.tpl:26 #: views/html/library/edit.tpl:66 views/html/library/edit.tpl:104 +#: views/html/seminaries/create.tpl:34 views/html/seminaries/edit.tpl:36 msgid "Title contains illegal characters" msgstr "Der Titel enthält ungültige Zeichen" @@ -632,6 +638,7 @@ msgstr "Der Titel enthält ungültige Zeichen" #: views/html/charactergroupsquests/edit.tpl:40 #: views/html/library/create.tpl:28 views/html/library/edit.tpl:28 #: views/html/library/edit.tpl:68 views/html/library/edit.tpl:106 +#: views/html/seminaries/create.tpl:36 views/html/seminaries/edit.tpl:38 msgid "Title already exists" msgstr "Der Titel existiert bereits" @@ -639,6 +646,7 @@ msgstr "Der Titel existiert bereits" #: views/html/charactergroupsquests/edit.tpl:42 #: views/html/library/create.tpl:30 views/html/library/edit.tpl:30 #: views/html/library/edit.tpl:70 views/html/library/edit.tpl:108 +#: views/html/seminaries/create.tpl:38 views/html/seminaries/edit.tpl:40 msgid "Title invalid" msgstr "Der Titel ist ungültig" @@ -666,8 +674,8 @@ msgstr "Die XP-Angabe ist ungültig" #: views/html/library/edit.tpl:43 views/html/library/edit.tpl:44 #: views/html/library/edit.tpl:121 views/html/library/edit.tpl:122 #: views/html/questgroups/create.tpl:14 views/html/questgroups/create.tpl:15 -#: views/html/seminaries/create.tpl:11 views/html/seminaries/create.tpl:12 -#: views/html/seminaries/edit.tpl:13 views/html/seminaries/edit.tpl:14 +#: views/html/seminaries/create.tpl:68 views/html/seminaries/create.tpl:69 +#: views/html/seminaries/edit.tpl:70 views/html/seminaries/edit.tpl:71 msgid "Title" msgstr "Titel" @@ -682,6 +690,8 @@ msgstr "Questgruppe" #: views/html/charactergroupsquests/edit.tpl:85 #: views/html/charactergroupsquests/edit.tpl:86 #: views/html/charactergroupsquests/quest.tpl:45 +#: views/html/seminaries/create.tpl:72 views/html/seminaries/create.tpl:73 +#: views/html/seminaries/edit.tpl:74 views/html/seminaries/edit.tpl:75 msgid "Description" msgstr "Beschreibung" @@ -735,7 +745,7 @@ msgstr "Die Datei ist ungültig" #: views/html/charactergroupsquests/manage.tpl:66 #: views/html/library/edit.tpl:46 views/html/library/edit.tpl:86 -#: views/html/seminaries/edit.tpl:16 views/html/users/edit.tpl:103 +#: views/html/users/edit.tpl:103 msgid "save" msgstr "speichern" @@ -1122,6 +1132,42 @@ msgstr "eingereicht" msgid "New seminary" msgstr "Neuer Kurs" +#: views/html/seminaries/create.tpl:19 views/html/seminaries/edit.tpl:21 +#, php-format +msgid "Error during moodpic upload: %s" +msgstr "Fehler beim Upload des Stimmungsbildes: %s" + +#: views/html/seminaries/create.tpl:21 views/html/seminaries/edit.tpl:23 +#, php-format +msgid "Moodpic has wrong type “%s”" +msgstr "Der Dateityp „%s“ ist für Stimmungsbilder nicht erlaubt" + +#: views/html/seminaries/create.tpl:23 views/html/seminaries/edit.tpl:25 +msgid "Moodpic exceeds size maximum" +msgstr "Das Stimmungsbild ist zu groß" + +#: views/html/seminaries/create.tpl:25 views/html/seminaries/edit.tpl:27 +msgid "Moodpic invalid" +msgstr "Das Stimmungsbild ist ungültig" + +#: views/html/seminaries/create.tpl:43 views/html/seminaries/edit.tpl:45 +#, php-format +msgid "Course is too long (max. %d chars)" +msgstr "Der Kurs ist zu lang (max. %d Zeichen)" + +#: views/html/seminaries/create.tpl:45 views/html/seminaries/edit.tpl:47 +msgid "Course invalid" +msgstr "Das Kurs ist ungültig" + +#: views/html/seminaries/create.tpl:58 views/html/seminaries/edit.tpl:60 +msgid "Moodpic" +msgstr "Stimmungsbild" + +#: views/html/seminaries/create.tpl:70 views/html/seminaries/create.tpl:71 +#: views/html/seminaries/edit.tpl:72 views/html/seminaries/edit.tpl:73 +msgid "Course" +msgstr "Kurs" + #: views/html/seminaries/delete.tpl:10 views/html/seminaries/seminary.tpl:10 msgid "Delete seminary" msgstr "Kurs löschen" diff --git a/models/MediaModel.inc b/models/MediaModel.inc index 08823bab..c1cdf6c7 100644 --- a/models/MediaModel.inc +++ b/models/MediaModel.inc @@ -135,6 +135,45 @@ } + /** + * 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 Quests media by creating a new Seminarymedia and * adding it to the list of Quests media. diff --git a/models/SeminariesModel.inc b/models/SeminariesModel.inc index e31cdce7..fe734fba 100644 --- a/models/SeminariesModel.inc +++ b/models/SeminariesModel.inc @@ -133,23 +133,49 @@ /** - * Create a new seminary. + * Check if a Seminary title already exists. * - * @param string $title Title of seminary to create - * @param int $userId ID of creating user - * @return int ID of the newly created seminary + * @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 createSeminary($title, $userId) + 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) '. + '(created_user_id, title, url, course, description) '. 'VALUES '. - '(?, ?, ?)', - 'iss', + '(?, ?, ?, ?, ?)', + 'issss', $userId, $title, - \nre\core\Linker::createLinkParam($title) + \nre\core\Linker::createLinkParam($title), + $course, + $description ); @@ -158,21 +184,44 @@ /** - * Edit a seminary. + * Set the moodpic for a Seminary. * - * @throws DatamodelException - * @param int $seminaryId ID of the seminary to delete - * @param string $title New title of seminary + * @param int $seminaryId ID of Seminary to set moodpic for + * @param int $mediaId ID of moodpic media */ - public function editSeminary($seminaryId, $title) + public function setMoodpicForSeminary($seminaryId, $mediaId) { $this->db->query( 'UPDATE seminaries '. - 'SET title = ?, url = ? '. + 'SET seminarymedia_id = ? '. 'WHERE id = ?', - 'ssi', + 'ii', + $mediaId, + $seminaryId + ); + } + + + /** + * Edit a seminary. + * + * @throws DatamodelException + * @param int $seminaryId ID of Seminary to delete + * @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 ); } diff --git a/views/html/seminaries/create.tpl b/views/html/seminaries/create.tpl index 425f2367..a6cb63eb 100644 --- a/views/html/seminaries/create.tpl +++ b/views/html/seminaries/create.tpl @@ -6,10 +6,71 @@