Moodle
  1. Moodle
  2. MDL-27597

get_categories returns categories not under the parent category

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.9.12, 2.0.3, 2.1.1, 2.2
    • Fix Version/s: 1.9.14, 2.0.5, 2.1.2
    • Component/s: Course
    • Labels:
    • Testing Instructions:
      Hide

      testing can be done by developers only
      1/ do a fresh install
      2/ create 8 different subcategories in Misc
      3/ create two more to capts
      4/ fill the top catch with some subcategories
      5/ create PHP script that asks for categories of cat id 1, verify results

      Show
      testing can be done by developers only 1/ do a fresh install 2/ create 8 different subcategories in Misc 3/ create two more to capts 4/ fill the top catch with some subcategories 5/ create PHP script that asks for categories of cat id 1, verify results
    • Affected Branches:
      MOODLE_19_STABLE, MOODLE_20_STABLE, MOODLE_21_STABLE, MOODLE_22_STABLE
    • Fixed Branches:
      MOODLE_19_STABLE, MOODLE_20_STABLE, MOODLE_21_STABLE
    • Pull from Repository:
    • Pull Master Branch:
      w31_MDL-27597_m22_catlike
    • Rank:
      17306

      Description

      If you have a course category $cat, with $cat->id == 1 ('Miscellaneous' by default in Moodle installs), then make this function call:

      get_categories($cat, NULL, false);

      Intending to get all the descendant categories of this category, then you will, also get any categories with an ID starting with 1 (or their sub categories).

      e.g. this will also return every category with the ID 10, 15, 105, etc. or a category with the path '/10/25', '/10/26' or '/101/124' etc.

      The problem is this line in datalib.php:
      JOIN {$CFG->prefix}course_categories ccp
      ON (cc.path LIKE ".sql_concat('ccp.path',"'%'").")

      (or the Moodle 2.0 version:
      JOIN

      {course_categories}

      ccp
      ON (cc.path LIKE ".$DB->sql_concat('ccp.path',"'%'").")
      )

      Searching for cc.path LIKE "/1%" will find all the other categories as well.

      Possible solutions:

      1. Change the line to:
      ON (cc.path LIKE ".sql_concat('ccp.path',"'/%'").") // And the M2.0 equivalent

      2. Change the line to:
      ON ((cc.id = ccp.id) OR (cc.path LIKE ".sql_concat('ccp.path',"'/%'").")) // And the M2.0 equivalent

      Solution 1. will no longer return the parent in the list (which for my purposes would be even better!), solution 2. would be closer to (what I guess is) the intended functionality.

        Activity

        Hide
        Davo Smith added a comment -

        This is a one-line fix to an issue which is obviously a bug - please could someone check it and commit it?

        Show
        Davo Smith added a comment - This is a one-line fix to an issue which is obviously a bug - please could someone check it and commit it?
        Hide
        Petr Škoda added a comment -

        You meant

        ON ((cc.parent = ccp.id) OR (cc.path LIKE ".$DB->sql_concat('ccp.path',"'/%'")."))
        

        right?

        Show
        Petr Škoda added a comment - You meant ON ((cc.parent = ccp.id) OR (cc.path LIKE ".$DB->sql_concat('ccp.path'," '/%' ")." )) right?
        Hide
        Eloy Lafuente (stronk7) added a comment -

        Integrated thanks!

        Note for testers: Please test this both under 19_STABLE and any 2.x branch.

        Show
        Eloy Lafuente (stronk7) added a comment - Integrated thanks! Note for testers: Please test this both under 19_STABLE and any 2.x branch.
        Hide
        Sam Hemelryk added a comment -

        Thanks guys, this has passed.

        Just noting I really think we should add (not now just at some point) if ($parent == 'none' || empty($parent)) ..
        Hehe my first test involved me using get_categories(0, null, false) which threw me off for a while

        Cheers
        Sam

        Show
        Sam Hemelryk added a comment - Thanks guys, this has passed. Just noting I really think we should add (not now just at some point) if ($parent == 'none' || empty($parent)) .. Hehe my first test involved me using get_categories(0, null, false) which threw me off for a while Cheers Sam
        Hide
        Eloy Lafuente (stronk7) added a comment -

        Sent upstream and closing, many thanks!

        Show
        Eloy Lafuente (stronk7) added a comment - Sent upstream and closing, many thanks!

          People

          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: