Skip to:
Content

BuddyPress.org

Ticket #4551: meta-api.patch

File meta-api.patch, 36.5 KB (added by sbrajesh, 12 years ago)

Meta API patch for Bp 1.6 Trunk

  • bp-core/bp-core-meta.php

     
     1<?php
     2/**
     3 * BuddyPress Metadata API
     4 *
     5 * Functions for retrieving and manipulating metadata of various BuddyPress object/component types. Metadata
     6 * for an object is a represented by a simple key-value pair. Objects may contain multiple
     7 * metadata entries that share the same key and differ only in their value.
     8 *
     9 * @package BuddyPress
     10 * @subpackage Core
     11 * @since 1.6.2
     12 */
     13
     14/**
     15 * Add metadata for the specified object.
     16 *
     17 * @since 1.6.2
     18 * @uses $wpdb WordPress database object for queries.
     19 * @uses do_action() Calls 'added_{$meta_type}_meta' with meta_id of added metadata entry,
     20 *              object ID, meta key, and meta value
     21 *
     22 * @param string $meta_type Type of object metadata is for (e.g., activity, group etc)
     23 * @param int $object_id ID of the object metadata is for
     24 * @param string $meta_key Metadata key
     25 * @param string $meta_value Metadata value
     26 * @param bool $unique Optional, default is false. Whether the specified metadata key should be
     27 *              unique for the object. If true, and the object already has a value for the specified
     28 *              metadata key, no change will be made
     29 * @return bool The meta ID on successful update, false on failure.
     30 */
     31function bp_add_metadata($meta_type, $object_id, $meta_key, $meta_value, $unique = false) {
     32        if ( !$meta_type || !$meta_key )
     33                return false;
     34
     35        if ( !$object_id = absint($object_id) )
     36                return false;
     37
     38        if ( ! $table = _bp_get_meta_table($meta_type) )
     39                return false;
     40
     41        global $wpdb;
     42
     43        $column = esc_sql($meta_type . '_id');
     44
     45        // expected_slashed ($meta_key)
     46        $meta_key = stripslashes($meta_key);
     47        $meta_value = stripslashes_deep($meta_value);
     48        $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     49
     50        $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
     51        if ( null !== $check )
     52                return $check;
     53
     54        if ( $unique && $wpdb->get_var( $wpdb->prepare(
     55                "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
     56                $meta_key, $object_id ) ) )
     57                return false;
     58
     59        $_meta_value = $meta_value;
     60        $meta_value = maybe_serialize( $meta_value );
     61
     62        do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
     63
     64        $result = $wpdb->insert( $table, array(
     65                $column => $object_id,
     66                'meta_key' => $meta_key,
     67                'meta_value' => $meta_value
     68        ) );
     69
     70        if ( ! $result )
     71                return false;
     72
     73        $mid = (int) $wpdb->insert_id;
     74
     75        wp_cache_delete($object_id, 'bp_'.$meta_type . '_meta');
     76
     77        do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
     78
     79        return $mid;
     80}
     81
     82/**
     83 * Update metadata for the specified object. If no value already exists for the specified object
     84 * ID and metadata key, the metadata will be added.
     85 *
     86 * @since 1.6.2
     87 * @uses $wpdb WordPress database object for queries.
     88 * @uses do_action() Calls 'update_{$meta_type}_meta' before updating metadata with meta_id of
     89 *              metadata entry to update, object ID, meta key, and meta value
     90 * @uses do_action() Calls 'updated_{$meta_type}_meta' after updating metadata with meta_id of
     91 *              updated metadata entry, object ID, meta key, and meta value
     92 *
     93 * @param string $meta_type Type of object metadata is for (e.g., activity, group etc)
     94 * @param int $object_id ID of the object metadata is for
     95 * @param string $meta_key Metadata key
     96 * @param string $meta_value Metadata value
     97 * @param string $prev_value Optional. If specified, only update existing metadata entries with
     98 *              the specified value. Otherwise, update all entries.
     99 * @return bool True on successful update, false on failure.
     100 */
     101function bp_update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_value = '') {
     102        if ( !$meta_type || !$meta_key )
     103                return false;
     104
     105        if ( !$object_id = absint($object_id) )
     106                return false;
     107
     108        if ( ! $table = _bp_get_meta_table($meta_type) )
     109                return false;
     110
     111        global $wpdb;
     112
     113        $column = esc_sql($meta_type . '_id');//eg.g activity_id, group_id
     114        $id_column = 'id';
     115
     116        // expected_slashed ($meta_key)
     117        $meta_key = stripslashes($meta_key);
     118        $passed_value = $meta_value;
     119        $meta_value = stripslashes_deep($meta_value);
     120        $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     121
     122        $check = apply_filters( "update_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $prev_value );
     123        if ( null !== $check )
     124                return (bool) $check;
     125
     126        if ( ! $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ) )
     127                return bp_add_metadata($meta_type, $object_id, $meta_key, $passed_value);
     128
     129        // Compare existing value to new value if no prev value given and the key exists only once.
     130        if ( empty($prev_value) ) {
     131                $old_value = bp_get_metadata($meta_type, $object_id, $meta_key);
     132                if ( count($old_value) == 1 ) {
     133                        if ( $old_value[0] === $meta_value )
     134                                return false;
     135                }
     136        }
     137
     138        $_meta_value = $meta_value;
     139        $meta_value = maybe_serialize( $meta_value );
     140
     141        $data  = compact( 'meta_value' );
     142        $where = array( $column => $object_id, 'meta_key' => $meta_key );
     143
     144        if ( !empty( $prev_value ) ) {
     145                $prev_value = maybe_serialize($prev_value);
     146                $where['meta_value'] = $prev_value;
     147        }
     148
     149        do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
     150
     151       
     152
     153        $wpdb->update( $table, $data, $where );
     154
     155        wp_cache_delete($object_id, 'bp_'.$meta_type . '_meta');
     156
     157        do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
     158
     159       
     160
     161        return true;
     162}
     163
     164/**
     165 * Delete metadata for the specified object.
     166 *
     167 * @since 1.6.2
     168 * @uses $wpdb WordPress database object for queries.
     169 * @uses do_action() Calls 'deleted_{$meta_type}_meta' after deleting with meta_id of
     170 *              deleted metadata entries, object ID, meta key, and meta value
     171 *
     172 * @param string $meta_type Type of object metadata is for (e.g., activity, group)
     173 * @param int $object_id ID of the object metadata is for
     174 * @param string $meta_key Metadata key
     175 * @param string $meta_value Optional. Metadata value. If specified, only delete metadata entries
     176 *              with this value. Otherwise, delete all entries with the specified meta_key.
     177 * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries
     178 *              for all objects, ignoring the specified object_id. Otherwise, only delete matching
     179 *              metadata entries for the specified object_id.
     180 * @return bool True on successful delete, false on failure.
     181 */
     182function bp_delete_metadata($meta_type, $object_id, $meta_key, $meta_value = '', $delete_all = false) {
     183        if ( !$meta_type || !$meta_key )
     184                return false;
     185
     186        if ( (!$object_id = absint($object_id)) && !$delete_all )
     187                return false;
     188
     189        if ( ! $table = _bp_get_meta_table($meta_type) )
     190                return false;
     191
     192        global $wpdb;
     193
     194        $type_column = esc_sql($meta_type . '_id');
     195        $id_column = 'id';
     196        // expected_slashed ($meta_key)
     197        $meta_key = stripslashes($meta_key);
     198        $meta_value = stripslashes_deep($meta_value);
     199
     200        $check = apply_filters( "delete_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $delete_all );
     201        if ( null !== $check )
     202                return (bool) $check;
     203
     204        $_meta_value = $meta_value;
     205        $meta_value = maybe_serialize( $meta_value );
     206
     207        $query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
     208
     209        if ( !$delete_all )
     210                $query .= $wpdb->prepare(" AND $type_column = %d", $object_id );
     211
     212        if ( $meta_value )
     213                $query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
     214
     215        $meta_ids = $wpdb->get_col( $query );
     216        if ( !count( $meta_ids ) )
     217                return false;
     218
     219        if ( $delete_all )
     220                $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) );
     221
     222        do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
     223
     224       
     225
     226        $query = "DELETE FROM $table WHERE $id_column IN( " . implode( ',', $meta_ids ) . " )";
     227
     228        $count = $wpdb->query($query);
     229
     230        if ( !$count )
     231                return false;
     232
     233        if ( $delete_all ) {
     234                foreach ( (array) $object_ids as $o_id ) {
     235                        wp_cache_delete($o_id, 'bp_'.$meta_type . '_meta');
     236                }
     237        } else {
     238                wp_cache_delete($object_id, 'bp_'.$meta_type . '_meta');
     239        }
     240
     241        do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
     242
     243       
     244
     245        return true;
     246}
     247
     248/**
     249 * Retrieve metadata for the specified object.
     250 *
     251 * @since 1.6.2
     252 *
     253 * @param string $meta_type Type of object metadata is for (e.g., activity, group)
     254 * @param int $object_id ID of the object metadata is for
     255 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for
     256 *              the specified object.
     257 * @param bool $single Optional, default is false. If true, return only the first value of the
     258 *              specified meta_key. This parameter has no effect if meta_key is not specified.
     259 * @return string|array Single metadata value, or array of values
     260 */
     261function bp_get_metadata($meta_type, $object_id, $meta_key = '', $single = false) {
     262        if ( !$meta_type )
     263                return false;
     264
     265        if ( !$object_id = absint($object_id) )
     266                return false;
     267
     268        $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single );
     269        if ( null !== $check ) {
     270                if ( $single && is_array( $check ) )
     271                        return $check[0];
     272                else
     273                        return $check;
     274        }
     275
     276        $meta_cache = wp_cache_get($object_id, 'bp_'.$meta_type . '_meta');
     277
     278        if ( !$meta_cache ) {
     279                $meta_cache = _bp_update_meta_cache( $meta_type, array( $object_id ) );
     280                $meta_cache = $meta_cache[$object_id];
     281        }
     282
     283        if ( !$meta_key )
     284                return $meta_cache;
     285
     286        if ( isset($meta_cache[$meta_key]) ) {
     287                if ( $single )
     288                        return maybe_unserialize( $meta_cache[$meta_key][0] );
     289                else
     290                        return array_map('maybe_unserialize', $meta_cache[$meta_key]);
     291        }
     292
     293        if ($single)
     294                return '';
     295        else
     296                return array();
     297}
     298
     299/**
     300 * Determine if a meta key is set for a given object
     301 *
     302 * @since 1.6.2
     303 *
     304 * @param string $meta_type Type of object metadata is for (e.g., activity, group)
     305 * @param int $object_id ID of the object metadata is for
     306 * @param string $meta_key Metadata key.
     307 * @return boolean true of the key is set, false if not.
     308 */
     309function bp_metadata_exists( $meta_type, $object_id, $meta_key ) {
     310        if ( ! $meta_type )
     311                return false;
     312
     313        if ( ! $object_id = absint( $object_id ) )
     314                return false;
     315
     316        $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true );
     317        if ( null !== $check )
     318                return true;
     319
     320        $meta_cache = wp_cache_get( $object_id, 'bp_'.$meta_type . '_meta' );
     321
     322        if ( !$meta_cache ) {
     323                $meta_cache = _bp_update_meta_cache( $meta_type, array( $object_id ) );
     324                $meta_cache = $meta_cache[$object_id];
     325        }
     326
     327        if ( isset( $meta_cache[ $meta_key ] ) )
     328                return true;
     329
     330        return false;
     331}
     332
     333/**
     334 * Get meta data by meta ID
     335 *
     336 * @since 1.6.2
     337 *
     338 * @param string $meta_type Type of object metadata is for (e.g., activity, group, or message)
     339 * @param int $meta_id ID for a specific meta row
     340 * @return object Meta object or false.
     341 */
     342function bp_get_metadata_by_mid( $meta_type, $meta_id ) {
     343        global $wpdb;
     344
     345        if ( ! $meta_type )
     346                return false;
     347
     348        if ( !$meta_id = absint( $meta_id ) )
     349                return false;
     350
     351        if ( ! $table = _bp_get_meta_table($meta_type) )
     352                return false;
     353
     354        $id_column = 'id';
     355
     356        $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
     357
     358        if ( empty( $meta ) )
     359                return false;
     360
     361        if ( isset( $meta->meta_value ) )
     362                $meta->meta_value = maybe_unserialize( $meta->meta_value );
     363
     364        return $meta;
     365}
     366
     367/**
     368 * Update meta data by meta ID
     369 *
     370 * @since 1.6.2
     371 *
     372 * @uses get_metadata_by_mid() Calls get_metadata_by_mid() to fetch the meta key, value
     373 *              and object_id of the given meta_id.
     374 *
     375 * @param string $meta_type Type of object metadata is for (e.g., activity, group)
     376 * @param int $meta_id ID for a specific meta row
     377 * @param string $meta_value Metadata value
     378 * @param string $meta_key Optional, you can provide a meta key to update it
     379 * @return bool True on successful update, false on failure.
     380 */
     381function bp_update_metadata_by_mid( $meta_type, $meta_id, $meta_value, $meta_key = false ) {
     382        global $wpdb;
     383
     384        // Make sure everything is valid.
     385        if ( ! $meta_type )
     386                return false;
     387
     388        if ( ! $meta_id = absint( $meta_id ) )
     389                return false;
     390
     391        if ( ! $table = _bp_get_meta_table( $meta_type ) )
     392                return false;
     393
     394        $column = esc_sql($meta_type . '_id');
     395        $id_column =  'id';
     396
     397        // Fetch the meta and go on if it's found.
     398        if ( $meta = bp_get_metadata_by_mid( $meta_type, $meta_id ) ) {
     399                $original_key = $meta->meta_key;
     400                $original_value = $meta->meta_value;
     401                $object_id = $meta->{$column};
     402
     403                // If a new meta_key (last parameter) was specified, change the meta key,
     404                // otherwise use the original key in the update statement.
     405                if ( false === $meta_key ) {
     406                        $meta_key = $original_key;
     407                } elseif ( ! is_string( $meta_key ) ) {
     408                        return false;
     409                }
     410
     411                // Sanitize the meta
     412                $_meta_value = $meta_value;
     413                $meta_value = sanitize_meta( $meta_key, $meta_value, $meta_type );
     414                $meta_value = maybe_serialize( $meta_value );
     415
     416                // Format the data query arguments.
     417                $data = array(
     418                        'meta_key' => $meta_key,
     419                        'meta_value' => $meta_value
     420                );
     421
     422                // Format the where query arguments.
     423                $where = array();
     424                $where[$id_column] = $meta_id;
     425
     426                do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
     427
     428               
     429
     430                // Run the update query, all fields in $data are %s, $where is a %d.
     431                $result = (bool) $wpdb->update( $table, $data, $where, '%s', '%d' );
     432
     433                // Clear the caches.
     434                wp_cache_delete($object_id, 'bp_'.$meta_type . '_meta');
     435
     436                do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
     437
     438               
     439
     440                return $result;
     441        }
     442
     443        // And if the meta was not found.
     444        return false;
     445}
     446
     447/**
     448 * Delete meta data by meta ID
     449 *
     450 * @since 1.6.2
     451 *
     452 * @uses get_metadata_by_mid() Calls get_metadata_by_mid() to fetch the meta key, value
     453 *              and object_id of the given meta_id.
     454 *
     455 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
     456 * @param int $meta_id ID for a specific meta row
     457 * @return bool True on successful delete, false on failure.
     458 */
     459function bp_delete_metadata_by_mid( $meta_type, $meta_id ) {
     460        global $wpdb;
     461
     462        // Make sure everything is valid.
     463        if ( ! $meta_type )
     464                return false;
     465
     466        if ( ! $meta_id = absint( $meta_id ) )
     467                return false;
     468
     469        if ( ! $table = _bp_get_meta_table( $meta_type ) )
     470                return false;
     471
     472        // object and id columns
     473        $column = esc_sql($meta_type . '_id');
     474        $id_column = 'id';
     475
     476        // Fetch the meta and go on if it's found.
     477        if ( $meta = get_metadata_by_mid( $meta_type, $meta_id ) ) {
     478                $object_id = $meta->{$column};
     479
     480                do_action( "delete_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
     481
     482
     483                // Run the query, will return true if deleted, false otherwise
     484                $result = (bool) $wpdb->delete( $table, array( $id_column => $meta_id ) );
     485
     486                // Clear the caches.
     487                wp_cache_delete($object_id, 'bp_'.$meta_type . '_meta');
     488
     489                do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
     490
     491               
     492
     493                return $result;
     494
     495        }
     496
     497        // Meta id was not found.
     498        return false;
     499}
     500
     501/**
     502 * Update the metadata cache for the specified objects.
     503 *
     504 * @since 1.6.2
     505 * @uses $wpdb WordPress database object for queries.
     506 *
     507 * @param string $meta_type Type of object metadata is for (e.g., activity, group)
     508 * @param int|array $object_ids array or comma delimited list of object IDs to update cache for
     509 * @return mixed Metadata cache for the specified objects, or false on failure.
     510 */
     511function _bp_update_meta_cache($meta_type, $object_ids) {
     512        if ( empty( $meta_type ) || empty( $object_ids ) )
     513                return false;
     514
     515        if ( ! $table = _bp_get_meta_table($meta_type) )
     516                return false;
     517
     518        $column = esc_sql($meta_type . '_id');
     519
     520        global $wpdb;
     521
     522        if ( !is_array($object_ids) ) {
     523                $object_ids = preg_replace('|[^0-9,]|', '', $object_ids);
     524                $object_ids = explode(',', $object_ids);
     525        }
     526
     527        $object_ids = array_map('intval', $object_ids);
     528
     529        $cache_key = 'bp_'.$meta_type . '_meta';
     530        $ids = array();
     531        $cache = array();
     532        foreach ( $object_ids as $id ) {
     533                $cached_object = wp_cache_get( $id, $cache_key );
     534                if ( false === $cached_object )
     535                        $ids[] = $id;
     536                else
     537                        $cache[$id] = $cached_object;
     538        }
     539
     540        if ( empty( $ids ) )
     541                return $cache;
     542
     543        // Get meta info
     544        $id_list = join(',', $ids);
     545        $meta_list = $wpdb->get_results( $wpdb->prepare("SELECT $column, meta_key, meta_value FROM $table WHERE $column IN ($id_list)",
     546                $meta_type), ARRAY_A );
     547
     548        if ( !empty($meta_list) ) {
     549                foreach ( $meta_list as $metarow) {
     550                        $mpid = intval($metarow[$column]);
     551                        $mkey = $metarow['meta_key'];
     552                        $mval = $metarow['meta_value'];
     553
     554                        // Force subkeys to be array type:
     555                        if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) )
     556                                $cache[$mpid] = array();
     557                        if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) )
     558                                $cache[$mpid][$mkey] = array();
     559
     560                        // Add a value to the current pid/key:
     561                        $cache[$mpid][$mkey][] = $mval;
     562                }
     563        }
     564
     565        foreach ( $ids as $id ) {
     566                if ( ! isset($cache[$id]) )
     567                        $cache[$id] = array();
     568                wp_cache_add( $id, $cache[$id], $cache_key );
     569        }
     570
     571        return $cache;
     572}
     573
     574/**
     575 * Given a meta query, generates SQL clauses to be appended to a main query
     576 *
     577 * @since 1.6.2
     578 *
     579 * @see WP_Meta_Query
     580 *
     581 * @param array $meta_query A meta query
     582 * @param string $type Type of meta
     583 * @param string $primary_table
     584 * @param string $primary_id_column
     585 * @param object $context (optional) The main query object
     586 * @return array( 'join' => $join_sql, 'where' => $where_sql )
     587 */
     588function bp_get_meta_sql( $meta_query, $type, $primary_table, $primary_id_column, $context = null ) {
     589        $meta_query_obj = new BP_Meta_Query( $meta_query );
     590        return $meta_query_obj->get_sql( $type, $primary_table, $primary_id_column, $context );
     591}
     592
     593/**
     594 * Container class for a multiple metadata query, built on the op of WP_Meta_query and works exactly as WP_Meta_query
     595 *
     596 * @since 1.6.2
     597 */
     598class BP_Meta_Query extends WP_Meta_Query {
     599        /**
     600        * List of metadata queries. A single query is an associative array:
     601        * - 'key' string The meta key
     602        * - 'value' string|array The meta value
     603        * - 'compare' (optional) string How to compare the key to the value.
     604        *              Possible values: '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN'.
     605        *              Default: '='
     606        * - 'type' string (optional) The type of the value.
     607        *              Possible values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED'.
     608        *              Default: 'CHAR'
     609        *
     610        * @since 1.6.2
     611        * @access public
     612        * @var array
     613        */
     614       
     615
     616       
     617        function __construct( $meta_query = false ) {
     618                parent::__construct($meta_query);
     619        }
     620
     621       
     622
     623        /**
     624         * Generates SQL clauses to be appended to a main query.
     625         *
     626         * @since 1.6.2
     627         * @access public
     628         *
     629         * @param string $type Type of meta
     630         * @param string $primary_table
     631         * @param string $primary_id_column
     632         * @param object $context (optional) The main query object
     633         * @return array( 'join' => $join_sql, 'where' => $where_sql )
     634         */
     635        function get_sql( $type, $primary_table, $primary_id_column, $context = null ) {
     636                global $wpdb;
     637
     638                if ( ! $meta_table = _bp_get_meta_table( $type ) )
     639                        return false;
     640
     641                $meta_id_column = esc_sql( $type . '_id' );
     642
     643                $join = array();
     644                $where = array();
     645
     646                foreach ( $this->queries as $k => $q ) {
     647                        $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : '';
     648                        $meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR';
     649
     650                        if ( 'NUMERIC' == $meta_type )
     651                                $meta_type = 'SIGNED';
     652                        elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) )
     653                                $meta_type = 'CHAR';
     654
     655                        $i = count( $join );
     656                        $alias = $i ? 'mt' . $i : $meta_table;
     657
     658                        // Set JOIN
     659                        $join[$i]  = "INNER JOIN $meta_table";
     660                        $join[$i] .= $i ? " AS $alias" : '';
     661                        $join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)";
     662
     663                        $where[$k] = '';
     664                        if ( !empty( $meta_key ) )
     665                                $where[$k] = $wpdb->prepare( "$alias.meta_key = %s", $meta_key );
     666
     667                        if ( !isset( $q['value'] ) ) {
     668                                if ( empty( $where[$k] ) )
     669                                        unset( $join[$i] );
     670                                continue;
     671                        }
     672
     673                        $meta_value = $q['value'];
     674
     675                        $meta_compare = is_array( $meta_value ) ? 'IN' : '=';
     676                        if ( isset( $q['compare'] ) )
     677                                $meta_compare = strtoupper( $q['compare'] );
     678
     679                        if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) )
     680                                $meta_compare = '=';
     681
     682                        if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) {
     683                                if ( ! is_array( $meta_value ) )
     684                                        $meta_value = preg_split( '/[,\s]+/', $meta_value );
     685
     686                                if ( empty( $meta_value ) ) {
     687                                        unset( $join[$i] );
     688                                        continue;
     689                                }
     690                        } else {
     691                                $meta_value = trim( $meta_value );
     692                        }
     693
     694                        if ( 'IN' == substr( $meta_compare, -2) ) {
     695                                $meta_compare_string = '(' . substr( str_repeat( ',%s', count( $meta_value ) ), 1 ) . ')';
     696                        } elseif ( 'BETWEEN' == substr( $meta_compare, -7) ) {
     697                                $meta_value = array_slice( $meta_value, 0, 2 );
     698                                $meta_compare_string = '%s AND %s';
     699                        } elseif ( 'LIKE' == substr( $meta_compare, -4 ) ) {
     700                                $meta_value = '%' . like_escape( $meta_value ) . '%';
     701                                $meta_compare_string = '%s';
     702                        } else {
     703                                $meta_compare_string = '%s';
     704                        }
     705
     706                        if ( ! empty( $where[$k] ) )
     707                                $where[$k] .= ' AND ';
     708
     709                        $where[$k] = ' (' . $where[$k] . $wpdb->prepare( "CAST($alias.meta_value AS {$meta_type}) {$meta_compare} {$meta_compare_string})", $meta_value );
     710                }
     711
     712                $where = array_filter( $where );
     713
     714                if ( empty( $where ) )
     715                        $where = '';
     716                else
     717                        $where = ' AND (' . implode( "\n{$this->relation} ", $where ) . ' )';
     718
     719                $join = implode( "\n", $join );
     720                if ( ! empty( $join ) )
     721                        $join = ' ' . $join;
     722
     723                return apply_filters_ref_array( 'get_meta_sql', array( compact( 'join', 'where' ), $this->queries, $type, $primary_table, $primary_id_column, $context ) );
     724        }
     725}
     726
     727/**
     728 * Retrieve the name of the metadata table for the specified object type.
     729 * Plugin Develpres can use the filter bp_meta_tables to add their own table
     730 *
     731 * @since 1.6.0
     732 * @uses $wpdb WordPress database object for queries.
     733 *
     734 * @param string $type Type of object to get metadata table for (e.g., comment, post, or user)
     735 * @return mixed Metadata table name, or false if no metadata table exists
     736 */
     737function _bp_get_meta_table($type) {
     738        global $bp;
     739
     740        $table_map=array();
     741        if(bp_is_action_variable('blogs'))
     742            $table_map['activity']=$bp->activity->table_name_meta;
     743        if(bp_is_active('groups'))
     744            $table_map['group']=$bp->groups->table_name_groupmeta;
     745       
     746        if(bp_is_active('blogs'))
     747            $table_map['blog']=$bp->blogs->table_name_blogmeta;
     748                   
     749        $table_map=apply_filters('bp_meta_tables',$table_map);//allow plugins to utilize it
     750        $table_name = $table_map[$type];
     751       
     752        return $table_name;
     753
     754}
     755
     756
     757
     758
     759
  • bp-loader.php

     
    412412                if ( empty( $this->maintenance_mode ) ) {
    413413
    414414                        // Require all of the BuddyPress core libraries
     415                        require( $this->plugin_dir . 'bp-core/bp-core-meta.php'    );
    415416                        require( $this->plugin_dir . 'bp-core/bp-core-actions.php'    );
    416417                        require( $this->plugin_dir . 'bp-core/bp-core-caps.php'       );
    417418                        require( $this->plugin_dir . 'bp-core/bp-core-cache.php'      );
  • bp-activity/bp-activity-functions.php

     
    444444 * @param string $meta_key
    445445 * @param string $meta_value
    446446 *
    447  * @global object $wpdb
    448  * @global object $bp BuddyPress global settings
    449  * @uses wp_cache_delete()
    450  * @uses is_wp_error()
     447 * @uses bp_delete_metadata()
    451448 *
    452449 * @return bool True on success, false on failure
    453450 */
    454451function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '' ) {
    455         global $wpdb, $bp;
     452       
    456453
    457454        // Return false if any of the above values are not set
    458455        if ( !is_numeric( $activity_id ) )
    459456                return false;
    460457
    461         // Sanitize key
    462         $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
    463 
    464         if ( is_array( $meta_value ) || is_object( $meta_value ) )
    465                 $meta_value = serialize( $meta_value );
    466 
    467         // Trim off whitespace
    468         $meta_value = trim( $meta_value );
    469 
    470         // Delete all for activity_id
    471         if ( empty( $meta_key ) )
    472                 $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
    473 
    474         // Delete only when all match
    475         else if ( $meta_value )
    476                 $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s", $activity_id, $meta_key, $meta_value ) );
    477 
    478         // Delete only when activity_id and meta_key match
    479         else
    480                 $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
    481 
    482         // Delete cache entry
    483         wp_cache_delete( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' );
    484 
    485         // Success
    486         if ( !is_wp_error( $retval ) )
    487                 return true;
    488 
    489         // Fail
    490         else
    491                 return false;
     458        return bp_delete_metadata('activity', $activity_id, $meta_key, $meta_value);
    492459}
    493460
    494461/**
     
    499466 * @param int $activity_id
    500467 * @param string $meta_key
    501468 *
    502  * @global object $wpdb
    503  * @global object $bp BuddyPress global settings
    504  * @uses wp_cache_get()
    505  * @uses wp_cache_set()
     469 * @uses bp_get_metadata
    506470 * @uses apply_filters() To call the 'bp_activity_get_meta' hook
    507471 *
    508472 * @return bool
    509473 */
    510474function bp_activity_get_meta( $activity_id = 0, $meta_key = '' ) {
    511         global $wpdb, $bp;
    512 
     475       
    513476        // Make sure activity_id is valid
    514477        if ( empty( $activity_id ) || !is_numeric( $activity_id ) )
    515478                return false;
    516 
     479       
     480        $metas=array();
    517481        // We have a key to look for
    518482        if ( !empty( $meta_key ) ) {
     483            $metas=bp_get_metadata('activity', $activity_id, $meta_key);
     484        }
    519485
    520                 // Sanitize key
    521                 $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
    522 
    523                 // Check cache
    524                 if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' ) ) {
    525                         // No cache so hit the DB
    526                         $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
    527 
    528                         // Set cache
    529                         wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $metas, 'bp' );
    530                 }
    531 
    532         // No key so get all for activity_id
    533         } else {
    534                 $metas = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
    535                                
    536                 if ( !empty( $metas ) ) {
    537                         $metas = array_map( 'maybe_unserialize', (array) $metas );
    538                        
    539                         foreach( $metas as $mkey => $mvalue ) {
    540                                 wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $mkey, $mvalue, 'bp' );
    541                         }
    542                 }
    543         }
    544        
    545         // No result so return false
    546         if ( empty( $metas ) )
    547                 return false;
    548 
    549         // Maybe, just maybe... unserialize
    550         $metas = array_map( 'maybe_unserialize', (array) $metas );
    551 
    552486        // Return first item in array if only 1, else return all metas found
    553487        $retval = ( 1 == count( $metas ) ? $metas[0] : $metas );
    554488
     
    564498 * @param int $activity_id
    565499 * @param string $meta_key
    566500 * @param string $meta_value
     501 * @uses bp_update_metadat()
    567502 *
    568  * @global object $wpdb
    569  * @global object $bp BuddyPress global settings
    570  * @uses maybe_serialize()
    571  * @uses bp_activity_delete_meta()
    572  * @uses wp_cache_set()
    573  *
    574503 * @return bool True on success, false on failure
    575504 */
    576505function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
    577         global $wpdb, $bp;
    578506
     507
    579508        // Make sure activity_id is valid
    580509        if ( !is_numeric( $activity_id ) )
    581510                return false;
    582511
    583         // Sanitize key
    584         $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
     512            bp_update_metadata('activity', $activity_id, $meta_key, $meta_value);
    585513
    586         // Sanitize value
    587         if ( is_string( $meta_value ) )
    588                 $meta_value = stripslashes( $wpdb->escape( $meta_value ) );
    589 
    590         // Maybe, just maybe... serialize
    591         $meta_value = maybe_serialize( $meta_value );
    592 
    593         // If value is empty, delete the meta key
    594         if ( empty( $meta_value ) )
    595                 return bp_activity_delete_meta( $activity_id, $meta_key );
    596 
    597         // See if meta key exists for activity_id
    598         $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
    599 
    600         // Meta key does not exist so INSERT
    601         if ( empty( $cur ) )
    602                 $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $activity_id, $meta_key, $meta_value ) );
    603 
    604         // Meta key exists, so UPDATE
    605         else if ( $cur->meta_value != $meta_value )
    606                 $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s", $meta_value, $activity_id, $meta_key ) );
    607 
    608         // Weirdness, so return false
    609         else
    610                 return false;
    611 
    612         // Set cache
    613         wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $meta_value, 'bp' );
    614 
    615514        // Victory is ours!
    616515        return true;
    617516}
  • bp-blogs/bp-blogs-functions.php

     
    573573        if ( !is_numeric( $blog_id ) )
    574574                return false;
    575575
    576         $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
     576        bp_delete_metadata('blog', $blog_id, $meta_key,$meta_value);
     577       
    577578
    578         if ( is_array($meta_value) || is_object($meta_value) )
    579                 $meta_value = serialize($meta_value);
    580 
    581         $meta_value = trim( $meta_value );
    582 
    583         if ( !$meta_key )
    584                 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id ) );
    585         else if ( $meta_value )
    586                 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s AND meta_value = %s", $blog_id, $meta_key, $meta_value ) );
    587         else
    588                 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
    589 
    590         wp_cache_delete( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' );
    591 
    592579        return true;
    593580}
    594581
    595582function bp_blogs_get_blogmeta( $blog_id, $meta_key = '') {
    596         global $wpdb, $bp;
     583       
    597584
    598585        $blog_id = (int) $blog_id;
    599586
    600587        if ( !$blog_id )
    601588                return false;
     589        $metas=bp_get_metadata('blog', $blog_id, $meta_key, false);
    602590
    603         if ( !empty($meta_key) ) {
    604                 $meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
     591       
    605592
    606                 if ( !$metas = wp_cache_get( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, 'bp' ) ) {
    607                         $metas = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
    608                         wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $metas, 'bp' );
    609                 }
    610         } else {
    611                 $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d", $blog_id) );
    612         }
    613 
    614         if ( empty($metas) ) {
    615                 if ( empty($meta_key) )
    616                         return array();
    617                 else
    618                         return '';
    619         }
    620 
    621         $metas = array_map('maybe_unserialize', (array) $metas);
    622 
    623593        if ( 1 == count($metas) )
    624594                return $metas[0];
    625595        else
     
    627597}
    628598
    629599function bp_blogs_update_blogmeta( $blog_id, $meta_key, $meta_value ) {
    630         global $wpdb, $bp;
     600       
    631601
    632602        if ( !is_numeric( $blog_id ) )
    633603                return false;
    634604
    635         $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
     605            bp_update_metadata('blog', $blog_id, $meta_key, $meta_value);
    636606
    637         if ( is_string($meta_value) )
    638                 $meta_value = stripslashes($wpdb->escape($meta_value));
    639 
    640         $meta_value = maybe_serialize($meta_value);
    641 
    642         if (empty( $meta_value ) )
    643                 return bp_blogs_delete_blogmeta( $blog_id, $meta_key );
    644 
    645         $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name_blogmeta} WHERE blog_id = %d AND meta_key = %s", $blog_id, $meta_key ) );
    646 
    647         if ( !$cur )
    648                 $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->blogs->table_name_blogmeta} ( blog_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $blog_id, $meta_key, $meta_value ) );
    649         else if ( $cur->meta_value != $meta_value )
    650                 $wpdb->query( $wpdb->prepare( "UPDATE {$bp->blogs->table_name_blogmeta} SET meta_value = %s WHERE blog_id = %d AND meta_key = %s", $meta_value, $blog_id, $meta_key ) );
    651         else
    652                 return false;
    653 
    654         wp_cache_set( 'bp_blogs_blogmeta_' . $blog_id . '_' . $meta_key, $meta_value, 'bp' );
    655 
    656607        return true;
    657608}
    658609
  • bp-groups/bp-groups-functions.php

     
    904904/*** Group Meta ****************************************************/
    905905
    906906function groups_delete_groupmeta( $group_id, $meta_key = false, $meta_value = false ) {
    907         global $wpdb, $bp;
     907       
    908908
    909909        if ( !is_numeric( $group_id ) )
    910910                return false;
    911911
    912         $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
     912            bp_delete_metadata('group', $group_id, $meta_key, $meta_value);
    913913
    914         if ( is_array( $meta_value ) || is_object( $meta_value ) )
    915                 $meta_value = serialize($meta_value);
    916 
    917         $meta_value = trim( $meta_value );
    918 
    919         if ( !$meta_key )
    920                 $wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d", $group_id ) );
    921         else if ( $meta_value )
    922                 $wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s AND meta_value = %s", $group_id, $meta_key, $meta_value ) );
    923         else
    924                 $wpdb->query( $wpdb->prepare( "DELETE FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key ) );
    925 
    926         // Delete the cached object
    927         wp_cache_delete( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, 'bp' );
    928 
    929914        return true;
    930915}
    931916
    932917function groups_get_groupmeta( $group_id, $meta_key = '') {
    933         global $wpdb, $bp;
    934 
     918       
     919       
    935920        $group_id = (int) $group_id;
    936921
    937922        if ( !$group_id )
    938923                return false;
    939 
    940         if ( !empty($meta_key) ) {
    941                 $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
    942 
    943                 $metas = wp_cache_get( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, 'bp' );
    944                 if ( false === $metas ) {
    945                         $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key) );
    946                         wp_cache_set( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, $metas, 'bp' );
    947                 }
    948         } else {
    949                 $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d", $group_id) );
    950         }
    951 
    952         if ( empty( $metas ) ) {
    953                 if ( empty( $meta_key ) )
    954                         return array();
    955                 else
    956                         return '';
    957         }
    958 
    959         $metas = array_map( 'maybe_unserialize', (array) $metas );
    960 
    961         if ( 1 == count( $metas ) )
     924       
     925        $metas=bp_get_metadata('group', $group_id, $meta_key);
     926       
     927        if ( 1 == count( $metas ) )
    962928                return $metas[0];
    963929        else
    964930                return $metas;
    965931}
    966932
    967933function groups_update_groupmeta( $group_id, $meta_key, $meta_value ) {
    968         global $wpdb, $bp;
     934       
    969935
    970936        if ( !is_numeric( $group_id ) )
    971937                return false;
    972938
    973         $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
     939            bp_update_metadata('group', $group_id, $meta_key, $meta_value);
    974940
    975         if ( is_string( $meta_value ) )
    976                 $meta_value = stripslashes( $wpdb->escape( $meta_value ) );
    977 
    978         $meta_value = maybe_serialize( $meta_value );
    979 
    980         $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM " . $bp->groups->table_name_groupmeta . " WHERE group_id = %d AND meta_key = %s", $group_id, $meta_key ) );
    981 
    982         if ( !$cur )
    983                 $wpdb->query( $wpdb->prepare( "INSERT INTO " . $bp->groups->table_name_groupmeta . " ( group_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $group_id, $meta_key, $meta_value ) );
    984         else if ( $cur->meta_value != $meta_value )
    985                 $wpdb->query( $wpdb->prepare( "UPDATE " . $bp->groups->table_name_groupmeta . " SET meta_value = %s WHERE group_id = %d AND meta_key = %s", $meta_value, $group_id, $meta_key ) );
    986         else
    987                 return false;
    988 
    989         // Update the cached object and recache
    990         wp_cache_set( 'bp_groups_groupmeta_' . $group_id . '_' . $meta_key, $meta_value, 'bp' );
    991 
    992941        return true;
    993942}
    994943