Hi,
The fact of an activity being available to a student is not something concrete that 'happens' (and could have a timestamp attached to it) like when a user is assigned a grade. It's just a consequence of the current value of other data.
For example, say you use the date option set to 11:00. The server doesn't suddenly notice - oh it's 11:00, I'll now go and unlock those activities. Instead, every time a user logs onto the course, something in the server goes, oh what time is it currently, not 11:00 yet, ok that particular activity isn't open at the moment. The activity might be 'closed' again with similarly nothing happening. For example, if you were to send the server back in time, it would be closed again. (Or, perhaps more realistically, somebody could change the activity settings to put the required time forward.)
An activity becoming available can depend on three things at present:
- An 'available from' date in the activity settings. This is simple, you can find it from get_fast_modinfo in the code.
- Another activity becoming complete (or not complete, or complete-with-pass-mark, etc). The most recent change in completion state for each activity for a user is stored with timestamp, so you could potentially find this - look at the code for the activity completion report if you want to.
- A grade changing (from not set to set, or from low to high, or vice versa). Grade history is stored - unlike completion it includes previous changes not just the current value - and timestamped, so you could potentially find this too.
Again there's information in get_fast_modinfo if you want to know precisely which conditions and/or grades an activity depends on, but implementing to work out when something first became available to a user, generically, is impossible. For example, if it depends on activity completion, then they might complete and uncomplete the required activity several times, and only the last timestamp will be saved. Or if it depends on a simple date, somebody might have changed the activity settings since they first saw it, and the old value isn't available.
From Moodle 2.3, activity availability can also depend on whether the section it's in is available. The section has the same kind of conditions possible. This makes it even more impossible, in the generic case, to work out exactly when activity X became available to user Y.
Forgot to say that in addition to the above, activities can also be unavailable/available because a teacher has clicked the 'eye' icon to manually hide/show them.
Advice: What do you really need to do? If the certificates are always available based on when some other activity X was marked completed, and if you know because of your setup that it's not possible/likely for X to be UNmarked completed, then you can get the data for that. Same if they always depend on a grade.
Better advice: Why not save yourself a headache and define the certificate as 'awarded' only when the student first looks at it? You could just store that date somewhere (in a new table or field). If necessary, advise students to click on the certificate as soon as they (complete the final assessment / whatever it is) so they get the right date even if they don't want to print it out that instant. Job done! And reliably, to boot.
Terrible advice: If you really, really, really want this to work the way you probably originally wanted, it might be possible to do something on cron, e.g. every hour to check whether the activity is available to each student (who didn't already get it). This is going to be horribly slow so make sure you have it as an option that only applies to certain certificates where you need it. It will be infeasible for large systems as checking conditions for other users is not efficient - it might take, say, 0.1 seconds per user, so if you have say 1,800 students on a course, that's 3 minutes just for the one course. Only needs 10 large courses using this and you're taking 30 minutes to run this cron task and slowing down all your forum emails and everything. Not a good look.
--sam