/** * Validate Fold * * @param int $actiontype The action type of the fold we're validating * @param array $data The form data in array format * @return array An array of error strings */ function validate_fold($actiontype, $data) { $errors = array(); $ranges = array(); $parsed = array(); $langsuffix = $this->types[$actiontype]; $prefix = $langsuffix . '_'; // Fallback check, if add another range button pushed skip vaidation. // Otherwise validate and make sure all rows have been filled correctly out if (!array_key_exists($prefix . 'add', $data)) { // Iterate through the submitted values. // Existing data has the key track_<number>_min/max/etc. foreach ($data as $key => $value) { $error = ''; if (false === strpos($key, $prefix)) { continue; } // Extract the element unique id $parts = explode('_', $key); $id = $parts[1]; if (array_key_exists($id, $parsed)) { continue; } $keyprefix = $prefix . $id; $keymin = $keyprefix . '_min'; $keymax = $keyprefix . '_max'; $keyselect = $keyprefix . '_selected'; $keygroup = $keyprefix . '_score'; $skip_empty = false; // Skip over empty score ranges. if (!$this->valid_score($data, $keymin) && !$this->valid_score($data, $keymax)) { if (!empty($data[$keyselect])) { $error = get_string('results_error_incomplete_score_range', self::LANG_FILE); } else { $skip_empty = true; } } else { if (!$this->valid_score($data, $keymin) || !$this->valid_score($data, $keymax)) { $error = get_string('results_error_incomplete_score_range', self::LANG_FILE); } else { if (elis_float_comp($data[$keymin], $data[$keymax], '>')) { $error = get_string('results_error_min_larger_than_max', self::LANG_FILE); } else { if (empty($data[$keyselect])) { $error = get_string('results_error_no_' . $langsuffix, self::LANG_FILE); } } } } // Only check the ranges if no other error has been found yet. if (!$skip_empty && empty($error)) { foreach ($ranges as $range) { if (elis_float_comp($range['min'], $data[$keymin], '<=') && elis_float_comp($data[$keymin], $range['max'], '<=')) { $error = get_string('results_error_range_overlap_min', self::LANG_FILE); } else { if (elis_float_comp($range['min'], $data[$keymax], '<=') && elis_float_comp($data[$keymax], $range['max'], '<=')) { $error = get_string('results_error_range_overlap_max', self::LANG_FILE); } else { if (elis_float_comp($data[$keymin], $range['min'], '<=') && elis_float_comp($range['max'], $data[$keymax], '<=')) { $error = get_string('results_error_range_envelop', self::LANG_FILE); } } } } $ranges[] = array('min' => $data[$keymin], 'max' => $data[$keymax]); } if (!empty($error)) { $errors[$keygroup] = $error; } $parsed[$id] = true; } } return $errors; }
/** * Test elis_float_comp() function * @dataProvider elis_float_comp_dataprovider * @param float $num1 The first number to compare. * @param float $num2 The second number to compare. * @param string $op The comparison operation. * @param bool $expectedresult The expected result. */ public function test_elis_float_comp($num1, $num2, $op, $expectedresult) { $this->assertEquals($expectedresult, elis_float_comp($num1, $num2, $op)); $this->assertEquals($expectedresult, elis_float_comp($num1, $num2, $op, true)); }
/** * Process all the students in this class * * Class properties required: * id - id of class * criteriatype - what mark to look at, 0 for final mark, anything else is an element id * engineid - id of results engine entry * scheduleddate - date when it was supposed to run * rundate - date when it is being run * * Class properties required by sub-functions: * eventtriggertype - what type of trigger the engine uses * lockedgrade - whether the grade must be locked if "set grade" trigger is used * * @param $class object The class object see above for required attributes * @return boolean Success/failure * @uses $CFG */ function results_engine_process($class) { global $CFG, $DB; $params = array('classid' => $class->id); $students = results_engine_get_students($class); if (sizeof($students) == 0) { return true; } $params = array('resultsid' => $class->engineid); $fields = 'id, actiontype, minimum, maximum, trackid, classid, fieldid, fielddata'; $actions = $DB->get_records('local_elisprogram_res_action', $params, '', $fields); $fieldids = array(); $classids = array(); $trackids = array(); foreach ($actions as $action) { if ($action->actiontype == RESULTS_ENGINE_UPDATE_PROFILE) { $fieldids[$action->fieldid] = $action->fieldid; } else { if ($action->actiontype == RESULTS_ENGINE_ASSIGN_CLASS) { $classids[$action->classid] = $action->classid; } else { if ($action->actiontype == RESULTS_ENGINE_ASSIGN_TRACK) { $trackids[$action->trackid] = $action->trackid; } } } } foreach ($fieldids as $id) { if ($record = $DB->get_record('local_eliscore_field', array('id' => $id))) { $userfields[$id] = new field($record, null, array(), true); } } $classes = $DB->get_records_list('local_elisprogram_cls', 'id', $classids); $tracks = $DB->get_records_list('local_elisprogram_trk', 'id', $trackids); // Log that the class has been processed $log = new stdClass(); $log->classid = $class->id; $log->datescheduled = $class->scheduleddate; $log->daterun = $class->rundate; $classlogid = $DB->insert_record('local_elisprogram_res_clslog', $log); $log = new stdClass(); $log->classlogid = $classlogid; $log->daterun = $class->rundate; // Find the correct action to take based on student marks foreach ($students as $student) { $do = null; foreach ($actions as $action) { if (elis_float_comp($student->grade, $action->minimum, '>=') && elis_float_comp($student->grade, $action->maximum, '<=')) { $do = $action; break; } } if ($do != null) { $obj = new object(); switch ($do->actiontype) { case RESULTS_ENGINE_ASSIGN_TRACK: usertrack::enrol($student->userid, $do->trackid); $message = 'results_action_assign_track'; $track = $tracks[$do->trackid]; $obj->name = $track->name . ' (' . $track->idnumber . ')'; break; case RESULTS_ENGINE_ASSIGN_CLASS: $enrol = new student(); $enrol->classid = $do->classid; $enrol->userid = $student->userid; $enrol->save(); $message = 'results_action_assign_class'; $obj->name = $classes[$do->classid]->idnumber; break; case RESULTS_ENGINE_UPDATE_PROFILE: if (!array_key_exists($do->fieldid, $userfields)) { print get_string('results_field_not_found', RESULTS_ENGINE_LANG_FILE, $do) . "\n"; break; } /* $context = \local_elisprogram\context\user::instance($student->userid); field_data::set_for_context_and_field($context, $userfields[$do->fieldid], $do->fielddata); */ //set field $filter = new select_filter('id = :userid', array('userid' => $student->userid)); if (user::exists($filter)) { //get user $user = user::find($filter); $user = $user->current(); //set field $field = 'field_' . $userfields[$do->fieldid]->shortname; $user->{$field} = $do->fielddata; $user->save(); } $message = 'results_action_update_profile'; $obj->name = $userfields[$do->fieldid]->shortname; $obj->value = $do->fielddata; break; default: // If we don't know what we're doing, do nothing. break; } $obj->id = $do->id; $log->action = get_string($message, RESULTS_ENGINE_LANG_FILE, $obj); $log->userid = $student->userid; $DB->insert_record('local_elisprogram_res_stulog', $log, false); } } if (isset($class->cron) && $class->cron) { print get_string('results_class_processed', RESULTS_ENGINE_LANG_FILE, $class) . "\n"; } return true; }