Skip to:
Content

BuddyPress.org

Ticket #3961: 3961.05.patch

File 3961.05.patch, 17.6 KB (added by r-a-y, 3 years ago)
  • src/bp-core/admin/bp-core-admin-schema.php

     
    202202                                slug varchar(200) NOT NULL,
    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
    211213        $sql[] = "CREATE TABLE {$bp_prefix}bp_groups_members (
  • src/bp-core/bp-core-update.php

     
    508508 * 2.7.0 update routine.
    509509 *
    510510 * - Add email unsubscribe salt.
     511 * - Add `parent_id` column to groups table.
    511512 *
    512513 * @since 2.7.0
    513514 */
    514515function bp_update_to_2_7() {
    515516        bp_add_option( 'bp-emails-unsubscribe-salt', base64_encode( wp_generate_password( 64, true, true ) ) );
     517
     518        /*
     519         * Also handled by `bp_core_install()`.
     520         * Add `parent_id` column to groups table.
     521         */
     522        if ( bp_is_active( 'groups' ) ) {
     523                bp_core_install_groups();
     524        }
    516525}
    517526
    518527/**
  • src/bp-groups/bp-groups-actions.php

     
    566566        ) );
    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 = ! empty( $group->parent_id ) ? $group->parent_id : 0;
     580        $child_args = array(
     581                'parent_id'         => $group->id,
     582                'show_hidden'       => true,
     583                'per_page'          => false,
     584                'populate_extras'   => false,
     585                'update_meta_cache' => false,
     586        );
     587        $children = groups_get_groups( $child_args );
     588        $children = $children['groups'];
     589
     590        foreach ( $children as $cgroup ) {
     591                // Create the BP_Groups_Group object.
     592                $child_group = groups_get_group( array( 'group_id' => $cgroup->id ) );
     593                $child_group->parent_id = $grandparent_group_id;
     594                $child_group->save();
     595        }
     596}
     597add_action( 'bp_groups_delete_group', 'bp_groups_update_orphaned_groups_on_group_delete', 10, 2 );
     598 No newline at end of file
  • src/bp-groups/bp-groups-activity.php

     
    244244                // rather than manually.
    245245                $uncached_ids = array();
    246246                foreach ( $group_ids as $group_id ) {
    247                         if ( false === wp_cache_get( $group_id, 'bp_groups' ) ) {
     247                        $g = wp_cache_get( $group_id, 'bp_groups' );
     248                        if ( false === $g  || ! isset( $g->parent_id ) ) {
    248249                                $uncached_ids[] = $group_id;
    249250                        }
    250251                }
  • src/bp-groups/bp-groups-functions.php

     
    8787 *     @type string   $slug         The group slug.
    8888 *     @type string   $status       The group's status. Accepts 'public', 'private' or
    8989 *                                  'hidden'. Defaults to 'public'.
     90 *     @type int      $parent_id    The ID of the parent group. Default: 0.
    9091 *     @type int      $enable_forum Optional. Whether the group has a forum enabled.
    9192 *                                  If the legacy forums are enabled for this group
    9293 *                                  or if a bbPress forum is enabled for the group,
     
    105106                'description'  => '',
    106107                'slug'         => '',
    107108                'status'       => 'public',
     109                'parent_id'    => 0,
    108110                'enable_forum' => 0,
    109111                'date_created' => bp_core_current_time()
    110112        );
     
    151153        $group->description  = $description;
    152154        $group->slug         = $slug;
    153155        $group->status       = $status;
     156        $group->parent_id    = $parent_id;
    154157        $group->enable_forum = (int) $enable_forum;
    155158        $group->date_created = $date_created;
    156159
     
    270273 *                                   to the group. 'members', 'mods', or 'admins'.
    271274 * @return bool True on success, false on failure.
    272275 */
    273 function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false ) {
     276function groups_edit_group_settings( $group_id, $enable_forum, $status, $invite_status = false, $parent_id = false ) {
    274277
    275278        $group = groups_get_group( array( 'group_id' => $group_id ) );
    276279        $group->enable_forum = $enable_forum;
     
    285288        // Now update the status.
    286289        $group->status = $status;
    287290
     291        // Update the parent ID if necessary.
     292        if ( false !== $parent_id ) {
     293                $group->parent_id = $parent_id;
     294        }
     295
    288296        if ( !$group->save() )
    289297                return false;
    290298
     
    703711                'user_id'            => false,          // Pass a user_id to limit to only groups that this user is a member of.
    704712                'include'            => false,          // Only include these specific groups (group_ids).
    705713                'exclude'            => false,          // Do not include these specific groups (group_ids).
     714                'parent_id'          => false,          // Get groups that are children of the specified group(s).
    706715                'search_terms'       => false,          // Limit to groups that match these search terms.
    707716                'group_type'         => '',
    708717                'group_type__in'     => '',
     
    722731                'user_id'            => $r['user_id'],
    723732                'include'            => $r['include'],
    724733                'exclude'            => $r['exclude'],
     734                'parent_id'          => $r['parent_id'],
    725735                'search_terms'       => $r['search_terms'],
    726736                'group_type'         => $r['group_type'],
    727737                'group_type__in'     => $r['group_type__in'],
  • src/bp-groups/bp-groups-template.php

     
    137137 *                                            about groups. Default: true.
    138138 *     @type array|string $exclude            Array or comma-separated list of group IDs. Results will exclude
    139139 *                                            the listed groups. Default: false.
     140 *     @type array|string $parent_id          Array or comma-separated list of group IDs. Results will include only
     141 *                                            child groups of the listed groups. Default: false.
    140142 *     @type bool         $update_meta_cache  Whether to fetch groupmeta for queried groups. Default: true.
    141143 * }
    142144 * @return bool True if there are groups to display that match the params
     
    150152        $slug         = false;
    151153        $type         = '';
    152154        $search_terms = false;
     155        $parent_id    = false;
    153156
    154157        // When looking your own groups, check for two action variables.
    155158        if ( bp_is_current_action( 'my-groups' ) ) {
     
    198201                'meta_query'         => false,
    199202                'include'            => false,
    200203                'exclude'            => false,
     204                'parent_id'          => $parent_id,
    201205                'populate_extras'    => true,
    202206                'update_meta_cache'  => true,
    203207        ), 'has_groups' );
     
    221225                'meta_query'         => $r['meta_query'],
    222226                'include'            => $r['include'],
    223227                'exclude'            => $r['exclude'],
     228                'parent_id'          => $r['parent_id'],
    224229                'populate_extras'    => (bool) $r['populate_extras'],
    225230                'update_meta_cache'  => (bool) $r['update_meta_cache'],
    226231        ) );
  • src/bp-groups/classes/class-bp-groups-group.php

     
    6868        public $status;
    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         *
    7383         * @since 1.6.0
     
    184194         * Set up data about the current group.
    185195         *
    186196         * @since 1.6.0
     197         * @since 2.7.0 Handle cache invalidation for new 'parent_id' column.
    187198         */
    188199        public function populate() {
    189200                global $wpdb;
     
    199210                        $group = $wpdb->get_row( $wpdb->prepare( "SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id = %d", $this->id ) );
    200211
    201212                        wp_cache_set( $this->id, $group, 'bp_groups' );
     213
     214                // BP 2.7 - Older cache exists, so invalidate cache and refetch.
     215                } elseif ( false !== $group && ! isset( $group->parent_id ) ) {
     216                        wp_cache_delete( $this->id, 'bp_groups' );
     217                        $this->populate();
     218                        return;
    202219                }
    203220
    204221                // No group found so set the ID and bail.
     
    214231                $this->slug         = $group->slug;
    215232                $this->description  = stripslashes( $group->description );
    216233                $this->status       = $group->status;
     234                $this->parent_id    = $group->parent_id;
    217235                $this->enable_forum = $group->enable_forum;
    218236                $this->date_created = $group->date_created;
    219237
     
    282300                $this->slug         = apply_filters( 'groups_group_slug_before_save',         $this->slug,         $this->id );
    283301                $this->description  = apply_filters( 'groups_group_description_before_save',  $this->description,  $this->id );
    284302                $this->status       = apply_filters( 'groups_group_status_before_save',       $this->status,       $this->id );
     303                $this->parent_id    = apply_filters( 'groups_group_parent_id_before_save',    $this->parent_id,    $this->id );
    285304                $this->enable_forum = apply_filters( 'groups_group_enable_forum_before_save', $this->enable_forum, $this->id );
    286305                $this->date_created = apply_filters( 'groups_group_date_created_before_save', $this->date_created, $this->id );
    287306
     
    324343                                        slug = %s,
    325344                                        description = %s,
    326345                                        status = %s,
     346                                        parent_id = %d,
    327347                                        enable_forum = %d,
    328348                                        date_created = %s
    329349                                WHERE
     
    334354                                        $this->slug,
    335355                                        $this->description,
    336356                                        $this->status,
     357                                        $this->parent_id,
    337358                                        $this->enable_forum,
    338359                                        $this->date_created,
    339360                                        $this->id
     
    346367                                        slug,
    347368                                        description,
    348369                                        status,
     370                                        parent_id,
    349371                                        enable_forum,
    350372                                        date_created
    351373                                ) VALUES (
    352                                         %d, %s, %s, %s, %s, %d, %s
     374                                        %d, %s, %s, %s, %s, %d, %d, %s
    353375                                )",
    354376                                        $this->creator_id,
    355377                                        $this->name,
    356378                                        $this->slug,
    357379                                        $this->description,
    358380                                        $this->status,
     381                                        $this->parent_id,
    359382                                        $this->enable_forum,
    360383                                        $this->date_created
    361384                        );
     
    710733         *                                            See {@link WP_Meta_Query::queries} for description.
    711734         *     @type array|string $value              Optional. Array or comma-separated list of group IDs. Results
    712735         *                                            will be limited to groups within the list. Default: false.
     736         *     @type array|string $parent_id          Optional. Array or comma-separated list of group IDs. Results
     737         *                                            will be limited to children of the specified groups. Default: false.
    713738         *     @type bool         $populate_extras    Whether to fetch additional information
    714739         *                                            (such as member count) about groups. Default: true.
    715740         *     @type array|string $exclude            Optional. Array or comma-separated list of group IDs.
     
    761786                        'group_type__not_in' => '',
    762787                        'meta_query'         => false,
    763788                        'include'            => false,
     789                        'parent_id'          => false,
    764790                        'populate_extras'    => true,
    765791                        'update_meta_cache'  => true,
    766792                        'exclude'            => false,
     
    835861                        $sql['include'] = " AND g.id IN ({$include})";
    836862                }
    837863
     864                if ( ! empty( $r['parent_id'] ) ) {
     865                        $parent_id        = implode( ',', wp_parse_id_list( $r['parent_id'] ) );
     866                        $sql['parent_id'] = " AND g.parent_id IN ({$parent_id})";
     867                }
     868
    838869                if ( ! empty( $r['exclude'] ) ) {
    839870                        $exclude        = implode( ',', wp_parse_id_list( $r['exclude'] ) );
    840871                        $sql['exclude'] = " AND g.id NOT IN ({$exclude})";
     
    948979                }
    949980
    950981                // Already escaped in the paginated results block.
     982                if ( ! empty( $parent_id ) ) {
     983                        $total_sql['where'][] = "g.parent_id IN ({$parent_id})";
     984                }
     985
     986                // Already escaped in the paginated results block.
    951987                if ( ! empty( $exclude ) ) {
    952988                        $total_sql['where'][] = "g.id NOT IN ({$exclude})";
    953989                }
  • src/bp-groups/classes/class-bp-groups-template.php

     
    165165                        'slug'               => false,
    166166                        'include'            => false,
    167167                        'exclude'            => false,
     168                        'parent_id'          => false,
    168169                        'search_terms'       => '',
    169170                        'group_type'         => '',
    170171                        'group_type__in'     => '',
     
    226227                                'group_type__not_in' => $group_type__not_in,
    227228                                'include'            => $include,
    228229                                'exclude'            => $exclude,
     230                                'parent_id'          => $parent_id,
    229231                                'populate_extras'    => $populate_extras,
    230232                                'update_meta_cache'  => $update_meta_cache,
    231233                                'show_hidden'        => $show_hidden,
  • tests/phpunit/testcases/groups/cache.php

     
    219219                // check if function references cache or hits the DB by comparing query count
    220220                $this->assertEquals( $first_query_count, $wpdb->num_queries );
    221221        }
     222
     223        /**
     224         * @group schema
     225         */
     226        public function test_invalidate_old_group_cache_after_db_schema_change() {
     227                $g1 = $this->factory->group->create();
     228
     229                // Fetch group object to set the cache.
     230                new BP_Groups_Group( $g1 );
     231
     232                // Set older cached version by unsetting 'parent_id' prop and resaving.
     233                $data = wp_cache_get( $g1, 'bp_groups' );
     234                unset( $data->parent_id );
     235                wp_cache_set( $g1, $data, 'bp_groups' );
     236
     237                // Now refetch group object to see if cached version is updated.
     238                $g = new BP_Groups_Group( $g1 );
     239
     240                $this->assertTrue( isset( $g->parent_id ) );
     241        }
    222242}
  • tests/phpunit/testcases/groups/class-bp-groups-group.php

     
    13831383
    13841384                $this->assertEmpty( $groups['groups'] );
    13851385        }
     1386
     1387        /**
     1388         * @group hierarchical_groups
     1389         */
     1390        public function test_get_by_parent_id() {
     1391                $g1 = $this->factory->group->create();
     1392                $g2 = $this->factory->group->create( array(
     1393                        'parent_id' => $g1,
     1394                ) );
     1395                $g3 = $this->factory->group->create( array(
     1396                        'parent_id' => $g2,
     1397                ) );
     1398                $g4 = $this->factory->group->create();
     1399
     1400                $groups = BP_Groups_Group::get( array(
     1401                        'parent_id' => $g1,
     1402                ) );
     1403
     1404                $found = wp_list_pluck( $groups['groups'], 'id' );
     1405                $this->assertEquals( array( $g2 ), $found );
     1406        }
     1407
     1408        /**
     1409         * @group hierarchical_groups
     1410         */
     1411        public function test_get_by_parent_id_ignore_grandparent() {
     1412                $g1 = $this->factory->group->create();
     1413                $g2 = $this->factory->group->create( array(
     1414                        'parent_id' => $g1,
     1415                ) );
     1416                $g3 = $this->factory->group->create( array(
     1417                        'parent_id' => $g2,
     1418                ) );
     1419                $g4 = $this->factory->group->create();
     1420
     1421                $groups = BP_Groups_Group::get( array(
     1422                        'parent_id' => $g2,
     1423                ) );
     1424
     1425                $found = wp_list_pluck( $groups['groups'], 'id' );
     1426                $this->assertEquals( array( $g3 ), $found );
     1427        }
     1428
     1429        /**
     1430         * @group hierarchical_groups
     1431         */
     1432        public function test_get_by_parent_id_array() {
     1433                $g1 = $this->factory->group->create();
     1434                $g2 = $this->factory->group->create( array(
     1435                        'parent_id' => $g1,
     1436                ) );
     1437                $g3 = $this->factory->group->create( array(
     1438                        'parent_id' => $g2,
     1439                ) );
     1440                $g4 = $this->factory->group->create();
     1441
     1442                $groups = BP_Groups_Group::get( array(
     1443                        'parent_id' => array( $g1, $g2 ),
     1444                ) );
     1445
     1446                $found = wp_list_pluck( $groups['groups'], 'id' );
     1447                $this->assertEqualSets( array( $g2, $g3 ), $found );
     1448        }
     1449
     1450        /**
     1451         * @group hierarchical_groups
     1452         */
     1453        public function test_get_by_parent_id_comma_separated_string() {
     1454                $g1 = $this->factory->group->create();
     1455                $g2 = $this->factory->group->create( array(
     1456                        'parent_id' => $g1,
     1457                ) );
     1458                $g3 = $this->factory->group->create( array(
     1459                        'parent_id' => $g2,
     1460                ) );
     1461                $g4 = $this->factory->group->create();
     1462
     1463                $groups = BP_Groups_Group::get( array(
     1464                        'parent_id' => "$g1, $g2",
     1465                ) );
     1466
     1467                $found = wp_list_pluck( $groups['groups'], 'id' );
     1468                $this->assertEqualSets( array( $g2, $g3 ), $found );
     1469        }
    13861470}
    13871471
    13881472/**
  • tests/phpunit/testcases/groups/functions.php

     
    664664                groups_accept_invite( $u2, $g );
    665665                $this->assertEquals( 0, groups_get_invite_count_for_user( $u2 ) );
    666666        }
     667
     668        /**
     669         * @group hierarchical_groups
     670         */
     671        public function test_update_orphaned_groups_on_group_delete_top_level() {
     672                $g1 = $this->factory->group->create();
     673                $g2 = $this->factory->group->create( array(
     674                        'parent_id' => $g1,
     675                ) );
     676
     677                groups_delete_group( $g1 );
     678
     679                $child = groups_get_group( array( 'group_id' => $g2 ) );
     680                $this->assertEquals( 0, $child->parent_id );
     681        }
     682
     683        /**
     684         * @group hierarchical_groups
     685         */
     686        public function test_update_orphaned_groups_on_group_delete_two_levels() {
     687                $g1 = $this->factory->group->create();
     688                $g2 = $this->factory->group->create( array(
     689                        'parent_id' => $g1,
     690                ) );
     691                $g3 = $this->factory->group->create( array(
     692                        'parent_id' => $g2,
     693                ) );
     694
     695                groups_delete_group( $g2 );
     696
     697                $child = groups_get_group( array( 'group_id' => $g3 ) );
     698                $this->assertEquals( $g1, $child->parent_id );
     699        }
    667700}