mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 08:26:37 +02:00
MDL-44070 Conditional availability enhancements (6): core changes
Changes core code to use new API instead of the old one when checking user access to activities and sections. Includes changes to other libraries that are necessary after adding the availability system and removing old conditional tables etc.
This commit is contained in:
parent
6a601097a0
commit
8d1f33e122
14 changed files with 393 additions and 402 deletions
|
@ -44,8 +44,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||||
new lang_string('configcompletiondefault', 'completion'), 1, $options));
|
new lang_string('configcompletiondefault', 'completion'), 1, $options));
|
||||||
|
|
||||||
$optionalsubsystems->add($checkbox = new admin_setting_configcheckbox('enableavailability',
|
$optionalsubsystems->add($checkbox = new admin_setting_configcheckbox('enableavailability',
|
||||||
new lang_string('enableavailability','condition'),
|
new lang_string('enableavailability', 'availability'),
|
||||||
new lang_string('configenableavailability','condition'), 0));
|
new lang_string('enableavailability_desc', 'availability'), 0));
|
||||||
$checkbox->set_affects_modinfo(true);
|
$checkbox->set_affects_modinfo(true);
|
||||||
|
|
||||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
|
$optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
|
||||||
|
|
|
@ -165,10 +165,9 @@ class core_course_external extends external_api {
|
||||||
//user that can view hidden module should know about the visibility
|
//user that can view hidden module should know about the visibility
|
||||||
$module['visible'] = $cm->visible;
|
$module['visible'] = $cm->visible;
|
||||||
|
|
||||||
//availability date (also send to user who can see hidden module when the showavailabilyt is ON)
|
// Availability date (also send to user who can see hidden module).
|
||||||
if ($canupdatecourse or ($CFG->enableavailability && $canviewhidden && $cm->showavailability)) {
|
if ($CFG->enableavailability && ($canviewhidden || $canupdatecourse)) {
|
||||||
$module['availablefrom'] = $cm->availablefrom;
|
$module['availability'] = $cm->availability;
|
||||||
$module['availableuntil'] = $cm->availableuntil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$baseurl = 'webservice/pluginfile.php';
|
$baseurl = 'webservice/pluginfile.php';
|
||||||
|
@ -223,8 +222,7 @@ class core_course_external extends external_api {
|
||||||
'modicon' => new external_value(PARAM_URL, 'activity icon url'),
|
'modicon' => new external_value(PARAM_URL, 'activity icon url'),
|
||||||
'modname' => new external_value(PARAM_PLUGIN, 'activity module type'),
|
'modname' => new external_value(PARAM_PLUGIN, 'activity module type'),
|
||||||
'modplural' => new external_value(PARAM_TEXT, 'activity module plural name'),
|
'modplural' => new external_value(PARAM_TEXT, 'activity module plural name'),
|
||||||
'availablefrom' => new external_value(PARAM_INT, 'module availability start date', VALUE_OPTIONAL),
|
'availability' => new external_value(PARAM_RAW, 'module availability settings', VALUE_OPTIONAL),
|
||||||
'availableuntil' => new external_value(PARAM_INT, 'module availability en date', VALUE_OPTIONAL),
|
|
||||||
'indent' => new external_value(PARAM_INT, 'number of identation in the site'),
|
'indent' => new external_value(PARAM_INT, 'number of identation in the site'),
|
||||||
'contents' => new external_multiple_structure(
|
'contents' => new external_multiple_structure(
|
||||||
new external_single_structure(
|
new external_single_structure(
|
||||||
|
|
|
@ -1056,16 +1056,8 @@ function get_array_of_activities($courseid) {
|
||||||
$rawmods[$seq]->completiongradeitemnumber;
|
$rawmods[$seq]->completiongradeitemnumber;
|
||||||
$mod[$seq]->completionview = $rawmods[$seq]->completionview;
|
$mod[$seq]->completionview = $rawmods[$seq]->completionview;
|
||||||
$mod[$seq]->completionexpected = $rawmods[$seq]->completionexpected;
|
$mod[$seq]->completionexpected = $rawmods[$seq]->completionexpected;
|
||||||
$mod[$seq]->availablefrom = $rawmods[$seq]->availablefrom;
|
|
||||||
$mod[$seq]->availableuntil = $rawmods[$seq]->availableuntil;
|
|
||||||
$mod[$seq]->showavailability = $rawmods[$seq]->showavailability;
|
|
||||||
$mod[$seq]->showdescription = $rawmods[$seq]->showdescription;
|
$mod[$seq]->showdescription = $rawmods[$seq]->showdescription;
|
||||||
if (!empty($CFG->enableavailability)) {
|
$mod[$seq]->availability = $rawmods[$seq]->availability;
|
||||||
condition_info::fill_availability_conditions($rawmods[$seq]);
|
|
||||||
$mod[$seq]->conditionscompletion = $rawmods[$seq]->conditionscompletion;
|
|
||||||
$mod[$seq]->conditionsgrade = $rawmods[$seq]->conditionsgrade;
|
|
||||||
$mod[$seq]->conditionsfield = $rawmods[$seq]->conditionsfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
$modname = $mod[$seq]->mod;
|
$modname = $mod[$seq]->mod;
|
||||||
$functionname = $modname."_get_coursemodule_info";
|
$functionname = $modname."_get_coursemodule_info";
|
||||||
|
@ -1139,8 +1131,7 @@ function get_array_of_activities($courseid) {
|
||||||
// 'empty'. This list corresponds to code in the cm_info constructor.
|
// 'empty'. This list corresponds to code in the cm_info constructor.
|
||||||
foreach (array('idnumber', 'groupmode', 'groupingid', 'groupmembersonly',
|
foreach (array('idnumber', 'groupmode', 'groupingid', 'groupmembersonly',
|
||||||
'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content',
|
'indent', 'completion', 'extra', 'extraclasses', 'iconurl', 'onclick', 'content',
|
||||||
'icon', 'iconcomponent', 'customdata', 'showavailability', 'availablefrom',
|
'icon', 'iconcomponent', 'customdata', 'availability',
|
||||||
'availableuntil', 'conditionscompletion', 'conditionsgrade',
|
|
||||||
'completionview', 'completionexpected', 'score', 'showdescription')
|
'completionview', 'completionexpected', 'score', 'showdescription')
|
||||||
as $property) {
|
as $property) {
|
||||||
if (property_exists($mod[$seq], $property) &&
|
if (property_exists($mod[$seq], $property) &&
|
||||||
|
@ -1698,8 +1689,6 @@ function course_delete_module($cmid) {
|
||||||
// features are not turned on, in case they were turned on previously (these will be
|
// features are not turned on, in case they were turned on previously (these will be
|
||||||
// very quick on an empty table).
|
// very quick on an empty table).
|
||||||
$DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id));
|
$DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id));
|
||||||
$DB->delete_records('course_modules_availability', array('coursemoduleid'=> $cm->id));
|
|
||||||
$DB->delete_records('course_modules_avail_fields', array('coursemoduleid' => $cm->id));
|
|
||||||
$DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id,
|
$DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id,
|
||||||
'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
|
'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
|
||||||
|
|
||||||
|
|
|
@ -220,9 +220,10 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$moduleinfo->completionexpected = time() + (7 * 24 * 3600);
|
$moduleinfo->completionexpected = time() + (7 * 24 * 3600);
|
||||||
|
|
||||||
// Conditional activity.
|
// Conditional activity.
|
||||||
$moduleinfo->availablefrom = time();
|
$moduleinfo->availability = '{"op":"&","showc":[true,true],"c":[' .
|
||||||
$moduleinfo->availableuntil = time() + (7 * 24 * 3600);
|
'{"type":"date","d":">=","t":' . time() . '},' .
|
||||||
$moduleinfo->showavailability = CONDITION_STUDENTVIEW_SHOW;
|
'{"type":"date","d":"<","t":' . (time() + (7 * 24 * 3600)) . '}' .
|
||||||
|
']}';
|
||||||
$coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
|
$coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
|
||||||
$moduleinfo->conditiongradegroup = array(array('conditiongradeitemid' => $coursegradeitem->id, 'conditiongrademin' => 10, 'conditiongrademax' => 80));
|
$moduleinfo->conditiongradegroup = array(array('conditiongradeitemid' => $coursegradeitem->id, 'conditiongrademin' => 10, 'conditiongrademax' => 80));
|
||||||
$moduleinfo->conditionfieldgroup = array(array('conditionfield' => 'email', 'conditionfieldoperator' => OP_CONTAINS, 'conditionfieldvalue' => '@'));
|
$moduleinfo->conditionfieldgroup = array(array('conditionfield' => 'email', 'conditionfieldoperator' => OP_CONTAINS, 'conditionfieldvalue' => '@'));
|
||||||
|
@ -280,9 +281,7 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
|
$this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
|
||||||
$this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
|
$this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
|
||||||
$this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
|
$this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
|
||||||
$this->assertEquals($moduleinfo->availablefrom, $dbcm->availablefrom);
|
$this->assertEquals($moduleinfo->availability, $dbcm->availability);
|
||||||
$this->assertEquals($moduleinfo->availableuntil, $dbcm->availableuntil);
|
|
||||||
$this->assertEquals($moduleinfo->showavailability, $dbcm->showavailability);
|
|
||||||
$this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
|
$this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
|
||||||
$this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
|
$this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
|
||||||
$this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
|
$this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
|
||||||
|
@ -298,25 +297,6 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
|
$this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
|
||||||
$this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
|
$this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
|
||||||
|
|
||||||
// Common values when conditional activity is enabled.
|
|
||||||
foreach ($moduleinfo->conditionfieldgroup as $fieldgroup) {
|
|
||||||
$isfieldgroupsaved = $DB->count_records('course_modules_avail_fields', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'userfield' => $fieldgroup['conditionfield'], 'operator' => $fieldgroup['conditionfieldoperator'],
|
|
||||||
'value' => $fieldgroup['conditionfieldvalue']));
|
|
||||||
$this->assertEquals(1, $isfieldgroupsaved);
|
|
||||||
}
|
|
||||||
foreach ($moduleinfo->conditiongradegroup as $gradegroup) {
|
|
||||||
$isgradegroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'grademin' => $gradegroup['conditiongrademin'], 'grademax' => $gradegroup['conditiongrademax'],
|
|
||||||
'gradeitemid' => $gradegroup['conditiongradeitemid']));
|
|
||||||
$this->assertEquals(1, $isgradegroupsaved);
|
|
||||||
}
|
|
||||||
foreach ($moduleinfo->conditioncompletiongroup as $completiongroup) {
|
|
||||||
$iscompletiongroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'sourcecmid' => $completiongroup['conditionsourcecmid'], 'requiredcompletion' => $completiongroup['conditionrequiredcompletion']));
|
|
||||||
$this->assertEquals(1, $iscompletiongroupsaved);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test specific to the module.
|
// Test specific to the module.
|
||||||
$modulerunasserts = $modulename.'_create_run_asserts';
|
$modulerunasserts = $modulename.'_create_run_asserts';
|
||||||
$this->$modulerunasserts($moduleinfo, $dbmodinstance);
|
$this->$modulerunasserts($moduleinfo, $dbmodinstance);
|
||||||
|
@ -478,13 +458,14 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$moduleinfo->completionunlocked = 1;
|
$moduleinfo->completionunlocked = 1;
|
||||||
|
|
||||||
// Conditional activity.
|
// Conditional activity.
|
||||||
$moduleinfo->availablefrom = time();
|
|
||||||
$moduleinfo->availableuntil = time() + (7 * 24 * 3600);
|
|
||||||
$moduleinfo->showavailability = CONDITION_STUDENTVIEW_SHOW;
|
|
||||||
$coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
|
$coursegradeitem = grade_item::fetch_course_item($moduleinfo->course); //the activity will become available only when the user reach some grade into the course itself.
|
||||||
$moduleinfo->conditiongradegroup = array(array('conditiongradeitemid' => $coursegradeitem->id, 'conditiongrademin' => 10, 'conditiongrademax' => 80));
|
$moduleinfo->availability = '{"op":"&","showc":[true,true],"c":[' .
|
||||||
$moduleinfo->conditionfieldgroup = array(array('conditionfield' => 'email', 'conditionfieldoperator' => OP_CONTAINS, 'conditionfieldvalue' => '@'));
|
'{"type":"date","d":">=","t":' . time() . '},' .
|
||||||
$moduleinfo->conditioncompletiongroup = array(array('conditionsourcecmid' => $assigncm->id, 'conditionrequiredcompletion' => COMPLETION_COMPLETE)); // "conditionsourcecmid == 0" => none
|
'{"type":"date","d":"<","t":' . (time() + (7 * 24 * 3600)) . '}' .
|
||||||
|
'{"type":"grade","id":' . $coursegradeitem->id . ',"min":10,"max":80},' .
|
||||||
|
'{"type":"profile","sf":"email","op":"contains","v":"@"},'.
|
||||||
|
'{"type":"completion","id":'. $assigncm->id . ',"e":' . COMPLETION_COMPLETE . '}' .
|
||||||
|
']}';
|
||||||
|
|
||||||
// Grading and Advanced grading.
|
// Grading and Advanced grading.
|
||||||
require_once($CFG->dirroot . '/rating/lib.php');
|
require_once($CFG->dirroot . '/rating/lib.php');
|
||||||
|
@ -533,9 +514,7 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
|
$this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
|
||||||
$this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
|
$this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
|
||||||
$this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
|
$this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
|
||||||
$this->assertEquals($moduleinfo->availablefrom, $dbcm->availablefrom);
|
$this->assertEquals($moduleinfo->availability, $dbcm->availability);
|
||||||
$this->assertEquals($moduleinfo->availableuntil, $dbcm->availableuntil);
|
|
||||||
$this->assertEquals($moduleinfo->showavailability, $dbcm->showavailability);
|
|
||||||
$this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
|
$this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
|
||||||
$this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
|
$this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
|
||||||
$this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
|
$this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
|
||||||
|
@ -551,25 +530,6 @@ class core_course_courselib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
|
$this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
|
||||||
$this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
|
$this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
|
||||||
|
|
||||||
// Common values when conditional activity is enabled.
|
|
||||||
foreach ($moduleinfo->conditionfieldgroup as $fieldgroup) {
|
|
||||||
$isfieldgroupsaved = $DB->count_records('course_modules_avail_fields', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'userfield' => $fieldgroup['conditionfield'], 'operator' => $fieldgroup['conditionfieldoperator'],
|
|
||||||
'value' => $fieldgroup['conditionfieldvalue']));
|
|
||||||
$this->assertEquals(1, $isfieldgroupsaved);
|
|
||||||
}
|
|
||||||
foreach ($moduleinfo->conditiongradegroup as $gradegroup) {
|
|
||||||
$isgradegroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'grademin' => $gradegroup['conditiongrademin'], 'grademax' => $gradegroup['conditiongrademax'],
|
|
||||||
'gradeitemid' => $gradegroup['conditiongradeitemid']));
|
|
||||||
$this->assertEquals(1, $isgradegroupsaved);
|
|
||||||
}
|
|
||||||
foreach ($moduleinfo->conditioncompletiongroup as $completiongroup) {
|
|
||||||
$iscompletiongroupsaved = $DB->count_records('course_modules_availability', array('coursemoduleid' => $dbcm->id,
|
|
||||||
'sourcecmid' => $completiongroup['conditionsourcecmid'], 'requiredcompletion' => $completiongroup['conditionrequiredcompletion']));
|
|
||||||
$this->assertEquals(1, $iscompletiongroupsaved);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test specific to the module.
|
// Test specific to the module.
|
||||||
$modulerunasserts = $modulename.'_update_run_asserts';
|
$modulerunasserts = $modulename.'_update_run_asserts';
|
||||||
$this->$modulerunasserts($moduleinfo, $dbmodinstance);
|
$this->$modulerunasserts($moduleinfo, $dbmodinstance);
|
||||||
|
|
|
@ -360,16 +360,16 @@ class grade_report_user extends grade_report {
|
||||||
($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil()))) {
|
($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil()))) {
|
||||||
$hide = true;
|
$hide = true;
|
||||||
} else if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) {
|
} else if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) {
|
||||||
// The grade object can be marked visible but still be hidden if...
|
// The grade object can be marked visible but still be hidden if
|
||||||
// 1) "enablegroupmembersonly" is on and the activity is assigned to a grouping the user is not in.
|
// the student cannot see the activity due to conditional access
|
||||||
// 2) the student cannot see the activity due to conditional access and its set to be hidden entirely.
|
// and it's set to be hidden entirely.
|
||||||
$instances = $this->gtree->modinfo->get_instances_of($grade_object->itemmodule);
|
$instances = $this->gtree->modinfo->get_instances_of($grade_object->itemmodule);
|
||||||
if (!empty($instances[$grade_object->iteminstance])) {
|
if (!empty($instances[$grade_object->iteminstance])) {
|
||||||
$cm = $instances[$grade_object->iteminstance];
|
$cm = $instances[$grade_object->iteminstance];
|
||||||
if (!$cm->uservisible) {
|
if (!$cm->uservisible) {
|
||||||
// Further checks are required to determine whether the activity is entirely hidden or just greyed out.
|
// If there is 'availableinfo' text then it is only greyed
|
||||||
if ($cm->is_user_access_restricted_by_group() || $cm->is_user_access_restricted_by_conditional_access() ||
|
// out and not entirely hidden.
|
||||||
$cm->is_user_access_restricted_by_capability()) {
|
if (!$cm->availableinfo) {
|
||||||
$hide = true;
|
$hide = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,16 +147,17 @@ class core_grade_reportuserlib_testcase extends advanced_testcase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditional activity tests.
|
// Conditional activity tests.
|
||||||
$DB->insert_record('course_modules_availability', (object)array(
|
// Note: I have ported this test to the new conditional availability
|
||||||
'coursemoduleid'=>$forum1cm->id,
|
// system, but it does not appear to actually test anything - in fact,
|
||||||
'gradeitemid' => 37,
|
// if you remove the code that sets the condition, it still passes
|
||||||
'grademin' => 5.5
|
// because it apparently is intended to have the same number of rows
|
||||||
));
|
// even when some are hidden. The same is true of the
|
||||||
|
// set_coursemodule_visible test above. I don't feel this is a very
|
||||||
$cm = (object)array('id' => $forum1cm->id);
|
// good test; somebody with more knowledge of this report might want to
|
||||||
$test = new condition_info($cm, CONDITION_MISSING_EVERYTHING);
|
// fix it to check that the row actually is being hidden.
|
||||||
$fullcm = $test->get_full_course_module();
|
$DB->set_field('course_modules', 'availability', '{"op":"|","show":false,"c":[' .
|
||||||
|
'{"type":"grade","min":5.5,"id":37}]}', array('id' => $forum1cm->id));
|
||||||
|
get_fast_modinfo($course->id, 0, true);
|
||||||
foreach ($users as $user) {
|
foreach ($users as $user) {
|
||||||
|
|
||||||
$this->setUser($user);
|
$this->setUser($user);
|
||||||
|
|
|
@ -1522,6 +1522,11 @@ function get_all_instances_in_course($modulename, $course, $userid=NULL, $includ
|
||||||
* and the module's type (eg "forum") returns whether the object
|
* and the module's type (eg "forum") returns whether the object
|
||||||
* is visible or not, groupmembersonly visibility not tested
|
* is visible or not, groupmembersonly visibility not tested
|
||||||
*
|
*
|
||||||
|
* NOTE: This does NOT take into account visibility to a particular user.
|
||||||
|
* To get visibility access for a specific user, use get_fast_modinfo, get a
|
||||||
|
* cm_info object from this, and check the ->uservisible property; or use
|
||||||
|
* the \core_availability\info_module::is_user_visible() static function.
|
||||||
|
*
|
||||||
* @global object
|
* @global object
|
||||||
|
|
||||||
* @param $moduletype Name of the module eg 'forum'
|
* @param $moduletype Name of the module eg 'forum'
|
||||||
|
@ -1548,46 +1553,6 @@ function instance_is_visible($moduletype, $module) {
|
||||||
return true; // visible by default!
|
return true; // visible by default!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether a course module is visible within a course,
|
|
||||||
* this is different from instance_is_visible() - faster and visibility for user
|
|
||||||
*
|
|
||||||
* @global object
|
|
||||||
* @global object
|
|
||||||
* @uses DEBUG_DEVELOPER
|
|
||||||
* @uses CONTEXT_MODULE
|
|
||||||
* @uses CONDITION_MISSING_EXTRATABLE
|
|
||||||
* @param object $cm object
|
|
||||||
* @param int $userid empty means current user
|
|
||||||
* @return bool Success
|
|
||||||
*/
|
|
||||||
function coursemodule_visible_for_user($cm, $userid=0) {
|
|
||||||
global $USER,$CFG;
|
|
||||||
|
|
||||||
if (empty($cm->id)) {
|
|
||||||
debugging("Incorrect course module parameter!", DEBUG_DEVELOPER);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (empty($userid)) {
|
|
||||||
$userid = $USER->id;
|
|
||||||
}
|
|
||||||
if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', context_module::instance($cm->id), $userid)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($CFG->enableavailability) {
|
|
||||||
require_once($CFG->libdir.'/conditionlib.php');
|
|
||||||
$ci=new condition_info($cm,CONDITION_MISSING_EXTRATABLE);
|
|
||||||
if(!$ci->is_available($cm->availableinfo,false,$userid) and
|
|
||||||
!has_capability('moodle/course:viewhiddenactivities',
|
|
||||||
context_module::instance($cm->id), $userid)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return groups_course_module_visible($cm, $userid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// LOG FUNCTIONS /////////////////////////////////////////////////////
|
/// LOG FUNCTIONS /////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -2386,7 +2386,6 @@ function delete_course_module($id) {
|
||||||
// features are not turned on, in case they were turned on previously (these will be
|
// features are not turned on, in case they were turned on previously (these will be
|
||||||
// very quick on an empty table)
|
// very quick on an empty table)
|
||||||
$DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id));
|
$DB->delete_records('course_modules_completion', array('coursemoduleid' => $cm->id));
|
||||||
$DB->delete_records('course_modules_availability', array('coursemoduleid'=> $cm->id));
|
|
||||||
$DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id,
|
$DB->delete_records('course_completion_criteria', array('moduleinstance' => $cm->id,
|
||||||
'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
|
'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY));
|
||||||
|
|
||||||
|
@ -4389,3 +4388,22 @@ function ajaxenabled(array $browsers = null) {
|
||||||
debugging('ajaxenabled() is deprecated - please update your code to assume it returns true.', DEBUG_DEVELOPER);
|
debugging('ajaxenabled() is deprecated - please update your code to assume it returns true.', DEBUG_DEVELOPER);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether a course module is visible within a course,
|
||||||
|
* this is different from instance_is_visible() - faster and visibility for user
|
||||||
|
*
|
||||||
|
* @global object
|
||||||
|
* @global object
|
||||||
|
* @uses DEBUG_DEVELOPER
|
||||||
|
* @uses CONTEXT_MODULE
|
||||||
|
* @param object $cm object
|
||||||
|
* @param int $userid empty means current user
|
||||||
|
* @return bool Success
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
function coursemodule_visible_for_user($cm, $userid=0) {
|
||||||
|
debugging('coursemodule_visible_for_user() deprecated since Moodle 2.7. ' .
|
||||||
|
'Replace with \core_availability\info_module::is_user_visible().');
|
||||||
|
return \core_availability\info_module::is_user_visible($cm, $userid, false);
|
||||||
|
}
|
||||||
|
|
|
@ -99,9 +99,10 @@ class course_modinfo {
|
||||||
private $instances;
|
private $instances;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups that the current user belongs to. This value is usually not available (set to null)
|
* Groups that the current user belongs to. This value is calculated on first
|
||||||
* unless the course has activities set to groupmembersonly. When set, it is an array of
|
* request to the property or function.
|
||||||
* grouping id => array of group id => group id. Includes grouping id 0 for 'all groups'.
|
* When set, it is an array of grouping id => array of group id => group id.
|
||||||
|
* Includes grouping id 0 for 'all groups'.
|
||||||
* @var int[][]
|
* @var int[][]
|
||||||
*/
|
*/
|
||||||
private $groups;
|
private $groups;
|
||||||
|
@ -562,7 +563,7 @@ class course_modinfo {
|
||||||
// Get section data
|
// Get section data
|
||||||
$sections = $DB->get_records('course_sections', array('course' => $course->id), 'section',
|
$sections = $DB->get_records('course_sections', array('course' => $course->id), 'section',
|
||||||
'section, id, course, name, summary, summaryformat, sequence, visible, ' .
|
'section, id, course, name, summary, summaryformat, sequence, visible, ' .
|
||||||
'availablefrom, availableuntil, showavailability, groupingid');
|
'availability');
|
||||||
$compressedsections = array();
|
$compressedsections = array();
|
||||||
|
|
||||||
$formatoptionsdef = course_get_format($course)->section_format_options();
|
$formatoptionsdef = course_get_format($course)->section_format_options();
|
||||||
|
@ -658,7 +659,6 @@ class course_modinfo {
|
||||||
* - {@link cm_info::get_icon_url()}
|
* - {@link cm_info::get_icon_url()}
|
||||||
* - {@link cm_info::$uservisible}
|
* - {@link cm_info::$uservisible}
|
||||||
* - {@link cm_info::$available}
|
* - {@link cm_info::$available}
|
||||||
* - {@link cm_info::$showavailability}
|
|
||||||
* - {@link cm_info::$availableinfo}
|
* - {@link cm_info::$availableinfo}
|
||||||
* - plus any of the properties listed in Stage 3.
|
* - plus any of the properties listed in Stage 3.
|
||||||
*
|
*
|
||||||
|
@ -723,12 +723,7 @@ class course_modinfo {
|
||||||
* @property-read int $completionview 1 if 'on view' completion is enabled, 0 otherwise - from course_modules table
|
* @property-read int $completionview 1 if 'on view' completion is enabled, 0 otherwise - from course_modules table
|
||||||
* @property-read int $completionexpected Set to a unix time if completion of this activity is expected at a
|
* @property-read int $completionexpected Set to a unix time if completion of this activity is expected at a
|
||||||
* particular time, 0 if no time set - from course_modules table
|
* particular time, 0 if no time set - from course_modules table
|
||||||
* @property-read int $availablefrom Available date for this activity (0 if not set, or set to seconds since epoch; before this
|
* @property-read string $availability Availability information as JSON string or null if none -
|
||||||
* date, activity does not display to students) - from course_modules table
|
|
||||||
* @property-read int $availableuntil Available until date for this activity (0 if not set, or set to seconds since epoch; from
|
|
||||||
* this date, activity does not display to students) - from course_modules table
|
|
||||||
* @property-read int $showavailability When activity is unavailable, this field controls whether it is shown to students (0 =
|
|
||||||
* hide completely, 1 = show greyed out with information about when it will be available) -
|
|
||||||
* from course_modules table
|
* from course_modules table
|
||||||
* @property-read int $showdescription Controls whether the description of the activity displays on the course main page (in
|
* @property-read int $showdescription Controls whether the description of the activity displays on the course main page (in
|
||||||
* addition to anywhere it might display within the activity itself). 0 = do not show
|
* addition to anywhere it might display within the activity itself). 0 = do not show
|
||||||
|
@ -912,26 +907,10 @@ class cm_info implements IteratorAggregate {
|
||||||
private $completionexpected;
|
private $completionexpected;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available date for this activity (0 if not set, or set to seconds since epoch; before this
|
* Availability information as JSON string or null if none - from course_modules table
|
||||||
* date, activity does not display to students) - from course_modules table
|
* @var string
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $availablefrom;
|
private $availability;
|
||||||
|
|
||||||
/**
|
|
||||||
* Available until date for this activity (0 if not set, or set to seconds since epoch; from
|
|
||||||
* this date, activity does not display to students) - from course_modules table
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $availableuntil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When activity is unavailable, this field controls whether it is shown to students (0 =
|
|
||||||
* hide completely, 1 = show greyed out with information about when it will be available) -
|
|
||||||
* from course_modules table
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $showavailability;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls whether the description of the activity displays on the course main page (in
|
* Controls whether the description of the activity displays on the course main page (in
|
||||||
|
@ -1095,10 +1074,11 @@ class cm_info implements IteratorAggregate {
|
||||||
'modplural' => 'get_module_type_name_plural',
|
'modplural' => 'get_module_type_name_plural',
|
||||||
'id' => false,
|
'id' => false,
|
||||||
'added' => false,
|
'added' => false,
|
||||||
|
'availability' => false,
|
||||||
'available' => 'get_available',
|
'available' => 'get_available',
|
||||||
'availablefrom' => false,
|
'availablefrom' => 'get_deprecated_available_date',
|
||||||
'availableinfo' => 'get_available_info',
|
'availableinfo' => 'get_available_info',
|
||||||
'availableuntil' => false,
|
'availableuntil' => 'get_deprecated_available_date',
|
||||||
'completion' => false,
|
'completion' => false,
|
||||||
'completionexpected' => false,
|
'completionexpected' => false,
|
||||||
'completiongradeitemnumber' => false,
|
'completiongradeitemnumber' => false,
|
||||||
|
@ -1528,7 +1508,7 @@ class cm_info implements IteratorAggregate {
|
||||||
static $cmfields = array('id', 'course', 'module', 'instance', 'section', 'idnumber', 'added',
|
static $cmfields = array('id', 'course', 'module', 'instance', 'section', 'idnumber', 'added',
|
||||||
'score', 'indent', 'visible', 'visibleold', 'groupmode', 'groupingid', 'groupmembersonly',
|
'score', 'indent', 'visible', 'visibleold', 'groupmode', 'groupingid', 'groupmembersonly',
|
||||||
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
|
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
|
||||||
'availablefrom', 'availableuntil', 'showavailability', 'showdescription');
|
'showdescription', 'availability');
|
||||||
foreach ($cmfields as $key) {
|
foreach ($cmfields as $key) {
|
||||||
$cmrecord->$key = $this->$key;
|
$cmrecord->$key = $this->$key;
|
||||||
}
|
}
|
||||||
|
@ -1649,19 +1629,24 @@ class cm_info implements IteratorAggregate {
|
||||||
*
|
*
|
||||||
* When this is function is called, user-visible status is recalculated automatically.
|
* When this is function is called, user-visible status is recalculated automatically.
|
||||||
*
|
*
|
||||||
|
* The $showavailability flag does not really do anything any more, but is retained
|
||||||
|
* for backward compatibility. Setting this to false will cause $availableinfo to
|
||||||
|
* be ignored.
|
||||||
|
*
|
||||||
* Note: May not be called from _cm_info_view (only _cm_info_dynamic).
|
* Note: May not be called from _cm_info_view (only _cm_info_dynamic).
|
||||||
* @param bool $available False if this item is not 'available'
|
* @param bool $available False if this item is not 'available'
|
||||||
* @param int $showavailability 0 = do not show this item at all if it's not available,
|
* @param int $showavailability 0 = do not show this item at all if it's not available,
|
||||||
* 1 = show this item greyed out with the following message
|
* 1 = show this item greyed out with the following message
|
||||||
* @param string $availableinfo Information about why this is not available which displays
|
* @param string $availableinfo Information about why this is not available, or
|
||||||
* to those who have viewhiddenactivities, and to everyone if showavailability is set;
|
* empty string if not displaying
|
||||||
* note that this function replaces the existing data (if any)
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function set_available($available, $showavailability=0, $availableinfo='') {
|
public function set_available($available, $showavailability=0, $availableinfo='') {
|
||||||
$this->check_not_view_only();
|
$this->check_not_view_only();
|
||||||
$this->available = $available;
|
$this->available = $available;
|
||||||
$this->showavailability = $showavailability;
|
if (!$showavailability) {
|
||||||
|
$availableinfo = '';
|
||||||
|
}
|
||||||
$this->availableinfo = $availableinfo;
|
$this->availableinfo = $availableinfo;
|
||||||
$this->update_user_visible();
|
$this->update_user_visible();
|
||||||
}
|
}
|
||||||
|
@ -1730,9 +1715,7 @@ class cm_info implements IteratorAggregate {
|
||||||
? $mod->completionview : 0;
|
? $mod->completionview : 0;
|
||||||
$this->completionexpected = isset($mod->completionexpected)
|
$this->completionexpected = isset($mod->completionexpected)
|
||||||
? $mod->completionexpected : 0;
|
? $mod->completionexpected : 0;
|
||||||
$this->showavailability = isset($mod->showavailability) ? $mod->showavailability : 0;
|
$this->availability = isset($mod->availability) ? $mod->availability : null;
|
||||||
$this->availablefrom = isset($mod->availablefrom) ? $mod->availablefrom : 0;
|
|
||||||
$this->availableuntil = isset($mod->availableuntil) ? $mod->availableuntil : 0;
|
|
||||||
$this->conditionscompletion = isset($mod->conditionscompletion)
|
$this->conditionscompletion = isset($mod->conditionscompletion)
|
||||||
? $mod->conditionscompletion : array();
|
? $mod->conditionscompletion : array();
|
||||||
$this->conditionsgrade = isset($mod->conditionsgrade)
|
$this->conditionsgrade = isset($mod->conditionsgrade)
|
||||||
|
@ -1774,8 +1757,9 @@ class cm_info implements IteratorAggregate {
|
||||||
|
|
||||||
if (!empty($CFG->enableavailability)) {
|
if (!empty($CFG->enableavailability)) {
|
||||||
require_once($CFG->libdir. '/conditionlib.php');
|
require_once($CFG->libdir. '/conditionlib.php');
|
||||||
// Get availability information
|
// Get availability information.
|
||||||
$ci = new condition_info($this);
|
$ci = new \core_availability\info_module($this);
|
||||||
|
|
||||||
// Note that the modinfo currently available only includes minimal details (basic data)
|
// Note that the modinfo currently available only includes minimal details (basic data)
|
||||||
// but we know that this function does not need anything more than basic data.
|
// but we know that this function does not need anything more than basic data.
|
||||||
$this->available = $ci->is_available($this->availableinfo, true,
|
$this->available = $ci->is_available($this->availableinfo, true,
|
||||||
|
@ -1820,12 +1804,32 @@ class cm_info implements IteratorAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter method for property $showavailability, ensures that dynamic data is retrieved
|
* Getter method for property $showavailability. Works by checking the
|
||||||
|
* availableinfo property to see if it's empty or not.
|
||||||
|
*
|
||||||
* @return int
|
* @return int
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
*/
|
*/
|
||||||
private function get_show_availability() {
|
private function get_show_availability() {
|
||||||
$this->obtain_dynamic_data();
|
debugging('$cm->showavailability property has been deprecated. You ' .
|
||||||
return $this->showavailability;
|
'can replace it by checking if $cm->availableinfo has content.',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return ($this->get_available_info() !== '') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for $availablefrom and $availableuntil. Just returns zero
|
||||||
|
* as these are no longer supported.
|
||||||
|
*
|
||||||
|
* @return int Zero
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
private function get_deprecated_available_date() {
|
||||||
|
debugging('$cm->availablefrom and $cm->availableuntil have been deprecated. This ' .
|
||||||
|
'information is no longer available as the system provides more complex ' .
|
||||||
|
'options (for example, there might be different dates for different users).',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1867,7 +1871,7 @@ class cm_info implements IteratorAggregate {
|
||||||
|
|
||||||
$this->uservisible = false;
|
$this->uservisible = false;
|
||||||
// Ensure activity is completely hidden from the user.
|
// Ensure activity is completely hidden from the user.
|
||||||
$this->showavailability = 0;
|
$this->availableinfo = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1918,12 +1922,23 @@ class cm_info implements IteratorAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the module's conditional access settings mean that the user cannot see the activity at all
|
* Checks whether the module's conditional access settings mean that the
|
||||||
|
* user cannot see the activity at all
|
||||||
|
*
|
||||||
|
* This is deprecated because it is confusing (name sounds like it's about
|
||||||
|
* access restriction but it is actually about display), is not used
|
||||||
|
* anywhere, and is not necessary. Nobody (outside conditional libraries)
|
||||||
|
* should care what it is that restricted something.
|
||||||
*
|
*
|
||||||
* @return bool True if the user cannot see the module. False if the activity is either available or should be greyed out.
|
* @return bool True if the user cannot see the module. False if the activity is either available or should be greyed out.
|
||||||
|
* @deprecated since 2.7
|
||||||
*/
|
*/
|
||||||
public function is_user_access_restricted_by_conditional_access() {
|
public function is_user_access_restricted_by_conditional_access() {
|
||||||
global $CFG;
|
global $CFG;
|
||||||
|
debugging('cm_info::is_user_access_restricted_by_conditional_access() ' .
|
||||||
|
'is deprecated; this function is not needed (use $cm->uservisible ' .
|
||||||
|
'and $cm->availableinfo) to decide whether it should be available ' .
|
||||||
|
'or appear)', DEBUG_DEVELOPER);
|
||||||
|
|
||||||
if (empty($CFG->enableavailability)) {
|
if (empty($CFG->enableavailability)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1934,22 +1949,9 @@ class cm_info implements IteratorAggregate {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If module will always be visible anyway (but greyed out), don't bother checking anything else
|
// Return false if user can access the activity, or if its availability
|
||||||
if ($this->get_show_availability() == CONDITION_STUDENTVIEW_SHOW) {
|
// info is set (= should be displayed even though not accessible).
|
||||||
return false;
|
return !$this->get_user_visible() && !$this->get_available_info();
|
||||||
}
|
|
||||||
|
|
||||||
// Can the user see hidden modules?
|
|
||||||
if (has_capability('moodle/course:viewhiddenactivities', $this->get_context(), $userid)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the module hidden due to unmet conditions?
|
|
||||||
if (!$this->get_available()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2213,14 +2215,7 @@ class cached_cm_info {
|
||||||
* @property-read int $visible Section visibility (1 = visible) - from course_sections table
|
* @property-read int $visible Section visibility (1 = visible) - from course_sections table
|
||||||
* @property-read string $summary Section summary text if specified - from course_sections table
|
* @property-read string $summary Section summary text if specified - from course_sections table
|
||||||
* @property-read int $summaryformat Section summary text format (FORMAT_xx constant) - from course_sections table
|
* @property-read int $summaryformat Section summary text format (FORMAT_xx constant) - from course_sections table
|
||||||
* @property-read int $showavailability When section is unavailable, this field controls whether it is shown to students (0 =
|
* @property-read string $availability Availability information as JSON string -
|
||||||
* hide completely, 1 = show greyed out with information about when it will be available) -
|
|
||||||
* from course_sections table
|
|
||||||
* @property-read int $availablefrom Available date for this section (0 if not set, or set to seconds since epoch;
|
|
||||||
* before this date, section does not display to students) - from course_sections table
|
|
||||||
* @property-read int $availableuntil Available until date for this section (0 if not set, or set to seconds since epoch;
|
|
||||||
* from this date, section does not display to students) - from course_sections table
|
|
||||||
* @property-read int $groupingid If section is restricted to users of a particular grouping, this is its id (0 if not set) -
|
|
||||||
* from course_sections table
|
* from course_sections table
|
||||||
* @property-read array $conditionscompletion Availability conditions for this section based on the completion of
|
* @property-read array $conditionscompletion Availability conditions for this section based on the completion of
|
||||||
* course-modules (array from course-module id to required completion state
|
* course-modules (array from course-module id to required completion state
|
||||||
|
@ -2278,33 +2273,10 @@ class section_info implements IteratorAggregate {
|
||||||
private $_summaryformat;
|
private $_summaryformat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When section is unavailable, this field controls whether it is shown to students (0 =
|
* Availability information as JSON string - from course_sections table
|
||||||
* hide completely, 1 = show greyed out with information about when it will be available) -
|
* @var string
|
||||||
* from course_sections table
|
|
||||||
* @var int
|
|
||||||
*/
|
*/
|
||||||
private $_showavailability;
|
private $_availability;
|
||||||
|
|
||||||
/**
|
|
||||||
* Available date for this section (0 if not set, or set to seconds since epoch; before this
|
|
||||||
* date, section does not display to students) - from course_sections table
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $_availablefrom;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Available until date for this section (0 if not set, or set to seconds since epoch; from
|
|
||||||
* this date, section does not display to students) - from course_sections table
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $_availableuntil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If section is restricted to users of a particular grouping, this is its id
|
|
||||||
* (0 if not set) - from course_sections table
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $_groupingid;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Availability conditions for this section based on the completion of
|
* Availability conditions for this section based on the completion of
|
||||||
|
@ -2364,10 +2336,7 @@ class section_info implements IteratorAggregate {
|
||||||
'summary' => '',
|
'summary' => '',
|
||||||
'summaryformat' => '1', // FORMAT_HTML, but must be a string
|
'summaryformat' => '1', // FORMAT_HTML, but must be a string
|
||||||
'visible' => '1',
|
'visible' => '1',
|
||||||
'showavailability' => '0',
|
'availability' => null,
|
||||||
'availablefrom' => '0',
|
|
||||||
'availableuntil' => '0',
|
|
||||||
'groupingid' => '0',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2518,15 +2487,10 @@ class section_info implements IteratorAggregate {
|
||||||
}
|
}
|
||||||
if (!empty($CFG->enableavailability)) {
|
if (!empty($CFG->enableavailability)) {
|
||||||
require_once($CFG->libdir. '/conditionlib.php');
|
require_once($CFG->libdir. '/conditionlib.php');
|
||||||
// Get availability information
|
// Get availability information.
|
||||||
$ci = new condition_info_section($this);
|
$ci = new \core_availability\info_section($this);
|
||||||
$this->_available = $ci->is_available($this->_availableinfo, true,
|
$this->_available = $ci->is_available($this->_availableinfo, true,
|
||||||
$userid, $this->modinfo);
|
$userid, $this->modinfo);
|
||||||
if ($this->_availableinfo === '' && $this->_groupingid) {
|
|
||||||
// Still may have some extra text in availableinfo because of groupping.
|
|
||||||
// Set as undefined so the next call to get_availabeinfo() calculates it.
|
|
||||||
$this->_availableinfo = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$this->_available = true;
|
$this->_available = true;
|
||||||
$this->_availableinfo = '';
|
$this->_availableinfo = '';
|
||||||
|
@ -2607,6 +2571,62 @@ class section_info implements IteratorAggregate {
|
||||||
return $this->_uservisible;
|
return $this->_uservisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for property $showavailability. Works by checking the
|
||||||
|
* availableinfo property to see if it's empty or not.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
private function get_showavailability() {
|
||||||
|
debugging('$section->showavailability property has been deprecated. You ' .
|
||||||
|
'can replace it by checking if $section->availableinfo has content.',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return ($this->get_availableinfo() !== '') ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for $availablefrom. Just returns zero as no longer supported.
|
||||||
|
*
|
||||||
|
* @return int Zero
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
private function get_availablefrom() {
|
||||||
|
debugging('$section->availablefrom has been deprecated. This ' .
|
||||||
|
'information is no longer available as the system provides more complex ' .
|
||||||
|
'options (for example, there might be different dates for different users).',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for $availablefrom. Just returns zero as no longer supported.
|
||||||
|
*
|
||||||
|
* @return int Zero
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
private function get_availableuntil() {
|
||||||
|
debugging('$section->availableuntil has been deprecated. This ' .
|
||||||
|
'information is no longer available as the system provides more complex ' .
|
||||||
|
'options (for example, there might be different dates for different users).',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter method for $groupingid. Just returns zero as no longer supported.
|
||||||
|
*
|
||||||
|
* @return int Zero
|
||||||
|
* @deprecated Since Moodle 2.7
|
||||||
|
*/
|
||||||
|
private function get_groupingid() {
|
||||||
|
debugging('$section->groupingid has been deprecated. This ' .
|
||||||
|
'information is no longer available as the system provides more complex ' .
|
||||||
|
'options (for example, combining multiple groupings).',
|
||||||
|
DEBUG_DEVELOPER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores the course_sections.sequence value
|
* Restores the course_sections.sequence value
|
||||||
*
|
*
|
||||||
|
@ -2646,18 +2666,6 @@ class section_info implements IteratorAggregate {
|
||||||
// Sequence stored implicity in modinfo $sections array
|
// Sequence stored implicity in modinfo $sections array
|
||||||
unset($section->sequence);
|
unset($section->sequence);
|
||||||
|
|
||||||
// Add availability data if turned on
|
|
||||||
if ($CFG->enableavailability) {
|
|
||||||
require_once($CFG->dirroot . '/lib/conditionlib.php');
|
|
||||||
condition_info_section::fill_availability_conditions($section);
|
|
||||||
if (count($section->conditionscompletion) == 0) {
|
|
||||||
unset($section->conditionscompletion);
|
|
||||||
}
|
|
||||||
if (count($section->conditionsgrade) == 0) {
|
|
||||||
unset($section->conditionsgrade);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove default data
|
// Remove default data
|
||||||
foreach (self::$sectioncachedefaults as $field => $value) {
|
foreach (self::$sectioncachedefaults as $field => $value) {
|
||||||
// Exact compare as strings to avoid problems if some strings are set
|
// Exact compare as strings to avoid problems if some strings are set
|
||||||
|
|
|
@ -5073,12 +5073,6 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
|
||||||
$DB->delete_records_select('course_modules_completion',
|
$DB->delete_records_select('course_modules_completion',
|
||||||
'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)',
|
'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)',
|
||||||
array($courseid));
|
array($courseid));
|
||||||
$DB->delete_records_select('course_modules_availability',
|
|
||||||
'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)',
|
|
||||||
array($courseid));
|
|
||||||
$DB->delete_records_select('course_modules_avail_fields',
|
|
||||||
'coursemoduleid IN (SELECT id from {course_modules} WHERE course=?)',
|
|
||||||
array($courseid));
|
|
||||||
|
|
||||||
// Remove course-module data.
|
// Remove course-module data.
|
||||||
$cms = $DB->get_records('course_modules', array('course' => $course->id));
|
$cms = $DB->get_records('course_modules', array('course' => $course->id));
|
||||||
|
@ -5188,13 +5182,7 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
|
||||||
}
|
}
|
||||||
$DB->update_record('course', $oldcourse);
|
$DB->update_record('course', $oldcourse);
|
||||||
|
|
||||||
// Delete course sections and availability options.
|
// Delete course sections.
|
||||||
$DB->delete_records_select('course_sections_availability',
|
|
||||||
'coursesectionid IN (SELECT id from {course_sections} WHERE course=?)',
|
|
||||||
array($course->id));
|
|
||||||
$DB->delete_records_select('course_sections_avail_fields',
|
|
||||||
'coursesectionid IN (SELECT id from {course_sections} WHERE course=?)',
|
|
||||||
array($course->id));
|
|
||||||
$DB->delete_records('course_sections', array('course' => $course->id));
|
$DB->delete_records('course_sections', array('course' => $course->id));
|
||||||
|
|
||||||
// Delete legacy, section and any other course files.
|
// Delete legacy, section and any other course files.
|
||||||
|
|
|
@ -176,7 +176,7 @@ abstract class testing_module_generator extends component_generator_base {
|
||||||
$easymergefields = array('section', 'added', 'score', 'indent',
|
$easymergefields = array('section', 'added', 'score', 'indent',
|
||||||
'visible', 'visibleold', 'groupmode', 'groupingid', 'groupmembersonly',
|
'visible', 'visibleold', 'groupmode', 'groupingid', 'groupmembersonly',
|
||||||
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
|
'completion', 'completiongradeitemnumber', 'completionview', 'completionexpected',
|
||||||
'availablefrom', 'availableuntil', 'showavailability', 'showdescription');
|
'availability', 'showdescription');
|
||||||
foreach ($easymergefields as $key) {
|
foreach ($easymergefields as $key) {
|
||||||
if (isset($options[$key])) {
|
if (isset($options[$key])) {
|
||||||
$moduleinfo->$key = $options[$key];
|
$moduleinfo->$key = $options[$key];
|
||||||
|
@ -191,9 +191,7 @@ abstract class testing_module_generator extends component_generator_base {
|
||||||
'groupmode' => 0,
|
'groupmode' => 0,
|
||||||
'groupingid' => 0,
|
'groupingid' => 0,
|
||||||
'groupmembersonly' => 0,
|
'groupmembersonly' => 0,
|
||||||
'showavailability' => 0,
|
'availability' => null,
|
||||||
'availablefrom' => 0,
|
|
||||||
'availableuntil' => 0,
|
|
||||||
'completion' => 0,
|
'completion' => 0,
|
||||||
'completionview' => 0,
|
'completionview' => 0,
|
||||||
'completionexpected' => 0,
|
'completionexpected' => 0,
|
||||||
|
|
|
@ -213,57 +213,10 @@ class core_test_generator_testcase extends advanced_testcase {
|
||||||
// We need id of the grading item for the second module to create availability dependency in the 3rd module.
|
// We need id of the grading item for the second module to create availability dependency in the 3rd module.
|
||||||
$gradingitem = grade_item::fetch(array('courseid'=>$course->id, 'itemtype'=>'mod', 'itemmodule' => 'assign', 'iteminstance' => $m3->id));
|
$gradingitem = grade_item::fetch(array('courseid'=>$course->id, 'itemtype'=>'mod', 'itemmodule' => 'assign', 'iteminstance' => $m3->id));
|
||||||
|
|
||||||
// Now prepare options to create the 4th module which availability depends on other modules.
|
// Now prepare option to create the 4th module with an availability condition.
|
||||||
// Following options available if $CFG->enableavailability is set:
|
|
||||||
$optionsavailability = array(
|
$optionsavailability = array(
|
||||||
'showavailability' => 1,
|
'availability' => '{"op":"&","showc":[true],"c":[' .
|
||||||
'availablefrom' => time() - WEEKSECS,
|
'{"type":"date","d":">=","t":' . (time() - WEEKSECS) . '}]}',
|
||||||
'availableuntil' => time() + WEEKSECS,
|
|
||||||
'conditiongradegroup' => array(
|
|
||||||
array(
|
|
||||||
'conditiongradeitemid' => $gradingitem->id,
|
|
||||||
'conditiongrademin' => 20,
|
|
||||||
'conditiongrademax' => 80,
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'conditionfieldgroup' => array(
|
|
||||||
array(
|
|
||||||
'conditionfield' => 'address',
|
|
||||||
'conditionfieldoperator' => 'contains',
|
|
||||||
'conditionfieldvalue' => 'street',
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'conditioncompletiongroup' => array(
|
|
||||||
array(
|
|
||||||
'conditionsourcecmid' => $m2->cmid,
|
|
||||||
'conditionrequiredcompletion' => 1
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'conditionsourcecmid' => $m3->cmid,
|
|
||||||
'conditionrequiredcompletion' => 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
// The same data for assertion (different format).
|
|
||||||
$optionsavailabilityassertion = array(
|
|
||||||
'conditionsgrade' => array(
|
|
||||||
$gradingitem->id => (object)array(
|
|
||||||
'min' => 20,
|
|
||||||
'max' => 80,
|
|
||||||
'name' => $gradingitem->itemname
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'conditionsfield' => array(
|
|
||||||
'address' => (object)array(
|
|
||||||
'fieldname' => 'address',
|
|
||||||
'operator' => 'contains',
|
|
||||||
'value' => 'street'
|
|
||||||
)
|
|
||||||
),
|
|
||||||
'conditionscompletion' => array(
|
|
||||||
$m2->cmid => 1,
|
|
||||||
$m3->cmid => 1
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create module with conditional availability.
|
// Create module with conditional availability.
|
||||||
|
@ -304,12 +257,7 @@ class core_test_generator_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($featuregrade['gradecat'], $gradingitem->categoryid);
|
$this->assertEquals($featuregrade['gradecat'], $gradingitem->categoryid);
|
||||||
|
|
||||||
$cm4 = $modinfo->cms[$m4->cmid];
|
$cm4 = $modinfo->cms[$m4->cmid];
|
||||||
$this->assertEquals($optionsavailability['showavailability'], $cm4->showavailability);
|
$this->assertEquals($optionsavailability['availability'], $cm4->availability);
|
||||||
$this->assertEquals($optionsavailability['availablefrom'], $cm4->availablefrom);
|
|
||||||
$this->assertEquals($optionsavailability['availableuntil'], $cm4->availableuntil);
|
|
||||||
$this->assertEquals($optionsavailabilityassertion['conditionsgrade'], $cm4->conditionsgrade);
|
|
||||||
$this->assertEquals($optionsavailabilityassertion['conditionsfield'], $cm4->conditionsfield);
|
|
||||||
$this->assertEquals($optionsavailabilityassertion['conditionscompletion'], $cm4->conditionscompletion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_create_block() {
|
public function test_create_block() {
|
||||||
|
|
|
@ -58,27 +58,17 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
array('course' => $course->id),
|
array('course' => $course->id),
|
||||||
array('completion' => 1));
|
array('completion' => 1));
|
||||||
|
|
||||||
// Generate the module and add availability conditions.
|
// Add availability conditions.
|
||||||
$conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE);
|
$availability = '{"op":"&","showc":[true,true,true],"c":[' .
|
||||||
$conditionsgrade = array(666 => (object)array('min' => 0.4, 'max' => null, 'name' => '!missing'));
|
'{"type":"completion","cm":' . $prereqforum->cmid . ',"e":"' .
|
||||||
$conditionsfield = array('email' => (object)array(
|
COMPLETION_COMPLETE . '"},' .
|
||||||
'fieldname' => 'email',
|
'{"type":"grade","id":666,"min":0.4},' .
|
||||||
'operator' => 'contains',
|
'{"type":"profile","op":"contains","sf":"email","v":"test"}' .
|
||||||
'value' => 'test'
|
']}';
|
||||||
));
|
$DB->set_field('course_sections', 'availability', $availability,
|
||||||
$sectiondb = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
|
array('course' => $course->id, 'section' => 2));
|
||||||
$ci = new condition_info_section((object)array('id' => $sectiondb->id), CONDITION_MISSING_EVERYTHING);
|
|
||||||
foreach ($conditionscompletion as $cmid => $requiredcompletion) {
|
|
||||||
$ci->add_completion_condition($cmid, $requiredcompletion);
|
|
||||||
}
|
|
||||||
foreach ($conditionsgrade as $gradeid => $conditiongrade) {
|
|
||||||
$ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true);
|
|
||||||
}
|
|
||||||
foreach ($conditionsfield as $conditionfield) {
|
|
||||||
$ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
|
|
||||||
}
|
|
||||||
// Direct calls to condition_info_section methods do not reset the course cache. Do it manually.
|
|
||||||
rebuild_course_cache($course->id, true);
|
rebuild_course_cache($course->id, true);
|
||||||
|
$sectiondb = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
|
||||||
|
|
||||||
// Create and enrol a student.
|
// Create and enrol a student.
|
||||||
$studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
|
$studentrole = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
|
||||||
|
@ -100,14 +90,8 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($sectiondb->visible, $si->visible);
|
$this->assertEquals($sectiondb->visible, $si->visible);
|
||||||
$this->assertEquals($sectiondb->summary, $si->summary);
|
$this->assertEquals($sectiondb->summary, $si->summary);
|
||||||
$this->assertEquals($sectiondb->summaryformat, $si->summaryformat);
|
$this->assertEquals($sectiondb->summaryformat, $si->summaryformat);
|
||||||
$this->assertEquals($sectiondb->showavailability, $si->showavailability);
|
|
||||||
$this->assertEquals($sectiondb->availablefrom, $si->availablefrom);
|
|
||||||
$this->assertEquals($sectiondb->availableuntil, $si->availableuntil);
|
|
||||||
$this->assertEquals($sectiondb->groupingid, $si->groupingid);
|
|
||||||
$this->assertEquals($sectiondb->sequence, $si->sequence); // Since this section does not contain invalid modules.
|
$this->assertEquals($sectiondb->sequence, $si->sequence); // Since this section does not contain invalid modules.
|
||||||
$this->assertEquals($conditionscompletion, $si->conditionscompletion);
|
$this->assertEquals($availability, $si->availability);
|
||||||
$this->assertEquals($conditionsgrade, $si->conditionsgrade);
|
|
||||||
$this->assertEquals($conditionsfield, $si->conditionsfield);
|
|
||||||
|
|
||||||
// Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
|
// Dynamic fields, just test that they can be retrieved (must be carefully tested in each activity type).
|
||||||
$this->assertEquals(0, $si->available);
|
$this->assertEquals(0, $si->available);
|
||||||
|
@ -142,31 +126,18 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
array('course' => $course->id),
|
array('course' => $course->id),
|
||||||
array('completion' => 1));
|
array('completion' => 1));
|
||||||
|
|
||||||
// Generate the module and add availability conditions.
|
// Generate module and add availability conditions.
|
||||||
$conditionscompletion = array($prereqforum->cmid => COMPLETION_COMPLETE);
|
$availability = '{"op":"&","showc":[true,true,true],"c":[' .
|
||||||
$conditionsgrade = array(666 => (object)array('min' => 0.4, 'max' => null, 'name' => '!missing'));
|
'{"type":"completion","cm":' . $prereqforum->cmid . ',"e":"' .
|
||||||
$conditionsfield = array('email' => (object)array(
|
COMPLETION_COMPLETE . '"},' .
|
||||||
'fieldname' => 'email',
|
'{"type":"grade","id":666,"min":0.4},' .
|
||||||
'operator' => 'contains',
|
'{"type":"profile","op":"contains","sf":"email","v":"test"}' .
|
||||||
'value' => 'test'
|
']}';
|
||||||
));
|
|
||||||
$assign = $this->getDataGenerator()->create_module('assign',
|
$assign = $this->getDataGenerator()->create_module('assign',
|
||||||
array('course' => $course->id),
|
array('course' => $course->id),
|
||||||
array('idnumber' => 123,
|
array('idnumber' => 123,
|
||||||
'groupmode' => VISIBLEGROUPS,
|
'groupmode' => VISIBLEGROUPS,
|
||||||
'availablefrom' => time() + 3600,
|
'availability' => $availability));
|
||||||
'availableuntil' => time() + 5*3600));
|
|
||||||
$ci = new condition_info((object)array('id' => $assign->cmid), CONDITION_MISSING_EVERYTHING);
|
|
||||||
foreach ($conditionscompletion as $cmid => $requiredcompletion) {
|
|
||||||
$ci->add_completion_condition($cmid, $requiredcompletion);
|
|
||||||
}
|
|
||||||
foreach ($conditionsgrade as $gradeid => $conditiongrade) {
|
|
||||||
$ci->add_grade_condition($gradeid, $conditiongrade->min, $conditiongrade->max, true);
|
|
||||||
}
|
|
||||||
foreach ($conditionsfield as $conditionfield) {
|
|
||||||
$ci->add_user_field_condition($conditionfield->fieldname, $conditionfield->operator, $conditionfield->value);
|
|
||||||
}
|
|
||||||
// Direct access to condition_info functions does not reset course cache, do it manually.
|
|
||||||
rebuild_course_cache($course->id, true);
|
rebuild_course_cache($course->id, true);
|
||||||
|
|
||||||
// Retrieve all related records from DB.
|
// Retrieve all related records from DB.
|
||||||
|
@ -216,9 +187,6 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber);
|
$this->assertEquals($moduledb->completiongradeitemnumber, $cm->completiongradeitemnumber);
|
||||||
$this->assertEquals($moduledb->completionview, $cm->completionview);
|
$this->assertEquals($moduledb->completionview, $cm->completionview);
|
||||||
$this->assertEquals($moduledb->completionexpected, $cm->completionexpected);
|
$this->assertEquals($moduledb->completionexpected, $cm->completionexpected);
|
||||||
$this->assertEquals($moduledb->availablefrom, $cm->availablefrom);
|
|
||||||
$this->assertEquals($moduledb->availableuntil, $cm->availableuntil);
|
|
||||||
$this->assertEquals($moduledb->showavailability, $cm->showavailability);
|
|
||||||
$this->assertEquals($moduledb->showdescription, $cm->showdescription);
|
$this->assertEquals($moduledb->showdescription, $cm->showdescription);
|
||||||
$this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info.
|
$this->assertEquals(null, $cm->extra); // Deprecated field. Used in module types that don't return cached_cm_info.
|
||||||
$this->assertEquals($cachedcminfo->icon, $cm->icon);
|
$this->assertEquals($cachedcminfo->icon, $cm->icon);
|
||||||
|
@ -228,9 +196,7 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($cachedcminfo->name, $cm->name);
|
$this->assertEquals($cachedcminfo->name, $cm->name);
|
||||||
$this->assertEquals($sectiondb->section, $cm->sectionnum);
|
$this->assertEquals($sectiondb->section, $cm->sectionnum);
|
||||||
$this->assertEquals($moduledb->section, $cm->section);
|
$this->assertEquals($moduledb->section, $cm->section);
|
||||||
$this->assertEquals($conditionscompletion, $cm->conditionscompletion);
|
$this->assertEquals($availability, $cm->availability);
|
||||||
$this->assertEquals($conditionsgrade, $cm->conditionsgrade);
|
|
||||||
$this->assertEquals($conditionsfield, $cm->conditionsfield);
|
|
||||||
$this->assertEquals(context_module::instance($moduledb->id), $cm->context);
|
$this->assertEquals(context_module::instance($moduledb->id), $cm->context);
|
||||||
$this->assertEquals($modnamessingular['assign'], $cm->modfullname);
|
$this->assertEquals($modnamessingular['assign'], $cm->modfullname);
|
||||||
$this->assertEquals($modnamesplural['assign'], $cm->modplural);
|
$this->assertEquals($modnamesplural['assign'], $cm->modplural);
|
||||||
|
@ -553,12 +519,14 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$course = $this->getDataGenerator()->create_course();
|
$course = $this->getDataGenerator()->create_course();
|
||||||
// 1. Create an activity that is currently unavailable and hidden entirely (for students).
|
// 1. Create an activity that is currently unavailable and hidden entirely (for students).
|
||||||
$assign1 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
|
$assign1 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
|
||||||
array('availablefrom' => time() + 10000, 'showavailability' => CONDITION_STUDENTVIEW_HIDE));
|
array('availability' => '{"op":"|","show":false,"c":[' .
|
||||||
|
'{"type":"date","d":">=","t":' . (time() + 10000) . '}]}'));
|
||||||
// 2. Create an activity that is currently available.
|
// 2. Create an activity that is currently available.
|
||||||
$assign2 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
|
$assign2 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id));
|
||||||
// 3. Create an activity that is currently unavailable and set to be greyed out.
|
// 3. Create an activity that is currently unavailable and set to be greyed out.
|
||||||
$assign3 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
|
$assign3 = $this->getDataGenerator()->create_module('assign', array('course'=>$course->id),
|
||||||
array('availablefrom' => time() + 10000, 'showavailability' => CONDITION_STUDENTVIEW_SHOW));
|
array('availability' => '{"op":"|","show":true,"c":[' .
|
||||||
|
'{"type":"date","d":">=","t":' . (time() + 10000) . '}]}'));
|
||||||
|
|
||||||
// Set up a teacher.
|
// Set up a teacher.
|
||||||
$coursecontext = context_course::instance($course->id);
|
$coursecontext = context_course::instance($course->id);
|
||||||
|
@ -568,39 +536,52 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
|
|
||||||
// If conditional availability is disabled the activity will always be unrestricted.
|
// If conditional availability is disabled the activity will always be unrestricted.
|
||||||
$CFG->enableavailability = false;
|
$CFG->enableavailability = false;
|
||||||
$cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
$cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
||||||
$this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
|
$this->assertTrue($cm->uservisible);
|
||||||
|
|
||||||
|
// Test deprecated function.
|
||||||
|
$this->assertFalse($cm->is_user_access_restricted_by_conditional_access());
|
||||||
|
$this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
|
||||||
|
phpunit_util::reset_debugging();
|
||||||
|
|
||||||
// Turn on conditional availability and reset the get_fast_modinfo cache.
|
// Turn on conditional availability and reset the get_fast_modinfo cache.
|
||||||
$CFG->enableavailability = true;
|
$CFG->enableavailability = true;
|
||||||
get_fast_modinfo($course, 0, true);
|
get_fast_modinfo($course, 0, true);
|
||||||
|
|
||||||
// The unavailable, hidden entirely activity should now be restricted.
|
// The unavailable, hidden entirely activity should now be restricted.
|
||||||
$cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
$cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
||||||
$this->assertFalse($cm_info->available);
|
$this->assertFalse($cm->uservisible);
|
||||||
$this->assertEquals(CONDITION_STUDENTVIEW_HIDE, $cm_info->showavailability);
|
$this->assertFalse($cm->available);
|
||||||
$this->assertTrue($cm_info->is_user_access_restricted_by_conditional_access());
|
$this->assertEquals('', $cm->availableinfo);
|
||||||
|
|
||||||
|
// Test deprecated function.
|
||||||
|
$this->assertTrue($cm->is_user_access_restricted_by_conditional_access());
|
||||||
|
$this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
|
||||||
|
phpunit_util::reset_debugging();
|
||||||
|
|
||||||
// If the activity is available it should not be restricted.
|
// If the activity is available it should not be restricted.
|
||||||
$cm_info = get_fast_modinfo($course)->instances['assign'][$assign2->id];
|
$cm = get_fast_modinfo($course)->instances['assign'][$assign2->id];
|
||||||
$this->assertTrue($cm_info->available);
|
$this->assertTrue($cm->uservisible);
|
||||||
$this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
|
$this->assertTrue($cm->available);
|
||||||
|
|
||||||
// If the activity is unavailable and set to be greyed out it should not be restricted.
|
// If the activity is unavailable and set to be greyed out it should not be restricted.
|
||||||
$cm_info = get_fast_modinfo($course)->instances['assign'][$assign3->id];
|
$cm = get_fast_modinfo($course)->instances['assign'][$assign3->id];
|
||||||
$this->assertFalse($cm_info->available);
|
$this->assertFalse($cm->uservisible);
|
||||||
$this->assertEquals(CONDITION_STUDENTVIEW_SHOW, $cm_info->showavailability);
|
$this->assertFalse($cm->available);
|
||||||
$this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
|
$this->assertNotEquals('', (string)$cm->availableinfo);
|
||||||
|
|
||||||
|
// Test deprecated function (weird case, it actually checks visibility).
|
||||||
|
$this->assertFalse($cm->is_user_access_restricted_by_conditional_access());
|
||||||
|
$this->assertEquals(1, count(phpunit_util::get_debugging_messages()));
|
||||||
|
phpunit_util::reset_debugging();
|
||||||
|
|
||||||
// If the activity is unavailable and set to be hidden entirely its restricted unless user has 'moodle/course:viewhiddenactivities'.
|
// If the activity is unavailable and set to be hidden entirely its restricted unless user has 'moodle/course:viewhiddenactivities'.
|
||||||
// Switch to a teacher and reload the context info.
|
// Switch to a teacher and reload the context info.
|
||||||
$this->setUser($teacher);
|
$this->setUser($teacher);
|
||||||
$cm_info = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
|
||||||
$this->assertFalse($cm_info->available);
|
|
||||||
$this->assertEquals(CONDITION_STUDENTVIEW_HIDE, $cm_info->showavailability);
|
|
||||||
|
|
||||||
$this->assertTrue(has_capability('moodle/course:viewhiddenactivities', $coursecontext));
|
$this->assertTrue(has_capability('moodle/course:viewhiddenactivities', $coursecontext));
|
||||||
$this->assertFalse($cm_info->is_user_access_restricted_by_conditional_access());
|
$cm = get_fast_modinfo($course)->instances['assign'][$assign1->id];
|
||||||
|
$this->assertTrue($cm->uservisible);
|
||||||
|
$this->assertFalse($cm->available);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_is_user_access_restricted_by_capability() {
|
public function test_is_user_access_restricted_by_capability() {
|
||||||
|
@ -718,10 +699,12 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
'idnumber' => '12345',
|
'idnumber' => '12345',
|
||||||
'showdescription' => true
|
'showdescription' => true
|
||||||
));
|
));
|
||||||
|
// Pick a small valid availability value to use.
|
||||||
|
$availabilityvalue = '{"op":"|","show":true,"c":[{"type":"date","d":">=","t":4}]}';
|
||||||
$mods[2] = $this->getDataGenerator()->create_module('book',
|
$mods[2] = $this->getDataGenerator()->create_module('book',
|
||||||
array('course' => $course->id,
|
array('course' => $course->id,
|
||||||
'indent' => 5,
|
'indent' => 5,
|
||||||
'showavailability' => true,
|
'availability' => $availabilityvalue,
|
||||||
'showdescription' => false,
|
'showdescription' => false,
|
||||||
'completion' => true,
|
'completion' => true,
|
||||||
'completionview' => true,
|
'completionview' => true,
|
||||||
|
@ -730,10 +713,8 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$mods[3] = $this->getDataGenerator()->create_module('forum',
|
$mods[3] = $this->getDataGenerator()->create_module('forum',
|
||||||
array('course' => $course->id,
|
array('course' => $course->id,
|
||||||
'visible' => 0,
|
'visible' => 0,
|
||||||
'availablefrom' => time() - 1000,
|
|
||||||
'availableto' => time() + 1000,
|
|
||||||
'groupmode' => 1,
|
'groupmode' => 1,
|
||||||
'showavailability' => false));
|
'availability' => null));
|
||||||
$mods[4] = $this->getDataGenerator()->create_module('forum',
|
$mods[4] = $this->getDataGenerator()->create_module('forum',
|
||||||
array('course' => $course->id,
|
array('course' => $course->id,
|
||||||
'groupmembersonly' => true,
|
'groupmembersonly' => true,
|
||||||
|
@ -805,4 +786,120 @@ class core_modinfolib_testcase extends advanced_testcase {
|
||||||
$this->assertEquals($cm2, $cminfo->get_course_module_record(true));
|
$this->assertEquals($cm2, $cminfo->get_course_module_record(true));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the availability property that has been added to course modules
|
||||||
|
* and sections (just to see that it is correctly saved and accessed).
|
||||||
|
*/
|
||||||
|
public function test_availability_property() {
|
||||||
|
global $DB, $CFG;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
// Create a course with two modules and three sections.
|
||||||
|
$course = $this->getDataGenerator()->create_course(
|
||||||
|
array('format' => 'topics', 'numsections' => 3),
|
||||||
|
array('createsections' => true));
|
||||||
|
$forum = $this->getDataGenerator()->create_module('forum',
|
||||||
|
array('course' => $course->id));
|
||||||
|
$forum2 = $this->getDataGenerator()->create_module('forum',
|
||||||
|
array('course' => $course->id));
|
||||||
|
|
||||||
|
// Get modinfo. Check that availability is null for both cm and sections.
|
||||||
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
|
$cm = $modinfo->get_cm($forum->cmid);
|
||||||
|
$this->assertNull($cm->availability);
|
||||||
|
$section = $modinfo->get_section_info(1, MUST_EXIST);
|
||||||
|
$this->assertNull($section->availability);
|
||||||
|
|
||||||
|
// Update availability for cm and section in database.
|
||||||
|
$DB->set_field('course_modules', 'availability', '{}', array('id' => $cm->id));
|
||||||
|
$DB->set_field('course_sections', 'availability', '{}', array('id' => $section->id));
|
||||||
|
|
||||||
|
// Clear cache and get modinfo again.
|
||||||
|
rebuild_course_cache($course->id, true);
|
||||||
|
get_fast_modinfo(0, 0, true);
|
||||||
|
$modinfo = get_fast_modinfo($course->id);
|
||||||
|
|
||||||
|
// Check values that were changed.
|
||||||
|
$cm = $modinfo->get_cm($forum->cmid);
|
||||||
|
$this->assertEquals('{}', $cm->availability);
|
||||||
|
$section = $modinfo->get_section_info(1, MUST_EXIST);
|
||||||
|
$this->assertEquals('{}', $section->availability);
|
||||||
|
|
||||||
|
// Check other values are still null.
|
||||||
|
$cm = $modinfo->get_cm($forum2->cmid);
|
||||||
|
$this->assertNull($cm->availability);
|
||||||
|
$section = $modinfo->get_section_info(2, MUST_EXIST);
|
||||||
|
$this->assertNull($section->availability);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some properties have been deprecated from both the section and module
|
||||||
|
* classes. This checks they still work (and show warnings).
|
||||||
|
*/
|
||||||
|
public function test_availability_deprecations() {
|
||||||
|
global $CFG, $DB;
|
||||||
|
$this->resetAfterTest();
|
||||||
|
$CFG->enableavailability = true;
|
||||||
|
|
||||||
|
// Create a course with two modules. The modules are not available to
|
||||||
|
// users. One of them is set to show this information, the other is not.
|
||||||
|
// Same setup for sections.
|
||||||
|
$generator = $this->getDataGenerator();
|
||||||
|
$course = $this->getDataGenerator()->create_course(
|
||||||
|
array('format' => 'topics', 'numsections' => 2),
|
||||||
|
array('createsections' => true));
|
||||||
|
$show = '{"op":"|","show":true,"c":[{"type":"date","d":"<","t":1395857332}]}';
|
||||||
|
$noshow = '{"op":"|","show":false,"c":[{"type":"date","d":"<","t":1395857332}]}';
|
||||||
|
$forum1 = $generator->create_module('forum',
|
||||||
|
array('course' => $course->id, 'availability' => $show));
|
||||||
|
$forum2 = $generator->create_module('forum',
|
||||||
|
array('course' => $course->id, 'availability' => $noshow));
|
||||||
|
$DB->set_field('course_sections', 'availability',
|
||||||
|
$show, array('course' => $course->id, 'section' => 1));
|
||||||
|
$DB->set_field('course_sections', 'availability',
|
||||||
|
$noshow, array('course' => $course->id, 'section' => 2));
|
||||||
|
|
||||||
|
// Create a user without special permissions.
|
||||||
|
$user = $generator->create_user();
|
||||||
|
$generator->enrol_user($user->id, $course->id);
|
||||||
|
|
||||||
|
// Get modinfo and cm objects.
|
||||||
|
$modinfo = get_fast_modinfo($course, $user->id);
|
||||||
|
$cm1 = $modinfo->get_cm($forum1->cmid);
|
||||||
|
$cm2 = $modinfo->get_cm($forum2->cmid);
|
||||||
|
|
||||||
|
// Check the showavailability property.
|
||||||
|
$this->assertEquals(1, $cm1->showavailability);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
$this->assertEquals(0, $cm2->showavailability);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
|
||||||
|
// Check the dates (these always return 0 now).
|
||||||
|
$this->assertEquals(0, $cm1->availablefrom);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
$this->assertEquals(0, $cm1->availableuntil);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
|
||||||
|
// Get section objects.
|
||||||
|
$section1 = $modinfo->get_section_info(1);
|
||||||
|
$section2 = $modinfo->get_section_info(2);
|
||||||
|
|
||||||
|
// Check showavailability.
|
||||||
|
$this->assertEquals(1, $section1->showavailability);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
$this->assertEquals(0, $section2->showavailability);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
|
||||||
|
// Check dates (zero).
|
||||||
|
$this->assertEquals(0, $section1->availablefrom);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
$this->assertEquals(0, $section1->availableuntil);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
|
||||||
|
// Check groupingid (zero).
|
||||||
|
$this->assertEquals(0, $section1->groupingid);
|
||||||
|
$this->assertDebuggingCalled(null, DEBUG_DEVELOPER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,32 @@ DEPRECATIONS:
|
||||||
* mod_feedback\event\instances_list_viewed has been deprecated. Please use mod_feedback\event\course_module_instance_list_viewed instead.
|
* mod_feedback\event\instances_list_viewed has been deprecated. Please use mod_feedback\event\course_module_instance_list_viewed instead.
|
||||||
* mod_page\event\instances_list_viewed has been deprecated. Please use mod_page\event\course_module_instance_list_viewed instead.
|
* mod_page\event\instances_list_viewed has been deprecated. Please use mod_page\event\course_module_instance_list_viewed instead.
|
||||||
* The constants FRONTPAGECOURSELIST, FRONTPAGETOPICONLY & FRONTPAGECOURSELIMIT have been removed.
|
* The constants FRONTPAGECOURSELIST, FRONTPAGETOPICONLY & FRONTPAGECOURSELIMIT have been removed.
|
||||||
|
* Conditional availability API has moved and changed. The condition_info class is
|
||||||
|
replaced by \core_availability\info_module, and condition_info_section by
|
||||||
|
\core_availability\info_section. (Code that uses the old classes will generally
|
||||||
|
still work.)
|
||||||
|
* coursemodule_visible_for_user() has been deprecated but still works - replaced
|
||||||
|
by a new static function \core_availability\info_module::is_user_visible()
|
||||||
|
* cm_info::is_user_access_restricted_by_conditional_access has been deprecated
|
||||||
|
but still works (it has never done what its name suggests, and is
|
||||||
|
unnecessary).
|
||||||
|
* cm_info and section_info property showavailability has been deprecated, but
|
||||||
|
still works (with the caveat that this information is now per-user).
|
||||||
|
* cm_info and section_info properties availablefrom and availableuntil have been
|
||||||
|
deprecated and always return zero (underlying data doesn't have these values).
|
||||||
|
* section_info property groupingid has been deprecated and always returns zero,
|
||||||
|
same deal.
|
||||||
* Various cm_info methods have been deprecated in favour of their read-only properties (get_url(), get_content(), get_extra_classes(),
|
* Various cm_info methods have been deprecated in favour of their read-only properties (get_url(), get_content(), get_extra_classes(),
|
||||||
get_on_click(), get_custom_data(), get_after_link, get_after_edit_icons)
|
get_on_click(), get_custom_data(), get_after_link, get_after_edit_icons)
|
||||||
* The ajaxenabled function has been deprecated and always returns true. All code should be fully functional in Javascript.
|
* The ajaxenabled function has been deprecated and always returns true. All code should be fully functional in Javascript.
|
||||||
* count_login_failures() has been deprecated, use user_count_login_failures() instead. Refer MDL-42891 for details.
|
* count_login_failures() has been deprecated, use user_count_login_failures() instead. Refer MDL-42891 for details.
|
||||||
|
|
||||||
|
Conditional availability (activities and sections):
|
||||||
|
* New conditional availability API in /availability, including new availability
|
||||||
|
condition plugins in /availability/condition. The new API is very similar with
|
||||||
|
regard to checking availability, but any code that modifies availability settings
|
||||||
|
for an activity or section is likely to need substantial changes.
|
||||||
|
|
||||||
YUI:
|
YUI:
|
||||||
* The lightbox attribute for moodle-core-notification-dialogue has been
|
* The lightbox attribute for moodle-core-notification-dialogue has been
|
||||||
deprecated and replaced by the modal attribute. This was actually
|
deprecated and replaced by the modal attribute. This was actually
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue