mdjnelson / moodle-mod_customcert

Enables the creation of dynamically generated certificates with complete customisation via the web browser.
https://moodle.org/plugins/mod_customcert
GNU General Public License v3.0
89 stars 155 forks source link

`date`, `daterange`, `gradeitemname` and `grade` elements do not restore when linked to a manual grade item #582

Closed matthewhilton closed 3 months ago

matthewhilton commented 9 months ago

The date element has the ability to link a grade item, e.g. show date when grade item was graded.

The way this is stored is in the json as something like: { "dateitem":"gradeitem:12345" ...}

However when you attempt to restore a customcert instance, it gives an error

Adhoc task failed: core\task\asynchronous_restore_task,Error reading from database ERROR:  invalid input syntax for type bigint: "gradeitem:793169"
SELECT * FROM mdl_backup_ids_temp WHERE backupid = $1 AND itemname = $2 AND itemid = $3
[array (
  0 => '5f407911d3c291366a30b99021f841f8',
  1 => 'course_module',
  2 => 'gradeitem:793169',
)]

This is because itemid is an integer, but its trying to search for a string.

Happens when using backup/restore or course copy

This comes from this line https://github.com/mdjnelson/moodle-mod_customcert/blob/c3942c3b756df0b2a894c6b041be3799c0d749bc/element/date/classes/element.php#L291

Likely related to #149

danowar2k commented 6 months ago

This error will happen at least with elements of types "date" and "grade". The reason for this is that both of these store gradeitem in the data JSON. The select dropdown for the gradeitems can contain activities (which have integer IDs), but also other "gradeitems" (which are written as "gradeitem": "gradeitem:XYZ", where XYZ is an integer).

Backups correctly stores the JSON, but then the restore process for "date" and "grade" doesn't do anything to extract the integer from that string, see https://github.com/mdjnelson/moodle-mod_customcert/blob/22a84c5703e3e26d06d3ce5a1568178206e97c32/element/date/classes/element.php#L326-L334 (for date) and https://github.com/mdjnelson/moodle-mod_customcert/blob/22a84c5703e3e26d06d3ce5a1568178206e97c32/element/grade/classes/element.php#L193-L201 (for grade).

The functions assume that $gradeitem->gradeitem is an integer, which "gradeitem:XYZ" is not. Before looking for the appropriate ID in the backup table, it should extract the integer.

~What does "gradeitem:XYZ" represent? Is the gradeitem something that's even restored with a course or a customcert activity? Or is that something that should be ignored when restoring or even already when backing up?~

I've just looked at the backup file of the course that couldn't be restored, the grade items are backed up, I've found the item with ID XYZ. So the restore probably only needs to respect that the $gradeitem->gradeitem could contain the string, check for it, and if it finds it, act accordingly.

mdjnelson commented 5 months ago

Anyone willing to do a PR? :)

mdjnelson commented 5 months ago

Also, thanks for your detailed research into this.

mdjnelson commented 4 months ago

This took me down a rabbit hole and ended up being way more work than I thought. Fortunately it is done, I think. Pushing fix soon.

mdjnelson commented 3 months ago

Fixed. Pushed to 4.2 and 4.1.

mdjnelson commented 3 months ago

Eh, seems I already knew about this but did not get round to fixing it, whoops. See https://github.com/mdjnelson/moodle-mod_customcert/issues/347.