Adding availability conditions to a course module

Adding availability conditions to a course module

by Michael Hughes -
Number of replies: 3
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

We have a plugin that automates the creation of assignments with dependencies (you have to get 40% otherwise you have resubmit, and the re-attempts stuff doesn't fulfill their requirements as each resubmission attracts additional penalties: 10% for 1st resubmittion, 40% for second, 100% for third).

Previously it was simple in the PHP code to do this:

$ci = new \conditioninfo($newcm, CONDITION_MISSING_EVERYTHING);
$ci->add_grade_condition($previous_activity_cm_grade_item->id, null, 40);

Now everything has moved to the fancy Javascript interface for setting up interactively, but all of the PHP functions to do this has (as far as I can see) been removed or relegated for legacy handling.

Is it really a case of having to do it all in JSON?

Average of ratings: -
In reply to Michael Hughes

Re: Adding availability conditions to a course module

by Michael Hughes -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

This is what I eventually came up with to make it work in exactly the same way as the above code:

$gconditionjson = \availability_grade\condition::get_json($previous_activity_gradeitem->id, null, 40);
$treejson = \core_availability\tree::get_root_json(
    array($gconditionjson), 
        \core_availability\tree::OP_AND,
        array(false)
    );
$DB->set_field('course_modules', 'availability', json_encode($treejson), array('id' => $newcm->id));

hmm...is all I can say to this smile

Average of ratings: Useful (1)
In reply to Michael Hughes

Re: Adding availability conditions to a course module

by sam marshall -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

It's not surprising the code is a little longer because the new API includes support for infinitely more complex sets of restrictions...

That said, I don't think the way you've done it is quite 'perfect'. The question here is, are you doing this only on newly-created activities (so you know for sure that yours are the only conditions) - if so then you can make the code simpler. If not then the approach above will work, but doing it perfectly would be more complex still, unless I've misunderstood something.

To explain why: your code works by creating a new root tree, with the existing tree as one branch, and a new condition as the other branch. This works in general but (for good reasons too complex to explain here) the 'show' options are only available at the root level, which might cause a change in behaviour. The perfect logic would be:

a) If the top-level condition is currently AND or NOT OR, then add your condition (or a negative version of it) directly to the existing top-level tree.

b) If the top-level condition is currently OR or NOT AND, then do it like you have done (making sure to correctly transfer the show option to the subtree).

(Also just to note - after doing any of this then you need to rebuild course cache.)

It would be possible to add PHP functions to incorporate some of this logic, i.e. when you want to add an AND condition to the root level of a tree, which is probably the most common case of a programmatic modification. This wasn't implemented already because nothing in Moodle core needs it (the previous API was needed by Moodle core) and it is possible to achieve by manually manipulating the JSON array, as you have.

--sam

In reply to sam marshall

Re: Adding availability conditions to a course module

by Michael Hughes -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

I this case the condition is set one an activity just after its been created, as it's part of an scripted process to create re-submission activities (and they need to have their own grade items).