From 6b9556addb5dfaeb42eb1b81af929e0efb5f0167 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 15 Feb 2024 12:42:41 +0100 Subject: [PATCH 01/17] Verify Sub on server side --- classes/external.php | 4 +-- classes/mooduell.php | 83 ++++++++++++++++++++++++++++++++++++++++++++ test.php | 44 +++++++++++++++++++++++ 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 test.php diff --git a/classes/external.php b/classes/external.php index c22a016..71ada51 100644 --- a/classes/external.php +++ b/classes/external.php @@ -375,11 +375,11 @@ public static function get_mooduell_purchases_returns() { 'purchases' => new external_multiple_structure(new external_single_structure( [ 'id' => new external_value(PARAM_INT, 'id'), - 'productid' => new external_value(PARAM_INT, 'productid'), + 'productid' => new external_value(PARAM_TEXT, 'productid'), 'purchasetoken' => new external_value(PARAM_TEXT, 'purchasetoken'), 'receipt' => new external_value(PARAM_TEXT, 'receipt', VALUE_OPTIONAL, ''), 'signature' => new external_value(PARAM_TEXT, 'signature', VALUE_OPTIONAL, ''), - 'orderid' => new external_value(PARAM_INT, 'orderid', VALUE_OPTIONAL, ''), + 'orderid' => new external_value(PARAM_TEXT, 'orderid', VALUE_OPTIONAL, ''), 'free' => new external_value(PARAM_INT, 'free', VALUE_OPTIONAL, 0), 'userid' => new external_value(PARAM_INT, 'userid'), 'mooduellid' => new external_value(PARAM_INT, 'mooduellid', VALUE_OPTIONAL, 0), diff --git a/classes/mooduell.php b/classes/mooduell.php index fca0a0d..a8688a8 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -418,6 +418,88 @@ private function return_list_of_questions() { } return $listofquestions; } + + public static function update_all_subscriptions() { + + global $DB, $CFG; + + // Get Subscriptions. + list($insqlplatform, $inparams1) = $DB->get_in_or_equal($CFG->wwwroot); + list($insqlproduct, $inparams2) = $DB->get_in_or_equal('unlockplatformsubscription'); + + $params = array_merge($inparams1, $inparams2); + + $sql = "SELECT * FROM {mooduell_purchase} + WHERE platformid $insqlplatform + AND productid $insqlproduct"; + + $allpurchases = $DB->get_records_sql($sql, $params); + foreach ($allpurchases as $returnitem) { + $result = self::verify_purchase($returnitem); + + // Logic to determine if subscription is okay or not + // Request was ok. + if ($result->ok === true) { + $allproductsinreceipt = $result->data->collection; + foreach ($allproductsinreceipt as $singleproduct) { + if ($singleproduct->id === 'unlockplatformsubscription') { + // Subscription item. + if ($singleproduct->isExpired === false) { + // Extend validity. + return; + } else if ($singleproduct->isExpired === true) { + // Delete Cancel etc. + $udpatedentry = $returnitem; + $udpatedentry->productid = 'notvalid'; + $DB->update_record('mooduell_purchase', $udpatedentry); + } + } + } + } else { + // Failed verification. + return; + } + } + } + + public static function verify_purchase($purchase) { + if ($purchase->store === 'ios') { + $payload = array( + 'id' => 'at.wunderbyte.mooduellapp', + 'type' => 'application', + 'transaction' => array( + 'id' => 'at.wunderbyte.mooduellapp', + 'type' => 'ios-appstore', + 'appStoreReceipt' => $purchase->purchasetoken + ) + ); + } else { + $payload = array( + ); + } + + $url = "https://validator.iaptic.com/v1/validate"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); + curl_setopt($ch, CURLOPT_HTTPHEADER, + array( + "Authorization: Basic " . base64_encode('at.wunderbyte.mooduellapp:4575a924-9af6-4a88-95d1-9c80aa1444b1'), + "Content-Type: application/json" + )); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $responsedata = curl_exec($ch); + if (curl_errno($ch)) { + return curl_error($ch); + } + curl_close($ch); + return json_decode($responsedata); + } + + + /** * Returns List of relevant Purchases * @@ -442,6 +524,7 @@ public static function get_purchases($courses, $quizzes) { $returnitems = ['purchases' => []]; return $returnitems; } + list($insqlcourses, $inparams) = $DB->get_in_or_equal($courseids); list($insqlquizzes, $inparams2) = $DB->get_in_or_equal($quizids); list($insqlplatform, $inparams3) = $DB->get_in_or_equal($CFG->wwwroot); diff --git a/test.php b/test.php new file mode 100644 index 0000000..864b172 --- /dev/null +++ b/test.php @@ -0,0 +1,44 @@ +. + +/** + * @package mod_mooduell + * @copyright 2024 Wunderbyte GmbH + * @author Chrsitian Badusch + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../../config.php'); + +use mod_mooduell\mooduell; + +$context = \context_system::instance(); +$PAGE->set_context($context); +require_login(); + +$PAGE->set_pagelayout('standard'); +$title = "MooDuell Testpage"; +$PAGE->set_title($title); +$PAGE->set_url('/test.php'); +$PAGE->set_heading($title); + +echo $OUTPUT->header(); + +$mooduell = new mooduell(2); + +$mooduell->update_all_subscriptions(); + +echo $OUTPUT->footer(); From be4144964b297993b31239f2675586b4bff16a3d Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 15 Feb 2024 13:45:48 +0100 Subject: [PATCH 02/17] Improve test.php --- test.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test.php b/test.php index 864b172..ba41679 100644 --- a/test.php +++ b/test.php @@ -25,6 +25,8 @@ use mod_mooduell\mooduell; + +$mooduellid = required_param('mooduellid', PARAM_RAW); $context = \context_system::instance(); $PAGE->set_context($context); require_login(); @@ -36,8 +38,8 @@ $PAGE->set_heading($title); echo $OUTPUT->header(); - -$mooduell = new mooduell(2); + // Create mooduell instance. +$mooduell = new mooduell($mooduellid); $mooduell->update_all_subscriptions(); From 88d36eac998b0678a37295b3a4157e2cc9a917e3 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 15 Feb 2024 13:53:33 +0100 Subject: [PATCH 03/17] cmid for test.php --- test.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test.php b/test.php index ba41679..c49fc41 100644 --- a/test.php +++ b/test.php @@ -26,8 +26,8 @@ use mod_mooduell\mooduell; -$mooduellid = required_param('mooduellid', PARAM_RAW); -$context = \context_system::instance(); +$cmid = required_param('cmid', PARAM_RAW); +// $context = \context_system::instance(); $PAGE->set_context($context); require_login(); @@ -38,8 +38,10 @@ $PAGE->set_heading($title); echo $OUTPUT->header(); +$context = \context_module::instance($cmid); + // Create mooduell instance. -$mooduell = new mooduell($mooduellid); +$mooduell = new mooduell($context->cm->instanceid); $mooduell->update_all_subscriptions(); From 6ec599baf2e6fe2c2e16ed4866ab91287970dd13 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 15 Feb 2024 13:54:51 +0100 Subject: [PATCH 04/17] fixed test.php --- test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test.php b/test.php index c49fc41..f1b3776 100644 --- a/test.php +++ b/test.php @@ -25,11 +25,12 @@ use mod_mooduell\mooduell; - +require_login(); $cmid = required_param('cmid', PARAM_RAW); // $context = \context_system::instance(); +$context = \context_module::instance($cmid); $PAGE->set_context($context); -require_login(); + $PAGE->set_pagelayout('standard'); $title = "MooDuell Testpage"; @@ -38,7 +39,6 @@ $PAGE->set_heading($title); echo $OUTPUT->header(); -$context = \context_module::instance($cmid); // Create mooduell instance. $mooduell = new mooduell($context->cm->instanceid); From f3d95eb811e50463dc04a1f8f22baa322f115dfe Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 15 Feb 2024 14:24:49 +0100 Subject: [PATCH 05/17] test.php changes --- test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test.php b/test.php index f1b3776..fcb3784 100644 --- a/test.php +++ b/test.php @@ -26,9 +26,9 @@ use mod_mooduell\mooduell; require_login(); -$cmid = required_param('cmid', PARAM_RAW); +$cmid = required_param('cmid', PARAM_INT); // $context = \context_system::instance(); -$context = \context_module::instance($cmid); +$context = \context_system::instance(); $PAGE->set_context($context); @@ -41,7 +41,7 @@ echo $OUTPUT->header(); // Create mooduell instance. -$mooduell = new mooduell($context->cm->instanceid); +$mooduell = new mooduell($cmid); $mooduell->update_all_subscriptions(); From 052e156af06b4a9aa8afe743485d2e86d1d02061 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Mon, 19 Feb 2024 13:06:31 +0100 Subject: [PATCH 06/17] check_subscription as daily task --- classes/task/update_subscription_task.php | 47 +++++++++++++++++++++++ db/tasks.php | 36 +++++++++++++++++ lang/de/mooduell.php | 2 + lang/en/mooduell.php | 2 + test.php | 17 ++++---- version.php | 2 +- 6 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 classes/task/update_subscription_task.php create mode 100644 db/tasks.php diff --git a/classes/task/update_subscription_task.php b/classes/task/update_subscription_task.php new file mode 100644 index 0000000..1e9bf6a --- /dev/null +++ b/classes/task/update_subscription_task.php @@ -0,0 +1,47 @@ +. + +/** + * update subscription task for mooduell + * + * @package mod_mooduell + * @copyright 2024 Christian Badusch + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_mooduell\task; +use mod_mooduell\mooduell; + +class update_subscription_task extends \core\task\scheduled_task { + + public function get_name() { + return get_string('updatesubscription', 'mod_mooduell'); + } + + public function execute() { + global $DB; + + $mooduell = $DB->get_record('modules', ['name' => 'mooduell']); + if ($mooduell) { + $mooduellid = $DB->get_record('course_modules', ['module' => $mooduell->id]); + if ($mooduellid) { + $mooduellinstance = new mooduell($mooduellid->id); + $mooduellinstance->update_all_subscriptions(); + } + + } + } +} diff --git a/db/tasks.php b/db/tasks.php new file mode 100644 index 0000000..da5ce26 --- /dev/null +++ b/db/tasks.php @@ -0,0 +1,36 @@ +. + +/** + * Mooduell module scheduled tasks definition + * + * @package mod_mooduell + * @copyright 2024 Christian Badusch + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$tasks = [ + ['classname' => 'mod_mooduell\task\update_subscription_task', + 'blocking' => 0, + 'minute' => '30', + 'hour' => '7', + 'day' => '*', + 'dayofweek' => '*', + 'month' => '*', + ], +]; diff --git a/lang/de/mooduell.php b/lang/de/mooduell.php index 04102fe..241fc08 100755 --- a/lang/de/mooduell.php +++ b/lang/de/mooduell.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +$string['updatesubscription'] = "Subscription status prüfen"; + $string['disablesbadges'] = 'Disble Badges'; $string['theme'] = 'Theme'; $string['themedesc'] = 'Theme für die App im JSON Format'; diff --git a/lang/en/mooduell.php b/lang/en/mooduell.php index dd44d89..c6c9290 100755 --- a/lang/en/mooduell.php +++ b/lang/en/mooduell.php @@ -25,6 +25,8 @@ defined('MOODLE_INTERNAL') || die(); +$string['updatesubscription'] = "Check subscription status"; + $string['disablesbadges'] = 'Auszeichnungen deaktivieren'; $string['theme'] = 'Theme'; $string['themedesc'] = 'Theme in JSON format'; diff --git a/test.php b/test.php index fcb3784..c068d42 100644 --- a/test.php +++ b/test.php @@ -26,11 +26,19 @@ use mod_mooduell\mooduell; require_login(); -$cmid = required_param('cmid', PARAM_INT); -// $context = \context_system::instance(); + $context = \context_system::instance(); $PAGE->set_context($context); +$mooduell = $DB->get_record('modules', ['name' => 'mooduell']); +if ($mooduell) { + $mooduellid = $DB->get_record('course_modules', ['module' => $mooduell->id]); + if ($mooduellid) { + $mooduellinstance = new mooduell($mooduellid->id); + $mooduellinstance->update_all_subscriptions(); + } + +} $PAGE->set_pagelayout('standard'); $title = "MooDuell Testpage"; @@ -40,9 +48,4 @@ echo $OUTPUT->header(); - // Create mooduell instance. -$mooduell = new mooduell($cmid); - -$mooduell->update_all_subscriptions(); - echo $OUTPUT->footer(); diff --git a/version.php b/version.php index ce2fed7..f816f81 100755 --- a/version.php +++ b/version.php @@ -26,7 +26,7 @@ $plugin->component = 'mod_mooduell'; $plugin->release = 'v2.1.5'; -$plugin->version = 2024020900; +$plugin->version = 2024021907; $plugin->requires = 2020061500; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ From 641aca8a0144f5c13b18dc22e2133a5cb9725635 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Mon, 19 Feb 2024 15:46:20 +0100 Subject: [PATCH 07/17] Linting --- classes/mooduell.php | 31 +++++++++++++++-------- classes/task/update_subscription_task.php | 13 ++++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index a8688a8..1970998 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -419,6 +419,11 @@ private function return_list_of_questions() { return $listofquestions; } + /** + * Updates the platform subscription. + * + * + */ public static function update_all_subscriptions() { global $DB, $CFG; @@ -462,20 +467,25 @@ public static function update_all_subscriptions() { } } + /** + * verifies a single + * + * @param mixed $purchase + * @return object + */ public static function verify_purchase($purchase) { if ($purchase->store === 'ios') { - $payload = array( + $payload = [ 'id' => 'at.wunderbyte.mooduellapp', 'type' => 'application', - 'transaction' => array( + 'transaction' => [ 'id' => 'at.wunderbyte.mooduellapp', 'type' => 'ios-appstore', - 'appStoreReceipt' => $purchase->purchasetoken - ) - ); + 'appStoreReceipt' => $purchase->purchasetoken, + ], + ]; } else { - $payload = array( - ); + $payload = []; } $url = "https://validator.iaptic.com/v1/validate"; @@ -483,12 +493,11 @@ public static function verify_purchase($purchase) { curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, - array( + [ "Authorization: Basic " . base64_encode('at.wunderbyte.mooduellapp:4575a924-9af6-4a88-95d1-9c80aa1444b1'), - "Content-Type: application/json" - )); + "Content-Type: application/json", + ]); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); - // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $responsedata = curl_exec($ch); if (curl_errno($ch)) { diff --git a/classes/task/update_subscription_task.php b/classes/task/update_subscription_task.php index 1e9bf6a..f123d22 100644 --- a/classes/task/update_subscription_task.php +++ b/classes/task/update_subscription_task.php @@ -25,12 +25,25 @@ namespace mod_mooduell\task; use mod_mooduell\mooduell; +/** + * update_subscription_task + */ class update_subscription_task extends \core\task\scheduled_task { + /** + * Returns the taskname. + * + * @return string + */ public function get_name() { return get_string('updatesubscription', 'mod_mooduell'); } + /** + * Executes the task and checks the subscription. + * + * @return void + */ public function execute() { global $DB; From 4d222d8ffb3307cbfaa6ca8d7c1615deb4b35af2 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Tue, 20 Feb 2024 12:22:27 +0100 Subject: [PATCH 08/17] do not return subscription if not valid --- classes/mooduell.php | 7 ++++--- classes/task/update_subscription_task.php | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index 1970998..5ee3366 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -468,12 +468,13 @@ public static function update_all_subscriptions() { } /** - * verifies a single + * Verifies a single purchase. * * @param mixed $purchase * @return object */ public static function verify_purchase($purchase) { + // If sub has been purchases on ios. if ($purchase->store === 'ios') { $payload = [ 'id' => 'at.wunderbyte.mooduellapp', @@ -541,10 +542,10 @@ public static function get_purchases($courses, $quizzes) { $params = array_merge($inparams, $inparams2, $inparams3); $sql = "SELECT * FROM {mooduell_purchase} - WHERE userid = {$userid} + WHERE userid = {$userid} AND NOT productid = 'notvalid' OR courseid $insqlcourses OR mooduellid $insqlquizzes AND ispublic = 1 - OR platformid $insqlplatform"; + OR platformid $insqlplatform AND NOT productid = 'notvalid'"; $returnitems = ['purchases' => $DB->get_records_sql($sql, $params)]; return $returnitems; diff --git a/classes/task/update_subscription_task.php b/classes/task/update_subscription_task.php index f123d22..034ff5a 100644 --- a/classes/task/update_subscription_task.php +++ b/classes/task/update_subscription_task.php @@ -54,7 +54,6 @@ public function execute() { $mooduellinstance = new mooduell($mooduellid->id); $mooduellinstance->update_all_subscriptions(); } - } } } From ad8a79bc9cea4d7672b7b60fdf8c81d18f8a4fff Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 21 Feb 2024 12:21:52 +0100 Subject: [PATCH 09/17] Android Verify payload --- classes/mooduell.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classes/mooduell.php b/classes/mooduell.php index 5ee3366..40030c5 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -462,6 +462,12 @@ public static function update_all_subscriptions() { } } else { // Failed verification. + // Android expired. + if ($result->code === 6778003) { + $udpatedentry = $returnitem; + $udpatedentry->productid = 'notvalid'; + $DB->update_record('mooduell_purchase', $udpatedentry); + } return; } } From ea20cbd9f5b5e63df921933773f6235a99ae376b Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 21 Feb 2024 13:04:52 +0100 Subject: [PATCH 10/17] fixed payload for android verify --- classes/mooduell.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index 40030c5..8fb5811 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -492,7 +492,17 @@ public static function verify_purchase($purchase) { ], ]; } else { - $payload = []; + $payload = [ + 'id' => $purchase->productid, + 'type' => $purchase->productid === 'unlockplatformsubscription' ? 'paid subscription' : 'consumeable', + 'transaction' => [ + 'type' => 'android-playstore', + 'id' => $purchase->orderid, + 'purchaseToken' => $purchase->purchasetoken, + 'signature' => $purchase->signature, + 'receipt' => $purchase->receipt, + ], + ]; } $url = "https://validator.iaptic.com/v1/validate"; From af140285361a08fbe62e83656efc933de5e63d6f Mon Sep 17 00:00:00 2001 From: cbadusch Date: Thu, 29 Feb 2024 13:53:58 +0100 Subject: [PATCH 11/17] Addling License Key --- classes/external.php | 3 +- classes/mooduell.php | 3 +- classes/utils/wb_payment.php | 114 +++++++++++++++++++++++++++++++++++ lang/de/mooduell.php | 7 +++ lang/en/mooduell.php | 7 +++ settings.php | 48 +++++++++++++-- 6 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 classes/utils/wb_payment.php diff --git a/classes/external.php b/classes/external.php index 71ada51..1d11d80 100644 --- a/classes/external.php +++ b/classes/external.php @@ -27,6 +27,7 @@ use mod_mooduell\manage_tokens; use mod_mooduell\mooduell; use mod_mooduell\completion\completion_utils; +use mod_mooduell\utils\wb_payment; defined('MOODLE_INTERNAL') || die(); @@ -298,7 +299,7 @@ public static function get_quizzes_with_caps_parameters() { public static function get_mooduell_support() { global $DB; $url = get_config('mooduell', 'supporturl'); - $pay = get_config('mooduell', 'unlockplatform'); + $pay = wb_payment::pro_version_is_activated(); $badges = get_config('mooduell', 'disablebadges'); $themeimg = get_config('mod_mooduell', 'companylogo'); $themeimgalt = get_config('mod_mooduell', 'companylogoalternative'); diff --git a/classes/mooduell.php b/classes/mooduell.php index 8fb5811..3e8d08f 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -580,8 +580,9 @@ public static function purchase_item($purchase) { case 'unlockplatformsubscription': if ($purchase['store'] == 'ios') { // Ios. + $purchasetokenformatted = str_replace('~', '+', $purchase['purchasetoken']); $existingsub = $DB->get_records('mooduell_purchase', [ - 'productid' => $purchase['productid'], + 'purchasetoken' => $purchasetokenformatted, 'store' => 'ios', ]); } else { diff --git a/classes/utils/wb_payment.php b/classes/utils/wb_payment.php new file mode 100644 index 0000000..2cff08e --- /dev/null +++ b/classes/utils/wb_payment.php @@ -0,0 +1,114 @@ +. + +/** + * Wunderbyte Payment Methods. + * + * Contains methods for license verification and more. + * + * @package mod_mooduell + * @copyright 2023 Wunderbyte GmbH + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_mooduell\utils; + +use stdClass; + +/** + * Class to handle Wunderbyte Payment Methods. + * + * Contains methods for license verification and more. + * + * @package mod_mooduell + * @copyright 2023 Wunderbyte GmbH + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class wb_payment { + + /** + * mod_mooduell_PUBLIC_KEY + * + * @var mixed + */ + const mod_mooduell_PUBLIC_KEY = "-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8vRBnPDug2pKoGY9wQS +KNTK1SzrPuU0KC8xm22GPQZQM1XkPpvNwBp8CmXUN29r/qiPxapDNVmIH5Ectvb+ +NA7EsuVSS8xV6HfjV0tNZKIfFA4b1JD7t6l4gGDLuoppvKQV9n1JP/uZhQlFZ8Dg +7qMXGsEWRcmRGSBZxIVA+EiN35ALsR78MYWEmuAtKKtskqD4cwnAQzZhU1tZRFHz +/uSfhS2tFXQ7vjvCPIozzo9Mgy4Vr4Qoc9ohg0AfK/D3IoA/mpQFpVC+hyS+rQ0d +uqjiVvh1b0cI3ZBEwWeaNKR4Z3dVb3RHOnICCJPyxxIfSDKWDmQDMCMLa5UjvSvM +pwIDAQAB +-----END PUBLIC KEY-----"; + + /** + * Decrypt a PRO license key to get the expiration date of the license + * + * @param string $encryptedlicensekey an object containing licensekey and signature + * @return string the expiration date of the license key formatted as Y-m-d + */ + public static function decryptlicensekey(string $encryptedlicensekey): string { + global $CFG; + // Step 1: Do base64 decoding. + $encryptedlicensekey = base64_decode($encryptedlicensekey); + + // Step 2: Decrypt using public key. + openssl_public_decrypt($encryptedlicensekey, $licensekey, self::mod_mooduell_PUBLIC_KEY); + + // Step 3: Do another base64 decode and decrypt using wwwroot. + $c = base64_decode($licensekey); + $ivlen = openssl_cipher_iv_length($cipher = "AES-128-CBC"); + $iv = substr($c, 0, $ivlen); + + // Bugfix when passing wrong license keys that are too short. + if (strlen($iv) != 16) { + return false; + } + + $sha2len = 32; + $ciphertextraw = substr($c, $ivlen + $sha2len); + $decryptedcontent = openssl_decrypt($ciphertextraw, $cipher, $CFG->wwwroot, $options = OPENSSL_RAW_DATA, $iv); + + return $decryptedcontent; + } + + /** + * Helper function to determine if the user has set a valid license key which has not yet expired. + * + * @return bool true if the license key is valid at current date + * @throws \dml_exception + */ + public static function pro_version_is_activated() { + // Get license key which has been set in settings.php. + $pluginconfig = get_config('mooduell'); + if (!empty($pluginconfig->licensekey)) { + $licensekeyfromsettings = $pluginconfig->licensekey; + // DEBUG: echo "License key from plugin config: $licensekey_from_settings
"; END. + + $expirationtimestamp = strtotime(self::decryptlicensekey($licensekeyfromsettings)); + // Return true if the current timestamp has not yet reached the expiration date. + if (time() < $expirationtimestamp) { + return true; + } + } + // Overriding - always use PRO for testing / debugging. + // Check if Behat OR PhpUnit tests are running. + if ((defined('BEHAT_SITE_RUNNING') && BEHAT_SITE_RUNNING) || (defined('PHPUNIT_TEST') && PHPUNIT_TEST)) { + return true; + } + return false; + } +} diff --git a/lang/de/mooduell.php b/lang/de/mooduell.php index 241fc08..3889b86 100755 --- a/lang/de/mooduell.php +++ b/lang/de/mooduell.php @@ -25,6 +25,13 @@ defined('MOODLE_INTERNAL') || die(); +$string['licensekeycfg'] = 'PRO-Version aktivieren'; +$string['licensekeycfgdesc'] = 'Mit einer PRO-Lizenz können Sie so viele Buchungsvorlagen erstellen wie Sie wollen und PRO-Features wie z.B. globale Mailvorlagen, Info-Texte für Wartelistenplätze und Benachrichtigungen für Trainer:innen nutzen.'; +$string['licensekey'] = 'PRO-Lizenz-Schlüssel'; +$string['licensekeydesc'] = 'Laden Sie hier einen gültigen Schlüssel hoch, um die PRO-Version zu aktivieren.'; +$string['license_activated'] = 'PRO-Version wurde erfolgreich aktiviert.
(Läuft ab am: '; +$string['license_invalid'] = 'Ungültiger Lizenz-Schlüssel.'; + $string['updatesubscription'] = "Subscription status prüfen"; $string['disablesbadges'] = 'Disble Badges'; diff --git a/lang/en/mooduell.php b/lang/en/mooduell.php index c6c9290..7097316 100755 --- a/lang/en/mooduell.php +++ b/lang/en/mooduell.php @@ -25,6 +25,13 @@ defined('MOODLE_INTERNAL') || die(); +$string['licensekeycfg'] = 'Activate PRO version'; +$string['licensekeycfgdesc'] = 'With a PRO license you can create as many booking templates as you like and use PRO features such as global mail templates, waiting list info texts or teacher notifications.'; +$string['licensekey'] = 'PRO license key'; +$string['licensekeydesc'] = 'Upload a valid license key to activate the PRO version.'; +$string['license_activated'] = 'PRO version activated successfully.
(Expires: '; +$string['license_invalid'] = 'Invalid license key'; + $string['updatesubscription'] = "Check subscription status"; $string['disablesbadges'] = 'Auszeichnungen deaktivieren'; diff --git a/settings.php b/settings.php index 00fd47d..9253056 100755 --- a/settings.php +++ b/settings.php @@ -24,12 +24,48 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use mod_mooduell\utils\wb_payment; + defined('MOODLE_INTERNAL') || die(); global $ADMIN; if ($ADMIN->fulltree) { + // Has PRO version been activated? + $proversion = wb_payment::pro_version_is_activated(); + + $settings->add( + new admin_setting_heading('licensekeycfgheading', + get_string('licensekeycfg', 'mod_mooduell'), + get_string('licensekeycfgdesc', 'mod_mooduell'))); + + // Dynamically change the license info text. + $licensekeydesc = get_string('licensekeydesc', 'mod_mooduell'); + + // Get license key which has been set in text field. + $pluginconfig = get_config('mooduell'); + if (!empty($pluginconfig->licensekey)) { + $licensekey = $pluginconfig->licensekey; + + $expirationdate = wb_payment::decryptlicensekey($licensekey); + if (!empty($expirationdate)) { + $licensekeydesc = "

" + .get_string('license_activated', 'mod_mooduell') + .$expirationdate + .")

"; + } else { + $licensekeydesc = "

" + .get_string('license_invalid', 'mod_mooduell') + ."

"; + } + } + + $settings->add( + new admin_setting_configtext('mooduell/licensekey', + get_string('licensekey', 'mod_mooduell'), + $licensekeydesc, '')); + $setting = new admin_setting_configcheckbox( 'mooduell/usefullnames', get_string('usefullnames', 'mod_mooduell'), @@ -152,12 +188,12 @@ 0 )); - $settings->add(new admin_setting_configcheckbox( - 'mooduell/unlockplatform', - get_string('unlockplatform', 'mod_mooduell'), - "", - 0 - )); + // $settings->add(new admin_setting_configcheckbox( + // 'mooduell/unlockplatform', + // get_string('unlockplatform', 'mod_mooduell'), + // "", + // 0 + // )); $settings->add(new admin_setting_configcheckbox( 'mooduell/disablebadges', From 253d336df38251340a8a40ecdb75ffb35cc33d15 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 6 Mar 2024 13:28:04 +0100 Subject: [PATCH 12/17] subscriptions now have validuntil field --- classes/mooduell.php | 13 ++++++++++--- db/install.xml | 1 + db/tasks.php | 4 ++-- db/upgrade.php | 15 +++++++++++++++ version.php | 2 +- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index 3e8d08f..b55ba7d 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -450,7 +450,10 @@ public static function update_all_subscriptions() { if ($singleproduct->id === 'unlockplatformsubscription') { // Subscription item. if ($singleproduct->isExpired === false) { - // Extend validity. + // Extend validity for a day. + $udpatedentry = $returnitem; + $udpatedentry->validuntil = $returnitem->validuntil + (60 * 60 * 24); + $DB->update_record('mooduell_purchase', $udpatedentry); return; } else if ($singleproduct->isExpired === true) { // Delete Cancel etc. @@ -554,14 +557,16 @@ public static function get_purchases($courses, $quizzes) { list($insqlcourses, $inparams) = $DB->get_in_or_equal($courseids); list($insqlquizzes, $inparams2) = $DB->get_in_or_equal($quizids); list($insqlplatform, $inparams3) = $DB->get_in_or_equal($CFG->wwwroot); + // Give 4 days leeway in case task hasnt run. + $leeway = time() - (60 * 60 * 24 * 4); $params = array_merge($inparams, $inparams2, $inparams3); - + $params[] = $leeway; $sql = "SELECT * FROM {mooduell_purchase} WHERE userid = {$userid} AND NOT productid = 'notvalid' OR courseid $insqlcourses OR mooduellid $insqlquizzes AND ispublic = 1 - OR platformid $insqlplatform AND NOT productid = 'notvalid'"; + OR platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; $returnitems = ['purchases' => $DB->get_records_sql($sql, $params)]; return $returnitems; @@ -622,6 +627,8 @@ public static function purchase_item($purchase) { } $newdata = $purchase; $newdata['timecreated'] = time(); + // We check subscription every day. + $newdata['validuntil'] = time() + (60 * 60 * 24); $manipulatedstring = $newdata['purchasetoken']; if ($newdata['signature']) { $manipulatedsignature = $newdata['signature']; diff --git a/db/install.xml b/db/install.xml index 9afef82..cd73c19 100755 --- a/db/install.xml +++ b/db/install.xml @@ -160,6 +160,7 @@ + diff --git a/db/tasks.php b/db/tasks.php index da5ce26..0a0a25e 100644 --- a/db/tasks.php +++ b/db/tasks.php @@ -27,8 +27,8 @@ $tasks = [ ['classname' => 'mod_mooduell\task\update_subscription_task', 'blocking' => 0, - 'minute' => '30', - 'hour' => '7', + 'minute' => '0', + 'hour' => '0', 'day' => '*', 'dayofweek' => '*', 'month' => '*', diff --git a/db/upgrade.php b/db/upgrade.php index da983ba..68771e5 100755 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -275,5 +275,20 @@ function xmldb_mooduell_upgrade($oldversion) { upgrade_mod_savepoint(true, 2022033101, 'mooduell'); } + if ($oldversion < 2024030600) { + + // Define field validuntil to be added to mooduell_purchase. + $table = new xmldb_table('mooduell_purchase'); + $field = new xmldb_field('validuntil', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'ispublic'); + + // Conditionally launch add field validuntil. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Mooduell savepoint reached. + upgrade_mod_savepoint(true, 2024030600, 'mooduell'); + } + return true; } diff --git a/version.php b/version.php index f816f81..6277593 100755 --- a/version.php +++ b/version.php @@ -26,7 +26,7 @@ $plugin->component = 'mod_mooduell'; $plugin->release = 'v2.1.5'; -$plugin->version = 2024021907; +$plugin->version = 2024030600; $plugin->requires = 2020061500; $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = [ From 6887c05605d861492c04a45f8ee271d4a7f52dfd Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 6 Mar 2024 14:34:10 +0100 Subject: [PATCH 13/17] get_purchases logic subs only --- classes/mooduell.php | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index b55ba7d..28091a6 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -553,20 +553,26 @@ public static function get_purchases($courses, $quizzes) { $returnitems = ['purchases' => []]; return $returnitems; } - - list($insqlcourses, $inparams) = $DB->get_in_or_equal($courseids); - list($insqlquizzes, $inparams2) = $DB->get_in_or_equal($quizids); - list($insqlplatform, $inparams3) = $DB->get_in_or_equal($CFG->wwwroot); - // Give 4 days leeway in case task hasnt run. $leeway = time() - (60 * 60 * 24 * 4); - - $params = array_merge($inparams, $inparams2, $inparams3); + list($insqlplatform, $inparams1) = $DB->get_in_or_equal($CFG->wwwroot); + $params[] = $inparams1; $params[] = $leeway; $sql = "SELECT * FROM {mooduell_purchase} - WHERE userid = {$userid} AND NOT productid = 'notvalid' - OR courseid $insqlcourses - OR mooduellid $insqlquizzes AND ispublic = 1 - OR platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; + WHERE platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; + // Logic for more than subs. + // list($insqlcourses, $inparams) = $DB->get_in_or_equal($courseids); + // list($insqlquizzes, $inparams2) = $DB->get_in_or_equal($quizids); + // list($insqlplatform, $inparams3) = $DB->get_in_or_equal($CFG->wwwroot); + // // Give 4 days leeway in case task hasnt run. + // $leeway = time() - (60 * 60 * 24 * 4); + + // $params = array_merge($inparams, $inparams2, $inparams3); + // $params[] = $leeway; + // $sql = "SELECT * FROM {mooduell_purchase} + // WHERE userid = {$userid} AND NOT productid = 'notvalid' + // OR courseid $insqlcourses + // OR mooduellid $insqlquizzes AND ispublic = 1 + // OR platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; $returnitems = ['purchases' => $DB->get_records_sql($sql, $params)]; return $returnitems; From 315ede465eb63cc4b5016039e65d948e537a5d64 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 6 Mar 2024 14:38:13 +0100 Subject: [PATCH 14/17] Fix --- classes/mooduell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index 28091a6..7bd97b9 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -555,7 +555,7 @@ public static function get_purchases($courses, $quizzes) { } $leeway = time() - (60 * 60 * 24 * 4); list($insqlplatform, $inparams1) = $DB->get_in_or_equal($CFG->wwwroot); - $params[] = $inparams1; + $params = $inparams1; $params[] = $leeway; $sql = "SELECT * FROM {mooduell_purchase} WHERE platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; From 32eb54100357e60b2fecbf1389777fe4208b0c37 Mon Sep 17 00:00:00 2001 From: cbadusch Date: Wed, 6 Mar 2024 14:42:52 +0100 Subject: [PATCH 15/17] Logic --- classes/mooduell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/mooduell.php b/classes/mooduell.php index 7bd97b9..7344e2f 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -452,7 +452,7 @@ public static function update_all_subscriptions() { if ($singleproduct->isExpired === false) { // Extend validity for a day. $udpatedentry = $returnitem; - $udpatedentry->validuntil = $returnitem->validuntil + (60 * 60 * 24); + $udpatedentry->validuntil = time() + (60 * 60 * 24); $DB->update_record('mooduell_purchase', $udpatedentry); return; } else if ($singleproduct->isExpired === true) { From d5ba2a83a85b203138655ee111fa5ec6c8e56cad Mon Sep 17 00:00:00 2001 From: cbadusch Date: Mon, 11 Mar 2024 11:39:11 +0100 Subject: [PATCH 16/17] Linting --- classes/completion/completion_utils.php | 2 +- classes/game_finished.php | 10 +++++----- classes/mooduell.php | 18 +----------------- classes/output/list_action.php | 2 +- classes/output/overview_student.php | 8 ++++---- classes/output/overview_teacher.php | 10 +++++----- classes/privacy/provider.php | 4 ++-- classes/question_control.php | 8 ++++---- classes/task/update_subscription_task.php | 1 - classes/utils/wb_payment.php | 4 ++-- settings.php | 15 +++------------ tests/mooduell_external_test.php | 4 ++-- 12 files changed, 30 insertions(+), 56 deletions(-) diff --git a/classes/completion/completion_utils.php b/classes/completion/completion_utils.php index 8d29b71..cfb2fe1 100644 --- a/classes/completion/completion_utils.php +++ b/classes/completion/completion_utils.php @@ -124,7 +124,7 @@ public static function get_completion_challenges_array($mooduellinstance): array // Date until the challenge needs to be done. $challenge->targetdate = $mooduellinstance->cm->completionexpected ?? null; - // TODO: Calculate a user's rank within a challenge. - Will be done in a future release. + // Calculate a user's rank within a challenge. - Will be done in a future release. $challenge->challengerank = null; // Add an array of objects containing localized language strings needed by the app. diff --git a/classes/game_finished.php b/classes/game_finished.php index 0a190a8..d392fc4 100644 --- a/classes/game_finished.php +++ b/classes/game_finished.php @@ -69,11 +69,11 @@ public static function update_highscores_table(int $cmid) { 'gamesplayed' => $entry->played, 'gameswon' => $entry->won, 'gameslost' => $entry->lost, - 'gamesstarted' => 0, // TODO: this will be added later. - 'gamesfinished' => 0, // TODO: this will be added later. + 'gamesstarted' => 0, + 'gamesfinished' => 0, 'score' => $entry->score, 'qcorrect' => $entry->correct, - 'qplayed' => $entry->qplayed, + 'qplayed' => $entry->qplayed, 'qcpercentage' => $entry->correctpercentage, 'timecreated' => time(), 'timemodified' => time(), @@ -87,8 +87,8 @@ public static function update_highscores_table(int $cmid) { $entry = (object) $entry; // Let's have a look if the entry already exists in the DB. - $sql = 'select * from {mooduell_highscores} where mooduellid = '. - $entry->mooduellid.' and userid = '.$entry->userid; + $sql = 'select * from {mooduell_highscores} where mooduellid = ' . + $entry->mooduellid . ' and userid = ' . $entry->userid; $data = $DB->get_record_sql($sql); // If the entry could be found in the database. diff --git a/classes/mooduell.php b/classes/mooduell.php index 7344e2f..e0d8731 100644 --- a/classes/mooduell.php +++ b/classes/mooduell.php @@ -326,7 +326,6 @@ public function return_list_of_all_questions_in_quiz() { $cachetime = get_config('mooduell', 'cachetime'); if ($cachetime > 0) { - // Next we take a look in the cache. $cache = cache::make('mod_mooduell', 'questionscache'); @@ -336,7 +335,6 @@ public function return_list_of_all_questions_in_quiz() { $this->questions = $questions; return $questions; } - } $questions = []; @@ -347,7 +345,7 @@ public function return_list_of_all_questions_in_quiz() { $newquestion = new question_control($entry, $listofanswers); // Add empty combined feedback (for ddwtos questions) to prevent webservice errors. - $combinedfeedback = new stdClass; + $combinedfeedback = new stdClass(); $combinedfeedback->correctfeedback = null; $combinedfeedback->partiallycorrectfeedback = null; $combinedfeedback->incorrectfeedback = null; @@ -559,20 +557,6 @@ public static function get_purchases($courses, $quizzes) { $params[] = $leeway; $sql = "SELECT * FROM {mooduell_purchase} WHERE platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; - // Logic for more than subs. - // list($insqlcourses, $inparams) = $DB->get_in_or_equal($courseids); - // list($insqlquizzes, $inparams2) = $DB->get_in_or_equal($quizids); - // list($insqlplatform, $inparams3) = $DB->get_in_or_equal($CFG->wwwroot); - // // Give 4 days leeway in case task hasnt run. - // $leeway = time() - (60 * 60 * 24 * 4); - - // $params = array_merge($inparams, $inparams2, $inparams3); - // $params[] = $leeway; - // $sql = "SELECT * FROM {mooduell_purchase} - // WHERE userid = {$userid} AND NOT productid = 'notvalid' - // OR courseid $insqlcourses - // OR mooduellid $insqlquizzes AND ispublic = 1 - // OR platformid $insqlplatform AND validuntil > ? AND NOT productid = 'notvalid'"; $returnitems = ['purchases' => $DB->get_records_sql($sql, $params)]; return $returnitems; diff --git a/classes/output/list_action.php b/classes/output/list_action.php index 33fed74..bac3fa0 100644 --- a/classes/output/list_action.php +++ b/classes/output/list_action.php @@ -84,7 +84,7 @@ public function export_for_template(renderer_base $output) { * @param int $counter * @return array */ - private function render_questions_table_for_game(stdClass $game, mooduell $mooduell, int $counter = null):array { + private function render_questions_table_for_game(stdClass $game, mooduell $mooduell, int $counter = null): array { global $PAGE; $tablename = bin2hex(random_bytes(12)); diff --git a/classes/output/overview_student.php b/classes/output/overview_student.php index 8e0b4cc..3f91349 100644 --- a/classes/output/overview_student.php +++ b/classes/output/overview_student.php @@ -97,7 +97,7 @@ public function export_for_template(renderer_base $output) { * @param mooduell $mooduell * @return string */ - private function render_open_games_table(mooduell $mooduell):string { + private function render_open_games_table(mooduell $mooduell): string { return $this->render_games_table($mooduell, 'opengames'); } @@ -107,7 +107,7 @@ private function render_open_games_table(mooduell $mooduell):string { * @param mooduell $mooduell * @return string */ - private function render_finished_games_table(mooduell $mooduell):string { + private function render_finished_games_table(mooduell $mooduell): string { return $this->render_games_table($mooduell, 'finishedgames'); } @@ -118,7 +118,7 @@ private function render_finished_games_table(mooduell $mooduell):string { * @param string $action * @return string */ - private function render_games_table(mooduell $mooduell, string $action):string { + private function render_games_table(mooduell $mooduell, string $action): string { $gamestable = new table_games($action, $mooduell->cm->id); $finishedgames = $action == 'finishedgames' ? true : false; @@ -150,7 +150,7 @@ private function render_games_table(mooduell $mooduell, string $action):string { * @param mooduell $mooduell * @return string */ - private function render_highscores_table(mooduell $mooduell):string { + private function render_highscores_table(mooduell $mooduell): string { $highscorestable = new table_highscores('highscores', $mooduell->cm->id); // Sort the table by descending score by default. diff --git a/classes/output/overview_teacher.php b/classes/output/overview_teacher.php index 251e853..fb70420 100644 --- a/classes/output/overview_teacher.php +++ b/classes/output/overview_teacher.php @@ -91,7 +91,7 @@ public function export_for_template(renderer_base $output) { * @param mooduell $mooduell * @return string */ - private function render_open_games_table(mooduell $mooduell):string { + private function render_open_games_table(mooduell $mooduell): string { return $this->render_games_table($mooduell, 'opengames'); } @@ -101,7 +101,7 @@ private function render_open_games_table(mooduell $mooduell):string { * @param mooduell $mooduell * @return string */ - private function render_finished_games_table(mooduell $mooduell):string { + private function render_finished_games_table(mooduell $mooduell): string { return $this->render_games_table($mooduell, 'finishedgames'); } @@ -112,7 +112,7 @@ private function render_finished_games_table(mooduell $mooduell):string { * @param string $action * @return string */ - private function render_games_table(mooduell $mooduell, $action):string { + private function render_games_table(mooduell $mooduell, $action): string { $tablename = bin2hex(random_bytes(12)); @@ -152,7 +152,7 @@ private function render_games_table(mooduell $mooduell, $action):string { * @param mooduell $mooduell * @return string */ - private function render_highscores_table(mooduell $mooduell):string { + private function render_highscores_table(mooduell $mooduell): string { $tablename = bin2hex(random_bytes(12)); $highscorestable = new table_highscores($tablename, $mooduell->cm->id); @@ -191,7 +191,7 @@ private function render_highscores_table(mooduell $mooduell):string { * @param mooduell $mooduell * @return string */ - private function render_questions_table(mooduell $mooduell):string { + private function render_questions_table(mooduell $mooduell): string { $tablename = bin2hex(random_bytes(12)); diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 40bbe8f..057401a 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -52,7 +52,7 @@ class provider implements * @param collection $collection a reference to the collection to use to store the metadata. * @return collection the updated collection of metadata items. */ - public static function get_metadata(collection $collection) : collection { + public static function get_metadata(collection $collection): collection { // Stores the mooduell game progress. $collection->add_database_table( 'mooduell_games', @@ -133,7 +133,7 @@ public static function get_metadata(collection $collection) : collection { * @param int $userid the userid. * @return contextlist the list of contexts containing user info for the user. */ - public static function get_contexts_for_userid(int $userid) : contextlist { + public static function get_contexts_for_userid(int $userid): contextlist { $contextlist = new contextlist(); diff --git a/classes/question_control.php b/classes/question_control.php index 435a196..42bf41f 100644 --- a/classes/question_control.php +++ b/classes/question_control.php @@ -107,7 +107,7 @@ public function __construct($data = null, $listofanswers = null) { $this->questionid = $data->id; $this->name = $data->name; if ($data->qtype == 'ddwtos') { - $this->questiontext = trim(strip_tags(html_entity_decode($data->questiontext))); + $this->questiontext = trim(strip_tags(html_entity_decode($data->questiontext, ENT_QUOTES))); } else { $this->questiontext = $data->questiontext; } @@ -143,17 +143,17 @@ public function __construct($data = null, $listofanswers = null) { // Remove HTML and decode HTML entities like " ". if (!empty($combinedfeedback->correctfeedback)) { $combinedfeedback->correctfeedback = - trim(strip_tags(html_entity_decode($combinedfeedback->correctfeedback))); + trim(strip_tags(html_entity_decode($combinedfeedback->correctfeedback, ENT_QUOTES))); } if (!empty($combinedfeedback->partiallycorrectfeedback)) { $combinedfeedback->partiallycorrectfeedback = - trim(strip_tags(html_entity_decode($combinedfeedback->partiallycorrectfeedback))); + trim(strip_tags(html_entity_decode($combinedfeedback->partiallycorrectfeedback, ENT_QUOTES))); } if (!empty($combinedfeedback->incorrectfeedback)) { $combinedfeedback->incorrectfeedback = - trim(strip_tags(html_entity_decode($combinedfeedback->incorrectfeedback))); + trim(strip_tags(html_entity_decode($combinedfeedback->incorrectfeedback, ENT_QUOTES))); } } } else { diff --git a/classes/task/update_subscription_task.php b/classes/task/update_subscription_task.php index 034ff5a..ae2fd64 100644 --- a/classes/task/update_subscription_task.php +++ b/classes/task/update_subscription_task.php @@ -29,7 +29,6 @@ * update_subscription_task */ class update_subscription_task extends \core\task\scheduled_task { - /** * Returns the taskname. * diff --git a/classes/utils/wb_payment.php b/classes/utils/wb_payment.php index 2cff08e..85a5080 100644 --- a/classes/utils/wb_payment.php +++ b/classes/utils/wb_payment.php @@ -44,7 +44,7 @@ class wb_payment { * * @var mixed */ - const mod_mooduell_PUBLIC_KEY = "-----BEGIN PUBLIC KEY----- + const MOD_MOODUELL_PUBLIC_KEY = "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu8vRBnPDug2pKoGY9wQS KNTK1SzrPuU0KC8xm22GPQZQM1XkPpvNwBp8CmXUN29r/qiPxapDNVmIH5Ectvb+ NA7EsuVSS8xV6HfjV0tNZKIfFA4b1JD7t6l4gGDLuoppvKQV9n1JP/uZhQlFZ8Dg @@ -66,7 +66,7 @@ public static function decryptlicensekey(string $encryptedlicensekey): string { $encryptedlicensekey = base64_decode($encryptedlicensekey); // Step 2: Decrypt using public key. - openssl_public_decrypt($encryptedlicensekey, $licensekey, self::mod_mooduell_PUBLIC_KEY); + openssl_public_decrypt($encryptedlicensekey, $licensekey, self::MOD_MOODUELL_PUBLIC_KEY); // Step 3: Do another base64 decode and decrypt using wwwroot. $c = base64_decode($licensekey); diff --git a/settings.php b/settings.php index 9253056..89db7ee 100755 --- a/settings.php +++ b/settings.php @@ -39,7 +39,6 @@ new admin_setting_heading('licensekeycfgheading', get_string('licensekeycfg', 'mod_mooduell'), get_string('licensekeycfgdesc', 'mod_mooduell'))); - // Dynamically change the license info text. $licensekeydesc = get_string('licensekeydesc', 'mod_mooduell'); @@ -63,14 +62,14 @@ $settings->add( new admin_setting_configtext('mooduell/licensekey', - get_string('licensekey', 'mod_mooduell'), - $licensekeydesc, '')); + get_string('licensekey', 'mod_mooduell'), + $licensekeydesc, '')); $setting = new admin_setting_configcheckbox( 'mooduell/usefullnames', get_string('usefullnames', 'mod_mooduell'), "", - 0 + 0 ); $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false); $settings->add($setting); @@ -188,13 +187,6 @@ 0 )); - // $settings->add(new admin_setting_configcheckbox( - // 'mooduell/unlockplatform', - // get_string('unlockplatform', 'mod_mooduell'), - // "", - // 0 - // )); - $settings->add(new admin_setting_configcheckbox( 'mooduell/disablebadges', get_string('disablesbadges', 'mod_mooduell'), @@ -217,7 +209,6 @@ 'themepicture', 0 )); - $settings->add(new admin_setting_configstoredfile( 'mod_mooduell/companylogoalternative', get_string('alternativelogo', 'mod_mooduell'), diff --git a/tests/mooduell_external_test.php b/tests/mooduell_external_test.php index 4f65d66..961b6f1 100644 --- a/tests/mooduell_external_test.php +++ b/tests/mooduell_external_test.php @@ -45,7 +45,7 @@ class mooduell_external_test extends advanced_testcase { /** * Tests set up. */ - public function setUp():void { + public function setUp(): void { $this->resetAfterTest(); } @@ -174,7 +174,7 @@ public function test_get_quiz_users() { // Check users. $this->assertIsArray($users); $this->assertEquals(2, count($users)); - // TODO: no built-in methods to compare stdClass instances. + // No built-in methods to compare stdClass instances. $ids = array_map(function($item) { return $item->id; }, $users); From 979e0cead37420c269ced6e2e28423bc2018665b Mon Sep 17 00:00:00 2001 From: cbadusch Date: Mon, 11 Mar 2024 12:49:56 +0100 Subject: [PATCH 17/17] More Linting --- test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test.php b/test.php index c068d42..5e520a5 100644 --- a/test.php +++ b/test.php @@ -15,6 +15,8 @@ // along with Moodle. If not, see . /** + * Testing some functions. + * * @package mod_mooduell * @copyright 2024 Wunderbyte GmbH * @author Chrsitian Badusch