WordPress.org

Make WordPress Core

Ticket #17850: 17850.12.diff

File 17850.12.diff, 13.5 KB (added by ryan, 3 years ago)
  • 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', $post_id , $meta['meta_key'] ) ) 
    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_mid( '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', $post_id, $meta['key'] ) ) 
     269                                                update_meta($meta['id'], $meta['key'], $meta['value']); 
     270                                } elseif ( current_user_can( 'delete_post_meta', $post_id, $pmeta->meta_key ) ) { 
     271                                                delete_meta($meta['id']); 
    268272                                } 
    269                                 else { 
    270                                         delete_meta($meta['id']); 
    271                                 } 
     273                        } elseif ( current_user_can( 'add_post_meta', $post_id, $meta['key'] ) ) { 
     274                                        add_post_meta( $post_id, $meta['key'], $meta['value'] ); 
    272275                        } 
    273                         else { 
    274                                 $_POST['metakeyinput'] = $meta['key']; 
    275                                 $_POST['metavalue'] = $meta['value']; 
    276                                 add_meta($post_id); 
    277                         } 
    278276                } 
    279277        } 
    280278 
  • 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 'add_post_meta': 
     957                $post = get_post( $args[0] ); 
     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                $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;  
     962                         
     963                if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) { 
     964                        $allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps ); 
     965                        if ( ! $allowed ) 
     966                                $caps[] = $cap; 
     967                } elseif ( $meta_key && is_protected_meta( $meta_key, '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_mid( $meta_type, $meta_id ) { 
     300        global $wpdb; 
     301 
     302        if ( ! $meta_type ) 
     303                return false; 
     304 
     305        if ( !$meta_id = absint( $meta_id ) ) 
     306                return false; 
     307 
     308        if ( ! $table = _get_meta_table($meta_type) ) 
     309                return false; 
     310 
     311        $id_column = ( 'user' == $meta_type ) ? 'umeta_id' : 'meta_id'; 
     312 
     313        $meta = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE $id_column = %d", $meta_id ) ); 
     314 
     315        if ( empty( $meta ) ) 
     316                return false; 
     317 
     318        if ( isset( $meta->meta_value ) ) 
     319                $meta->meta_value = maybe_unserialize( $meta->meta_value ); 
     320 
     321        return $meta; 
     322} 
     323 
     324/** 
    285325 * Update the metadata cache for the specified objects. 
    286326 * 
    287327 * @since 2.9.0 
     
    588628 * @return bool True if the key is protected, false otherwise. 
    589629 */ 
    590630function is_protected_meta( $meta_key, $meta_type = null ) { 
    591         $protected = (  '_' == $meta_key[0] ); 
     631        $protected = ( '_' == $meta_key[0] ); 
    592632 
    593633        return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type ); 
    594634} 
    595635 
    596636/** 
     637 * Determine whether a meta key is hidden 
     638 * 
     639 * @since 3.2.0 
     640 * 
     641 * @param string $meta_key Meta key 
     642 * @return bool True if the key is hidden, false otherwise. 
     643 */ 
     644function is_hidden_meta( $meta_key, $meta_type = null ) { 
     645        $hidden = ( '_' == $meta_key[0] ); 
     646 
     647        return apply_filters( 'is_hidden_meta', $hidden, $meta_key, $meta_type ); 
     648} 
     649 
     650/** 
    597651 * Sanitize meta value 
    598652 * 
    599653 * @since 3.1.3 
     
    603657 * @param string $meta_type Type of meta 
    604658 * @return mixed Sanitized $meta_value 
    605659 */ 
    606 function sanitize_meta( $meta_key, $meta_value, $meta_type = null ) { 
    607         return apply_filters( 'sanitize_meta', $meta_value, $meta_key, $meta_type ); 
     660function sanitize_meta( $meta_key, $meta_value, $meta_type ) { 
     661        return apply_filters( "sanitize_{$meta_type}_meta_{$meta_key}", $meta_value, $meta_key, $meta_type ); 
    608662} 
    609663 
     664/** 
     665 * Register meta key 
     666 *  
     667 * @since 3.3.0 
     668 * 
     669 * @param string $meta_key Meta key 
     670 * @param string $meta_type Type of meta 
     671 * @param string|array $sanitize_callback A function or method to call when sanitizing the value of $meta_key. 
     672 * @param string|array $auth_callback Optional. A function or method to call when performing edit_post_meta, add_post_meta, and delete_post_meta capability checks. 
     673 * @param array $args Arguments 
     674 */ 
     675function register_meta( $meta_key, $meta_type, $sanitize_callback, $auth_callback = null ) { 
     676        global $_wp_meta; 
     677 
     678        $args = (object) $args; 
     679 
     680        if ( is_callable( $sanitize_callback ) ) 
     681                add_filter( "sanitize_{$meta_type}_meta_{$meta_key}", $sanitize_callback, 10, 3 ); 
     682 
     683        if ( empty( $auth_callback ) ) { 
     684                if ( is_protected_meta( $meta_key, $meta_type ) ) 
     685                        $auth_callback = '__return_false'; 
     686                else 
     687                        $auth_callback = '__return_true'; 
     688        } 
     689 
     690        if ( is_callable( $auth_callback ) ) 
     691                add_filter( "auth_{$meta_type}_meta_{$meta_key}", $auth_callback, 10, 6 ); 
     692} 
     693 
    610694?> 
  • 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_mid( '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->post_id, $meta->meta_key ) || 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_mid( '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->post_id, $meta->meta_key ) ) 
    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', $post_ID, $value['key'] ) ) 
    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', $post_ID, $meta->meta_key ) ) 
    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( 'add_post_meta', $post_ID, $metakey ) ) 
    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 
     
    771767        return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, post_id 
    772768                        FROM $wpdb->postmeta WHERE post_id = %d 
    773769                        ORDER BY meta_key,meta_id", $postid), ARRAY_A ); 
    774  
    775770} 
    776771 
    777772/** 
     
    789784 
    790785        $meta_key = stripslashes($meta_key); 
    791786 
    792         if ( is_protected_meta( $meta_key ) ) 
     787        if ( is_protected_meta( $meta_key, 'post' ) ) 
    793788                return false; 
    794789 
    795790        if ( '' === trim( $meta_value ) ) 
  • wp-admin/includes/meta-boxes.php

     
    425425<div id="ajax-response"></div> 
    426426<?php 
    427427$metadata = has_meta($post->ID); 
    428 list_meta($metadata); 
     428foreach ( $metadata as $key => $value ) { 
     429        if ( is_hidden_meta( $metadata[ $key ][ 'meta_key' ] ) || ! current_user_can( 'edit_post_meta', $post->ID, $metadata[ $key ][ 'meta_key' ] ) ) 
     430                unset( $metadata[ $key ] ); 
     431} 
     432list_meta( $metadata ); 
    429433meta_form(); ?> 
    430434</div> 
    431435<p><?php _e('Custom fields can be used to add extra metadata to a post that you can <a href="http://codex.wordpress.org/Using_Custom_Fields" target="_blank">use in your theme</a>.'); ?></p> 
  • 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 ) 
     
    478478                $style = 'alternate'; 
    479479        else 
    480480                $style = ''; 
    481         if ('_' == $entry['meta_key'] { 0 } ) 
    482                 $style .= ' hidden'; 
    483481 
    484482        if ( is_serialized( $entry['meta_value'] ) ) { 
    485483                if ( is_serialized_string( $entry['meta_value'] ) ) {