Open JomacInc opened 4 months ago
I am not a moodle dev (I am a php dev though), but I did work out that I could solve the issue by adding the below to lib.php Is there a better way to do this and if not, can it be looked at as an enhancement so I don't have to mod the plugin source?
function subcourse_cm_info_dynamic(cm_info $cm) {
global $USER, $DB;
$refcourse = $DB->get_field('subcourse', 'refcourse', ['id' => $cm->instance], IGNORE_MISSING);
if( !empty($refcourse) ) {
$context = get_context_instance(CONTEXT_COURSE, $refcourse);
if( !is_enrolled($context, $USER->id) ) {
$cm->set_available(false, 0, 'You are not enrolled in this unit');
}
}
}
Hey @JomacInc - best way would be to fire through a pull request with the change - we'd need a setting somewhere to allow it to be enabled/disabled (some sites will want all courses to show.) - but that could be a site wide setting in the settings.php file rather than needing to set it inside each subcourse. Also we'd need that dynamic function to do some better caching - it's called in a bunch of places and so doing a db call (get_field) on each run is probably not ideal - take a look at some of the exisitng cm_info_dynamic functions in other modules and see if you can do the work without needing to run a db call to get teh $refcourse. - maybe even just getting the courseid from the cm_info might be better.
Thanks @danmarsden - as mentioned, Moodle dev is above my paygrade at the moment - I just don't have the time/capacity to learn the in's and out's of mod creation. I was worried about caching because I assumed needing the current user would cause issues (or is caching user specific?).
I'm hoping it can be a feature request to be added in properly by someone who knows how to do it.
thanks @JomacInc - the code you've added above is pretty close
Someone might notice this in the tracker and think "I need this too" and use your example and our discussion here to send through a PR.
thanks again!
Thanks @danmarsden , I adjust the subcourse_get_coursemodule_info function as below to include the refcourse id into customdata so I don't need to do a db call and updated my function to use it.
function subcourse_get_coursemodule_info($coursemodule) {
global $CFG, $DB;
$subcourse = $DB->get_record('subcourse', ['id' => $coursemodule->instance],
'id, refcourse, name, intro, introformat, instantredirect, blankwindow, coursepageprintgrade, coursepageprintprogress');
if (!$subcourse) {
return null;
}
$info = new cached_cm_info();
$info->name = $subcourse->name;
$info->customdata = (object) [
'coursepageprintgrade' => $subcourse->coursepageprintgrade,
'coursepageprintprogress' => $subcourse->coursepageprintprogress,
'refcourse' => $subcourse->refcourse,
];
if ($subcourse->instantredirect && $subcourse->blankwindow) {
$url = new moodle_url('/mod/subcourse/view.php', ['id' => $coursemodule->id, 'isblankwindow' => 1]);
$info->onclick = "window.open('".$url->out(false)."'); return false;";
}
if ($coursemodule->showdescription) {
// Set content from intro and introformat. Filters are disabled because we filter with format_text at display time.
$info->content = format_module_intro('subcourse', $subcourse, $coursemodule->id, false);
}
return $info;
}
function subcourse_cm_info_dynamic(cm_info $cm) {
global $USER;
if( !empty($cm->customdata->refcourse) ) {
$context = get_context_instance(CONTEXT_COURSE, $cm->customdata->refcourse);
if( !is_enrolled($context, $USER->id) ) {
$cm->set_available(false, 0, 'You are not enrolled in this unit');
}
}
}
The only question now is, do I have to worry about my changes being wiped out by an update without my knowledge?
Is there a way we can have the block only shown if the current user is actually enrolled in the sub-course? We have a range of sub-courses under a master course, but students will be enrolled in some of them (user specific electives).