Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-26275

Large gradebook won't save changes due to POST size limit

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Critical
    • Resolution: Fixed
    • Affects Version/s: 1.9.10, 2.1.3, 2.2, STABLE backlog
    • Fix Version/s: 2.3
    • Component/s: Gradebook
    • Environment:
      Apache 2.2.10, PHP 5.2.14, SLES 11 SP1, Oracle 11g
    • Database:
      Oracle
    • Testing Instructions:
      Hide

      Note that there are two known issues that you might encounter while testing.
      MDL-32306. Shift tabbing in the grader report isnt quite correct.
      MDL-31036. With quick feedback on you may encounter html tags in student feedback and have to un-override overridden grades twice.

      When the testing instructions say to refresh the grader report this is most safely done by clicking "Grader report" in the navigation breadcrumbs. F5 refreshing should be avoided to avoid accidentally repeating non-ajax actions.

      Go to a course with at least two students and at least one gradeable activity. Set an activity to have a numeric grade and make a note of the maximum grade.

      Make sure that your student doesn't already have an overridden grade for the activity. You can un-override a grade by going to the grader report, turning on editing, clicking the edit icon and unchecking the overridden checkbox. You may need to do this twice (MDL-31036).

      Students per page safety net test

      Edit /grade/report/grader/lib.php around line 1710. You need to print out the value of $fieldsperstudent ie var_dump($fieldsperstudent); or similar.
      Refresh the grader report and make a note of the number of fields needed per student. It depends on the number of activities plus some other settings.
      Add or edit max_input_vars in php.ini. php.ini is at /etc/php5/apache2 for me but your location may be different.
      Set max_input_vars to be more than $fieldsperstudent but less than 2 * $fieldsperstudent. For example, my $fieldsperstudent was 18 so I did this:
      max_input_vars = 20

      Restart apache and refresh the grader report. Only a single student should be displayed. You should get a debug message similar to the following plus a stack trace:

      Reduced maximum students per page from 20 to 1. Consider increasing the PHP setting max_input_vars from 20.

      You may get other PHP warnings and errors because you've set max_input_vars so low as to make Moodle not work. Turn it back up. 1000 is the default. Restart apache.

      Grader report ajax/non-ajax test

      You may want to keep the two following site settings available in separate tabs for easy access.
      Turn grade_report_enableajax OFF. Grader report ajax is a site setting.
      Turn grade_report_showquickfeedback ON. Show quick feedback is also a site setting.

      Go to the grader report. Clicking in empty space in a student grade cell should do nothing.

      Turn grader report ajax on and refresh the grader report. Now clicking on a cell should display two boxes. The first is for the student's grade. The second is for feedback. Enter something valid in both fields and press enter.

      The grade should change (or appear if there was no previous grade) and the cell background color should change.

      Refresh the grader report and check that the grade and feedback were saved.

      Turn ajax off then turn editing on on the grader report. All the fields will display.

      Click on edit hand/pencil icon in a student grade cell and check that the edit grade page loads after only a single click. You shouldn't have to click it twice.

      Go back to the grader report. Enter a new grade and feedback for your student and click "Update". Check that the grade and feedback were updated.

      Turn ajax on and refresh the grader report. Check that the "Update" button is hidden (may take a few seconds while the JS loads).

      Enter another grade and different feedback and tab to another grade. Refresh the grader report and check that the changes were saved.

      Enter another grade and different feedback and press enter without leaving the feedback field. Refresh the grader report and check that the changes were saved.

      Go to an empty (no grade) grade cell. Enter a grade and tab away. Refresh the grader report and check that the grade was saved.

      Turn off quick feedback and repeat the above.
      Editing mode off, ajax off (nothing happens)
      Editing mode off, ajax on
      Editing mode on, ajax off
      Editing mode on, ajax on

      Choose another grade item that uses a custom scale. Repeat these again.
      Editing mode off, ajax off (nothing happens)
      Editing mode off, ajax on
      Editing mode on, ajax off
      Editing mode on, ajax on

      Show
      Note that there are two known issues that you might encounter while testing. MDL-32306 . Shift tabbing in the grader report isnt quite correct. MDL-31036 . With quick feedback on you may encounter html tags in student feedback and have to un-override overridden grades twice. When the testing instructions say to refresh the grader report this is most safely done by clicking "Grader report" in the navigation breadcrumbs. F5 refreshing should be avoided to avoid accidentally repeating non-ajax actions. Go to a course with at least two students and at least one gradeable activity. Set an activity to have a numeric grade and make a note of the maximum grade. Make sure that your student doesn't already have an overridden grade for the activity. You can un-override a grade by going to the grader report, turning on editing, clicking the edit icon and unchecking the overridden checkbox. You may need to do this twice ( MDL-31036 ). Students per page safety net test Edit /grade/report/grader/lib.php around line 1710. You need to print out the value of $fieldsperstudent ie var_dump($fieldsperstudent); or similar. Refresh the grader report and make a note of the number of fields needed per student. It depends on the number of activities plus some other settings. Add or edit max_input_vars in php.ini. php.ini is at /etc/php5/apache2 for me but your location may be different. Set max_input_vars to be more than $fieldsperstudent but less than 2 * $fieldsperstudent. For example, my $fieldsperstudent was 18 so I did this: max_input_vars = 20 Restart apache and refresh the grader report. Only a single student should be displayed. You should get a debug message similar to the following plus a stack trace: Reduced maximum students per page from 20 to 1. Consider increasing the PHP setting max_input_vars from 20. You may get other PHP warnings and errors because you've set max_input_vars so low as to make Moodle not work. Turn it back up. 1000 is the default. Restart apache. Grader report ajax/non-ajax test You may want to keep the two following site settings available in separate tabs for easy access. Turn grade_report_enableajax OFF. Grader report ajax is a site setting. Turn grade_report_showquickfeedback ON. Show quick feedback is also a site setting. Go to the grader report. Clicking in empty space in a student grade cell should do nothing. Turn grader report ajax on and refresh the grader report. Now clicking on a cell should display two boxes. The first is for the student's grade. The second is for feedback. Enter something valid in both fields and press enter. The grade should change (or appear if there was no previous grade) and the cell background color should change. Refresh the grader report and check that the grade and feedback were saved. Turn ajax off then turn editing on on the grader report. All the fields will display. Click on edit hand/pencil icon in a student grade cell and check that the edit grade page loads after only a single click. You shouldn't have to click it twice. Go back to the grader report. Enter a new grade and feedback for your student and click "Update". Check that the grade and feedback were updated. Turn ajax on and refresh the grader report. Check that the "Update" button is hidden (may take a few seconds while the JS loads). Enter another grade and different feedback and tab to another grade. Refresh the grader report and check that the changes were saved. Enter another grade and different feedback and press enter without leaving the feedback field. Refresh the grader report and check that the changes were saved. Go to an empty (no grade) grade cell. Enter a grade and tab away. Refresh the grader report and check that the grade was saved. Turn off quick feedback and repeat the above. Editing mode off, ajax off (nothing happens) Editing mode off, ajax on Editing mode on, ajax off Editing mode on, ajax on Choose another grade item that uses a custom scale. Repeat these again. Editing mode off, ajax off (nothing happens) Editing mode off, ajax on Editing mode on, ajax off Editing mode on, ajax on
    • Workaround:
      Hide

      Increase the value of max_input_vars in php.ini.

      Show
      Increase the value of max_input_vars in php.ini.
    • Affected Branches:
      MOODLE_19_STABLE, MOODLE_21_STABLE, MOODLE_22_STABLE
    • Fixed Branches:
      MOODLE_23_STABLE
    • Pull Master Branch:
      MDL-26275_large_grader

      Description

      We have a course with 47 students and 18 assignments/tests/quizzes. When we try to update the grades for the students in the gradebook, only part of the grades are saved. For the ones that don't save, we have to click on the little "hand" icon to manually "edit" the grade, and it will save then.

      Using Firebug, I traced this down to a problem with how Moodle saves the changes to the gradebook, basically by creating one giant form POST containing all the fields and values, like:

      id=2161&sesskey=F9J3pymnk6&report=grader&oldgrade_13214_4098=8.00&grade_13214_4098=8.00&oldgrade_13214_4099=&grade_13214_4099=&oldgrade_13214_4100=&grade_13214_4100=&oldgrade_13214_4101=.....

      In our case, the form post for this gradebook ended up being 33184 bytes, which appears to be too large for something (Apache/Firefox/IE/PHP/linux/etc.) to handle.

      To test things out, I made a php page in our Moodle instance (moodle/test/index.php) containing the following code to output all the information it received:

      <?php
         if ($_REQUEST) {
            echo "<table border=1> \n";
            echo " <tr> \n";
            echo "  <td><b>result_name </b></td> \n ";
            echo "  <td><b>result_val  </b></td> \n ";
            echo " </tr> \n";
            while (list($result_nme, $result_val) = each($_REQUEST)) {
               echo " <tr> \n";
               echo "  <td> $result_nme </td> \n";
               echo "  <td> $result_val </td> \n";
               echo " </tr> \n";
            }
            echo "</table> \n";
         }
      ?>
      

      I then created a copy of the index.php page inside moodle/grade/report/grader/ and pointed that copy of the page to post its data to the test page I created.

      I've attached a couple of files to help illustrate this:
      outputPostAttribs.pdf contains the browser output of that test recipient page I made.
      FirebugLocationWithRequestHeaders.txt is an output of the Form POST data that Firebug reported

      The two grades I entered (at the bottom of the list) were the grades for students with Moodle ID's 32738 and 7348 (I gave them a grade of 2.) When you parse through the Firebug file, you can see the following values:
      grade_32738_4098=2
      grade_7348_4098=2
      However, those fields aren't in the list that Apache received.

      The bad thing is that I'm not aware of an easy workaround for this issue short of a complete overhaul of the Moodle gradebook.

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Votes:
                  15 Vote for this issue
                  Watchers:
                  16 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Fix Release Date:
                    25/Jun/12