public function check_answer()
 {
     global $DB, $CFG;
     $formattextdefoptions = new stdClass();
     $formattextdefoptions->noclean = true;
     $formattextdefoptions->para = false;
     $answers = $this->get_answers();
     shuffle($answers);
     $params = array('answers' => $answers, 'lessonid' => $this->lesson->id, 'contents' => $this->get_contents());
     $mform = new lesson_display_answer_form_truefalse($CFG->wwwroot . '/mod/lesson/continue.php', $params);
     $data = $mform->get_data();
     require_sesskey();
     $result = parent::check_answer();
     if (empty($data->answerid)) {
         $result->noanswer = true;
         return $result;
     }
     $result->answerid = $data->answerid;
     $answer = $DB->get_record("lesson_answers", array("id" => $result->answerid), '*', MUST_EXIST);
     if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
         $result->correctanswer = true;
     }
     if ($this->lesson->custom) {
         if ($answer->score > 0) {
             $result->correctanswer = true;
         } else {
             $result->correctanswer = false;
         }
     }
     $result->newpageid = $answer->jumpto;
     $result->response = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
     $result->studentanswer = $result->userresponse = $answer->answer;
     return $result;
 }
Beispiel #2
0
    public function check_answer() {
        global $CFG;
        $result = parent::check_answer();

        $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
        $data = $mform->get_data();
        require_sesskey();

        $formattextdefoptions = new stdClass();
        $formattextdefoptions->noclean = true;
        $formattextdefoptions->para = false;

        // set defaults
        $result->response = '';
        $result->newpageid = 0;

        if (!isset($data->answer) || !is_numeric($data->answer)) {
            $result->noanswer = true;
            return $result;
        } else {
            // Just doing default PARAM_RAW, not doing PARAM_INT because it could be a float.
            $result->useranswer = (float)$data->answer;
        }
        $result->studentanswer = $result->userresponse = $result->useranswer;
        $answers = $this->get_answers();
        foreach ($answers as $answer) {
            $answer = parent::rewrite_answers_urls($answer);
            if (strpos($answer->answer, ':')) {
                // there's a pairs of values
                list($min, $max) = explode(':', $answer->answer);
                $minimum = (float) $min;
                $maximum = (float) $max;
            } else {
                // there's only one value
                $minimum = (float) $answer->answer;
                $maximum = $minimum;
            }
            if (($result->useranswer >= $minimum) && ($result->useranswer <= $maximum)) {
                $result->newpageid = $answer->jumpto;
                $result->response = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
                if ($this->lesson->jumpto_is_correct($this->properties->id, $result->newpageid)) {
                    $result->correctanswer = true;
                }
                if ($this->lesson->custom) {
                    if ($answer->score > 0) {
                        $result->correctanswer = true;
                    } else {
                        $result->correctanswer = false;
                    }
                }
                $result->answerid = $answer->id;
                return $result;
            }
        }
        return $result;
    }
 /**
  * Add a new section with the provided title and (optional) summary
  *
  * @return string
  */
 public function addsection_action()
 {
     global $CFG, $PAGE, $DB;
     require_once $CFG->dirroot . '/course/lib.php';
     $sectioname = required_param('newsection', PARAM_TEXT);
     $summary = optional_param('summary', '', PARAM_RAW);
     require_sesskey();
     $courseid = $PAGE->context->get_course_context()->instanceid;
     $course = course_get_format($courseid)->get_course();
     $course->numsections++;
     course_get_format($course)->update_course_format_options(array('numsections' => $course->numsections));
     course_create_sections_if_missing($course, range(0, $course->numsections));
     $modinfo = get_fast_modinfo($course);
     $section = $modinfo->get_section_info($course->numsections, MUST_EXIST);
     $DB->set_field('course_sections', 'name', $sectioname, array('id' => $section->id));
     $DB->set_field('course_sections', 'summary', $summary, array('id' => $section->id));
     $DB->set_field('course_sections', 'summaryformat', FORMAT_HTML, array('id' => $section->id));
     rebuild_course_cache($course->id);
     redirect(course_get_url($course, $section->section));
 }
 /**
  * Toggle Post Flags
  */
 public function flag_action()
 {
     global $DB;
     require_sesskey();
     $postid = required_param('postid', PARAM_INT);
     $flag = required_param('flag', PARAM_ALPHA);
     $returnurl = required_param('returnurl', PARAM_LOCALURL);
     $flags = $DB->get_field('hsuforum_posts', 'flags', array('id' => $postid), MUST_EXIST);
     $flaglib = new \hsuforum_lib_flag();
     $newflags = $flaglib->toggle_flag($flags, $flag);
     if ($newflags != $flags) {
         $updateok = $DB->set_field('hsuforum_posts', 'flags', $newflags, array('id' => $postid));
         if (AJAX_SCRIPT && !$updateok) {
             http_response_code(500);
         }
     }
     if (!AJAX_SCRIPT) {
         redirect(new \moodle_url($returnurl));
     }
 }
Beispiel #5
0
 /**
  * Check for a sess key and then call add_attempt.
  *
  * @param int $userid int The user to add the attempt for
  * @return bool - true if successful.
  */
 protected function process_add_attempt($userid)
 {
     require_sesskey();
     return $this->add_attempt($userid);
 }
Beispiel #6
0
 /**
  * main invoke method, it sets the postaction attribute
  * if possible and checks sesskey_protected if needed
  */
 function invoke()
 {
     global $SESSION;
     // Sesskey protection
     if ($this->sesskey_protected) {
         require_sesskey();
     }
     // If we are used any dir, save it in the lastused session object
     // Some actions can use it to perform positioning
     if ($lastused = optional_param('dir', NULL, PARAM_PATH)) {
         $SESSION->lastused = $lastused;
     }
     $this->postaction = optional_param('postaction', NULL, PARAM_ALPHAEXT);
     // Avoid being recursive
     if ($this->title == $this->postaction) {
         $this->postaction = NULL;
     }
 }
Beispiel #7
0
 /**
  * Handle showing/processing the submission from the block editing form.
  * @return boolean true if the form was submitted and the new config saved. Does not
  *      return if the editing form was displayed. False otherwise.
  */
 public function process_url_move()
 {
     global $CFG, $DB, $PAGE;
     $blockid = optional_param('bui_moveid', null, PARAM_INT);
     if (!$blockid) {
         return false;
     }
     require_sesskey();
     $block = $this->find_instance($blockid);
     if (!$this->page->user_can_edit_blocks()) {
         throw new moodle_exception('nopermissions', '', $this->page->url->out(), get_string('editblock'));
     }
     $newregion = optional_param('bui_newregion', '', PARAM_ALPHANUMEXT);
     $newweight = optional_param('bui_newweight', null, PARAM_FLOAT);
     if (!$newregion || is_null($newweight)) {
         // Don't have a valid target position yet, must be just starting the move.
         $this->movingblock = $blockid;
         $this->page->ensure_param_not_in_url('bui_moveid');
         return false;
     }
     if (!$this->is_known_region($newregion)) {
         throw new moodle_exception('unknownblockregion', '', $this->page->url, $newregion);
     }
     // Move this block. This may involve moving other nearby blocks.
     $blocks = $this->birecordsbyregion[$newregion];
     $maxweight = self::MAX_WEIGHT;
     $minweight = -self::MAX_WEIGHT;
     // Initialise the used weights and spareweights array with the default values
     $spareweights = array();
     $usedweights = array();
     for ($i = $minweight; $i <= $maxweight; $i++) {
         $spareweights[$i] = $i;
         $usedweights[$i] = array();
     }
     // Check each block and sort out where we have used weights
     foreach ($blocks as $bi) {
         if ($bi->weight > $maxweight) {
             // If this statement is true then the blocks weight is more than the
             // current maximum. To ensure that we can get the best block position
             // we will initialise elements within the usedweights and spareweights
             // arrays between the blocks weight (which will then be the new max) and
             // the current max
             $parseweight = $bi->weight;
             while (!array_key_exists($parseweight, $usedweights)) {
                 $usedweights[$parseweight] = array();
                 $spareweights[$parseweight] = $parseweight;
                 $parseweight--;
             }
             $maxweight = $bi->weight;
         } else {
             if ($bi->weight < $minweight) {
                 // As above except this time the blocks weight is LESS than the
                 // the current minimum, so we will initialise the array from the
                 // blocks weight (new minimum) to the current minimum
                 $parseweight = $bi->weight;
                 while (!array_key_exists($parseweight, $usedweights)) {
                     $usedweights[$parseweight] = array();
                     $spareweights[$parseweight] = $parseweight;
                     $parseweight++;
                 }
                 $minweight = $bi->weight;
             }
         }
         if ($bi->id != $block->instance->id) {
             unset($spareweights[$bi->weight]);
             $usedweights[$bi->weight][] = $bi->id;
         }
     }
     // First we find the nearest gap in the list of weights.
     $bestdistance = max(abs($newweight - self::MAX_WEIGHT), abs($newweight + self::MAX_WEIGHT)) + 1;
     $bestgap = null;
     foreach ($spareweights as $spareweight) {
         if (abs($newweight - $spareweight) < $bestdistance) {
             $bestdistance = abs($newweight - $spareweight);
             $bestgap = $spareweight;
         }
     }
     // If there is no gap, we have to go outside -self::MAX_WEIGHT .. self::MAX_WEIGHT.
     if (is_null($bestgap)) {
         $bestgap = self::MAX_WEIGHT + 1;
         while (!empty($usedweights[$bestgap])) {
             $bestgap++;
         }
     }
     // Now we know the gap we are aiming for, so move all the blocks along.
     if ($bestgap < $newweight) {
         $newweight = floor($newweight);
         for ($weight = $bestgap + 1; $weight <= $newweight; $weight++) {
             foreach ($usedweights[$weight] as $biid) {
                 $this->reposition_block($biid, $newregion, $weight - 1);
             }
         }
         $this->reposition_block($block->instance->id, $newregion, $newweight);
     } else {
         $newweight = ceil($newweight);
         for ($weight = $bestgap - 1; $weight >= $newweight; $weight--) {
             if (array_key_exists($weight, $usedweights)) {
                 foreach ($usedweights[$weight] as $biid) {
                     $this->reposition_block($biid, $newregion, $weight + 1);
                 }
             }
         }
         $this->reposition_block($block->instance->id, $newregion, $newweight);
     }
     $this->page->ensure_param_not_in_url('bui_moveid');
     $this->page->ensure_param_not_in_url('bui_newregion');
     $this->page->ensure_param_not_in_url('bui_newweight');
     return true;
 }
Beispiel #8
0
/**
 * Returns draft area itemid for a given element.
 *
 * @category files
 * @param string $elname name of formlib editor element, or a hidden form field that stores the draft area item id, etc.
 * @return int the itemid, or 0 if there is not one yet.
 */
function file_get_submitted_draft_itemid($elname)
{
    // this is a nasty hack, ideally all new elements should use arrays here or there should be a new parameter
    if (!isset($_REQUEST[$elname])) {
        return 0;
    }
    if (is_array($_REQUEST[$elname])) {
        $param = optional_param_array($elname, 0, PARAM_INT);
        if (!empty($param['itemid'])) {
            $param = $param['itemid'];
        } else {
            debugging('Missing itemid, maybe caused by unset maxfiles option', DEBUG_DEVELOPER);
            return false;
        }
    } else {
        $param = optional_param($elname, 0, PARAM_INT);
    }
    if ($param) {
        require_sesskey();
    }
    return $param;
}
Beispiel #9
0
/**
 * Returns draft area itemid for a given element.
 *
 * @param string $elname name of formlib editor element, or a hidden form field that stores the draft area item id, etc.
 * @return integer the itemid, or 0 if there is not one yet.
 */
function file_get_submitted_draft_itemid($elname)
{
    $param = optional_param($elname, 0, PARAM_INT);
    if ($param) {
        require_sesskey();
    }
    if (is_array($param)) {
        if (!empty($param['itemid'])) {
            $param = $param['itemid'];
        } else {
            debugging('Missing itemid, maybe caused by unset maxfiles option', DEBUG_DEVELOPER);
            return false;
        }
    }
    return $param;
}
Beispiel #10
0
 public function construction_override($pageid, lesson $lesson)
 {
     global $CFG, $PAGE, $DB;
     require_sesskey();
     $timenow = time();
     // the new page is not the first page (end of cluster always comes after an existing page)
     if (!($page = $DB->get_record("lesson_pages", array("id" => $pageid)))) {
         print_error('cannotfindpages', 'lesson');
     }
     // could put code in here to check if the user really can insert an end of cluster
     $newpage = new stdClass();
     $newpage->lessonid = $lesson->id;
     $newpage->prevpageid = $pageid;
     $newpage->nextpageid = $page->nextpageid;
     $newpage->qtype = $this->qtype;
     $newpage->timecreated = $timenow;
     $newpage->title = get_string("endofclustertitle", "lesson");
     $newpage->contents = get_string("endofclustertitle", "lesson");
     $newpageid = $DB->insert_record("lesson_pages", $newpage);
     // update the linked list...
     $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
     if ($page->nextpageid) {
         // the new page is not the last page
         $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
     }
     // ..and the single "answer"
     $newanswer = new stdClass();
     $newanswer->lessonid = $lesson->id;
     $newanswer->pageid = $newpageid;
     $newanswer->timecreated = $timenow;
     $newanswer->jumpto = LESSON_NEXTPAGE;
     $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
     $lesson->add_message(get_string('addedendofcluster', 'lesson'), 'notifysuccess');
     redirect($CFG->wwwroot . '/mod/lesson/edit.php?id=' . $PAGE->cm->id);
 }
Beispiel #11
0
    public function check_answer() {
        global $USER, $DB, $PAGE, $CFG;

        require_sesskey();
        $newpageid = optional_param('jumpto', NULL, PARAM_INT);
        // going to insert into lesson_branch
        if ($newpageid == LESSON_RANDOMBRANCH) {
            $branchflag = 1;
        } else {
            $branchflag = 0;
        }
        if ($grades = $DB->get_records("lesson_grades", array("lessonid" => $this->lesson->id, "userid" => $USER->id), "grade DESC")) {
            $retries = count($grades);
        } else {
            $retries = 0;
        }
        $branch = new stdClass;
        $branch->lessonid = $this->lesson->id;
        $branch->userid = $USER->id;
        $branch->pageid = $this->properties->id;
        $branch->retry = $retries;
        $branch->flag = $branchflag;
        $branch->timeseen = time();

        $DB->insert_record("lesson_branch", $branch);

        //  this is called when jumping to random from a branch table
        $context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id);
        if($newpageid == LESSON_UNSEENBRANCHPAGE) {
            if (has_capability('mod/lesson:manage', $context)) {
                 $newpageid = LESSON_NEXTPAGE;
            } else {
                 $newpageid = lesson_unseen_question_jump($this->lesson, $USER->id, $this->properties->id);  // this may return 0
            }
        }
        // convert jumpto page into a proper page id
        if ($newpageid == 0) {
            $newpageid = $this->properties->id;
        } elseif ($newpageid == LESSON_NEXTPAGE) {
            if (!$newpageid = $this->nextpageid) {
                // no nextpage go to end of lesson
                $newpageid = LESSON_EOL;
            }
        } elseif ($newpageid == LESSON_PREVIOUSPAGE) {
            $newpageid = $this->prevpageid;
        } elseif ($newpageid == LESSON_RANDOMPAGE) {
            $newpageid = lesson_random_question_jump($this->lesson, $this->properties->id);
        } elseif ($newpageid == LESSON_RANDOMBRANCH) {
            $newpageid = lesson_unseen_branch_jump($this->lesson, $USER->id);
        }
        // no need to record anything in lesson_attempts
        redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id,'pageid'=>$newpageid)));
    }
Beispiel #12
0
 /**
  * save grade
  *
  * @param  moodleform $mform
  * @return bool - was the grade saved
  */
 private function process_save_grade(&$mform)
 {
     global $USER, $DB, $CFG;
     // Include grade form
     require_once $CFG->dirroot . '/mod/assign/gradeform.php';
     // Need submit permission to submit an assignment
     require_capability('mod/assign:grade', $this->context);
     require_sesskey();
     $rownum = required_param('rownum', PARAM_INT);
     $useridlist = optional_param('useridlist', '', PARAM_TEXT);
     if ($useridlist) {
         $useridlist = explode(',', $useridlist);
     } else {
         $useridlist = $this->get_grading_userid_list();
     }
     $last = false;
     $userid = $useridlist[$rownum];
     if ($rownum == count($useridlist) - 1) {
         $last = true;
     }
     $data = new stdClass();
     $mform = new mod_assign_grade_form(null, array($this, $data, array('rownum' => $rownum, 'useridlist' => $useridlist, 'last' => false)), 'post', '', array('class' => 'gradeform'));
     if ($formdata = $mform->get_data()) {
         $grade = $this->get_user_grade($userid, true);
         $gradingdisabled = $this->grading_disabled($userid);
         $gradinginstance = $this->get_grading_instance($userid, $gradingdisabled);
         if (!$gradingdisabled) {
             if ($gradinginstance) {
                 $grade->grade = $gradinginstance->submit_and_get_grade($formdata->advancedgrading, $grade->id);
             } else {
                 // handle the case when grade is set to No Grade
                 if (isset($formdata->grade)) {
                     $grade->grade = grade_floatval(unformat_float($formdata->grade));
                 }
             }
         }
         $grade->grader = $USER->id;
         $adminconfig = $this->get_admin_config();
         $gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
         // call save in plugins
         foreach ($this->feedbackplugins as $plugin) {
             if ($plugin->is_enabled() && $plugin->is_visible()) {
                 if (!$plugin->save($grade, $formdata)) {
                     $result = false;
                     print_error($plugin->get_error());
                 }
                 if ('assignfeedback_' . $plugin->get_type() == $gradebookplugin) {
                     // this is the feedback plugin chose to push comments to the gradebook
                     $grade->feedbacktext = $plugin->text_for_gradebook($grade);
                     $grade->feedbackformat = $plugin->format_for_gradebook($grade);
                 }
             }
         }
         $this->process_outcomes($userid, $formdata);
         $grade->mailed = 0;
         $this->update_grade($grade);
         $this->notify_grade_modified($grade);
         $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
         $this->add_to_log('grade submission', $this->format_grade_for_log($grade));
     } else {
         return false;
     }
     return true;
 }
 /**
  * Render coupon page (including header / footer).
  *
  * @param int $id block instance id
  * @param int $filter table filter
  * @param int $ownerid the owner id of the coupons. Set 0 or NULL to see all.
  * @return string
  */
 protected function page_coupons($id, $filter, $ownerid = null)
 {
     // Actions anyone?
     $action = optional_param('action', null, PARAM_ALPHA);
     if ($action === 'delete' && $filter === \block_coupon\tables\coupons::UNUSED) {
         global $DB;
         require_sesskey();
         $id = required_param('itemid', PARAM_INT);
         $DB->delete_records('block_coupon', array('id' => $id));
         $DB->delete_records('block_coupon_cohorts', array('couponid' => $id));
         $DB->delete_records('block_coupon_groups', array('couponid' => $id));
         $DB->delete_records('block_coupon_courses', array('couponid' => $id));
         redirect($this->page->url, get_string('coupon:deleted', 'block_coupon'));
     }
     // Table instance.
     $table = new \block_coupon\tables\coupons($ownerid, $filter);
     $table->baseurl = $this->page->url;
     $table->is_downloadable(true);
     $table->show_download_buttons_at(array(TABLE_P_BOTTOM, TABLE_P_TOP));
     $download = optional_param('download', '', PARAM_ALPHA);
     if (!empty($download)) {
         $table->is_downloading($download, 'coupons', 'coupons');
         $table->render(25);
         exit;
     }
     $selectedtab = '';
     switch ($filter) {
         case \block_coupon\tables\coupons::UNUSED:
             $selectedtab = 'cpunused';
             break;
         case \block_coupon\tables\coupons::USED:
             $selectedtab = 'cpused';
             break;
     }
     $out = '';
     $out .= $this->header();
     $out .= html_writer::start_div('block-coupon-container');
     $out .= html_writer::start_div();
     $out .= $this->get_tabs($this->page->context, $selectedtab, array('id' => $id));
     $out .= html_writer::end_div();
     ob_start();
     $table->render(25);
     $out .= ob_get_clean();
     $out .= html_writer::end_div();
     $out .= $this->footer();
     return $out;
 }
Beispiel #14
0
 /**
  * Call an external function validating all params/returns correctly.
  *
  * Note that an external function may modify the state of the current page, so this wrapper
  * saves and restores tha PAGE and COURSE global variables before/after calling the external function.
  *
  * @param string $function A webservice function name.
  * @param array $args Params array (named params)
  * @param boolean $ajaxonly If true, an extra check will be peformed to see if ajax is required.
  * @return array containing keys for error (bool), exception and data.
  */
 public static function call_external_function($function, $args, $ajaxonly = false)
 {
     global $PAGE, $COURSE, $CFG, $SITE;
     require_once $CFG->libdir . "/pagelib.php";
     $externalfunctioninfo = self::external_function_info($function);
     $currentpage = $PAGE;
     $currentcourse = $COURSE;
     $response = array();
     try {
         // Taken straight from from setup.php.
         if (!empty($CFG->moodlepageclass)) {
             if (!empty($CFG->moodlepageclassfile)) {
                 require_once $CFG->moodlepageclassfile;
             }
             $classname = $CFG->moodlepageclass;
         } else {
             $classname = 'moodle_page';
         }
         $PAGE = new $classname();
         $COURSE = clone $SITE;
         if ($ajaxonly && !$externalfunctioninfo->allowed_from_ajax) {
             throw new moodle_exception('servicenotavailable', 'webservice');
         }
         // Do not allow access to write or delete webservices as a public user.
         if ($externalfunctioninfo->loginrequired) {
             if (defined('NO_MOODLE_COOKIES') && NO_MOODLE_COOKIES && !PHPUNIT_TEST) {
                 throw new moodle_exception('servicenotavailable', 'webservice');
             }
             if (!isloggedin()) {
                 throw new moodle_exception('servicenotavailable', 'webservice');
             } else {
                 require_sesskey();
             }
         }
         // Validate params, this also sorts the params properly, we need the correct order in the next part.
         $callable = array($externalfunctioninfo->classname, 'validate_parameters');
         $params = call_user_func($callable, $externalfunctioninfo->parameters_desc, $args);
         // Execute - gulp!
         $callable = array($externalfunctioninfo->classname, $externalfunctioninfo->methodname);
         $result = call_user_func_array($callable, array_values($params));
         // Validate the return parameters.
         if ($externalfunctioninfo->returns_desc !== null) {
             $callable = array($externalfunctioninfo->classname, 'clean_returnvalue');
             $result = call_user_func($callable, $externalfunctioninfo->returns_desc, $result);
         }
         $response['error'] = false;
         $response['data'] = $result;
     } catch (Exception $e) {
         $exception = get_exception_info($e);
         unset($exception->a);
         if (!debugging('', DEBUG_DEVELOPER)) {
             unset($exception->debuginfo);
             unset($exception->backtrace);
         }
         $response['error'] = true;
         $response['exception'] = $exception;
         // Do not process the remaining requests.
     }
     $PAGE = $currentpage;
     $COURSE = $currentcourse;
     return $response;
 }
Beispiel #15
0
 public function check_answer()
 {
     global $CFG, $PAGE;
     $formattextdefoptions = new stdClass();
     $formattextdefoptions->noclean = true;
     $formattextdefoptions->para = false;
     $result = parent::check_answer();
     $mform = $this->make_answer_form();
     $data = $mform->get_data();
     require_sesskey();
     if (!$data) {
         redirect(new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id, 'pageid' => $this->properties->id)));
     }
     $response = $data->response;
     if (!is_array($response)) {
         $result->noanswer = true;
         return $result;
     }
     $answers = $this->get_answers();
     $correct = array_shift($answers);
     $wrong = array_shift($answers);
     foreach ($answers as $key => $answer) {
         if ($answer->answer === '' or $answer->response === '') {
             // incomplete option!
             unset($answers[$key]);
         }
     }
     // get he users exact responses for record keeping
     $hits = 0;
     $userresponse = array();
     foreach ($response as $key => $value) {
         foreach ($answers as $answer) {
             if ($value === $answer->response) {
                 $userresponse[] = $answer->id;
             }
             if ((int) $answer->id === (int) $key) {
                 $result->studentanswer .= '<br />' . format_text($answer->answer, $answer->answerformat, $formattextdefoptions) . ' = ' . $value;
             }
             if ((int) $answer->id === (int) $key and $value === $answer->response) {
                 $hits++;
             }
         }
     }
     $result->userresponse = implode(",", $userresponse);
     if ($hits == count($answers)) {
         $result->correctanswer = true;
         $result->response = format_text($correct->answer, $correct->answerformat, $formattextdefoptions);
         $result->answerid = $correct->id;
         $result->newpageid = $correct->jumpto;
     } else {
         $result->correctanswer = false;
         $result->response = format_text($wrong->answer, $wrong->answerformat, $formattextdefoptions);
         $result->answerid = $wrong->id;
         $result->newpageid = $wrong->jumpto;
     }
     return $result;
 }
Beispiel #16
0
 /**
  * Hook method to handle the remote request to install an add-on
  *
  * This is used as a callback when the admin picks a plugin version in the
  * Moodle Plugins directory and is redirected back to their site to install
  * it.
  *
  * This hook is called early from admin/tool/installaddon/index.php page so that
  * it has opportunity to take over the UI.
  *
  * @param tool_installaddon_renderer $output
  * @param string|null $request
  * @param bool $confirmed
  */
 public function handle_remote_request(tool_installaddon_renderer $output, $request, $confirmed = false)
 {
     global $CFG;
     require_once dirname(__FILE__) . '/pluginfo_client.php';
     if (is_null($request)) {
         return;
     }
     $data = $this->decode_remote_request($request);
     if ($data === false) {
         echo $output->remote_request_invalid_page($this->index_url());
         exit;
     }
     list($plugintype, $pluginname) = normalize_component($data->component);
     $plugintypepath = $this->get_plugintype_root($plugintype);
     if (file_exists($plugintypepath . '/' . $pluginname)) {
         echo $output->remote_request_alreadyinstalled_page($data, $this->index_url());
         exit;
     }
     if (!$this->is_plugintype_writable($plugintype)) {
         $continueurl = $this->index_url(array('installaddonrequest' => $request));
         echo $output->remote_request_permcheck_page($data, $plugintypepath, $continueurl, $this->index_url());
         exit;
     }
     $continueurl = $this->index_url(array('installaddonrequest' => $request, 'confirm' => 1, 'sesskey' => sesskey()));
     if (!$confirmed) {
         echo $output->remote_request_confirm_page($data, $continueurl, $this->index_url());
         exit;
     }
     // The admin has confirmed their intention to install the add-on.
     require_sesskey();
     // Fetch the plugin info. The essential information is the URL to download the ZIP
     // and the MD5 hash of the ZIP, obtained via HTTPS.
     $client = tool_installaddon_pluginfo_client::instance();
     try {
         $pluginfo = $client->get_pluginfo($data->component, $data->version);
     } catch (tool_installaddon_pluginfo_exception $e) {
         if (debugging()) {
             throw $e;
         } else {
             echo $output->remote_request_pluginfo_exception($data, $e, $this->index_url());
             exit;
         }
     }
     // Fetch the ZIP with the plugin version
     $jobid = md5(rand() . uniqid('', true));
     $sourcedir = make_temp_directory('tool_installaddon/' . $jobid . '/source');
     $zipfilename = 'downloaded.zip';
     try {
         $this->download_file($pluginfo->downloadurl, $sourcedir . '/' . $zipfilename);
     } catch (tool_installaddon_installer_exception $e) {
         if (debugging()) {
             throw $e;
         } else {
             echo $output->installer_exception($e, $this->index_url());
             exit;
         }
     }
     // Check the MD5 checksum
     $md5expected = $pluginfo->downloadmd5;
     $md5actual = md5_file($sourcedir . '/' . $zipfilename);
     if ($md5expected !== $md5actual) {
         $e = new tool_installaddon_installer_exception('err_zip_md5', array('expected' => $md5expected, 'actual' => $md5actual));
         if (debugging()) {
             throw $e;
         } else {
             echo $output->installer_exception($e, $this->index_url());
             exit;
         }
     }
     // Redirect to the validation page.
     $nexturl = new moodle_url('/admin/tool/installaddon/validate.php', array('sesskey' => sesskey(), 'jobid' => $jobid, 'zip' => $zipfilename, 'type' => $plugintype));
     redirect($nexturl);
 }
Beispiel #17
0
 /**
  * Allocate submissions as requested by user
  *
  * @return workshop_allocation_result
  */
 public function init()
 {
     global $PAGE;
     $mode = optional_param('mode', 'display', PARAM_ALPHA);
     $perpage = optional_param('perpage', null, PARAM_INT);
     if ($perpage and $perpage > 0 and $perpage <= 1000) {
         require_sesskey();
         set_user_preference('workshopallocation_manual_perpage', $perpage);
         redirect($PAGE->url);
     }
     $result = new workshop_allocation_result($this);
     switch ($mode) {
         case 'new':
             if (!confirm_sesskey()) {
                 throw new moodle_exception('confirmsesskeybad');
             }
             $reviewerid = required_param('by', PARAM_INT);
             $authorid = required_param('of', PARAM_INT);
             $m = array();
             // message object to be passed to the next page
             $submission = $this->workshop->get_submission_by_author($authorid);
             if (!$submission) {
                 // nothing submitted by the given user
                 $m[] = self::MSG_NOSUBMISSION;
                 $m[] = $authorid;
             } else {
                 // ok, we have the submission
                 $res = $this->workshop->add_allocation($submission, $reviewerid);
                 if ($res == workshop::ALLOCATION_EXISTS) {
                     $m[] = self::MSG_EXISTS;
                     $m[] = $submission->authorid;
                     $m[] = $reviewerid;
                 } else {
                     $m[] = self::MSG_ADDED;
                     $m[] = $submission->authorid;
                     $m[] = $reviewerid;
                 }
             }
             $m = implode('-', $m);
             // serialize message object to be passed via URL
             redirect($PAGE->url->out(false, array('m' => $m)));
             break;
         case 'del':
             if (!confirm_sesskey()) {
                 throw new moodle_exception('confirmsesskeybad');
             }
             $assessmentid = required_param('what', PARAM_INT);
             $confirmed = optional_param('confirm', 0, PARAM_INT);
             $assessment = $this->workshop->get_assessment_by_id($assessmentid);
             if ($assessment) {
                 if (!$confirmed) {
                     $m[] = self::MSG_CONFIRM_DEL;
                     $m[] = $assessment->id;
                     $m[] = $assessment->authorid;
                     $m[] = $assessment->reviewerid;
                     if (is_null($assessment->grade)) {
                         $m[] = 0;
                     } else {
                         $m[] = 1;
                     }
                 } else {
                     if ($this->workshop->delete_assessment($assessment->id)) {
                         $m[] = self::MSG_DELETED;
                         $m[] = $assessment->authorid;
                         $m[] = $assessment->reviewerid;
                     } else {
                         $m[] = self::MSG_DELETE_ERROR;
                         $m[] = $assessment->authorid;
                         $m[] = $assessment->reviewerid;
                     }
                 }
                 $m = implode('-', $m);
                 // serialize message object to be passed via URL
                 redirect($PAGE->url->out(false, array('m' => $m)));
             }
             break;
     }
     $result->set_status(workshop_allocation_result::STATUS_VOID);
     return $result;
 }
 public function discsubscribers_action()
 {
     global $OUTPUT, $USER, $DB, $COURSE, $PAGE;
     require_once dirname(dirname(__DIR__)) . '/repository/discussion.php';
     require_once dirname(dirname(__DIR__)) . '/lib/userselector/discussion/existing.php';
     require_once dirname(dirname(__DIR__)) . '/lib/userselector/discussion/potential.php';
     $discussionid = required_param('discussionid', PARAM_INT);
     $edit = optional_param('edit', -1, PARAM_BOOL);
     // Turn editing on and off.
     $url = $PAGE->url;
     $url->param('discussionid', $discussionid);
     if ($edit !== 0) {
         $url->param('edit', $edit);
     }
     $PAGE->set_url($url);
     $discussion = $DB->get_record('hsuforum_discussions', array('id' => $discussionid), '*', MUST_EXIST);
     $forum = $PAGE->activityrecord;
     $course = $COURSE;
     $cm = $PAGE->cm;
     $context = $PAGE->context;
     $repo = new \hsuforum_repository_discussion();
     if (hsuforum_is_forcesubscribed($forum)) {
         throw new coding_exception('Cannot manage discussion subscriptions when subscription is forced');
     }
     $currentgroup = groups_get_activity_group($cm);
     $options = array('forum' => $forum, 'discussion' => $discussion, 'currentgroup' => $currentgroup, 'context' => $context);
     $existingselector = new \hsuforum_userselector_discussion_existing('existingsubscribers', $options);
     $subscriberselector = new \hsuforum_userselector_discussion_potential('potentialsubscribers', $options);
     if (data_submitted()) {
         require_sesskey();
         $subscribe = (bool) optional_param('subscribe', false, PARAM_RAW);
         $unsubscribe = (bool) optional_param('unsubscribe', false, PARAM_RAW);
         /** It has to be one or the other, not both or neither */
         if (!($subscribe xor $unsubscribe)) {
             print_error('invalidaction');
         }
         if ($subscribe) {
             $users = $subscriberselector->get_selected_users();
             foreach ($users as $user) {
                 $repo->subscribe($discussion->id, $user->id);
             }
         } else {
             if ($unsubscribe) {
                 $users = $existingselector->get_selected_users();
                 foreach ($users as $user) {
                     $repo->unsubscribe($discussion->id, $user->id);
                 }
             }
         }
         $subscriberselector->invalidate_selected_users();
         $existingselector->invalidate_selected_users();
         redirect($PAGE->url);
     }
     $strsubscribers = get_string('discussionsubscribers', 'hsuforum');
     // This works but it doesn't make a good navbar, would have to change the settings menu.
     // $PAGE->settingsnav->find('discsubscribers', navigation_node::TYPE_SETTING)->make_active();
     $PAGE->navbar->add(shorten_text(format_string($discussion->name)), new moodle_url('/mod/hsuforum/discuss.php', array('d' => $discussion->id)));
     $PAGE->navbar->add($strsubscribers);
     $PAGE->set_title($strsubscribers);
     $PAGE->set_heading($COURSE->fullname);
     if (has_capability('mod/hsuforum:managesubscriptions', $context)) {
         if ($edit != -1) {
             $USER->subscriptionsediting = $edit;
         }
         if (!empty($USER->subscriptionsediting)) {
             $string = get_string('turneditingoff');
             $edit = "off";
         } else {
             $string = get_string('turneditingon');
             $edit = "on";
         }
         $url = $PAGE->url;
         $url->param('edit', $edit);
         $PAGE->set_button($OUTPUT->single_button($url, $string, 'get'));
     } else {
         unset($USER->subscriptionsediting);
     }
     $output = $OUTPUT->heading($strsubscribers);
     if (empty($USER->subscriptionsediting)) {
         $output .= $this->renderer->subscriber_overview($existingselector->get_repo()->get_subscribed_users($forum, $discussion, $context, $currentgroup), $discussion->name, $forum, $course);
     } else {
         $output .= $this->renderer->subscriber_selection_form($existingselector, $subscriberselector);
     }
     return $output;
 }
    /**
     * save grade
     *
     * @param  moodleform $mform
     * @return bool - was the grade saved
     */
    private function process_save_grade(&$mform) {
        global $CFG;
        // Include grade form
        require_once($CFG->dirroot . '/mod/assign/gradeform.php');

        // Need submit permission to submit an assignment
        require_capability('mod/assign:grade', $this->context);
        require_sesskey();

        $rownum = required_param('rownum', PARAM_INT);
        $useridlist = optional_param('useridlist', '', PARAM_TEXT);
        if ($useridlist) {
            $useridlist = explode(',', $useridlist);
        } else {
            $useridlist = $this->get_grading_userid_list();
        }
        $last = false;
        $userid = $useridlist[$rownum];
        if ($rownum == count($useridlist) - 1) {
            $last = true;
        }

        $data = new stdClass();
        $mform = new mod_assign_grade_form(null, array($this, $data, array('rownum'=>$rownum, 'useridlist'=>$useridlist, 'last'=>false)), 'post', '', array('class'=>'gradeform'));

        if ($formdata = $mform->get_data()) {
            if ($this->get_instance()->teamsubmission && $formdata->applytoall) {
                $groupid = 0;
                if ($this->get_submission_group($userid)) {
                    $group = $this->get_submission_group($userid);
                    if ($group) {
                        $groupid = $group->id;
                    }
                }
                $members = $this->get_submission_group_members($groupid, true);
                foreach ($members as $member) {
                    // User may exist in multple groups (which should put them in the default group).
                    $this->apply_grade_to_user($formdata, $member->id);
                }
            } else {
                $this->apply_grade_to_user($formdata, $userid);
            }
        } else {
            return false;
        }
        return true;
    }
Beispiel #20
0
    /**
     * Add a new attempt for a user.
     *
     * @param int $userid int The user to add the attempt for
     * @return bool - true if successful.
     */
    protected function process_add_attempt($userid) {
        require_capability('mod/assign:grade', $this->context);
        require_sesskey();

        if ($this->get_instance()->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) {
            return false;
        }

        if ($this->get_instance()->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, false);
        } else {
            $submission = $this->get_user_submission($userid, false);
        }

        if (!$submission) {
            return false;
        }

        // No more than max attempts allowed.
        if ($this->get_instance()->maxattempts != ASSIGN_UNLIMITED_ATTEMPTS &&
            $submission->attemptnumber >= ($this->get_instance()->maxattempts - 1)) {
            return false;
        }

        // Create the new submission record for the group/user.
        if ($this->get_instance()->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, true, $submission->attemptnumber+1);
        } else {
            $submission = $this->get_user_submission($userid, true, $submission->attemptnumber+1);
        }

        // Set the status of the new attempt to reopened.
        $submission->status = ASSIGN_SUBMISSION_STATUS_REOPENED;
        $this->update_submission($submission, $userid, false, $this->get_instance()->teamsubmission);
        return true;
    }
Beispiel #21
0
 /**
  * Process the upload - creating the module in the course and returning the result to the browser
  *
  * @param string $displayname optional the name (from the browser) to give the course module instance
  * @param string $content optional the content of the upload (for non-file uploads)
  */
 public function process($displayname = null, $content = null)
 {
     require_capability('moodle/course:manageactivities', $this->context);
     if ($this->is_file_upload()) {
         require_capability('moodle/course:managefiles', $this->context);
         if ($content != null) {
             throw new moodle_exception('fileuploadwithcontent', 'moodle');
         }
     } else {
         if (empty($content)) {
             throw new moodle_exception('dnduploadwithoutcontent', 'moodle');
         }
     }
     require_sesskey();
     $this->displayname = $displayname;
     if ($this->is_file_upload()) {
         $this->handle_file_upload();
     } else {
         $this->handle_other_upload($content);
     }
 }
Beispiel #22
0
 /**
  * Loop through uploaded grades and update the grades for this assignment
  *
  * @param int $draftid - The unique draft item id for this import
  * @param int $importid - The unique import ID for this csv import operation
  * @param bool $ignoremodified - Ignore the last modified date when checking fields
  * @return string - The html response
  */
 public function process_import_grades($draftid, $importid, $ignoremodified)
 {
     global $USER, $DB;
     require_sesskey();
     require_capability('mod/assign:grade', $this->assignment->get_context());
     $gradeimporter = new assignfeedback_offline_grade_importer($importid, $this->assignment);
     $context = context_user::instance($USER->id);
     $fs = get_file_storage();
     if (!($files = $fs->get_area_files($context->id, 'user', 'draft', $draftid, 'id DESC', false))) {
         redirect(new moodle_url('view.php', array('id' => $this->assignment->get_course_module()->id, 'action' => 'grading')));
         return;
     }
     $file = reset($files);
     $csvdata = $file->get_content();
     if ($csvdata) {
         $gradeimporter->parsecsv($csvdata);
     }
     if (!$gradeimporter->init()) {
         $thisurl = new moodle_url('/mod/assign/view.php', array('action' => 'viewpluginpage', 'pluginsubtype' => 'assignfeedback', 'plugin' => 'offline', 'pluginaction' => 'uploadgrades', 'id' => $assignment->get_course_module()->id));
         print_error('invalidgradeimport', 'assignfeedback_offline', $thisurl);
         return;
     }
     // Does this assignment use a scale?
     $scaleoptions = null;
     if ($this->assignment->get_instance()->grade < 0) {
         if ($scale = $DB->get_record('scale', array('id' => -$this->assignment->get_instance()->grade))) {
             $scaleoptions = make_menu_from_list($scale->scale);
         }
     }
     // We may need to upgrade the gradebook comments after this update.
     $adminconfig = $this->assignment->get_admin_config();
     $gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
     $updatecount = 0;
     while ($record = $gradeimporter->next()) {
         $user = $record->user;
         $modified = $record->modified;
         $userdesc = fullname($user);
         $usergrade = $this->assignment->get_user_grade($user->id, false);
         if (!empty($scaleoptions)) {
             // This is a scale - we need to convert any grades to indexes in the scale.
             $scaleindex = array_search($record->grade, $scaleoptions);
             if ($scaleindex !== false) {
                 $record->grade = $scaleindex;
             } else {
                 $record->grade = '';
             }
         } else {
             $record->grade = unformat_float($record->grade);
         }
         // Note: Do not count the seconds when comparing modified dates.
         $skip = false;
         $stalemodificationdate = $usergrade && $usergrade->timemodified > $modified + 60;
         if ($usergrade && $usergrade->grade == $record->grade) {
             // Skip - grade not modified.
             $skip = true;
         } else {
             if (!isset($record->grade) || $record->grade === '' || $record->grade < 0) {
                 // Skip - grade has no value.
                 $skip = true;
             } else {
                 if (!$ignoremodified && $stalemodificationdate) {
                     // Skip - grade has been modified.
                     $skip = true;
                 } else {
                     if ($this->assignment->grading_disabled($record->user->id)) {
                         // Skip grade is locked.
                         $skip = true;
                     } else {
                         if ($this->assignment->get_instance()->grade > -1 && ($record->grade < 0 || $record->grade > $this->assignment->get_instance()->grade)) {
                             // Out of range.
                             $skip = true;
                         }
                     }
                 }
             }
         }
         if (!$skip) {
             $grade = $this->assignment->get_user_grade($record->user->id, true);
             $grade->grade = $record->grade;
             $grade->grader = $USER->id;
             if ($this->assignment->update_grade($grade)) {
                 $this->assignment->notify_grade_modified($grade);
                 $updatecount += 1;
             }
         }
         if ($ignoremodified || !$stalemodificationdate) {
             foreach ($record->feedback as $feedback) {
                 $plugin = $feedback['plugin'];
                 $field = $feedback['field'];
                 $newvalue = $feedback['value'];
                 $description = $feedback['description'];
                 $oldvalue = '';
                 if ($usergrade) {
                     $oldvalue = $plugin->get_editor_text($field, $usergrade->id);
                     if (empty($oldvalue)) {
                         $oldvalue = '';
                     }
                 }
                 if ($newvalue != $oldvalue) {
                     $updatecount += 1;
                     $grade = $this->assignment->get_user_grade($record->user->id, true);
                     $this->assignment->notify_grade_modified($grade);
                     $plugin->set_editor_text($field, $newvalue, $grade->id);
                     // If this is the gradebook comments plugin - post an update to the gradebook.
                     if ($plugin->get_subtype() . '_' . $plugin->get_type() == $gradebookplugin) {
                         $grade->feedbacktext = $plugin->text_for_gradebook($grade);
                         $grade->feedbackformat = $plugin->format_for_gradebook($grade);
                         $this->assignment->update_grade($grade);
                     }
                 }
             }
         }
     }
     $gradeimporter->close(true);
     $renderer = $this->assignment->get_renderer();
     $o = '';
     $o .= $renderer->render(new assign_header($this->assignment->get_instance(), $this->assignment->get_context(), false, $this->assignment->get_course_module()->id, get_string('importgrades', 'assignfeedback_offline')));
     $o .= $renderer->box(get_string('updatedgrades', 'assignfeedback_offline', $updatecount));
     $url = new moodle_url('view.php', array('id' => $this->assignment->get_course_module()->id, 'action' => 'grading'));
     $o .= $renderer->continue_button($url);
     $o .= $renderer->render_footer();
     return $o;
 }
 public function check_answer()
 {
     global $CFG, $PAGE;
     $formattextdefoptions = new stdClass();
     $formattextdefoptions->noclean = true;
     $formattextdefoptions->para = false;
     $result = parent::check_answer();
     $mform = $this->make_answer_form();
     $data = $mform->get_data();
     require_sesskey();
     if (!$data) {
         redirect(new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id, 'pageid' => $this->properties->id)));
     }
     $response = $data->response;
     $getanswers = $this->get_answers();
     foreach ($getanswers as $key => $answer) {
         $getanswers[$key] = parent::rewrite_answers_urls($answer);
     }
     $correct = array_shift($getanswers);
     $wrong = array_shift($getanswers);
     $answers = array();
     foreach ($getanswers as $key => $answer) {
         if ($answer->answer !== '' or $answer->response !== '') {
             $answers[$answer->id] = $answer;
         }
     }
     // get the user's exact responses for record keeping
     $hits = 0;
     $userresponse = array();
     foreach ($response as $id => $value) {
         if ($value == '') {
             $result->noanswer = true;
             return $result;
         }
         $value = htmlspecialchars_decode($value);
         $userresponse[] = $value;
         // Make sure the user's answer exists in question's answer
         if (array_key_exists($id, $answers)) {
             $answer = $answers[$id];
             $result->studentanswer .= '<br />' . format_text($answer->answer, $answer->answerformat, $formattextdefoptions) . ' = ' . $value;
             if (trim($answer->response) == trim($value)) {
                 $hits++;
             }
         }
     }
     $result->userresponse = implode(",", $userresponse);
     if ($hits == count($answers)) {
         $result->correctanswer = true;
         $result->response = format_text($correct->answer, $correct->answerformat, $formattextdefoptions);
         $result->answerid = $correct->id;
         $result->newpageid = $correct->jumpto;
     } else {
         $result->correctanswer = false;
         $result->response = format_text($wrong->answer, $wrong->answerformat, $formattextdefoptions);
         $result->answerid = $wrong->id;
         $result->newpageid = $wrong->jumpto;
     }
     return $result;
 }
Beispiel #24
0
 /**
  * Displays the report.
  */
 function display($quiz, $cm, $course)
 {
     global $CFG, $QTYPES;
     $viewoptions = array('mode' => 'grading', 'q' => $quiz->id);
     if ($questionid = optional_param('questionid', 0, PARAM_INT)) {
         $viewoptions += array('questionid' => $questionid);
     }
     // grade question specific parameters
     $gradeungraded = optional_param('gradeungraded', 0, PARAM_INT);
     if ($userid = optional_param('userid', 0, PARAM_INT)) {
         $viewoptions += array('userid' => $userid);
     }
     if ($attemptid = optional_param('attemptid', 0, PARAM_INT)) {
         $viewoptions += array('attemptid' => $attemptid);
     }
     if ($gradeall = optional_param('gradeall', 0, PARAM_INT)) {
         $viewoptions += array('gradeall' => $gradeall);
     }
     if ($gradeungraded = optional_param('gradeungraded', 0, PARAM_INT)) {
         $viewoptions += array('gradeungraded' => $gradeungraded);
     }
     if ($gradenextungraded = optional_param('gradenextungraded', 0, PARAM_INT)) {
         $viewoptions += array('gradenextungraded' => $gradenextungraded);
     }
     $this->cm = $cm;
     $this->print_header_and_tabs($cm, $course, $quiz, $reportmode = "grading");
     // Check permissions
     $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
     if (!has_capability('mod/quiz:grade', $this->context)) {
         notify(get_string('gradingnotallowed', 'quiz_grading'));
         return true;
     }
     $gradeableqs = quiz_report_load_questions($quiz);
     $questionsinuse = implode(',', array_keys($gradeableqs));
     foreach ($gradeableqs as $qid => $question) {
         if (!$QTYPES[$question->qtype]->is_question_manual_graded($question, $questionsinuse)) {
             unset($gradeableqs[$qid]);
         }
     }
     if (empty($gradeableqs)) {
         print_heading(get_string('noessayquestionsfound', 'quiz'));
         return true;
     } else {
         if (count($gradeableqs) == 1) {
             $questionid = array_shift(array_keys($gradeableqs));
         }
     }
     $currentgroup = groups_get_activity_group($this->cm, true);
     $this->users = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $currentgroup, '', false);
     $this->userids = implode(',', array_keys($this->users));
     if (!empty($questionid)) {
         if (!isset($gradeableqs[$questionid])) {
             error("Gradeable question with id {$questionid} not found");
         } else {
             $question =& $gradeableqs[$questionid];
         }
         $question->maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $question->id);
         // Some of the questions code is optimised to work with several questions
         // at once so it wants the question to be in an array. The array key
         // must be the question id.
         $key = $question->id;
         $questions[$key] =& $question;
         // We need to add additional questiontype specific information to
         // the question objects.
         if (!get_question_options($questions)) {
             error("Unable to load questiontype specific question information");
         }
         // This will have extended the question object so that it now holds
         // all the information about the questions that may be needed later.
     }
     add_to_log($course->id, "quiz", "manualgrading", "report.php?mode=grading&amp;q={$quiz->id}", "{$quiz->id}", "{$cm->id}");
     echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>';
     // for overlib
     if ($data = data_submitted()) {
         // post data submitted, process it
         require_sesskey();
         // now go through all of the responses and save them.
         $allok = true;
         foreach ($data->manualgrades as $uniqueid => $response) {
             // get our attempt
             $uniqueid = clean_param($uniqueid, PARAM_INT);
             if (!($attempt = get_record_sql("SELECT * FROM {$CFG->prefix}quiz_attempts " . "WHERE uniqueid = {$uniqueid} AND " . "userid IN ({$this->userids}) AND " . "quiz=" . $quiz->id))) {
                 error('No such attempt ID exists');
             }
             // Load the state for this attempt (The questions array was created earlier)
             $states = get_question_states($questions, $quiz, $attempt);
             // The $states array is indexed by question id but because we are dealing
             // with only one question there is only one entry in this array
             $state =& $states[$question->id];
             // the following will update the state and attempt
             $error = question_process_comment($question, $state, $attempt, $response['comment'], $response['grade']);
             if (is_string($error)) {
                 notify($error);
                 $allok = false;
             } else {
                 if ($state->changed) {
                     // If the state has changed save it and update the quiz grade
                     save_question_session($question, $state);
                     quiz_save_best_grade($quiz, $attempt->userid);
                 }
             }
         }
         if ($allok) {
             notify(get_string('changessaved', 'quiz'), 'notifysuccess');
         } else {
             notify(get_string('changessavedwitherrors', 'quiz'), 'notifysuccess');
         }
     }
     $this->viewurl = new moodle_url($CFG->wwwroot . '/mod/quiz/report.php', $viewoptions);
     /// find out current groups mode
     if ($groupmode = groups_get_activity_groupmode($this->cm)) {
         // Groups are being used
         groups_print_activity_menu($this->cm, $this->viewurl->out(false, array('userid' => 0, 'attemptid' => 0)));
     }
     echo '<div class="quizattemptcounts">' . quiz_num_attempt_summary($quiz, $cm, true, $currentgroup) . '</div>';
     if (empty($this->users)) {
         if ($currentgroup) {
             notify(get_string('nostudentsingroup'));
         } else {
             notify(get_string('nostudentsyet'));
         }
         return true;
     }
     $gradeablequestionids = implode(',', array_keys($gradeableqs));
     $qattempts = quiz_get_total_qas_graded_and_ungraded($quiz, $gradeablequestionids, $this->userids);
     if (empty($qattempts)) {
         notify(get_string('noattemptstoshow', 'quiz'));
         return true;
     }
     $qmenu = array();
     foreach ($gradeableqs as $qid => $questionformenu) {
         $a = new object();
         $a->number = $gradeableqs[$qid]->number;
         $a->name = $gradeableqs[$qid]->name;
         $a->gradedattempts = $qattempts[$qid]->gradedattempts;
         $a->totalattempts = $qattempts[$qid]->totalattempts;
         $a->openspan = '';
         $a->closespan = '';
         $qmenu[$qid] = get_string('questiontitle', 'quiz_grading', $a);
     }
     if (count($gradeableqs) != 1) {
         $qurl = fullclone($this->viewurl);
         $qurl->remove_params('questionid', 'attemptid', 'gradeall', 'gradeungraded', 'gradenextungraded');
         $menu = popup_form($qurl->out() . '&amp;questionid=', $qmenu, 'questionid', $questionid, 'choose', '', '', true);
         echo '<div class="mdl-align">' . $menu . '</div>';
     }
     if (!$questionid) {
         return true;
     }
     $a = new object();
     $a->number = $question->number;
     $a->name = $question->name;
     $a->gradedattempts = $qattempts[$question->id]->gradedattempts;
     $a->totalattempts = $qattempts[$question->id]->totalattempts;
     $a->openspan = '<span class="highlightgraded">';
     $a->closespan = '</span>';
     print_heading(get_string('questiontitle', 'quiz_grading', $a));
     // our 3 different views
     // the first one displays all of the manually graded questions in the quiz
     // with the number of ungraded attempts for each question
     // the second view displays the users who have answered the essay question
     // and all of their attempts at answering the question
     // the third prints the question with a comment
     // and grade form underneath it
     $ungraded = $qattempts[$questionid]->totalattempts - $qattempts[$questionid]->gradedattempts;
     if ($gradenextungraded || $gradeungraded || $gradeall || $userid || $attemptid) {
         $this->print_questions_and_form($quiz, $question, $userid, $attemptid, $gradeungraded, $gradenextungraded, $ungraded);
     } else {
         $this->view_question($quiz, $question, $qattempts[$questionid]->totalattempts, $ungraded);
     }
     return true;
 }
Beispiel #25
0
 public function check_answer()
 {
     global $CFG;
     $result = parent::check_answer();
     $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot . '/mod/lesson/continue.php', array('contents' => $this->get_contents()));
     $data = $mform->get_data();
     require_sesskey();
     $studentanswer = trim($data->answer);
     if ($studentanswer === '') {
         $result->noanswer = true;
         return $result;
     }
     $i = 0;
     $answers = $this->get_answers();
     foreach ($answers as $answer) {
         $answer = parent::rewrite_answers_urls($answer, false);
         $i++;
         // Applying PARAM_TEXT as it is applied to the answer submitted by the user.
         $expectedanswer = clean_param($answer->answer, PARAM_TEXT);
         $ismatch = false;
         $markit = false;
         $useregexp = $this->qoption;
         if ($useregexp) {
             //we are using 'normal analysis', which ignores case
             $ignorecase = '';
             if (substr($expectedanswer, -2) == '/i') {
                 $expectedanswer = substr($expectedanswer, 0, -2);
                 $ignorecase = 'i';
             }
         } else {
             $expectedanswer = str_replace('*', '#####', $expectedanswer);
             $expectedanswer = preg_quote($expectedanswer, '/');
             $expectedanswer = str_replace('#####', '.*', $expectedanswer);
         }
         // see if user typed in any of the correct answers
         if (!$this->lesson->custom && $this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) or $this->lesson->custom && $answer->score > 0) {
             if (!$useregexp) {
                 // we are using 'normal analysis', which ignores case
                 if (preg_match('/^' . $expectedanswer . '$/i', $studentanswer)) {
                     $ismatch = true;
                 }
             } else {
                 if (preg_match('/^' . $expectedanswer . '$/' . $ignorecase, $studentanswer)) {
                     $ismatch = true;
                 }
             }
             if ($ismatch == true) {
                 $result->correctanswer = true;
             }
         } else {
             if (!$useregexp) {
                 //we are using 'normal analysis'
                 // see if user typed in any of the wrong answers; don't worry about case
                 if (preg_match('/^' . $expectedanswer . '$/i', $studentanswer)) {
                     $ismatch = true;
                 }
             } else {
                 // we are using regular expressions analysis
                 $startcode = substr($expectedanswer, 0, 2);
                 switch ($startcode) {
                     //1- check for absence of required string in $studentanswer (coded by initial '--')
                     case "--":
                         $expectedanswer = substr($expectedanswer, 2);
                         if (!preg_match('/^' . $expectedanswer . '$/' . $ignorecase, $studentanswer)) {
                             $ismatch = true;
                         }
                         break;
                         //2- check for code for marking wrong strings (coded by initial '++')
                     //2- check for code for marking wrong strings (coded by initial '++')
                     case "++":
                         $expectedanswer = substr($expectedanswer, 2);
                         $markit = true;
                         //check for one or several matches
                         if (preg_match_all('/' . $expectedanswer . '/' . $ignorecase, $studentanswer, $matches)) {
                             $ismatch = true;
                             $nb = count($matches[0]);
                             $original = array();
                             $marked = array();
                             $fontStart = '<span class="incorrect matches">';
                             $fontEnd = '</span>';
                             for ($i = 0; $i < $nb; $i++) {
                                 array_push($original, $matches[0][$i]);
                                 array_push($marked, $fontStart . $matches[0][$i] . $fontEnd);
                             }
                             $studentanswer = str_replace($original, $marked, $studentanswer);
                         }
                         break;
                         //3- check for wrong answers belonging neither to -- nor to ++ categories
                     //3- check for wrong answers belonging neither to -- nor to ++ categories
                     default:
                         if (preg_match('/^' . $expectedanswer . '$/' . $ignorecase, $studentanswer, $matches)) {
                             $ismatch = true;
                         }
                         break;
                 }
                 $result->correctanswer = false;
             }
         }
         if ($ismatch) {
             $result->newpageid = $answer->jumpto;
             $options = new stdClass();
             $options->para = false;
             $result->response = format_text($answer->response, $answer->responseformat, $options);
             $result->answerid = $answer->id;
             break;
             // quit answer analysis immediately after a match has been found
         }
     }
     $result->userresponse = $studentanswer;
     //clean student answer as it goes to output.
     $result->studentanswer = s($studentanswer);
     return $result;
 }
 public function construction_override($pageid, lesson $lesson)
 {
     global $DB, $CFG, $PAGE;
     require_sesskey();
     // first get the preceeding page
     $timenow = time();
     // the new page is not the first page (end of branch always comes after an existing page)
     if (!($page = $DB->get_record("lesson_pages", array("id" => $pageid)))) {
         print_error('cannotfindpagerecord', 'lesson');
     }
     // chain back up to find the (nearest branch table)
     $btpage = clone $page;
     $btpageid = $btpage->id;
     while ($btpage->qtype != LESSON_PAGE_BRANCHTABLE && $btpage->prevpageid > 0) {
         $btpageid = $btpage->prevpageid;
         if (!($btpage = $DB->get_record("lesson_pages", array("id" => $btpageid)))) {
             print_error('cannotfindpagerecord', 'lesson');
         }
     }
     if ($btpage->qtype == LESSON_PAGE_BRANCHTABLE) {
         $newpage = new stdClass();
         $newpage->lessonid = $lesson->id;
         $newpage->prevpageid = $pageid;
         $newpage->nextpageid = $page->nextpageid;
         $newpage->qtype = $this->qtype;
         $newpage->timecreated = $timenow;
         $newpage->title = get_string("endofbranch", "lesson");
         $newpage->contents = get_string("endofbranch", "lesson");
         $newpageid = $DB->insert_record("lesson_pages", $newpage);
         // update the linked list...
         $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
         if ($page->nextpageid) {
             // the new page is not the last page
             $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
         }
         // ..and the single "answer"
         $newanswer = new stdClass();
         $newanswer->lessonid = $lesson->id;
         $newanswer->pageid = $newpageid;
         $newanswer->timecreated = $timenow;
         $newanswer->jumpto = $btpageid;
         $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
         $lesson->add_message(get_string('addedanendofbranch', 'lesson'), 'notifysuccess');
     } else {
         $lesson->add_message(get_string('nobranchtablefound', 'lesson'));
     }
     redirect($CFG->wwwroot . "/mod/lesson/edit.php?id=" . $PAGE->cm->id);
 }
Beispiel #27
0
 public function check_answer()
 {
     global $PAGE, $CFG;
     $result = parent::check_answer();
     $result->isessayquestion = true;
     $mform = new lesson_display_answer_form_essay($CFG->wwwroot . '/mod/lesson/continue.php', array('contents' => $this->get_contents()));
     $data = $mform->get_data();
     require_sesskey();
     if (!$data) {
         redirect(new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id, 'pageid' => $this->properties->id)));
     }
     if (is_array($data->answer)) {
         $studentanswer = $data->answer['text'];
         $studentanswerformat = $data->answer['format'];
     } else {
         $studentanswer = $data->answer;
         $studentanswerformat = FORMAT_MOODLE;
     }
     if (trim($studentanswer) === '') {
         $result->noanswer = true;
         return $result;
     }
     $answers = $this->get_answers();
     foreach ($answers as $answer) {
         $result->answerid = $answer->id;
         $result->newpageid = $answer->jumpto;
     }
     $userresponse = new stdClass();
     $userresponse->sent = 0;
     $userresponse->graded = 0;
     $userresponse->score = 0;
     $userresponse->answer = $studentanswer;
     $userresponse->answerformat = $studentanswerformat;
     $userresponse->response = "";
     $result->userresponse = serialize($userresponse);
     $result->studentanswerformat = $studentanswerformat;
     $result->studentanswer = $studentanswer;
     return $result;
 }
Beispiel #28
0
 public function check_answer()
 {
     global $DB, $CFG, $PAGE;
     $result = parent::check_answer();
     $formattextdefoptions = new stdClass();
     $formattextdefoptions->noclean = true;
     $formattextdefoptions->para = false;
     $answers = $this->get_used_answers();
     shuffle($answers);
     $action = $CFG->wwwroot . '/mod/lesson/continue.php';
     $params = array('answers' => $answers, 'lessonid' => $this->lesson->id, 'contents' => $this->get_contents());
     if ($this->properties->qoption) {
         $mform = new lesson_display_answer_form_multichoice_multianswer($action, $params);
     } else {
         $mform = new lesson_display_answer_form_multichoice_singleanswer($action, $params);
     }
     $data = $mform->get_data();
     require_sesskey();
     if (!$data) {
         redirect(new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id, 'pageid' => $this->properties->id)));
     }
     if ($this->properties->qoption) {
         // MULTIANSWER allowed, user's answer is an array
         if (empty($data->answer) || !is_array($data->answer)) {
             $result->noanswer = true;
             return $result;
         }
         $studentanswers = array();
         foreach ($data->answer as $key => $value) {
             $studentanswers[] = (int) $key;
         }
         // get what the user answered
         $result->userresponse = implode(",", $studentanswers);
         // get the answers in a set order, the id order
         $answers = $this->get_used_answers();
         $ncorrect = 0;
         $nhits = 0;
         $correctresponse = '';
         $wrongresponse = '';
         $correctanswerid = 0;
         $wronganswerid = 0;
         // store student's answers for displaying on feedback page
         $result->studentanswer = '';
         foreach ($answers as $answer) {
             foreach ($studentanswers as $answerid) {
                 if ($answerid == $answer->id) {
                     $result->studentanswer .= '<br />' . format_text($answer->answer, $answer->answerformat, $formattextdefoptions);
                 }
             }
         }
         $correctpageid = null;
         $wrongpageid = null;
         // this is for custom scores.  If score on answer is positive, it is correct
         if ($this->lesson->custom) {
             $ncorrect = 0;
             $nhits = 0;
             foreach ($answers as $answer) {
                 if ($answer->score > 0) {
                     $ncorrect++;
                     foreach ($studentanswers as $answerid) {
                         if ($answerid == $answer->id) {
                             $nhits++;
                         }
                     }
                     // save the first jumpto page id, may be needed!...
                     if (!isset($correctpageid)) {
                         // leave in its "raw" state - will converted into a proper page id later
                         $correctpageid = $answer->jumpto;
                     }
                     // save the answer id for scoring
                     if ($correctanswerid == 0) {
                         $correctanswerid = $answer->id;
                     }
                     // ...also save any response from the correct answers...
                     if (trim(strip_tags($answer->response))) {
                         $correctresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
                     }
                 } else {
                     // save the first jumpto page id, may be needed!...
                     if (!isset($wrongpageid)) {
                         // leave in its "raw" state - will converted into a proper page id later
                         $wrongpageid = $answer->jumpto;
                     }
                     // save the answer id for scoring
                     if ($wronganswerid == 0) {
                         $wronganswerid = $answer->id;
                     }
                     // ...and from the incorrect ones, don't know which to use at this stage
                     if (trim(strip_tags($answer->response))) {
                         $wrongresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
                     }
                 }
             }
         } else {
             foreach ($answers as $answer) {
                 if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
                     $ncorrect++;
                     foreach ($studentanswers as $answerid) {
                         if ($answerid == $answer->id) {
                             $nhits++;
                         }
                     }
                     // save the first jumpto page id, may be needed!...
                     if (!isset($correctpageid)) {
                         // leave in its "raw" state - will converted into a proper page id later
                         $correctpageid = $answer->jumpto;
                     }
                     // save the answer id for scoring
                     if ($correctanswerid == 0) {
                         $correctanswerid = $answer->id;
                     }
                     // ...also save any response from the correct answers...
                     if (trim(strip_tags($answer->response))) {
                         $correctresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
                     }
                 } else {
                     // save the first jumpto page id, may be needed!...
                     if (!isset($wrongpageid)) {
                         // leave in its "raw" state - will converted into a proper page id later
                         $wrongpageid = $answer->jumpto;
                     }
                     // save the answer id for scoring
                     if ($wronganswerid == 0) {
                         $wronganswerid = $answer->id;
                     }
                     // ...and from the incorrect ones, don't know which to use at this stage
                     if (trim(strip_tags($answer->response))) {
                         $wrongresponse = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
                     }
                 }
             }
         }
         if (count($studentanswers) == $ncorrect and $nhits == $ncorrect) {
             $result->correctanswer = true;
             $result->response = $correctresponse;
             $result->newpageid = $correctpageid;
             $result->answerid = $correctanswerid;
         } else {
             $result->response = $wrongresponse;
             $result->newpageid = $wrongpageid;
             $result->answerid = $wronganswerid;
         }
     } else {
         // only one answer allowed
         if (empty($data->answerid) && !is_int($data->answerid)) {
             $result->noanswer = true;
             return $result;
         }
         $result->answerid = $data->answerid;
         if (!($answer = $DB->get_record("lesson_answers", array("id" => $result->answerid)))) {
             print_error("Continue: answer record not found");
         }
         if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
             $result->correctanswer = true;
         }
         if ($this->lesson->custom) {
             if ($answer->score > 0) {
                 $result->correctanswer = true;
             } else {
                 $result->correctanswer = false;
             }
         }
         $result->newpageid = $answer->jumpto;
         $result->response = format_text($answer->response, $answer->responseformat, $formattextdefoptions);
         $result->userresponse = format_text($answer->answer, $answer->answerformat, $formattextdefoptions);
         $result->studentanswer = $result->userresponse;
     }
     return $result;
 }
Beispiel #29
0
}
$edit = ($editable and $edit);
$seenaspublished = false;
// is the submission seen as a published submission?
if ($submission->id and ($ownsubmission or $canviewall or $isreviewer)) {
    // ok you can go
} elseif ($submission->id and $ispublished) {
    // ok you can go
    $seenaspublished = true;
} elseif (is_null($submission->id) and $cansubmit) {
    // ok you can go
} else {
    print_error('nopermissions', 'error', $workshop->view_url(), 'view or create submission');
}
if ($assess and $submission->id and !$isreviewer and $canallocate and $workshop->assessing_allowed($USER->id)) {
    require_sesskey();
    $assessmentid = $workshop->add_allocation($submission, $USER->id);
    redirect($workshop->assess_url($assessmentid));
}
if ($edit) {
    require_once dirname(__FILE__) . '/submission_form.php';
    $maxfiles = $workshop->nattachments;
    $maxbytes = $workshop->maxbytes;
    $contentopts = array('trusttext' => true, 'subdirs' => false, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes, 'context' => $workshop->context, 'return_types' => FILE_INTERNAL | FILE_EXTERNAL);
    $attachmentopts = array('subdirs' => true, 'maxfiles' => $maxfiles, 'maxbytes' => $maxbytes, 'return_types' => FILE_INTERNAL);
    $submission = file_prepare_standard_editor($submission, 'content', $contentopts, $workshop->context, 'mod_workshop', 'submission_content', $submission->id);
    $submission = file_prepare_standard_filemanager($submission, 'attachment', $attachmentopts, $workshop->context, 'mod_workshop', 'submission_attachment', $submission->id);
    $mform = new workshop_submission_form($PAGE->url, array('current' => $submission, 'workshop' => $workshop, 'contentopts' => $contentopts, 'attachmentopts' => $attachmentopts));
    if ($mform->is_cancelled()) {
        redirect($workshop->view_url());
    } elseif ($cansubmit and $formdata = $mform->get_data()) {
Beispiel #30
0
 /**
  * Delete the step.
  *
  * @param   int         $stepid     The ID of the step to remove.
  */
 protected function delete_step($stepid)
 {
     require_sesskey();
     $step = step::instance($stepid);
     $tour = $step->get_tour();
     $step->remove();
     redirect($tour->get_view_link());
 }