WordPress.org

Make WordPress Core

Ticket #17850: 17850.8.diff

File 17850.8.diff, 12.0 KB (added by ryan, 7 years ago)

get_metadata_by_id(), error checking in register_meta(), barely tested

  • wp-includes/post-template.php

     
    737737                echo "<ul class='post-meta'>\n";
    738738                foreach ( (array) $keys as $key ) {
    739739                        $keyt = trim($key);
    740                         if ( '_' == $keyt[0] )
     740                        if ( is_hidden_meta( $keyt ) )
    741741                                continue;
    742742                        $values = array_map('trim', get_post_custom_values($key));
    743743                        $value = implode($values,', ');
  • wp-includes/class-wp-xmlrpc-server.php

     
    234234
    235235                foreach ( (array) has_meta($post_id) as $meta ) {
    236236                        // Don't expose protected fields.
    237                         if ( strpos($meta['meta_key'], '_wp_') === 0 ) {
     237                        if ( ! current_user_can( 'edit_post_meta', $meta['meta_key'], $post_id ) )
    238238                                continue;
    239                         }
    240239
    241240                        $custom_fields[] = array(
    242241                                "id"    => $meta['meta_id'],
     
    262261                foreach ( (array) $fields as $meta ) {
    263262                        if ( isset($meta['id']) ) {
    264263                                $meta['id'] = (int) $meta['id'];
    265 
     264                                $pmeta = get_metadata_by_id( 'post', $meta['id'] );
    266265                                if ( isset($meta['key']) ) {
    267                                         update_meta($meta['id'], $meta['key'], $meta['value']);
     266                                        if ( $meta['key'] != $pmeta->meta_key )
     267                                                continue;
     268                                        if ( current_user_can( 'edit_post_meta', $meta['key'], $post_id ) )
     269                                                update_meta($meta['id'], $meta['key'], $meta['value']);
     270                                } else {
     271                                        if ( current_user_can( 'delete_post_meta', $pmeta->meta_key, $post_id ) )
     272                                                delete_meta($meta['id']);
    268273                                }
    269                                 else {
    270                                         delete_meta($meta['id']);
    271                                 }
     274                        } else {
     275                                if ( current_user_can( 'create_post_meta', $meta['key'], $post_id ) )
     276                                        add_post_meta( $post_id, $meta['key'], $meta['value'] );
    272277                        }
    273                         else {
    274                                 $_POST['metakeyinput'] = $meta['key'];
    275                                 $_POST['metavalue'] = $meta['value'];
    276                                 add_meta($post_id);
    277                         }
    278278                }
    279279        }
    280280
  • wp-includes/capabilities.php

     
    951951                else
    952952                        $caps[] = $post_type->cap->read_private_posts;
    953953                break;
     954        case 'edit_post_meta':
     955        case 'delete_post_meta':
     956        case 'create_post_meta':
     957                $post = get_post( $args[1] );
     958                $post_type_object = get_post_type_object( $post->post_type );
     959                $caps = map_meta_cap( $post_type_object->cap->edit_post, $user_id, $post->ID );
     960
     961                global $_wp_meta;
     962                if ( isset( $_wp_meta[ 'post' ][ $args[ 0 ] ] ) && isset( $_wp_meta[ 'post' ][ $args[ 0 ] ]->auth_callback ) ) {
     963                        $meta_cb = $_wp_meta[ 'post' ][ $args[ 0 ] ]->auth_callback;
     964                        $allowed = call_user_func( $meta_cb, $meta_key, $post->ID, $user_id );
     965                        if ( ! $allowed )
     966                                $caps[] = $cap;
     967                } elseif ( is_protected_meta( $args[ 0 ], 'post' ) ) {
     968                        $caps[] = $cap;
     969                }
     970                break;
    954971        case 'edit_comment':
    955972                $comment = get_comment( $args[0] );
    956973                $post = get_post( $comment->comment_post_ID );
  • wp-includes/meta.php

     
    2626 * @param bool $unique Optional, default is false.  Whether the specified metadata key should be
    2727 *              unique for the object.  If true, and the object already has a value for the specified
    2828 *              metadata key, no change will be made
    29  * @return bool True on successful update, false on failure.
     29 * @return bool The meta ID on successful update, false on failure.
    3030 */
    3131function add_metadata($meta_type, $object_id, $meta_key, $meta_value, $unique = false) {
    3232        if ( !$meta_type || !$meta_key )
     
    4949
    5050        $check = apply_filters( "add_{$meta_type}_metadata", null, $object_id, $meta_key, $meta_value, $unique );
    5151        if ( null !== $check )
    52                 return (bool) $check;
     52                return $check;
    5353
    5454        if ( $unique && $wpdb->get_var( $wpdb->prepare(
    5555                "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d",
     
    6161
    6262        do_action( "add_{$meta_type}_meta", $object_id, $meta_key, $_meta_value );
    6363
    64         $wpdb->insert( $table, array(
     64        $result = $wpdb->insert( $table, array(
    6565                $column => $object_id,
    6666                'meta_key' => $meta_key,
    6767                'meta_value' => $meta_value
    6868        ) );
    6969
     70        if ( ! $result )
     71                return false;
     72
     73        $mid = (int) $wpdb->insert_id;
     74
    7075        wp_cache_delete($object_id, $meta_type . '_meta');
    7176        // users cache stores usermeta that must be cleared.
    7277        if ( 'user' == $meta_type )
    7378                clean_user_cache($object_id);
    7479
    75         do_action( "added_{$meta_type}_meta", $wpdb->insert_id, $object_id, $meta_key, $_meta_value );
     80        do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
    7681
    77         return true;
     82        return $mid;
    7883}
    7984
    8085/**
     
    146151        do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
    147152
    148153        $wpdb->update( $table, $data, $where );
     154
    149155        wp_cache_delete($object_id, $meta_type . '_meta');
    150156        // users cache stores usermeta that must be cleared.
    151157        if ( 'user' == $meta_type )
     
    282288}
    283289
    284290/**
     291 * Get meta data by meta ID
     292 *
     293 * @since 3.3.0
     294 *
     295 * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
     296 * @param int $meta_id ID for a specific meta row
     297 * @return object Meta object or false.
     298 */
     299function get_metadata_by_id( $meta_type, $meta_id ) {
     300        if ( ! $meta_type )
     301                return false;
     302
     303        if ( !$meta_id = absint( $meta_id ) )
     304                return false;
     305
     306        if ( ! $table = _get_meta_table($meta_type) )
     307                return false;
     308
     309        $id_column = ( 'user' == $meta_type ) ? 'umeta_id' : 'meta_id';
     310
     311        $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) );
     312
     313        if ( empty( $meta ) )
     314                return false;
     315
     316        if ( isset( $meta->meta_value ) )
     317                $meta->meta_value = maybe_unserialize( $meta->meta_value );
     318
     319        return $meta;
     320}
     321
     322/**
    285323 * Update the metadata cache for the specified objects.
    286324 *
    287325 * @since 2.9.0
     
    588626 * @return bool True if the key is protected, false otherwise.
    589627 */
    590628function is_protected_meta( $meta_key, $meta_type = null ) {
    591         $protected = (  '_' == $meta_key[0] );
     629        $protected = ( '_' == $meta_key[0] );
    592630
    593631        return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
    594632}
    595633
    596634/**
     635 * Determine whether a meta key is hidden
     636 *
     637 * @since 3.2.0
     638 *
     639 * @param string $meta_key Meta key
     640 * @return bool True if the key is hidden, false otherwise.
     641 */
     642function is_hidden_meta( $meta_key, $meta_type = null ) {
     643        $hidden = ( '_' == $meta_key[0] );
     644
     645        return apply_filters( 'is_hidden_meta', $hidden, $meta_key, $meta_type );
     646}
     647
     648/**
    597649 * Sanitize meta value
    598650 *
    599651 * @since 3.1.3
     
    603655 * @param string $meta_type Type of meta
    604656 * @return mixed Sanitized $meta_value
    605657 */
    606 function sanitize_meta( $meta_key, $meta_value, $meta_type = null ) {
    607         return apply_filters( 'sanitize_meta', $meta_value, $meta_key, $meta_type );
     658function sanitize_meta( $meta_key, $meta_value, $meta_type ) {
     659        return apply_filters( "sanitize_{$meta_type}_meta_{$meta_key}", $meta_value, $meta_key, $meta_type );
    608660}
    609661
     662/**
     663 * Register meta key
     664 *
     665 * @since 3.3.0
     666 *
     667 * @param string $meta_key Meta key
     668 * @param string $meta_type Type of meta
     669 * @param array $args Arguments
     670 */
     671function register_meta( $meta_key, $meta_type, $args = array() ) {
     672        global $_wp_meta;
     673
     674        $args = (object) $args;
     675
     676        if ( isset( $args->sanitize_callback ) ) {
     677                if ( ! is_callable( $args->sanitize_callback ) ) {
     678                        unset( $args->sanitize_callback );
     679                } else {
     680                        add_filter( "sanitize_{$meta_type}_meta_{$meta_key}", $args->sanitize_callback );
     681                }
     682        }
     683
     684        if ( isset( $args->auth_callback ) ) {
     685                if ( ! is_callable( $args->auth_callback ) )
     686                        unset( $args->auth_callback );
     687        }
     688
     689        $_wp_meta[ $meta_type ][ $meta_key ] = (object) $args;
     690}
     691
    610692?>
  • wp-admin/admin-ajax.php

     
    393393        break;
    394394case 'delete-meta' :
    395395        check_ajax_referer( "delete-meta_$id" );
    396         if ( !$meta = get_post_meta_by_id( $id ) )
     396        if ( !$meta = get_metadata_by_id( 'post', $id ) )
    397397                die('1');
    398398
    399         if ( !current_user_can( 'edit_post', $meta->post_id ) || is_protected_meta( $meta->meta_key ) )
     399        if ( !current_user_can( 'delete_post_meta', $meta->meta_key, $meta->post_id ) || is_hidden_meta( $meta->meta_key ) )
    400400                die('-1');
    401401        if ( delete_meta( $meta->meta_id ) )
    402402                die('1');
     
    849849                        die(__('Please provide a custom field value.'));
    850850                }
    851851
    852                 $meta = get_post_meta_by_id( $mid );
     852                $meta = get_metadata_by_id( 'post', $mid );
    853853                $pid = (int) $meta->post_id;
    854854                $meta = get_object_vars( $meta );
    855855                $x = new WP_Ajax_Response( array(
     
    869869                        die(__('Please provide a custom field value.'));
    870870                if ( !$meta = get_post_meta_by_id( $mid ) )
    871871                        die('0'); // if meta doesn't exist
    872                 if ( !current_user_can( 'edit_post', $meta->post_id ) )
     872                if ( is_hidden_meta( $meta->meta_key ) || !current_user_can( 'edit_post_meta', $meta->meta_key, $meta->post_id ) )
    873873                        die('-1');
    874                 if ( is_protected_meta( $meta->meta_key ) )
    875                         die('-1');
    876874                if ( $meta->meta_value != stripslashes($value) || $meta->meta_key != stripslashes($key) ) {
    877875                        if ( !$u = update_meta( $mid, $key, $value ) )
    878876                                die('0'); // We know meta exists; we also know it's unchanged (or DB error, in which case there are bigger problems).
  • wp-admin/includes/post.php

     
    210210                                continue;
    211211                        if ( $meta->post_id != $post_ID )
    212212                                continue;
    213                         if ( is_protected_meta( $value['key'] ) )
     213                        if ( is_hidden_meta( $value['key'] ) || ! current_user_can( 'edit_post_meta', $value['key'], $post_ID ) )
    214214                                continue;
    215215                        update_meta( $key, $value['key'], $value['value'] );
    216216                }
     
    222222                                continue;
    223223                        if ( $meta->post_id != $post_ID )
    224224                                continue;
    225                         if ( is_protected_meta( $meta->meta_key ) )
     225                        if ( is_hidden_meta( $meta->meta_key ) || ! current_user_can( 'delete_post_meta', $meta->meta_key, $post_ID ) )
    226226                                continue;
    227227                        delete_meta( $key );
    228228                }
     
    671671        if ( is_string($metavalue) )
    672672                $metavalue = trim( $metavalue );
    673673
    674         if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
     674        if ( ('0' === $metavalue || ! empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
    675675                // We have a key/value pair. If both the select and the
    676676                // input for the key have data, the input takes precedence:
    677677
     
    681681                if ( $metakeyinput)
    682682                        $metakey = $metakeyinput; // default
    683683
    684                 if ( is_protected_meta( $metakey ) )
     684                if ( is_hidden_meta( $metakey ) || ! current_user_can( 'create_post_meta', $metakey, $post_ID ) )
    685685                        return false;
    686686
    687                 wp_cache_delete($post_ID, 'post_meta');
    688                 $wpdb->insert( $wpdb->postmeta, array( 'post_id' => $post_ID, 'meta_key' => $metakey, 'meta_value' => $metavalue ) );
    689                 $meta_id = $wpdb->insert_id;
    690                 do_action( 'added_postmeta', $meta_id, $post_ID, $metakey, $metavalue );
    691 
    692                 return $meta_id;
     687                return add_post_meta($post_ID, $metakey, $metavalue);
    693688        }
     689
    694690        return false;
    695691} // add_meta
    696692
     
    789785
    790786        $meta_key = stripslashes($meta_key);
    791787
    792         if ( is_protected_meta( $meta_key ) )
     788        if ( is_protected_meta( $meta_key, 'post' ) )
    793789                return false;
    794790
    795791        if ( '' === trim( $meta_value ) )
  • wp-admin/includes/template.php

     
    466466function _list_meta_row( $entry, &$count ) {
    467467        static $update_nonce = false;
    468468
    469         if ( is_protected_meta( $entry['meta_key'] ) )
     469        if ( is_hidden_meta( $entry['meta_key'] ) || is_protected_meta( $entry['meta_key'], 'post' ) )
    470470                return;
    471471
    472472        if ( !$update_nonce )