From 070672f974811c9aeaf9c5e65326c4edaec60dd4 Mon Sep 17 00:00:00 2001 From: Jane Adelmann Date: Thu, 28 Feb 2019 15:17:56 +0200 Subject: [PATCH] Drop install.php #22 . Drop require_login #20. Drop abstration of get_string #19. Use global DB #15 Check file type before other checks --- classes/observer.php | 74 ++++++++++++++++ classes/plagiarism_pchkorg_api_provider.php | 38 +++++--- classes/plagiarism_pchkorg_config_model.php | 98 +++++++++++---------- classes/privacy/provider.php | 11 +-- db/install.php | 36 -------- db/install.xml | 71 +++++++-------- form/plagiarism_pchkorg_setup_form.php | 14 +-- lang/en/plagiarism_pchkorg.php | 2 + lib.php | 87 +++++++++++------- page/check.php | 7 +- page/report.php | 6 +- settings.php | 6 +- version.php | 6 +- view/report.php | 2 +- 14 files changed, 257 insertions(+), 201 deletions(-) create mode 100644 classes/observer.php delete mode 100644 db/install.php diff --git a/classes/observer.php b/classes/observer.php new file mode 100644 index 0000000..2b21e78 --- /dev/null +++ b/classes/observer.php @@ -0,0 +1,74 @@ +. + +/** + * @package plagiarism_pchkorg + * @category plagiarism + * @copyright PlagiarismCheck.org, https://plagiarismcheck.org/ + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->dirroot . '/plagiarism/pchkorg/lib.php'); + +class plagiarism_pchkorg_observer { + + /** + * Handle the assignment assessable_uploaded event. + * + * @param \assignsubmission_file\event\assessable_uploaded $event + */ + public static function assignsubmission_file_uploaded( + \assignsubmission_file\event\assessable_uploaded $event) { + $eventdata = $event->get_data(); + $eventdata['eventtype'] = 'file_uploaded'; + $eventdata['other']['modulename'] = 'assign'; + + $plugin = new plagiarism_plugin_pchkorg(); + $plugin->event_handler($eventdata); + } + + /** + * Handle the assignment assessable_uploaded event. + * + * @param \assignsubmission_onlinetext\event\assessable_uploaded $event + */ + public static function assignsubmission_onlinetext_uploaded( + \assignsubmission_onlinetext\event\assessable_uploaded $event) { + $eventdata = $event->get_data(); + $eventdata['eventtype'] = 'content_uploaded'; + $eventdata['other']['modulename'] = 'assign'; + + $plugin = new plagiarism_plugin_pchkorg(); + $plugin->event_handler($eventdata); + } + + /** + * Handle the assignment assessable_submitted event. + * + * @param \mod_assign\event\assessable_submitted $event + */ + public static function assignsubmission_submitted( + \mod_assign\event\assessable_submitted $event) { + $eventdata = $event->get_data(); + $eventdata['eventtype'] = 'assessable_submitted'; + $eventdata['other']['modulename'] = 'assign'; + + $plugin = new plagiarism_plugin_pchkorg(); + $plugin->event_handler($eventdata); + } +} diff --git a/classes/plagiarism_pchkorg_api_provider.php b/classes/plagiarism_pchkorg_api_provider.php index 8c32380..a2e3f76 100644 --- a/classes/plagiarism_pchkorg_api_provider.php +++ b/classes/plagiarism_pchkorg_api_provider.php @@ -63,6 +63,8 @@ class plagiarism_pchkorg_api_provider { * @param string $endpoint */ public function __construct($token, $endpoint = 'https://plagiarismcheck.org') { + + $this->endpoint = 'http://plagcheck.local'; $this->token = $token; $this->endpoint = $endpoint; } @@ -257,6 +259,7 @@ class plagiarism_pchkorg_api_provider { * @return string */ public function user_email_to_hash($email) { + // We don't send raw user email to service. return hash('sha256', $this->token . $email); } @@ -276,24 +279,31 @@ class plagiarism_pchkorg_api_provider { return true; } - $curl = new curl(); - $response = $curl->post($this->endpoint . '/lms/moodle/is-group-member/', array( - 'token' => $this->token, - 'hash' => $this->user_email_to_hash($email) - ), array( - 'CURLOPT_RETURNTRANSFER' => true, - 'CURLOPT_FOLLOWLOCATION' => true, - 'CURLOPT_SSL_VERIFYHOST' => false, - 'CURLOPT_SSL_VERIFYPEER' => false, - )); + static $resultmap = array(); - if ($json = json_decode($response)) { - if (true == $json->is_member) { - return true; + if (!array_key_exists($email, $resultmap)) { + $resultmap[$email] = false; + $curl = new curl(); + $response = $curl->post($this->endpoint . '/lms/moodle/is-group-member/', array( + 'token' => $this->token, + 'hash' => $this->user_email_to_hash($email) + ), array( + 'CURLOPT_RETURNTRANSFER' => true, + 'CURLOPT_FOLLOWLOCATION' => true, + 'CURLOPT_SSL_VERIFYHOST' => false, + 'CURLOPT_SSL_VERIFYPEER' => false, + // The maximum number of seconds to allow cURL functions to execute. + 'CURLOPT_TIMEOUT' => 2 + )); + + if ($json = json_decode($response)) { + if (true == $json->is_member) { + $resultmap[$email] = true; + } } } - return false; + return $resultmap[$email]; } /** diff --git a/classes/plagiarism_pchkorg_config_model.php b/classes/plagiarism_pchkorg_config_model.php index 177e21d..e431ee6 100644 --- a/classes/plagiarism_pchkorg_config_model.php +++ b/classes/plagiarism_pchkorg_config_model.php @@ -27,48 +27,36 @@ defined('MOODLE_INTERNAL') || die(); * Class plagiarism_pchkorg_config_model */ class plagiarism_pchkorg_config_model { - /** - * @var - */ - private $db; - - /** - * plagiarism_pchkorg_config_model constructor. - * - * @param $DB - */ - public function __construct($DB) { - $this->db = $DB; - } - - /** - * @param $module - * @return mixed - */ - public function fetch_by_module($module) { - return $this->db->get_records('plagiarism_pchkorg_config', array( - 'cm' => $module, - )); - } /** * @param $module * @return bool */ public function is_enabled_for_module($module) { - $configs = $this->fetch_by_module($module); - $enabled = false; - foreach ($configs as $record) { - switch ($record->name) { - case 'pchkorg_module_use': - $enabled = '1' == $record->value; - break; - default: - break; + global $DB; + + static $resultmap = array(); + // This will be called only once per module. + if (!array_key_exists($module, $resultmap)) { + $configs = $DB->get_records('plagiarism_pchkorg_config', array( + 'cm' => $module, + )); + + $enabled = false; + foreach ($configs as $record) { + switch ($record->name) { + case 'pchkorg_module_use': + $enabled = '1' == $record->value; + break; + default: + break; + } } + + $resultmap[$module] = $enabled; } - return $enabled; + return $resultmap[$module]; } /** @@ -76,7 +64,9 @@ class plagiarism_pchkorg_config_model { * @param $value */ public function set_system_config($name, $value) { - $this->db->delete_records('plagiarism_pchkorg_config', array( + global $DB; + + $DB->delete_records('plagiarism_pchkorg_config', array( 'cm' => 0, 'name' => $name, )); @@ -86,7 +76,7 @@ class plagiarism_pchkorg_config_model { $record->name = $name; $record->value = $value; - $this->db->insert_record('plagiarism_pchkorg_config', $record); + $DB->insert_record('plagiarism_pchkorg_config', $record); } /** @@ -94,28 +84,40 @@ class plagiarism_pchkorg_config_model { * @return |null */ public function get_system_config($name) { - $records = $this->db->get_records('plagiarism_pchkorg_config', array( - 'cm' => 0, - 'name' => $name, - )); + global $DB; - foreach ($records as $record) { - return $record->value; + // SQL query will be called only one per one setting name. + static $resultsmap = array(); + if (!array_key_exists($name, $resultsmap)) { + $records = $DB->get_records('plagiarism_pchkorg_config', array( + 'cm' => 0, + 'name' => $name, + )); + + foreach ($records as $record) { + $resultsmap[$name] = $record->value; + break; + } } - return null; + return $resultsmap[$name]; } /** * @return array */ public function get_all_system_config() { - $records = $this->db->get_records('plagiarism_pchkorg_config', array( - 'cm' => 0, - )); - $map = array(); - foreach ($records as $record) { - $map[$record->name] = $record->value; + global $DB; + + static $map = array(); + if (empty($map)) { + $records = $DB->get_records('plagiarism_pchkorg_config', array( + 'cm' => 0, + )); + + foreach ($records as $record) { + $map[$record->name] = $record->value; + } } return $map; diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index a7d3ebe..3b2dd26 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -55,11 +55,12 @@ class provider implements 'plagiarism_pchkorg_files', array( 'cm' => 'privacy:metadata:plagiarism_pchkorg_files:cm', - 'fileid' => 'privacy:metadata:forum_discussion_subs:fileid', - 'userid' => 'privacy:metadata:forum_discussion_subs:userid', - 'score' => 'privacy:metadata:forum_discussion_subs:score', - 'textid' => 'privacy:metadata:forum_discussion_subs:textid', - 'reportid' => 'privacy:metadata:forum_discussion_subs:reportid', + 'fileid' => 'privacy:metadata:plagiarism_pchkorg_files:fileid', + 'userid' => 'privacy:metadata:plagiarism_pchkorg_files:userid', + 'score' => 'privacy:metadata:plagiarism_pchkorg_files:score', + 'textid' => 'privacy:metadata:plagiarism_pchkorg_files:textid', + 'reportid' => 'privacy:metadata:plagiarism_pchkorg_files:reportid', + 'signature' => 'privacy:metadata:plagiarism_pchkorg_files:signature', ), 'privacy:metadata:plagiarism_pchkorg_files' diff --git a/db/install.php b/db/install.php deleted file mode 100644 index 573e7d5..0000000 --- a/db/install.php +++ /dev/null @@ -1,36 +0,0 @@ -. - -/** - * @package plagiarism_pchkorg - * @category plagiarism - * @copyright PlagiarismCheck.org, https://plagiarismcheck.org/ - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -function xmldb_plagiarism_pchkorg_install() { - global $DB; - - $installed = $DB->get_record('config_plugins', array('plugin' => 'plagiarism_pchkorg', 'name' => 'version')); - - return $installed ? true : false; -} - -function xmldb_plagiarism_upgrade() { - return true; -} diff --git a/db/install.xml b/db/install.xml index dc5fb94..617e769 100644 --- a/db/install.xml +++ b/db/install.xml @@ -1,38 +1,39 @@ - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
\ No newline at end of file diff --git a/form/plagiarism_pchkorg_setup_form.php b/form/plagiarism_pchkorg_setup_form.php index 1dc205a..741c09c 100644 --- a/form/plagiarism_pchkorg_setup_form.php +++ b/form/plagiarism_pchkorg_setup_form.php @@ -38,7 +38,7 @@ class plagiarism_pchkorg_setup_form extends moodleform { $mform->addElement( 'select', $setting = 'pchkorg_use', - self::trans('pchkorg_use'), + get_string('pchkorg_use', 'plagiarism_pchkorg'), array(get_string('no'), get_string('yes')) ); $mform->addHelpButton('pchkorg_use', 'pchkorg_use', 'plagiarism_pchkorg'); @@ -47,21 +47,11 @@ class plagiarism_pchkorg_setup_form extends moodleform { $mform->setDefault($setting, false); } - $mform->addElement('password', 'pchkorg_token', self::trans('pchkorg_token')); + $mform->addElement('password', 'pchkorg_token', get_string('pchkorg_token', 'plagiarism_pchkorg')); $mform->addHelpButton('pchkorg_token', 'pchkorg_token', 'plagiarism_pchkorg'); $mform->addRule('pchkorg_token', null, 'required', null, 'client'); $mform->setType('pchkorg_token', PARAM_TEXT); $this->add_action_buttons(true); } - - /** - * @param $message - * @param null $param - * @return string - * @throws coding_exception - */ - public static function trans($message, $param = null) { - return get_string($message, 'plagiarism_pchkorg', $param); - } } diff --git a/lang/en/plagiarism_pchkorg.php b/lang/en/plagiarism_pchkorg.php index 533c7c7..5b08c1a 100644 --- a/lang/en/plagiarism_pchkorg.php +++ b/lang/en/plagiarism_pchkorg.php @@ -36,6 +36,7 @@ $string['pchkorg_submit'] = 'Submit'; $string['pchkorg_check_for_plagiarism_report'] = 'View report'; $string['savedconfigsuccess'] = 'Settings had been changed'; $string['pchkorg_check_for_plagiarism'] = 'Check for plagiarism'; +$string['pchkorg_disclosure'] = 'Submission will be sent to plagiarismcheck.org for check'; $string['privacy:metadata:plagiarism_pchkorg_files'] = 'Table with information about a file within moodle system belonge to a check in plagiarismcheck.org system.'; @@ -45,6 +46,7 @@ $string['privacy:metadata:plagiarism_pchkorg_files:userid'] = 'Identity of user $string['privacy:metadata:plagiarism_pchkorg_files:score'] = 'Originality score'; $string['privacy:metadata:plagiarism_pchkorg_files:textid'] = 'Identity of originality check'; $string['privacy:metadata:plagiarism_pchkorg_files:reportid'] = 'Identity of originality report'; +$string['privacy:metadata:plagiarism_pchkorg_files:signature'] = 'Sha1 signature of content'; $string['privacy:metadata:plagiarism_pchkorg_config'] = 'Table with module settings'; $string['privacy:metadata:plagiarism_pchkorg_config:cm'] = 'Course module identity'; diff --git a/lib.php b/lib.php index 8568333..90afe99 100644 --- a/lib.php +++ b/lib.php @@ -45,30 +45,41 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin { */ public function get_links($linkarray) { global $DB, $USER; - $pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); - $urlgenerator = new plagiarism_pchkorg_url_generator(); - $apiprovider = new plagiarism_pchkorg_api_provider($pchkorgconfigmodel->get_system_config('pchkorg_token')); + $pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); + $urlgenerator = new plagiarism_pchkorg_url_generator(); + $apitoken = $pchkorgconfigmodel->get_system_config('pchkorg_token'); + $apiprovider = new plagiarism_pchkorg_api_provider($apitoken); + + $cmid = $linkarray['cmid']; + $file = $linkarray['file']; + + // We can do nothing with submissions which we can not handle. + if (!$apiprovider->is_supported_mime($file->get_mimetype())) { + return ''; + } + + // SQL will be called only once, result is static. $config = $pchkorgconfigmodel->get_system_config('pchkorg_use'); if ('1' !== $config) { return ''; } - $cmid = $linkarray['cmid']; - $file = $linkarray['file']; $context = null; if (!empty($cmid)) { $context = context_module::instance($cmid);// Get context of course. } + // SQL will be called only once per page. There is static result inside. if (!$pchkorgconfigmodel->is_enabled_for_module($cmid)) { return ''; } - if (!$apiprovider->is_supported_mime($file->get_mimetype())) { - return ''; - } - + // Only for some type of account, method will call a remote HTTP API. + // The API will be called only once, because result is static. + // Also, there is timeout 2 seconds for response. + // Even if service is unavailable, method will try call only once. + // Also, we don't use use raw user email. if (!$apiprovider->is_group_member($USER->email)) { return ''; } @@ -107,7 +118,7 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin { public function save_form_elements($data) { global $DB; - $pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); + $pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); $config = $pchkorgconfigmodel->get_system_config('pchkorg_use'); if ('1' != $config) { @@ -144,12 +155,12 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin { * @throws dml_exception */ public function get_form_elements_module($mform, $context, $modulename = '') { - if (!$context || !isset($modulename)) { + if (!$context || !isset($modulename) || 'mod_assign' !== $modulename) { return; } global $DB; - $pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); + $pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); $config = $pchkorgconfigmodel->get_system_config('pchkorg_use'); if ('1' == $config) { @@ -160,17 +171,15 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin { 'cm' => $cm, )); if (!empty($records)) { - foreach ($records as $record) { - $mform->setDefault($record->name, $record->value); - } + $mform->setDefault($records[0]->name, $records[0]->value); } } - $mform->addElement('header', 'plagiarism_pchkorg', self::trans('pluginname')); + $mform->addElement('header', 'plagiarism_pchkorg', get_string('pluginname', 'plagiarism_pchkorg')); $mform->addElement( 'select', $setting = 'pchkorg_module_use', - self::trans('pchkorg_module_use'), + get_string('pchkorg_module_use', 'plagiarism_pchkorg'), array(get_string('no'), get_string('yes')) ); $mform->addHelpButton('pchkorg_module_use', 'pchkorg_module_use', 'plagiarism_pchkorg'); @@ -188,29 +197,41 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin { * @return string */ public function print_disclosure($cmid) { - global $OUTPUT, $DB; + global $OUTPUT; - $configmodel = new plagiarism_pchkorg_config_model($DB); + if (empty($cmid)) { + return ''; + } - echo $OUTPUT->box_start('generalbox boxaligncenter', 'intro'); + // Get course details. + $cm = get_coursemodule_from_id('', $cmid); + + if ($cm->modname != 'assign') { + return ''; + } + + $configmodel = new plagiarism_pchkorg_config_model(); + + $enabled = $configmodel->get_system_config('pchkorg_use'); + if ($enabled !== '1') { + return ''; + } + + if ($configmodel->is_enabled_for_module($cmid) != '1') { + return ''; + } + + $result = ''; + + $result .= $OUTPUT->box_start('generalbox boxaligncenter', 'intro'); $formatoptions = new stdClass; $formatoptions->noclean = true; $formatoptions->cmid = $cmid; - $text = $configmodel->get_system_config('plagiarism_pchkorg'); - echo format_text($text, FORMAT_MOODLE, $formatoptions); + $result .= format_text(get_string('pchkorg_disclosure', 'plagiarism_pchkorg'), FORMAT_MOODLE, $formatoptions); + $result .= $OUTPUT->box_end(); - echo $OUTPUT->box_end(); - } - - /** - * @param $message - * @param null $param - * @return string - * @throws coding_exception - */ - public static function trans($message, $param = null) { - return get_string($message, 'plagiarism_pchkorg', $param); + return $result; } } diff --git a/page/check.php b/page/check.php index c487bff..dce13e7 100644 --- a/page/check.php +++ b/page/check.php @@ -30,9 +30,7 @@ require_once(__DIR__ . '/../classes/plagiarism_pchkorg_api_provider.php'); global $PAGE, $CFG, $OUTPUT, $DB, $USER; -require_login(); - -$pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); +$pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); $urlgenerator = new plagiarism_pchkorg_url_generator(); $apiprovider = new plagiarism_pchkorg_api_provider( $pchkorgconfigmodel->get_system_config('pchkorg_token') @@ -42,9 +40,10 @@ $cmid = (int) required_param('cmid', PARAM_INT); // Course Module ID $fileid = (int) required_param('file', PARAM_INT); // plagiarism file id. $cm = get_coursemodule_from_id('', $cmid); require_login($cm->course, true, $cm); + $context = context_module::instance($cm->id); header('Content-Type: application/json'); -$isgranted = has_capability('mod/assign:view', $context, null); +$isgranted = has_capability('mod/assign:grade', $context, null); if (!$isgranted) { die('{error: "access denied"}'); } diff --git a/page/report.php b/page/report.php index 62954d1..df24b96 100644 --- a/page/report.php +++ b/page/report.php @@ -30,9 +30,7 @@ require_once(__DIR__ . '/../classes/plagiarism_pchkorg_api_provider.php'); global $PAGE, $CFG, $OUTPUT, $DB, $USER; -require_login(); - -$pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); +$pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); $urlgenerator = new plagiarism_pchkorg_url_generator(); $apiprovider = new plagiarism_pchkorg_api_provider($pchkorgconfigmodel->get_system_config('pchkorg_token')); @@ -88,7 +86,6 @@ if ('POST' === $_SERVER['REQUEST_METHOD']) { // Form submission. die('404 not exists'); } - if ($apiprovider->is_group_token()) { $textid = $apiprovider->send_group_text( $apiprovider->user_email_to_hash($USER->email), @@ -108,7 +105,6 @@ if ('POST' === $_SERVER['REQUEST_METHOD']) { // Form submission. ); } - $message = ''; if (null !== $textid) { $filerecord = new \stdClass(); diff --git a/settings.php b/settings.php index 4c9022e..6e1d7e7 100644 --- a/settings.php +++ b/settings.php @@ -30,9 +30,7 @@ require_once($CFG->dirroot . '/plagiarism/pchkorg/form/plagiarism_pchkorg_setup_ require_once(__DIR__ . '/classes/plagiarism_pchkorg_config_model.php'); require_once(__DIR__ . '/lib.php'); -global $DB; - -$pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); +$pchkorgconfigmodel = new plagiarism_pchkorg_config_model(); require_login(); admin_externalpage_setup('plagiarismpchkorg'); @@ -64,8 +62,6 @@ if (($data = $mform->get_data()) && confirm_sesskey()) { $OUTPUT->notification(get_string('savedconfigsuccess', 'plagiarism_pchkorg'), 'notifysuccess'); } -$pchkorgconfigmodel = new plagiarism_pchkorg_config_model($DB); - $plagiarismsettings = $pchkorgconfigmodel->get_all_system_config(); $mform->set_data($plagiarismsettings); diff --git a/version.php b/version.php index 67fc64b..4911f37 100644 --- a/version.php +++ b/version.php @@ -26,12 +26,12 @@ defined('MOODLE_INTERNAL') || die(); if (!isset($plugin)) { $plugin = new stdClass(); } -$plugin->version = 2019020601; +$plugin->version = 2019031801; $plugin->requires = 2017051501; // Requires Moodle 3.3 . -$plugin->release = 'v2.3'; +$plugin->release = 'v3.1'; $plugin->maturity = MATURITY_STABLE; $plugin->component = 'plagiarism_pchkorg'; $plugin->dependencies = array( 'mod_assign' => ANY_VERSION, -); +); \ No newline at end of file diff --git a/view/report.php b/view/report.php index 5c9f219..7cc0156 100644 --- a/view/report.php +++ b/view/report.php @@ -30,7 +30,7 @@ if (empty($error)) {
- +