public function get_discussionid($forumdata) { list($querystrid, $discussionid, $reply, $edit, $delete) = explode('_', $forumdata); if (empty($discussionid)) { $parent = ''; if ($reply != 0) { $parent = forum_get_post_full($reply); } else { if ($edit != 0) { $parent = forum_get_post_full($edit); } else { if ($delete != 0) { $parent = forum_get_post_full($delete); } } } if (!empty($parent)) { $discussionid = $parent->discussion; } } return $discussionid; }
} if ($forum->type == 'qanda' && !has_capability('moodle/course:manageactivities', $context)) { notify(get_string('qandanotify', 'forum')); } $forum->intro = trim($forum->intro); switch ($forum->type) { case 'single': if (!($discussion = get_record("forum_discussions", "forum", $forum->id))) { if ($discussions = get_records("forum_discussions", "forum", $forum->id, "timemodified ASC")) { notify("Warning! There is more than one discussion in this forum - using the most recent"); $discussion = array_pop($discussions); } else { error("Could not find the discussion in this forum"); } } if (!($post = forum_get_post_full($discussion->firstpost))) { error("Could not find the first post in this forum"); } if ($mode) { set_user_preference("forum_displaymode", $mode); } $displaymode = get_user_preferences("forum_displaymode", $CFG->forum_displaymode); $canrate = has_capability('mod/forum:rate', $context); forum_print_discussion($course, $forum, $discussion, $post, $displaymode, NULL, $canrate); break; case 'eachuser': if (!empty($forum->intro)) { print_box(format_text($forum->intro), 'generalbox', 'intro'); } echo '<p align="center">'; if (forum_user_can_post_discussion($forum)) {
$event->add_record_snapshot('forum', $forum); $event->trigger(); unset($SESSION->fromdiscussion); if ($mode) { set_user_preference('forum_displaymode', $mode); } $displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); if ($parent) { // If flat AND parent, then force nested display this time if ($displaymode == FORUM_MODE_FLATOLDEST or $displaymode == FORUM_MODE_FLATNEWEST) { $displaymode = FORUM_MODE_NESTED; } } else { $parent = $discussion->firstpost; } if (!($post = forum_get_post_full($parent))) { print_error("notexists", 'forum', "{$CFG->wwwroot}/mod/forum/view.php?f={$forum->id}"); } if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) { print_error('noviewdiscussionspermission', 'forum', "{$CFG->wwwroot}/mod/forum/view.php?id={$forum->id}"); } if ($mark == 'read' or $mark == 'unread') { if ($CFG->forum_usermarksread && forum_tp_can_track_forums($forum) && forum_tp_is_tracked($forum)) { if ($mark == 'read') { forum_tp_add_read_record($USER->id, $postid); } else { // unread forum_tp_delete_read_records($USER->id, $postid); } } }
/** * Returns the specified forum post from its internal cache. * * @throws \dml_missing_record_exception * @param int $postid * @return stdClass */ protected function get_post($postid) { if (empty($this->postsdata[$postid])) { $this->postsdata[$postid] = forum_get_post_full($postid); if (!$this->postsdata[$postid]) { throw new \dml_missing_record_exception('forum_posts'); } } return $this->postsdata[$postid]; }
$forumtracked = forum_tp_is_tracked($forum); $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked); forum_print_posts_nested($course, $cm, $forum, $discussion, $post, false, false, $forumtracked, $posts); } } else { echo $OUTPUT->header(); echo $OUTPUT->confirm(get_string("deletesure", "forum", $replycount), "post.php?delete={$delete}&confirm={$delete}", $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '#p' . $post->id); forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false); } } echo $OUTPUT->footer(); die; } else { if (!empty($prune)) { // Pruning if (!($post = forum_get_post_full($prune))) { print_error('invalidpostid', 'forum'); } if (!($discussion = $DB->get_record("forum_discussions", array("id" => $post->discussion)))) { print_error('notpartofdiscussion', 'forum'); } if (!($forum = $DB->get_record("forum", array("id" => $discussion->forum)))) { print_error('invalidforumid', 'forum'); } if ($forum->type == 'single') { print_error('cannotsplit', 'forum'); } if (!$post->parent) { print_error('alreadyfirstpost', 'forum'); } if (!($cm = get_coursemodule_from_instance("forum", $forum->id, $forum->course))) {
/** * Returns a list of forum posts for a discussion * * @param int $discussionid the post ids * @param string $sortby sort by this element (id, created or modified) * @param string $sortdirection sort direction: ASC or DESC * * @return array the forum post details * @since Moodle 2.7 */ public static function get_forum_discussion_posts($discussionid, $sortby = "created", $sortdirection = "DESC") { global $CFG, $DB, $USER; $warnings = array(); // Validate the parameter. $params = self::validate_parameters(self::get_forum_discussion_posts_parameters(), array('discussionid' => $discussionid, 'sortby' => $sortby, 'sortdirection' => $sortdirection)); // Compact/extract functions are not recommended. $discussionid = $params['discussionid']; $sortby = $params['sortby']; $sortdirection = $params['sortdirection']; $sortallowedvalues = array('id', 'created', 'modified'); if (!in_array($sortby, $sortallowedvalues)) { throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' . 'allowed values are: ' . implode(',', $sortallowedvalues)); } $sortdirection = strtoupper($sortdirection); $directionallowedvalues = array('ASC', 'DESC'); if (!in_array($sortdirection, $directionallowedvalues)) { throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' . 'allowed values are: ' . implode(',', $directionallowedvalues)); } $discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST); $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). $modcontext = context_module::instance($cm->id); self::validate_context($modcontext); // This require must be here, see mod/forum/discuss.php. require_once $CFG->dirroot . "/mod/forum/lib.php"; // Check they have the view forum capability. require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); if (!($post = forum_get_post_full($discussion->firstpost))) { throw new moodle_exception('notexists', 'forum'); } // This function check groups, qanda, timed discussions, etc. if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) { throw new moodle_exception('noviewdiscussionspermission', 'forum'); } $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); // We will add this field in the response. $canreply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); $forumtracked = forum_tp_is_tracked($forum); $sort = 'p.' . $sortby . ' ' . $sortdirection; $posts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked); foreach ($posts as $pid => $post) { if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) { $warning = array(); $warning['item'] = 'post'; $warning['itemid'] = $post->id; $warning['warningcode'] = '1'; $warning['message'] = 'You can\'t see this post'; $warnings[] = $warning; continue; } // Function forum_get_all_discussion_posts adds postread field. // Note that the value returned can be a boolean or an integer. The WS expects a boolean. if (empty($post->postread)) { $posts[$pid]->postread = false; } else { $posts[$pid]->postread = true; } $posts[$pid]->canreply = $canreply; if (!empty($posts[$pid]->children)) { $posts[$pid]->children = array_keys($posts[$pid]->children); } else { $posts[$pid]->children = array(); } $user = new stdclass(); $user = username_load_fields_from_object($user, $post); $posts[$pid]->userfullname = fullname($user, $canviewfullname); $posts[$pid] = (array) $post; } $result = array(); $result['posts'] = $posts; $result['warnings'] = $warnings; return $result; }
/** * Create new posts into an existing discussion. * * @param int $postid the post id we are going to reply to * @param string $subject new post subject * @param string $message new post message (only html format allowed) * @param array $options optional settings * @return array of warnings and the new post id * @since Moodle 3.0 * @throws moodle_exception */ public static function add_discussion_post($postid, $subject, $message, $options = array()) { global $DB, $CFG, $USER; require_once($CFG->dirroot . "/mod/forum/lib.php"); $params = self::validate_parameters(self::add_discussion_post_parameters(), array( 'postid' => $postid, 'subject' => $subject, 'message' => $message, 'options' => $options )); // Validate options. $options = array( 'discussionsubscribe' => true ); foreach ($params['options'] as $option) { $name = trim($option['name']); switch ($name) { case 'discussionsubscribe': $value = clean_param($option['value'], PARAM_BOOL); break; default: throw new moodle_exception('errorinvalidparam', 'webservice', '', $name); } $options[$name] = $value; } $warnings = array(); if (!$parent = forum_get_post_full($params['postid'])) { throw new moodle_exception('invalidparentpostid', 'forum'); } if (!$discussion = $DB->get_record("forum_discussions", array("id" => $parent->discussion))) { throw new moodle_exception('notpartofdiscussion', 'forum'); } // Request and permission validation. $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); $context = context_module::instance($cm->id); self::validate_context($context); if (!forum_user_can_post($forum, $discussion, $USER, $cm, $course, $context)) { throw new moodle_exception('nopostforum', 'forum'); } $thresholdwarning = forum_check_throttling($forum, $cm); forum_check_blocking_threshold($thresholdwarning); // Create the post. $post = new stdClass(); $post->discussion = $discussion->id; $post->parent = $parent->id; $post->subject = $params['subject']; $post->message = $params['message']; $post->messageformat = FORMAT_HTML; // Force formatting for now. $post->messagetrust = trusttext_trusted($context); $post->itemid = 0; if ($postid = forum_add_new_post($post, null)) { $post->id = $postid; // Trigger events and completion. $params = array( 'context' => $context, 'objectid' => $post->id, 'other' => array( 'discussionid' => $discussion->id, 'forumid' => $forum->id, 'forumtype' => $forum->type, ) ); $event = \mod_forum\event\post_created::create($params); $event->add_record_snapshot('forum_posts', $post); $event->add_record_snapshot('forum_discussions', $discussion); $event->trigger(); // Update completion state. $completion = new completion_info($course); if ($completion->is_enabled($cm) && ($forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_COMPLETE); } $settings = new stdClass(); $settings->discussionsubscribe = $options['discussionsubscribe']; forum_post_subscription($settings, $forum, $discussion); } else { throw new moodle_exception('couldnotadd', 'forum'); } $result = array(); $result['postid'] = $postid; $result['warnings'] = $warnings; return $result; }
function leaf_get_newsitem($d) { global $DB, $USER, $CFG, $OUTPUT; static $str; require_once $CFG->libdir . '/filelib.php'; $discussion = $DB->get_record('forum_discussions', array('id' => $d, 'course' => 1), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $discussion->course), '*', MUST_EXIST); $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); $parent = $discussion->firstpost; $post = forum_get_post_full($parent); $displaymode = -1; $canreply = false; $canrate = false; $sort = "p.created ASC"; $posts = forum_get_all_discussion_posts($discussion->id, $sort, false); foreach ($posts as $post) { $post->course = $course->id; $post->forum = $forum->id; $postuser = new stdClass(); $postuser->id = $post->userid; $postuser->firstname = $post->firstname; $postuser->lastname = $post->lastname; $postuser->imagealt = $post->imagealt; $postuser->picture = $post->picture; $postuser->email = $post->email; $postuser->fullname = fullname($postuser); $output = ''; $output .= html_writer::tag('a', '', array('id' => 'p' . $post->id)); $output .= html_writer::start_tag('div', array('class' => 'forumpost clearfix firstpost starter')); $output .= html_writer::start_tag('div', array('class' => 'row header clearfix')); $output .= html_writer::start_tag('div', array('class' => 'left picture')); $output .= $OUTPUT->user_picture($postuser, array('courseid' => $course->id)); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class' => 'topic firstpost starter')); $postsubject = $post->subject; if (empty($post->subjectnoformat)) { $postsubject = format_string($postsubject); } $output .= html_writer::tag('div', $postsubject, array('class' => 'subject')); $output .= html_writer::tag('div', $postuser->fullname, array('class' => 'author')); $output .= html_writer::end_tag('div'); //topic $output .= html_writer::end_tag('div'); //row $output .= html_writer::start_tag('div', array('class' => 'row maincontent clearfix')); $output .= html_writer::start_tag('div', array('class' => 'left')); $output .= html_writer::tag('div', ' ', array('class' => 'grouppictures')); $output .= html_writer::end_tag('div'); //left side $output .= html_writer::start_tag('div', array('class' => 'no-overflow')); $output .= html_writer::start_tag('div', array('class' => 'content')); $options = new stdClass(); $options->para = false; $options->trusted = $post->messagetrust; // Prepare whole post $postclass = 'fullpost'; $postcontent = format_text($post->message, $post->messageformat, $options, $course->id); // Output the post content $output .= html_writer::tag('div', $postcontent, array('class' => 'posting ' . $postclass)); $output .= html_writer::end_tag('div'); // Content $output .= html_writer::end_tag('div'); // Content mask $output .= html_writer::end_tag('div'); // Row $output .= html_writer::start_tag('div', array('class' => 'row side')); $output .= html_writer::tag('div', ' ', array('class' => 'left')); $output .= html_writer::start_tag('div', array('class' => 'options clearfix')); // Close remaining open divs $output .= html_writer::end_tag('div'); // content $output .= html_writer::end_tag('div'); // row $output .= html_writer::end_tag('div'); // forumpost echo $output; } }
/** * Makes the pop up contents for the grading interface * * @param array $params * @param $coursemodule * @global moodle_database $DB * @global $PAGE * @global stdClass $CFG * @global $SESSION * @global $USER * @global $OUTPUT * @params object $coursemodule * @return string HTML */ public function grading_popup($params, $coursemodule) { global $DB, $PAGE, $CFG, $SESSION, $USER, $OUTPUT; $output = ''; // Lifted from /mod/forum/discuss.php... /* $parent = $params['parent']; // If set, then display this post and all children. $mode = $params['mode']; // If set, changes the layout of the thread $move = $params['move']; // If set, moves this discussion to another forum $mark = $params['mark']; // Used for tracking read posts if user initiated. $postid = $params['postid']; // Used for tracking read posts if user initiated. */ $discussion = $DB->get_record('forum_discussions', array('id' => $params['discussionid']), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $discussion->course), '*', MUST_EXIST); $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); $modcontext = context_module::instance($cm->id); // Security - cmid is used to check context permissions earlier on, so it must match when // derived from the discussion. if (!($cm->id == $params['coursemoduleid'])) { print_error('Bad params!'); return false; } // Add ajax-related libs. $PAGE->requires->yui2_lib('event'); $PAGE->requires->yui2_lib('connection'); $PAGE->requires->yui2_lib('json'); // Move this down fix for MDL-6926. require_once $CFG->dirroot . '/mod/forum/lib.php'; // Restrict news forums - should not be graded. if ($forum->type == 'news') { print_error('invaliddiscussionid', 'forum', "{$CFG->wwwroot}/mod/forum/view.php?f={$forum->id}"); } unset($SESSION->fromdiscussion); // In case the user has used the drop-down to change from threaded to flat or something. if (isset($params['mode'])) { set_user_preference('forum_displaymode', $params['mode']); } $displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); $parent = $discussion->firstpost; $post = forum_get_post_full($parent); if (!$post) { print_error("notexists", 'forum', "{$CFG->wwwroot}/mod/forum/view.php?f={$forum->id}"); } if (!forum_user_can_view_post($post, $course, $cm, $forum, $discussion)) { print_error('nopermissiontoview', 'forum', "{$CFG->wwwroot}/mod/forum/view.php?id={$forum->id}"); } // For now, restrict to rating only. $canreply = false; // Without this, the nesting doesn't work properly as the css isn't picked up. $output .= html_writer::start_tag('div', array('class' => 'path-mod-forum')); $output .= html_writer::start_tag('div', array('class' => 'discussioncontrols clearfix')); $output .= html_writer::start_tag('div', array('class' => 'discussioncontrol displaymode')); // We don't want to have the current mode returned in the url as well as the new one. unset($params['mode']); $newurl = new moodle_url('/blocks/ajax_marking/actions/grading_popup.php', $params); $select = new single_select($newurl, 'mode', forum_get_layout_modes(), $displaymode, null, "mode"); $output .= $OUTPUT->render($select); $output .= html_writer::end_tag('div'); // If user has not already posted and it's a Q & A forum... $forumisqanda = $forum->type == 'qanda'; $noviewwithoutposting = !has_capability('mod/forum:viewqandawithoutposting', $modcontext); $hasnotposted = !forum_user_has_posted($forum->id, $discussion->id, $USER->id); if ($forumisqanda && $noviewwithoutposting && $hasnotposted) { $output .= $OUTPUT->notification(get_string('qandanotify', 'forum')); } $canrate = has_capability('mod/forum:rate', $modcontext); ob_start(); forum_print_discussion($course, $cm, $forum, $discussion, $post, $displaymode, $canreply, $canrate); $output .= ob_get_contents(); ob_end_clean(); $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); return $output; }
/** * * @global type $CFG * @param type $linkarray * @return type */ public function get_links($linkarray) { global $CFG, $DB, $OUTPUT, $PAGE, $USER; // Don't submit certain file types to Turnitin. if (!empty($linkarray["file"])) { $file = $linkarray["file"]; $filearea = $file->get_filearea(); $nonsubmittingareas = array("feedback_files", "introattachment"); if (in_array($filearea, $nonsubmittingareas)) { return; } } // Set static variables. static $cm; static $forum; if (empty($cm)) { $cm = get_coursemodule_from_id('', $linkarray["cmid"]); if ($cm->modname == 'forum') { if (!($forum = $DB->get_record("forum", array("id" => $cm->instance)))) { print_error('invalidforumid', 'forum'); } } } static $plagiarismsettings; if (empty($plagiarismsettings)) { $plagiarismsettings = $this->get_settings($linkarray["cmid"]); if ($cm->modname == 'assign') { $plagiarismsettings["plagiarism_draft_submit"] = isset($plagiarismsettings["plagiarism_draft_submit"]) ? $plagiarismsettings["plagiarism_draft_submit"] : 0; } } // Exit if Turnitin is not being used for this module. if (empty($plagiarismsettings['use_turnitin'])) { return; } static $config; if (empty($config)) { $config = turnitintooltwo_admin_config(); } static $moduletiienabled; if (empty($moduletiienabled)) { $moduletiienabled = $this->get_config_settings('mod_' . $cm->modname); } // Exit if Turnitin is not being used for this activity type. if (empty($moduletiienabled)) { return; } static $moduledata; if (empty($moduledata)) { $moduledata = $DB->get_record($cm->modname, array('id' => $cm->instance)); } static $context; if (empty($context)) { $context = context_course::instance($cm->course); } static $coursedata; if (empty($coursedata)) { // Create the course/class in Turnitin if it doesn't already exist. $coursedata = turnitintooltwo_assignment::get_course_data($cm->course, 'PP'); if (empty($coursedata->turnitin_cid)) { // Course may existed in a previous incarnation of this plugin. // Get this and save it in courses table if so. if ($turnitincid = $this->get_previous_course_id($cm)) { $coursedata->turnitin_cid = $turnitincid; $coursedata = $this->migrate_previous_course($coursedata, $turnitincid); } else { // Otherwise create new course in Turnitin. $tiicoursedata = $this->create_tii_course($cm, $coursedata); $coursedata->turnitin_cid = $tiicoursedata->turnitin_cid; $coursedata->turnitin_ctl = $tiicoursedata->turnitin_ctl; } } } // Work out if logged in user is a tutor on this module. static $istutor; switch ($cm->modname) { case "forum": case "workshop": if (empty($istutor)) { $istutor = has_capability('plagiarism/turnitin:viewfullreport', $context); } break; default: if (empty($istutor)) { $istutor = has_capability('mod/' . $cm->modname . ':grade', $context); } break; } // Define the timestamp for updating Peermark Assignments. if (empty($_SESSION["updated_pm"][$cm->id]) && $config->enablepeermark) { $_SESSION["updated_pm"][$cm->id] = time() - 60 * 5; } $output = ""; // If a text submission has been made, we can only display links for current attempts so don't show links previous attempts. // This will need to be reworked when linkarray contains submission id. static $contentdisplayed; if ($cm->modname == 'assign' && !empty($linkarray["content"]) && $contentdisplayed == true) { return $output; } if ((!empty($linkarray["file"]) || !empty($linkarray["content"])) && !empty($linkarray["cmid"])) { // Include Javascript. $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/jquery-1.8.2.min.js'); $PAGE->requires->js($jsurl); $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/turnitintooltwo.js'); $PAGE->requires->js($jsurl); $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/plagiarism_plugin.js'); $PAGE->requires->js($jsurl); $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/jquery.colorbox.js'); $PAGE->requires->js($jsurl); $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/jquery.tooltipster.js'); $PAGE->requires->js($jsurl); $PAGE->requires->string_for_js('closebutton', 'turnitintooltwo'); // Initialise vars for working out whether we are submitting. $submitting = false; $submission_status = true; $identifier = ''; // Get Assignment submission data and account for draft submissions which may not be submitted if ($cm->modname == 'assign') { if (!empty($linkarray["file"])) { $submission = $DB->get_record('assign_submission', array('userid' => $linkarray["userid"], 'assignment' => $moduledata->id, 'id' => $file->get_itemid())); } else { // This will need to be reworked when linkarray contains submission id. $submissions = $DB->get_records('assign_submission', array('userid' => $linkarray["userid"], 'assignment' => $moduledata->id)); $submission = end($submissions); } if ($submission) { $submission_status = $submission->status == "submitted" || $moduledata->submissiondrafts == 1 && $plagiarismsettings["plagiarism_draft_submit"] == 0 ? true : false; } } // Check whether a user's submission needs to be sent to Turnitin via Ajax. // Get File or Content information, for content only submit if it has been modified. $itemid = 0; if (!empty($linkarray["file"])) { $identifier = $file->get_pathnamehash(); $itemid = $file->get_itemid(); $submissiontype = 'file'; $submitting = $submission_status ? true : false; // Get plagiarism file info to check if file was previously submitted and has been modified. $typefield = $CFG->dbtype == "oci" ? " to_char(submissiontype) " : " submissiontype "; $plagiarismfiles = $DB->get_records_select('plagiarism_turnitin_files', " userid = ? AND cm = ? AND identifier = ? AND (" . $typefield . " = ? OR " . $typefield . " IS NULL )", array($linkarray["userid"], $linkarray["cmid"], $identifier, $submissiontype, '')); $plagiarismfile = end($plagiarismfiles); if (!empty($plagiarismfile)) { $submitting = $file->get_timemodified() > $plagiarismfile->lastmodified ? $submitting : false; } } else { if (!empty($linkarray["content"])) { // Get turnitin text content details. $submissiontype = $cm->modname == "forum" ? 'forum_post' : 'text_content'; switch ($cm->modname) { case 'assign': $moodletextsubmission = $DB->get_record('assignsubmission_onlinetext', array('submission' => $submission->id), 'onlinetext'); if (empty($moodletextsubmission)) { $content = ''; $submission_status = false; } else { $content = $moodletextsubmission->onlinetext; } break; case 'workshop': $submission = $DB->get_record('workshop_submissions', array('authorid' => $linkarray["userid"], 'workshopid' => $moduledata->id)); $content = $linkarray["content"]; break; case 'forum': static $discussionid; // Use query string id to check whether we are on forum home page. $querystrid = optional_param('id', 0, PARAM_INT); // Work out the discussion id from query string. if (empty($discussionid)) { $discussionid = optional_param('d', 0, PARAM_INT); } if (empty($discussionid)) { $reply = optional_param('reply', 0, PARAM_INT); $edit = optional_param('edit', 0, PARAM_INT); $delete = optional_param('delete', 0, PARAM_INT); $parent = ''; if ($reply != 0) { $parent = forum_get_post_full($reply); } else { if ($edit != 0) { $parent = forum_get_post_full($edit); } else { if ($delete != 0) { $parent = forum_get_post_full($delete); } } } if (!empty($parent)) { $discussionid = $parent->discussion; } } // Some forum types don't pass in certain values on main forum page. if ((empty($discussionid) || $querystrid != 0) && ($forum->type == 'blog' || $forum->type == 'single')) { if (!($discussion = $DB->get_record_sql('SELECT FD.id FROM {forum_posts} FP JOIN {forum_discussions} FD ON FP.discussion = FD.id WHERE FD.forum = ? AND FD.course = ? AND FP.userid = ? AND FP.message LIKE ? ', array($forum->id, $forum->course, $linkarray["userid"], $linkarray["content"])))) { print_error('notpartofdiscussion', 'forum'); } $discussionid = $discussion->id; } $submission = $DB->get_record_select('forum_posts', " userid = ? AND message LIKE ? AND discussion = ? ", array($linkarray["userid"], $linkarray["content"], $discussionid)); $itemid = $submission->id; $submission->timemodified = $submission->modified; $content = $linkarray["content"]; break; } // Get plagiarism file info. $identifier = sha1($content); $typefield = $CFG->dbtype == "oci" ? " to_char(submissiontype) " : " submissiontype "; switch ($cm->modname) { case 'assign': case 'workshop': $plagiarismfile = $DB->get_record_select('plagiarism_turnitin_files', " userid = ? AND cm = ? AND " . $typefield . " = ? ", array($linkarray["userid"], $linkarray["cmid"], $submissiontype)); break; case 'forum': $plagiarismfile = $DB->get_record_select('plagiarism_turnitin_files', " userid = ? AND cm = ? AND identifier = ? AND " . $typefield . " = ? ", array($linkarray["userid"], $linkarray["cmid"], $identifier, $submissiontype)); break; } if (!empty($plagiarismfile)) { $submitting = $submission->timemodified > $plagiarismfile->lastmodified && $plagiarismfile->identifier != $identifier ? true : false; } else { $submitting = true; } } } // Group submissions where all students have to submit sets userid to 0; if ($linkarray['userid'] == 0 && !$istutor) { $linkarray['userid'] = $USER->id; } $output .= $OUTPUT->box_start('tii_links_container'); // Show the EULA for a student if necessary. if ($linkarray["userid"] == $USER->id) { $eula = ""; static $userid; if (empty($userid)) { $userid = 0; } // Condition added to test for Moodle 2.7 as it calls this function twice. if ($CFG->branch >= 27 || $userid != $linkarray["userid"]) { // Show EULA if necessary and we have a connection to Turnitin. static $eulashown; if (empty($eulashown)) { $eulashown = false; } $user = new turnitintooltwo_user($USER->id, "Learner"); $success = $user->join_user_to_class($coursedata->turnitin_cid); // $success is false if there is no Turnitin connection and null if user has previously been enrolled. if ((is_null($success) || $success === true) && $eulashown == false) { $eulaaccepted = $user->user_agreement_accepted == 0 ? $user->get_accepted_user_agreement() : $user->user_agreement_accepted; $userid = $linkarray["userid"]; if ($eulaaccepted != 1) { $eula_link = html_writer::link($CFG->wwwroot . '/plagiarism/turnitin/extras.php?cmid=' . $linkarray["cmid"] . '&cmd=useragreement&view_context=box_solid', get_string('turnitinppulapost', 'turnitintooltwo'), array("class" => "pp_turnitin_eula_link")); $eula = html_writer::tag('div', $eula_link, array('class' => 'pp_turnitin_ula js_required', 'data-userid' => $user->id)); $submitting = false; } // Show EULA launcher and form placeholder. if (!empty($eula)) { $output .= $eula; $turnitincomms = new turnitintooltwo_comms(); $turnitincall = $turnitincomms->initialise_api(); $customdata = array("disable_form_change_checker" => true, "elements" => array(array('html', $OUTPUT->box('', '', 'useragreement_inputs')))); $eulaform = new turnitintooltwo_form($turnitincall->getApiBaseUrl() . TiiLTI::EULAENDPOINT, $customdata, 'POST', $target = 'eulaWindow', array('id' => 'eula_launch')); $output .= $OUTPUT->box($eulaform->display(), 'tii_useragreement_form', 'useragreement_form'); $eulashown = true; } } else { $submitting = false; } } // If a user has just submitted then send to Turnitin via Ajax. if ($submitting && $submission_status) { // Include Javascript for Submitting. $jsurl = new moodle_url('/mod/turnitintooltwo/jquery/plagiarism_submission.js'); $PAGE->requires->js($jsurl); // Forum posts have a lot of html stripped out so we have to get data to ajax differently if ($submissiontype == 'forum_post') { $output .= html_writer::start_tag('div', array('class' => 'plagiarism_submission')); $output .= html_writer::tag('div', $identifier . '-' . $submissiontype, array('class' => 'plagiarism_submission_id')); $output .= html_writer::tag('div', urlencode($linkarray["content"]), array('class' => 'plagiarism_submission_content')); $output .= html_writer::tag('div', $linkarray["cmid"], array('class' => 'plagiarism_submission_cmid')); $output .= html_writer::tag('div', $itemid, array('class' => 'plagiarism_submission_itemid')); $output .= html_writer::end_tag('div'); } else { $output .= html_writer::start_tag('div', array('class' => 'plagiarism_submission', 'id' => $identifier . '-' . $submissiontype)); $output .= html_writer::tag('div', $linkarray["cmid"], array('class' => 'plagiarism_submission_cmid')); $output .= html_writer::tag('div', $itemid, array('class' => 'plagiarism_submission_itemid')); $output .= html_writer::end_tag('div'); } } } // Check whether submission is a group submission - only applicable to assignment module. // If it's a group submission then other users in the group should be able to see the originality score // They can not open the DV though. $submissionusers = array($linkarray["userid"]); if ($cm->modname == "assign" && $CFG->branch > 23) { if ($moduledata->teamsubmission) { $assignment = new assign($context, $cm, null); if ($group = $assignment->get_submission_group($linkarray["userid"])) { $users = groups_get_members($group->id); $submissionusers = array_keys($users); } } } // Display Links for files and contents. if ((!empty($linkarray["file"]) || !empty($linkarray["content"])) && ($istutor || $submission_status && in_array($USER->id, $submissionusers))) { // Prevent text content links being displayed for previous attempts as we have no way of getting the data. if (!empty($linkarray["content"]) && $linkarray["userid"] == $USER->id) { $contentdisplayed = true; } // Get turnitin details - have to do this again as submission may have been made above. $plagiarismfiles = $DB->get_records('plagiarism_turnitin_files', array('userid' => $linkarray["userid"], 'cm' => $linkarray["cmid"], 'identifier' => $identifier), 'lastmodified DESC', '*', 0, 1); $plagiarismfile = current($plagiarismfiles); // Get user's grades. // Get Due date $duedate = 0; if (!empty($moduledata->duedate)) { $duedate = $moduledata->duedate; } else { if (!empty($moduledata->timedue)) { $duedate = $moduledata->timedue; } } // Get post date $postdate = 0; if ($cm->modname != "forum") { // Populate gradeitem query $queryarray = array('iteminstance' => $cm->instance, 'itemmodule' => $cm->modname, 'courseid' => $cm->course, 'itemnumber' => 0); if ($gradeitem = $DB->get_record('grade_items', $queryarray)) { switch ($gradeitem->hidden) { case 1: $postdate = strtotime('+1 month'); break; case 0: $postdate = time(); if ($CFG->branch >= 26 && $cm->modname == 'assign' && !empty($moduledata->markingworkflow)) { $gradesreleased = $DB->record_exists('assign_user_flags', array('userid' => $linkarray["userid"], 'assignment' => $cm->instance, 'workflowstate' => 'released')); $postdate = $gradesreleased ? time() : strtotime('+4 weeks', $duedate); } break; default: $postdate = $gradeitem->hidden; break; } } } $currentgradequery = false; if ($istutor || $linkarray["userid"] == $USER->id) { if ($cm->modname == 'forum') { static $gradeitem; if (empty($gradeitem)) { $gradeitem = $DB->get_record('grade_items', array('iteminstance' => $cm->instance, 'itemmodule' => $cm->modname, 'courseid' => $cm->course)); } if ($gradeitem) { $currentgradequery = $DB->get_record('grade_grades', array('userid' => $linkarray["userid"], 'itemid' => $gradeitem->id)); } } else { if ($cm->modname == 'workshop') { if ($gradeitem) { $currentgradequery = $DB->get_record('grade_grades', array('userid' => $linkarray["userid"], 'itemid' => $gradeitem->id)); } $postdate = $moduledata->assessmentend; } else { if ($cm->modname == 'assign') { if ($gradeitem) { $currentgradesquery = $DB->get_records('assign_grades', array('userid' => $linkarray["userid"], 'assignment' => $cm->instance), 'id DESC'); $currentgradequery = current($currentgradesquery); } } } } } if ($plagiarismfile && (!$submitting || !$submission_status)) { if ($plagiarismfile->statuscode == 'success') { if ($istutor || $linkarray["userid"] == $USER->id) { $output .= html_writer::tag('div', $OUTPUT->pix_icon('icon-sml', get_string('turnitinid', 'turnitintooltwo') . ': ' . $plagiarismfile->externalid, 'mod_turnitintooltwo', array('class' => 'turnitin_paper_id')) . get_string('turnitinid', 'turnitintooltwo') . ': ' . $plagiarismfile->externalid); } // Show Originality Report score and link. if (($istutor || in_array($USER->id, $submissionusers) && $plagiarismsettings["plagiarism_show_student_report"]) && ((is_null($plagiarismfile->orcapable) || $plagiarismfile->orcapable == 1) && !is_null($plagiarismfile->similarityscore))) { // This class is applied so that only the user who submitted or a tutor can open the DV. $useropenclass = $USER->id == $linkarray["userid"] || $istutor ? 'pp_origreport_open' : ''; $output .= $OUTPUT->box_start('row_score pp_origreport ' . $useropenclass . ' origreport_' . $plagiarismfile->externalid . '_' . $linkarray["cmid"], $CFG->wwwroot . '/plagiarism/turnitin/extras.php?cmid=' . $linkarray["cmid"]); // Show score. if ($plagiarismfile->statuscode == "pending") { $output .= html_writer::tag('div', ' ', array('title' => get_string('pending', 'turnitintooltwo'), 'class' => 'tii_tooltip origreport_score score_colour score_colour_')); } else { // Put EN flag if translated matching is on and that is the score used. $transmatch = $plagiarismfile->transmatch == 1 ? ' EN' : ''; if (is_null($plagiarismfile->similarityscore)) { $score = ' '; $titlescore = get_string('pending', 'turnitintooltwo'); $class = 'score_colour_'; } else { $score = $plagiarismfile->similarityscore . '%'; $titlescore = $plagiarismfile->similarityscore . '% ' . get_string('similarity', 'turnitintooltwo'); $class = 'score_colour_' . round($plagiarismfile->similarityscore, -1); } $output .= html_writer::tag('div', $score . $transmatch, array('title' => $titlescore, 'class' => 'tii_tooltip origreport_score score_colour ' . $class)); } // Put in div placeholder for DV launch form. $output .= $OUTPUT->box('', 'launch_form origreport_form_' . $plagiarismfile->externalid); // Add url for launching DV from Forum post. if ($cm->modname == 'forum') { $output .= $OUTPUT->box($CFG->wwwroot . '/plagiarism/turnitin/extras.php?cmid=' . $linkarray["cmid"], 'origreport_forum_launch origreport_forum_launch_' . $plagiarismfile->externalid); } $output .= $OUTPUT->box_end(true); } if ($plagiarismfile->orcapable == 0 && !is_null($plagiarismfile->orcapable)) { // This class is applied so that only the user who submitted or a tutor can open the DV. $useropenclass = $USER->id == $linkarray["userid"] || $istutor ? 'pp_origreport_open' : ''; $output .= $OUTPUT->box_start('row_score pp_origreport ' . $useropenclass, ''); $output .= html_writer::tag('div', 'x', array('title' => get_string('notorcapable', 'turnitintooltwo'), 'class' => 'tii_tooltip score_colour score_colour_ score_no_orcapable')); $output .= $OUTPUT->box_end(true); } // Can grade and feedback be released to this student yet? $released = $postdate <= time() && (!is_null($plagiarismfile->grade) || isset($currentgradequery->grade)); // Show link to open grademark. if ($config->usegrademark && ($istutor || $linkarray["userid"] == $USER->id && $released) && !empty($gradeitem)) { // Output grademark icon. $output .= $OUTPUT->box_start('grade_icon', ''); $output .= html_writer::tag('div', $OUTPUT->pix_icon('icon-edit', get_string('grademark', 'turnitintooltwo'), 'mod_turnitintooltwo'), array('title' => get_string('grademark', 'turnitintooltwo'), 'class' => 'pp_grademark_open tii_tooltip grademark_' . $plagiarismfile->externalid . '_' . $linkarray["cmid"], 'id' => $CFG->wwwroot . '/plagiarism/turnitin/extras.php?cmid=' . $linkarray["cmid"])); // Add url for launching DV from Forum post. if ($cm->modname == 'forum') { $output .= $OUTPUT->box($CFG->wwwroot . '/plagiarism/turnitin/extras.php?cmid=' . $linkarray["cmid"], 'grademark_forum_launch grademark_forum_launch_' . $plagiarismfile->externalid); } // Put in div placeholder for DV launch form. $output .= $OUTPUT->box('', 'launch_form grademark_form_' . $plagiarismfile->externalid); $output .= $OUTPUT->box_end(true); } if (!$istutor && $config->usegrademark && !empty($plagiarismsettings["plagiarism_rubric"])) { // Update assignment in case rubric is not stored in Turnitin yet. $this->sync_tii_assignment($cm, $coursedata->turnitin_cid); $rubricviewlink = html_writer::tag('div', html_writer::link($CFG->wwwroot . '/plagiarism/turnitin/ajax.php?cmid=' . $cm->id . '&action=rubricview&view_context=box', ' ', array('class' => 'tii_tooltip rubric_view_pp_launch', 'id' => 'rubric_view_launch', 'title' => get_string('launchrubricview', 'turnitintooltwo'))) . html_writer::tag('span', '', array('class' => 'launch_form', 'id' => 'rubric_view_form')), array('class' => 'row_rubric_view')); $output .= $rubricviewlink; } if ($config->enablepeermark) { // If this module is already on Turnitin then refresh and get Peermark Assignments. if (!empty($plagiarismsettings['turnitin_assignid'])) { if ($_SESSION["updated_pm"][$cm->id] <= time() - 60 * 2) { $this->refresh_peermark_assignments($cm, $plagiarismsettings['turnitin_assignid']); $turnitintooltwoassignment = new turnitintooltwo_assignment($cm->instance, '', 'PP'); $_SESSION["peermark_assignments"][$cm->id] = $turnitintooltwoassignment->get_peermark_assignments($plagiarismsettings['turnitin_assignid']); $_SESSION["updated_pm"][$cm->id] = time(); } // Determine if we have any active Peermark Assignments. static $peermarksactive; if (!isset($peermarksactive)) { $peermarksactive = false; foreach ($_SESSION["peermark_assignments"][$cm->id] as $peermarkassignment) { if (time() > $peermarkassignment->dtstart) { $peermarksactive = true; break; } } } // Show Peermark Reviews link. if ($istutor && count($_SESSION["peermark_assignments"][$cm->id]) > 0 || !$istutor && $peermarksactive) { $peermarkreviewslink = $OUTPUT->box_start('row_peermark_reviews', ''); $peermarkreviewslink .= html_writer::link($CFG->wwwroot . '/plagiarism/turnitin/ajax.php?cmid=' . $cm->id . '&action=peermarkreviews&view_context=box', '', array('title' => get_string('launchpeermarkreviews', 'turnitintooltwo'), 'class' => 'peermark_reviews_pp_launch tii_tooltip')); $peermarkreviewslink .= html_writer::tag('span', '', array('class' => 'launch_form', 'id' => 'peermark_reviews_form')); $peermarkreviewslink .= $OUTPUT->box_end(true); $output .= $peermarkreviewslink; } } } } else { if ($plagiarismfile->statuscode == 'error') { // Deal with legacy error issues. if (!isset($plagiarismfile->errorcode)) { $errorcode = 0; if ($submissiontype == 'file') { if ($file->get_filesize() > TURNITINTOOLTWO_MAX_FILE_UPLOAD_SIZE) { $errorcode = 2; } } } else { $errorcode = $plagiarismfile->errorcode; } // Show error message if there is one. if ($errorcode == 0) { $langstring = $istutor ? 'ppsubmissionerrorseelogs' : 'ppsubmissionerrorstudent'; $errorstring = isset($plagiarismfile->errormsg) ? get_string($langstring, 'turnitintooltwo') : $plagiarismfile->errormsg; } else { $errorstring = get_string('errorcode' . $plagiarismfile->errorcode, 'turnitintooltwo', display_size(TURNITINTOOLTWO_MAX_FILE_UPLOAD_SIZE)); } $erroricon = html_writer::tag('div', $OUTPUT->pix_icon('x-red', $errorstring, 'mod_turnitintooltwo'), array('title' => $errorstring, 'class' => 'tii_tooltip tii_error_icon')); // If logged in as a student, attach error text after icon. if (!$istutor) { $output .= html_writer::tag('div', $erroricon . ' ' . $errorstring, array('class' => 'warning clear')); } else { $output .= html_writer::tag('div', $erroricon, array('class' => 'clear')); } } } } else { // Add Error to show that user has not accepted EULA. if ($linkarray["userid"] != $USER->id && $istutor) { // There is a moodle plagiarism bug where get_links is called twice, the first loop is incorrect and is killing // this functionality. Have to check that user exists here first else there will be a fatal error. if ($mdl_user = $DB->get_record('user', array('id' => $linkarray["userid"]))) { // We also need to check for security that they are actually on the Course. switch ($cm->modname) { case 'assign': case 'workshop': $capability = 'mod/' . $cm->modname . ':submit'; break; case 'forum': $capability = 'mod/' . $cm->modname . ':replypost'; break; } if (has_capability($capability, $context, $linkarray["userid"])) { $user = new turnitintooltwo_user($linkarray["userid"], "Learner"); if ($user->user_agreement_accepted != 1) { $erroricon = html_writer::tag('div', $OUTPUT->pix_icon('doc-x-grey', get_string('notacceptedeula', 'turnitintooltwo'), 'mod_turnitintooltwo'), array('title' => get_string('notacceptedeula', 'turnitintooltwo'), 'class' => 'tii_tooltip tii_error_icon')); $output .= html_writer::tag('div', $erroricon, array('class' => 'clear')); } } } } } // Show error warning for submission $output .= html_writer::tag('div', '', array('class' => 'turnitin_submit_error warning clear turnitin_submit_error_' . $identifier)); // Show success of submission $output .= html_writer::tag('div', '', array('class' => 'turnitin_submit_success success clear turnitin_submit_success_' . $identifier)); $output .= html_writer::tag('div', '', array('class' => 'clear')); } $output .= $OUTPUT->box_end(true); } return $output; }