jpahullo / moodle-tool_mergeusers

Merge users script for Moodle
https://moodle.org/plugins/view.php?plugin=tool_mergeusers
22 stars 50 forks source link

'Error writing to database". Column 'timemodified' cannot be null #121

Open tommysghid opened 7 years ago

tommysghid commented 7 years ago

We have Moodle 3.0.4 We just upgraded the Merge Users Tool 1.13 for Moodle 2.2-3.2 (Build: 2016120100) 2016113000. Now we get a random error that I have never had before and cannot find any information on. Any help in fixing this would be great:

Exception thrown when merging: 'Error writing to database". Column 'timemodified' cannot be null Trace:

0 /var/www/html/moodle/lib/dml/mysqli_native_moodle_database.php(1392): moodle_database->query_end(false)

1 /var/www/html/moodle/lib/dml/mysqli_native_moodle_database.php(1424): mysqli_native_moodle_database->update_record_raw('coursemodules...', Array, false)

2 /var/www/html/moodle/lib/completionlib.php(1007): mysqli_native_moodle_database->update_record('coursemodules...', Object(stdClass))

3 /var/www/html/moodle/lib/completionlib.php(577): completion_info->internal_set_data(Object(stdClass), Object(stdClass))

4 /var/www/html/moodle/lib/completionlib.php(1249): completion_info->update_state(Object(stdClass), 0, '372829')

5 /var/www/html/moodle/lib/grade/grade_grade.php(1107): completion_info->inform_grade_changed(Object(stdClass), Object(grade_item), Object(grade_grade), false)

6 /var/www/html/moodle/lib/grade/grade_object.php(266): grade_grade->notify_changed(false)

7 /var/www/html/moodle/lib/grade/grade_grade.php(1021): grade_object->update('mod/quiz')

8 /var/www/html/moodle/lib/grade/grade_item.php(1857): grade_grade->update('mod/quiz')

9 /var/www/html/moodle/lib/gradelib.php(284): grade_item->update_raw_grade('372829', NULL, 'mod/quiz', false, '0', '350662', NULL, NULL, Object(grade_grade))

10 /var/www/html/moodle/mod/quiz/lib.php(800): grade_update('mod/quiz', '10', 'mod', 'quiz', '7', 0, Object(stdClass), Array)

11 /var/www/html/moodle/mod/quiz/lib.php(692): quiz_grade_item_update(Object(stdClass), Object(stdClass))

12 /var/www/html/moodle/lib/gradelib.php(1219): quiz_update_grades(Object(stdClass), '372829')

13 /var/www/html/moodle/admin/tool/mergeusers/lib/mergeusertool.php(495): grade_update_mod_grades(Object(stdClass), '372829')

14 /var/www/html/moodle/admin/tool/mergeusers/lib/mergeusertool.php(291): MergeUserTool->updateGrades('372829', '279237')

15 /var/www/html/moodle/admin/tool/mergeusers/lib/mergeusertool.php(216): MergeUserTool->_merge('372829', '279237')

16 /var/www/html/moodle/admin/tool/mergeusers/index.php(135): MergeUserTool->merge('372829', '279237')

17 {main}

jpahullo commented 7 years ago

Hi all,

It seems like regrading users after merging users (only it happens when necessary), this operation does not have sufficient detail for updating records. It is not easy to solve, but it is necessary to debug deeply on this.

If you can go with a solution, please, report your PR and we will check on that.

Regards,

Jordi

tommysghid commented 7 years ago

So I looked further into the issue. The issue is in /lib/grade/grade_item.php Specifically here:

$grade->timecreated = $datesubmitted;

    if ($grade->is_overridden()) {
        // keep original graded date - update_final_grade() sets this for overridden grades

    } else if (is_null($grade->rawgrade) and is_null($grade->feedback)) {
        // no grade and feedback means no grading yet
        //Customization
        //03-10-17
        $grade->timemodified = time();//null;

    } else if (!empty($dategraded)) {
        // fine - module sends info when graded (yay!)
        $grade->timemodified = $dategraded;

    } else if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade)
               or $grade->feedback !== $oldgrade->feedback) {
        // guess - if either grade or feedback changed set new graded date
        $grade->timemodified = time();

    } else {
        //keep original graded date
    }
    // end of hack alert

The grade timemodified defaults to null every time. But it has to have a timemodified value to update the database. $grade->timemodified = time();//null; So there is something wrong with your updated plugin. We didn't have this issue before we upgraded just recently.

For the time being we just add $grade->timemodified = time(); merge users; then change it back $grade->timemodified = null;

This is really inconvenient. And I don't know what the long term consequences in all use cases would be to leave it like we are changing it. So we don't. I will leave that up to you guys to figure out

jpahullo commented 6 years ago

Thanks for reporting. We'll keep an eye on that. It's a bit weird. We need to check that it happens to us. Could you report which was the situation with both merged users that brought you to this error? Thanks!

jpahullo commented 3 years ago

Hi!

I looked at the stack trace and checked a bit what is going on.

I think we're doing well on our side. In fact, from this plugin, we cannot change Moodle core code nor behaviour. Actually, this plugin has to obey to the Moodle API and workflow.

From my viewpoint, there is no timemodifed that we can pass to the grading from our call, since all is loaded and reseted in the last part of the stack (that from completion_info for instance).

Maybe it's a bit tricky and we can do something from our call, maybe it's something that does not happen any more in current Moodle versions. Is there someone that could say if it's hapenning yet and the Moodle version and the plugin version?

Thanks for your time.