diff --git a/app/Utils.inc b/app/Utils.inc index d248dee1..a445dcf5 100644 --- a/app/Utils.inc +++ b/app/Utils.inc @@ -78,6 +78,35 @@ return substr($string, 0, $pos); } + + /** + * Send an e‑mail. + * + * @param string $from Sender of mail + * @param mixed $to One (string) or many (array) receivers + * @param string $subject Subject of mail + * @param string $message Message of mail + * @param boolean $html Whether mail should be formatted as HTML or not + * @return Whether mail has been send or not + */ + public static function sendMail($from, $to, $subject, $message, $html=false) + { + // Set receivers + $to = is_array($to) ? implode(',', $to) : $to; + + // Set header + $headers = array(); + $headers[] = 'Content-type: text/'.($html ? 'html' : 'plain').'; charset=UTF-8'; + if(!is_null($from)) { + $headers[] = "From: $from"; + } + $header = implode("\r\n", $headers)."\r\n"; + + + // Send mail + return mail($to, $subject, $message, $header); + } + } ?> diff --git a/configs/AppConfig.inc b/configs/AppConfig.inc index adca33d5..8128f4d2 100644 --- a/configs/AppConfig.inc +++ b/configs/AppConfig.inc @@ -32,7 +32,8 @@ public static $app = array( 'name' => 'The Legend of Z', 'namespace' => 'hhu\\z\\', - 'timeZone' => 'Europe/Berlin' + 'timeZone' => 'Europe/Berlin', + 'mailsender' => 'noreply@zyren.inf-d.de' ); diff --git a/controllers/CharactersController.inc b/controllers/CharactersController.inc index 6299dfe7..8f7e02cf 100644 --- a/controllers/CharactersController.inc +++ b/controllers/CharactersController.inc @@ -199,6 +199,9 @@ // Validate Character properties $validation = $this->Validation->validateParams($this->request->getPostParams(), array('charactername')); $charactername = $this->request->getPostParam('charactername'); + if($this->Characters->characterNameExists($charactername)) { + $validation = $this->Validation->addValidationResult($validation, 'charactername', 'exist', true); + } // Validate type $typeIndex = null; @@ -245,6 +248,9 @@ } } + // Send mail + $this->sendRegistrationMail($charactername); + // Redirect $this->redirect($this->linker->link(array('seminaries'))); } @@ -260,6 +266,31 @@ $this->set('fieldsValidation', $fieldsValidation); } + + + + /** + * Send mail for new Character registration. + * + * @param string $charactername Name of newly registered Character + */ + private function sendRegistrationMail($charactername) + { + $sender = \nre\configs\AppConfig::$app['mailsender']; + if(empty($sender)) { + return; + } + + // Send notification mail to system moderators + $subject = sprintf('new Character registration: %s', $charactername); + $message = sprintf('User “%s” <%s> has registered a new Character “%s” for the Seminary “%s”', self::$user['username'], self::$user['email'], $charactername, self::$seminary['title']); + $moderators = $this->Users->getUsersWithSeminaryRole(self::$seminary['id'], 'moderator'); + foreach($moderators as &$moderator) + { + \hhu\z\Utils::sendMail($sender, $moderator['email'], $subject, $message); + } + } + } ?> diff --git a/controllers/UsersController.inc b/controllers/UsersController.inc index 535dcbbe..90e50912 100644 --- a/controllers/UsersController.inc +++ b/controllers/UsersController.inc @@ -164,9 +164,16 @@ // Get params and validate them $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); $username = $this->request->getPostParam('username'); + if($this->Users->usernameExists($username)) { + $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); + } $prename = $this->request->getPostParam('prename'); $surname = $this->request->getPostParam('surname'); $email = $this->request->getPostParam('email'); + if($this->Users->emailExists($email)) { + $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); + } + // Register if($validation === true) @@ -178,7 +185,10 @@ $email, $this->request->getPostParam('password') ); - + + // Send mail + $this->sendRegistrationMail($username, $email); + // Login $this->Auth->setUserId($userId); $user = $this->Users->getUserById($userId); @@ -323,6 +333,31 @@ } + + + /** + * Send mail for new user registration. + * + * @param string $username Name of newly registered user + * @param string $email E‑mail address of newly registered user + */ + private function sendRegistrationMail($username, $email) + { + $sender = \nre\configs\AppConfig::$app['mailsender']; + if(empty($sender)) { + return; + } + + // Send notification mail to system moderators + $subject = sprintf('new user registration: %s', $username); + $message = sprintf('User “%s” <%s> has registered themself to %s', $username, $email, \nre\configs\AppConfig::$app['name']); + $moderators = $this->Users->getUsersWithRole('moderator'); + foreach($moderators as &$moderator) + { + \hhu\z\Utils::sendMail($sender, $moderator['email'], $subject, $message); + } + } + } ?> diff --git a/controllers/components/ValidationComponent.inc b/controllers/components/ValidationComponent.inc index dbe5b0b3..950d45ed 100644 --- a/controllers/components/ValidationComponent.inc +++ b/controllers/components/ValidationComponent.inc @@ -110,6 +110,31 @@ return $validation; } + + /** + * Add a custom determined validation result to a validation + * store. + * + * @param mixed $validation Validation store to add result to + * @param string $param Name of parameter of the custom validation result + * @param string $setting Name of setting of the custom validation result + * @param mixed $result Validation result + * @return mixed The altered validation store + */ + public function addValidationResult($validation, $param, $setting, $result) + { + if(!is_array($validation)) { + $validation = array(); + } + if(!array_key_exists($param, $validation)) { + $validation[$param] = array(); + } + $validation[$param][$setting] = $result; + + + return $validation; + } + } ?> 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 ea696668..3525bcf5 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 d4860fa3..86648bc7 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-04-16 11:36+0100\n" -"PO-Revision-Date: 2014-04-16 11:36+0100\n" +"POT-Creation-Date: 2014-04-16 13:19+0100\n" +"PO-Revision-Date: 2014-04-16 13:19+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: de_DE\n" @@ -79,12 +79,12 @@ msgid "submitted at %s on %s h" msgstr "eingereicht am %s um %s Uhr" #: questtypes/submit/html/submission.tpl:6 -#: questtypes/submit/html/submission.tpl:8 views/html/quests/quest.tpl:40 +#: questtypes/submit/html/submission.tpl:8 views/html/quests/quest.tpl:46 #: views/html/quests/submissions.tpl:33 msgid "solved" msgstr "gelöst" -#: questtypes/submit/html/submission.tpl:9 views/html/quests/quest.tpl:42 +#: questtypes/submit/html/submission.tpl:9 views/html/quests/quest.tpl:48 #: views/html/quests/submissions.tpl:24 msgid "unsolved" msgstr "ungelöst" @@ -202,31 +202,35 @@ msgid "Character name contains illegal characters" msgstr "Der Charaktername enthält ungültige Zeichen" #: views/html/characters/register.tpl:26 +msgid "Character name already exists" +msgstr "Der Charaktername existiert bereits" + +#: views/html/characters/register.tpl:28 msgid "Character name invalid" msgstr "Der Charaktername ist ungültig" -#: views/html/characters/register.tpl:38 +#: views/html/characters/register.tpl:40 msgid "Character properties" msgstr "Charaktereigenschaften" -#: views/html/characters/register.tpl:39 views/html/characters/register.tpl:40 +#: views/html/characters/register.tpl:41 views/html/characters/register.tpl:42 msgid "Character name" msgstr "Charaktername" -#: views/html/characters/register.tpl:41 +#: views/html/characters/register.tpl:43 msgid "Character type" msgstr "Charaktertyp" -#: views/html/characters/register.tpl:52 +#: views/html/characters/register.tpl:54 #, php-format msgid "The Seminary field “%s” is invalid" msgstr "Das Kursfeld „%s“ ist ungültig" -#: views/html/characters/register.tpl:57 +#: views/html/characters/register.tpl:59 msgid "Seminary fields" msgstr "Kursfelder" -#: views/html/characters/register.tpl:79 views/html/seminaries/create.tpl:14 +#: views/html/characters/register.tpl:81 views/html/seminaries/create.tpl:14 #: views/html/users/create.tpl:17 msgid "create" msgstr "erstellen" @@ -245,7 +249,7 @@ msgstr "Login" #: views/html/users/create.tpl:6 views/html/users/create.tpl:7 #: views/html/users/edit.tpl:6 views/html/users/edit.tpl:7 #: views/html/users/login.tpl:9 views/html/users/login.tpl:10 -#: views/html/users/register.tpl:74 views/html/users/register.tpl:75 +#: views/html/users/register.tpl:78 views/html/users/register.tpl:79 msgid "Username" msgstr "Benutzername" @@ -253,7 +257,7 @@ msgstr "Benutzername" #: views/html/users/create.tpl:14 views/html/users/create.tpl:15 #: views/html/users/edit.tpl:14 views/html/users/edit.tpl:15 #: views/html/users/login.tpl:11 views/html/users/login.tpl:12 -#: views/html/users/register.tpl:82 views/html/users/register.tpl:83 +#: views/html/users/register.tpl:86 views/html/users/register.tpl:87 msgid "Password" msgstr "Passwort" @@ -306,19 +310,19 @@ msgstr "Filter anwenden" msgid "Reset filters" msgstr "Filter zurücksetzen" -#: views/html/quests/quest.tpl:50 +#: views/html/quests/quest.tpl:57 msgid "Task" msgstr "Aufgabe" -#: views/html/quests/quest.tpl:55 +#: views/html/quests/quest.tpl:63 msgid "Task already successfully solved" msgstr "Du hast die Aufgabe bereits erfolgreich gelöst" -#: views/html/quests/quest.tpl:57 +#: views/html/quests/quest.tpl:66 msgid "Show answer" msgstr "Lösung anzeigen" -#: views/html/quests/quest.tpl:71 views/html/quests/quest.tpl:80 +#: views/html/quests/quest.tpl:79 views/html/quests/quest.tpl:88 msgid "Quest" msgstr "Quest" @@ -406,19 +410,19 @@ msgstr "Neuer Benutzer" #: views/html/users/create.tpl:8 views/html/users/create.tpl:9 #: views/html/users/edit.tpl:8 views/html/users/edit.tpl:9 -#: views/html/users/register.tpl:76 views/html/users/register.tpl:77 +#: views/html/users/register.tpl:80 views/html/users/register.tpl:81 msgid "Prename" msgstr "Vorname" #: views/html/users/create.tpl:10 views/html/users/create.tpl:11 #: views/html/users/edit.tpl:10 views/html/users/edit.tpl:11 -#: views/html/users/register.tpl:78 views/html/users/register.tpl:79 +#: views/html/users/register.tpl:82 views/html/users/register.tpl:83 msgid "Surname" msgstr "Nachname" #: views/html/users/create.tpl:12 views/html/users/create.tpl:13 #: views/html/users/edit.tpl:12 views/html/users/edit.tpl:13 -#: views/html/users/register.tpl:80 views/html/users/register.tpl:81 +#: views/html/users/register.tpl:84 views/html/users/register.tpl:85 #: views/html/users/user.tpl:12 msgid "E‑mail address" msgstr "E‑Mail-Adresse" @@ -468,66 +472,74 @@ msgid "Username contains illegal characters" msgstr "Der Benutzername enthält ungültige Zeichen" #: views/html/users/register.tpl:20 +msgid "Username already exists" +msgstr "Der Benutzername existiert bereits" + +#: views/html/users/register.tpl:22 msgid "Username invalid" msgstr "Der Benutzername ist ungültig" -#: views/html/users/register.tpl:25 +#: views/html/users/register.tpl:27 #, php-format msgid "Prename is too short (min. %d chars)" msgstr "Der Vorname ist zu kurz (min. %d Zeichen)" -#: views/html/users/register.tpl:27 +#: views/html/users/register.tpl:29 #, php-format msgid "Prename is too long (max. %d chars)" msgstr "Der Vorname ist zu lang (max. %d Zeichen)" -#: views/html/users/register.tpl:29 +#: views/html/users/register.tpl:31 #, php-format msgid "Prename contains illegal characters" msgstr "Der Vorname enthält ungültige Zeichen" -#: views/html/users/register.tpl:31 +#: views/html/users/register.tpl:33 msgid "Prename invalid" msgstr "Der Vorname ist ungültig" -#: views/html/users/register.tpl:36 +#: views/html/users/register.tpl:38 #, php-format msgid "Surname is too short (min. %d chars)" msgstr "Der Nachname ist zu kurz (min. %d Zeichen)" -#: views/html/users/register.tpl:38 +#: views/html/users/register.tpl:40 #, php-format msgid "Surname is too long (max. %d chars)" msgstr "Der Nachname ist zu lang (max. %d Zeichen)" -#: views/html/users/register.tpl:40 +#: views/html/users/register.tpl:42 #, php-format msgid "Surname contains illegal characters" msgstr "Der Nachname enthält ungültige Zeichen" -#: views/html/users/register.tpl:42 +#: views/html/users/register.tpl:44 msgid "Surname invalid" msgstr "Der Nachname ist ungültig" -#: views/html/users/register.tpl:47 views/html/users/register.tpl:49 +#: views/html/users/register.tpl:49 views/html/users/register.tpl:53 msgid "E‑mail address invalid" msgstr "Die E‑Mail-Adresse ist ungültig" -#: views/html/users/register.tpl:54 +#: views/html/users/register.tpl:51 +msgid "E‑mail address already exists" +msgstr "E‑Mail-Adresse existiert bereits" + +#: views/html/users/register.tpl:58 #, php-format msgid "Password is too short (min. %d chars)" msgstr "Das Passwort ist zu kurz (min. %d Zeichen)" -#: views/html/users/register.tpl:56 +#: views/html/users/register.tpl:60 #, php-format msgid "Password is too long (max. %d chars)" msgstr "Das Passwort ist zu lang (max. %d Zeichen)" -#: views/html/users/register.tpl:58 +#: views/html/users/register.tpl:62 msgid "Password invalid" msgstr "Das Passwort ist ungültig" -#: views/html/users/register.tpl:85 +#: views/html/users/register.tpl:89 msgid "Register" msgstr "Registrieren" diff --git a/models/CharactersModel.inc b/models/CharactersModel.inc index a409ef0d..7b27da8d 100644 --- a/models/CharactersModel.inc +++ b/models/CharactersModel.inc @@ -390,6 +390,31 @@ } + /** + * Check if a Character name already exists. + * + * @param string $name Character name to check + * @return boolean Whether Character name exists or not + */ + public function characterNameExists($name) + { + $data = $this->db->query( + 'SELECT count(id) AS c '. + 'FROM characters '. + 'WHERE name = ? OR url = ?', + 'ss', + $name, + \nre\core\Linker::createLinkParam($name) + ); + if(!empty($data)) { + return ($data[0]['c'] > 0); + } + + + return false; + } + + /** * Create a new Character. * diff --git a/models/UsersModel.inc b/models/UsersModel.inc index 88a7ed2d..c773a0b5 100644 --- a/models/UsersModel.inc +++ b/models/UsersModel.inc @@ -49,6 +49,49 @@ } + /** + * 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 '. + '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 users with the given user Seminary role. + * + * @param int $seminaryId ID of Seminary + * @param string $userseminaryrole User Seminary role + * @return array List of users + */ + public function getUsersWithSeminaryRole($seminaryId, $userseminaryrole) + { + return $this->db->query( + 'SELECT users.id, users.created, users.username, users.url, users.surname, users.prename, users.email '. + 'FROM users '. + 'LEFT JOIN users_userseminaryroles ON users_userseminaryroles.user_id = users.id '. + 'LEFT JOIN userseminaryroles ON userseminaryroles.id = users_userseminaryroles.userseminaryrole_id '. + 'WHERE users_userseminaryroles.seminary_id = ? AND userseminaryroles.name = ? '. + 'ORDER BY username ASC', + 'is', + $seminaryId, $userseminaryrole + ); + } + + /** * Get a user and its data by its ID. * @@ -124,6 +167,55 @@ } + /** + * Check if an username already exists. + * + * @param string $username Username to check + * @return boolean Whether username exists or not + */ + public function usernameExists($username) + { + $data = $this->db->query( + 'SELECT count(id) AS c '. + 'FROM users '. + 'WHERE username = ? OR url = ?', + 'ss', + $username, + \nre\core\Linker::createLinkParam($username) + ); + if(!empty($data)) { + return ($data[0]['c'] > 0); + } + + + return false; + } + + + /** + * Check if an e‑mail address already exists. + * + * @param string $email E‑mail address to check + * @return boolean Whether e‑mail address exists or not + */ + public function emailExists($email) + { + $data = $this->db->query( + 'SELECT count(id) AS c '. + 'FROM users '. + 'WHERE email = ?', + 's', + $email + ); + if(!empty($data)) { + return ($data[0]['c'] > 0); + } + + + return false; + } + + /** * Create a new user. * diff --git a/views/html/characters/register.tpl b/views/html/characters/register.tpl index 15317277..d62c0d35 100644 --- a/views/html/characters/register.tpl +++ b/views/html/characters/register.tpl @@ -23,6 +23,8 @@ break; case 'regex': echo _('Character name contains illegal characters'); break; + case 'exist': echo _('Character name already exists'); + break; default: echo _('Character name invalid'); } break; diff --git a/views/html/users/register.tpl b/views/html/users/register.tpl index 184e0a0c..20cbfc63 100644 --- a/views/html/users/register.tpl +++ b/views/html/users/register.tpl @@ -17,6 +17,8 @@ break; case 'regex': echo _('Username contains illegal characters'); break; + case 'exist': echo _('Username already exists'); + break; default: echo _('Username invalid'); } break; @@ -46,6 +48,8 @@ switch($setting) { case 'regex': echo _('E‑mail address invalid'); break; + case 'exist': echo _('E‑mail address already exists'); + break; default: echo _('E‑mail address invalid'); } break;