function setUp() { global $db, $CFG; $this->real_db = fullclone($db); $db = new MockADODB_mysql(); $this->rs = new MockADORecordSet_mysql(); $this->rs->EOF = false; $this->firstcolumn = new stdClass(); $this->firstcolumn->name = 'id'; // Override dataroot: we don't want to test with live data $this->real_dataroot = fullclone($CFG->dataroot); $CFG->dataroot .= '/unittests'; $this->userbasedir = $CFG->dataroot . '/user'; // Create some sample files in this temporary directory mkdir($CFG->dataroot); mkdir($this->userbasedir); $this->testfiles = array('0/1', '0/3', '1000/1043', '457498000/457498167'); foreach ($this->testfiles as $file) { $parts = explode('/', $file); if (!file_exists("{$this->userbasedir}/{$parts[0]}")) { mkdir("{$this->userbasedir}/{$parts[0]}"); } mkdir("{$this->userbasedir}/{$file}"); $handle = fopen("{$this->userbasedir}/{$file}/f1.gif", 'w+b'); fclose($handle); } }
/** * Form definition */ public function definition() { $data = fullclone($this->_customdata); if (isset($data->id)) { $data->tc = $data->id; $data->action = 'colledit'; } else { $data = new stdClass(); $data->action = 'colladd'; $data->isdefault = false; } $mform = $this->_form; $mform->addElement('hidden', 'tc'); $mform->setType('tc', PARAM_INT); $mform->addElement('hidden', 'action'); $mform->setType('action', PARAM_ALPHA); $mform->addElement('text', 'name', get_string('name')); $mform->setType('name', PARAM_NOTAGS); $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client'); if (empty($data->isdefault)) { $mform->addRule('name', get_string('required'), 'required', null, 'client'); } else { $mform->addElement('static', 'collnameexplained', '', get_string('collnameexplained', 'tag', get_string('defautltagcoll', 'tag'))); } $mform->addElement('advcheckbox', 'searchable', get_string('searchable', 'tag')); $mform->addHelpButton('searchable', 'searchable', 'tag'); $mform->setDefault('searchable', 1); if (!empty($data->isdefault)) { $mform->freeze('searchable'); } $this->add_action_buttons(); $this->set_data($data); }
function mediaplugin_filter($courseid, $text) { global $CFG; include 'defaultsettings.php'; // You should never modify parameters passed to a method or function, it's BAD practice. Create a copy instead. // The reason is that you must always be able to refer to the original parameter that was passed. // For this reason, I changed $text = preg_replace(..,..,$text) into $newtext = preg.... (NICOLAS CONNAULT) // Thanks to Pablo Etcheverry for pointing this out! MDL-10177 // We're using the UFO technique for flash to attain XHTML Strict 1.0 // See: http://www.bobbyvandersluis.com/ufo/ $newtext = fullclone($text); if ($CFG->filter_mediaplugin_enable_mp3) { $search = '/<a.*?href="([^<]+\\.mp3)"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_mp3_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_swf) { $search = '/<a.*?href="([^<]+\\.swf)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_swf_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_flv) { $search = '/<a.*?href="([^<]+\\.flv)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_flv_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_mov) { $search = '/<a.*?href="([^<]+\\.mov)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_wmv) { $search = '/<a.*?href="([^<]+\\.wmv)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_mpg) { $search = '/<a.*?href="([^<]+\\.mpe?g)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_qt_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_avi) { $search = '/<a.*?href="([^<]+\\.avi)(\\?d=([\\d]{1,3}%?)x([\\d]{1,3}%?))?"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_wmp_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_ram) { $search = '/<a.*?href="([^<]+\\.ram)"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_rpm) { $search = '/<a.*?href="([^<]+\\.rpm)"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); } if ($CFG->filter_mediaplugin_enable_rm) { $search = '/<a.*?href="([^<]+\\.rm)"[^>]*>.*?<\\/a>/is'; $newtext = preg_replace_callback($search, 'mediaplugin_filter_real_callback', $newtext); } if (is_null($newtext)) { $newtext = $text; } return $newtext; }
function filter($text, array $options = array()) { if (!($courseid = get_courseid_from_context($this->context))) { return $text; } // Initialise/invalidate our trivial cache if dealing with a different course if (!isset(self::$cachedcourseid) || self::$cachedcourseid !== (int) $courseid) { self::$activitylist = null; } self::$cachedcourseid = (int) $courseid; /// It may be cached if (is_null(self::$activitylist)) { self::$activitylist = array(); $modinfo = get_fast_modinfo($courseid); if (!empty($modinfo->cms)) { self::$activitylist = array(); /// We will store all the activities here //Sort modinfo by name length $sortedactivities = fullclone($modinfo->cms); usort($sortedactivities, 'filter_activitynames_comparemodulenamesbylength'); foreach ($sortedactivities as $cm) { //Exclude labels, hidden activities and activities for group members only if ($cm->visible and empty($cm->groupmembersonly) and $cm->has_view()) { $title = s(trim(strip_tags($cm->name))); $currentname = trim($cm->name); $entitisedname = s($currentname); /// Avoid empty or unlinkable activity names if (!empty($title)) { $href_tag_begin = html_writer::start_tag('a', array('class' => 'autolink', 'title' => $title, 'href' => $cm->get_url())); self::$activitylist[$cm->id] = new filterobject($currentname, $href_tag_begin, '</a>', false, true); if ($currentname != $entitisedname) { /// If name has some entity (& " < >) add that filter too. MDL-17545 self::$activitylist[$cm->id . '-e'] = new filterobject($entitisedname, $href_tag_begin, '</a>', false, true); } } } } } } $filterslist = array(); if (self::$activitylist) { $cmid = $this->context->instanceid; if ($this->context->contextlevel == CONTEXT_MODULE && isset(self::$activitylist[$cmid])) { // remove filterobjects for the current module $filterslist = array_diff_key(self::$activitylist, array($cmid => 1, $cmid . '-e' => 1)); } else { $filterslist = self::$activitylist; } } if ($filterslist) { return $text = filter_phrases($text, $filterslist); } else { return $text; } }
/** * Prints/return reader selector * * @param report_log_renderable $reportlog log report. */ public function reader_selector(report_log_renderable $reportlog) { $readers = $reportlog->get_readers(true); if (empty($readers)) { $readers = array(get_string('nologreaderenabled', 'report_log')); } $url = fullclone ($reportlog->url); $url->remove_params(array('logreader')); $select = new single_select($url, 'logreader', $readers, $reportlog->selectedlogreader, null); $select->set_label(get_string('selectlogreader', 'report_log')); echo $this->output->render($select); }
unset($itemdata->locked); unset($itemdata->locktime); $convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef', 'aggregationcoef2'); foreach ($convert as $param) { if (property_exists($itemdata, $param)) { $itemdata->{$param} = unformat_float($itemdata->{$param}); } } if (isset($itemdata->aggregationcoef2)) { $itemdata->aggregationcoef2 = $itemdata->aggregationcoef2 / 100.0; } // When creating a new category, a number of grade item fields are filled out automatically, and are required. // If the user leaves these fields empty during creation of a category, we let the default values take effect // Otherwise, we let the user-entered grade item values take effect $grade_item = $grade_category->load_grade_item(); $grade_item_copy = fullclone($grade_item); grade_item::set_properties($grade_item, $itemdata); if (empty($grade_item->id)) { $grade_item->id = $grade_item_copy->id; } if (empty($grade_item->grademax) && $grade_item->grademax != '0') { $grade_item->grademax = $grade_item_copy->grademax; } if (empty($grade_item->grademin) && $grade_item->grademin != '0') { $grade_item->grademin = $grade_item_copy->grademin; } if (empty($grade_item->gradepass) && $grade_item->gradepass != '0') { $grade_item->gradepass = $grade_item_copy->gradepass; } if (empty($grade_item->aggregationcoef) && $grade_item->aggregationcoef != '0') { $grade_item->aggregationcoef = $grade_item_copy->aggregationcoef;
public function multichoice_comment_on_datasetitems($questionid, $questiontext, $answers, $data, $number) { global $DB; $comment = new stdClass(); $comment->stranswers = array(); $comment->outsidelimit = false; $comment->answers = array(); // Find a default unit: if (!empty($questionid) && $unit = $DB->get_record('question_numerical_units', array('question' => $questionid, 'multiplier' => 1.0))) { $unit = $unit->unit; } else { $unit = ''; } $answers = fullclone($answers); $errors = ''; $delimiter = ': '; foreach ($answers as $key => $answer) { $answer->answer = $this->substitute_variables($answer->answer, $data); //evaluate the equations i.e {=5+4) $qtext = ''; $qtextremaining = $answer->answer; while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) { $qtextsplits = explode($regs1[0], $qtextremaining, 2); $qtext = $qtext.$qtextsplits[0]; $qtextremaining = $qtextsplits[1]; if (empty($regs1[1])) { $str = ''; } else { if ($formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) { $str = $formulaerrors; } else { eval('$str = '.$regs1[1].';'); $texteval= qtype_calculated_calculate_answer( $str, $data, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, $answer->correctanswerformat, ''); $str = $texteval->answer; } } $qtext = $qtext.$str; } $answer->answer = $qtext.$qtextremaining;; $comment->stranswers[$key]= $answer->answer; } return fullclone($comment); }
function definition() { $mform =& $this->_form; $strquestionlabel = $this->qtypeobj->comment_header($this->question); if ($this->maxnumber != -1) { $this->noofitems = $this->maxnumber; } else { $this->noofitems = 0; } //------------------------------------------------------------------------------------------------------------------------------ $mform->addElement('submit', 'updatedatasets', get_string('updatedatasetparam', 'qtype_datasetdependent')); $mform->registerNoSubmitButton('updatedatasets'); $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_datasetdependent')); $idx = 1; $j = $this->noofitems * count($this->datasetdefs) + 1; foreach ($this->datasetdefs as $defkey => $datasetdef) { $mform->addElement('text', "number[{$j}]", get_string('param', 'qtype_datasetdependent', $datasetdef->name)); $mform->setType("number[{$j}]", PARAM_NUMBER); $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j); $idx++; $mform->addElement('hidden', "definition[{$j}]"); $mform->addElement('hidden', "itemid[{$j}]"); $mform->addElement('static', "divider[{$j}]", '', '<hr />'); $j++; } $mform->addElement('header', 'updateanswershdr', get_string('answerstoleranceparam', 'qtype_datasetdependent')); $mform->addElement('submit', 'updateanswers', get_string('updatetolerancesparam', 'qtype_datasetdependent')); $mform->setAdvanced('updateanswers', true); $mform->registerNoSubmitButton('updateanswers'); $answers = fullclone($this->question->options->answers); $key1 = 1; foreach ($answers as $key => $answer) { if ('' === $answer->answer) { } else { if ('*' === $answer->answer) { $mform->addElement('static', 'answercomment[' . ($this->noofitems + $key1) . ']', $answer->answer); $mform->addElement('hidden', 'tolerance[' . $key . ']', ''); $mform->setAdvanced('tolerance[' . $key . ']', true); $mform->addElement('hidden', 'tolerancetype[' . $key . ']', ''); $mform->setAdvanced('tolerancetype[' . $key . ']', true); $mform->addElement('hidden', 'correctanswerlength[' . $key . ']', ''); $mform->setAdvanced('correctanswerlength[' . $key . ']', true); $mform->addElement('hidden', 'correctanswerformat[' . $key . ']', ''); $mform->setAdvanced('correctanswerformat[' . $key . ']', true); } else { $mform->addElement('static', 'answercomment[' . ($this->noofitems + $key1) . ']', $answer->answer); $mform->addElement('text', 'tolerance[' . $key . ']', get_string('tolerance', 'qtype_calculated')); $mform->setAdvanced('tolerance[' . $key . ']', true); $mform->addElement('select', 'tolerancetype[' . $key . ']', get_string('tolerancetype', 'quiz'), $this->qtypeobj->tolerance_types()); $mform->setAdvanced('tolerancetype[' . $key . ']', true); $mform->addElement('select', 'correctanswerlength[' . $key . ']', get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); $mform->setAdvanced('correctanswerlength[' . $key . ']', true); $answerlengthformats = array('1' => get_string('decimalformat', 'quiz'), '2' => get_string('significantfiguresformat', 'quiz')); $mform->addElement('select', 'correctanswerformat[' . $key . ']', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats); $mform->setAdvanced('correctanswerformat[' . $key . ']', true); $mform->addElement('static', 'dividertolerance', '', '<hr />'); $mform->setAdvanced('dividertolerance', true); } } $key1++; } $addremoveoptions = array(); $addremoveoptions['1'] = '1'; for ($i = 10; $i <= 100; $i += 10) { $addremoveoptions["{$i}"] = "{$i}"; } $mform->addElement('header', 'additemhdr', get_string('add', 'moodle')); $mform->closeHeaderBefore('additemhdr'); if ($this->qtypeobj->supports_dataset_item_generation()) { $radiogrp = array(); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('reuseifpossible', 'qtype_datasetdependent'), 0); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregeneration', 'qtype_datasetdependent'), 1); $mform->addGroup($radiogrp, 'forceregenerationgrp', get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false); } $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_datasetdependent')); $mform->addElement('static', "dividera", '', '<hr />'); $addgrp = array(); $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle')); $addgrp[] =& $mform->createElement('select', "selectadd", get_string('additem', 'qtype_datasetdependent'), $addremoveoptions); $addgrp[] =& $mform->createElement('static', "stat", "Items", get_string('item(s)', 'qtype_datasetdependent')); $mform->addGroup($addgrp, 'addgrp', '', ' ', false); $mform->addElement('static', "divideradd", '', ''); // $mform->closeHeaderBefore('divideradd'); if ($this->noofitems > 0) { $mform->addElement('header', 'additemhdr', get_string('delete', 'moodle')); $deletegrp = array(); $deletegrp[] =& $mform->createElement('submit', 'deletebutton', get_string('delete', 'moodle')); $deletegrp[] =& $mform->createElement('select', "selectdelete", get_string('deleteitem', 'qtype_datasetdependent') . "1", $addremoveoptions); $deletegrp[] =& $mform->createElement('static', "stat", "Items", get_string('lastitem(s)', 'qtype_datasetdependent')); $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false); // $mform->addElement('static', "dividerdelete", '', '<hr />'); // $mform->closeHeaderBefore('dividerdelete'); } else { $mform->addElement('static', 'warning', '', '<span class="error">' . get_string('youmustaddatleastoneitem', 'qtype_datasetdependent') . '</span>'); } //------------------------------------------------------------------------------------------------------------------------------ $j = $this->noofitems * count($this->datasetdefs); for ($i = $this->noofitems; $i >= 1; $i--) { $mform->addElement('header', '', get_string('itemno', 'qtype_datasetdependent', $i)); foreach ($this->datasetdefs as $defkey => $datasetdef) { $mform->addElement('text', "number[{$j}]", get_string('param', 'qtype_datasetdependent', $datasetdef->name)); $mform->setType("number[{$j}]", PARAM_NUMBER); $mform->addElement('hidden', "itemid[{$j}]"); $mform->setType("itemid[{$j}]", PARAM_INT); $mform->addElement('hidden', "definition[{$j}]"); $mform->setType("definition[{$j}]", PARAM_NOTAGS); $j--; } if ('' != $strquestionlabel) { $repeated[] =& $mform->addElement('static', "answercomment[{$i}]", $strquestionlabel); } } // if ($this->outsidelimit){ $mform->addElement('static', 'outsidelimit', '', ''); // } //------------------------------------------------------------------------------------------------------------------------------ //non standard name for button element needed so not using add_action_buttons if (!($this->noofitems == 0)) { $mform->addElement('submit', 'backtoquiz', get_string('savechanges')); $mform->closeHeaderBefore('backtoquiz'); } //hidden elements $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'courseid'); $mform->setType('courseid', PARAM_INT); $mform->setDefault('courseid', 0); $mform->addElement('hidden', 'category'); $mform->setType('category', PARAM_RAW); $mform->setDefault('category', array('contexts' => array($this->categorycontext))); $mform->addElement('hidden', 'cmid'); $mform->setType('cmid', PARAM_INT); $mform->setDefault('cmid', 0); $mform->addElement('hidden', 'wizard', 'datasetitems'); $mform->setType('wizard', PARAM_ALPHA); $mform->addElement('hidden', 'returnurl'); $mform->setType('returnurl', PARAM_LOCALURL); $mform->setDefault('returnurl', 0); }
/** * This function just makes sure a user is logged out. * * @package core_access * @category access */ function require_logout() { global $USER, $DB; if (!isloggedin()) { // This should not happen often, no need for hooks or events here. \core\session\manager::terminate_current(); return; } // Execute hooks before action. $authplugins = array(); $authsequence = get_enabled_auth_plugins(); foreach ($authsequence as $authname) { $authplugins[$authname] = get_auth_plugin($authname); $authplugins[$authname]->prelogout_hook(); } // Store info that gets removed during logout. $sid = session_id(); $event = \core\event\user_loggedout::create(array('userid' => $USER->id, 'objectid' => $USER->id, 'other' => array('sessionid' => $sid))); if ($session = $DB->get_record('sessions', array('sid' => $sid))) { $event->add_record_snapshot('sessions', $session); } // Clone of $USER object to be used by auth plugins. $user = fullclone($USER); // Delete session record and drop $_SESSION content. \core\session\manager::terminate_current(); // Trigger event AFTER action. $event->trigger(); // Hook to execute auth plugins redirection after event trigger. foreach ($authplugins as $authplugin) { $authplugin->postlogout_hook($user); } }
/** * Will create the moodle course from the template * course_ext is an array as obtained from ldap -- flattened somewhat * * @param array $course_ext * @param progress_trace $trace * @return mixed false on error, id for the newly created course otherwise. */ function create_course($course_ext, progress_trace $trace) { global $CFG, $DB; require_once "{$CFG->dirroot}/course/lib.php"; // Override defaults with template course $template = false; if ($this->get_config('template')) { if ($template = $DB->get_record('course', array('shortname' => $this->get_config('template')))) { $template = fullclone(course_get_format($template)->get_course()); unset($template->id); // So we are clear to reinsert the record unset($template->fullname); unset($template->shortname); unset($template->idnumber); } } if (!$template) { $courseconfig = get_config('moodlecourse'); $template = new stdClass(); $template->summary = ''; $template->summaryformat = FORMAT_HTML; $template->format = $courseconfig->format; $template->newsitems = $courseconfig->newsitems; $template->showgrades = $courseconfig->showgrades; $template->showreports = $courseconfig->showreports; $template->maxbytes = $courseconfig->maxbytes; $template->groupmode = $courseconfig->groupmode; $template->groupmodeforce = $courseconfig->groupmodeforce; $template->visible = $courseconfig->visible; $template->lang = $courseconfig->lang; $template->enablecompletion = $courseconfig->enablecompletion; } $course = $template; $course->category = $this->get_config('category'); if (!$DB->record_exists('course_categories', array('id' => $this->get_config('category')))) { $categories = $DB->get_records('course_categories', array(), 'sortorder', 'id', 0, 1); $first = reset($categories); $course->category = $first->id; } // Override with required ext data $course->idnumber = $course_ext[$this->get_config('course_idnumber')][0]; $course->fullname = $course_ext[$this->get_config('course_fullname')][0]; $course->shortname = $course_ext[$this->get_config('course_shortname')][0]; if (empty($course->idnumber) || empty($course->fullname) || empty($course->shortname)) { // We are in trouble! $trace->output(get_string('cannotcreatecourse', 'enrol_ldap') . ' ' . var_export($course, true)); return false; } $summary = $this->get_config('course_summary'); if (!isset($summary) || empty($course_ext[$summary][0])) { $course->summary = ''; } else { $course->summary = $course_ext[$this->get_config('course_summary')][0]; } // Check if the shortname already exists if it does - skip course creation. if ($DB->record_exists('course', array('shortname' => $course->shortname))) { $trace->output(get_string('duplicateshortname', 'enrol_ldap', $course)); return false; } $newcourse = create_course($course); return $newcourse->id; }
public function generate_courses() { global $DB; $this->verbose("Generating " . $this->get('number_of_courses') . " courses..."); $base_course = new stdClass(); $next_course_id = $DB->get_field_sql("SELECT MAX(id) FROM {course}") + 1; $base_course->MAX_FILE_SIZE = '2097152'; $base_course->category = '1'; $base_course->summary = 'Blah Blah'; $base_course->format = 'weeks'; $base_course->numsections = '10'; $base_course->startdate = mktime(); $base_course->id = '0'; $courses_count = 0; $courses = array(); for ($i = 1; $i <= $this->get('number_of_courses'); $i++) { $newcourse = fullclone($base_course); $newcourse->fullname = "Test course {$next_course_id}"; $newcourse->shortname = "Test {$next_course_id}"; $newcourse->idnumber = $next_course_id; if (!($course = create_course($newcourse))) { $this->verbose("Error inserting a new course in the database!"); if (!$this->get('ignore_errors')) { die; } } else { $courses_count++; $next_course_id++; $courses[] = $course->id; $next_course_id = $course->id + 1; $this->verbose("Inserted {$course->fullname} into DB (idnumber={$course->idnumber})."); } } if (!$this->get('quiet')) { echo "{$courses_count} test courses correctly inserted into the database.{$this->eolchar}"; } return $courses; }
function validation($data, $files) { $errors = parent::validation($data, $files); if (isset($this->questiondisplay->options->questions)) { $subquestions = fullclone($this->questiondisplay->options->questions); if (count($subquestions)) { $sub = 1; foreach ($subquestions as $subquestion) { $prefix = 'sub_' . $sub . '_'; $answercount = 0; $maxgrade = false; $maxfraction = -1; foreach ($subquestion->answer as $key => $answer) { $trimmedanswer = trim($answer); if ($trimmedanswer !== '') { $answercount++; if ($subquestion->qtype == 'numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) { $errors[$prefix . 'answer[' . $key . ']'] = get_string('answermustbenumberorstar', 'qtype_numerical'); } if ($subquestion->fraction[$key] == 1) { $maxgrade = true; } if ($subquestion->fraction[$key] > $maxfraction) { $maxfraction = $subquestion->fraction[$key]; } } } if ($answercount == 0) { if ($subquestion->qtype == 'multichoice') { $errors[$prefix . 'answer[0]'] = get_string('notenoughanswers', 'qtype_multichoice', 2); } else { $errors[$prefix . 'answer[0]'] = get_string('notenoughanswers', 'quiz', 1); } } if ($maxgrade == false) { $errors[$prefix . 'fraction[0]'] = get_string('fractionsnomax', 'question'); } $sub++; } } else { $errors['questiontext'] = get_string('questionsmissing', 'qtype_multianswer'); } } return $errors; }
protected function definition() { global $PAGE; $labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated"); $mform = $this->_form; $mform->setDisableShortforms(); $strquestionlabel = $this->qtypeobj->comment_header($this->question); if ($this->maxnumber != -1) { $this->noofitems = $this->maxnumber; } else { $this->noofitems = 0; } $label = get_string("sharedwildcards", "qtype_calculated"); $html2 = $this->qtypeobj->print_dataset_definitions_category_shared($this->question, $this->datasetdefs); $mform->addElement('static', 'listcategory', $label, $html2); // ...----------------------------------------------------------------------. $mform->addElement('submit', 'updatedatasets', get_string('updatedatasetparam', 'qtype_calculated')); $mform->registerNoSubmitButton('updatedatasets'); $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_calculated')); $idx = 1; $data = array(); $j = $this->noofitems * count($this->datasetdefs) + 1; foreach ($this->datasetdefs as $defkey => $datasetdef) { if ($datasetdef->category |= 0) { $name = get_string('sharedwildcard', 'qtype_calculated', $datasetdef->name); } else { $name = get_string('wildcard', 'qtype_calculated', $datasetdef->name); } $mform->addElement('text', "number[{$j}]", $name); $mform->setType("number[{$j}]", PARAM_RAW); // This parameter will be validated in validation(). $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j); $idx++; $mform->addElement('hidden', "definition[{$j}]"); $mform->setType("definition[{$j}]", PARAM_RAW); $mform->addElement('hidden', "itemid[{$j}]"); $mform->setType("itemid[{$j}]", PARAM_RAW); $mform->addElement('static', "divider[{$j}]", '', '<hr />'); $mform->setType("divider[{$j}]", PARAM_RAW); $j++; } $mform->addElement('header', 'updateanswershdr', get_string('answerstoleranceparam', 'qtype_calculated')); $mform->addElement('submit', 'updateanswers', get_string('updatetolerancesparam', 'qtype_calculated')); $mform->setAdvanced('updateanswers', true); $mform->registerNoSubmitButton('updateanswers'); $answers = fullclone($this->question->options->answers); $key1 = 1; foreach ($answers as $key => $answer) { $ans = shorten_text($answer->answer, 17, true); if ($ans === '*') { $mform->addElement('static', 'answercomment[' . ($this->noofitems + $key1) . ']', $ans); $mform->addElement('hidden', 'tolerance[' . $key . ']', ''); $mform->setType('tolerance[' . $key . ']', PARAM_RAW); $mform->setAdvanced('tolerance[' . $key . ']', true); $mform->addElement('hidden', 'tolerancetype[' . $key . ']', ''); $mform->setType('tolerancetype[' . $key . ']', PARAM_RAW); $mform->setAdvanced('tolerancetype[' . $key . ']', true); $mform->addElement('hidden', 'correctanswerlength[' . $key . ']', ''); $mform->setType('correctanswerlength[' . $key . ']', PARAM_RAW); $mform->setAdvanced('correctanswerlength[' . $key . ']', true); $mform->addElement('hidden', 'correctanswerformat[' . $key . ']', ''); $mform->setType('correctanswerformat[' . $key . ']', PARAM_RAW); $mform->setAdvanced('correctanswerformat[' . $key . ']', true); } else { if ($ans !== '') { $mform->addElement('static', 'answercomment[' . ($this->noofitems + $key1) . ']', $ans); $mform->addElement('text', 'tolerance[' . $key . ']', get_string('tolerance', 'qtype_calculated')); $mform->setType('tolerance[' . $key . ']', PARAM_RAW); $mform->setAdvanced('tolerance[' . $key . ']', true); $mform->addElement('select', 'tolerancetype[' . $key . ']', get_string('tolerancetype', 'qtype_numerical'), $this->qtypeobj->tolerance_types()); $mform->setAdvanced('tolerancetype[' . $key . ']', true); $mform->addElement('select', 'correctanswerlength[' . $key . ']', get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); $mform->setAdvanced('correctanswerlength[' . $key . ']', true); $answerlengthformats = array('1' => get_string('decimalformat', 'qtype_numerical'), '2' => get_string('significantfiguresformat', 'qtype_calculated')); $mform->addElement('select', 'correctanswerformat[' . $key . ']', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats); $mform->setAdvanced('correctanswerformat[' . $key . ']', true); $mform->addElement('static', 'dividertolerance', '', '<hr />'); $mform->setAdvanced('dividertolerance', true); } } $key1++; } $addremoveoptions = array(); $addremoveoptions['1'] = '1'; for ($i = 10; $i <= 100; $i += 10) { $addremoveoptions["{$i}"] = "{$i}"; } $showoptions = array(); $showoptions['1'] = '1'; $showoptions['2'] = '2'; $showoptions['5'] = '5'; for ($i = 10; $i <= 100; $i += 10) { $showoptions["{$i}"] = "{$i}"; } $mform->addElement('header', 'addhdr', get_string('add', 'moodle')); $mform->closeHeaderBefore('addhdr'); if ($this->qtypeobj->supports_dataset_item_generation()) { $radiogrp = array(); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('reuseifpossible', 'qtype_calculated'), 0); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregenerationshared', 'qtype_calculated'), 1); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregenerationall', 'qtype_calculated'), 2); $mform->addGroup($radiogrp, 'forceregenerationgrp', get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false); } $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_calculated')); $mform->addElement('static', "dividera", '', '<hr />'); $addgrp = array(); $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle')); $addgrp[] =& $mform->createElement('select', "selectadd", get_string('additem', 'qtype_calculated'), $addremoveoptions); $addgrp[] =& $mform->createElement('static', "stat", "Items", get_string('newsetwildcardvalues', 'qtype_calculatedsimple')); $mform->addGroup($addgrp, 'addgrp', get_string('additem', 'qtype_calculated'), ' ', false); $mform->addElement('static', "divideradd", '', ''); if ($this->noofitems > 0) { $mform->addElement('header', 'deleteitemhdr', get_string('delete', 'moodle')); $deletegrp = array(); $deletegrp[] = $mform->createElement('submit', 'deletebutton', get_string('delete', 'moodle')); $deletegrp[] = $mform->createElement('select', 'selectdelete', get_string('deleteitem', 'qtype_calculated') . "1", $addremoveoptions); $deletegrp[] = $mform->createElement('static', "stat", "Items", get_string('setwildcardvalues', 'qtype_calculatedsimple')); $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false); } else { $mform->addElement('static', 'warning', '', '<span class="error">' . get_string('youmustaddatleastoneitem', 'qtype_calculated') . '</span>'); } $addgrp1 = array(); $addgrp1[] = $mform->createElement('submit', 'showbutton', get_string('showitems', 'qtype_calculated')); $addgrp1[] = $mform->createElement('select', "selectshow", '', $showoptions); $addgrp1[] = $mform->createElement('static', "stat", '', get_string('setwildcardvalues', 'qtype_calculated')); $mform->addGroup($addgrp1, 'addgrp1', '', ' ', false); $mform->registerNoSubmitButton('showbutton'); $mform->closeHeaderBefore('addgrp1'); // ...----------------------------------------------------------------------. $j = $this->noofitems * count($this->datasetdefs); $k = optional_param('selectshow', 1, PARAM_INT); for ($i = $this->noofitems; $i >= 1; $i--) { if ($k > 0) { $mform->addElement('header', 'setnoheader' . $i, "<b>" . get_string('setno', 'qtype_calculated', $i) . "</b> "); } foreach ($this->datasetdefs as $defkey => $datasetdef) { if ($k > 0) { if ($datasetdef->category == 0) { $mform->addElement('text', "number[{$j}]", get_string('wildcard', 'qtype_calculated', $datasetdef->name)); } else { $mform->addElement('text', "number[{$j}]", get_string('sharedwildcard', 'qtype_calculated', $datasetdef->name)); } } else { $mform->addElement('hidden', "number[{$j}]", ''); } $mform->setType("number[{$j}]", PARAM_RAW); // This parameter will be validated in validation(). $mform->addElement('hidden', "itemid[{$j}]"); $mform->setType("itemid[{$j}]", PARAM_INT); $mform->addElement('hidden', "definition[{$j}]"); $mform->setType("definition[{$j}]", PARAM_NOTAGS); $data[$datasetdef->name] = $datasetdef->items[$i]->value; $j--; } if ('' != $strquestionlabel && $k > 0) { // ... $this->outsidelimit || !empty($this->numbererrors ). $repeated[] = $mform->addElement('static', "answercomment[{$i}]", $strquestionlabel); // Decode equations in question text. $qtext = $this->qtypeobj->substitute_variables($this->question->questiontext, $data); $textequations = $this->qtypeobj->find_math_equations($qtext); if ($textequations != '' && count($textequations) > 0) { $mform->addElement('static', "divider1[{$j}]", '', 'Formulas {=..} in question text'); foreach ($textequations as $key => $equation) { if ($formulaerrors = qtype_calculated_find_formula_errors($equation)) { $str = $formulaerrors; } else { eval('$str = ' . $equation . ';'); } $equation = shorten_text($equation, 17, true); $mform->addElement('static', "textequation", "{={$equation}}", "=" . $str); } } } $k--; } $mform->addElement('static', 'outsidelimit', '', ''); // Submit buttons. if ($this->noofitems > 0) { $buttonarray = array(); $buttonarray[] = $mform->createElement('submit', 'savechanges', get_string('savechanges')); $previewlink = $PAGE->get_renderer('core_question')->question_preview_link($this->question->id, $this->categorycontext, true); $buttonarray[] = $mform->createElement('static', 'previewlink', '', $previewlink); $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); $mform->closeHeaderBefore('buttonar'); } $this->add_hidden_fields(); $mform->addElement('hidden', 'category'); $mform->setType('category', PARAM_SEQUENCE); $mform->addElement('hidden', 'wizard', 'datasetitems'); $mform->setType('wizard', PARAM_ALPHA); }
function comment_on_datasetitems($questionid, $answers, $data, $number) { global $DB; $comment = new stdClass(); $comment->stranswers = array(); $comment->outsidelimit = false; $comment->answers = array(); /// Find a default unit: if (!empty($questionid) && ($unit = $DB->get_record('question_numerical_units', array('question' => $questionid, 'multiplier' => 1.0)))) { $unit = $unit->unit; } else { $unit = ''; } $answers = fullclone($answers); $strmin = get_string('min', 'quiz'); $strmax = get_string('max', 'quiz'); $errors = ''; $delimiter = ': '; $virtualqtype = $this->get_virtual_qtype(); foreach ($answers as $key => $answer) { $formula = $this->substitute_variables($answer->answer, $data); $formattedanswer = qtype_calculated_calculate_answer($answer->answer, $data, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, $answer->correctanswerformat, $unit); if ($formula === '*') { $answer->min = ' '; $formattedanswer->answer = $answer->answer; } else { eval('$answer->answer = ' . $formula . ';'); $virtualqtype->get_tolerance_interval($answer); } if ($answer->min === '') { // This should mean that something is wrong $comment->stranswers[$key] = " {$formattedanswer->answer}" . '<br/><br/>'; } else { if ($formula === '*') { $comment->stranswers[$key] = $formula . ' = ' . get_string('anyvalue', 'qtype_calculated') . '<br/><br/><br/>'; } else { $comment->stranswers[$key] = $formula . ' = ' . $formattedanswer->answer . '<br/>'; $comment->stranswers[$key] .= $strmin . $delimiter . $answer->min . '---'; $comment->stranswers[$key] .= $strmax . $delimiter . $answer->max; $comment->stranswers[$key] .= '<br/>'; $correcttrue->correct = $formattedanswer->answer; $correcttrue->true = $answer->answer; if ($formattedanswer->answer < $answer->min || $formattedanswer->answer > $answer->max) { $comment->outsidelimit = true; $comment->answers[$key] = $key; $comment->stranswers[$key] .= get_string('trueansweroutsidelimits', 'qtype_calculated', $correcttrue); //<span class="error">ERROR True answer '..' outside limits</span>'; } else { $comment->stranswers[$key] .= get_string('trueanswerinsidelimits', 'qtype_calculated', $correcttrue); //' True answer :'.$calculated->trueanswer.' inside limits'; } $comment->stranswers[$key] .= ''; } } } return fullclone($comment); }
protected function definition() { $labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated"); $mform =& $this->_form; $strquestionlabel = $this->qtypeobj->comment_header($this->question); if ($this->maxnumber != -1 ) { $this->noofitems = $this->maxnumber; } else { $this->noofitems = 0; } $label = get_string("sharedwildcards", "qtype_calculated"); $html2 = $this->qtypeobj->print_dataset_definitions_category_shared( $this->question, $this->datasetdefs); $mform->addElement('static', 'listcategory', $label, $html2); //---------------------------------------------------------------------- $mform->addElement('submit', 'updatedatasets', get_string('updatedatasetparam', 'qtype_calculated')); $mform->registerNoSubmitButton('updatedatasets'); $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_calculated')); $idx = 1; $data = array(); $j = (($this->noofitems) * count($this->datasetdefs))+1; foreach ($this->datasetdefs as $defkey => $datasetdef) { if ($datasetdef->category |= 0 ) { $name = get_string('sharedwildcard', 'qtype_calculated', $datasetdef->name); } else { $name = get_string('wildcard', 'qtype_calculated', $datasetdef->name); } $mform->addElement('text', "number[$j]", $name); $mform->setType("number[$j]", PARAM_NUMBER); $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j); $idx++; $mform->addElement('hidden', "definition[$j]"); $mform->setType("definition[$j]", PARAM_RAW); $mform->addElement('hidden', "itemid[$j]"); $mform->setType("itemid[$j]", PARAM_RAW); $mform->addElement('static', "divider[$j]", '', '<hr />'); $mform->setType("divider[$j]", PARAM_RAW); $j++; } $mform->addElement('header', 'updateanswershdr', get_string('answerstoleranceparam', 'qtype_calculated')); $mform->addElement('submit', 'updateanswers', get_string('updatetolerancesparam', 'qtype_calculated')); $mform->setAdvanced('updateanswers', true); $mform->registerNoSubmitButton('updateanswers'); $answers = fullclone($this->question->options->answers); $key1 =1; foreach ($answers as $key => $answer) { if ('' === $answer->answer) { // Do nothing. } else if ('*' === $answer->answer) { $mform->addElement('static', 'answercomment[' . ($this->noofitems+$key1) . ']', $answer->answer); $mform->addElement('hidden', 'tolerance['.$key.']', ''); $mform->setType('tolerance['.$key.']', PARAM_RAW); $mform->setAdvanced('tolerance['.$key.']', true); $mform->addElement('hidden', 'tolerancetype['.$key.']', ''); $mform->setType('tolerancetype['.$key.']', PARAM_RAW); $mform->setAdvanced('tolerancetype['.$key.']', true); $mform->addElement('hidden', 'correctanswerlength['.$key.']', ''); $mform->setType('correctanswerlength['.$key.']', PARAM_RAW); $mform->setAdvanced('correctanswerlength['.$key.']', true); $mform->addElement('hidden', 'correctanswerformat['.$key.']', ''); $mform->setType('correctanswerformat['.$key.']', PARAM_RAW); $mform->setAdvanced('correctanswerformat['.$key.']', true); } else { $mform->addElement('static', 'answercomment[' . ($this->noofitems+$key1) . ']', $answer->answer); $mform->addElement('text', 'tolerance['.$key.']', get_string('tolerance', 'qtype_calculated')); $mform->setAdvanced('tolerance['.$key.']', true); $mform->addElement('select', 'tolerancetype['.$key.']', get_string('tolerancetype', 'qtype_numerical'), $this->qtypeobj->tolerance_types()); $mform->setAdvanced('tolerancetype['.$key.']', true); $mform->addElement('select', 'correctanswerlength['.$key.']', get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); $mform->setAdvanced('correctanswerlength['.$key.']', true); $answerlengthformats = array( '1' => get_string('decimalformat', 'qtype_numerical'), '2' => get_string('significantfiguresformat', 'qtype_calculated') ); $mform->addElement('select', 'correctanswerformat['.$key.']', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats); $mform->setAdvanced('correctanswerformat['.$key.']', true); $mform->addElement('static', 'dividertolerance', '', '<hr />'); $mform->setAdvanced('dividertolerance', true); } $key1++; } $addremoveoptions = array(); $addremoveoptions['1']='1'; for ($i=10; $i<=100; $i+=10) { $addremoveoptions["$i"]="$i"; } $showoptions = Array(); $showoptions['1']='1'; $showoptions['2']='2'; $showoptions['5']='5'; for ($i=10; $i<=100; $i+=10) { $showoptions["$i"]="$i"; } $mform->addElement('header', 'additemhdr', get_string('add', 'moodle')); $mform->closeHeaderBefore('additemhdr'); if ($this->qtypeobj->supports_dataset_item_generation()) { $radiogrp = array(); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('reuseifpossible', 'qtype_calculated'), 0); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregenerationshared', 'qtype_calculated'), 1); $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregenerationall', 'qtype_calculated'), 2); $mform->addGroup($radiogrp, 'forceregenerationgrp', get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false); } $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_calculated')); $mform->addElement('static', "dividera", '', '<hr />'); $addgrp = array(); $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle')); $addgrp[] =& $mform->createElement('select', "selectadd", get_string('additem', 'qtype_calculated'), $addremoveoptions); $addgrp[] = & $mform->createElement('static', "stat", "Items", get_string('newsetwildcardvalues', 'qtype_calculatedsimple')); $mform->addGroup($addgrp, 'addgrp', get_string('additem', 'qtype_calculated'), ' ', false); $mform->addElement('static', "divideradd", '', ''); if ($this->noofitems > 0) { $mform->addElement('header', 'additemhdr', get_string('delete', 'moodle')); $deletegrp = array(); $deletegrp[] = $mform->createElement('submit', 'deletebutton', get_string('delete', 'moodle')); $deletegrp[] = $mform->createElement('select', 'selectdelete', get_string('deleteitem', 'qtype_calculated')."1", $addremoveoptions); $deletegrp[] = $mform->createElement('static', "stat", "Items", get_string('setwildcardvalues', 'qtype_calculatedsimple')); $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false); } else { $mform->addElement('static', 'warning', '', '<span class="error">' . get_string('youmustaddatleastoneitem', 'qtype_calculated').'</span>'); } $addgrp1 = array(); $addgrp1[] = $mform->createElement('submit', 'showbutton', get_string('showitems', 'qtype_calculated')); $addgrp1[] = $mform->createElement('select', "selectshow", '' , $showoptions); $addgrp1[] = $mform->createElement('static', "stat", '', get_string('setwildcardvalues', 'qtype_calculated')); $mform->addGroup($addgrp1, 'addgrp1', '', ' ', false); $mform->registerNoSubmitButton('showbutton'); $mform->closeHeaderBefore('addgrp1'); //---------------------------------------------------------------------- $j = $this->noofitems * count($this->datasetdefs); $k = 1; if ("" != optional_param('selectshow', '', PARAM_INT)) { $k = optional_param('selectshow', '', PARAM_INT); } for ($i = $this->noofitems; $i >= 1; $i--) { if ($k > 0) { $mform->addElement('header', '', "<b>" . get_string('setno', 'qtype_calculated', $i)."</b> "); } foreach ($this->datasetdefs as $defkey => $datasetdef) { if ($k > 0) { if ($datasetdef->category == 0 ) { $mform->addElement('text', "number[$j]", get_string('wildcard', 'qtype_calculated', $datasetdef->name)); } else { $mform->addElement('text', "number[$j]", get_string( 'sharedwildcard', 'qtype_calculated', $datasetdef->name)); } } else { $mform->addElement('hidden', "number[$j]" , ''); } $mform->setType("number[$j]", PARAM_NUMBER); $mform->addElement('hidden', "itemid[$j]"); $mform->setType("itemid[$j]", PARAM_INT); $mform->addElement('hidden', "definition[$j]"); $mform->setType("definition[$j]", PARAM_NOTAGS); $data[$datasetdef->name] =$datasetdef->items[$i]->value; $j--; } if ('' != $strquestionlabel && ($k > 0 )) { //|| $this->outsidelimit || !empty($this->numbererrors ) $repeated[] = $mform->addElement('static', "answercomment[$i]", $strquestionlabel); // decode equations in question text $qtext = $this->qtypeobj->substitute_variables( $this->question->questiontext, $data); $textequations = $this->qtypeobj->find_math_equations($qtext); if ($textequations != '' && count($textequations) > 0 ) { $mform->addElement('static', "divider1[$j]", '', 'Formulas {=..} in question text'); foreach ($textequations as $key => $equation) { if ($formulaerrors = qtype_calculated_find_formula_errors($equation)) { $str=$formulaerrors; } else { eval('$str = '.$equation.';'); } $mform->addElement('static', "textequation", "{=$equation}", "=".$str); } } } $k--; } $mform->addElement('static', 'outsidelimit', '', ''); //---------------------------------------------------------------------- // Non standard name for button element needed so not using add_action_buttons if (!($this->noofitems==0) ) { $mform->addElement('submit', 'savechanges', get_string('savechanges')); $mform->closeHeaderBefore('savechanges'); } //hidden elements $mform->addElement('hidden', 'id'); $mform->setType('id', PARAM_INT); $mform->addElement('hidden', 'courseid'); $mform->setType('courseid', PARAM_INT); $mform->setDefault('courseid', 0); $mform->addElement('hidden', 'category'); $mform->setType('category', PARAM_RAW); $mform->setDefault('category', array('contexts' => array($this->categorycontext))); $mform->addElement('hidden', 'cmid'); $mform->setType('cmid', PARAM_INT); $mform->setDefault('cmid', 0); $mform->addElement('hidden', 'wizard', 'datasetitems'); $mform->setType('wizard', PARAM_ALPHA); $mform->addElement('hidden', 'returnurl'); $mform->setType('returnurl', PARAM_LOCALURL); $mform->setDefault('returnurl', 0); }
/** * Constructs based on course. * Note: This constructor should not usually be called directly. * Use get_fast_modinfo($course) instead as this maintains a cache. * @param stdClass $course course object, only property id is required. * @param int $userid User ID * @throws moodle_exception if course is not found */ public function __construct($course, $userid) { global $CFG, $COURSE, $SITE, $DB; if (!isset($course->cacherev)) { // We require presence of property cacherev to validate the course cache. // No need to clone the $COURSE or $SITE object here because we clone it below anyway. $course = get_course($course->id, false); } $cachecoursemodinfo = cache::make('core', 'coursemodinfo'); // Retrieve modinfo from cache. If not present or cacherev mismatches, call rebuild and retrieve again. $coursemodinfo = $cachecoursemodinfo->get($course->id); if ($coursemodinfo === false || ($course->cacherev != $coursemodinfo->cacherev)) { $coursemodinfo = self::build_course_cache($course); } // Set initial values $this->userid = $userid; $this->sections = array(); $this->cms = array(); $this->instances = array(); $this->groups = null; // If we haven't already preloaded contexts for the course, do it now // Modules are also cached here as long as it's the first time this course has been preloaded. context_helper::preload_course($course->id); // Quick integrity check: as a result of race conditions modinfo may not be regenerated after the change. // It is especially dangerous if modinfo contains the deleted course module, as it results in fatal error. // We can check it very cheap by validating the existence of module context. if ($course->id == $COURSE->id || $course->id == $SITE->id) { // Only verify current course (or frontpage) as pages with many courses may not have module contexts cached. // (Uncached modules will result in a very slow verification). foreach ($coursemodinfo->modinfo as $mod) { if (!context_module::instance($mod->cm, IGNORE_MISSING)) { debugging('Course cache integrity check failed: course module with id '. $mod->cm. ' does not have context. Rebuilding cache for course '. $course->id); // Re-request the course record from DB as well, don't use get_course() here. $course = $DB->get_record('course', array('id' => $course->id), '*', MUST_EXIST); $coursemodinfo = self::build_course_cache($course); break; } } } // Overwrite unset fields in $course object with cached values, store the course object. $this->course = fullclone($course); foreach ($coursemodinfo as $key => $value) { if ($key !== 'modinfo' && $key !== 'sectioncache' && (!isset($this->course->$key) || $key === 'cacherev')) { $this->course->$key = $value; } } // Loop through each piece of module data, constructing it static $modexists = array(); foreach ($coursemodinfo->modinfo as $mod) { if (empty($mod->name)) { // something is wrong here continue; } // Skip modules which don't exist if (!array_key_exists($mod->mod, $modexists)) { $modexists[$mod->mod] = file_exists("$CFG->dirroot/mod/$mod->mod/lib.php"); } if (!$modexists[$mod->mod]) { continue; } // Construct info for this module $cm = new cm_info($this, null, $mod, null); // Store module in instances and cms array if (!isset($this->instances[$cm->modname])) { $this->instances[$cm->modname] = array(); } $this->instances[$cm->modname][$cm->instance] = $cm; $this->cms[$cm->id] = $cm; // Reconstruct sections. This works because modules are stored in order if (!isset($this->sections[$cm->sectionnum])) { $this->sections[$cm->sectionnum] = array(); } $this->sections[$cm->sectionnum][] = $cm->id; } // Expand section objects $this->sectioninfo = array(); foreach ($coursemodinfo->sectioncache as $number => $data) { $this->sectioninfo[$number] = new section_info($data, $number, null, null, $this, null); } }
function validation($data, $files) { $errors = parent::validation($data, $files); $questiondisplay = qtype_multianswer_extract_question($data['questiontext']); // echo "<p> questiondisplay ".$data['questiontext']['text']." <pre>";print_r($questiondisplay);echo "</pre></p>"; if (isset($questiondisplay->options->questions)) { $subquestions = fullclone($questiondisplay->options->questions); if (count($subquestions)) { $sub = 1; foreach ($subquestions as $subquestion) { $prefix = 'sub_' . $sub . '_'; $answercount = 0; $maxgrade = false; $maxfraction = -1; if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) && $this->savedquestiondisplay->options->questions[$sub]->qtype != $questiondisplay->options->questions[$sub]->qtype) { $storemess = " STORED QTYPE " . $question_type_names[$this->savedquestiondisplay->options->questions[$sub]->qtype]; } foreach ($subquestion->answer as $key => $answer) { $trimmedanswer = trim($answer); if ($trimmedanswer !== '') { $answercount++; if ($subquestion->qtype == 'numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) { $errors[$prefix . 'answer[' . $key . ']'] = get_string('answermustbenumberorstar', 'qtype_numerical'); } if ($subquestion->fraction[$key] == 1) { $maxgrade = true; } if ($subquestion->fraction[$key] > $maxfraction) { $maxfraction = $subquestion->fraction[$key]; } } } if ($answercount == 0) { if ($subquestion->qtype == 'multichoice') { $errors[$prefix . 'answer[0]'] = get_string('notenoughanswers', 'qtype_multichoice', 2); } else { $errors[$prefix . 'answer[0]'] = get_string('notenoughanswers', 'quiz', 1); } } if ($maxgrade == false) { $errors[$prefix . 'fraction[0]'] = get_string('fractionsnomax', 'question'); } $sub++; } } else { $errors['questiontext'] = get_string('questionsmissing', 'qtype_multianswer'); } } // $question = qtype_multianswer_extract_question($data['questiontext']); // if (isset $question->options->questions if (($this->negative_diff > 0 || $this->used_in_quiz && ($this->negative_diff > 0 || $this->negative_diff < 0 || $this->qtype_change)) && $this->confirm == 0) { $errors['confirm'] = get_string('confirmsave', 'qtype_multianswer', $this->negative_diff); } return $errors; }
/** * Converts to object * * @return stdClass */ public function to_object() { return fullclone($this->record); }
function comment_on_datasetitems($question, $data, $number) { /// Find a default unit: if (!empty($question->id) && ($unit = get_record('question_numerical_units', 'question', $question->id, 'multiplier', 1.0))) { $unit = $unit->unit; } else { $unit = ''; } $answers = fullclone($question->options->answers); $stranswers = ''; $strmin = get_string('min', 'quiz'); $strmax = get_string('max', 'quiz'); $errors = ''; $delimiter = ': '; $virtualqtype = $this->get_virtual_qtype(); foreach ($answers as $answer) { $formula = parent::substitute_variables($answer->answer, $data); $formattedanswer = qtype_calculated_calculate_answer($answer->answer, $data, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, $answer->correctanswerformat, $unit); if ($formula === '*') { $answer->min = ''; } else { eval('$answer->answer = ' . $formula . ';'); $virtualqtype->get_tolerance_interval($answer); } if ($answer->min === '') { // This should mean that something is wrong $stranswers .= " -{$formattedanswer->answer}" . '<br/><br/>'; } else { $stranswers .= $formula . ' = ' . $formattedanswer->answer . '<br/>'; $stranswers .= $strmin . $delimiter . $answer->min . '---'; $stranswers .= $strmax . $delimiter . $answer->max; $stranswers .= '<br/>'; $correcttrue->correct = $formattedanswer->answer; $correcttrue->true = $answer->answer; if ($formattedanswer->answer < $answer->min || $formattedanswer->answer > $answer->max) { $stranswers .= get_string('trueansweroutsidelimits', 'qtype_calculated', $correcttrue); //<span class="error">ERROR True answer '..' outside limits</span>'; } else { $stranswers .= get_string('trueanswerinsidelimits', 'qtype_calculated', $correcttrue); //' True answer :'.$calculated->trueanswer.' inside limits'; } $stranswers .= '<br/>'; } } return "{$stranswers}"; }
/** * Test the notification sending features. */ public function test_process_event() { global $DB, $USER; $this->resetAfterTest(); $this->setAdminUser(); $msgsink = $this->redirectMessages(); // Generate data. $course = $this->getDataGenerator()->create_course(); $toolgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor'); $rulerecord = new stdClass(); $rulerecord->courseid = $course->id; $rulerecord->eventname = '\\mod_book\\event\\course_module_instance_list_viewed'; $rulerecord->frequency = 1; $rule = $toolgenerator->create_rule($rulerecord); $subrecord = new stdClass(); $subrecord->courseid = $course->id; $subrecord->ruleid = $rule->id; $subrecord->userid = $USER->id; $toolgenerator->create_subscription($subrecord); $recordexists = $DB->record_exists('task_adhoc', array('component' => 'tool_monitor')); $this->assertFalse($recordexists); // Now let us trigger the event. $event = \mod_book\event\course_module_instance_list_viewed::create_from_course($course); $event->trigger(); $this->verify_processed_data($msgsink); // Clean up. \tool_monitor\rule_manager::delete_rule($rule->id); $DB->delete_records('tool_monitor_events'); // Let us create a rule with more than 1 frequency. $rulerecord->frequency = 5; $rule = $toolgenerator->create_rule($rulerecord); $subrecord->ruleid = $rule->id; $toolgenerator->create_subscription($subrecord); // Let us trigger events. for ($i = 0; $i < 5; $i++) { $event = \mod_book\event\course_module_instance_list_viewed::create_from_course($course); $event->trigger(); if ($i != 4) { $this->verify_message_not_sent_yet($msgsink); } } $this->verify_processed_data($msgsink); // Clean up. \tool_monitor\rule_manager::delete_rule($rule->id); $DB->delete_records('tool_monitor_events'); // Now let us create a rule specific to a module instance. $cm = new stdClass(); $cm->course = $course->id; $book = $this->getDataGenerator()->create_module('book', $cm); $rulerecord->eventname = '\\mod_book\\event\\course_module_viewed'; $rulerecord->cmid = $book->cmid; $rule = $toolgenerator->create_rule($rulerecord); $subrecord->ruleid = $rule->id; $toolgenerator->create_subscription($subrecord); // Let us trigger events. $params = array('context' => context_module::instance($book->cmid), 'objectid' => $book->id); for ($i = 0; $i < 5; $i++) { $event = \mod_book\event\course_module_viewed::create($params); $event->trigger(); if ($i != 4) { $this->verify_message_not_sent_yet($msgsink); } } $this->verify_processed_data($msgsink); // Clean up. \tool_monitor\rule_manager::delete_rule($rule->id); $DB->delete_records('tool_monitor_events'); // Now let us create a rule for event that happens in category context events. $rulerecord->eventname = '\\core\\event\\course_category_created'; $rulerecord->courseid = 0; $rule = $toolgenerator->create_rule($rulerecord); $subrecord->courseid = 0; $subrecord->ruleid = $rule->id; $toolgenerator->create_subscription($subrecord); // Let us trigger events. for ($i = 0; $i < 5; $i++) { $this->getDataGenerator()->create_category(); if ($i != 4) { $this->verify_message_not_sent_yet($msgsink); } } $this->verify_processed_data($msgsink); // Clean up. \tool_monitor\rule_manager::delete_rule($rule->id); $DB->delete_records('tool_monitor_events'); // Now let us create a rule at site level. $rulerecord->eventname = '\\core\\event\\blog_entry_created'; $rulerecord->courseid = 0; $rule = $toolgenerator->create_rule($rulerecord); $subrecord->courseid = 0; $subrecord->ruleid = $rule->id; $toolgenerator->create_subscription($subrecord); // Let us trigger events. $blog = new blog_entry(); $blog->subject = "Subject of blog"; $blog->userid = $USER->id; $states = blog_entry::get_applicable_publish_states(); $blog->publishstate = reset($states); for ($i = 0; $i < 5; $i++) { $newblog = fullclone($blog); $newblog->add(); if ($i != 4) { $this->verify_message_not_sent_yet($msgsink); } } $this->verify_processed_data($msgsink); }
admin_externalpage_print_footer(); exit; } else { error("Could not set the theme!"); } } admin_externalpage_print_header('themeselector'); print_heading($strthemes); $themes = get_list_of_plugins("theme"); $sesskey = !empty($USER->id) ? $USER->sesskey : ''; echo "<table style=\"margin-left:auto;margin-right:auto;\" cellpadding=\"7\" cellspacing=\"5\">\n"; if (!$USER->screenreader) { echo "\t<tr class=\"generaltableheader\">\n\t\t<th scope=\"col\">{$strtheme}</th>\n"; echo "\t\t<th scope=\"col\">{$strinfo}</th>\n\t</tr>\n"; } $original_theme = fullclone($THEME); foreach ($themes as $theme) { unset($THEME); if (!file_exists($CFG->themedir . '/' . $theme . '/config.php')) { // bad folder continue; } include $CFG->themedir . '/' . $theme . '/config.php'; $readme = ''; $screenshot = ''; $screenshotpath = ''; if (file_exists("{$theme}/README.html")) { $readme = "\t\t\t\t<li>" . link_to_popup_window($CFG->themewww . '/' . $theme . '/README.html', $theme, $strinfo, 400, 500, '', 'none', true) . "</li>\n"; } else { if (file_exists("{$theme}/README.txt")) { $readme = "\t\t\t\t<li>" . link_to_popup_window($CFG->themewww . '/' . $theme . '/README.txt', $theme, $strinfo, 400, 500, '', 'none', true) . "</li>\n";
/** * We need a new object for display. Sub-question stats can appear more than once in different slots. * So we create a clone of the object and then we can set properties on the object that are per slot. * * @param int $displaynumber The display number for this sub question. * @param int $slot The slot number. * @param int $subqid The sub question id. * @param null|int $variant The variant no. * @return calculated_for_subquestion The object for display. */ protected function make_new_subq_stat_for($displaynumber, $slot, $subqid, $variant = null) { $slotstat = fullclone($this->for_subq($subqid, $variant)); $slotstat->question->number = $this->for_slot($slot)->question->number; $slotstat->subqdisplayorder = $displaynumber; return $slotstat; }
$question->formoptions->cansaveasnew = false; $question->formoptions->repeatelements = true; $question->formoptions->movecontext = false; $formeditable = true; require_capability('moodle/question:add', $categorycontext); } $question->formoptions->mustbeusable = (bool) $appendqnumstring; // Validate the question type. $PAGE->set_pagetype('question-type-' . $question->qtype); // Create the question editing form. if ($wizardnow !== '' && !$movecontext) { $mform = $qtypeobj->next_wizard_form('question.php', $question, $wizardnow, $formeditable); } else { $mform = $qtypeobj->create_editing_form('question.php', $question, $category, $contexts, $formeditable); } $toform = fullclone($question); // send the question object and a few more parameters to the form $toform->category = "{$category->id},{$category->contextid}"; $toform->scrollpos = $scrollpos; if ($formeditable && $id) { $toform->categorymoveto = $toform->category; } $toform->appendqnumstring = $appendqnumstring; $toform->returnurl = $originalreturnurl; $toform->movecontext = $movecontext; if ($cm !== null) { $toform->cmid = $cm->id; $toform->courseid = $cm->course; } else { $toform->courseid = $COURSE->id; }
if (!empty($CFG->usetags)) { useredit_update_interests($usernew, $usernew->interests); } //update user picture if (!empty($CFG->gdversion) and empty($CFG->disableuserimages)) { useredit_update_picture($usernew, $userform); } // update mail bounces useredit_update_bounces($user, $usernew); /// update forum track preference useredit_update_trackforums($user, $usernew); // save custom profile fields data profile_save_data($usernew); // If email was changed, send confirmation email now if ($email_changed && $CFG->emailchangeconfirmation) { $temp_user = fullclone($user); $temp_user->email = $usernew->preference_newemail; $temp_user->emailstop = NULL; $a = new stdClass(); $a->url = $CFG->wwwroot . '/user/emailupdate.php?key=' . $usernew->preference_newemailkey . '&id=' . $user->id; $a->site = $SITE->fullname; $a->fullname = fullname($user, true); $emailupdatemessage = get_string('auth_emailupdatemessage', 'auth', $a); $emailupdatetitle = get_string('auth_emailupdatetitle', 'auth', $a); if (!($mail_results = email_to_user($temp_user, get_admin(), $emailupdatetitle, $emailupdatemessage))) { die("could not send email!"); } } } else { // End If - calendar.php modifyQSUser($olduserinfo);
/** * Method to add a repeating group of elements to a form. * * @param array $elementobjs Array of elements or groups of elements that are to be repeated * @param int $repeats no of times to repeat elements initially * @param array $options a nested array. The first array key is the element name. * the second array key is the type of option to set, and depend on that option, * the value takes different forms. * 'default' - default value to set. Can include '{no}' which is replaced by the repeat number. * 'type' - PARAM_* type. * 'helpbutton' - array containing the helpbutton params. * 'disabledif' - array containing the disabledIf() arguments after the element name. * 'rule' - array containing the addRule arguments after the element name. * 'expanded' - whether this section of the form should be expanded by default. (Name be a header element.) * 'advanced' - whether this element is hidden by 'Show more ...'. * @param string $repeathiddenname name for hidden element storing no of repeats in this form * @param string $addfieldsname name for button to add more fields * @param int $addfieldsno how many fields to add at a time * @param string $addstring name of button, {no} is replaced by no of blanks that will be added. * @param bool $addbuttoninside if true, don't call closeHeaderBefore($addfieldsname). Default false. * @return int no of repeats of element in this page */ function repeat_elements($elementobjs, $repeats, $options, $repeathiddenname, $addfieldsname, $addfieldsno = 5, $addstring = null, $addbuttoninside = false) { if ($addstring === null) { $addstring = get_string('addfields', 'form', $addfieldsno); } else { $addstring = str_ireplace('{no}', $addfieldsno, $addstring); } $repeats = optional_param($repeathiddenname, $repeats, PARAM_INT); $addfields = optional_param($addfieldsname, '', PARAM_TEXT); if (!empty($addfields)) { $repeats += $addfieldsno; } $mform =& $this->_form; $mform->registerNoSubmitButton($addfieldsname); $mform->addElement('hidden', $repeathiddenname, $repeats); $mform->setType($repeathiddenname, PARAM_INT); //value not to be overridden by submitted value $mform->setConstants(array($repeathiddenname => $repeats)); $namecloned = array(); for ($i = 0; $i < $repeats; $i++) { foreach ($elementobjs as $elementobj) { $elementclone = fullclone($elementobj); $this->repeat_elements_fix_clone($i, $elementclone, $namecloned); if ($elementclone instanceof HTML_QuickForm_group && !$elementclone->_appendName) { foreach ($elementclone->getElements() as $el) { $this->repeat_elements_fix_clone($i, $el, $namecloned); } $elementclone->setLabel(str_replace('{no}', $i + 1, $elementclone->getLabel())); } $mform->addElement($elementclone); } } for ($i = 0; $i < $repeats; $i++) { foreach ($options as $elementname => $elementoptions) { $pos = strpos($elementname, '['); if ($pos !== FALSE) { $realelementname = substr($elementname, 0, $pos) . "[{$i}]"; $realelementname .= substr($elementname, $pos); } else { $realelementname = $elementname . "[{$i}]"; } foreach ($elementoptions as $option => $params) { switch ($option) { case 'default': $mform->setDefault($realelementname, str_replace('{no}', $i + 1, $params)); break; case 'helpbutton': $params = array_merge(array($realelementname), $params); call_user_func_array(array(&$mform, 'addHelpButton'), $params); break; case 'disabledif': foreach ($namecloned as $num => $name) { if ($params[0] == $name) { $params[0] = $params[0] . "[{$i}]"; break; } } $params = array_merge(array($realelementname), $params); call_user_func_array(array(&$mform, 'disabledIf'), $params); break; case 'rule': if (is_string($params)) { $params = array(null, $params, null, 'client'); } $params = array_merge(array($realelementname), $params); call_user_func_array(array(&$mform, 'addRule'), $params); break; case 'type': $mform->setType($realelementname, $params); break; case 'expanded': $mform->setExpanded($realelementname, $params); break; case 'advanced': $mform->setAdvanced($realelementname, $params); break; } } } } $mform->addElement('submit', $addfieldsname, $addstring); if (!$addbuttoninside) { $mform->closeHeaderBefore($addfieldsname); } return $repeats; }
$question->formoptions->movecontext = false; $formeditable = true; require_capability('moodle/question:add', $categorycontext); } $question->formoptions->mustbeusable = (bool) $appendqnumstring; // Validate the question type. $PAGE->set_pagetype('question-type-' . $question->qtype); // Create the question editing form. if ($wizardnow !== '' && !$movecontext){ $mform = $qtypeobj->next_wizard_form('question.php', $question, $wizardnow, $formeditable); } else { $mform = $qtypeobj->create_editing_form('question.php', $question, $category, $contexts, $formeditable); } $toform = fullclone($question); // send the question object and a few more parameters to the form $toform->category = "$category->id,$category->contextid"; $toform->scrollpos = $scrollpos; if ($formeditable && $id){ $toform->categorymoveto = $toform->category; } $toform->appendqnumstring = $appendqnumstring; $toform->returnurl = $originalreturnurl; $toform->movecontext = $movecontext; if ($cm !== null){ $toform->cmid = $cm->id; $toform->courseid = $cm->course; } else { $toform->courseid = $COURSE->id; }
/** * Performs a full sync with external database. * * First it creates new courses if necessary, then * enrols and unenrols users. * * @param bool $verbose * @return int 0 means success, 1 db connect failure, 4 db read failure */ public function sync_courses($verbose = false) { global $CFG, $DB; // Make sure we sync either enrolments or courses. if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('newcoursetable') or !$this->get_config('newcoursefullname') or !$this->get_config('newcourseshortname')) { if ($verbose) { mtrace('Course synchronisation skipped.'); } return 0; } if ($verbose) { mtrace('Starting course synchronisation...'); } // We may need a lot of memory here. @set_time_limit(0); raise_memory_limit(MEMORY_HUGE); if (!($extdb = $this->db_init())) { mtrace('Error while communicating with external enrolment database'); return 1; } $table = $this->get_config('newcoursetable'); $fullname = trim($this->get_config('newcoursefullname')); $shortname = trim($this->get_config('newcourseshortname')); $idnumber = trim($this->get_config('newcourseidnumber')); $category = trim($this->get_config('newcoursecategory')); // Lowercased versions - necessary because we normalise the resultset with array_change_key_case(). $fullname_l = strtolower($fullname); $shortname_l = strtolower($shortname); $idnumber_l = strtolower($idnumber); $category_l = strtolower($category); $localcategoryfield = $this->get_config('localcategoryfield', 'id'); $defaultcategory = $this->get_config('defaultcategory'); if (!$DB->record_exists('course_categories', array('id' => $defaultcategory))) { if ($verbose) { mtrace(" default course category does not exist!"); } $categories = $DB->get_records('course_categories', array(), 'sortorder', 'id', 0, 1); $first = reset($categories); $defaultcategory = $first->id; } $sqlfields = array($fullname, $shortname); if ($category) { $sqlfields[] = $category; } if ($idnumber) { $sqlfields[] = $idnumber; } $sql = $this->db_get_sql($table, array(), $sqlfields, true); $createcourses = array(); if ($rs = $extdb->Execute($sql)) { if (!$rs->EOF) { while ($fields = $rs->FetchRow()) { $fields = array_change_key_case($fields, CASE_LOWER); $fields = $this->db_decode($fields); if (empty($fields[$shortname_l]) or empty($fields[$fullname_l])) { if ($verbose) { mtrace(' error: invalid external course record, shortname and fullname are mandatory: ' . json_encode($fields)); // Hopefully every geek can read JS, right? } continue; } if ($DB->record_exists('course', array('shortname' => $fields[$shortname_l]))) { // Already exists, skip. continue; } // Allow empty idnumber but not duplicates. if ($idnumber and $fields[$idnumber_l] !== '' and $fields[$idnumber_l] !== null and $DB->record_exists('course', array('idnumber' => $fields[$idnumber_l]))) { if ($verbose) { mtrace(' error: duplicate idnumber, can not create course: ' . $fields[$shortname_l] . ' [' . $fields[$idnumber_l] . ']'); } continue; } $course = new stdClass(); $course->fullname = $fields[$fullname_l]; $course->shortname = $fields[$shortname_l]; $course->idnumber = $idnumber ? $fields[$idnumber_l] : ''; if ($category) { if (empty($fields[$category_l])) { // Empty category means use default. $course->category = $defaultcategory; } else { if ($coursecategory = $DB->get_record('course_categories', array($localcategoryfield => $fields[$category_l]), 'id')) { // Yay, correctly specified category! $course->category = $coursecategory->id; unset($coursecategory); } else { // Bad luck, better not continue because unwanted ppl might get access to course in different category. if ($verbose) { mtrace(' error: invalid category ' . $localcategoryfield . ', can not create course: ' . $fields[$shortname_l]); } continue; } } } else { $course->category = $defaultcategory; } $createcourses[] = $course; } } $rs->Close(); } else { mtrace('Error reading data from the external course table'); $extdb->Close(); return 4; } if ($createcourses) { require_once "{$CFG->dirroot}/course/lib.php"; $templatecourse = $this->get_config('templatecourse'); $template = false; if ($templatecourse) { if ($template = $DB->get_record('course', array('shortname' => $templatecourse))) { $template = fullclone(course_get_format($template)->get_course()); unset($template->id); unset($template->fullname); unset($template->shortname); unset($template->idnumber); } else { if ($verbose) { mtrace(" can not find template for new course!"); } } } if (!$template) { $courseconfig = get_config('moodlecourse'); $template = new stdClass(); $template->summary = ''; $template->summaryformat = FORMAT_HTML; $template->format = $courseconfig->format; $template->newsitems = $courseconfig->newsitems; $template->showgrades = $courseconfig->showgrades; $template->showreports = $courseconfig->showreports; $template->maxbytes = $courseconfig->maxbytes; $template->groupmode = $courseconfig->groupmode; $template->groupmodeforce = $courseconfig->groupmodeforce; $template->visible = $courseconfig->visible; $template->lang = $courseconfig->lang; $template->groupmodeforce = $courseconfig->groupmodeforce; } foreach ($createcourses as $fields) { $newcourse = clone $template; $newcourse->fullname = $fields->fullname; $newcourse->shortname = $fields->shortname; $newcourse->idnumber = $fields->idnumber; $newcourse->category = $fields->category; // Detect duplicate data once again, above we can not find duplicates // in external data using DB collation rules... if ($DB->record_exists('course', array('shortname' => $newcourse->shortname))) { if ($verbose) { mtrace(" can not insert new course, duplicate shortname detected: " . $newcourse->shortname); } continue; } else { if (!empty($newcourse->idnumber) and $DB->record_exists('course', array('idnumber' => $newcourse->idnumber))) { if ($verbose) { mtrace(" can not insert new course, duplicate idnumber detected: " . $newcourse->idnumber); } continue; } } $c = create_course($newcourse); if ($verbose) { mtrace(" creating course: {$c->id}, {$c->fullname}, {$c->shortname}, {$c->idnumber}, {$c->category}"); } } unset($createcourses); unset($template); } // Close db connection. $extdb->Close(); if ($verbose) { mtrace('...course synchronisation finished.'); } return 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&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() . '&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; }
public function comment_on_datasetitems($qtypeobj, $questionid, $questiontext, $answers, $data, $number) { global $DB; $comment = new stdClass(); $comment->stranswers = array(); $comment->outsidelimit = false; $comment->answers = array(); // Find a default unit. if (!empty($questionid) && ($unit = $DB->get_record('question_numerical_units', array('question' => $questionid, 'multiplier' => 1.0)))) { $unit = $unit->unit; } else { $unit = ''; } $answers = fullclone($answers); $delimiter = ': '; $virtualqtype = $qtypeobj->get_virtual_qtype(); foreach ($answers as $key => $answer) { $error = qtype_calculated_find_formula_errors($answer->answer); if ($error) { $comment->stranswers[$key] = $error; continue; } $formula = $this->substitute_variables($answer->answer, $data); $formattedanswer = qtype_calculated_calculate_answer($answer->answer, $data, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, $answer->correctanswerformat, $unit); if ($formula === '*') { $answer->min = ' '; $formattedanswer->answer = $answer->answer; } else { eval('$ansvalue = ' . $formula . ';'); $ans = new qtype_numerical_answer(0, $ansvalue, 0, '', 0, $answer->tolerance); $ans->tolerancetype = $answer->tolerancetype; list($answer->min, $answer->max) = $ans->get_tolerance_interval($answer); } if ($answer->min === '') { // This should mean that something is wrong. $comment->stranswers[$key] = " {$formattedanswer->answer}" . '<br/><br/>'; } else { if ($formula === '*') { $comment->stranswers[$key] = $formula . ' = ' . get_string('anyvalue', 'qtype_calculated') . '<br/><br/><br/>'; } else { $formula = shorten_text($formula, 57, true); $comment->stranswers[$key] = $formula . ' = ' . $formattedanswer->answer . '<br/>'; $correcttrue = new stdClass(); $correcttrue->correct = $formattedanswer->answer; $correcttrue->true = ''; if ($formattedanswer->answer < $answer->min || $formattedanswer->answer > $answer->max) { $comment->outsidelimit = true; $comment->answers[$key] = $key; $comment->stranswers[$key] .= get_string('trueansweroutsidelimits', 'qtype_calculated', $correcttrue); } else { $comment->stranswers[$key] .= get_string('trueanswerinsidelimits', 'qtype_calculated', $correcttrue); } $comment->stranswers[$key] .= '<br/>'; $comment->stranswers[$key] .= get_string('min', 'qtype_calculated') . $delimiter . $answer->min . ' --- '; $comment->stranswers[$key] .= get_string('max', 'qtype_calculated') . $delimiter . $answer->max; } } } return fullclone($comment); }
public function comment_on_datasetitems($qtypeobj, $questionid, $questiontext, $answers, $data, $number) { global $DB; $comment = new stdClass(); $comment->stranswers = array(); $comment->outsidelimit = false; $comment->answers = array(); $answers = fullclone($answers); $errors = ''; $delimiter = ': '; foreach ($answers as $key => $answer) { $answer->answer = $this->substitute_variables($answer->answer, $data); //evaluate the equations i.e {=5+4) $qtext = ''; $qtextremaining = $answer->answer; while (preg_match('~\{=([^[:space:]}]*)}~', $qtextremaining, $regs1)) { $qtextsplits = explode($regs1[0], $qtextremaining, 2); $qtext =$qtext.$qtextsplits[0]; $qtextremaining = $qtextsplits[1]; if (empty($regs1[1])) { $str = ''; } else { if ($formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) { $str=$formulaerrors; } else { eval('$str = '.$regs1[1].';'); } } $qtext = $qtext.$str; } $answer->answer = $qtext.$qtextremaining; $comment->stranswers[$key] = $answer->answer; } return fullclone($comment); }