Skip to:
Content

BuddyPress.org

Ticket #4017: 4017.04.diff

File 4017.04.diff, 21.9 KB (added by Mamaduka, 4 years ago)
  • src/bp-core/bp-core-taxonomy.php

    diff --git src/bp-core/bp-core-taxonomy.php src/bp-core/bp-core-taxonomy.php
    index 7a9c4e6..af91ba7 100644
    function bp_register_default_taxonomies() { 
    2424        register_taxonomy( 'bp_member_type', 'user', array(
    2525                'public' => false,
    2626        ) );
     27
     28        // Group Type.
     29        register_taxonomy( 'bp_group_type', 'bp_group', array(
     30                'public' => false,
     31        ) );
    2732}
    2833add_action( 'bp_register_taxonomies', 'bp_register_default_taxonomies' );
    2934
  • src/bp-groups/bp-groups-cache.php

    diff --git src/bp-groups/bp-groups-cache.php src/bp-groups/bp-groups-cache.php
    index f20cd19..3a379b2 100644
    function groups_clear_group_administrator_cache_on_member_save( BP_Groups_Member 
    206206}
    207207add_action( 'groups_member_after_save', 'groups_clear_group_administrator_cache_on_member_save' );
    208208
     209/**
     210 * Clear the group type cache for group.
     211 *
     212 * Called when group is deleted.
     213 *
     214 * @since 2.5.0
     215 *
     216 * @param int $group_id The group ID.
     217 */
     218function groups_clear_group_type_cache( $group_id = 0 ) {
     219        wp_cache_delete( $group_id, 'bp_groups_group_type' );
     220}
     221add_action( 'groups_delete_group', 'groups_clear_group_type_cache' );
     222
    209223/* List actions to clear super cached pages on, if super cache is installed */
    210224add_action( 'groups_join_group',                 'bp_core_clear_cache' );
    211225add_action( 'groups_leave_group',                'bp_core_clear_cache' );
  • src/bp-groups/bp-groups-functions.php

    diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php
    index 3492d9b..6dbd2c7 100644
    function groups_remove_data_for_user( $user_id ) { 
    17471747add_action( 'wpmu_delete_user',  'groups_remove_data_for_user' );
    17481748add_action( 'delete_user',       'groups_remove_data_for_user' );
    17491749add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
     1750
     1751/** Member Types *************************************************************/
     1752
     1753/**
     1754 * Register a group type.
     1755 *
     1756 * @since 2.5.0
     1757 *
     1758 * @param string $group_type Unique string identifier for the group type.
     1759 * @param array  $args {
     1760 *     Array of arguments describing the group type.
     1761 *
     1762 *     @type array       $labels {
     1763 *         Array of labels to use in various parts of the interface.
     1764 *
     1765 *         @type string $name          Default name. Should typically be plural.
     1766 *         @type string $singular_name Singular name.
     1767 *     }
     1768 *     @type bool|string $has_directory Whether the group type should have its own type-specific directory.
     1769 *                                      Pass `true` to use the `$group_type` string as the type's slug.
     1770 *                                      Pass a string to customize the slug. Pass `false` to disable.
     1771 *                                      Default: true.
     1772 * }
     1773 * @return object|WP_Error Group type object on success, WP_Error object on failure.
     1774 */
     1775function groups_register_type( $group_type, $args = array() ) {
     1776        $bp = buddypress();
     1777
     1778        if ( isset( $bp->groups->types[ $group_type ] ) ) {
     1779                return new WP_Error( 'bp_group_type_exists', __( 'Group type already exists.', 'buddypress' ), $group_type );
     1780        }
     1781
     1782        $r = bp_parse_args( $args, array(
     1783                'labels'        => array(),
     1784                'has_directory' => true,
     1785        ), 'register_group_type' );
     1786
     1787        $group_type = sanitize_key( $group_type );
     1788
     1789        // Store the group type name as data in the object (not just as the array key).
     1790        $r['name'] = $group_type;
     1791
     1792        // Make sure the relevant labels have been filled in.
     1793        $default_name = isset( $r['labels']['name'] ) ? $r['labels']['name'] : ucfirst( $r['name'] );
     1794        $r['labels'] = array_merge( array(
     1795                'name'          => $default_name,
     1796                'singular_name' => $default_name,
     1797        ), $r['labels'] );
     1798
     1799        if ( $r['has_directory'] ) {
     1800                if ( is_string( $r['has_directory'] ) ) {
     1801                        $directory_slug = $r['has_directory'];
     1802                } else {
     1803                        $directory_slug = $group_type;
     1804                }
     1805
     1806                // Sanitize for use in URls.
     1807                $r['directory_slug'] = sanitize_title( $directory_slug );
     1808                $r['has_directory']  = true;
     1809        } else {
     1810                $r['directory_slug'] = '';
     1811                $r['has_directory']  = false;
     1812        }
     1813
     1814        $bp->groups->types[ $group_type ] = $type = (object) $r;
     1815
     1816        /**
     1817         * Fires after a group type is registered.
     1818         *
     1819         * @since 2.5.0
     1820         *
     1821         * @param  string $group_type Group type indentifier.
     1822         * @param  object $$type      Group type object.
     1823         */
     1824        do_action( 'groups_registered_type', $group_type, $type );
     1825
     1826        return $type;
     1827}
     1828
     1829/**
     1830 * Get a list of all registered group type objects.
     1831 *
     1832 * @since 2.5.0
     1833 *
     1834 * @see groups_register_type() for accepted arguments.
     1835 *
     1836 * @param array|string $args     Optional. An array of key => value arguments to match against
     1837 *                               the group type objects. Default empty array.
     1838 * @param string       $output   Optional. The type of output to return. Accepts 'names'
     1839 *                               or 'objects'. Default 'names'.
     1840 * @param string       $operator Optional. The logical operation to perform. 'or' means only one
     1841 *                               element from the array needs to match; 'and' means all elements
     1842 *                               must match. Accepts 'or' or 'and'. Default 'and'.
     1843 * @return array       $types    A list of groups type names or objects.
     1844 */
     1845function groups_get_types( $args = array(), $output = 'names', $operator = 'and' ) {
     1846        $types = buddypress()->groups->types;
     1847
     1848        $type = wp_filter_object_list( $types, $args, $operator );
     1849
     1850        /**
     1851         * Filters the array of group type objects.
     1852         *
     1853         * This filter is run before the $output filter has been applied, so that
     1854         * filtering functions have access to the entire group type objects.
     1855         *
     1856         * @since 2.5.0
     1857         *
     1858         * @param array  $types     group type objects, keyed by name.
     1859         * @param array  $args      Array of key=>value arguments for filtering.
     1860         * @param string $operator  'or' to match any of $args, 'and' to require all.
     1861         */
     1862        $types = apply_filters( 'groups_get_types', $types, $args, $operator );
     1863
     1864        if ( 'names' === $output ) {
     1865                $types = wp_list_pluck( $types, 'name' );
     1866        }
     1867
     1868        return $types;
     1869}
     1870
     1871/**
     1872 * Retrieve a group type object by name.
     1873 *
     1874 * @since 2.5.0
     1875 *
     1876 * @param string $group_type The name of the group type.
     1877 * @return object A group type object.
     1878 */
     1879function groups_get_type_object( $group_type ) {
     1880        $types = groups_get_types( array(), 'objects' );
     1881
     1882        if ( empty( $types[ $group_type ] ) ) {
     1883                return null;
     1884        }
     1885
     1886        return $types[ $group_type ];
     1887}
     1888
     1889/**
     1890 * Checks whether group type(s) exist.
     1891 *
     1892 * @param  string|array $group_types The name(s) of group type(s).
     1893 * @return bool|array   $types       Array of group types on success, false on failure.
     1894 */
     1895function groups_type_exists( $group_types ) {
     1896        if ( empty( $group_types ) ) {
     1897                return false;
     1898        }
     1899
     1900        if ( ! is_array( $group_types ) ) {
     1901                $group_types = array( $group_types );
     1902        }
     1903
     1904        $types = array();
     1905        foreach ( $group_types as $group_type ) {
     1906                // Skip, if type isn't registered.
     1907                if ( ! groups_get_type_object( $group_type ) ) {
     1908                        continue;
     1909                }
     1910
     1911                $types[] = $group_type;
     1912        }
     1913
     1914        if ( empty( $types ) ) {
     1915                return false;
     1916        }
     1917
     1918        return $types;
     1919}
     1920
     1921/**
     1922 * Set type for a group.
     1923 *
     1924 * @since 2.5.0
     1925 *
     1926 * @param int          $group       ID of the group.
     1927 * @param string|array $group_types Group type(s).
     1928 * @param bool         $append      Optional. True to append this to existing types for group,
     1929 *                            false to replace. Default: false.
     1930 * @return array $retval See {@see bp_set_object_terms()}.
     1931 */
     1932function groups_set_type( $group_id, $group_types, $append = false ) {
     1933        $types = groups_type_exists( $group_types );
     1934
     1935        if ( ! empty( $group_types ) && ! $types ) {
     1936                return false;
     1937        }
     1938
     1939        $retval = bp_set_object_terms( $group_id, $types, 'bp_group_type', $append );
     1940
     1941        // Bust the cache if the type has been updated.
     1942        if ( ! is_wp_error( $retval ) ) {
     1943                wp_cache_delete( $group_id, 'bp_groups_group_type' );
     1944
     1945                /**
     1946                 * Fires just after a group type has been changed.
     1947                 *
     1948                 * @since 2.2.0
     1949                 *
     1950                 * @param int          $group_id    ID of the group whose group type has been updated.
     1951                 * @param string|array $group_types Group type(s).
     1952                 * @param bool         $append      Whether the type is being appended to existing types.
     1953                 */
     1954                do_action( 'groups_set_type', $group_id, $group_types, $append );
     1955        }
     1956
     1957        return $retval;
     1958}
     1959
     1960/**
     1961 * Get type for a group.
     1962 *
     1963 * @since 2.5.0
     1964 *
     1965 * @param int  $group_id ID of the group.
     1966 * @param bool $single  Optional. Whether to return a single type string. If multiple types are found
     1967 *                      for the group, the oldest one will be returned. Default: true.
     1968 * @return string|array|bool On success, returns a single group type (if $single is true) or an array of group
     1969 *                           types (if $single is false). Returns false on failure.
     1970 */
     1971function groups_get_type( $group_id, $single = true ) {
     1972        $types = wp_cache_get( $group_id, 'bp_groups_group_type' );
     1973
     1974        if ( false === $types ) {
     1975                $types = bp_get_object_terms( $group_id, 'bp_group_type' );
     1976
     1977                if ( ! is_wp_error( $types ) ) {
     1978                        $types = wp_list_pluck( $types, 'name' );
     1979                        wp_cache_set( $group_id, $types, 'bp_groups_group_type' );
     1980                }
     1981        }
     1982
     1983        $type = false;
     1984        if ( ! empty( $types ) ) {
     1985                if ( $single ) {
     1986                        $type = end( $types );
     1987                } else {
     1988                        $type = $types;
     1989                }
     1990        }
     1991
     1992        /**
     1993         * Filter's a groups's group type(s).
     1994         *
     1995         * @since 2.5.0
     1996         *
     1997         * @param string $type     Group type.
     1998         * @param int    $group_id ID of the group.
     1999         * @param bool   $single   Whether to return a single type srting, or an array.
     2000         */
     2001        return apply_filters( 'groups_get_type', $type, $group_id, $single );
     2002}
     2003
     2004/**
     2005 * Remove type for a group.
     2006 *
     2007 * @since 2.5.0
     2008 *
     2009 * @param int          $group       ID of the user.
     2010 * @param string|array $group_types Group type(s).
     2011 * @return bool|WP_Error            True on success. False or WP_Error on failure.
     2012 */
     2013function groups_remove_type( $group_id, $group_types ) {
     2014        if ( ! $types = groups_type_exists( $group_types ) ) {
     2015                return false;
     2016        }
     2017
     2018        $deleted = bp_remove_object_terms( $group_id, $types, 'bp_group_type' );
     2019
     2020        // Bust the case, if the type has been removed.
     2021        if ( ! is_wp_error( $deleted ) ) {
     2022                wp_cache_delete( $group_id, 'bp_groups_group_type' );
     2023
     2024                /**
     2025                 * Fire just after a group's group type has been removed.
     2026                 *
     2027                 * @since 2.5.0
     2028                 *
     2029                 * @param int          $group       ID of the group whose group type has been removed.
     2030                 * @param string|array $group_types Group type(s).
     2031                 */
     2032                do_action( 'groups_remove_type', $group_id, $group_types );
     2033        }
     2034
     2035        return $deleted;
     2036}
     2037
     2038/**
     2039 * Check whether the given group has a certain group type.
     2040 *
     2041 * @param  int    $group_id   ID of the group.
     2042 * @param  srting $group_type Group type.
     2043 * @return bool   Whether the group has the give group type.
     2044 */
     2045function groups_has_type( $group_id, $group_type ) {
     2046        if ( empty( $group_type ) || ! groups_get_type_object( $group_type ) ) {
     2047                return false;
     2048        }
     2049
     2050        // Get all group's group types.
     2051        $types = groups_get_type( $group_id, false );
     2052
     2053        if ( ! is_array( $types ) ) {
     2054                return false;
     2055        }
     2056
     2057        return in_array( $group_type, $types );
     2058}
     2059
     2060/**
     2061 * Delete a group's type when the group is deleted.
     2062 *
     2063 * @param  int   $group_id ID of the group.
     2064 * @return array $value    See {@see group_set_type()}.
     2065 */
     2066function groups_remove_type_on_group_delete( $group_id = 0 ) {
     2067        groups_set_type( $group_id, '' );
     2068}
     2069add_action( 'groups_delete_group', 'groups_remove_type_on_group_delete' );
     2070 No newline at end of file
  • src/bp-groups/classes/class-bp-groups-group.php

    diff --git src/bp-groups/classes/class-bp-groups-group.php src/bp-groups/classes/class-bp-groups-group.php
    index fb9fd39..92a28e6 100644
    class BP_Groups_Group { 
    643643         *
    644644         * @param array $args {
    645645         *     Array of parameters. All items are optional.
    646          *     @type string       $type              Optional. Shorthand for certain orderby/
    647          *                                           order combinations. 'newest', 'active', 'popular',
    648          *                                           'alphabetical', 'random'. When present, will override
    649          *                                           orderby and order params. Default: null.
    650          *     @type string       $orderby           Optional. Property to sort by.
    651          *                                           'date_created', 'last_activity', 'total_member_count',
    652          *                                           'name', 'random'. Default: 'date_created'.
    653          *     @type string       $order             Optional. Sort order. 'ASC' or 'DESC'.
    654          *                                           Default: 'DESC'.
    655          *     @type int          $per_page          Optional. Number of items to return per page
    656          *                                           of results. Default: null (no limit).
    657          *     @type int          $page              Optional. Page offset of results to return.
    658          *                                           Default: null (no limit).
    659          *     @type int          $user_id           Optional. If provided, results will be limited to groups
    660          *                                           of which the specified user is a member. Default: null.
    661          *     @type string       $search_terms      Optional. If provided, only groups whose names
    662          *                                           or descriptions match the search terms will be
    663          *                                           returned. Default: false.
    664          *     @type array        $meta_query        Optional. An array of meta_query conditions.
    665          *                                           See {@link WP_Meta_Query::queries} for description.
    666          *     @type array|string $value             Optional. Array or comma-separated list of group IDs.
    667          *                                           Results will be limited to groups within the
    668          *                                           list. Default: false.
    669          *     @type bool         $populate_extras   Whether to fetch additional information
    670          *                                           (such as member count) about groups. Default: true.
    671          *     @type array|string $exclude           Optional. Array or comma-separated list of group IDs.
    672          *                                           Results will exclude the listed groups. Default: false.
    673          *     @type bool         $update_meta_cache Whether to pre-fetch groupmeta for
    674          *                                           the returned groups. Default: true.
    675          *     @type bool         $show_hidden       Whether to include hidden groups in results. Default: false.
     646         *     @type string       $type                Optional. Shorthand for certain orderby/
     647         *                                             order combinations. 'newest', 'active', 'popular',
     648         *                                             'alphabetical', 'random'. When present, will override
     649         *                                             orderby and order params. Default: null.
     650         *     @type string       $orderby             Optional. Property to sort by.
     651         *                                             'date_created', 'last_activity', 'total_member_count',
     652         *                                             'name', 'random'. Default: 'date_created'.
     653         *     @type string       $order               Optional. Sort order. 'ASC' or 'DESC'.
     654         *                                             Default: 'DESC'.
     655         *     @type int          $per_page            Optional. Number of items to return per page
     656         *                                             of results. Default: null (no limit).
     657         *     @type int          $page                Optional. Page offset of results to return.
     658         *                                             Default: null (no limit).
     659         *     @type int          $user_id             Optional. If provided, results will be limited to groups
     660         *                                             of which the specified user is a member. Default: null.
     661         *     @type string       $search_terms        Optional. If provided, only groups whose names
     662         *                                             or descriptions match the search terms will be
     663         *                                             returned. Default: false.
     664         *     @type array|string $group_type          Array or comma-separated list of group types to limit results to.
     665         *     @type array|string $group_type__in      Array or comma-separated list of group types to limit results to.
     666         *     @type array|string $group_type__not_in  Array or comma-separated list of group types,that will be
     667         *                                             excluded from results.
     668         *     @type array        $meta_query          Optional. An array of meta_query conditions.
     669         *                                             See {@link WP_Meta_Query::queries} for description.
     670         *     @type array|string $value               Optional. Array or comma-separated list of group IDs.
     671         *                                             Results will be limited to groups within the
     672         *                                             list. Default: false.
     673         *     @type bool         $populate_extras     Whether to fetch additional information
     674         *                                             (such as member count) about groups. Default: true.
     675         *     @type array|string $exclude             Optional. Array or comma-separated list of group IDs.
     676         *                                             Results will exclude the listed groups. Default: false.
     677         *     @type bool         $update_meta_cache   Whether to pre-fetch groupmeta for
     678         *                                             the returned groups. Default: true.
     679         *     @type bool         $show_hidden         Whether to include hidden groups in results. Default: false.
    676680         * }
    677681         * @return array {
    678682         *     @type array $groups Array of group objects returned by the
    class BP_Groups_Group { 
    705709                }
    706710
    707711                $defaults = array(
    708                         'type'              => null,
    709                         'orderby'           => 'date_created',
    710                         'order'             => 'DESC',
    711                         'per_page'          => null,
    712                         'page'              => null,
    713                         'user_id'           => 0,
    714                         'search_terms'      => false,
    715                         'meta_query'        => false,
    716                         'include'           => false,
    717                         'populate_extras'   => true,
    718                         'update_meta_cache' => true,
    719                         'exclude'           => false,
    720                         'show_hidden'       => false,
     712                        'type'               => null,
     713                        'orderby'            => 'date_created',
     714                        'order'              => 'DESC',
     715                        'per_page'           => null,
     716                        'page'               => null,
     717                        'user_id'            => 0,
     718                        'search_terms'       => false,
     719                        'group_type'         => '',
     720                        'group_type__in'     => '',
     721                        'group_type__not_in' => '',
     722                        'meta_query'         => false,
     723                        'include'            => false,
     724                        'populate_extras'    => true,
     725                        'update_meta_cache'  => true,
     726                        'exclude'            => false,
     727                        'show_hidden'        => false,
    721728                );
    722729
    723730                $r = wp_parse_args( $args, $defaults );
    class BP_Groups_Group { 
    761768                        $sql['meta'] = $meta_query_sql['where'];
    762769                }
    763770
     771                // Only use 'group_type__in', if 'group_type' is not set.
     772                if ( empty( $r['group_type'] ) && ! empty( $r['group_type__in']) ) {
     773                        $r['group_type'] = $r['group_type__in'];
     774                }
     775
     776                // Group types to exclude. This has priority over inclusions.
     777                if ( ! empty( $r['group_type__not_in'] ) ) {
     778                        $group_type_clause = self::get_sql_clause_for_group_types($r['group_type__not_in'], 'NOT IN' );
     779
     780                // Group types to include.
     781                } elseif ( ! empty( $r['group_type'] ) ) {
     782                        $group_type_clause = self::get_sql_clause_for_group_types($r['group_type'], 'IN' );
     783                }
     784
     785                if ( ! empty( $group_type_clause ) ) {
     786                        $sql['group_type'] = $group_type_clause;
     787                }
     788
    764789                if ( ! empty( $r['user_id'] ) ) {
    765790                        $sql['user'] = $wpdb->prepare( " AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id'] );
    766791                }
    class BP_Groups_Group { 
    872897                        $total_sql['where'][] = $meta_query_clause;
    873898                }
    874899
     900                // Trim leading 'AND' to match $total_sql query style.
     901                if ( ! empty( $group_type_clause ) ) {
     902                        $total_sql['where'][] = preg_replace( '/^\s*AND\s*/', '', $group_type_clause );
     903                }
     904
    875905                // Already escaped in the paginated results block.
    876906                if ( ! empty( $include ) ) {
    877907                        $total_sql['where'][] = "g.id IN ({$include})";
    class BP_Groups_Group { 
    15631593
    15641594                return $ids;
    15651595        }
     1596
     1597        /**
     1598         * Get SQL clause for group type(s).
     1599         *
     1600         * @since 2.5.0
     1601         *
     1602         * @param  string|array $group_types Group type(s).
     1603         * @param  string       $operator    'IN' or 'NOT IN'.
     1604         * @return string       $clause      SQL clause.
     1605         */
     1606        protected static function get_sql_clause_for_group_types( $group_types, $operator ) {
     1607                global $wpdb;
     1608
     1609                // Sanitize operator.
     1610                if ( 'NOT IN' !== $operator ) {
     1611                        $operator = 'IN';
     1612                }
     1613
     1614                // Parse and sanitize types.
     1615                if ( ! is_array( $group_types ) ) {
     1616                        $group_types = preg_split( '/[,\s+]/', $group_types );
     1617                }
     1618
     1619                $types = groups_type_exists( $group_types );
     1620                if ( false === $types ) {
     1621                        $types = array();
     1622                }
     1623
     1624                $tax_query = new WP_Tax_Query( array(
     1625                        array(
     1626                                'taxonomy' => 'bp_group_type',
     1627                                'field'    => 'name',
     1628                                'operator' => $operator,
     1629                                'terms'    => $types,
     1630                        ),
     1631                ) );
     1632
     1633                $switched = false;
     1634                if ( ! bp_is_root_blog() ) {
     1635                        switch_to_blog( bp_get_root_blog_id() );
     1636                        $switched = true;
     1637                }
     1638
     1639                $sql_clauses = $tax_query->get_sql( 'g', 'id' );
     1640
     1641                if ( $switched ) {
     1642                        restore_current_blog();
     1643                }
     1644
     1645                $clause = '';
     1646
     1647                // The no_results clauses are the same between IN and NOT IN.
     1648                if ( false !== strpos( $sql_clauses['where'], '0 = 1' ) ) {
     1649                        $clause = $sql_clauses['where'];
     1650
     1651                // The tax_query clause generated for NOT IN can be used almost as-is.
     1652                } elseif ( 'NOT IN' === $operator ) {
     1653                        $clause = $sql_clauses['where'];
     1654
     1655                // IN clauses must be converted to a subquery.
     1656                } elseif ( preg_match( '/' . $wpdb->term_relationships . '\.term_taxonomy_id IN \([0-9, ]+\)/', $sql_clauses['where'], $matches ) ) {
     1657                        $clause = " AND g.id IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
     1658                }
     1659
     1660                return $clause;
     1661        }
    15661662}