/** * Returns a query object with the basics all set up to get assignment stuff * * @global moodle_database $DB * @return block_ajax_marking_query_base */ public function query_factory() { global $DB; $query = new block_ajax_marking_query_base($this); $query->add_from(array('table' => 'assignment', 'alias' => 'moduletable')); $query->add_from(array('join' => 'INNER JOIN', 'table' => 'assignment_submissions', 'alias' => 'sub', 'on' => 'sub.assignment = moduletable.id')); // Standard userid for joins. $query->add_select(array('table' => 'sub', 'column' => 'userid')); $query->add_select(array('table' => 'sub', 'column' => 'timemodified', 'alias' => 'timestamp')); // First bit: not graded // Second bit of first bit: has been resubmitted // Third bit: if it's advanced upload, only care about the first bit if 'send for marking' // was clicked. $commentstring = $DB->sql_compare_text('sub.submissioncomment'); $assignmenttypestring = $DB->sql_compare_text('moduletable.assignmenttype'); $datastring = $DB->sql_compare_text('sub.data2'); // Resubmit seems not to be used for upload types. $query->add_where(array('type' => 'AND', 'condition' => "( (sub.grade = -1 AND {$commentstring} = '') /* Never marked */\n OR\n ( ( moduletable.resubmit = 1\n OR ({$assignmenttypestring} = 'upload' AND moduletable.var4 = 1)\n ) /* Resubmit allowed */\n AND (sub.timemodified > sub.timemarked) /* Resubmit happened */\n )\n )\n /* Not in draft state */\n AND ( {$assignmenttypestring} != 'upload'\n OR ( {$assignmenttypestring} = 'upload' AND {$datastring} = 'submitted'))\n AND {$assignmenttypestring} != 'offline'\n ")); // TODO only sent for marking. // Advanced upload: data2 will be 'submitted' and grade will be -1, but if 'save changes' // is clicked, timemarked will be set to time(), but actually, grade and comment may // still be empty. return $query; }
/** * We need to check whether the activity can be displayed (the user may have hidden it * using the settings). This sql can be dropped into a query so that it will get the right * students. This will also make sure that if only some groups are being displayed, the * submission is by a user who is in one of the displayed groups. * * @param block_ajax_marking_query_base $query a query object to apply these changes to * @return void */ private static function apply_sql_display_settings($query) { // Here, we filter out the users with no group memberships, where the users without group // memberships have been set to be hidden for this coursemodule. // Second bit (after OR) filters out those who have group memberships, but all of them are // set to be hidden. This is done by saying 'are there any visible at all' // The bit after that, talking about separate groups is to make sure users don't see any // of these groups unless they are members of them if separate groups is enabled. // $sitedefaultnogroup = 1; // what to do with users who have no group membership? // list($existsvisibilitysubquery, $existsparams) = block_ajax_marking_group_visibility_subquery(); // $query->add_params($existsparams); // $hidden = <<<SQL // ( // ( /* User has no group memberships */ // NOT EXISTS (SELECT NULL // FROM {groups_members} groups_members // INNER JOIN {groups} groups // ON groups_members.groupid = groups.id // WHERE groups_members.userid = moduleunion.userid // AND groups.courseid = moduleunion.course) // // /* Settings say 'show people who have no group memberships' */ // AND ( COALESCE(cmconfig.showorphans, // courseconfig.showorphans, // {$sitedefaultnogroup}) = 1 ) ) // // OR // // /* student is in at least one group that is supposed to be shown to this teacher */ // ( EXISTS (SELECT NULL // FROM {groups_members} groups_members // INNER JOIN {groups} groups // ON groups_members.groupid = groups.id // INNER JOIN ({$existsvisibilitysubquery}) existsvisibilitysubquery // ON existsvisibilitysubquery.groupid = groups.id // WHERE groups_members.userid = moduleunion.userid // AND existsvisibilitysubquery.cmid = moduleunion.coursemoduleid // AND groups.courseid = moduleunion.course // AND existsvisibilitysubquery.display = 1) // ) // ) //SQL; // $query->add_where(array('type' => 'AND', // 'condition' => $hidden)); // We allow course settings to override the site default and activity settings to override // the course ones. $sitedefaultactivitydisplay = 1; $query->add_where(array('type' => 'AND', 'condition' => "COALESCE(cmconfig.display,\n courseconfig.display,\n {$sitedefaultactivitydisplay}) = 1")); }
/** * Returns a query object with the basics all set up to get assignment stuff * * @global moodle_database $DB * @return block_ajax_marking_query_base */ public function query_factory() { global $DB; $query = new block_ajax_marking_query_base($this); $query->add_from(array('table' => $this->modulename, 'alias' => 'moduletable')); $query->add_from(array('table' => 'quiz_attempts', 'on' => 'moduletable.id = quiz_attempts.quiz')); $query->add_from(array('table' => 'question_attempts', 'on' => 'question_attempts.questionusageid = quiz_attempts.uniqueid')); $query->add_from(array('table' => 'question_attempt_steps', 'alias' => 'sub', 'on' => 'question_attempts.id = sub.questionattemptid')); $query->add_from(array('table' => 'question', 'on' => 'question_attempts.questionid = question.id')); // Standard userid for joins. $query->add_select(array('table' => 'quiz_attempts', 'column' => 'userid')); $query->add_select(array('table' => 'sub', 'column' => 'timecreated', 'alias' => 'timestamp')); $query->add_where(array('type' => 'AND', 'condition' => 'quiz_attempts.timefinish > 0')); $query->add_where(array('type' => 'AND', 'condition' => 'quiz_attempts.preview = 0')); $comparesql = $DB->sql_compare_text('question_attempts.behaviour') . " = 'manualgraded'"; $query->add_where(array('type' => 'AND', 'condition' => $comparesql)); $query->add_where(array('type' => 'AND', 'condition' => "sub.state = '" . question_state::$needsgrading . "' ")); // We want to get a list of graded states so we can retrieve all questions that don't have // one. $gradedstates = array(); $us = new ReflectionClass('question_state'); foreach ($us->getStaticProperties() as $name => $class) { /* @var question_state $class */ if ($class->is_graded()) { $gradedstates[] = $name; } } list($gradedsql, $gradedparams) = $DB->get_in_or_equal($gradedstates, SQL_PARAMS_NAMED, 'quizq001'); $subsql = "NOT EXISTS( SELECT 1\n FROM {question_attempt_steps} st\n WHERE st.state {$gradedsql}\n AND st.questionattemptid = question_attempts.id)"; $query->add_where(array('type' => 'AND', 'condition' => $subsql)); $query->add_params($gradedparams); return $query; }
/** * Returns a query object with the basics all set up to get assignment stuff * * @global moodle_database $DB * @return block_ajax_marking_query_base */ public function query_factory() { global $USER; $query = new block_ajax_marking_query_base($this); $query->add_from(array('table' => $this->modulename, 'alias' => 'moduletable')); $query->add_from(array('join' => 'INNER JOIN', 'table' => 'workshop_submissions', 'alias' => 'sub', 'on' => 'sub.workshopid = moduletable.id')); $query->add_from(array('join' => 'LEFT JOIN', 'table' => 'workshop_assessments', 'alias' => 'a', 'on' => 'sub.id = a.submissionid')); // Standard userid for joins. $query->add_select(array('table' => 'sub', 'column' => 'authorid', 'alias' => 'userid')); $query->add_select(array('table' => 'sub', 'column' => 'timemodified', 'alias' => 'timestamp')); // Assumes that we want to see stuff that has not been assessed by the current user yet. Perhaps // we have more than one assessor? Perhaps it's peer assessment only? $query->add_where(array('type' => 'AND', 'condition' => 'NOT EXISTS( SELECT 1 FROM {workshop_assessments} workshop_assessments WHERE workshop_assessments.submissionid = sub.id AND workshop_assessments.reviewerid = :workshopuserid AND workshop_assessments.grade != -1 )')); $query->add_where(array('type' => 'AND', 'condition' => 'moduletable.phase < ' . workshop::PHASE_CLOSED)); // Do we want to only see stuff when the workshop has been put into a later phase? // If it has, a teacher will have done this manually and will know about the grading work. // Unless there are two teachers. $query->add_param('workshopuserid', $USER->id); return $query; }
/** * This is for when a courseid node is an ancestor of the node that has been * selected, so we just do a where. * * @param block_ajax_marking_query_base $query * @param int $courseid * @SuppressWarnings(PHPMD.UnusedPrivateMethod) Dynamic method names don't register */ public static function configwhere_filter(block_ajax_marking_query_base $query, $courseid) { $conditions = array('type' => 'AND', 'condition' => 'course_modules.course = :courseidfiltercourseid'); $query->add_where($conditions); $query->add_param('courseidfiltercourseid', $courseid); }
/** * Returns a query object with the basics all set up to get assignment stuff * * @global moodle_database $DB * @return block_ajax_marking_query_base */ public function query_factory() { global $USER; $query = new block_ajax_marking_query_base($this); // This currently does a simple check for whether or not the current user has added a // rating or not. No scope for another teacher to do all the marking, or some of it. list($notmyratingsql, $notmyratingparams) = $this->get_teacher_sql(); $query->add_params($notmyratingparams); $query->add_from(array('table' => 'forum_posts', 'alias' => 'sub')); $query->add_from(array('table' => 'forum_discussions', 'alias' => 'discussions', 'on' => 'sub.discussion = discussions.id')); $query->add_from(array('table' => $this->modulename, 'alias' => 'moduletable', 'on' => 'discussions.forum = moduletable.id')); // We need the context id to check the ratings table in the teacher SQL. $query->add_from(array('table' => 'course_modules', 'alias' => 'forumcoursemodules', 'on' => 'moduletable.id = forumcoursemodules.instance ' . 'AND forumcoursemodules.module = ' . $this->get_module_id())); $query->add_from(array('table' => 'context', 'alias' => 'forumcontext', 'on' => 'forumcoursemodules.id = forumcontext.instanceid ' . 'AND forumcontext.contextlevel = ' . CONTEXT_MODULE)); // Standard userid for joins. $query->add_select(array('table' => 'sub', 'column' => 'userid')); $query->add_select(array('table' => 'sub', 'column' => 'modified', 'alias' => 'timestamp')); $query->add_where(array('type' => 'AND', 'condition' => 'sub.userid <> :forumuserid')); $query->add_where(array('type' => 'AND', 'condition' => 'moduletable.assessed > 0')); $query->add_where(array('type' => 'AND', 'condition' => " {$notmyratingsql} ")); $query->add_where(array('type' => 'AND', 'condition' => '( (moduletable.assesstimestart = 0) OR (sub.created >= moduletable.assesstimestart) ) ')); $query->add_where(array('type' => 'AND', 'condition' => '( (moduletable.assesstimefinish = 0) OR (sub.created <= moduletable.assesstimefinish) )')); $query->add_param('forumuserid', $USER->id); return $query; }
/** * Returns a query object with the basics all set up to get assignment stuff * * @global moodle_database $DB * @return block_ajax_marking_query_base */ public function query_factory() { global $DB, $USER; $query = new block_ajax_marking_query_base($this); $query->add_from(array('table' => 'assign', 'alias' => 'moduletable')); $query->add_from(array('join' => 'INNER JOIN', 'table' => 'assign_submission', 'alias' => 'sub', 'on' => 'sub.assignment = moduletable.id')); // LEFT JOIN, rather than NOT EXISTS because we may have an empty form saved, which // will create a grade record, but with a null grade. These should still count as ungraded. $query->add_from(array('join' => 'LEFT JOIN', 'table' => 'assign_grades', 'on' => 'assign_grades.assignment = moduletable.id AND assign_grades.userid = sub.userid AND assign_grades.grader = :assigngraderid')); $query->add_param('assigngraderid', $USER->id); // Standard user id for joins. $query->add_select(array('table' => 'sub', 'column' => 'userid')); $query->add_select(array('table' => 'sub', 'column' => 'timemodified', 'alias' => 'timestamp')); $statustext = $DB->sql_compare_text('sub.status'); $query->add_where(array('type' => 'AND', 'condition' => $statustext . " = '" . ASSIGN_SUBMISSION_STATUS_SUBMITTED . "'")); $query->add_where(array('type' => 'AND', 'condition' => 'assign_grades.grade IS NULL')); // First bit: not graded // Second bit of first bit: has been resubmitted // Third bit: if it's advanced upload, only care about the first bit if 'send for marking' // was clicked. return $query; }