mirror of
https://github.com/PlagiarismCheck/moodle-plagiarism_pchkorg.git
synced 2024-09-07 21:17:02 +00:00
Use moodle task.
This commit is contained in:
parent
070672f974
commit
dfd7195f91
@ -21,19 +21,35 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); // It must be included from a Moodle page.
|
||||
}
|
||||
|
||||
require_once($CFG->dirroot . '/plagiarism/pchkorg/lib.php');
|
||||
require_once($CFG->dirroot.'/plagiarism/pchkorg/lib.php');
|
||||
|
||||
/**
|
||||
* This class subscribe to events.
|
||||
*/
|
||||
class plagiarism_pchkorg_observer {
|
||||
/**
|
||||
* Handle the course_module_deleted event.
|
||||
* @param \core\event\course_module_deleted $event
|
||||
*/
|
||||
public static function course_module_deleted(
|
||||
\core\event\course_module_deleted $event) {
|
||||
global $DB;
|
||||
$eventdata = $event->get_data();
|
||||
|
||||
$DB->delete_records('plagiarism_pchkorg_files', array('cm' => $eventdata['contextinstanceid']));
|
||||
$DB->delete_records('plagiarism_pchkorg_config', array('cm' => $eventdata['contextinstanceid']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
\assignsubmission_file\event\assessable_uploaded $event) {
|
||||
$eventdata = $event->get_data();
|
||||
$eventdata['eventtype'] = 'file_uploaded';
|
||||
$eventdata['other']['modulename'] = 'assign';
|
||||
@ -44,11 +60,10 @@ class plagiarism_pchkorg_observer {
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
\assignsubmission_onlinetext\event\assessable_uploaded $event) {
|
||||
$eventdata = $event->get_data();
|
||||
$eventdata['eventtype'] = 'content_uploaded';
|
||||
$eventdata['other']['modulename'] = 'assign';
|
||||
@ -59,11 +74,10 @@ class plagiarism_pchkorg_observer {
|
||||
|
||||
/**
|
||||
* Handle the assignment assessable_submitted event.
|
||||
*
|
||||
* @param \mod_assign\event\assessable_submitted $event
|
||||
*/
|
||||
public static function assignsubmission_submitted(
|
||||
\mod_assign\event\assessable_submitted $event) {
|
||||
\mod_assign\event\assessable_submitted $event) {
|
||||
$eventdata = $event->get_data();
|
||||
$eventdata['eventtype'] = 'assessable_submitted';
|
||||
$eventdata['other']['modulename'] = 'assign';
|
||||
|
@ -24,25 +24,34 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class plagiarism_pchkorg_api_provider
|
||||
* Class provider HTTP-API methods.
|
||||
*/
|
||||
class plagiarism_pchkorg_api_provider {
|
||||
|
||||
/**
|
||||
* @var
|
||||
* Auth token.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* Url of api.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $endpoint;
|
||||
|
||||
/**
|
||||
* @var
|
||||
* Last api error.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $lasterror;
|
||||
|
||||
/**
|
||||
* Fetch last api error.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_last_error() {
|
||||
@ -50,6 +59,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup last api error.
|
||||
*
|
||||
* @param mixed $lasterror
|
||||
*/
|
||||
public function set_last_error($lasterror) {
|
||||
@ -57,19 +68,19 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* plagiarism_pchkorg_api_provider constructor.
|
||||
* Constructor for api provider.
|
||||
*
|
||||
* @param $token
|
||||
* @param string $endpoint
|
||||
*/
|
||||
public function __construct($token, $endpoint = 'https://plagiarismcheck.org') {
|
||||
|
||||
$this->endpoint = 'http://plagcheck.local';
|
||||
$this->token = $token;
|
||||
$this->endpoint = $endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send text for originality check.
|
||||
*
|
||||
* @param $authorhash
|
||||
* @param $cousereid
|
||||
* @param $assignmentid
|
||||
@ -78,6 +89,7 @@ class plagiarism_pchkorg_api_provider {
|
||||
* @param $content
|
||||
* @param $mime
|
||||
* @param $filename
|
||||
*
|
||||
* @return |null
|
||||
*/
|
||||
public function send_group_text($authorhash, $cousereid, $assignmentid, $submissionid, $attachmentid, $content, $mime,
|
||||
@ -124,6 +136,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build HTTP body of request.
|
||||
*
|
||||
* @param $boundary
|
||||
* @param $authorhash
|
||||
* @param $cousereid
|
||||
@ -155,6 +169,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
$body .= $this->get_part('attachment_id', $attachmentid, $boundary);
|
||||
$body .= $this->get_part('filename', $filename, $boundary);
|
||||
$body .= $this->get_part('language', 'en', $boundary);
|
||||
$body .= $this->get_part('skip_english_words_validation', '1', $boundary);
|
||||
$body .= $this->get_part('skip_percentage_words_validation', '1', $boundary);
|
||||
$body .= $this->get_file_part('content', $content, $mime, $filename, $boundary);
|
||||
$body .= '--' . $boundary . '--' . $eol;
|
||||
|
||||
@ -162,12 +178,15 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send text to the service for check.
|
||||
*
|
||||
* @param $content
|
||||
* @param $mime
|
||||
* @param $filename
|
||||
* @return |null
|
||||
*/
|
||||
public function send_text($content, $mime, $filename) {
|
||||
|
||||
$boundary = sprintf('PLAGCHECKBOUNDARY-%s', uniqid(time()));
|
||||
|
||||
$curl = new curl();
|
||||
@ -201,6 +220,32 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method send information to service thar agreement had been accepted.
|
||||
* Method will be called only for personal account type.
|
||||
*
|
||||
*/
|
||||
public function save_accepted_agreement() {
|
||||
$curl = new curl();
|
||||
$curl->post(
|
||||
$this->endpoint . '/api/v1/agreement/create/moodle-plugin/2019-04-11/',
|
||||
'',
|
||||
array(
|
||||
'CURLOPT_RETURNTRANSFER' => true,
|
||||
'CURLOPT_FOLLOWLOCATION' => true,
|
||||
'CURLOPT_SSL_VERIFYHOST' => false,
|
||||
'CURLOPT_SSL_VERIFYPEER' => false,
|
||||
'CURLOPT_POST' => true,
|
||||
'CURLOPT_HTTPHEADER' => array(
|
||||
'X-API-TOKEN: ' . $this->generate_api_token(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build part of HTTP body.
|
||||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @param $boundary
|
||||
@ -217,6 +262,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build part of HTTP body. This part contains file.
|
||||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @param $mime
|
||||
@ -237,6 +284,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build body for http-request.
|
||||
*
|
||||
* @param $boundary
|
||||
* @param $content
|
||||
* @param $mime
|
||||
@ -248,6 +297,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
|
||||
$body = '';
|
||||
$body .= $this->get_part('language', 'en', $boundary);
|
||||
$body .= $this->get_part('skip_english_words_validation', '1', $boundary);
|
||||
$body .= $this->get_part('skip_percentage_words_validation', '1', $boundary);
|
||||
$body .= $this->get_file_part('text', $content, $mime, $filename, $boundary);
|
||||
$body .= '--' . $boundary . '--' . $eol;
|
||||
|
||||
@ -255,15 +306,20 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert user email to sha256 salted hash.
|
||||
*
|
||||
* @param $email
|
||||
* @return string
|
||||
*/
|
||||
public function user_email_to_hash($email) {
|
||||
// We don't send raw user email to service.
|
||||
// We don't send raw user email to the service.
|
||||
return hash('sha256', $this->token . $email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check type of service account.
|
||||
* There are two types of accounts: personal and group.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_group_token() {
|
||||
@ -271,6 +327,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that user belongs to group when it is group account.
|
||||
*
|
||||
* @param string $email
|
||||
* @return bool
|
||||
*/
|
||||
@ -307,8 +365,11 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check status of document.
|
||||
* If document has been checked, state is 5.
|
||||
*
|
||||
* @param $textid
|
||||
* @return |null
|
||||
* @return object|null
|
||||
*/
|
||||
public function check_text($textid) {
|
||||
$curl = new curl();
|
||||
@ -333,6 +394,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build url for the api.
|
||||
*
|
||||
* @param $id
|
||||
* @return string
|
||||
*/
|
||||
@ -341,6 +404,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate token for API auth.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_api_token() {
|
||||
@ -354,6 +419,8 @@ class plagiarism_pchkorg_api_provider {
|
||||
}
|
||||
|
||||
/**
|
||||
* List of supported mime.
|
||||
*
|
||||
* @param $mime
|
||||
* @return bool
|
||||
*/
|
||||
@ -364,7 +431,17 @@ class plagiarism_pchkorg_api_provider {
|
||||
'application/rtf',
|
||||
'application/vnd.oasis.opendocument.text',
|
||||
'text/plain',
|
||||
'plain/text',
|
||||
'application/pdf',
|
||||
), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return maximum size of document.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_max_filesize() {
|
||||
return 20 * 1048576;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ defined('MOODLE_INTERNAL') || die();
|
||||
class plagiarism_pchkorg_config_model {
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if plugin is enable for some specific module.
|
||||
* Result is static.
|
||||
*
|
||||
* @param $module
|
||||
* @return bool
|
||||
*/
|
||||
@ -60,6 +64,9 @@ class plagiarism_pchkorg_config_model {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Save plugin settings.
|
||||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
*/
|
||||
@ -104,6 +111,10 @@ class plagiarism_pchkorg_config_model {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Fetch all plugin settings as array.
|
||||
* Result is static.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_system_config() {
|
||||
|
@ -57,10 +57,14 @@ class provider implements
|
||||
'cm' => 'privacy:metadata:plagiarism_pchkorg_files:cm',
|
||||
'fileid' => 'privacy:metadata:plagiarism_pchkorg_files:fileid',
|
||||
'userid' => 'privacy:metadata:plagiarism_pchkorg_files:userid',
|
||||
'state' => 'privacy:metadata:plagiarism_pchkorg_files:state',
|
||||
'score' => 'privacy:metadata:plagiarism_pchkorg_files:score',
|
||||
'created_at' => 'privacy:metadata:plagiarism_pchkorg_files:created_at',
|
||||
'textid' => 'privacy:metadata:plagiarism_pchkorg_files:textid',
|
||||
'reportid' => 'privacy:metadata:plagiarism_pchkorg_files:reportid',
|
||||
'signature' => 'privacy:metadata:plagiarism_pchkorg_files:signature',
|
||||
'attempt' => 'privacy:metadata:plagiarism_pchkorg_files:attempt',
|
||||
'itemid' => 'privacy:metadata:plagiarism_pchkorg_files:itemid',
|
||||
|
||||
),
|
||||
'privacy:metadata:plagiarism_pchkorg_files'
|
||||
|
@ -21,24 +21,37 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace plagiarism_pchkorg\task;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if (empty($error)) {
|
||||
$PAGE->requires->js_init_code('window.document.getElementById("plagiarism_pchkorg_report_id").submit();', false);
|
||||
echo $OUTPUT->header();
|
||||
?>
|
||||
<form id="plagiarism_pchkorg_report_id" action="<?php echo htmlspecialchars($action) ?>" method="post">
|
||||
<input type="hidden" name="token" value="<?php echo htmlspecialchars($token) ?>"/>
|
||||
<input type="hidden" name="lms-type" value="moodle"/>
|
||||
<input type="submit" value="<?php echo get_string('pchkorg_check_for_plagiarism_report', 'plagiarism_pchkorg'); ?>">
|
||||
</form>
|
||||
<?php
|
||||
} else {
|
||||
echo $OUTPUT->header();
|
||||
?>
|
||||
<h2>Error: <?php
|
||||
echo htmlspecialchars($error) ?></h2>
|
||||
<?php
|
||||
}
|
||||
/**
|
||||
* Send queued submissions to Turnitin.
|
||||
*/
|
||||
class send_submissions extends \core\task\scheduled_task {
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
/**
|
||||
* Name of the task.
|
||||
*
|
||||
* @return string
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function get_name() {
|
||||
return get_string('sendqueuedsubmissions', 'plagiarism_pchkorg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Task execution.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
public function execute() {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/plagiarism/pchkorg/lib.php');
|
||||
|
||||
$plugin = new \plagiarism_plugin_pchkorg();
|
||||
$plugin->cron_send_submissions();
|
||||
}
|
||||
}
|
@ -21,32 +21,36 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace plagiarism_pchkorg\task;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class plagiarism_pchkorg_url_generator
|
||||
* Update report Scores from Turnitin.
|
||||
*/
|
||||
class plagiarism_pchkorg_url_generator {
|
||||
class update_reports extends \core\task\scheduled_task {
|
||||
|
||||
/**
|
||||
* @param $cmid
|
||||
* @param $fileid
|
||||
* @return moodle_url
|
||||
* @throws moodle_exception
|
||||
* Get a name of task
|
||||
*
|
||||
* @return string
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function get_check_url($cmid, $fileid) {
|
||||
return new moodle_url(sprintf(
|
||||
'/plagiarism/pchkorg/page/report.php?cmid=%s&file=%s',
|
||||
intval($cmid),
|
||||
intval($fileid)
|
||||
)
|
||||
);
|
||||
public function get_name() {
|
||||
return get_string('updatereportscores', 'plagiarism_pchkorg');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return moodle_url
|
||||
* @throws moodle_exception
|
||||
* Task execution.
|
||||
*
|
||||
* @throws \dml_exception
|
||||
*/
|
||||
public function get_status_url() {
|
||||
return new moodle_url('/plagiarism/pchkorg/page/status.php');
|
||||
public function execute() {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot.'/plagiarism/pchkorg/lib.php');
|
||||
|
||||
$plugin = new \plagiarism_plugin_pchkorg();
|
||||
$plugin->cron_update_reports();
|
||||
}
|
||||
}
|
@ -23,37 +23,21 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
echo $OUTPUT->header();
|
||||
?>
|
||||
|
||||
<style>
|
||||
.plagiarism-preview-content {
|
||||
width: 800px;
|
||||
height: 400px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.plagiarism-preview-content-inner {
|
||||
/*white-space: pre;*/
|
||||
}
|
||||
</style>
|
||||
<br/>
|
||||
<div class="plagiarism-preview-content">
|
||||
<div class="plagiarism-preview-content-inner">
|
||||
<?php
|
||||
echo nl2br(htmlspecialchars($content, ENT_COMPAT | ENT_HTML401, $encoding = 'UTF-8')) ?>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<?php
|
||||
|
||||
if ($issupported) {
|
||||
echo $form->display();
|
||||
} else {
|
||||
echo 'file not supported';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
echo $OUTPUT->footer();
|
||||
$observers = array (
|
||||
array(
|
||||
'eventname' => '\assignsubmission_file\event\assessable_uploaded',
|
||||
'callback' => 'plagiarism_pchkorg_observer::assignsubmission_file_uploaded'
|
||||
),
|
||||
array(
|
||||
'eventname' => '\assignsubmission_onlinetext\event\assessable_uploaded',
|
||||
'callback' => 'plagiarism_pchkorg_observer::assignsubmission_onlinetext_uploaded'
|
||||
),
|
||||
array(
|
||||
'eventname' => '\mod_assign\event\assessable_submitted',
|
||||
'callback' => 'plagiarism_pchkorg_observer::assignsubmission_submitted'
|
||||
),
|
||||
array(
|
||||
'eventname' => '\core\event\course_module_deleted',
|
||||
'callback' => 'plagiarism_pchkorg_observer::course_module_deleted'
|
||||
),
|
||||
);
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="plagiarism/pchkorg/db" VERSION="20190318" COMMENT="XMLDB file for Moodle plagiarism/pchkorg plugin."
|
||||
<XMLDB PATH="plagiarism/pchkorg/db" VERSION="20190406" COMMENT="XMLDB file for Moodle plagiarism/pchkorg plugin."
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
@ -8,14 +8,16 @@
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="cm" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="fileid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="fileid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="state" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="score" TYPE="float" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="created_at" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
|
||||
<FIELD NAME="textid" TYPE="int" LENGTH="11" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="reportid" TYPE="int" LENGTH="11" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="signature" TYPE="char" LENGTH="40" NOTNULL="false" DEFAULT="NULL" SEQUENCE="false" COMMENT="Sha1 signature of content"/>
|
||||
<FIELD NAME="attempt" TYPE="int" LENGTH="5" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
|
||||
<FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
|
@ -23,24 +23,23 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
|
||||
/**
|
||||
* Class send_text_form
|
||||
*/
|
||||
class send_text_form extends moodleform {
|
||||
|
||||
/**
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function definition() {
|
||||
$mform = $this->_form; // Don't forget the underscore!
|
||||
|
||||
$mform->addElement('hidden', 'fileid', '');
|
||||
$mform->setType('fileid', PARAM_INT);
|
||||
$mform->addElement('hidden', 'cmid', '');
|
||||
$mform->setType('cmid', PARAM_INT);
|
||||
|
||||
$this->add_action_buttons(false, get_string('pchkorg_submit', 'plagiarism_pchkorg'));
|
||||
}
|
||||
}
|
||||
$tasks = array(
|
||||
array(
|
||||
'classname' => 'plagiarism_pchkorg\task\update_reports',
|
||||
'blocking' => 0,
|
||||
'minute' => '*/5',
|
||||
'hour' => '*',
|
||||
'day' => '*',
|
||||
'dayofweek' => '*',
|
||||
'month' => '*'
|
||||
),
|
||||
array(
|
||||
'classname' => 'plagiarism_pchkorg\task\send_submissions',
|
||||
'blocking' => 0,
|
||||
'minute' => '*/5',
|
||||
'hour' => '*',
|
||||
'day' => '*',
|
||||
'dayofweek' => '*',
|
||||
'month' => '*'
|
||||
),
|
||||
);
|
@ -24,11 +24,14 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Class plagiarism_pchkorg_setup_form
|
||||
* Class defined plugin settings form.
|
||||
*/
|
||||
class plagiarism_pchkorg_setup_form extends moodleform {
|
||||
|
||||
/**
|
||||
*
|
||||
* Method defined plugin settings form.
|
||||
*
|
||||
* @throws coding_exception
|
||||
*/
|
||||
public function definition() {
|
||||
|
@ -36,18 +36,23 @@ $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['pchkorg_disclosure'] = 'Submission will be sent to <a target="_blank" href="https://plagiarismcheck.org/">PlagiarismCheck.org</a> for check.
|
||||
<br />
|
||||
By submitting assignment I agree with <a target="_blank" href="https://plagiarismcheck.org/terms-of-service/">Terms & Conditions</a> '
|
||||
. 'and <a target="_blank" href="https://plagiarismcheck.org/privacy-policy/">Privacy Policy</a>.';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files'] =
|
||||
'Table with information about a file within moodle system belonge to a check in plagiarismcheck.org system.';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:cm'] = 'Course module identity ';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:fileid'] = 'Identity of a submitted file';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:userid'] = 'Identity of user who submit file';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:state'] = 'Status of a document. For example: queued, sent, checked.';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:score'] = 'Originality score';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:created_at'] = 'Date and time when document was saved.';
|
||||
$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_files:attempt'] = 'Amount of sending attempts';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_files:itemid'] = 'Identity of submission';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_config'] = 'Table with module settings';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_config:cm'] = 'Course module identity';
|
||||
$string['privacy:metadata:plagiarism_pchkorg_config:name'] = 'Name of option';
|
||||
@ -56,6 +61,11 @@ $string['privacy:metadata:plagiarism_pchkorg_config:value'] = 'Value of option';
|
||||
$string['privacy:metadata:plagiarism_pchkorg'] = 'Service for originality check plagiarismcheck.org';
|
||||
$string['privacy:metadata:plagiarism_pchkorg:file'] =
|
||||
'Submission attachment for originality checkprivacy:metadata:plagiarism_pchkorg';
|
||||
|
||||
$string['pchkorg:enable'] = 'Enable or Disable plugin';
|
||||
$string['privacy:metadata:core_files'] = 'We need a content of submission, for originality check';
|
||||
$string['sendqueuedsubmissions'] = '';
|
||||
$string['updatereportscores'] = '';
|
||||
$string['pchkorg_label_title'] = 'PlagiarismCheck.org ID: %s; Similarity Score: %s%%';
|
||||
$string['pchkorg_label_result'] = 'ID: %s Similarity: %s%%';
|
||||
$string['pchkorg_label_sent'] = 'ID: %s Sent';
|
||||
$string['pchkorg_label_queued'] = 'In queue';
|
||||
|
464
lib.php
464
lib.php
@ -29,7 +29,6 @@ require_once($CFG->dirroot . '/plagiarism/lib.php');
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
require_once($CFG->libdir . '/accesslib.php');
|
||||
require_once(__DIR__ . '/classes/plagiarism_pchkorg_config_model.php');
|
||||
require_once(__DIR__ . '/classes/plagiarism_pchkorg_url_generator.php');
|
||||
require_once(__DIR__ . '/classes/plagiarism_pchkorg_api_provider.php');
|
||||
|
||||
/**
|
||||
@ -37,25 +36,30 @@ require_once(__DIR__ . '/classes/plagiarism_pchkorg_api_provider.php');
|
||||
*/
|
||||
class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
/**
|
||||
* hook to allow plagiarism specific information to be displayed beside a submission
|
||||
* hook to allow plagiarism specific information to be displayed beside a submission.
|
||||
*
|
||||
* @param array $linkarraycontains all relevant information for the plugin to generate a link
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function get_links($linkarray) {
|
||||
|
||||
global $DB, $USER;
|
||||
|
||||
$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'];
|
||||
if (array_key_exists('file', $linkarray)) {
|
||||
$file = $linkarray['file'];
|
||||
} else {
|
||||
// Online text submission.
|
||||
$file = null;
|
||||
}
|
||||
|
||||
// We can do nothing with submissions which we can not handle.
|
||||
if (!$apiprovider->is_supported_mime($file->get_mimetype())) {
|
||||
if (null !== $file && !$apiprovider->is_supported_mime($file->get_mimetype())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -78,8 +82,8 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
// 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.
|
||||
// Even if service will be unavailable, method will try call API only once.
|
||||
// Also, we don't use raw user email.
|
||||
if (!$apiprovider->is_group_member($USER->email)) {
|
||||
return '';
|
||||
}
|
||||
@ -91,28 +95,94 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
|
||||
$where = new \stdClass();
|
||||
$where->cm = $cmid;
|
||||
$where->fileid = $file->get_id();
|
||||
|
||||
$filerecord = $DB->get_record('plagiarism_pchkorg_files', (array) $where);
|
||||
|
||||
$checkurl = $urlgenerator->get_check_url($cmid, $file->get_id());
|
||||
|
||||
if ($filerecord) {
|
||||
$label = sprintf('%.2f', $filerecord->score) . '%';
|
||||
$link = sprintf(' <a href="%s" target="_blank">( %s )</a> ', $checkurl->__toString(), $label);
|
||||
if ($file === null) {
|
||||
$where->signature = sha1($linkarray['content']);
|
||||
$where->fileid = null;
|
||||
} else {
|
||||
$label = get_string('pchkorg_check_for_plagiarism', 'plagiarism_pchkorg');
|
||||
$link = sprintf(' <a href="%s">( %s )</a> ', $checkurl->__toString(), $label);
|
||||
$where->fileid = $file->get_id();
|
||||
}
|
||||
|
||||
return $link;
|
||||
$filerecords = $DB->get_records('plagiarism_pchkorg_files', (array) $where,
|
||||
'id', '*', 0, 1);
|
||||
|
||||
if ($filerecords) {
|
||||
$filerecord = end($filerecords);
|
||||
|
||||
$img = new moodle_url('/plagiarism/pchkorg/pix/icon.png');
|
||||
$imgsrc = $img->__toString();
|
||||
|
||||
// Text had been successfully checked.
|
||||
if ($filerecord->state == 5) {
|
||||
$action = $apiprovider->get_report_action($filerecord->textid);
|
||||
$reporttoken = $apiprovider->generate_api_token();
|
||||
$formid = 'plagiarism_pchkorg_report_id_' . $filerecord->id;
|
||||
$score = $filerecord->score;
|
||||
$title = sprintf(get_string('pchkorg_label_title', 'plagiarism_pchkorg'),
|
||||
$filerecord->textid,
|
||||
$score);
|
||||
$label = sprintf(get_string('pchkorg_label_result', 'plagiarism_pchkorg'), $filerecord->textid, $score);
|
||||
|
||||
if ($score < 30) {
|
||||
$color = '#63ec80a1';
|
||||
} else if (30 < $score && $score < 60) {
|
||||
$color = '#f7b011';
|
||||
} else {
|
||||
$color = '#f04343';
|
||||
}
|
||||
|
||||
return '
|
||||
<a style="padding: 5px 3px;
|
||||
text-decoration: none;
|
||||
background-color: ' . $color . ';
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
margin: 4px;"
|
||||
href="#" title="' . $title . '"
|
||||
class="plagiarism_pchkorg_report_id_score"
|
||||
onclick="document.getElementById(\'' . $formid . '\').submit(); return false;">
|
||||
<img src="' . $imgsrc . '" alt="logo" width="20px;" />
|
||||
' . $label . '
|
||||
</a><form target="_blank" id="' . $formid . '" action="' . $action . '" method="post">
|
||||
<input type="hidden" name="token" value="' . $reporttoken . '"/>
|
||||
<input type="hidden" name="lms-type" value="moodle"/>
|
||||
</form>';
|
||||
} else if ($filerecord->state == 10) {
|
||||
$label = get_string('pchkorg_label_queued', 'plagiarism_pchkorg');
|
||||
return '
|
||||
<span style="padding: 5px 3px;
|
||||
text-decoration: none;
|
||||
background-color: #eeeded;
|
||||
color: black;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
margin: 4px;"
|
||||
href="#" class="plagiarism_pchkorg_report_id_score">
|
||||
<img src="' . $imgsrc . '" alt="logo" width="20px;" />
|
||||
' . $label . '
|
||||
</span>';
|
||||
} else if ($filerecord->state == 12) {
|
||||
$label = sprintf(get_string('pchkorg_label_sent', 'plagiarism_pchkorg'), $filerecord->textid);
|
||||
return '
|
||||
<span style="padding: 5px 3px;
|
||||
text-decoration: none;
|
||||
background-color: #eeeded;
|
||||
color: black;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
margin: 4px;"
|
||||
href="#" class="plagiarism_pchkorg_report_id_score">
|
||||
<img src="' . $imgsrc . '" alt="logo" width="20px;" />
|
||||
' . $label . '
|
||||
</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/* hook to save plagiarism specific settings on a module settings page
|
||||
* @param object $data - data from an mform submission.
|
||||
*/
|
||||
/**
|
||||
* @param $data
|
||||
* hook to save plagiarism specific settings on a module settings page
|
||||
*
|
||||
* @param object $data - data from an mform submission.
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function save_form_elements($data) {
|
||||
@ -148,6 +218,9 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Build plugin settings form.
|
||||
*
|
||||
* @param object $mform
|
||||
* @param object $context
|
||||
* @param string $modulename
|
||||
@ -171,7 +244,8 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
'cm' => $cm,
|
||||
));
|
||||
if (!empty($records)) {
|
||||
$mform->setDefault($records[0]->name, $records[0]->value);
|
||||
$record = end($records);
|
||||
$mform->setDefault($record->name, $record->value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +265,7 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* hook to allow a disclosure to be printed notifying users what will happen with their submission
|
||||
* hook to allow a disclosure to be printed notifying users what will happen with their submission.
|
||||
*
|
||||
* @param int $cmid - course module id
|
||||
* @return string
|
||||
@ -206,7 +280,7 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
// Get course details.
|
||||
$cm = get_coursemodule_from_id('', $cmid);
|
||||
|
||||
if ($cm->modname != 'assign') {
|
||||
if (!$cm || $cm->modname != 'assign') {
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -217,7 +291,7 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($configmodel->is_enabled_for_module($cmid) != '1') {
|
||||
if (!$configmodel->is_enabled_for_module($cmid)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@ -229,9 +303,345 @@ class plagiarism_plugin_pchkorg extends plagiarism_plugin {
|
||||
$formatoptions->noclean = true;
|
||||
$formatoptions->cmid = $cmid;
|
||||
|
||||
$result .= '<div style="background-color: #d5ffd5; padding: 10px; border: 1px solid #b7dab7">';
|
||||
$result .= format_text(get_string('pchkorg_disclosure', 'plagiarism_pchkorg'), FORMAT_MOODLE, $formatoptions);
|
||||
$result .= '</div>';
|
||||
$result .= $OUTPUT->box_end();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method will handle event assessable_uploaded.
|
||||
*
|
||||
* @param $eventdata
|
||||
* @return bool
|
||||
* @throws coding_exception
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function event_handler($eventdata) {
|
||||
global $USER, $DB;
|
||||
|
||||
// We support only assign module so just ignore all other.
|
||||
if ($eventdata['other']['modulename'] !== 'assign') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
$apitoken = $pchkorgconfigmodel->get_system_config('pchkorg_token');
|
||||
$apiprovider = new plagiarism_pchkorg_api_provider($apitoken);
|
||||
|
||||
// SQL will be called only once, result is static.
|
||||
$config = $pchkorgconfigmodel->get_system_config('pchkorg_use');
|
||||
if ('1' !== $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Receive couser moudle id.
|
||||
$cmid = $eventdata['contextinstanceid'];
|
||||
// Remove the event if the course module no longer exists.
|
||||
$cm = get_coursemodule_from_id($eventdata['other']['modulename'], $cmid);
|
||||
if (!$cm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// SQL will be called only once per page. There is static result inside.
|
||||
// Plugin is enabled for this module.
|
||||
if (!$pchkorgconfigmodel->is_enabled_for_module($cm->id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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 raw users email.
|
||||
if (!$apiprovider->is_group_member($USER->email)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the author and submitter.
|
||||
$submitter = $eventdata['userid'];
|
||||
$author = (!empty($eventdata['relateduserid'])) ? $eventdata['relateduserid'] : $eventdata['userid'];
|
||||
|
||||
// Related user ID will be NULL if an instructor submits on behalf of a student who is in a group.
|
||||
// To get around this, we get the group ID, get the group members and set the author as the first student in the group.
|
||||
if ((empty($eventdata['relateduserid'])) && ($eventdata['other']['modulename'] == 'assign')
|
||||
&& has_capability('mod/assign:editothersubmission', context_module::instance($cm->id), $submitter)) {
|
||||
$moodlesubmission = $DB->get_record('assign_submission', array('id' => $eventdata['objectid']), 'id, groupid');
|
||||
if (!empty($moodlesubmission->groupid)) {
|
||||
$author = $this->get_first_group_author($cm->course, $moodlesubmission->groupid);
|
||||
}
|
||||
}
|
||||
|
||||
// Get actual text content and files to be submitted for draft submissions.
|
||||
// As this won't be present in eventdata for certain event types.
|
||||
if ($eventdata['other']['modulename'] == 'assign' && $eventdata['eventtype'] == "assessable_submitted") {
|
||||
// Get content.
|
||||
$moodlesubmission = $DB->get_record('assign_submission', array('id' => $eventdata['objectid']), 'id');
|
||||
if ($moodletextsubmission = $DB->get_record('assignsubmission_onlinetext',
|
||||
array('submission' => $moodlesubmission->id), 'onlinetext')) {
|
||||
$eventdata['other']['content'] = $moodletextsubmission->onlinetext;
|
||||
}
|
||||
|
||||
$filesconditions = array(
|
||||
'component' => 'assignsubmission_file',
|
||||
'itemid' => $moodlesubmission->id,
|
||||
'userid' => $author
|
||||
);
|
||||
|
||||
$moodlefiles = $DB->get_records('files', $filesconditions);
|
||||
if ($moodlefiles) {
|
||||
$fs = get_file_storage();
|
||||
foreach ($moodlefiles as $filedb) {
|
||||
$file = $fs->get_file_by_id($filedb->id);
|
||||
|
||||
if (!$file) {
|
||||
// We can not find file so we do not send it in queue.
|
||||
continue;
|
||||
} else {
|
||||
try {
|
||||
// Check that we can fetch content without exception.
|
||||
$content = $file->get_content();
|
||||
} catch (Exception $e) {
|
||||
// No we can not.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($file->get_filename() === '.') {
|
||||
continue;
|
||||
}
|
||||
$filemime = $file->get_mimetype();
|
||||
|
||||
// File type is not supported.
|
||||
if (!$apiprovider->is_supported_mime($filemime)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filerecord = new \stdClass();
|
||||
$filerecord->fileid = $file->get_id();
|
||||
$filerecord->cm = $cmid;
|
||||
$filerecord->userid = $USER->id;
|
||||
$filerecord->textid = null;
|
||||
$filerecord->state = 10;
|
||||
$filerecord->created_at = time();
|
||||
$filerecord->itemid = $eventdata['objectid'];
|
||||
$filerecord->signature = sha1($content);
|
||||
|
||||
$DB->insert_record('plagiarism_pchkorg_files', $filerecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Queue text content to send to plagiarismcheck.org.
|
||||
// If there was an error when creating the assignment then still queue the submission so it can be saved as failed.
|
||||
if (in_array($eventdata['eventtype'], array("content_uploaded", "assessable_submitted"))
|
||||
&& !empty($eventdata['other']['content'])) {
|
||||
|
||||
$signature = sha1($eventdata['other']['content']);
|
||||
|
||||
$filesconditions = array(
|
||||
'signature' => $signature,
|
||||
'cm' => $cmid,
|
||||
'userid' => $USER->id,
|
||||
'itemid' => $eventdata['objectid']
|
||||
);
|
||||
|
||||
$oldfile = $DB->get_record('plagiarism_pchkorg_files', $filesconditions);
|
||||
if ($oldfile) {
|
||||
// There is the same check in database, so we can skip this one.
|
||||
return true;
|
||||
}
|
||||
|
||||
$filerecord = new \stdClass();
|
||||
$filerecord->fileid = null;
|
||||
$filerecord->cm = $cmid;
|
||||
$filerecord->userid = $USER->id;
|
||||
$filerecord->textid = null;
|
||||
$filerecord->state = 10;
|
||||
$filerecord->created_at = time();
|
||||
|
||||
$filerecord->itemid = $eventdata['objectid'];
|
||||
$filerecord->signature = $signature;
|
||||
|
||||
$DB->insert_record('plagiarism_pchkorg_files', $filerecord);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Will find the first user in group assignment.
|
||||
*
|
||||
* @param $cmid
|
||||
* @param $groupid
|
||||
* @return mixed
|
||||
* @throws coding_exception
|
||||
*/
|
||||
private function get_first_group_author($cmid, $groupid) {
|
||||
static $context;
|
||||
if (empty($context)) {
|
||||
$context = context_course::instance($cmid);
|
||||
}
|
||||
|
||||
$groupmembers = groups_get_members($groupid, "u.id");
|
||||
foreach ($groupmembers as $author) {
|
||||
if (!has_capability('mod/assign:grade', $context, $author->id)) {
|
||||
return $author->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Method will be called by cron. Method sends queued files into plagiarism check system.
|
||||
*
|
||||
* @return bool
|
||||
* @throws coding_exception
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function cron_send_submissions() {
|
||||
global $DB;
|
||||
|
||||
$pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
$apitoken = $pchkorgconfigmodel->get_system_config('pchkorg_token');
|
||||
$apiprovider = new plagiarism_pchkorg_api_provider($apitoken);
|
||||
|
||||
// SQL will be called only once, result is static.
|
||||
$config = $pchkorgconfigmodel->get_system_config('pchkorg_use');
|
||||
if ('1' !== $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$filesconditions = array('state' => 10);
|
||||
|
||||
$moodlefiles = $DB->get_records('plagiarism_pchkorg_files', $filesconditions,
|
||||
'id', '*', 0, 20);
|
||||
if ($moodlefiles) {
|
||||
$fs = get_file_storage();
|
||||
|
||||
foreach ($moodlefiles as $filedb) {
|
||||
$textid = null;
|
||||
$user = $DB->get_record('user', array('id' => $filedb->userid));
|
||||
// This is attached file.
|
||||
$cm = get_coursemodule_from_id('', $filedb->cm);
|
||||
if ($filedb->fileid === null) {
|
||||
$moodletextsubmission = $DB->get_record('assignsubmission_onlinetext',
|
||||
array('submission' => $filedb->itemid), '*');
|
||||
if ($moodletextsubmission) {
|
||||
$content = $moodletextsubmission->onlinetext;
|
||||
|
||||
if ($apiprovider->is_group_token()) {
|
||||
$textid = $apiprovider->send_group_text(
|
||||
$apiprovider->user_email_to_hash($user->email),
|
||||
$cm->course,
|
||||
$cm->id,
|
||||
$moodletextsubmission->id,
|
||||
$moodletextsubmission->id,
|
||||
html_to_text($content, 75, false),
|
||||
'plain/text',
|
||||
sprintf('%s-submussion.txt', $moodletextsubmission->id)
|
||||
);
|
||||
} else {
|
||||
$textid = $apiprovider->send_text(
|
||||
html_to_text($content, 75, false),
|
||||
'plain/text',
|
||||
sprintf('%s-submussion.txt', $moodletextsubmission->id)
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$moodlesubmission = $DB->get_record('assign_submission', array('assignment' => $cm->instance,
|
||||
'userid' => $filedb->userid, 'id' => $filedb->itemid), 'id');
|
||||
$file = $fs->get_file_by_id($filedb->fileid);
|
||||
if ($apiprovider->is_group_token()) {
|
||||
$textid = $apiprovider->send_group_text(
|
||||
$apiprovider->user_email_to_hash($user->email),
|
||||
$cm->course,
|
||||
$cm->id,
|
||||
$moodlesubmission->id,
|
||||
$file->get_id(),
|
||||
$file->get_content(),
|
||||
$file->get_mimetype(),
|
||||
$file->get_filename()
|
||||
);
|
||||
} else {
|
||||
$agreementwhere = array(
|
||||
'cm' => 0,
|
||||
'name' => 'accepter_agreement',
|
||||
'value' => '1'
|
||||
);
|
||||
$agreementaccepted = $DB->get_records('plagiarism_pchkorg_config', $agreementwhere);
|
||||
if (!$agreementaccepted) {
|
||||
$apiprovider->save_accepted_agreement();
|
||||
$DB->insert_record('plagiarism_pchkorg_config', $agreementwhere);
|
||||
}
|
||||
|
||||
$textid = $apiprovider->send_text(
|
||||
$file->get_content(),
|
||||
$file->get_mimetype(),
|
||||
$file->get_filename()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$filedbnew = new stdClass();
|
||||
$filedbnew->id = $filedb->id;
|
||||
if ($textid) {
|
||||
// Text was successfully sent to the service.
|
||||
$filedbnew->textid = $textid;
|
||||
$filedbnew->state = 12; // 12 - is SENT.
|
||||
} else {
|
||||
$filedbnew->attempt = $filedb->attempt + 1;
|
||||
if ($filedbnew->attempt > 6) {
|
||||
$filedbnew->state = 11; // Sending error.
|
||||
}
|
||||
}
|
||||
$DB->update_record('plagiarism_pchkorg_files', $filedbnew);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method will update similarity score and change status of checks.
|
||||
*
|
||||
* @return bool
|
||||
* @throws dml_exception
|
||||
*/
|
||||
public function cron_update_reports() {
|
||||
global $DB;
|
||||
|
||||
$pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
$apitoken = $pchkorgconfigmodel->get_system_config('pchkorg_token');
|
||||
$apiprovider = new plagiarism_pchkorg_api_provider($apitoken);
|
||||
|
||||
// SQL will be called only once, result is static.
|
||||
$config = $pchkorgconfigmodel->get_system_config('pchkorg_use');
|
||||
if ('1' !== $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$filesconditions = array('state' => 12);
|
||||
|
||||
$moodlefiles = $DB->get_records('plagiarism_pchkorg_files', $filesconditions,
|
||||
'id', '*', 0, 20);
|
||||
|
||||
foreach ($moodlefiles as $filedb) {
|
||||
$report = $apiprovider->check_text($filedb->textid);
|
||||
if ($report !== null) {
|
||||
$filedbnew = new stdClass();
|
||||
$filedbnew->id = $filedb->id;
|
||||
$filedbnew->state = 5;
|
||||
$filedbnew->reportid = $report->id;
|
||||
$filedbnew->score = $report->percent;
|
||||
|
||||
$DB->update_record('plagiarism_pchkorg_files', $filedbnew);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,95 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* @package plagiarism_pchkorg
|
||||
* @category plagiarism
|
||||
* @copyright PlagiarismCheck.org, https://plagiarismcheck.org/
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../config.php');
|
||||
require_once(__DIR__ . '/../lib.php');
|
||||
require_once(__DIR__ . '/../form/send_text_form.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_config_model.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_url_generator.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_api_provider.php');
|
||||
|
||||
global $PAGE, $CFG, $OUTPUT, $DB, $USER;
|
||||
|
||||
$pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
$urlgenerator = new plagiarism_pchkorg_url_generator();
|
||||
$apiprovider = new plagiarism_pchkorg_api_provider(
|
||||
$pchkorgconfigmodel->get_system_config('pchkorg_token')
|
||||
);
|
||||
|
||||
$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:grade', $context, null);
|
||||
if (!$isgranted) {
|
||||
die('{error: "access denied"}');
|
||||
}
|
||||
$fs = get_file_storage();
|
||||
$file = $fs->get_file_by_id($fileid);
|
||||
|
||||
if (!$file) {
|
||||
die('{error: "file not exists"}');
|
||||
}
|
||||
|
||||
if ('submission_files' !== $file->get_filearea()
|
||||
|| $file->get_contextid() != $context->id) {
|
||||
die('{error: "access denied"}');
|
||||
}
|
||||
|
||||
// Prevent JS caching.
|
||||
$CFG->cachejs = false;
|
||||
$PAGE->set_url($urlgenerator->get_status_url());
|
||||
$where = new \stdClass();
|
||||
$where->cm = $cmid;
|
||||
$where->fileid = $fileid;
|
||||
|
||||
$filerecord = $DB->get_record('plagiarism_pchkorg_files', (array) $where);
|
||||
|
||||
if (!$filerecord) {
|
||||
echo json_encode(array(
|
||||
'success' => false,
|
||||
'message' => '404 can not find text'
|
||||
));
|
||||
}
|
||||
|
||||
$report = $apiprovider->check_text($filerecord->textid);
|
||||
if ($checked = (null !== $report)) {
|
||||
$filerecord->reportid = $report->id;
|
||||
$filerecord->score = $report->percent;
|
||||
$DB->update_record('plagiarism_pchkorg_files', $filerecord);
|
||||
}
|
||||
|
||||
$location = new moodle_url(sprintf(
|
||||
'/plagiarism/pchkorg/page/report.php?cmid=%s&file=%s',
|
||||
intval($cmid),
|
||||
intval($fileid)
|
||||
));
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => true,
|
||||
'checked' => $checked,
|
||||
'location' => $location->out(false)
|
||||
));
|
169
page/report.php
169
page/report.php
@ -1,169 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* @package plagiarism_pchkorg
|
||||
* @category plagiarism
|
||||
* @copyright PlagiarismCheck.org, https://plagiarismcheck.org/
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../config.php');
|
||||
require_once(__DIR__ . '/../lib.php');
|
||||
require_once(__DIR__ . '/../form/send_text_form.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_config_model.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_url_generator.php');
|
||||
require_once(__DIR__ . '/../classes/plagiarism_pchkorg_api_provider.php');
|
||||
|
||||
global $PAGE, $CFG, $OUTPUT, $DB, $USER;
|
||||
|
||||
$pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
$urlgenerator = new plagiarism_pchkorg_url_generator();
|
||||
$apiprovider = new plagiarism_pchkorg_api_provider($pchkorgconfigmodel->get_system_config('pchkorg_token'));
|
||||
|
||||
$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, 0, false, MUST_EXIST);
|
||||
require_login($cm->course, true, $cm);
|
||||
$context = context_module::instance($cm->id);// Get context of course.
|
||||
|
||||
$isgranted = has_capability('mod/assign:view', $context, null);
|
||||
|
||||
if (!$isgranted) {
|
||||
die('403 permission denied');
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
$form = new send_text_form($currenturl = $urlgenerator->get_check_url($cmid, $fileid));
|
||||
|
||||
$CFG->cachejs = false;
|
||||
$PAGE->set_url($currenturl);
|
||||
$PAGE->set_pagelayout('report');
|
||||
$PAGE->set_title(get_string('pluginname', 'plagiarism_pchkorg'));
|
||||
$PAGE->set_heading(get_string('pluginname', 'plagiarism_pchkorg'));
|
||||
|
||||
if ('POST' === $_SERVER['REQUEST_METHOD']) { // Form submission.
|
||||
|
||||
$data = $form->get_data();
|
||||
$cmid = (int) $data->cmid;
|
||||
$fileid = (int) $data->fileid;
|
||||
|
||||
$file = $fs->get_file_by_id($fileid);
|
||||
|
||||
$where = new \stdClass();
|
||||
$where->cm = $cmid;
|
||||
$where->fileid = $file->get_id();
|
||||
|
||||
$filerecord = $DB->get_record('plagiarism_pchkorg_files', (array) $where);
|
||||
// Preventing some race condition.
|
||||
if ($filerecord) {
|
||||
redirect($urlgenerator->get_check_url($cmid, $fileid), 'Document already checked.');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ('submission_files' !== $file->get_filearea()
|
||||
|| $file->get_contextid() != $context->id) {
|
||||
die('permission denied');
|
||||
}
|
||||
|
||||
if (!$file) {
|
||||
// File not found.
|
||||
|
||||
die('404 not exists');
|
||||
}
|
||||
|
||||
if ($apiprovider->is_group_token()) {
|
||||
$textid = $apiprovider->send_group_text(
|
||||
$apiprovider->user_email_to_hash($USER->email),
|
||||
$cm->course,
|
||||
$cm->id,
|
||||
$cm->id,
|
||||
$file->get_id(),
|
||||
$file->get_content(),
|
||||
$file->get_mimetype(),
|
||||
$file->get_filename()
|
||||
);
|
||||
} else {
|
||||
$textid = $apiprovider->send_text(
|
||||
$file->get_content(),
|
||||
$file->get_mimetype(),
|
||||
$file->get_filename()
|
||||
);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
if (null !== $textid) {
|
||||
$filerecord = new \stdClass();
|
||||
$filerecord->fileid = $fileid;
|
||||
$filerecord->cm = $cmid;
|
||||
$filerecord->userid = $USER->id;
|
||||
$filerecord->textid = $textid;
|
||||
$filerecord->state = 1; // 1 - is SENT.
|
||||
$filerecord->created_at = time();
|
||||
|
||||
$DB->insert_record('plagiarism_pchkorg_files', $filerecord);
|
||||
} else {
|
||||
if ('Invalid token' === $apiprovider->get_last_error()) {
|
||||
$pchkorgconfigmodel->set_system_config('pchkorg_use', '0');
|
||||
}
|
||||
$message = $apiprovider->get_last_error();
|
||||
}
|
||||
|
||||
redirect($urlgenerator->get_check_url($cmid, $fileid), $message);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $fs->get_file_by_id($fileid);
|
||||
if ('submission_files' !== $file->get_filearea()
|
||||
|| $file->get_contextid() != $context->id) {
|
||||
die('permission denied');
|
||||
}
|
||||
if (!$file) {
|
||||
die('404 not exists');
|
||||
}
|
||||
|
||||
$where = new \stdClass();
|
||||
$where->cm = $cmid;
|
||||
$where->fileid = $fileid;
|
||||
|
||||
$filerecord = $DB->get_record('plagiarism_pchkorg_files', (array) $where);
|
||||
|
||||
if (!$filerecord) {
|
||||
$content = $file->get_content();
|
||||
$mime = $file->get_mimetype();
|
||||
|
||||
if ($issupported = $apiprovider->is_supported_mime($file->get_mimetype())) {
|
||||
if ('plain/text' === $mime || 'text/plain' === $mime) {
|
||||
$content = $content = $file->get_content();
|
||||
} else {
|
||||
$content = $file->get_filename();
|
||||
}
|
||||
|
||||
$default = array('fileid' => $fileid, 'cmid' => $cmid);
|
||||
$form->set_data($default);
|
||||
}
|
||||
|
||||
require('../view/send_text.php');
|
||||
} else if (null !== $filerecord->reportid) {
|
||||
$action = $apiprovider->get_report_action($filerecord->textid);
|
||||
$token = $apiprovider->generate_api_token();
|
||||
|
||||
require('../view/report.php');
|
||||
} else if (null !== $filerecord->textid) {
|
||||
|
||||
require('../view/check_report.php');
|
||||
}
|
BIN
pix/icon.png
Normal file
BIN
pix/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@ -35,7 +35,7 @@ $pchkorgconfigmodel = new plagiarism_pchkorg_config_model();
|
||||
require_login();
|
||||
admin_externalpage_setup('plagiarismpchkorg');
|
||||
|
||||
$context = context_system::instance(CONTEXT_SYSTEM);
|
||||
$context = context_system::instance();
|
||||
|
||||
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
|
||||
|
||||
|
@ -26,12 +26,11 @@ defined('MOODLE_INTERNAL') || die();
|
||||
if (!isset($plugin)) {
|
||||
$plugin = new stdClass();
|
||||
}
|
||||
$plugin->version = 2019031801;
|
||||
$plugin->version = 2019041101;
|
||||
$plugin->requires = 2017051501; // Requires Moodle 3.3 .
|
||||
$plugin->release = 'v3.1';
|
||||
$plugin->release = 'v3.2';
|
||||
$plugin->maturity = MATURITY_STABLE;
|
||||
|
||||
$plugin->component = 'plagiarism_pchkorg';
|
||||
$plugin->dependencies = array(
|
||||
'mod_assign' => ANY_VERSION,
|
||||
);
|
||||
);
|
||||
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
$ajaxurl = new moodle_url('/plagiarism/pchkorg/page/check.php');
|
||||
$PAGE->requires->js_init_code("
|
||||
var interval;
|
||||
var data = {
|
||||
'file': $('#plagcheck-loader').attr('data-file'),
|
||||
'cmid': $('#plagcheck-loader').attr('data-cmid')
|
||||
};
|
||||
var checkStatus = function () {
|
||||
$.post('{$ajaxurl}', data, function (response) {
|
||||
if (!response || !response.success) {
|
||||
$('#plagcheck-loader').hide();
|
||||
clearInterval(interval);
|
||||
} else if (response.checked) {
|
||||
$('#plagcheck-loader').hide();
|
||||
clearInterval(interval);
|
||||
window.location.href = response.location;
|
||||
}
|
||||
}, 'JSON');
|
||||
};
|
||||
interval = setInterval(checkStatus, 1000);
|
||||
", true);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
?>
|
||||
<style>
|
||||
.loader {
|
||||
border: 16px solid #f3f3f3; /* Light grey */
|
||||
border-top: 16px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<div id="plagcheck-loader" data-cmid="<?php
|
||||
echo intval($cmid) ?>" data-file="<?php
|
||||
echo intval($fileid) ?>" class="loader"></div>
|
||||
</div>
|
||||
<?php
|
||||
echo $OUTPUT->footer();
|
Loading…
Reference in New Issue
Block a user