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

Coding error detected when deleting question category

    XMLWordPrintable

Details

    • MOODLE_310_STABLE, MOODLE_311_STABLE, MOODLE_39_STABLE, MOODLE_401_STABLE
    • MOODLE_311_STABLE, MOODLE_400_STABLE
    • MOODLE_311-MDL-74427-v4
    • MOODLE_400-MDL-74427-v4
    • master-MDL-74427-v4
    • Hide

      This patch is fully covered by unit and behat tests including bad data scenario.
      However, please feel free to do the following testing that covers bad pre-existing data case.

      Manual testing in Moodle 4.0 and master (optional)

      1. Create a course.
      2. Create a quiz.
      3. From the quiz page access question bank page.
      4. Switch to Categories view.
      5. For Default for Quiz parent category add two new categories: Category 1 and Category 2.
      6. Select from the database and note down category ids:

        moodle=# SELECT id, name, parent FROM mdl_question_categories;
         id |          name          | parent 
        ----+------------------------+--------
          1 | top                    |      0
          2 | Default for Quiz 1     |      1
          3 | top                    |      0
          4 | Default for Course 1   |      3
          5 | top                    |      0
          6 | Default for Category 1 |      5
          7 | top                    |      0
          8 | Default for System     |      7
          9 | Category 1             |      2
         10 | Category 2             |      2
        (10 rows)
        

      7. On the question bank page switch to Import view.
      8. Select Moodle XML format file format.
      9. Choose Category 1 in the Import category field.
      10. Upload kvaujjIouOFTOnnOVKMOgbHj.xml file.
      11. Click Import and then Continue.
      12. Run the following SQL and confirm, that all 3 questions are linked to Category 1:

        moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name
          FROM mdl_question q
          JOIN mdl_question_versions qv ON qv.questionid = q.id
          JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid
          LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid;
         id | parent |          name           |    qtype    | questioncategoryid |    name    
        ----+--------+-------------------------+-------------+--------------------+------------
          1 |      0 | Embedded answer (Cloze) | multianswer |                  9 | Category 1
          2 |      1 | Embedded answer (Cloze) | multichoice |                  9 | Category 1
          3 |      1 | Embedded answer (Cloze) | multichoice |                  9 | Category 1
        (3 rows)
        

      13. Manually update child questions to belong to not existing category:

        UPDATE mdl_question_bank_entries SET questioncategoryid = 123456789 WHERE id IN (2, 3);
        

      14. Confirm, that child-questions belong to the category that doesn't exist anymore:

        moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name
          FROM mdl_question q
          JOIN mdl_question_versions qv ON qv.questionid = q.id
          JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid
          LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid;
         id | parent |          name           |    qtype    | questioncategoryid |    name    
        ----+--------+-------------------------+-------------+--------------------+------------
          1 |      0 | Embedded answer (Cloze) | multianswer |                  9 | Category 1
          2 |      1 | Embedded answer (Cloze) | multichoice |          123456789 | 
          3 |      1 | Embedded answer (Cloze) | multichoice |          123456789 | 
        (3 rows)
        

      15. On the question bank page switch to Categories view.
      16. Click on the delete Category 1 category link.
      17. Confirm, that The category 'Category 1' contains 1 questions message is displayed.
      18. Choose Category 2 in the category dropdown menu and click Save in category.
      19. Confirm, that no error is displayed.
      20. Re-run the query and confirm, that parent question is now linked to Category 2, while child questions are still linked to the category that doesn't exist anymore:

        moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name
          FROM mdl_question q
          JOIN mdl_question_versions qv ON qv.questionid = q.id
          JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid
          LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid;
         id | parent |          name           |    qtype    | questioncategoryid |    name    
        ----+--------+-------------------------+-------------+--------------------+------------
          1 |      0 | Embedded answer (Cloze) | multianswer |                 10 | Category 2
          2 |      1 | Embedded answer (Cloze) | multichoice |          123456789 | 
          3 |      1 | Embedded answer (Cloze) | multichoice |          123456789 | 
        (3 rows)
        

      21. Edit the quiz and add the question from question bank (from Category 2).
      22. Enrol a student.
      23. Log in as student and attempt the quiz.
      24. Confirm, that there is no error during the quiz attempt and the question works as expected.
      Show
      This patch is fully covered by unit and behat tests including bad data scenario. However, please feel free to do the following testing that covers bad pre-existing data case. Manual testing in Moodle 4.0 and master (optional) Create a course. Create a quiz. From the quiz page access question bank page. Switch to Categories view. For Default for Quiz parent category add two new categories: Category 1 and Category 2 . Select from the database and note down category ids: moodle=# SELECT id, name, parent FROM mdl_question_categories; id | name | parent ----+------------------------+-------- 1 | top | 0 2 | Default for Quiz 1 | 1 3 | top | 0 4 | Default for Course 1 | 3 5 | top | 0 6 | Default for Category 1 | 5 7 | top | 0 8 | Default for System | 7 9 | Category 1 | 2 10 | Category 2 | 2 ( 10 rows) On the question bank page switch to Import view. Select Moodle XML format file format. Choose Category 1 in the Import category field. Upload kvaujjIouOFTOnnOVKMOgbHj.xml file. Click Import and then Continue . Run the following SQL and confirm , that all 3 questions are linked to Category 1 : moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name FROM mdl_question q JOIN mdl_question_versions qv ON qv.questionid = q.id JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid; id | parent | name | qtype | questioncategoryid | name ----+--------+-------------------------+-------------+--------------------+------------ 1 | 0 | Embedded answer (Cloze) | multianswer | 9 | Category 1 2 | 1 | Embedded answer (Cloze) | multichoice | 9 | Category 1 3 | 1 | Embedded answer (Cloze) | multichoice | 9 | Category 1 ( 3 rows) Manually update child questions to belong to not existing category: UPDATE mdl_question_bank_entries SET questioncategoryid = 123456789 WHERE id IN ( 2 , 3 ); Confirm , that child-questions belong to the category that doesn't exist anymore: moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name FROM mdl_question q JOIN mdl_question_versions qv ON qv.questionid = q.id JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid; id | parent | name | qtype | questioncategoryid | name ----+--------+-------------------------+-------------+--------------------+------------ 1 | 0 | Embedded answer (Cloze) | multianswer | 9 | Category 1 2 | 1 | Embedded answer (Cloze) | multichoice | 123456789 | 3 | 1 | Embedded answer (Cloze) | multichoice | 123456789 | ( 3 rows) On the question bank page switch to Categories view. Click on the delete Category 1 category link. Confirm , that The category 'Category 1' contains 1 questions message is displayed. Choose Category 2 in the category dropdown menu and click Save in category . Confirm , that no error is displayed. Re-run the query and confirm , that parent question is now linked to Category 2 , while child questions are still linked to the category that doesn't exist anymore: moodle=# SELECT q.id, q.parent, q.name, q.qtype, qbe.questioncategoryid, qc.name FROM mdl_question q JOIN mdl_question_versions qv ON qv.questionid = q.id JOIN mdl_question_bank_entries qbe ON qbe.id = qv.questionbankentryid LEFT JOIN mdl_question_categories qc ON qc.id = qbe.questioncategoryid; id | parent | name | qtype | questioncategoryid | name ----+--------+-------------------------+-------------+--------------------+------------ 1 | 0 | Embedded answer (Cloze) | multianswer | 10 | Category 2 2 | 1 | Embedded answer (Cloze) | multichoice | 123456789 | 3 | 1 | Embedded answer (Cloze) | multichoice | 123456789 | ( 3 rows) Edit the quiz and add the question from question bank (from Category 2). Enrol a student. Log in as student and attempt the quiz. Confirm , that there is no error during the quiz attempt and the question works as expected.

    Description

      When trying to delete some question categories I'm getting Coding error detected, it must be fixed by a programmer: moodle_database::get_in_or_equal() does not accept empty arrays error.

      After having a closer look I found that there is a disparity between query conditions on questions to be moved check and the actual move.

      The first query counts records by questioncategoryid = :param condition: https://github.com/moodle/moodle/blob/b5f51883f047102140b8860d85a2321153caa8a1/question/bank/managecategories/category.php#L110

      But later, when it tries to move questions an extra condition AND (q.parent = 0 OR q.parent = q.id) is added: https://github.com/moodle/moodle/blob/b5f51883f047102140b8860d85a2321153caa8a1/question/bank/managecategories/classes/question_category_object.php#L334

      Empty $questionids array causes question_move_questions_to_category() function to throw Coding error detected, it must be fixed by a programmer: moodle_database::get_in_or_equal() does not accept empty arrays error: https://github.com/moodle/moodle/blob/b5f51883f047102140b8860d85a2321153caa8a1/lib/questionlib.php#L700

      Attachments

        1. kvaujjIouOFTOnnOVKMOgbHj.xml
          2 kB
        2. solo_script_multianaswer.php
          2 kB
        3. Step 12.PNG
          Step 12.PNG
          15 kB
        4. Step 14.PNG
          Step 14.PNG
          16 kB
        5. Step 17.PNG
          Step 17.PNG
          47 kB
        6. Step 19.PNG
          Step 19.PNG
          58 kB
        7. Step 20.PNG
          Step 20.PNG
          16 kB
        8. Step 24_A.PNG
          Step 24_A.PNG
          62 kB
        9. Step 24_B.PNG
          Step 24_B.PNG
          75 kB

        Issue Links

          Activity

            People

              mikhailgolenkov Misha Golenkov
              mikhailgolenkov Misha Golenkov
              Tim Hunt Tim Hunt
              Ilya Tregubov Ilya Tregubov
              Gladys Basiana Gladys Basiana
              Safat Shahin, Tim Hunt, Andrew Lyons, Huong Nguyen, Jun Pataleta, Michael Hawkins, Shamim Rezaie, Simey Lameze, Stevani Andolo
              Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                9/May/22

                Time Tracking

                  Estimated:
                  Original Estimate - 0 minutes
                  0m
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 1 hour, 50 minutes
                  1h 50m