Skip to:
Content

BuddyPress.org

Changeset 11095


Ignore:
Timestamp:
09/13/2016 06:21:10 PM (3 years ago)
Author:
dcavins
Message:

Add query support for hierarchical groups.

Adds a new column to the groups table, parent_id, and support for
querying by parent_id via groups_get_groups() and
bp_has_groups().

Does not add any front-facing hierarchy functionality—that is left for
now to plugins.

Props dcavins, boonebgorges, r-a-y, djpaul, mercime.

See #3961.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/admin/bp-core-admin-schema.php

    r11093 r11095  
    203203                description longtext NOT NULL,
    204204                status varchar(10) NOT NULL DEFAULT 'public',
     205                parent_id bigint(20) NOT NULL DEFAULT 0,
    205206                enable_forum tinyint(1) NOT NULL DEFAULT '1',
    206207                date_created datetime NOT NULL,
    207208                KEY creator_id (creator_id),
    208                 KEY status (status)
     209                KEY status (status),
     210                KEY parent_id (parent_id)
    209211            ) {$charset_collate};";
    210212
  • trunk/src/bp-core/bp-core-update.php

    r11085 r11095  
    519519    // Update post_titles
    520520    bp_migrate_directory_page_titles();
     521
     522    /*
     523     * Add `parent_id` column to groups table.
     524     * Also handled by `bp_core_install()`.
     525     */
     526    if ( bp_is_active( 'groups' ) ) {
     527        bp_core_install_groups();
     528
     529        // Invalidate all cached group objects.
     530        global $wpdb;
     531        $bp = buddypress();
     532
     533        $group_ids = $wpdb->get_col( "SELECT id FROM {$bp->groups->table_name}" );
     534
     535        foreach ( $group_ids as $group_id ) {
     536            wp_cache_delete( $group_id, 'bp_groups' );
     537        }
     538    }
    521539}
    522540
  • trunk/src/bp-groups/bp-groups-actions.php

    r11091 r11095  
    567567}
    568568add_action( 'bp_actions', 'groups_action_group_feed' );
     569
     570/**
     571 * Update orphaned child groups when the parent is deleted.
     572 *
     573 * @since 2.7.0
     574 *
     575 * @param BP_Groups_Group $group Instance of the group item being deleted.
     576 */
     577function bp_groups_update_orphaned_groups_on_group_delete( $group ) {
     578    // Get child groups and set the parent to the deleted parent's parent.
     579    $grandparent_group_id = $group->parent_id;
     580    $child_args = array(
     581        'parent_id'         => $group->id,
     582        'show_hidden'       => true,
     583        'per_page'          => false,
     584        'update_meta_cache' => false,
     585    );
     586    $children = groups_get_groups( $child_args );
     587    $children = $children['groups'];
     588
     589    foreach ( $children as $cgroup ) {
     590        $cgroup->parent_id = $grandparent_group_id;
     591        $cgroup->save();
     592    }
     593}
     594add_action( 'bp_groups_delete_group', 'bp_groups_update_orphaned_groups_on_group_delete', 10, 2 );
  • trunk/src/bp-groups/bp-groups-functions.php

    r11091 r11095  
    7878 *     @type string   $status       The group's status. Accepts 'public', 'private' or
    7979 *                                  'hidden'. Defaults to 'public'.
     80 *     @type int      $parent_id    The ID of the parent group. Default: 0.
    8081 *     @type int      $enable_forum Optional. Whether the group has a forum enabled.
    8182 *                                  If the legacy forums are enabled for this group
     
    9697        'slug'         => '',
    9798        'status'       => 'public',
     99        'parent_id'    => 0,
    98100        'enable_forum' => 0,
    99101        'date_created' => bp_core_current_time()
     
    142144    $group->slug         = $slug;
    143145    $group->status       = $status;
     146    $group->parent_id    = $parent_id;
    144147    $group->enable_forum = (int) $enable_forum;
    145148    $group->date_created = $date_created;
     
    261264 * @return bool True on success, false on failure.
    262265 */
    263 function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false ) {
     266function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false, $parent_id = false ) {
    264267
    265268    $group = groups_get_group( $group_id );
     
    275278    // Now update the status.
    276279    $group->status = $status;
     280
     281    // Update the parent ID if necessary.
     282    if ( false !== $parent_id ) {
     283        $group->parent_id = $parent_id;
     284    }
    277285
    278286    if ( !$group->save() )
     
    675683 * @since 1.2.0
    676684 * @since 2.6.0 Added `$group_type`, `$group_type__in`, and `$group_type__not_in` parameters.
    677  * @since 2.7.0 Added `$update_admin_cache` parameter.
     685 * @since 2.7.0 Added `$update_admin_cache` and `$parent_id` parameters.
    678686 *
    679687 * @param array|string $args {
     
    695703        'include'            => false,          // Only include these specific groups (group_ids).
    696704        'exclude'            => false,          // Do not include these specific groups (group_ids).
     705        'parent_id'          => null,           // Get groups that are children of the specified group(s).
    697706        'search_terms'       => false,          // Limit to groups that match these search terms.
    698707        'group_type'         => '',
     
    715724        'include'            => $r['include'],
    716725        'exclude'            => $r['exclude'],
     726        'parent_id'          => $r['parent_id'],
    717727        'search_terms'       => $r['search_terms'],
    718728        'group_type'         => $r['group_type'],
  • trunk/src/bp-groups/bp-groups-template.php

    r11091 r11095  
    139139 *     @type array|string $exclude            Array or comma-separated list of group IDs. Results will exclude
    140140 *                                            the listed groups. Default: false.
     141 *     @type array|string $parent_id          Array or comma-separated list of group IDs. Results will include only
     142 *                                            child groups of the listed groups. Default: null.
    141143 *     @type bool         $update_meta_cache  Whether to fetch groupmeta for queried groups. Default: true.
    142144 *     @type bool         $update_admin_cache Whether to pre-fetch group admins for queried groups.
     
    203205        'include'            => false,
    204206        'exclude'            => false,
     207        'parent_id'          => null,
    205208        'populate_extras'    => true,
    206209        'update_meta_cache'  => true,
     
    227230        'include'            => $r['include'],
    228231        'exclude'            => $r['exclude'],
     232        'parent_id'          => $r['parent_id'],
    229233        'populate_extras'    => (bool) $r['populate_extras'],
    230234        'update_meta_cache'  => (bool) $r['update_meta_cache'],
  • trunk/src/bp-groups/classes/class-bp-groups-group.php

    r11089 r11095  
    6969
    7070    /**
     71     * Parent ID.
     72     *
     73     * ID of parent group, if applicable.
     74     *
     75     * @since 2.7.0
     76     * @var int
     77     */
     78    public $parent_id;
     79
     80    /**
    7181     * Should (legacy) bbPress forums be enabled for this group?
    7282     *
     
    209219        $this->description  = stripslashes( $group->description );
    210220        $this->status       = $group->status;
     221        $this->parent_id    = (int) $group->parent_id;
    211222        $this->enable_forum = (int) $group->enable_forum;
    212223        $this->date_created = $group->date_created;
     
    230241        $this->description  = apply_filters( 'groups_group_description_before_save',  $this->description,  $this->id );
    231242        $this->status       = apply_filters( 'groups_group_status_before_save',       $this->status,       $this->id );
     243        $this->parent_id    = apply_filters( 'groups_group_parent_id_before_save',    $this->parent_id,    $this->id );
    232244        $this->enable_forum = apply_filters( 'groups_group_enable_forum_before_save', $this->enable_forum, $this->id );
    233245        $this->date_created = apply_filters( 'groups_group_date_created_before_save', $this->date_created, $this->id );
     
    272284                    description = %s,
    273285                    status = %s,
     286                    parent_id = %d,
    274287                    enable_forum = %d,
    275288                    date_created = %s
     
    282295                    $this->description,
    283296                    $this->status,
     297                    $this->parent_id,
    284298                    $this->enable_forum,
    285299                    $this->date_created,
     
    294308                    description,
    295309                    status,
     310                    parent_id,
    296311                    enable_forum,
    297312                    date_created
    298313                ) VALUES (
    299                     %d, %s, %s, %s, %s, %d, %s
     314                    %d, %s, %s, %s, %s, %d, %d, %s
    300315                )",
    301316                    $this->creator_id,
     
    304319                    $this->description,
    305320                    $this->status,
     321                    $this->parent_id,
    306322                    $this->enable_forum,
    307323                    $this->date_created
     
    837853     * @since 1.6.0
    838854     * @since 2.6.0 Added `$group_type`, `$group_type__in`, and `$group_type__not_in` parameters.
    839      * @since 2.7.0 Added `$update_admin_cache` parameter.
     855     * @since 2.7.0 Added `$update_admin_cache` and `$parent_id` parameters.
    840856     *
    841857     * @param array $args {
     
    864880     *     @type array|string $value              Optional. Array or comma-separated list of group IDs. Results
    865881     *                                            will be limited to groups within the list. Default: false.
     882     *     @type array|string $parent_id          Optional. Array or comma-separated list of group IDs. Results
     883     *                                            will be limited to children of the specified groups. Default: null.
    866884     *     @type bool         $populate_extras    Whether to fetch additional information
    867885     *                                            (such as member count) about groups. Default: true.
     
    917935            'meta_query'         => false,
    918936            'include'            => false,
     937            'parent_id'          => null,
    919938            'populate_extras'    => true,
    920939            'update_meta_cache'  => true,
     
    9861005            $include        = implode( ',', wp_parse_id_list( $r['include'] ) );
    9871006            $where_conditions['include'] = "g.id IN ({$include})";
     1007        }
     1008
     1009        if ( ! is_null( $r['parent_id'] ) ) {
     1010            // Note that `wp_parse_id_list()` converts `false` to 0.
     1011            $parent_id        = implode( ',', wp_parse_id_list( $r['parent_id'] ) );
     1012            $where_conditions['parent_id'] = "g.parent_id IN ({$parent_id})";
    9881013        }
    9891014
  • trunk/src/bp-groups/classes/class-bp-groups-template.php

    r11091 r11095  
    166166            'include'            => false,
    167167            'exclude'            => false,
     168            'parent_id'          => null,
    168169            'search_terms'       => '',
    169170            'group_type'         => '',
     
    225226                'include'            => $include,
    226227                'exclude'            => $exclude,
     228                'parent_id'          => $parent_id,
    227229                'populate_extras'    => $populate_extras,
    228230                'update_meta_cache'  => $update_meta_cache,
  • trunk/tests/phpunit/testcases/groups/class-bp-groups-group.php

    r11091 r11095  
    17061706        $this->assertEmpty( $groups['groups'] );
    17071707    }
     1708
     1709    /**
     1710     * @group hierarchical_groups
     1711     */
     1712    public function test_get_by_parent_id() {
     1713        $g1 = $this->factory->group->create();
     1714        $g2 = $this->factory->group->create( array(
     1715            'parent_id' => $g1,
     1716        ) );
     1717        $g3 = $this->factory->group->create( array(
     1718            'parent_id' => $g2,
     1719        ) );
     1720        $g4 = $this->factory->group->create();
     1721
     1722        $groups = BP_Groups_Group::get( array(
     1723            'parent_id' => $g1,
     1724        ) );
     1725
     1726        $found = wp_list_pluck( $groups['groups'], 'id' );
     1727        $this->assertEquals( array( $g2 ), $found );
     1728    }
     1729
     1730    /**
     1731     * @group hierarchical_groups
     1732     */
     1733    public function test_get_by_parent_id_ignore_grandparent() {
     1734        $g1 = $this->factory->group->create();
     1735        $g2 = $this->factory->group->create( array(
     1736            'parent_id' => $g1,
     1737        ) );
     1738        $g3 = $this->factory->group->create( array(
     1739            'parent_id' => $g2,
     1740        ) );
     1741        $g4 = $this->factory->group->create();
     1742
     1743        $groups = BP_Groups_Group::get( array(
     1744            'parent_id' => $g2,
     1745        ) );
     1746
     1747        $found = wp_list_pluck( $groups['groups'], 'id' );
     1748        $this->assertEquals( array( $g3 ), $found );
     1749    }
     1750
     1751    /**
     1752     * @group hierarchical_groups
     1753     */
     1754    public function test_get_by_parent_id_array() {
     1755        $g1 = $this->factory->group->create();
     1756        $g2 = $this->factory->group->create( array(
     1757            'parent_id' => $g1,
     1758        ) );
     1759        $g3 = $this->factory->group->create( array(
     1760            'parent_id' => $g2,
     1761        ) );
     1762        $g4 = $this->factory->group->create();
     1763
     1764        $groups = BP_Groups_Group::get( array(
     1765            'parent_id' => array( $g1, $g2 ),
     1766        ) );
     1767
     1768        $found = wp_list_pluck( $groups['groups'], 'id' );
     1769        $this->assertEqualSets( array( $g2, $g3 ), $found );
     1770    }
     1771
     1772    /**
     1773     * @group hierarchical_groups
     1774     */
     1775    public function test_get_by_parent_id_comma_separated_string() {
     1776        $g1 = $this->factory->group->create();
     1777        $g2 = $this->factory->group->create( array(
     1778            'parent_id' => $g1,
     1779        ) );
     1780        $g3 = $this->factory->group->create( array(
     1781            'parent_id' => $g2,
     1782        ) );
     1783        $g4 = $this->factory->group->create();
     1784
     1785        $groups = BP_Groups_Group::get( array(
     1786            'parent_id' => "$g1, $g2",
     1787        ) );
     1788
     1789        $found = wp_list_pluck( $groups['groups'], 'id' );
     1790        $this->assertEqualSets( array( $g2, $g3 ), $found );
     1791    }
     1792
     1793    /**
     1794     * @group hierarchical_groups
     1795     */
     1796    public function test_get_by_parent_id_top_level_groups() {
     1797        $g1 = $this->factory->group->create();
     1798        $g2 = $this->factory->group->create( array(
     1799            'parent_id' => $g1,
     1800        ) );
     1801        $g3 = $this->factory->group->create( array(
     1802            'parent_id' => $g2,
     1803        ) );
     1804        $g4 = $this->factory->group->create();
     1805
     1806        $groups = BP_Groups_Group::get( array(
     1807            'parent_id' => 0,
     1808        ) );
     1809
     1810        $found = wp_list_pluck( $groups['groups'], 'id' );
     1811        $this->assertEqualSets( array( $g1, $g4 ), $found );
     1812    }
     1813
     1814    /**
     1815     * @group hierarchical_groups
     1816     */
     1817    public function test_get_by_parent_id_top_level_groups_using_false() {
     1818        $g1 = $this->factory->group->create();
     1819        $g2 = $this->factory->group->create( array(
     1820            'parent_id' => $g1,
     1821        ) );
     1822        $g3 = $this->factory->group->create( array(
     1823            'parent_id' => $g2,
     1824        ) );
     1825        $g4 = $this->factory->group->create();
     1826
     1827        $groups = BP_Groups_Group::get( array(
     1828            'parent_id' => false,
     1829        ) );
     1830
     1831        $found = wp_list_pluck( $groups['groups'], 'id' );
     1832        $this->assertEqualSets( array( $g1, $g4 ), $found );
     1833    }
    17081834}
    17091835
  • trunk/tests/phpunit/testcases/groups/functions.php

    r11091 r11095  
    635635        $this->assertEquals( 0, groups_get_invite_count_for_user( $u2 ) );
    636636    }
     637
     638    /**
     639     * @group hierarchical_groups
     640     */
     641    public function test_update_orphaned_groups_on_group_delete_top_level() {
     642        $g1 = $this->factory->group->create();
     643        $g2 = $this->factory->group->create( array(
     644            'parent_id' => $g1,
     645        ) );
     646
     647        groups_delete_group( $g1 );
     648
     649        $child = groups_get_group( array( 'group_id' => $g2 ) );
     650        $this->assertEquals( 0, $child->parent_id );
     651    }
     652
     653    /**
     654     * @group hierarchical_groups
     655     */
     656    public function test_update_orphaned_groups_on_group_delete_two_levels() {
     657        $g1 = $this->factory->group->create();
     658        $g2 = $this->factory->group->create( array(
     659            'parent_id' => $g1,
     660        ) );
     661        $g3 = $this->factory->group->create( array(
     662            'parent_id' => $g2,
     663        ) );
     664
     665        groups_delete_group( $g2 );
     666
     667        $child = groups_get_group( array( 'group_id' => $g3 ) );
     668        $this->assertEquals( $g1, $child->parent_id );
     669    }
    637670}
  • trunk/tests/phpunit/testcases/groups/template.php

    r9819 r11095  
    118118
    119119        $this->assertEquals( 1, $groups_template->group_count );
     120    }
     121
     122    /**
     123     * @group hierarchical_groups
     124     */
     125    public function test_bp_has_groups_parent_id() {
     126        $g1 = $this->factory->group->create();
     127        $g2 = $this->factory->group->create( array(
     128            'parent_id' => $g1,
     129        ) );
     130        $g3 = $this->factory->group->create( array(
     131            'parent_id' => $g2,
     132        ) );
     133        $g4 = $this->factory->group->create();
     134
     135        global $groups_template;
     136        bp_has_groups( array(
     137            'parent_id' => $g1,
     138        ) );
     139
     140        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     141        $this->assertEquals( array( $g2 ), $ids );
     142    }
     143
     144    /**
     145     * @group hierarchical_groups
     146     */
     147    public function test_bp_has_groups_parent_id_array() {
     148        $g1 = $this->factory->group->create();
     149        $g2 = $this->factory->group->create( array(
     150            'parent_id' => $g1,
     151        ) );
     152        $g3 = $this->factory->group->create( array(
     153            'parent_id' => $g2,
     154        ) );
     155        $g4 = $this->factory->group->create();
     156
     157        global $groups_template;
     158        bp_has_groups( array(
     159            'parent_id' => array( $g1, $g2 ),
     160        ) );
     161
     162        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     163        $this->assertEqualSets( array( $g2, $g3 ), $ids );
     164    }
     165
     166    /**
     167     * @group hierarchical_groups
     168     */
     169    public function test_bp_has_groups_parent_id_comma_separated() {
     170        $g1 = $this->factory->group->create();
     171        $g2 = $this->factory->group->create( array(
     172            'parent_id' => $g1,
     173        ) );
     174        $g3 = $this->factory->group->create( array(
     175            'parent_id' => $g2,
     176        ) );
     177        $g4 = $this->factory->group->create();
     178
     179        global $groups_template;
     180        bp_has_groups( array(
     181            'parent_id' => "{$g1},{$g2}",
     182        ) );
     183
     184        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     185        $this->assertEqualSets( array( $g2, $g3 ), $ids );
     186    }
     187
     188    /**
     189     * @group hierarchical_groups
     190     */
     191    public function test_bp_has_groups_parent_id_null() {
     192        $g1 = $this->factory->group->create();
     193        $g2 = $this->factory->group->create( array(
     194            'parent_id' => $g1,
     195        ) );
     196        $g3 = $this->factory->group->create( array(
     197            'parent_id' => $g2,
     198        ) );
     199        $g4 = $this->factory->group->create();
     200
     201        global $groups_template;
     202        bp_has_groups( array(
     203            'parent_id' => null,
     204        ) );
     205
     206        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     207        $this->assertEqualSets( array( $g1, $g2, $g3, $g4 ), $ids );
     208    }
     209
     210    /**
     211     * @group hierarchical_groups
     212     */
     213    public function test_bp_has_groups_parent_id_top_level_groups() {
     214        $g1 = $this->factory->group->create();
     215        $g2 = $this->factory->group->create( array(
     216            'parent_id' => $g1,
     217        ) );
     218        $g3 = $this->factory->group->create( array(
     219            'parent_id' => $g2,
     220        ) );
     221        $g4 = $this->factory->group->create();
     222
     223        global $groups_template;
     224        bp_has_groups( array(
     225            'parent_id' => 0,
     226        ) );
     227
     228        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     229        $this->assertEqualSets( array( $g1, $g4 ), $ids );
     230    }
     231
     232    /**
     233     * @group hierarchical_groups
     234     */
     235    public function test_bp_has_groups_parent_id_top_level_groups_using_false() {
     236        $g1 = $this->factory->group->create();
     237        $g2 = $this->factory->group->create( array(
     238            'parent_id' => $g1,
     239        ) );
     240        $g3 = $this->factory->group->create( array(
     241            'parent_id' => $g2,
     242        ) );
     243        $g4 = $this->factory->group->create();
     244
     245        global $groups_template;
     246        bp_has_groups( array(
     247            'parent_id' => false,
     248        ) );
     249
     250        $ids = wp_parse_id_list( wp_list_pluck( $groups_template->groups, 'id' ) );
     251        $this->assertEqualSets( array( $g1, $g4 ), $ids );
    120252    }
    121253
Note: See TracChangeset for help on using the changeset viewer.