diff --git a/admin/settings/plugins.php b/admin/settings/plugins.php
index 353377ae5814e..1beb39f58eab7 100644
--- a/admin/settings/plugins.php
+++ b/admin/settings/plugins.php
@@ -376,7 +376,17 @@
}
}
}
-
+if ($hassiteconfig && !empty($CFG->enableplagiarism)) {
+ $ADMIN->add('modules', new admin_category('plagiarism', get_string('plagiarism', 'plagiarism')));
+ $temp = new admin_settingpage('plagiarismsettings', get_string('plagiarismsettings', 'plagiarism'));
+ $temp->add(new admin_setting_manageplagiarism());
+ $ADMIN->add('plagiarism', $temp);
+ foreach (get_plugin_list('plagiarism') as $plugin => $plugindir) {
+ if (file_exists($plugindir.'/settings.php')) {
+ $ADMIN->add('plagiarism', new admin_externalpage('plagiarism'.$plugin, get_string($plugin, 'plagiarism_'.$plugin), "$CFG->wwwroot/plagiarism/$plugin/settings.php", 'moodle/site:config'));
+ }
+ }
+}
$ADMIN->add('reports', new admin_externalpage('comments', get_string('comments'), $CFG->wwwroot.'/comment/', 'moodle/site:viewreports'));
/// Now add reports
diff --git a/admin/settings/subsystems.php b/admin/settings/subsystems.php
index e30f07ae97019..7998f47b26567 100644
--- a/admin/settings/subsystems.php
+++ b/admin/settings/subsystems.php
@@ -39,4 +39,6 @@
$optionalsubsystems->add(new admin_setting_configcheckbox('enableavailability',
get_string('enableavailability','condition'),
get_string('configenableavailability','condition'), 0));
+
+ $optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', get_string('enableplagiarism','plagiarism'), get_string('configenableplagiarism','plagiarism'), 0));
}
diff --git a/course/modedit.php b/course/modedit.php
index 3a7ae149b4458..4b5583891d365 100644
--- a/course/modedit.php
+++ b/course/modedit.php
@@ -29,6 +29,7 @@
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->libdir.'/completionlib.php');
require_once($CFG->libdir.'/conditionlib.php');
+require_once($CFG->libdir.'/plagiarismlib.php');
$add = optional_param('add', '', PARAM_ALPHA); // module name
$update = optional_param('update', 0, PARAM_INT);
@@ -560,6 +561,7 @@
rebuild_course_cache($course->id);
grade_regrade_final_grades($course->id);
+ plagiarism_save_form_elements($fromform); //save plagiarism settings
if (isset($fromform->submitbutton)) {
redirect("$CFG->wwwroot/mod/$module->name/view.php?id=$fromform->coursemodule");
diff --git a/lang/en/plagiarism.php b/lang/en/plagiarism.php
new file mode 100644
index 0000000000000..1acc76962d6e9
--- /dev/null
+++ b/lang/en/plagiarism.php
@@ -0,0 +1,9 @@
+nosave = true;
+ parent::__construct('plagiarismui', get_string('plagiarismsettings', 'plagiarism'), '', '');
+ }
+
+ /**
+ * Always returns true
+ *
+ * @return true
+ */
+ public function get_setting() {
+ return true;
+ }
+
+ /**
+ * Always returns true
+ *
+ * @return true
+ */
+ public function get_defaultsetting() {
+ return true;
+ }
+
+ /**
+ * Always returns '' and doesn't write anything
+ *
+ * @return string Always returns ''
+ */
+ public function write_setting($data) {
+ // do not write any setting
+ return '';
+ }
+
+ /**
+ * Return XHTML to display control
+ *
+ * @param mixed $data Unused
+ * @param string $query
+ * @return string highlight
+ */
+ public function output_html($data, $query='') {
+ global $CFG, $OUTPUT;
+
+ // display strings
+ $txt = get_strings(array('settings', 'name'));
+
+ $plagiarismplugins = get_plugin_list('plagiarism');
+ if (empty($plagiarismplugins)) {
+ return get_string('nopluginsinstalled', 'plagiarism');
+ }
+
+ $return = $OUTPUT->heading(get_string('availableplugins', 'plagiarism'), 3, 'main');
+ $return .= $OUTPUT->box_start('generalbox authsui');
+
+ $table = new html_table();
+ $table->head = array($txt->name, $txt->settings);
+ $table->align = array('left', 'center');
+ $table->data = array();
+ $table->attributes['class'] = 'manageplagiarismtable generaltable';
+
+ // iterate through auth plugins and add to the display table
+ $authcount = count($plagiarismplugins);
+ foreach ($plagiarismplugins as $plugin => $dir) {
+ if (file_exists($dir.'/settings.php')) {
+ $displayname = "".get_string($plugin, 'plagiarism_'.$plugin)."";
+ // settings link
+ $settings = "wwwroot/plagiarism/$plugin/settings.php\">{$txt->settings}";
+ // add a row to the table
+ $table->data[] =array($displayname, $settings);
+ }
+ }
+ $return .= html_writer::table($table);
+ $return .= get_string('configplagiarismplugins', 'plagiarism');
+ $return .= $OUTPUT->box_end();
+ return highlight($query, $return);
+ }
+}
/**
* Special class for overview of external services
diff --git a/lib/cronlib.php b/lib/cronlib.php
index 799f2903d0df7..02afd379189b1 100644
--- a/lib/cronlib.php
+++ b/lib/cronlib.php
@@ -116,6 +116,10 @@ function cron_run() {
}
mtrace('Finished blocks');
+ //now do plagiarism checks
+ require_once($CFG->libdir.'/plagiarismlib.php');
+ plagiarism_cron();
+
mtrace("Starting quiz reports");
if ($reports = $DB->get_records_select('quiz_report', "cron > 0 AND ((? - lastcron) > cron)", array($timenow))) {
foreach ($reports as $report) {
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index 6e876c839c531..d5682551a8ec6 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -6917,6 +6917,7 @@ function get_core_subsystems() {
'notes' => 'notes',
'pagetype' => NULL,
'pix' => NULL,
+ 'plagiarism' => 'plagiarism',
'portfolio' => 'portfolio',
'publish' => 'course/publish',
'question' => 'question',
@@ -6973,6 +6974,7 @@ function get_plugin_types($fullpaths=true) {
'portfolio' => 'portfolio',
'qtype' => 'question/type',
'qformat' => 'question/format',
+ 'plagiarism' => 'plagiarism',
'theme' => 'theme'); // this is a bit hacky, themes may be in dataroot too
$mods = get_plugin_list('mod');
diff --git a/lib/plagiarismlib.php b/lib/plagiarismlib.php
new file mode 100644
index 0000000000000..b8c854626ee7c
--- /dev/null
+++ b/lib/plagiarismlib.php
@@ -0,0 +1,170 @@
+.
+
+/**
+ * plagiarismlib.php - Contains core Plagiarism related functions.
+ *
+ * @since 2.0
+ * @package moodlecore
+ * @subpackage plagiarism
+ * @copyright 2010 Dan Marsden http://danmarsden.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+///// GENERIC PLAGIARISM FUNCTIONS ////////////////////////////////////////////////////
+
+if (!defined('MOODLE_INTERNAL')) {
+ die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
+}
+
+/**
+ * displays the similarity score and provides a link to the full report if allowed.
+ *
+ * @param object $linkarray contains all relevant information for the plugin to generate a link
+ * @return string - url to allow login/viewing of a similarity report
+ */
+function plagiarism_get_links($linkarray) {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ $output = '';
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $output .= $plagiarismplugin->get_links($linkarray);
+ }
+ return $output;
+}
+
+/**
+ * saves/updates plagiarism settings from a modules config page - called by course/modedit.php
+ *
+ * @param object $data - form data
+ */
+function plagiarism_save_form_elements($data) {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $plagiarismplugin->save_form_elements($data);
+ }
+}
+
+/**
+ * adds the list of plagiarism settings to a form - called inside modules that have enabled plagiarism
+ *
+ * @param object $mform - Moodle form object
+ * @param object $context - context object
+ */
+function plagiarism_get_form_elements_module($mform, $context) {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $plagiarismplugin->get_form_elements_module($mform, $context);
+ }
+}
+/**
+ * updates the status of all files within a module
+ *
+ * @param object $course - full Course object
+ * @param object $cm - full cm object
+ */
+function plagiarism_update_status($course, $cm) {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $plagiarismplugin->update_status($course, $cm);
+ }
+}
+
+/**
+* Function that prints the student disclosure notifying that the files will be checked for plagiarism
+* @param integer $cmid - the cmid of this module
+*/
+function plagiarism_print_disclosure($cmid) {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $plagiarismplugin->print_disclosure($cmid);
+ }
+}
+/**
+ * used by admin/cron.php to get similarity scores from submitted files.
+ *
+ */
+function plagiarism_cron() {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return '';
+ }
+ $plagiarismplugins = plagiarism_load_available_plugins();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ $plagiarismplugin = new $plagiarismclass;
+ $plagiarismplugin->cron();
+ }
+}
+/**
+ * helper function - also loads lib file of plagiarism plugin
+ * @return array of available plugins
+ */
+function plagiarism_load_available_plugins() {
+ global $CFG;
+ if (empty($CFG->enableplagiarism)) {
+ return array();
+ }
+ $plagiarismplugins = get_plugin_list('plagiarism');
+ $availableplugins = array();
+ foreach($plagiarismplugins as $plugin => $dir) {
+ //check this plugin is enabled and a lib file exists.
+ if (get_config('plagiarism', $plugin."_use") && file_exists($dir."/lib.php")) {
+ require_once($dir.'/lib.php');
+ $plagiarismclass = "plagiarism_plugin_$plugin";
+ if (class_exists($plagiarismclass)) {
+ $availableplugins[$plugin] = $dir;
+ }
+ }
+ }
+ return $availableplugins;
+}
diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php
index 5b5cc61cf09bb..bba8fceb20ede 100644
--- a/mod/assignment/lib.php
+++ b/mod/assignment/lib.php
@@ -207,6 +207,7 @@ function view_intro() {
echo $OUTPUT->box_start('generalbox boxaligncenter', 'intro');
echo format_module_intro('assignment', $this->assignment, $this->cm->id);
echo $OUTPUT->box_end();
+ plagiarism_print_disclosure($this->cm->id);
}
/**
@@ -1096,6 +1097,7 @@ function display_submissions($message='') {
self::FILTER_REQUIRE_GRADING => get_string('requiregrading', 'assignment'));
$updatepref = optional_param('updatepref', 0, PARAM_INT);
+ plagiarism_update_status($this->course, $this->cm);
if (isset($_POST['updatepref'])){
$perpage = optional_param('perpage', 10, PARAM_INT);
@@ -1873,6 +1875,8 @@ function print_user_files($userid=0, $return=false) {
$button->set_format_by_file($file);
$output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
}
+ $output .= plagiarism_get_links(array('userid'=>$userid, 'file'=>$file, 'cmid'=>$this->cm->id, 'course'=>$this->course, 'assignment'=>$this->assignment));
+ $output .= '
';
}
if (count($files) > 1 && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
$button->set_callback_options('assignment_portfolio_caller', array('id' => $this->cm->id), '/mod/assignment/locallib.php');
diff --git a/mod/assignment/renderer.php b/mod/assignment/renderer.php
index 16c5f0f33a726..87282d4e1fef7 100644
--- a/mod/assignment/renderer.php
+++ b/mod/assignment/renderer.php
@@ -66,8 +66,9 @@ protected function htmllize_tree($tree, $dir) {
foreach ($dir['files'] as $file) {
$filename = $file->get_filename();
$icon = mimeinfo("icon", $filename);
+ $plagiarsmlinks = plagiarism_get_links(array('userid'=>$file->get_userid(), 'file'=>$file, 'cmid'=>$tree->cm->id, 'course'=>$tree->course));
$image = $this->output->pix_icon("f/$icon", $filename, 'moodle', array('class'=>'icon'));
- $result .= '