From 28c914a926c26614af2ccecaf8c901687b5906bd Mon Sep 17 00:00:00 2001 From: oliver Date: Sat, 12 Mar 2016 19:19:20 +0100 Subject: [PATCH] add Achievement condition ?qrcode? to trigger Achievements by scanning a QR-code (implements #126) --- controllers/AchievementsController.inc | 20 ++++ controllers/QrController.inc | 75 ++++++++++++- controllers/QrcodesController.inc | 44 +++++++- db/create.sql | 21 ++++ locale/de_DE/LC_MESSAGES/The Legend of Z.mo | Bin 29249 -> 29314 bytes locale/de_DE/LC_MESSAGES/The Legend of Z.po | 69 ++++++------ models/AchievementsModel.inc | 111 ++++++++++++++++++++ views/binary/qrcodes/achievement.tpl | 1 + views/html/achievements/conditions.tpl | 9 +- views/html/achievements/create.tpl | 2 + views/html/achievements/edit.tpl | 2 + views/html/qr/a.tpl | 0 12 files changed, 319 insertions(+), 35 deletions(-) create mode 100644 views/binary/qrcodes/achievement.tpl create mode 100644 views/html/qr/a.tpl diff --git a/controllers/AchievementsController.inc b/controllers/AchievementsController.inc index 9e9f2a5c..66e005d2 100644 --- a/controllers/AchievementsController.inc +++ b/controllers/AchievementsController.inc @@ -693,6 +693,10 @@ case 'achievement': $conditions = $this->Achievements->getAchievementConditionsAchievement($achievement['id']); break; + // QR-Code conditions + case 'qrcode': + $conditions = $this->Achievements->getAchievementConditionsQrcode($achievement['id']); + break; } // Values @@ -809,6 +813,12 @@ ); } break; + // QR-Code conditions + case 'qrcode': + if(array_key_exists($condition['id'], $deletes)) { + $this->Achievements->deleteAchievementConditionQrcode($condition['id']); + } + break; } } @@ -892,6 +902,16 @@ ); } break; + // QR-code conditions + case 'qrcode': + if(array_key_exists('qrcode', $condition)) + { + $this->Achievements->addAchievementConditionQrcode( + $this->Auth->getUserId(), + $achievement['id'] + ); + } + break; } } diff --git a/controllers/QrController.inc b/controllers/QrController.inc index 15c340d1..b335aad1 100644 --- a/controllers/QrController.inc +++ b/controllers/QrController.inc @@ -25,11 +25,84 @@ * * @var array */ - public $models = array('seminaries', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'charactergroupsachievements'); + public $models = array('seminaries', 'achievements', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'charactergroupsachievements'); + /** + * Action: a. + * + * Trigger an Achievement by a hash typically provided via a QR-code. + * + * @param $achievementConditionHash Hash value of QR-code condition of an Achievement + */ + public function a($achievementConditionHash) + { + // Check Achievement condition + $condition = $this->Achievements->getAchievementConditionQrcode( + $achievementConditionHash + ); + if(empty($condition)) { + throw new \nre\exceptions\IdNotFoundException($achievementConditionHash); + } + + // Get Achievement + $achievement = $this->Achievements->getAchievementById($condition['achievement_id']); + + // Get Seminary + $seminary = $this->Seminaries->getSeminaryById($achievement['seminary_id']); + + // Get Character + $character = $this->Characters->getCharacterForUserAndSeminary( + self::$user['id'], + $seminary['id'] + ); + + // Set Achievement achieved + $this->Achievements->setAchievementAchieved( + $achievement['id'], + $character['id'] + ); + + // Add notifications + $this->Notification->addNotification( + \hhu\z\controllers\components\NotificationComponent::TYPE_ACHIEVEMENT, + $achievement['title'], + $this->linker->link( + array( + 'achievements', + 'index', + $seminary['url'] + ), 0, true, null, true, $achievement['url'] + ), + ( + !is_null($achievement['achieved_achievementsmedia_id']) + ? $this->linker->link( + array( + 'media', + 'achievement', + $seminary['url'], + $achievement['url'] + ) + ) + : null + ) + ); + + // Redirect to Character profile + $this->redirect( + $this->linker->link( + array( + 'achievements', + 'index', + $seminary['url'] + ) + ) + ); + } + + /** * Action: cgqs. * diff --git a/controllers/QrcodesController.inc b/controllers/QrcodesController.inc index 256d1650..3598a223 100644 --- a/controllers/QrcodesController.inc +++ b/controllers/QrcodesController.inc @@ -24,7 +24,7 @@ * * @var array */ - public $models = array('seminaries', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'charactergroupsachievements'); + public $models = array('seminaries', 'achievements', 'charactergroups', 'charactergroupsquests', 'charactergroupsqueststations', 'charactergroupsachievements'); @@ -46,6 +46,48 @@ } + /** + * Action: achievement + * + * Display a QR-code for an Achievement. + * + * @throws \nre\exceptions\IdNotFoundException + * @param string $seminaryUrl URL-Title of a Seminary + * @param string $groupsgroupUrl URL-Title of a Character groups-group + * @param string $achievementUrl URL of Achievement + */ + public function achievement($seminaryUrl, $achievementUrl, $size=1) + { + // Get seminary + $seminary = $this->Seminaries->getSeminaryByUrl($seminaryUrl); + + // Get Achievement + $achievement = $this->Achievements->getAchievementByUrl( + $seminary['id'], + $achievementUrl + ); + + // Get condition + $conditions = $this->Achievements->getAchievementConditionsQrcode( + $achievement['id'] + ); + if(empty($conditions)) { + throw new IdNotFoundException($achievementUrl); + } + + // Generate QR-code + $url = $this->linker->link(array('qr', 'a', $conditions[0]['hash']), 0, true, null, true, null, true); + $file = $this->generateQRcode($url, $size); + if(is_null($file)) { + return; + } + + + // Pass data to view + $this->set('file', $file); + } + + /** * Action: charactergroupsqueststation * diff --git a/db/create.sql b/db/create.sql index 2fc813f8..2ceed202 100644 --- a/db/create.sql +++ b/db/create.sql @@ -100,6 +100,27 @@ CREATE TABLE `achievementconditions_date` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `achievementconditions_qrcode` +-- + +DROP TABLE IF EXISTS `achievementconditions_qrcode`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `achievementconditions_qrcode` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_user_id` int(11) NOT NULL, + `achievement_id` int(11) NOT NULL, + `hash` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`id`), + KEY `created_user_id` (`created_user_id`), + KEY `achievement_id` (`achievement_id`), + CONSTRAINT `achievementconditions_qrcode_ibfk_1` FOREIGN KEY (`created_user_id`) REFERENCES `users` (`id`), + CONSTRAINT `achievementconditions_qrcode_ibfk_2` FOREIGN KEY (`achievement_id`) REFERENCES `achievements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `achievementconditions_quest` -- 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 0cf53c8d588bc86717c7d5eb5aad3c3aaf1d126c..edb15af3d48d65abccb4550d5720e4ac24beb242 100644 GIT binary patch delta 7557 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 + 'SELECT id, hash '. + 'FROM achievementconditions_qrcode '. + 'WHERE achievement_id = ?', + 'i', + $achievementId + ); + } + + + /** + * Get QR-code condition for a hash value. + * + * @param string $hash Hash value to get condition for + * @return array QR-code condition or null + */ + public function getAchievementConditionQrcode($hash) + { + $data = $this->db->query( + 'SELECT id, achievement_id, hash '. + 'FROM achievementconditions_qrcode '. + 'WHERE hash = ?', + 's', + $hash + ); + if(!empty($data)) { + return $data[0]; + } + + + return null; + } + + + /** + * Add a new QR-code condition. + * + * @param int $userId ID of creating user + * @param int $achievementId ID of Achievement to add condition to + */ + public function addAchievementConditionQrcode($userId, $achievementId) + { + // Delete all existing QR-codes, we allow only one per Achievement + $this->db->query( + 'DELETE FROM achievementconditions_qrcode WHERE achievement_id = ?', + 'i', + $achievementId + ); + + // Create new QR-code condition + $this->db->query( + 'INSERT INTO achievementconditions_qrcode '. + '(created_user_id, achievement_id, hash) '. + 'VALUES '. + '(?, ?, ?)', + 'iis', + $userId, $achievementId, + \hhu\z\Utils::createRandomHash() + ); + } + + + /** + * Copy all QR-code conditions of an Achievement. + * + * @param int $userId ID of creating user + * @param int $sourceAchievementId ID of Achievement to copy conditions from + * @param int $targetAchievementId ID of Achievement to copy conditions to + */ + public function copyAchievementConditionsQrcode($userId, $sourceAchievementId, $targetAchievementId) + { + $this->db->query( + 'INSERT INTO achievementconditions_qrcode '. + '(created_user_id, achievement_id, hash) '. + 'SELECT ?, ?, ? '. + 'FROM achievementconditions_qrcode '. + 'WHERE achievement_id = ?', + 'iisi', + $userId, $targetAchievementId, + \hhu\z\Utils::createRandomHash(), + $sourceAchievementId + ); + } + + + /** + * Delete a QR-code condition. + * + * @param int $conditionId ID of condition to delete + */ + public function deleteAchievementConditionQrcode($conditionId) + { + $this->db->query('DELETE FROM achievementconditions_qrcode WHERE id = ?', 'i', $conditionId); + } + + /** * Set an Achievement as achieved for a Character. * @@ -1364,6 +1468,13 @@ case 'achievement': $this->copyAchievementConditionsAchievement($userId, $achievement['id'], $achievementIds[$achievement['id']], $achievementIds); break; + case 'qrcode': + $this->copyAchievementConditionsQrcode( + $userId, + $achievement['id'], + $achievementIds[$achievement['id']] + ); + break; } } } diff --git a/views/binary/qrcodes/achievement.tpl b/views/binary/qrcodes/achievement.tpl new file mode 100644 index 00000000..0d6fb0df --- /dev/null +++ b/views/binary/qrcodes/achievement.tpl @@ -0,0 +1 @@ + diff --git a/views/html/achievements/conditions.tpl b/views/html/achievements/conditions.tpl index 8091fe7d..d123cc80 100644 --- a/views/html/achievements/conditions.tpl +++ b/views/html/achievements/conditions.tpl @@ -71,6 +71,10 @@
+ + + +
checked="checked" /> @@ -138,8 +142,9 @@
- - hallo + + +
diff --git a/views/html/achievements/create.tpl b/views/html/achievements/create.tpl index 0dbc3593..3b0f6843 100644 --- a/views/html/achievements/create.tpl +++ b/views/html/achievements/create.tpl @@ -96,6 +96,8 @@ break; case 'achievement': echo _('Achievement conditions Achievement'); break; + case 'qrcode': echo _('QR-Code'); + break; } ?> diff --git a/views/html/achievements/edit.tpl b/views/html/achievements/edit.tpl index bc67eb85..0b719a74 100644 --- a/views/html/achievements/edit.tpl +++ b/views/html/achievements/edit.tpl @@ -102,6 +102,8 @@ break; case 'achievement': echo _('Achievement conditions Achievement'); break; + case 'qrcode': echo _('QR-Code'); + break; } ?> diff --git a/views/html/qr/a.tpl b/views/html/qr/a.tpl new file mode 100644 index 00000000..e69de29b