Skip to:
Content

BuddyPress.org

Ticket #4017: 4017.03.patch

File 4017.03.patch, 75.9 KB (added by imath, 5 years ago)
  • src/bp-core/bp-core-actions.php

    diff --git src/bp-core/bp-core-actions.php src/bp-core/bp-core-actions.php
    index 2bb2334..06e3c11 100644
    add_action( 'bp_loaded', 'bp_register_theme_directory', 14 ); 
    6767add_action( 'bp_init', 'bp_core_set_uri_globals',    2  );
    6868add_action( 'bp_init', 'bp_setup_globals',           4  );
    6969add_action( 'bp_init', 'bp_setup_canonical_stack',   5  );
     70add_action( 'bp_init', 'bp_register_taxonomies',     5  );
    7071add_action( 'bp_init', 'bp_setup_nav',               6  );
    7172add_action( 'bp_init', 'bp_setup_title',             8  );
    7273add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
    add_action( 'bp_template_redirect', 'bp_get_request', 10 ); 
    9697 */
    9798add_action( 'bp_after_setup_theme', 'bp_load_theme_functions', 1 );
    9899
     100/**
     101 * Start the BP Term class
     102 */
     103add_action( 'bp_core_setup_globals', array( 'BP_Terms', 'start' ) );
     104
    99105// Load the admin
    100106if ( is_admin() ) {
    101107        add_action( 'bp_loaded', 'bp_admin' );
  • src/bp-core/bp-core-catchuri.php

    diff --git src/bp-core/bp-core-catchuri.php src/bp-core/bp-core-catchuri.php
    index c9b6be5..162871d 100644
    function bp_core_load_template( $templates ) { 
    396396
    397397                // Template was located, lets set this as a valid page and not a 404.
    398398                status_header( 200 );
    399                 $wp_query->is_page     = true;
    400                 $wp_query->is_singular = true;
    401                 $wp_query->is_404      = false;
     399                $wp_query->queried_object    = null;
     400                $wp_query->queried_object_id = 0;
     401                $wp_query->is_page           = true;
     402                $wp_query->is_singular       = true;
     403                $wp_query->is_404            = false;
    402404
    403405                do_action( 'bp_core_pre_load_template', $located_template );
    404406
    function bp_core_load_template( $templates ) { 
    417419                // The rest will be done by bp_theme_compat_reset_post() later.
    418420                if ( is_buddypress() ) {
    419421                        status_header( 200 );
    420                         $wp_query->is_page     = true;
    421                         $wp_query->is_singular = true;
    422                         $wp_query->is_404      = false;
     422                        $wp_query->queried_object    = null;
     423                        $wp_query->queried_object_id = 0;
     424                        $wp_query->is_page           = true;
     425                        $wp_query->is_singular       = true;
     426                        $wp_query->is_404            = false;
    423427                }
    424428
    425429                do_action( 'bp_setup_theme_compat' );
  • src/bp-core/bp-core-classes.php

    diff --git src/bp-core/bp-core-classes.php src/bp-core/bp-core-classes.php
    index 1244cdf..24e5f6d 100644
    class BP_Members_Suggestions extends BP_Suggestions { 
    27002700                return apply_filters( 'bp_members_suggestions_get_suggestions', $results, $this );
    27012701        }
    27022702}
     2703
     2704/**
     2705 * Use WordPress term/taxonomy functions, forcing the table prefix to be the one of root blog id.
     2706 *
     2707 * This is needed for Multisite configs in case a component taxonomy is used from a child blog.
     2708 *
     2709 * @since BuddyPress (?)
     2710 */
     2711class BP_Terms {
     2712
     2713        /**
     2714         * Start the class
     2715         *
     2716         * @access public
     2717         * @since BuddyPress (?)
     2718         * @static
     2719         */
     2720        public static function start() {
     2721                $bp = buddypress();
     2722
     2723                if ( empty( $bp->terms ) ) {
     2724                        $bp->terms = new self;
     2725                }
     2726
     2727                return $bp->terms;
     2728        }
     2729
     2730        /**
     2731         * Constructor
     2732         *
     2733         * @access public
     2734         * @since BuddyPress (?)
     2735         */
     2736        public function __construct() {}
     2737
     2738        /**
     2739         * Set needed $wpdb->tables to be the one of root blog id
     2740         *
     2741         * @access public
     2742         * @since BuddyPress (?)
     2743         * @static
     2744         */
     2745        public static function set_tables() {
     2746                switch_to_blog( bp_get_root_blog_id() );
     2747        }
     2748
     2749        /**
     2750         * Reset $wpdb->tables to the one set by WordPress
     2751         *
     2752         * @access public
     2753         * @since BuddyPress (?)
     2754         * @static
     2755         */
     2756        public static function reset_tables() {
     2757                restore_current_blog();
     2758        }
     2759
     2760        /**
     2761         * Update term count
     2762         *
     2763         * @access public
     2764         * @since BuddyPress (?)
     2765         * @static
     2766         */
     2767        public static function update_term_count( $terms, $taxonomy ) {
     2768                self::set_tables();
     2769                _update_generic_term_count( $terms, $taxonomy );
     2770                self::reset_tables();
     2771        }
     2772
     2773        /**
     2774         * Get group tags
     2775         *
     2776         * @access public
     2777         * @since BuddyPress (?)
     2778         * @static
     2779         *
     2780         * @uses wp_get_object_terms()
     2781         */
     2782        public static function get_object_terms( $object_ids, $taxonomies, $args = array() ) {
     2783                self::set_tables();
     2784                $return = wp_get_object_terms( $object_ids, $taxonomies, $args );
     2785                self::reset_tables();
     2786                return $return;
     2787        }
     2788
     2789        /**
     2790         * Set group tags
     2791         *
     2792         * @access public
     2793         * @since BuddyPress (?)
     2794         * @static
     2795         *
     2796         * @uses wp_set_object_terms()
     2797         */
     2798        public static function set_object_terms( $object_id, $terms, $taxonomy, $append ) {
     2799                self::set_tables();
     2800                $return = wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
     2801                self::reset_tables();
     2802                return $return;
     2803        }
     2804
     2805        /**
     2806         * Remove group tags
     2807         *
     2808         * @access public
     2809         * @since BuddyPress (?)
     2810         * @static
     2811         *
     2812         * @uses wp_remove_object_terms()
     2813         */
     2814        public static function remove_object_terms( $object_id, $terms, $taxonomy ) {
     2815                self::set_tables();
     2816                $return = wp_remove_object_terms( $object_id, $terms, $taxonomy );
     2817                self::reset_tables();
     2818                return $return;
     2819        }
     2820
     2821        /**
     2822         * Remove all group relationships
     2823         *
     2824         * @access public
     2825         * @since BuddyPress (?)
     2826         * @static
     2827         *
     2828         * @uses wp_delete_object_term_relationships()
     2829         */
     2830        public static function delete_object_term_relationships( $object_id, $taxonomies = 'bp_group_tags' ) {
     2831                self::set_tables();
     2832                $return = wp_delete_object_term_relationships( $object_id, $taxonomies );
     2833                self::reset_tables();
     2834                return $return;
     2835        }
     2836
     2837        /**
     2838         * Get group ids for a given tag
     2839         *
     2840         * @access public
     2841         * @since BuddyPress (?)
     2842         * @static
     2843         *
     2844         * @uses get_objects_in_term()
     2845         */
     2846        public static function get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
     2847                self::set_tables();
     2848                $return = get_objects_in_term( $term_ids, $taxonomies, $args );
     2849                self::reset_tables();
     2850                return $return;
     2851        }
     2852
     2853        /**
     2854         * Get all Term data from database by Term ID
     2855         *
     2856         * @access public
     2857         * @since BuddyPress (?)
     2858         * @static
     2859         *
     2860         * @uses get_term()
     2861         */
     2862        public static function get_term( $term, $taxonomy, $output, $filter ) {
     2863                self::set_tables();
     2864                $return = get_term( $term, $taxonomy, $output, $filter );
     2865                self::reset_tables();
     2866                return $return;
     2867        }
     2868
     2869        /**
     2870         * Get all terms for a given taxonomy
     2871         *
     2872         * @access public
     2873         * @since BuddyPress (?)
     2874         * @static
     2875         *
     2876         * @uses get_terms()
     2877         */
     2878        public static function get_terms( $taxonomies, $args = array() ) {
     2879                self::set_tables();
     2880                $return = get_terms( $taxonomies, $args );
     2881                self::reset_tables();
     2882                return $return;
     2883        }
     2884
     2885        /**
     2886         * Get all terms to edit for a given taxonomy
     2887         *
     2888         * @access public
     2889         * @since BuddyPress (?)
     2890         * @static
     2891         *
     2892         * @uses get_terms_to_edit()
     2893         */
     2894        public static function get_terms_to_edit( $post_id, $taxonomy ) {
     2895                self::set_tables();
     2896                $return = get_terms_to_edit( $post_id, $taxonomy );
     2897                self::reset_tables();
     2898                return $return;
     2899        }
     2900
     2901        /**
     2902         * Insert a term based on arguments provided.
     2903         *
     2904         * @access public
     2905         * @since BuddyPress (?)
     2906         * @static
     2907         *
     2908         * @uses wp_insert_term()
     2909         */
     2910        public static function insert_term( $term, $taxonomy, $args = array() ) {
     2911                self::set_tables();
     2912                $return = wp_insert_term( $term, $taxonomy, $args );
     2913                self::reset_tables();
     2914                return $return;
     2915        }
     2916
     2917        /**
     2918         * Update term based on arguments provided.
     2919         *
     2920         * @access public
     2921         * @since BuddyPress (?)
     2922         * @static
     2923         *
     2924         * @uses wp_update_term()
     2925         */
     2926        public static function update_term( $term_id, $taxonomy, $args = array() ) {
     2927                self::set_tables();
     2928                $return = wp_update_term( $term_id, $taxonomy, $args );
     2929                self::reset_tables();
     2930                return $return;
     2931        }
     2932
     2933        /**
     2934         * Delete term based on arguments provided.
     2935         *
     2936         * @access public
     2937         * @since BuddyPress (?)
     2938         * @static
     2939         *
     2940         * @uses wp_delete_term()
     2941         */
     2942        public static function delete_term( $term_id, $taxonomy, $args = array() ) {
     2943                self::set_tables();
     2944                $return = wp_delete_term( $term_id, $taxonomy, $args );
     2945                self::reset_tables();
     2946                return $return;
     2947        }
     2948
     2949        /**
     2950         * Get term thanks to a specific field
     2951         *
     2952         * @access public
     2953         * @since BuddyPress (?)
     2954         * @static
     2955         *
     2956         * @uses get_term_by()
     2957         */
     2958        public static function get_term_by( $field, $value, $taxonomy, $output, $filter ) {
     2959                self::set_tables();
     2960                $return = get_term_by( $field, $value, $taxonomy, $output, $filter );
     2961                self::reset_tables();
     2962                return $return;
     2963        }
     2964
     2965        /**
     2966         * Get the term link
     2967         *
     2968         * @access public
     2969         * @since BuddyPress (?)
     2970         * @static
     2971         *
     2972         * @uses get_term_link()
     2973         */
     2974        public static function get_term_link( $term, $taxonomy ) {
     2975                $root_blog = bp_is_root_blog();
     2976
     2977                if ( ! $root_blog ) {
     2978                        switch_to_blog( bp_get_root_blog_id() );
     2979                }
     2980
     2981                $return = get_term_link( $term, $taxonomy );
     2982
     2983                if ( ! $root_blog ) {
     2984                        restore_current_blog();
     2985                }
     2986
     2987                return $return;
     2988        }
     2989
     2990        /**
     2991         * Copy WordPress get_the_term_list without using get_the_terms()
     2992         * function as it checks for an existing post.
     2993         *
     2994         * @access public
     2995         * @since BuddyPress (?)
     2996         * @static
     2997         *
     2998         * @uses self::get_object_terms()
     2999         * @uses self::get_term_link()
     3000         */
     3001        public static function get_the_term_list( $object_id, $taxonomy, $before, $sep, $after ) {
     3002
     3003                $terms = self::get_object_terms( $object_id, $taxonomy );
     3004
     3005                if ( is_wp_error( $terms ) )
     3006                        return $terms;
     3007
     3008                if ( empty( $terms ) )
     3009                        return false;
     3010
     3011                self::set_tables();
     3012                foreach ( $terms as $term ) {
     3013                        $link = get_term_link( $term, $taxonomy );
     3014                        if ( is_wp_error( $link ) )
     3015                                return $link;
     3016                        $term_links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';
     3017                }
     3018                self::reset_tables();
     3019
     3020                $term_links = apply_filters( "term_links-$taxonomy", $term_links );
     3021
     3022                return $before . join( $sep, $term_links ) . $after;
     3023        }
     3024
     3025        /**
     3026         * Get the sql for a Tax Query
     3027         *
     3028         * @access public
     3029         * @since BuddyPress (?)
     3030         * @static
     3031         *
     3032         * @uses get_term_link()
     3033         */
     3034        public static function get_tax_sql( $tax_query, $primary_table, $primary_id_column ) {
     3035                global $wpdb;
     3036                self::set_tables();
     3037                $return = get_tax_sql( $tax_query, $primary_table, $primary_id_column );
     3038                self::reset_tables();
     3039                return $return;
     3040        }
     3041}
  • src/bp-core/bp-core-component.php

    diff --git src/bp-core/bp-core-component.php src/bp-core/bp-core-component.php
    index 539359f..96a1d64 100644
    class BP_Component { 
    554554         *
    555555         * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_taxonomies'.
    556556         */
    557         public function register_taxonomies() {
     557        public function register_taxonomies( $taxonomy = '', $object_type = '', $args = array(), $network = false ) {
     558                if ( ! bp_is_root_blog() && empty( $network ) ) {
     559                        return;
     560                }
     561
     562                if ( ! taxonomy_exists( $taxonomy ) && ! empty( $object_type ) && ! empty( $args ) ) {
     563                        register_taxonomy( $taxonomy, $object_type, $args );
     564                }
     565
    558566                do_action( 'bp_' . $this->id . '_register_taxonomies' );
    559567        }
    560568
  • src/bp-core/bp-core-dependency.php

    diff --git src/bp-core/bp-core-dependency.php src/bp-core/bp-core-dependency.php
    index 8ce93a7..e428018 100644
    function bp_setup_title() { 
    6868}
    6969
    7070/**
     71 * Fire the 'bp_register_taxonomies' action, where plugins should register bp_terms.
     72 */
     73function bp_register_taxonomies() {
     74        do_action( 'bp_register_taxonomies' );
     75}
     76
     77/**
    7178 * Fire the 'bp_register_widgets' action, where plugins should register widgets.
    7279 */
    7380function bp_setup_widgets() {
  • src/bp-core/bp-core-functions.php

    diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php
    index 5b93f9c..5688f60 100644
    function bp_core_get_suggestions( $args ) { 
    20342034        }
    20352035
    20362036        return apply_filters( 'bp_core_get_suggestions', $retval, $args );
    2037 }
    2038  No newline at end of file
     2037}
     2038
     2039/** BuddyPress Terms **********************************************************/
     2040
     2041/**
     2042 * Get all Term data from database by Term ID.
     2043 *
     2044 * WordPress get_term function for BuddyPress root blog id
     2045 * @see get_term() for the full description.
     2046 *
     2047 * @since BuddyPress (?)
     2048 *
     2049 * @uses BP_Terms::get_term().
     2050 *
     2051 * @param int|object $term If integer, will get from database. If object will apply filters and return $term.
     2052 * @param string $taxonomy Taxonomy name that $term is part of.
     2053 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
     2054 * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
     2055 * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not
     2056 * exist then WP_Error will be returned.
     2057 */
     2058function bp_core_get_term( $term, $taxonomy, $output = OBJECT, $filter = 'raw' ) {
     2059        return BP_Terms::get_term( $term, $taxonomy, $output, $filter );
     2060}
     2061
     2062/**
     2063 * Retrieve the terms in a given taxonomy or list of taxonomies.
     2064 *
     2065 * WordPress get_terms function for BuddyPress root blog id
     2066 * @see get_terms() for the list of possible args.
     2067 *
     2068 * @since BuddyPress (?)
     2069 *
     2070 * @uses BP_Terms::get_terms().
     2071 *
     2072 * @param string|array $taxonomies Taxonomy name or list of Taxonomy names.
     2073 * @param string|array $args The values of what to search for when returning terms
     2074 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
     2075 */
     2076function bp_core_get_terms( $taxonomies = '', $args = '' ) {
     2077        return BP_Terms::get_terms( $taxonomies, $args );
     2078}
     2079
     2080/**
     2081 * Retrieve the terms in a given taxonomy to edit.
     2082 *
     2083 * WordPress get_terms_to_edit function for BuddyPress root blog id
     2084 * @see get_terms_to_edit() for the list of possible args.
     2085 *
     2086 * @since BuddyPress (?)
     2087 *
     2088 * @uses BP_Terms::get_terms().
     2089 *
     2090 * @param int $object_id Object ID.
     2091 * @param string $taxonomy The taxonomy to which to edit the term
     2092 * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist.
     2093 */
     2094function bp_core_get_terms_to_edit( $object_id, $taxonomy = '' ) {
     2095        return BP_Terms::get_terms_to_edit( $object_id, $taxonomy );
     2096}
     2097
     2098/**
     2099 * Add a new term to the database.
     2100 *
     2101 * WordPress wp_insert_term function for BuddyPress root blog id
     2102 * @see wp_insert_term() for the list of possible args.
     2103 *
     2104 * @since BuddyPress (?)
     2105 *
     2106 * @uses BP_Terms::insert_term().
     2107 *
     2108 * @param string       $term     The term to add or update.
     2109 * @param string       $taxonomy The taxonomy to which to add the term
     2110 * @param array|string $args
     2111 * @return array|WP_Error An array containing the term_id and term_taxonomy_id, WP_Error otherwise.
     2112 */
     2113function bp_core_insert_term( $term, $taxonomy, $args = array() ) {
     2114        return BP_Terms::insert_term( $term, $taxonomy, $args );
     2115}
     2116
     2117/**
     2118 * Update term based on arguments provided.
     2119 *
     2120 * WordPress wp_update_term function for BuddyPress root blog id
     2121 * @see wp_update_term() for the list of possible args.
     2122 *
     2123 * @since BuddyPress (?)
     2124 *
     2125 * @uses BP_Terms::update_term().
     2126 *
     2127 * @param int $term_id The ID of the term
     2128 * @param string $taxonomy The context in which to relate the term to the object.
     2129 * @param array|string $args Overwrite term field values
     2130 * @return array|WP_Error Returns Term ID and Taxonomy Term ID
     2131 */
     2132function bp_core_update_term( $term_id, $taxonomy, $args = array() ) {
     2133        return BP_Terms::update_term( $term_id, $taxonomy, $args );
     2134}
     2135
     2136/**
     2137 * Removes a term from the database.
     2138 *
     2139 * WordPress wp_update_term function for BuddyPress root blog id
     2140 * @see wp_delete_term() for the list of possible args.
     2141 *
     2142 * @since BuddyPress (?)
     2143 *
     2144 * @uses BP_Terms::delete_term().
     2145 *
     2146 * @param int $term_id Term ID
     2147 * @param string $taxonomy Taxonomy Name
     2148 * @param array|string $args Optional. Change 'default' term id and override found term ids.
     2149 * @return bool|WP_Error Returns false if not term; true if completes delete action.
     2150 */
     2151function bp_core_delete_term( $term_id, $taxonomy, $args = array() ) {
     2152        return BP_Terms::delete_term( $term_id, $taxonomy, $args );
     2153}
     2154
     2155/**
     2156 * Get all Term data from database by Term field and data.
     2157 *
     2158 * WordPress get_term_by function for BuddyPress root blog id
     2159 * @see get_term_by() for the list of possible args.
     2160 *
     2161 * @since BuddyPress (?)
     2162 *
     2163 * @uses BP_Terms::get_term_by().
     2164 *
     2165 * @param string $field Either 'slug', 'name', 'id' (term_id), or 'term_taxonomy_id'
     2166 * @param string|int $value Search for this term value
     2167 * @param string $taxonomy Taxonomy Name
     2168 * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
     2169 * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
     2170 * @return mixed Term Row from database. Will return false if $taxonomy does not exist or $term was not found.
     2171 */
     2172function bp_core_get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) {
     2173        return BP_Terms::get_term_by( $field, $value, $taxonomy, $output, $filter );
     2174}
     2175
     2176/**
     2177 * Generates a permalink for a taxonomy term archive.
     2178 *
     2179 * WordPress get_term_link function for BuddyPress root blog id
     2180 * @see get_term_link()
     2181 *
     2182 * @since BuddyPress (?)
     2183 *
     2184 * @uses BP_Terms::get_term_link().
     2185 *
     2186 * @param object|int|string $term
     2187 * @param string $taxonomy (optional if $term is object)
     2188 * @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist.
     2189 */
     2190function bp_core_get_term_link( $term, $taxonomy = '' ) {
     2191        return BP_Terms::get_term_link( $term, $taxonomy );
     2192}
     2193
     2194/**
     2195 * Retrieve a BuddyPress item terms as a list with specified format.
     2196 *
     2197 * WordPress get_the_term_list function adapted for BuddyPress
     2198 *
     2199 * @since BuddyPress (?)
     2200 *
     2201 * @uses BP_Terms::get_the_term_list().
     2202 *
     2203 * @param int $id BuddyPress item id (for instance a group id).
     2204 * @param string $taxonomy Taxonomy name.
     2205 * @param string $before Optional. Before list.
     2206 * @param string $sep Optional. Separate items using this.
     2207 * @param string $after Optional. After list.
     2208 * @return string|bool|WP_Error A list of terms on success, false or WP_Error on failure.
     2209 */
     2210function bp_core_get_the_term_list( $object_id, $taxonomy = '', $before = '', $sep = '', $after = '' ) {
     2211        return BP_Terms::get_the_term_list( $object_id, $taxonomy, $before, $sep, $after );
     2212}
     2213
     2214/**
     2215 * Retrieve object_ids of valid taxonomy and term.
     2216 *
     2217 * WordPress get_objects_in_term function for BuddyPress root blog id
     2218 * @see get_objects_in_term() for the list of possible args.
     2219 *
     2220 * @since BuddyPress (?)
     2221 *
     2222 * @uses BP_Terms::get_objects_in_term().
     2223 *
     2224 * @param int|array $term_ids Term id or array of term ids of terms that will be used
     2225 * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names
     2226 * @param array|string $args Change the order of the object_ids, either ASC or DESC
     2227 * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success
     2228 *      the array can be empty meaning that there are no $object_ids found or it will return the $object_ids found.
     2229 */
     2230function bp_core_get_objects_in_term( $term_ids, $taxonomies = '', $args = array() ) {
     2231        return BP_Terms::get_objects_in_term( $term_ids, $taxonomies, $args );
     2232}
     2233
     2234/**
     2235 * Retrieves the terms associated with the given object(s), in the supplied taxonomies.
     2236 *
     2237 * WordPress wp_get_object_terms function for BuddyPress root blog id
     2238 * @see wp_get_object_terms() for the list of possible args.
     2239 *
     2240 * @since BuddyPress (?)
     2241 *
     2242 * @uses BP_Terms::get_object_terms().
     2243 *
     2244 * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
     2245 * @param string|array $taxonomies The taxonomies to retrieve terms from.
     2246 * @param array|string $args Change what is returned
     2247 * @return array|WP_Error The requested term data or empty array if no terms found. WP_Error if any of the $taxonomies don't exist.
     2248 */
     2249function bp_core_get_object_terms( $object_ids, $taxonomies = '', $args = array() ) {
     2250        return BP_Terms::get_object_terms( $object_ids, $taxonomies, $args );
     2251}
     2252
     2253/**
     2254 * Create Term and Taxonomy Relationships.
     2255 *
     2256 * WordPress wp_set_object_terms function for BuddyPress root blog id
     2257 * @see wp_set_object_terms()
     2258 *
     2259 * @since BuddyPress (?)
     2260 *
     2261 * @uses BP_Terms::set_object_terms().
     2262 *
     2263 * @param int $object_id The object to relate to.
     2264 * @param array|int|string $terms The slug or id of the term, will replace all existing
     2265 * related terms in this taxonomy.
     2266 * @param array|string $taxonomy The context in which to relate the term to the object.
     2267 * @param bool $append If false will delete difference of terms.
     2268 * @return array|WP_Error Affected Term IDs
     2269 */
     2270function bp_core_set_object_terms( $object_id, $terms, $taxonomy = '', $append = false ) {
     2271        return BP_Terms::set_object_terms( $object_id, $terms, $taxonomy, $append );
     2272}
     2273
     2274/**
     2275 * Remove term(s) associated with a given object.
     2276 *
     2277 * WordPress wp_remove_object_terms function for BuddyPress root blog id
     2278 * @see wp_remove_object_terms()
     2279 *
     2280 * @since BuddyPress (?)
     2281 *
     2282 * @uses BP_Terms::remove_object_terms().
     2283 *
     2284 * @param int $object_id The ID of the object from which the terms will be removed.
     2285 * @param array|int|string $terms The slug(s) or ID(s) of the term(s) to remove.
     2286 * @param array|string $taxonomy Taxonomy name.
     2287 * @return bool|WP_Error True on success, false or WP_Error on failure.
     2288 */
     2289function bp_core_remove_object_terms( $object_id, $terms, $taxonomy = '' ) {
     2290        return BP_Terms::remove_object_terms( $object_id, $terms, $taxonomy );
     2291}
     2292
     2293/**
     2294 * Will unlink the object from the taxonomy or taxonomies.
     2295 *
     2296 * WordPress wp_delete_object_term_relationships function for BuddyPress root blog id
     2297 * @see wp_delete_object_term_relationships()
     2298 *
     2299 * @since BuddyPress (?)
     2300 *
     2301 * @uses BP_Terms::delete_object_term_relationships().
     2302 *
     2303 * @param int $object_id The term Object Id that refers to the term
     2304 * @param string|array $taxonomies List of Taxonomy Names or single Taxonomy name.
     2305 */
     2306function bp_core_delete_object_term_relationships( $object_id, $taxonomies = '' ) {
     2307        return BP_Terms::delete_object_term_relationships( $object_id, $taxonomies );
     2308}
     2309
     2310/**
     2311 * Will update term count based on number of objects.
     2312 *
     2313 * WordPress _update_generic_term_count function for BuddyPress root blog id
     2314 * @see _update_generic_term_count()
     2315 *
     2316 * @since BuddyPress (?)
     2317 *
     2318 * @uses BP_Terms::update_term_count().
     2319 *
     2320 * @param array $terms List of Term taxonomy IDs
     2321 * @param object $taxonomy Current taxonomy object of terms
     2322 */
     2323function bp_core_update_term_count( $terms, $taxonomy = '' ) {
     2324        return BP_Terms::update_term_count( $terms, $taxonomy );
     2325}
     2326
     2327/**
     2328 * Given a taxonomy query, generates SQL to be appended to a main query.
     2329 *
     2330 * WordPress get_tax_sql function for BuddyPress root blog id
     2331 * @see get_tax_sql()
     2332 *
     2333 * @since BuddyPress (?)
     2334 *
     2335 * @param array $tax_query A compact tax query
     2336 * @param string $primary_table
     2337 * @param string $primary_id_column
     2338 * @return array
     2339 */
     2340function bp_core_get_tax_sql( $tax_query = array(), $primary_table = '', $primary_id_column ='' ) {
     2341        return BP_Terms::get_tax_sql( $tax_query, $primary_table, $primary_id_column );
     2342}
  • src/bp-core/bp-core-template.php

    diff --git src/bp-core/bp-core-template.php src/bp-core/bp-core-template.php
    index c945432..19bf057 100644
    function bp_is_user_settings_profile() { 
    18981898 */
    18991899function bp_is_groups_directory() {
    19001900        if ( bp_is_groups_component() && ! bp_current_action() && ! bp_current_item() ) {
     1901                return true;
     1902        }
     1903
     1904        if ( bp_is_groups_component() && bp_is_groups_tag() ) {
     1905                return true;
     1906        }
     1907
     1908        return false;
     1909}
     1910
     1911/**
     1912 * Is the current page a groups tag page?
     1913 *
     1914 * @since BuddyPress (?)
     1915 *
     1916 * @return True if the current page is a groups tag page.
     1917 */
     1918function bp_is_groups_tag() {
     1919        if ( ! empty( buddypress()->groups->tag ) ) {
    19011920                return true;
    19021921        }
    19031922
    function bp_is_group() { 
    19171936        if ( ! empty( $retval ) ) {
    19181937                $retval = bp_is_groups_component() && groups_get_current_group();
    19191938        }
    1920        
     1939
    19211940        return (bool) $retval;
    19221941}
    19231942
    function bp_nav_menu( $args = array() ) { 
    27192738                return $nav_menu;
    27202739        }
    27212740}
     2741
     2742/**
     2743 * Display BuddyPress item tags form fields.
     2744 *
     2745 * An adapted copy of WordPress post_tags_meta_box()
     2746 * to avoid including the meta-boxes.php file and to
     2747 * be able to use in group edit/create/admin screens
     2748 *
     2749 * @since BuddyPress (?)
     2750 *
     2751 * @param Object BuddyPress item (such as BP_Groups_Group)
     2752 * @param array   $box {
     2753 *     Tags meta box arguments.
     2754 *
     2755 *     @type string   $id       Meta box ID.
     2756 *     @type string   $title    Meta box title.
     2757 *     @type callback $callback Meta box display callback.
     2758 *     @type array    $args {
     2759 *         Extra meta box arguments.
     2760 *
     2761 *         @type string $taxonomy Taxonomy. Default 'bp_group_tags'.
     2762 *     }
     2763 * }
     2764 */
     2765function bp_tags_meta_box( $item, $box ) {
     2766        $defaults = array( 'taxonomy' => 'bp_group_tags' );
     2767
     2768        if ( ! isset( $box['args'] ) || ! is_array( $box['args'] ) ) {
     2769                $args = array();
     2770        } else {
     2771                $args = $box['args'];
     2772        }
     2773
     2774        $r = wp_parse_args( $args, $defaults );
     2775        $tax = $r['taxonomy'];
     2776        $tax_name = esc_attr( $tax );
     2777        $taxonomy = get_taxonomy( $tax );
     2778        $user_can_assign_terms = bp_current_user_can( $taxonomy->cap->assign_terms );
     2779        $comma = _x( ',', 'tag delimiter', 'buddypress' );
     2780        ?>
     2781        <div class="tagsdiv" id="<?php echo $tax_name; ?>">
     2782                <div class="jaxtag">
     2783                <div class="nojs-tags hide-if-js">
     2784                <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
     2785                <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php disabled( ! $user_can_assign_terms ); ?>><?php echo str_replace( ',', $comma . ' ', bp_core_get_terms_to_edit( $item->id, $tax_name ) ); // textarea_escaped by esc_attr() ?></textarea></div>
     2786                <?php if ( $user_can_assign_terms ) : ?>
     2787                <div class="ajaxtag hide-if-no-js">
     2788                        <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
     2789                        <div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
     2790                        <p><input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
     2791                        <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" /></p>
     2792                </div>
     2793                <p class="howto"><?php echo $taxonomy->labels->separate_items_with_commas; ?></p>
     2794                <?php endif; ?>
     2795                </div>
     2796                <div class="tagchecklist"></div>
     2797        </div>
     2798        <?php if ( $user_can_assign_terms ) : ?>
     2799        <p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
     2800        <?php endif;
     2801}
  • src/bp-core/css/tagbox.css

    diff --git src/bp-core/css/tagbox.css src/bp-core/css/tagbox.css
    index e69de29..ee21784 100644
     
     1.bp-tag-editor {
     2        overflow: hidden;
     3}
     4
     5.bp-tag-editor .hide-if-js {
     6        display:none;
     7}
     8
     9.tagchecklist {
     10        margin-left: 14px;
     11        font-size: 12px;
     12        overflow: auto;
     13        margin-bottom:15px;
     14}
     15
     16.tagchecklist br {
     17        display: none;
     18}
     19
     20.tagchecklist strong {
     21        margin-left: -8px;
     22        position: absolute;
     23}
     24
     25.tagchecklist span {
     26        margin-right: 25px;
     27        display: block;
     28        float: left;
     29        font-size: 13px;
     30        line-height: 1.8em;
     31        white-space: nowrap;
     32        cursor: default;
     33}
     34
     35.tagchecklist span a {
     36        margin: 1px 0 0 -10px;
     37        cursor: pointer;
     38        width: 20px;
     39        height: 20px;
     40        display: block;
     41        float: left;
     42        text-indent: 0;
     43        overflow: hidden;
     44        position: absolute;
     45        color: #555;
     46        font-weight:bold;
     47        font-size: 90%;
     48}
     49
     50.tagsdiv {
     51        margin-top: -8px;
     52}
     53
     54.taghint {
     55        color: #aaa;
     56        margin: 15px 0 -24px 12px;
     57}
     58
     59.tagsdiv .howto {
     60        margin: 0 0 6px 0;
     61}
     62
     63.ajaxtag .newtag {
     64        position: relative;
     65}
     66
     67.tagsdiv .newtag {
     68        width: 180px;
     69}
     70
     71.tagsdiv .the-tags {
     72        display: block;
     73        height: 60px;
     74        margin: 0 auto;
     75        overflow: auto;
     76        width: 260px;
     77}
     78
     79body.buddypress .tagsdiv .the-tags {
     80        margin: 0 5px;
     81}
     82
     83/* tag hints */
     84.taghint {
     85        color: #aaa;
     86        margin: -17px 0 0 7px;
     87        visibility: hidden;
     88}
     89
     90input.newtag ~ div.taghint {
     91        visibility: visible;
     92}
     93
     94input.newtag:focus ~ div.taghint {
     95        visibility: hidden;
     96}
     97
     98p.popular-tags {
     99        border: none;
     100        line-height: 2em;
     101        max-width: 1000px;
     102        padding: 8px 12px 12px;
     103        text-align: justify;
     104}
     105
     106p.popular-tags a {
     107        padding: 0 3px;
     108}
     109
     110.tagcloud {
     111        width: 97%;
     112        margin: 0 0 40px;
     113        text-align: justify;
     114}
     115
     116.tagcloud h3 {
     117        margin: 2px 0 12px;
     118}
     119
     120.ac_results {
     121        padding: 0;
     122        margin: 0;
     123        list-style: none;
     124        position: absolute;
     125        z-index: 10000;
     126        display: none;
     127        border: 1px solid #808080;
     128        background-color: #fff;
     129}
     130
     131body.buddypress .ac_results {
     132        z-index: 500000;
     133}
     134
     135.ac_results li {
     136        padding: 2px 5px;
     137        white-space: nowrap;
     138        color: #101010;
     139        text-align: left;
     140}
     141
     142.ac_over {
     143        background-color: #f0f0b8;
     144        cursor: pointer;
     145}
  • src/bp-core/js/tagbox.js

    diff --git src/bp-core/js/tagbox.js src/bp-core/js/tagbox.js
    index e69de29..61838c2 100644
     
     1// return an array with any duplicate, whitespace or values removed
     2function array_unique_noempty(a) {
     3        var out = [];
     4        jQuery.each( a, function(key, val) {
     5                val = jQuery.trim(val);
     6                if ( val && jQuery.inArray(val, out) == -1 )
     7                        out.push(val);
     8                } );
     9        return out;
     10}
     11
     12( function($) {
     13        var titleHasFocus = false;
     14
     15        tagBox = {
     16                clean : function(tags) {
     17                        var comma = tagvars.comma;
     18                        if ( ',' !== comma )
     19                                tags = tags.replace(new RegExp(comma, 'g'), ',');
     20                        tags = tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');
     21                        if ( ',' !== comma )
     22                                tags = tags.replace(/,/g, comma);
     23                        return tags;
     24                },
     25
     26                parseTags : function(el) {
     27                        var id = el.id, num = id.split('-check-num-')[1], taxbox = $(el).closest('.tagsdiv'),
     28                                thetags = taxbox.find('.the-tags'), comma = tagvars.comma,
     29                                current_tags = thetags.val().split(comma), new_tags = [];
     30                        delete current_tags[num];
     31
     32                        $.each( current_tags, function(key, val) {
     33                                val = $.trim(val);
     34                                if ( val ) {
     35                                        new_tags.push(val);
     36                                }
     37                        });
     38
     39                        thetags.val( this.clean( new_tags.join(comma) ) );
     40
     41                        this.quickClicks(taxbox);
     42                        return false;
     43                },
     44
     45                quickClicks : function(el) {
     46                        var thetags = $('.the-tags', el),
     47                                tagchecklist = $('.tagchecklist', el),
     48                                id = $(el).attr('id'),
     49                                current_tags, disabled;
     50
     51                        if ( !thetags.length )
     52                                return;
     53
     54                        disabled = thetags.prop('disabled');
     55
     56                        current_tags = thetags.val().split(tagvars.comma);
     57                        tagchecklist.empty();
     58
     59                        $.each( current_tags, function( key, val ) {
     60                                var span, xbutton;
     61
     62                                val = $.trim( val );
     63
     64                                if ( ! val )
     65                                        return;
     66
     67                                // Create a new span, and ensure the text is properly escaped.
     68                                span = $('<span />').text( val );
     69
     70                                // If tags editing isn't disabled, create the X button.
     71                                if ( ! disabled ) {
     72                                        xbutton = $( '<a id="' + id + '-check-num-' + key + '" class="ntdelbutton">X</a>' );
     73                                        xbutton.click( function(){ tagBox.parseTags(this); });
     74                                        span.prepend('&nbsp;').prepend( xbutton );
     75                                }
     76
     77                                // Append the span to the tag list.
     78                                tagchecklist.append( span );
     79                        });
     80                },
     81
     82                flushTags : function(el, a, f) {
     83                        var tagsval, newtags, text,
     84                                tags = $('.the-tags', el),
     85                                newtag = $('input.newtag', el),
     86                                comma = tagvars.comma;
     87                        a = a || false;
     88
     89                        text = a ? $(a).text() : newtag.val();
     90                        tagsval = tags.val();
     91                        newtags = tagsval ? tagsval + comma + text : text;
     92
     93                        newtags = this.clean( newtags );
     94                        newtags = array_unique_noempty( newtags.split(comma) ).join(comma);
     95                        tags.val(newtags);
     96                        this.quickClicks(el);
     97
     98                        if ( !a )
     99                                newtag.val('');
     100                        if ( 'undefined' == typeof(f) )
     101                                newtag.focus();
     102
     103                        return false;
     104                },
     105
     106                get : function(id) {
     107                        var tax = id.substr(id.indexOf('-')+1);
     108
     109                        $.post(ajaxurl, {'action':'get-tagcloud', 'tax':tax}, function(r, stat) {
     110                                if ( 0 === r || 'success' != stat )
     111                                        r = wpAjax.broken;
     112
     113                                r = $('<p id="tagcloud-'+tax+'" class="the-tagcloud">'+r+'</p>');
     114                                $('a', r).click(function(){
     115                                        tagBox.flushTags( $(this).closest('.inside').children('.tagsdiv'), this);
     116                                        return false;
     117                                });
     118
     119                                $('#'+id).after(r);
     120                        });
     121                },
     122
     123                init : function() {
     124                        var t = this, ajaxtag = $('div.ajaxtag');
     125
     126                        $('.tagsdiv').each( function() {
     127                                tagBox.quickClicks(this);
     128                        });
     129
     130                        $('input.tagadd', ajaxtag).click(function(){
     131                                t.flushTags( $(this).closest('.tagsdiv') );
     132                        });
     133
     134                        $('div.taghint', ajaxtag).click(function(){
     135                                $(this).css('visibility', 'hidden').parent().siblings('.newtag').focus();
     136                        });
     137
     138                        $('input.newtag', ajaxtag).blur(function() {
     139                                if ( '' === this.value )
     140                                        $(this).parent().siblings('.taghint').css('visibility', '');
     141                        }).focus(function(){
     142                                $(this).parent().siblings('.taghint').css('visibility', 'hidden');
     143                        }).keyup(function(e){
     144                                if ( 13 == e.which ) {
     145                                        tagBox.flushTags( $(this).closest('.tagsdiv') );
     146                                        return false;
     147                                }
     148                        }).keypress(function(e){
     149                                if ( 13 == e.which ) {
     150                                        e.preventDefault();
     151                                        return false;
     152                                }
     153                        }).each(function(){
     154                                var tax = $(this).closest('div.tagsdiv').attr('id');
     155                                $(this).suggest( ajaxurl + '?action=ajax-tag-search&tax=' + tax, { delay: 500, minchars: 2, multiple: true, multipleSep: tagvars.comma + ' ' } );
     156                        });
     157
     158                        // save tags on group save
     159                        $('#post, #group-settings-form, #create-group-form').submit(function(){
     160                                $('div.tagsdiv').each( function() {
     161                                        tagBox.flushTags(this, false, 1);
     162                                });
     163                        });
     164
     165                        // tag cloud
     166                        $('a.tagcloud-link').click(function(){
     167                                tagBox.get( $(this).attr('id') );
     168                                $(this).unbind().click(function(){
     169                                        $(this).siblings('.the-tagcloud').toggle();
     170                                        return false;
     171                                });
     172                                return false;
     173                        });
     174                }
     175        };
     176
     177        if ( $( '#tagsdiv-bp_group_tags' ).length ) {
     178                tagBox.init();
     179        } else {
     180                $('#side-sortables, #normal-sortables, #advanced-sortables').children('div.postbox').each(function(){
     181                        if ( this.id.indexOf('tagsdiv-') === 0 ) {
     182                                tagBox.init();
     183                                return false;
     184                        }
     185                });
     186        }
     187
     188}(jQuery));
  • src/bp-groups/admin/css/admin.css

    diff --git src/bp-groups/admin/css/admin.css src/bp-groups/admin/css/admin.css
    index 651a6d5..6f64423 100644
     
    1 body.toplevel_page_bp-groups table.groups th#status,
    2 body.toplevel_page_bp-groups table.groups th#members {
     1#bp-groups-form #status,
     2#bp-groups-form #members {
    33        width: 10%;
    44}
    5 
    6 body.toplevel_page_bp-groups table.groups th#last_active {
     5#bp-groups-form #last_active,
     6#bp-groups-form #tag {
    77        width: 15%;
    88}
    99
  • src/bp-groups/admin/js/admin.js

    diff --git src/bp-groups/admin/js/admin.js src/bp-groups/admin/js/admin.js
    index 05c61e2..348e1a4 100644
     
    11/* global BP_Group_Admin, group_id, isRtl */
    22
    33(function($) {
     4
     5        if ( $( 'body.groups_page_bp-group-tags' ).length ) {
     6
     7                if ( $( '#edittag' ).length ) {
     8                        $( '#edittag' ).prop( 'action', BP_Group_Admin.edit_action );
     9                }
     10
     11                if ( $( '#addtag' ).length ) {
     12                        $( '#addtag' ).prop( 'action', BP_Group_Admin.edit_action );
     13                        $( '#addtag input[name="screen"]' ).prop( 'value', BP_Group_Admin.ajax_screen );
     14                }
     15
     16                if ( $( '.search-form' ).length ) {
     17                        $( '.search-form' ).append( '<input type="hidden" name="page" value="' + BP_Group_Admin.search_page + '"/>' );
     18                }
     19
     20                return;
     21        }
     22
    423        function add_member_to_list( e, ui ) {
    524                $('#bp-groups-new-members-list').append('<li data-login="' + ui.item.value + '"><a href="#" class="bp-groups-remove-new-member">x</a> ' + ui.item.label + '</li>');
    625        }
  • src/bp-groups/bp-groups-actions.php

    diff --git src/bp-groups/bp-groups-actions.php src/bp-groups/bp-groups-actions.php
    index 163e407..731cf0e 100644
    function groups_action_create_group() { 
    162162
    163163                        $new_group_id = isset( $bp->groups->new_group_id ) ? $bp->groups->new_group_id : 0;
    164164
    165                         if ( !$bp->groups->new_group_id = groups_create_group( array( 'group_id' => $new_group_id, 'name' => $_POST['group-name'], 'description' => $_POST['group-desc'], 'slug' => groups_check_slug( sanitize_title( esc_attr( $_POST['group-name'] ) ) ), 'date_created' => bp_core_current_time(), 'status' => 'public' ) ) ) {
     165                        if ( ! $bp->groups->new_group_id = groups_create_group( array( 'group_id' => $new_group_id, 'name' => $_POST['group-name'], 'description' => $_POST['group-desc'], 'slug' => groups_check_slug( sanitize_title( esc_attr( $_POST['group-name'] ) ) ), 'date_created' => bp_core_current_time(), 'status' => 'public' ) ) ) {
    166166                                bp_core_add_message( __( 'There was an error saving group details, please try again.', 'buddypress' ), 'error' );
    167167                                bp_core_redirect( bp_get_root_domain() . '/' . bp_get_groups_root_slug() . '/create/step/' . bp_get_groups_current_create_step() . '/' );
     168                        } else {
     169                                if ( ! empty( $_POST['tax_input'] ) ) {
     170                                        bp_groups_set_taxonomy( $_POST['tax_input'], $bp->groups->new_group_id );
     171                                }
    168172                        }
    169173                }
    170174
    function groups_action_group_feed() { 
    482486        ) );
    483487}
    484488add_action( 'bp_actions', 'groups_action_group_feed' );
     489
     490/**
     491 * Load the JS for the tagbox.
     492 *
     493 * @since BuddyPress (?)
     494 */
     495function bp_groups_tagbox_js() {
     496        if ( is_multisite() && ! bp_is_root_blog() ) {
     497                return false;
     498        }
     499
     500        if ( ! ( bp_is_group_create() && 'group-details' == bp_get_groups_current_create_step() ) && ! ( bp_is_group_admin_page() && 'edit-details' == bp_get_group_current_admin_tab() && bp_is_item_admin() ) ) {
     501                return false;
     502        }
     503
     504        $bp = buddypress();
     505
     506        // Decide whether to load the dev version of the CSS and JavaScript
     507        $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : 'min.';
     508
     509        wp_enqueue_style( 'bp-tagbox-css', $bp->plugin_url . "bp-core/css/tagbox.{$min}css", array(), bp_get_version() );
     510        wp_enqueue_script( 'bp-tagbox-js', $bp->plugin_url . "bp-core/js/tagbox.{$min}js", array( 'suggest', 'wp-ajax-response' ), bp_get_version(), true  );
     511
     512        wp_localize_script( 'bp-tagbox-js', 'tagvars', array(
     513                'comma' => _x( ',', 'tag delimiter', 'buddypress' ),
     514        ) );
     515}
     516add_action( 'bp_enqueue_scripts', 'bp_groups_tagbox_js' );
     517
     518/**
     519 * Set the groups current tag.
     520 *
     521 * @since BuddyPress (?)
     522 */
     523function bp_groups_directory_set_current_tag() {
     524        $bp = buddypress();
     525
     526        if ( bp_is_groups_component() && empty( $bp->groups->current_group ) && bp_is_current_action( bp_get_groups_tag_slug() ) ) {
     527                $bp->groups->tag = bp_core_get_term_by( 'slug', bp_action_variable( 0 ), 'bp_group_tags' );
     528        }
     529}
     530add_action( 'bp_init', 'bp_groups_directory_set_current_tag', 10 );
  • src/bp-groups/bp-groups-admin.php

    diff --git src/bp-groups/bp-groups-admin.php src/bp-groups/bp-groups-admin.php
    index ffcbf94..783c076 100644
    if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-groups' == $_REQUEST['pag 
    2525 *
    2626 * @since BuddyPress (1.7.0)
    2727 */
    28 function bp_groups_add_admin_menu() {
     28  function bp_groups_add_admin_menu() {
    2929
    30         // Add our screen
    31         $hook = add_menu_page(
    32                 _x( 'Groups', 'Admin Groups page title', 'buddypress' ),
    33                 _x( 'Groups', 'Admin Groups menu', 'buddypress' ),
     30        // Add our screen
     31        $hooks['admin_load'] = add_menu_page(
     32                __( 'Groups', 'buddypress' ),
     33                __( 'Groups', 'buddypress' ),
    3434                'bp_moderate',
    3535                'bp-groups',
    3636                'bp_groups_admin',
    3737                'div'
    3838        );
    3939
    40         // Hook into early actions to load custom CSS and our init handler.
    41         add_action( "load-$hook", 'bp_groups_admin_load' );
     40        $hooks['admin_tags_load'] = add_submenu_page(
     41                'bp-groups',
     42                __( 'Group Tags', 'buddypress' ),
     43                __( 'Group Tags', 'buddypress' ),
     44                'bp_moderate',
     45                'bp-group-tags',
     46                'bp_groups_admin_tags'
     47        );
     48
     49        foreach( $hooks as $key => $hook ) {
     50                if ( 'admin_tags_load' == $key ) {
     51                        buddypress()->groups->tags_action_screen = is_network_admin() ? $hook . '-network' : $hook ;
     52                }
     53
     54                // Hook into early actions to load custom CSS and our init handler.
     55                add_action( "load-$hook", "bp_groups_$key" );
     56        }
    4257}
    4358add_action( bp_core_admin_hook(), 'bp_groups_add_admin_menu' );
    4459
    function bp_groups_admin_load() { 
    126141                add_meta_box( 'bp_group_add_members', _x( 'Add New Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_add_new_members', get_current_screen()->id, 'normal', 'core' );
    127142                add_meta_box( 'bp_group_members', _x( 'Manage Members', 'group admin edit screen', 'buddypress' ), 'bp_groups_admin_edit_metabox_members', get_current_screen()->id, 'normal', 'core' );
    128143
     144                // Group tags metabox
     145                $taxonomy = get_taxonomy( 'bp_group_tags' );
     146                // meta_box_cb argument of register_taxonomy was introduced in WordPress 3.8
     147                if ( 'bp_group_tags' == $taxonomy->name && ( empty( $taxonomy->meta_box_cb ) || 'bp_tags_meta_box' != $taxonomy->meta_box_cb ) ) {
     148                        $taxonomy->meta_box_cb = 'bp_tags_meta_box';
     149                }
     150
     151                $tax_meta_box_id = 'tagsdiv-' . $taxonomy->name;
     152                add_meta_box( $tax_meta_box_id, $taxonomy->labels->name, $taxonomy->meta_box_cb, get_current_screen()->id, 'side', 'core', array( 'taxonomy' => $taxonomy->name ) );
     153                wp_enqueue_script( 'bp-tagbox-js', buddypress()->plugin_url . "bp-core/js/tagbox.{$min}js", array( 'suggest', 'wp-ajax-response' ), bp_get_version(), true  );
     154                wp_localize_script( 'bp-tagbox-js', 'tagvars', array(
     155                        'comma' => _x( ',', 'tag delimiter', 'buddypress' ),
     156                ) );
     157
    129158                do_action( 'bp_groups_admin_meta_boxes' );
    130159
    131160                // Enqueue javascripts
    function bp_groups_admin_load() { 
    338367                        }
    339368                }
    340369
     370                // Set group tags
     371                if ( ! empty( $_POST['tax_input'] ) ) {
     372                        bp_groups_set_taxonomy( $_POST['tax_input'], $group_id );
     373                }
     374
    341375                // Call actions for plugins to do something before we redirect
    342376                do_action( 'bp_group_admin_edit_after', $group_id );
    343377
    class BP_Groups_List_Table extends WP_List_Table { 
    13061340                        'comment'     => _x( 'Name', 'Groups admin Group Name column header',               'buddypress' ),
    13071341                        'description' => _x( 'Description', 'Groups admin Group Description column header', 'buddypress' ),
    13081342                        'status'      => _x( 'Status', 'Groups admin Privacy Status column header',         'buddypress' ),
     1343                        'tag'         => _x( 'Tags', 'Groups admin Tags column header',                     'buddypress' ),
    13091344                        'members'     => _x( '# Members', 'Groups admin Members column header',             'buddypress' ),
    13101345                        'last_active' => _x( 'Last Active', 'Groups admin Last Active column header',       'buddypress' )
    13111346                ) );
    class BP_Groups_List_Table extends WP_List_Table { 
    14671502        }
    14681503
    14691504        /**
     1505         * Markup for the Tags column.
     1506         *
     1507         * @since BuddyPress (?)
     1508         *
     1509         * @param array Information about the current row.
     1510         */
     1511        public function column_tag( $item = array() ) {
     1512                $tags = bp_core_get_the_term_list( $item['id'], 'bp_group_tags', '', ', ', '' );
     1513
     1514                if ( $tags ) {
     1515                        echo $tags;
     1516                } else {
     1517                        echo '&#8212';
     1518                }
     1519        }
     1520
     1521        /**
    14701522         * Markup for the Number of Members column.
    14711523         *
    14721524         * @since BuddyPress (1.7.0)
    class BP_Groups_List_Table extends WP_List_Table { 
    15021554                return apply_filters( 'bp_groups_admin_get_group_custom_column', '', $column_name, $item );
    15031555        }
    15041556}
     1557
     1558/** Group Tags Admin screen ***************************************************/
     1559
     1560/**
     1561 * Register a fake post type for the groups component
     1562 *
     1563 * @since BuddyPress (?)
     1564 *
     1565 * @global $wp_post_types the list of available post types
     1566 */
     1567function bp_groups_admin_tags_register_post_type() {
     1568        global $wp_post_types;
     1569
     1570        // Since our post type doesn't really exist, we need to fool WP into thinking
     1571        // it really exists to avoid notices. So the following is a little tomfoolery!
     1572        $faux_post_type = 'bp_group';
     1573
     1574        // Set needed properties
     1575        $wp_post_types[$faux_post_type]               = new stdClass;
     1576        $wp_post_types[$faux_post_type]->show_ui      = false;
     1577        $wp_post_types[$faux_post_type]->labels       = new stdClass;
     1578        $wp_post_types[$faux_post_type]->labels->name = __( 'Groups', 'buddypress' );
     1579        $wp_post_types[$faux_post_type]->name         = $faux_post_type;
     1580}
     1581add_action( 'bp_admin_init', 'bp_groups_admin_tags_register_post_type' );
     1582
     1583/**
     1584 * Make sure the BP Group Tags Screen includes the post type and taxonomy properties
     1585 *
     1586 * @since BuddyPress (?)
     1587 *
     1588 * @param WP_Screen $current_screen
     1589 * @uses  buddypress()
     1590 */
     1591function bp_groups_admin_tags_set_current_screen( $current_screen = OBJECT ) {
     1592        $bp = buddypress();
     1593
     1594        if ( empty( $bp->groups->tags_action_screen ) || $bp->groups->tags_action_screen != $current_screen->id ) {
     1595                return;
     1596        }
     1597
     1598        $current_screen->post_type = 'bp_group';
     1599        $current_screen->taxonomy  = 'bp_group_tags';
     1600}
     1601add_action( 'current_screen', 'bp_groups_admin_tags_set_current_screen' );
     1602
     1603/**
     1604 * Set up the Group Tags admin page.
     1605 *
     1606 * On multisite configs, the edit-tags.php page does not exist
     1607 * This function will include it to output the Group tags management forms
     1608 * But we still need to deal with actions before including this file. Some
     1609 * of this works thanks to the javascript part.
     1610 *
     1611 * @since BuddyPress (?)
     1612 *
     1613 * @uses bp_current_user_can()
     1614 * @uses add_query_arg()
     1615 * @uses bp_get_admin_url()
     1616 * @uses bp_admin_list_table_current_bulk_action() to get the current action
     1617 * @uses get_taxonomy() to get the group tags taxonomy
     1618 * @uses check_admin_referer()
     1619 * @uses bp_core_insert_term()
     1620 * @uses wp_redirect()
     1621 * @uses wp_parse_id_list()
     1622 * @uses bp_core_delete_term()
     1623 * @uses wp_enqueue_script()
     1624 * @uses wp_localize_script()
     1625 * @uses bp_core_get_term()
     1626 * @uses bp_core_update_term()
     1627 */
     1628function bp_groups_admin_tags_load() {
     1629        $cheating = __( 'Cheatin&#8217; uh?', 'buddypress' );
     1630
     1631        if ( ! bp_current_user_can( 'bp_moderate' ) ) {
     1632                wp_die( $cheating );
     1633        }
     1634
     1635        $post_type = 'bp_group';
     1636        $taxnow    = $taxonomy = 'bp_group_tags';
     1637
     1638        // Decide whether to load the dev version of the CSS and JavaScript
     1639        $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : 'min.';
     1640        $redirect_to = add_query_arg( 'page', 'bp-group-tags', bp_get_admin_url( 'admin.php' ) );
     1641
     1642        // Filter the updated messages
     1643        add_filter( 'term_updated_messages', 'bp_groups_admin_updated_message', 10, 1 );
     1644
     1645        $doaction = bp_admin_list_table_current_bulk_action();
     1646
     1647        /**
     1648         * Eventually deal with actions before including the edit-tags.php file
     1649         */
     1650        if ( ! empty( $doaction ) ) {
     1651                $bp_group_tags_tax = get_taxonomy( $taxonomy );
     1652
     1653                if ( ! $bp_group_tags_tax ) {
     1654                        wp_die( __( 'Invalid taxonomy', 'buddypress' ) );
     1655                }
     1656
     1657                switch ( $doaction ) {
     1658                        case 'add-tag':
     1659
     1660                                check_admin_referer( 'add-tag', '_wpnonce_add-tag' );
     1661
     1662                                if ( ! bp_current_user_can( $bp_group_tags_tax->cap->edit_terms ) ) {
     1663                                        wp_die( $cheating );
     1664                                }
     1665
     1666                                $inserted = bp_core_insert_term( $_POST['tag-name'], $bp_group_tags_tax->name, $_POST );
     1667
     1668                                if ( ! empty( $inserted ) && ! is_wp_error( $inserted ) ){
     1669                                        $redirect_to = add_query_arg( 'message', 1, $redirect_to );
     1670                                } else {
     1671                                        $redirect_to = add_query_arg( 'message', 4, $redirect_to );
     1672                                }
     1673                                wp_redirect( $redirect_to );
     1674                        exit;
     1675
     1676                        case 'delete':
     1677                        case 'bulk-delete':
     1678                                $tag_IDs = array();
     1679                                $query_args = array();
     1680
     1681                                if ( empty( $_REQUEST['tag_ID'] ) && empty( $_REQUEST['delete_tags'] ) ) {
     1682                                        wp_redirect( $redirect_to );
     1683                                        exit;
     1684                                } else if ( ! empty( $_REQUEST['tag_ID'] ) ) {
     1685                                        $tag_ID = absint( $_REQUEST['tag_ID'] );
     1686                                        check_admin_referer( 'delete-tag_' . $tag_ID );
     1687                                        $tag_IDs = array( $tag_ID );
     1688                                        $query_args['message'] = 2;
     1689                                } else {
     1690                                        check_admin_referer( 'bulk-tags' );
     1691                                        $tag_IDs = wp_parse_id_list( $_REQUEST['delete_tags'] );
     1692                                        $query_args['message'] = 6;
     1693                                }
     1694
     1695                                if ( ! bp_current_user_can( $bp_group_tags_tax->cap->delete_terms ) ) {
     1696                                        wp_die( $cheating );
     1697                                }
     1698
     1699                                foreach ( $tag_IDs as $tag_ID ) {
     1700                                        bp_core_delete_term( $tag_ID, $bp_group_tags_tax->name );
     1701                                }
     1702
     1703                                $redirect_to = add_query_arg( $query_args, $redirect_to );
     1704                                wp_redirect( $redirect_to );
     1705                        exit;
     1706
     1707                        case 'edit':
     1708                                // We need to reset the action of the edit form
     1709                                wp_enqueue_script( 'bp_groups_admin_tags_js', buddypress()->plugin_url . "bp-groups/admin/js/admin.{$min}js", array( 'jquery' ), bp_get_version(), true );
     1710                                wp_localize_script( 'bp_groups_admin_tags_js', 'BP_Group_Admin', array(
     1711                                        'edit_action' => $redirect_to,
     1712                                ) );
     1713                                break;
     1714
     1715                        case 'editedtag':
     1716                                $tag_ID = (int) $_POST['tag_ID'];
     1717                                check_admin_referer( 'update-tag_' . $tag_ID );
     1718
     1719                                if ( ! bp_current_user_can( $bp_group_tags_tax->cap->edit_terms ) )
     1720                                        wp_die( $cheating );
     1721
     1722                                $tag = bp_core_get_term( $tag_ID, $bp_group_tags_tax->name );
     1723                                if ( ! $tag ) {
     1724                                        wp_die( __( 'You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'buddypress' ) );
     1725                                }
     1726
     1727                                $ret = bp_core_update_term( $tag_ID, $bp_group_tags_tax->name, $_POST );
     1728
     1729                                if ( ! empty( $ret ) && ! is_wp_error( $ret ) ) {
     1730                                        $redirect_to = add_query_arg( 'message', 3, $redirect_to );
     1731                                } else {
     1732                                        $redirect_to = add_query_arg( 'message', 5, $redirect_to );
     1733                                }
     1734
     1735                                wp_redirect( $redirect_to );
     1736                        exit;
     1737                }
     1738
     1739        /**
     1740         * Make sure to "javascript change" some form attributes
     1741         * in edit-tags.php
     1742         */
     1743        } else {
     1744                wp_enqueue_script( 'bp_groups_admin_tags_js', buddypress()->plugin_url . "bp-groups/admin/js/admin.{$min}js", array( 'jquery' ), bp_get_version(), true );
     1745                wp_localize_script( 'bp_groups_admin_tags_js', 'BP_Group_Admin', array(
     1746                        'edit_action' => $redirect_to,
     1747                        'ajax_screen' => 'edit-' . $taxonomy,
     1748                        'search_page' => 'bp-group-tags',
     1749                ) );
     1750        }
     1751
     1752
     1753        require_once( ABSPATH . 'wp-admin/edit-tags.php' );
     1754        exit();
     1755}
     1756
     1757/**
     1758 * Make sure to display nothing on the group tags page
     1759 * as edit-tags.php will be loaded.
     1760 *
     1761 * @since BuddyPress (?)
     1762 */
     1763function bp_groups_admin_tags() {}
  • src/bp-groups/bp-groups-classes.php

    diff --git src/bp-groups/bp-groups-classes.php src/bp-groups/bp-groups-classes.php
    index 9428b8f..c7d6d9a 100644
    class BP_Groups_Group { 
    678678                        'user_id'           => 0,
    679679                        'search_terms'      => false,
    680680                        'meta_query'        => false,
     681                        'tax_query'         => false,
    681682                        'include'           => false,
    682683                        'populate_extras'   => true,
    683684                        'update_meta_cache' => true,
    class BP_Groups_Group { 
    724725                        $sql['meta'] = $meta_query_sql['where'];
    725726                }
    726727
     728                /** Tax Query ************************************************/
     729                $tax_query_sql = self::get_tax_query_sql( $r['tax_query'] );
     730
     731                if ( ! empty( $tax_query_sql['join'] ) ) {
     732                        $sql['from'] .= $tax_query_sql['join'];
     733                }
     734
     735                if ( ! empty( $tax_query_sql['where'] ) ) {
     736                        $sql['tax'] = $tax_query_sql['where'];
     737                }
     738
    727739                if ( ! empty( $r['user_id'] ) ) {
    728740                        $sql['user'] = $wpdb->prepare( " AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id'] );
    729741                }
    class BP_Groups_Group { 
    810822                        $total_sql['where'][] = $meta_query_clause;
    811823                }
    812824
     825                if ( ! empty( $tax_query_sql['where'] ) ) {
     826                        // Join the taxonomy table
     827                        $total_sql['select'] .= ", ". substr( $tax_query_sql['join'], 0, -2 );
     828
     829                        // Modify the tax_query clause from paged_sql for our syntax
     830                        $tax_query_clause = preg_replace( '/^\s*AND/', '', $tax_query_sql['where'] );
     831                        $total_sql['where'][] = $tax_query_clause;
     832                }
     833
    813834                // Already escaped in the paginated results block
    814835                if ( ! empty( $include ) ) {
    815836                        $total_sql['where'][] = "g.id IN ({$include})";
    class BP_Groups_Group { 
    908929        }
    909930
    910931        /**
     932         * Get the SQL for the 'tax_query' param in BP_Groups_Group::get()
     933         *
     934         * We use WP_Tax_Query to do the heavy lifting of parsing the
     935         * meta_query array and creating the necessary SQL clauses. However,
     936         * since BP_Groups_Group::get() builds its SQL differently than
     937         * WP_Query, we have to alter the return value
     938         *
     939         * @since BuddyPress (?)
     940         * @access protected
     941         *
     942         * @param array $tax_query An array of tax_query filters. See the
     943         *        documentation for {@link WP_Tax_Query} for details.
     944         * @return array $sql_array 'join' and 'where' clauses.
     945         */
     946        protected static function get_tax_query_sql( $tax_query = array() ) {
     947                $sql_array = array(
     948                        'join'  => '',
     949                        'where' => '',
     950                );
     951
     952                if ( empty( $tax_query ) ) {
     953                        return $sql_array;
     954                }
     955
     956                $clauses = bp_core_get_tax_sql( $tax_query, 'g', 'id' );
     957
     958                /**
     959                 * BP_Groups_Group::get() uses the comma syntax for table joins
     960                 * meaning we need to do some parsing to adjust..
     961                 */
     962                $inner_joins = explode( 'INNER JOIN', $clauses['join'] );
     963
     964                foreach( $inner_joins as $key => $part ) {
     965                        preg_match( '/(.*) ON/', $part, $matches_a );
     966                        if ( ! empty( $matches_a[1] ) ) {
     967                                $sql_array['join'][] = $matches_a[1];
     968                        }
     969                        preg_match( '/ON \((.*)\)/', $part, $matches_b );
     970                        if ( ! empty( $matches_b[1] ) ) {
     971                                $sql_array['where'][] = $matches_b[1];
     972                        }
     973                }
     974                $sql_array['where'] = array_merge( $sql_array['where'], array( str_replace( ' AND ', '', $clauses['where'] ) ) );
     975
     976                $sql_array['join']  = implode( ',', $sql_array['join'] ). ', ';
     977                $sql_array['where'] = ' AND ' . implode( ' AND ', $sql_array['where'] );
     978
     979                return $sql_array;
     980        }
     981
     982        /**
    911983         * Convert the 'type' parameter to 'order' and 'orderby'.
    912984         *
    913985         * @since BuddyPress (1.8.0)
  • src/bp-groups/bp-groups-filters.php

    diff --git src/bp-groups/bp-groups-filters.php src/bp-groups/bp-groups-filters.php
    index 9e66f3d..4ae6a37 100644
    function groups_filter_forums_root_page_sql( $sql ) { 
    233233        return apply_filters( 'groups_filter_bbpress_root_page_sql', 't.topic_id' );
    234234}
    235235add_filter( 'get_latest_topics_fields', 'groups_filter_forums_root_page_sql' );
     236
     237
     238/** Group Tags filters ********************************************************/
     239
     240/**
     241 * Allow Group Creators/ Admins to assign group tags.
     242 *
     243 * @since BuddyPress (?)
     244 *
     245 * @see WP_User::has_cap()
     246 *
     247 * @param array $caps The caps that WP associates with the given role.
     248 * @param array $cap The cap being tested for in WP_User::has_cap().
     249 * @param integer $user_id the current user id
     250 * @param array $args Miscellaneous arguments passed to the user_has_cap filter.
     251 * @return array $caps the needed cap
     252 */
     253function bp_groups_tags_cap( $caps = array(), $cap = '', $user_id = 0, $args = array() ) {
     254
     255        switch( $cap ) {
     256                case 'assign_group_tags' :
     257                        // Members in multisite have no roles
     258                        if ( ( bp_is_group_create() && is_user_logged_in() ) || bp_is_item_admin() ) {
     259                                $caps = array( 'exist' );
     260                        }
     261                        break;
     262
     263                case 'manage_group_tags' :
     264                case 'edit_group_tags'   :
     265                case 'delete_group_tags' :
     266                        $caps = array( 'manage_options' );
     267                        break;
     268        }
     269
     270        return $caps;
     271}
     272add_filter( 'bp_map_meta_caps', 'bp_groups_tags_cap', 10, 4 );
     273
     274/**
     275 * Count text callback for the "bp_group_tags" widget tag cloud
     276 *
     277 * @since BuddyPress (?)
     278 *
     279 * @param  array $args arguments passed to the wp_tag_cloud widget.
     280 * @return array       same arguments with the callback if relevant
     281 */
     282function bp_groups_widget_tag_cloud_args( $args = array() ) {
     283        if ( ! empty( $args['taxonomy'] ) && 'bp_group_tags' == $args['taxonomy'] ) {
     284                $args['topic_count_text_callback'] = 'bp_groups_tag_cloud_count_text_callback';
     285        }
     286
     287        return $args;
     288}
     289add_filter( 'widget_tag_cloud_args', 'bp_groups_widget_tag_cloud_args', 10, 1 );
     290
     291/**
     292 * Override the edit link for the bp_group_tags taxo
     293 *
     294 * @since BuddyPress (?)
     295 *
     296 * @param  string  $link        the term edit link
     297 * @param  integer $term_id     the term ID
     298 * @param  string  $taxonomy    the taxonomy name (eg: bp_group_tags)
     299 * @param  string  $object_type
     300 * @return string               the term edit link
     301 */
     302function bp_groups_admin_tags_edit_term_link( $link = '', $term_id = 0, $taxonomy = '', $object_type = '' ) {
     303        if ( empty( $taxonomy ) || 'bp_group_tags' != $taxonomy ) {
     304                return $link;
     305        }
     306
     307        $query_args = array(
     308                'page'   => 'bp-group-tags',
     309                'action' => 'edit',
     310                'tag_ID' => $term_id,
     311        );
     312
     313        return add_query_arg( $query_args, bp_get_admin_url( 'admin.php' ) );
     314
     315}
     316add_filter( 'get_edit_term_link', 'bp_groups_admin_tags_edit_term_link', 10, 4 );
     317
     318/**
     319 * Override the delete link for the bp_group_tags taxonomy
     320 *
     321 * @since BuddyPress (?)
     322 *
     323 * @param  array  $actions list of available row action
     324 * @param  Object $tag     Term Object
     325 * @return array           same list, making sure the delete action is edited if needed
     326 */
     327function bp_groups_admin_tags_row_action( $actions = array(), $tag = null ) {
     328        if ( empty( $tag ) ) {
     329                return $actions;
     330        }
     331
     332        // Only the delete action is to edit.
     333        $query_args = array(
     334                'page'     => 'bp-group-tags',
     335                'action'   => 'delete',
     336                'tag_ID'   => $tag->term_id,
     337                'taxonomy' => 'bp_group_tags'
     338        );
     339        $delete_link = add_query_arg( $query_args, bp_get_admin_url( 'admin.php' ) );
     340        $actions['delete'] = "<a class='delete-tag' href='" . esc_url( wp_nonce_url( $delete_link, 'delete-tag_' . $tag->term_id ) ) . "'>" . esc_html( _x( 'Delete', 'Group Tags term delete link', 'buddypress' ) ) . "</a>";
     341
     342        return $actions;
     343}
     344add_filter( 'bp_group_tags_row_actions', 'bp_groups_admin_tags_row_action', 10, 2 );
     345
     346/**
     347 * Register the Group tags updated messages
     348 *
     349 * @since BuddyPress (?)
     350 *
     351 * @param  array  $messages list of term updated messages
     352 * @return array            same list including Group tags ones
     353 */
     354function bp_groups_admin_updated_message( $messages = array() ) {
     355        $messages['bp_group_tags'] = array(
     356                0 => '', // Unused. Messages start at index 1.
     357                1 => __( 'Group Tag added.',       'buddypress' ),
     358                2 => __( 'Group Tag deleted.',     'buddypress' ),
     359                3 => __( 'Group Tag updated.',     'buddypress' ),
     360                4 => __( 'Group Tag not added.',   'buddypress' ),
     361                5 => __( 'Group Tag not updated.', 'buddypress' ),
     362                6 => __( 'Group Tags deleted.',    'buddypress' ),
     363        );
     364
     365        return $messages;
     366}
  • src/bp-groups/bp-groups-functions.php

    diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php
    index c83e743..eb0f1af 100644
    function groups_delete_group( $group_id ) { 
    273273        // Remove all outstanding invites for this group
    274274        groups_delete_all_group_invites( $group_id );
    275275
     276        // Remove Group Tags relationships
     277        bp_core_delete_object_term_relationships( $group_id, 'bp_group_tags' );
     278
    276279        do_action( 'groups_delete_group', $group_id );
    277280
    278281        return true;
    function groups_get_groups( $args = '' ) { 
    595598                'exclude'           => false,    // Do not include these specific groups (group_ids)
    596599                'search_terms'      => false,    // Limit to groups that match these search terms
    597600                'meta_query'        => false,    // Filter by groupmeta. See WP_Meta_Query for syntax
     601                'tax_query'         => false,
    598602                'show_hidden'       => false,    // Show hidden groups to non-admins
    599603                'per_page'          => 20,       // The number of results to return per page
    600604                'page'              => 1,        // The page to return if limiting per page
    function groups_get_groups( $args = '' ) { 
    611615                'exclude'           => $r['exclude'],
    612616                'search_terms'      => $r['search_terms'],
    613617                'meta_query'        => $r['meta_query'],
     618                'tax_query'         => $r['tax_query'],
    614619                'show_hidden'       => $r['show_hidden'],
    615620                'per_page'          => $r['per_page'],
    616621                'page'              => $r['page'],
    function groups_remove_data_for_user( $user_id ) { 
    14561461add_action( 'wpmu_delete_user',  'groups_remove_data_for_user' );
    14571462add_action( 'delete_user',       'groups_remove_data_for_user' );
    14581463add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
     1464
     1465/* Group Tags *****************************************************************/
     1466
     1467/**
     1468 * Set group tags
     1469 *
     1470 * @since BuddyPress (?)
     1471 *
     1472 * @param array $taxonomies
     1473 * @param integer $group_id
     1474 * @return true on success, false on failure
     1475 */
     1476function bp_groups_set_taxonomy( $taxonomies = array(), $group_id = 0 ) {
     1477        $retval = true;
     1478
     1479        if ( empty( $group_id ) ) {
     1480                return false;
     1481        }
     1482
     1483        foreach ( $taxonomies as $taxonomy => $tags ) {
     1484                $taxonomy_obj = get_taxonomy( $taxonomy );
     1485
     1486                if ( is_array( $tags ) ) {
     1487                        $tags = array_filter( $tags );
     1488                } else {
     1489                        $comma = _x( ',', 'tag delimiter', 'buddypress' );
     1490                        if ( ',' !== $comma ){
     1491                                $tags = str_replace( $comma, ',', $tags );
     1492                        }
     1493
     1494                        $tags = explode( ',', trim( $tags, " \n\t\r\0\x0B," ) );
     1495                }
     1496                if ( bp_current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
     1497                        $result = bp_core_set_object_terms( $group_id, $tags, $taxonomy );
     1498
     1499                        if ( is_wp_error( $result ) ) {
     1500                                $retval = false;
     1501                        }
     1502                }
     1503        }
     1504
     1505        return $retval;
     1506}
     1507
     1508/**
     1509 * Set tag cloud count text callback
     1510 *
     1511 * @since BuddyPress (?)
     1512 *
     1513 * @param integer $count
     1514 * @return string the count text callback
     1515 */
     1516function bp_groups_tag_cloud_count_text_callback( $count = 0 ) {
     1517        return sprintf( _n( '%d Group', '%d Groups', $count, 'buddypress' ), $count );
     1518}
     1519
     1520/**
     1521 * Add 'Tags' tab to groups directory page when we're on a group tag page.
     1522 *
     1523 * @since BuddyPress (?)
     1524 */
     1525function bp_groups_tag_add_directory_tab() {
     1526        if ( ! bp_is_groups_tag() ) {
     1527                return;
     1528        }
     1529?>
     1530
     1531        <li id="groups-tag"><a href="<?php echo bp_get_groups_directory_permalink() . bp_get_groups_tag_slug() . '/' . urldecode( esc_attr( buddypress()->groups->tag->slug ) ) . '/'; ?>" ><?php _ex( 'Tags', 'Group directory tab', 'buddypress' ); ?></a></li>
     1532<?php
     1533}
     1534add_action( 'bp_groups_directory_group_filter', 'bp_groups_tag_add_directory_tab', 0 );
     1535
     1536/**
     1537 * Set group loop scope when on a group tag page.
     1538 *
     1539 * @since BuddyPress (?)
     1540 */
     1541function bp_groups_tag_set_scope() {
     1542        // group tag page
     1543        if ( bp_is_groups_tag() ) {
     1544
     1545                // set scope to tag
     1546                $_POST['cookie'] = 'bp-groups-scope%3Dtag%3B%20bp-groups-filter%3D-1';
     1547
     1548                // reset the scope to 'tag' so our 'Tags' tab is highlighted
     1549                @setcookie( 'bp-groups-scope', 'tag', 0, '/' );
     1550
     1551                // reset the dropdown menu to 'Everything'
     1552                @setcookie( 'bp-groups-filter', '-1', 0, '/' );
     1553
     1554
     1555        // group directory
     1556        } elseif ( bp_is_groups_directory() ) {
     1557                $scope = ! empty( $_COOKIE['bp-groups-scope'] ) ? $_COOKIE['bp-groups-scope'] : '';
     1558
     1559                // if we're on the group directory and we last-visited a tag page,
     1560                // let's reset the scope to 'all'
     1561                if ( $scope == 'tag' ) {
     1562                        @setcookie( 'bp-groups-scope', 'all', 0, '/' );
     1563                }
     1564        }
     1565}
     1566add_action( 'bp_screens', 'bp_groups_tag_set_scope', 9 );
     1567
     1568/**
     1569 * Set querystring when on a group tag page.
     1570 *
     1571 * @since BuddyPress (?)
     1572 */
     1573function bp_groups_tag_querystring( $retval ) {
     1574        if ( ! bp_is_groups_tag() ) {
     1575                return $retval;
     1576        }
     1577
     1578        $args = wp_parse_args( $retval );
     1579
     1580        if ( ! isset( $args['scope'] ) ) {
     1581                return $retval;
     1582        }
     1583
     1584        if ( 'tag' !== $args['scope'] ) {
     1585                return $retval;
     1586        }
     1587
     1588        $args['type'] = 'tag';
     1589        $args['slug'] = bp_action_variable( 0 );
     1590
     1591        return $args;
     1592}
     1593add_filter( 'bp_ajax_querystring', 'bp_groups_tag_querystring', 20 );
     1594
     1595/**
     1596 * Inject a header on the group directory page if we're on a tag page.
     1597 *
     1598 * @since BuddyPress (?)
     1599 */
     1600function bp_groups_tag_header() {
     1601        if ( ! bp_is_groups_tag() ) {
     1602                return;
     1603        }
     1604
     1605        if ( defined( 'DOING_AJAX' ) ) {
     1606                // grab the AJAX querystring
     1607                $qs = ! empty( $_POST['cookie'] ) ? urldecode( $_POST['cookie'] ) : '';
     1608
     1609                // not a tag page? stop now!
     1610                if ( strpos( $qs, 'bp-groups-scope=tag' ) === false ) {
     1611                        return;
     1612                }
     1613        }
     1614
     1615        printf( '<h3>' . __( 'Groups tagged: "%s"', 'buddypress' ) . '</h3>', buddypress()->groups->tag->name );
     1616
     1617        if ( ! empty( buddypress()->groups->tag->description ) ) {
     1618                echo '<p>' . esc_html( buddypress()->groups->tag->description ) . '</p>';
     1619        }
     1620
     1621}
     1622add_action( 'bp_before_groups_loop', 'bp_groups_tag_header' );
     1623
     1624/**
     1625 * Add "Group Tags" input field to group creation and group admin edit pages.
     1626 *
     1627 * @since BuddyPress (?)
     1628 *
     1629 * @see bp_groups_the_tagbox()
     1630 */
     1631function bp_groups_tag_add_field_to_frontend_group_admin() {
     1632        // prevent duplicate fields on group creation page
     1633        if ( bp_is_group_creation_step( 'group-details' ) && did_action( 'groups_custom_group_fields_editable' ) ) {
     1634                return;
     1635        }
     1636?>
     1637
     1638        <label for="new-tag-bp_group_tags"><?php _e( 'Group Tags', 'buddypress' ); ?></label>
     1639        <div id="tagsdiv-bp_group_tags" class="bp-tag-editor">
     1640                <?php bp_groups_the_tagbox();?>
     1641        </div>
     1642
     1643<?php
     1644}
     1645add_action( 'bp_after_group_details_creation_step', 'bp_groups_tag_add_field_to_frontend_group_admin', 1 );
     1646add_action( 'groups_custom_group_fields_editable',  'bp_groups_tag_add_field_to_frontend_group_admin', 1 );
  • src/bp-groups/bp-groups-loader.php

    diff --git src/bp-groups/bp-groups-loader.php src/bp-groups/bp-groups-loader.php
    index e07dd26..b66f3af 100644
    class BP_Groups_Component extends BP_Component { 
    247247                        'members',
    248248                        'settings',
    249249                        'avatar',
     250                        bp_get_groups_tag_slug(),
    250251                        $this->slug,
    251252                        $this->root_slug,
    252253                ) );
    class BP_Groups_Component extends BP_Component { 
    625626
    626627                parent::setup_title();
    627628        }
     629
     630        public function register_taxonomies( $taxonomy = '', $object_type = '', $args = array(), $network = false ) {
     631                $labels = array(
     632                        'name'                       => _x( 'Group Tags',                           'groups tag general name',  'buddypress' ),
     633                        'singular_name'              => _x( 'Group Tag',                            'groups tag singular name', 'buddypress' ),
     634                        'search_items'               => _x( 'Search Group Tags',                    'groups tag search',        'buddypress' ),
     635                        'popular_items'              => _x( 'Popular Group Tags',                   'groups tag popular',       'buddypress' ),
     636                        'all_items'                  => _x( 'All Group Tags',                       'groups tag all',           'buddypress' ),
     637                        'parent_item'                => null,
     638                        'parent_item_colon'          => null,
     639                        'edit_item'                  => _x( 'Edit Group Tag',                       'groups tag edit',          'buddypress' ),
     640                        'update_item'                => _x( 'Update Group Tag',                     'groups tag update',        'buddypress' ),
     641                        'add_new_item'               => _x( 'Add New Group Tag',                    'groups tag add new',       'buddypress' ),
     642                        'new_item_name'              => _x( 'New Group Tag Name',                   'groups tag new',           'buddypress' ),
     643                        'separate_items_with_commas' => _x( 'Separate Group Tags with commas',      'groups tag comma',         'buddypress' ),
     644                        'add_or_remove_items'        => _x( 'Add or remove Group Tags',             'groups tag add remove',    'buddypress' ),
     645                        'choose_from_most_used'      => _x( 'Choose from the most used Group Tags', 'groups tag most used',     'buddypress' ),
     646                        'not_found'                  => _x( 'No Group Tags found.',                 'groups tag not found',     'buddypress' ),
     647                );
     648
     649                $args = array(
     650                        'hierarchical'          => false,
     651                        'labels'                => $labels,
     652                        'show_ui'               => false,
     653                        'show_admin_column'     => false,
     654                        'query_var'             => false,
     655                        'show_tagcloud'         => true,
     656                        'rewrite'               => array(
     657                                'slug' => bp_get_groups_root_slug() . '/' . bp_get_groups_tag_slug(),
     658                                'with_front' => false
     659                        ),
     660                        'capabilities' => array(
     661                                'manage_terms'  => 'manage_group_tags',
     662                                'edit_terms'    => 'edit_group_tags',
     663                                'delete_terms'  => 'delete_group_tags',
     664                                'assign_terms'  => 'assign_group_tags'
     665                        ),
     666                        'update_count_callback' => 'bp_core_update_term_count',
     667                        'meta_box_cb'           => 'bp_tags_meta_box'
     668                );
     669
     670                parent::register_taxonomies( 'bp_group_tags', array( 'bp_group' ), $args, true );
     671        }
    628672}
    629673
    630674/**
  • src/bp-groups/bp-groups-screens.php

    diff --git src/bp-groups/bp-groups-screens.php src/bp-groups/bp-groups-screens.php
    index e89c72b..e1b4882 100644
    function groups_screen_group_admin_edit_details() { 
    595595
    596596                        $group_notify_members = isset( $_POST['group-notify-members'] ) ? (int) $_POST['group-notify-members'] : 0;
    597597
    598                         if ( !groups_edit_base_group_details( $_POST['group-id'], $_POST['group-name'], $_POST['group-desc'], $group_notify_members ) ) {
     598                        $error = false;
     599
     600                        if ( ! groups_edit_base_group_details( $_POST['group-id'], $_POST['group-name'], $_POST['group-desc'], $group_notify_members ) ) {
     601                                $error = true;
     602                        }
     603
     604                        if ( ! empty( $_POST['tax_input'] ) ) {
     605                                if ( ! bp_groups_set_taxonomy( $_POST['tax_input'], $bp->groups->current_group->id ) ) {
     606                                        $error = true;
     607                                }
     608                        }
     609
     610                        if ( ! empty( $error ) ) {
    599611                                bp_core_add_message( __( 'There was an error updating group details; please try again.', 'buddypress' ), 'error' );
    600612                        } else {
    601613                                bp_core_add_message( __( 'Group details were successfully updated.', 'buddypress' ) );
    class BP_Groups_Theme_Compat { 
    10431055                        return;
    10441056
    10451057                // Group Directory
    1046                 if ( ! bp_current_action() && ! bp_current_item() ) {
     1058                if ( ( ! bp_current_action() && ! bp_current_item() ) || bp_is_groups_tag() ) {
    10471059                        bp_update_is_directory( true, 'groups' );
    10481060
    10491061                        do_action( 'groups_directory_groups_setup' );
  • src/bp-groups/bp-groups-template.php

    diff --git src/bp-groups/bp-groups-template.php src/bp-groups/bp-groups-template.php
    index d487aeb..890e337 100644
    class BP_Groups_Template { 
    206206                }
    207207
    208208                $defaults = array(
    209                         'type'            => 'active',
    210                         'page'            => 1,
    211                         'per_page'        => 20,
    212                         'max'             => false,
    213                         'show_hidden'     => false,
    214                         'page_arg'        => 'grpage',
    215                         'user_id'         => 0,
    216                         'slug'            => false,
    217                         'include'         => false,
    218                         'exclude'         => false,
    219                         'search_terms'    => '',
    220                         'meta_query'      => false,
    221                         'populate_extras' => true,
     209                        'type'              => 'active',
     210                        'page'              => 1,
     211                        'per_page'          => 20,
     212                        'max'               => false,
     213                        'show_hidden'       => false,
     214                        'page_arg'          => 'grpage',
     215                        'user_id'           => 0,
     216                        'slug'              => false,
     217                        'include'           => false,
     218                        'exclude'           => false,
     219                        'search_terms'      => '',
     220                        'meta_query'        => false,
     221                        'tax_query'         => false,
     222                        'populate_extras'   => true,
    222223                        'update_meta_cache' => true,
    223224                );
    224225
    class BP_Groups_Template { 
    267268                                'user_id'           => $user_id,
    268269                                'search_terms'      => $search_terms,
    269270                                'meta_query'        => $meta_query,
     271                                'tax_query'         => $tax_query,
    270272                                'include'           => $include,
    271273                                'exclude'           => $exclude,
    272274                                'populate_extras'   => $populate_extras,
    class BP_Groups_Template { 
    445447 *     @type array $meta_query Optional. An array of meta_query
    446448 *           conditions. See {@link WP_Meta_Query::queries} for
    447449 *           description.
     450 *     @type array $tax_query Optional. An array of tax_query
     451 *           conditions. See {@link WP_Tax_Query::queries} for
     452 *           description.
    448453 *     @type array|string Optional. Array or comma-separated list of
    449454 *           group IDs. Results will be limited to groups within the
    450455 *           list. Default: false.
    function bp_has_groups( $args = '' ) { 
    508513                'slug'              => $slug,
    509514                'search_terms'      => $search_terms,
    510515                'meta_query'        => false,
     516                'tax_query'         => false,
    511517                'include'           => false,
    512518                'exclude'           => false,
    513519                'populate_extras'   => true,
    514520                'update_meta_cache' => true,
    515521        ), 'has_groups' );
    516522
     523        // Filter by group tag
     524        // Pass 'type' as 'tag' and 'slug' with the tag's slug
     525        if ( 'tag' === $r['type'] && ! empty( $r['slug'] ) ) {
     526                $r['tax_query'] = array( array(
     527                        'taxonomy' => 'bp_group_tags',
     528                        'terms'    => $r['slug'],
     529                        'field'    => 'slug',
     530                ) );
     531        }
     532
    517533        // Setup the Groups template global
    518534        $groups_template = new BP_Groups_Template( array(
    519535                'type'              => $r['type'],
    function bp_has_groups( $args = '' ) { 
    528544                'slug'              => $r['slug'],
    529545                'search_terms'      => $r['search_terms'],
    530546                'meta_query'        => $r['meta_query'],
     547                'tax_query'         => $r['tax_query'],
    531548                'include'           => $r['include'],
    532549                'exclude'           => $r['exclude'],
    533550                'populate_extras'   => (bool) $r['populate_extras'],
    class BP_Groups_Membership_Requests_Template { 
    41264143function bp_group_has_membership_requests( $args = '' ) {
    41274144        global $requests_template;
    41284145
     4146        $tax_query = array();
     4147        if ( bp_is_groups_tag() ) {
     4148                $tax_query = array(
     4149                        array(
     4150                                'taxonomy' => 'bp_group_tags',
     4151                                'terms'    => $bp->groups->tag->term_id,
     4152                                'field'    => 'term_id',
     4153                        )
     4154                );
     4155        }
     4156
    41294157        $defaults = array(
    41304158                'group_id' => bp_get_current_group_id(),
    41314159                'per_page' => 10,
    function bp_groups_get_profile_stats( $args = '' ) { 
    47684796        // Filter and return
    47694797        return apply_filters( 'bp_groups_get_profile_stats', $r['output'], $r );
    47704798}
     4799
     4800/* Group Tags *****************************************************************/
     4801
     4802/**
     4803 * Output the groups component tag slug
     4804 *
     4805 * @package BuddyPress
     4806 * @subpackage Groups Template
     4807 * @since BuddyPress (?)
     4808 *
     4809 * @uses bp_get_groups_tag_slug()
     4810 */
     4811function bp_groups_tag_slug() {
     4812        echo bp_get_groups_tag_slug();
     4813}
     4814
     4815        /**
     4816         * Return the groups component tag slug
     4817         *
     4818         * @package BuddyPress
     4819         * @subpackage Groups Template
     4820         * @since BuddyPress (?)
     4821         */
     4822        function bp_get_groups_tag_slug() {
     4823                return apply_filters( 'bp_get_groups_tag_slug', 'tag' );
     4824        }
     4825
     4826/**
     4827 * Output the current group tagbox
     4828 *
     4829 * @since BuddyPress (?)
     4830 *
     4831 * @uses bp_get_groups_the_tagbox()
     4832 */
     4833function bp_groups_the_tagbox() {
     4834        echo bp_get_groups_the_tagbox();
     4835}
     4836        /**
     4837         * Return the current group tagbox
     4838         *
     4839         * @since BuddyPress (?)
     4840         */
     4841        function bp_get_groups_the_tagbox() {
     4842                $bp = buddypress();
     4843
     4844                $group = $bp->groups->current_group;
     4845
     4846                if ( empty( $group ) ) {
     4847                        $group = new stdClass;
     4848                        $group->id = 0;
     4849                }
     4850
     4851                $box = array(
     4852                        'taxonomy' => 'bp_group_tags',
     4853                        'title'    => __( 'Group Tags', 'buddypress' ),
     4854                );
     4855
     4856                require_once( ABSPATH . 'wp-admin/includes/taxonomy.php' );
     4857
     4858                ob_start();
     4859                bp_tags_meta_box( $group, $box );
     4860                $tagbox = ob_get_contents();
     4861                ob_end_clean();
     4862
     4863                return apply_filters( 'bp_get_groups_the_tagbox', '<div class="inside">' . $tagbox . '</div>' );
     4864        }
     4865
     4866/**
     4867 * Output group tags
     4868 *
     4869 * @since BuddyPress (?)
     4870 *
     4871 * @uses bp_get_groups_the_tags()
     4872 * @param int $group_id The group ID.
     4873 */
     4874function bp_groups_the_tags( $group_id = 0 ) {
     4875        echo bp_get_groups_the_tags( $group_id );
     4876}
     4877add_action( 'bp_directory_groups_item',    'bp_groups_the_tags' );
     4878add_action( 'bp_before_group_header_meta', 'bp_groups_the_tags' );
     4879
     4880        /**
     4881         * Return a comma-separated list of tags for a group.
     4882         *
     4883         * @since BuddyPress (?)
     4884         *
     4885         * @todo Perhaps add parameters for HTML markup?
     4886         *
     4887         * @param int $group_id The group ID.
     4888         * @return string|bool HTML markup of comma-separated tags; boolean false otherwise.
     4889         */
     4890        function bp_get_groups_the_tags( $group_id = 0 ) {
     4891                if ( empty( $group_id ) ) {
     4892                        $group_id = bp_get_group_id();
     4893                }
     4894
     4895                if ( empty( $group_id ) ) {
     4896                        return false;
     4897                }
     4898
     4899                $tag_list = bp_core_get_the_term_list( $group_id, 'bp_group_tags', '', ', ', '' );
     4900
     4901                if ( empty( $tag_list ) ) {
     4902                        return false;
     4903                }
     4904
     4905                $html  = '<div class="group-tags">';
     4906                $html .= '<span>' . esc_html_x( 'Tags:', 'Group tags prefix', 'buddypress' ) . ' </span>';
     4907                $html .= $tag_list;
     4908                $html .= '</div>';
     4909
     4910                return apply_filters( 'bp_get_groups_the_tags', $html, $group_id );
     4911        }
  • src/bp-templates/bp-legacy/buddypress/groups/index.php

    diff --git src/bp-templates/bp-legacy/buddypress/groups/index.php src/bp-templates/bp-legacy/buddypress/groups/index.php
    index 8f421bb..5ee9ce4 100644
     
    3131                        <ul>
    3232                                <?php do_action( 'bp_groups_directory_group_types' ); ?>
    3333
    34                                 <li id="groups-order-select" class="last filter">
     34                                <?php if ( ! bp_is_groups_tag() ) : ?>
    3535
    36                                         <label for="groups-order-by"><?php _e( 'Order By:', 'buddypress' ); ?></label>
     36                                        <li id="groups-order-select" class="last filter">
    3737
    38                                         <select id="groups-order-by">
    39                                                 <option value="active"><?php _e( 'Last Active', 'buddypress' ); ?></option>
    40                                                 <option value="popular"><?php _e( 'Most Members', 'buddypress' ); ?></option>
    41                                                 <option value="newest"><?php _e( 'Newly Created', 'buddypress' ); ?></option>
    42                                                 <option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
     38                                                <label for="groups-order-by"><?php _e( 'Order By:', 'buddypress' ); ?></label>
    4339
    44                                                 <?php do_action( 'bp_groups_directory_order_options' ); ?>
    45                                         </select>
    46                                 </li>
     40                                                <select id="groups-order-by">
     41                                                        <option value="active"><?php _e( 'Last Active', 'buddypress' ); ?></option>
     42                                                        <option value="popular"><?php _e( 'Most Members', 'buddypress' ); ?></option>
     43                                                        <option value="newest"><?php _e( 'Newly Created', 'buddypress' ); ?></option>
     44                                                        <option value="alphabetical"><?php _e( 'Alphabetical', 'buddypress' ); ?></option>
     45
     46                                                        <?php do_action( 'bp_groups_directory_order_options' ); ?>
     47                                                </select>
     48                                        </li>
     49
     50                                <?php endif ;?>
    4751                        </ul>
    4852                </div>
    4953