Skip to:
Content

BuddyPress.org

Changeset 12729


Ignore:
Timestamp:
09/21/2020 01:21:21 AM (16 months ago)
Author:
imath
Message:

BP Types: merge BP Types saved in DB with the ones registered by code

  • Introduces the bp_get_taxonomy_types() to merge types saved into the database with the types registered by code. It's now possible to edit all properties of the registered by code types except for the type's slug which needs to be unique.
  • Caches these merged types.
  • Introduces the bp_get_member_types_registered_by_code() to only get member types registered by code.
  • Updates the test_bp_get_member_type_should_not_return_unregistered_types() unit test to test_bp_get_registered_by_code_member_type_should_not_return_unregistered_types() to check the previous point new function.
  • Introduces the bp_update_type_metadata() function to update a type's metadata.

Props mercime, DJPaul, dcavins, boonebgorges, tw2113, sbrajesh

See #7179
See #7181

Location:
trunk
Files:
4 edited

Legend:

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

    r12541 r12729  
    391391add_action( 'bp_invitation_after_save', 'bp_invitations_reset_cache_incrementor' );
    392392add_action( 'bp_invitation_after_delete', 'bp_invitations_reset_cache_incrementor' );
     393
     394/**
     395 * Add a cache group for Database object types.
     396 *
     397 * @since 7.0.0
     398 */
     399function bp_set_object_type_terms_cache_group() {
     400    wp_cache_add_global_groups( 'bp_object_terms' );
     401}
     402add_action( 'bp_setup_cache_groups', 'bp_set_object_type_terms_cache_group' );
     403
     404/**
     405 * Clear the Database object types cache.
     406 *
     407 * @since 7.0.0
     408 *
     409 * @param int $type_id The Type's term ID.
     410 * @param string $taxonomy The Type's taxonomy name.
     411 */
     412function bp_clear_object_type_terms_cache( $type_id = 0, $taxonomy = '' ) {
     413    wp_cache_delete( $taxonomy, 'bp_object_terms' );
     414}
     415add_action( 'bp_type_inserted', 'bp_clear_object_type_terms_cache' );
     416add_action( 'bp_type_updated', 'bp_clear_object_type_terms_cache' );
     417add_action( 'bp_type_deleted', 'bp_clear_object_type_terms_cache' );
  • trunk/src/bp-core/bp-core-functions.php

    r12728 r12729  
    31443144}
    31453145
     3146/**
     3147 * Update a list of metadata for a given type ID and a given taxonomy.
     3148 *
     3149 * @since 7.0.0
     3150 *
     3151 * @param  integer $type_id    The database ID of the BP Type.
     3152 * @param  string  $taxonomy   The BP Type taxonomy.
     3153 * @param  array   $type_metas An associative array (meta_key=>meta_value).
     3154 * @return boolean             False on failure. True otherwise.
     3155 */
     3156function bp_update_type_metadata( $type_id = 0, $taxonomy = '', $type_metas = array() ) {
     3157    if ( ! $type_id || ! $taxonomy || ! is_array( $type_metas ) ) {
     3158        return false;
     3159    }
     3160
     3161    foreach ( $type_metas as $meta_key => $meta_value ) {
     3162        if ( ! registered_meta_key_exists( 'term', $meta_key, $taxonomy ) ) {
     3163            continue;
     3164        }
     3165
     3166        update_term_meta( $type_id, $meta_key, $meta_value );
     3167    }
     3168
     3169    return true;
     3170}
     3171
     3172/**
     3173 * Get types for a given BP Taxonomy.
     3174 *
     3175 * @since 7.0.0
     3176 *
     3177 * @param string $taxonomy The taxonomy to transform terms in types for.
     3178 * @param array  $types    Existing types to merge with the types found into the database.
     3179 *                         For instance this function is used internally to merge Group/Member
     3180 *                         types registered using code with the ones created by the administrator
     3181 *                         from the Group/Member types Administration screen. If not provided, only
     3182 *                         Types created by the administrator will be returned.
     3183 *                         Optional.
     3184 * @return array           The types of the given taxonomy.
     3185 */
     3186function bp_get_taxonomy_types( $taxonomy = '', $types = array() ) {
     3187    if ( ! $taxonomy ) {
     3188        return $types;
     3189    }
     3190
     3191    $db_types = wp_cache_get( $taxonomy, 'bp_object_terms' );
     3192
     3193    if ( ! $db_types ) {
     3194        $terms = bp_get_terms(
     3195            array(
     3196                'taxonomy' => $taxonomy,
     3197            )
     3198        );
     3199
     3200        if ( ! is_array( $terms ) || ! $terms ) {
     3201            return $types;
     3202        }
     3203
     3204        $type_metadata = array_keys( get_registered_meta_keys( 'term', $taxonomy ) );
     3205
     3206        foreach ( $terms as $term ) {
     3207            $type_name                      = $term->name;
     3208            $db_types[ $type_name ]         = new stdClass();
     3209            $db_types[ $type_name ]->db_id  = $term->term_id;
     3210            $db_types[ $type_name ]->labels = array();
     3211            $db_types[ $type_name ]->name   = $type_name;
     3212
     3213            if ( $type_metadata ) {
     3214                foreach ( $type_metadata as $meta_key ) {
     3215                    $type_key = str_replace( 'bp_type_', '', $meta_key );
     3216                    if ( in_array( $type_key, array( 'name', 'singular_name' ), true ) ) {
     3217                        $db_types[ $type_name ]->labels[ $type_key ] = get_term_meta( $term->term_id, $meta_key, true );
     3218                    } else {
     3219                        $db_types[ $type_name ]->{$type_key} = get_term_meta( $term->term_id, $meta_key, true );
     3220                    }
     3221                }
     3222            }
     3223        }
     3224
     3225        wp_cache_set( $taxonomy, $db_types, 'bp_object_terms' );
     3226    }
     3227
     3228    if ( is_array( $db_types ) ) {
     3229        foreach ( $db_types as $db_type_name => $db_type ) {
     3230            // Override props of registered by code types if customized by the admun user.
     3231            if ( isset( $types[ $db_type_name ] ) && isset( $types[ $db_type_name ]->code ) && $types[ $db_type_name ]->code ) {
     3232                // Merge Labels.
     3233                if ( $db_type->labels ) {
     3234                    foreach ( $db_type->labels as $key_label => $value_label ) {
     3235                        if ( '' !== $value_label ) {
     3236                            $types[ $db_type_name ]->labels[ $key_label ] = $value_label;
     3237                        }
     3238                    }
     3239                }
     3240
     3241                // Merge other properties.
     3242                foreach ( get_object_vars( $types[ $db_type_name ] ) as $key_prop => $value_prop ) {
     3243                    if ( 'labels' === $key_prop || 'name' === $key_prop ) {
     3244                        continue;
     3245                    }
     3246
     3247                    if ( isset( $db_type->{$key_prop} ) && '' !== $db_type->{$key_prop} ) {
     3248                        $types[ $db_type_name  ]->{$key_prop} = $db_type->{$key_prop};
     3249                    }
     3250                }
     3251
     3252                unset( $db_types[ $db_type_name ] );
     3253            }
     3254        }
     3255    }
     3256
     3257    return array_merge( $types, (array) $db_types );
     3258}
     3259
    31463260/** Email *****************************************************************/
    31473261
  • trunk/src/bp-members/bp-members-functions.php

    r12728 r12729  
    27642764        'labels'        => array(),
    27652765        'has_directory' => true,
     2766        'code'          => true,
     2767        'db_id'         => 0,
    27662768    ), 'register_member_type' );
    27672769
     
    28632865    $types = buddypress()->members->types;
    28642866
     2867    // Merge with types available into the database.
     2868    if ( ! isset( $args['code'] ) || true !== $args['code'] ) {
     2869        $types = bp_get_taxonomy_types( bp_get_member_type_tax_name(), $types );
     2870    }
     2871
    28652872    $types = wp_filter_object_list( $types, $args, $operator );
    28662873
     
    28852892    return $types;
    28862893}
     2894
     2895/**
     2896 * Only gets the member types registered by code.
     2897 *
     2898 * @since 7.0.0
     2899 *
     2900 * @return array The member types registered by code.
     2901 */
     2902function bp_get_member_types_registered_by_code() {
     2903    return bp_get_member_types(
     2904        array(
     2905            'code' => true,
     2906        ),
     2907        'objects'
     2908    );
     2909}
     2910add_filter( bp_get_member_type_tax_name() . '_registered_by_code', 'bp_get_member_types_registered_by_code' );
     2911
     2912/**
     2913 * Generates missing metadata for a type registered by code.
     2914 *
     2915 * @since 7.0.0
     2916 *
     2917 * @return array The member type metadata.
     2918 */
     2919function bp_set_registered_by_code_member_type_metadata( $metadata = array(), $type = '' ) {
     2920    $member_type = bp_get_member_type_object( $type );
     2921
     2922    foreach ( get_object_vars( $member_type ) as $object_key => $object_value ) {
     2923        if ( 'labels' === $object_key ) {
     2924            foreach ( $object_value as $label_key => $label_value ) {
     2925                $metadata[ 'bp_type_' . $label_key ] = $label_value;
     2926            }
     2927        } elseif ( ! in_array( $object_key, array( 'name', 'code', 'db_id' ), true ) ) {
     2928            $metadata[ 'bp_type_' . $object_key ] = $object_value;
     2929        }
     2930    }
     2931
     2932    /**
     2933     * Save metadata into database to avoid generating metadata
     2934     * each time a type is listed into the Types Admin screen.
     2935     */
     2936    if ( isset( $member_type->db_id ) && $member_type->db_id ) {
     2937        bp_update_type_metadata( $member_type->db_id, bp_get_member_type_tax_name(), $metadata );
     2938    }
     2939
     2940    return $metadata;
     2941}
     2942add_filter( bp_get_member_type_tax_name() . '_set_registered_by_code_metada', 'bp_set_registered_by_code_member_type_metadata', 10, 2 );
     2943
     2944/**
     2945 * Insert member types registered by code not yet saved into the database as WP Terms.
     2946 *
     2947 * @since 7.0.0
     2948 */
     2949function bp_insert_member_types_registered_by_code() {
     2950    $all_types     = bp_get_member_types( array(), 'objects' );
     2951    $unsaved_types = wp_filter_object_list( $all_types, array( 'db_id' => 0 ), 'and', 'name' );
     2952
     2953    if ( $unsaved_types ) {
     2954        foreach ( $unsaved_types as $type_name ) {
     2955            bp_insert_term(
     2956                $type_name,
     2957                bp_get_member_type_tax_name(),
     2958                array(
     2959                    'slug' => $type_name,
     2960                )
     2961            );
     2962        }
     2963    }
     2964}
     2965add_action( bp_get_member_type_tax_name() . '_add_form', 'bp_insert_member_types_registered_by_code', 1 );
    28872966
    28882967/**
     
    29693048 *
    29703049 * @since 2.2.0
     3050 * @since 7.0.0 Adds the `$use_db` parameter.
    29713051 *
    29723052 * @param int  $user_id ID of the user.
    29733053 * @param bool $single  Optional. Whether to return a single type string. If multiple types are found
    29743054 *                      for the user, the oldest one will be returned. Default: true.
     3055 * @param bool $use_db  Optional. Whether to request all member types or only the ones registered by code.
     3056 *                      Default: true.
    29753057 * @return string|array|bool On success, returns a single member type (if $single is true) or an array of member
    29763058 *                           types (if $single is false). Returns false on failure.
    29773059 */
    2978 function bp_get_member_type( $user_id, $single = true ) {
     3060function bp_get_member_type( $user_id, $single = true, $use_db = true ) {
    29793061    $types = wp_cache_get( $user_id, 'bp_member_member_type' );
    29803062
     
    29943076            wp_cache_set( $user_id, $types, 'bp_member_member_type' );
    29953077        }
     3078    }
     3079
     3080    if ( false === $use_db && $types ) {
     3081        $registred_by_code = bp_get_member_types_registered_by_code();
     3082        $ctype_names       = wp_list_pluck( $registred_by_code, 'name' );
     3083        $types             = array_intersect( $types, $ctype_names );
    29963084    }
    29973085
  • trunk/tests/phpunit/testcases/members/types.php

    r11737 r12729  
    394394    }
    395395
    396     public function test_bp_get_member_type_should_not_return_unregistered_types() {
     396    public function test_bp_get_registered_by_code_member_type_should_not_return_unregistered_types() {
    397397        $u1 = self::factory()->user->create();
    398398        bp_register_member_type( 'foo' );
     
    402402        bp_set_object_terms( $u1, 'ugh', bp_get_member_type_tax_name(), true );
    403403
    404         $type = bp_get_member_type( $u1, false );
     404        $type = bp_get_member_type( $u1, false, false );
    405405        $this->assertEquals( array( 'foo' ), $type );
    406406    }
Note: See TracChangeset for help on using the changeset viewer.