Ticket #55942: 55942.diff
File 55942.diff, 38.0 KB (added by , 14 months ago) |
---|
-
src/wp-includes/comment.php
diff --git a/src/wp-includes/comment.php b/src/wp-includes/comment.php index b732f83ad4e6..7343e5d81ab7 100644
a b function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) { 466 466 * Retrieves comment meta field for a comment. 467 467 * 468 468 * @since 2.9.0 469 * @since 6.3.0 Introduced the `$value_type` parameter. 469 470 * 470 471 * @link https://developer.wordpress.org/reference/functions/get_comment_meta/ 471 472 * … … function delete_comment_meta( $comment_id, $meta_key, $meta_value = '' ) { 475 476 * @param bool $single Optional. Whether to return a single value. 476 477 * This parameter has no effect if `$key` is not specified. 477 478 * Default false. 479 * @param string $value_type Optional. The expected data type of the value. 478 480 * @return mixed An array of values if `$single` is false. 479 481 * The value of meta data field if `$single` is true. 480 482 * False for an invalid `$comment_id` (non-numeric, zero, or negative value). 481 483 * An empty string if a valid but non-existing comment ID is passed. 482 484 */ 483 function get_comment_meta( $comment_id, $key = '', $single = false ) {484 return get_metadata( 'comment', $comment_id, $key, $single );485 function get_comment_meta( $comment_id, $key = '', $single = false, $value_type = '' ) { 486 return get_metadata( 'comment', $comment_id, $key, $single, $value_type ); 485 487 } 486 488 487 489 /** -
src/wp-includes/functions.php
diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 3267120b6f30..d67a72dea226 100644
a b function is_php_version_compatible( $required ) { 8584 8584 function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) { 8585 8585 return abs( (float) $expected - (float) $actual ) <= $precision; 8586 8586 } 8587 8588 /** 8589 * Get supported data types for meta and option values. 8590 * 8591 * This is a subset of the PHP data types that can be used for 8592 * meta and option values. See the documentation for PHP's 'settype()'. 8593 * 8594 * @since 6.3.0 8595 * 8596 * @return array List of supported value types. 8597 */ 8598 function wp_get_db_value_types() { 8599 return array( 8600 'boolean', 8601 'bool', 8602 'integer', 8603 'int', 8604 'float', 8605 'string', 8606 'array', 8607 'object', 8608 ); 8609 } 8610 8611 /** 8612 * Set the type of a meta or option value that was retrieved from the database. 8613 * 8614 * If `$value_type` is empty, the value is returned unchanged. If `$value_type` is not one 8615 * of the expected types, a user error is triggered and the value is returned unchanged. 8616 * 8617 * @since 6.3.0 8618 * 8619 * @param mixed $value Raw value from the database. 8620 * @param string $value_type The expected value type. 8621 * @return mixed The value with the requested type. 8622 */ 8623 function wp_settype_to_value_from_db( $value, $value_type ) { 8624 if ( ! empty( $value_type ) ) { 8625 $value_types = wp_get_db_value_types(); 8626 8627 if ( in_array( $value_type, $value_types, true ) ) { 8628 settype( $value, $value_type ); 8629 } else { 8630 // Improper use. 8631 /* translators: The function name that returns the supported types. */ 8632 $message = sprintf( __( 'Only types returned by %s are supported.' ), '<code>wp_get_db_value_types()</code>' ); 8633 _doing_it_wrong( 'wp_settype_to_value_from_db', $message ); 8634 } 8635 } 8636 8637 return $value; 8638 } 8639 8640 8641 /** 8642 * Decode a value after it was retrieved from the database. 8643 * 8644 * Unserialize the value if needed, and set it to the expected type. 8645 * Intended for use with option and meta values. 8646 * 8647 * @since 6.3.0 8648 * 8649 * @param mixed $value Raw value from the database. 8650 * @param string $value_type Optional. The expected value type. 8651 * @return mixed The decoded value. 8652 */ 8653 function wp_decode_value_from_db( $value, $value_type = '' ) { 8654 $original_value = $value; 8655 8656 if ( empty( $value_type ) ) { 8657 $value = maybe_unserialize( $value ); 8658 } else { 8659 if ( 'array' === $value_type || 'object' === $value_type ) { 8660 $value = maybe_unserialize( $value ); 8661 } 8662 8663 $value = wp_settype_to_value_from_db( $value, $value_type ); 8664 } 8665 8666 /** 8667 * Filter the decoded value. 8668 * 8669 * @since 6.3.0 8670 * 8671 * @param mixed $value Decoded value. 8672 * @param mixed $original_value Original value from the database. 8673 * @param string $value_type The expected value type. 8674 */ 8675 return apply_filters( 'wp_decode_value_from_db', $value, $original_value, $value_type ); 8676 } -
src/wp-includes/meta.php
diff --git a/src/wp-includes/meta.php b/src/wp-includes/meta.php index 2b5ca02696c2..b1e3b297dd7e 100644
a b function delete_metadata( $meta_type, $object_id, $meta_key, $meta_value = '', $ 552 552 * By default, an empty string is returned if `$single` is true, or an empty array 553 553 * if it's false. 554 554 * 555 * In most cases non-string scalar and null values will be converted and returned 556 * as string equivalents if the `$value_type` paramenter is not set. If it is set 557 * the values will be of the expected type. 558 * 555 559 * @since 2.9.0 560 * @since 6.3.0 Introduced the `$value_type` parameter. 556 561 * 557 562 * @see get_metadata_raw() 558 563 * @see get_metadata_default() 559 564 * 560 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 561 * or any other object type with an associated meta table. 562 * @param int $object_id ID of the object metadata is for. 563 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for 564 * the specified object. Default empty string. 565 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`. 566 * This parameter has no effect if `$meta_key` is not specified. Default false. 565 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 566 * or any other object type with an associated meta table. 567 * @param int $object_id ID of the object metadata is for. 568 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for 569 * the specified object. Default empty string. 570 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`. 571 * This parameter has no effect if `$meta_key` is not specified. Default false. 572 * @param string $value_type Optional. The expected data type of the value. 567 573 * @return mixed An array of values if `$single` is false. 568 574 * The value of the meta field if `$single` is true. 569 575 * False for an invalid `$object_id` (non-numeric, zero, or negative value), 570 576 * or if `$meta_type` is not specified. 571 577 * An empty string if a valid but non-existing object ID is passed. 572 578 */ 573 function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) {574 $value = get_metadata_raw( $meta_type, $object_id, $meta_key, $single );579 function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false, $value_type = '' ) { 580 $value = get_metadata_raw( $meta_type, $object_id, $meta_key, $single, $value_type ); 575 581 if ( ! is_null( $value ) ) { 576 582 return $value; 577 583 } … … function get_metadata( $meta_type, $object_id, $meta_key = '', $single = false ) 583 589 * Retrieves raw metadata value for the specified object. 584 590 * 585 591 * @since 5.5.0 592 * @since 6.3.0 Introduced the `$value_type` parameter. 586 593 * 587 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 588 * or any other object type with an associated meta table. 589 * @param int $object_id ID of the object metadata is for. 590 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for 591 * the specified object. Default empty string. 592 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`. 593 * This parameter has no effect if `$meta_key` is not specified. Default false. 594 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 595 * or any other object type with an associated meta table. 596 * @param int $object_id ID of the object metadata is for. 597 * @param string $meta_key Optional. Metadata key. If not specified, retrieve all metadata for 598 * the specified object. Default empty string. 599 * @param bool $single Optional. If true, return only the first value of the specified `$meta_key`. 600 * This parameter has no effect if `$meta_key` is not specified. Default false. 601 * @param string $value_type Optional. The expected data type of the value. 594 602 * @return mixed An array of values if `$single` is false. 595 603 * The value of the meta field if `$single` is true. 596 604 * False for an invalid `$object_id` (non-numeric, zero, or negative value), 597 605 * or if `$meta_type` is not specified. 598 606 * Null if the value does not exist. 599 607 */ 600 function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false ) {608 function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = false, $value_type = '' ) { 601 609 if ( ! $meta_type || ! is_numeric( $object_id ) ) { 602 610 return false; 603 611 } … … function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = fal 614 622 * (post, comment, term, user, or any other type with an associated meta table). 615 623 * Returning a non-null value will effectively short-circuit the function. 616 624 * 625 * The filter assumes that a numeric array is always returned similarly to the return value 626 * from {@see 'update_meta_cache()'}. Returning `false` is also acceptable to signify 627 * incorrect parameters. 628 * 617 629 * Possible filter names include: 618 630 * 619 631 * - `get_post_metadata` … … function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = fal 623 635 * 624 636 * @since 3.1.0 625 637 * @since 5.5.0 Added the `$meta_type` parameter. 626 * 627 * @param mixed $value The value to return, either a single metadata value or an array 628 * of values depending on the value of `$single`. Default null. 629 * @param int $object_id ID of the object metadata is for. 630 * @param string $meta_key Metadata key. 631 * @param bool $single Whether to return only the first value of the specified `$meta_key`. 632 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 633 * or any other object type with an associated meta table. 638 * @since 6.3.0 Added the `$value_type` parameter. 639 * 640 * @param mixed $value Numeric array of one or more meta values. Default null. 641 * @param int $object_id ID of the object metadata is for. 642 * @param string $meta_key Metadata key. 643 * @param bool $single Whether to return only the first value of the specified `$meta_key`. 644 * If `true` only the first element of the filtered array is returned. 645 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 646 * or any other object type with an associated meta table. 647 * @param string $value_type The expected data type of the value. 634 648 */ 635 $check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $meta_type ); 636 if ( null !== $check ) { 637 if ( $single && is_array( $check ) ) { 638 return $check[0]; 649 $pre_meta = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, $single, $meta_type, $value_type ); 650 if ( null !== $pre_meta ) { 651 // `false` is an expected return value in some cases. See above. 652 if ( false === $pre_meta ) { 653 return $pre_meta; 654 } 655 656 if ( $single ) { 657 // A numeric array is expected especiually if the meta value is also an array. 658 if ( is_array( $pre_meta ) && isset( $pre_meta[0] ) ) { 659 $pre_meta = $pre_meta[0]; 660 } 661 // Ensure the meta value is of the expected type after the filter. 662 return wp_settype_to_value_from_db( $pre_meta, $value_type ); 639 663 } else { 640 return $check; 664 if ( is_array( $pre_meta ) ) { 665 foreach ( $pre_meta as $key => $meta_value ) { 666 $pre_meta[ $key ] = wp_settype_to_value_from_db( $meta_value, $value_type ); 667 } 668 } else { 669 $pre_meta = wp_settype_to_value_from_db( $pre_meta, $value_type ); 670 } 671 672 return $pre_meta; 641 673 } 642 674 } 643 675 … … function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = fal 645 677 646 678 if ( ! $meta_cache ) { 647 679 $meta_cache = update_meta_cache( $meta_type, array( $object_id ) ); 680 648 681 if ( isset( $meta_cache[ $object_id ] ) ) { 649 682 $meta_cache = $meta_cache[ $object_id ]; 650 683 } else { … … function get_metadata_raw( $meta_type, $object_id, $meta_key = '', $single = fal 658 691 659 692 if ( isset( $meta_cache[ $meta_key ] ) ) { 660 693 if ( $single ) { 661 return maybe_unserialize( $meta_cache[ $meta_key ][0]);694 return wp_decode_value_from_db( $meta_cache[ $meta_key ][0], $value_type ); 662 695 } else { 663 return array_map( 'maybe_unserialize', $meta_cache[ $meta_key ] ); 696 $meta_values = $meta_cache[ $meta_key ]; 697 698 foreach ( (array) $meta_values as $key => $meta_value ) { 699 $meta_values[ $key ] = wp_decode_value_from_db( $meta_value, $value_type ); 700 } 701 702 return $meta_values; 664 703 } 665 704 } 666 705 … … function metadata_exists( $meta_type, $object_id, $meta_key ) { 768 807 * Retrieves metadata by meta ID. 769 808 * 770 809 * @since 3.3.0 810 * @since 6.3.0 Introduced the `$value_type` parameter. 771 811 * 772 812 * @global wpdb $wpdb WordPress database abstraction object. 773 813 * 774 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 775 * or any other object type with an associated meta table. 776 * @param int $meta_id ID for a specific meta row. 814 * @param string $meta_type Type of object metadata is for. Accepts 'post', 'comment', 'term', 'user', 815 * or any other object type with an associated meta table. 816 * @param int $meta_id ID for a specific meta row. 817 * @param string $value_type Optional. The expected data type of the value. 777 818 * @return stdClass|false { 778 819 * Metadata object, or boolean `false` if the metadata doesn't exist. 779 820 * … … function metadata_exists( $meta_type, $object_id, $meta_key ) { 787 828 * @type string $user_id Optional. The object ID when the meta type is 'user'. 788 829 * } 789 830 */ 790 function get_metadata_by_mid( $meta_type, $meta_id ) {831 function get_metadata_by_mid( $meta_type, $meta_id, $value_type = '' ) { 791 832 global $wpdb; 792 833 793 834 if ( ! $meta_type || ! is_numeric( $meta_id ) || floor( $meta_id ) != $meta_id ) { … … function get_metadata_by_mid( $meta_type, $meta_id ) { 820 861 * 821 862 * @since 5.0.0 822 863 * 823 * @param stdClass|null $value The value to return. 824 * @param int $meta_id Meta ID. 864 * @param stdClass|null $value The value to return. 865 * @param int $meta_id Meta ID. 866 * @param string $value_type The expected data type of the value. 825 867 */ 826 $check = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id ); 827 if ( null !== $check ) { 828 return $check; 868 $pre_meta = apply_filters( "get_{$meta_type}_metadata_by_mid", null, $meta_id, $value_type ); 869 if ( null !== $pre_meta ) { 870 // Ensure the returned meta value is of the expected type. 871 if ( is_object( $pre_meta ) && isset( $pre_meta->meta_value ) ) { 872 $pre_meta->meta_value = wp_settype_to_value_from_db( $pre_meta->meta_value, $value_type ); 873 } 874 875 return $pre_meta; 829 876 } 830 877 831 878 $id_column = ( 'user' === $meta_type ) ? 'umeta_id' : 'meta_id'; … … function get_metadata_by_mid( $meta_type, $meta_id ) { 837 884 } 838 885 839 886 if ( isset( $meta->meta_value ) ) { 840 $meta->meta_value = maybe_unserialize( $meta->meta_value );887 $meta->meta_value = wp_decode_value_from_db( $meta->meta_value, $value_type ); 841 888 } 842 889 843 890 return $meta; -
src/wp-includes/ms-site.php
diff --git a/src/wp-includes/ms-site.php b/src/wp-includes/ms-site.php index 486fad241424..7f5311f20054 100644
a b function delete_site_meta( $site_id, $meta_key, $meta_value = '' ) { 1061 1061 * Retrieves metadata for a site. 1062 1062 * 1063 1063 * @since 5.1.0 1064 * @since 6.3.0 Introduced the `$value_type` parameter. 1064 1065 * 1065 * @param int $site_id Site ID. 1066 * @param string $key Optional. The meta key to retrieve. By default, 1067 * returns data for all keys. Default empty. 1068 * @param bool $single Optional. Whether to return a single value. 1069 * This parameter has no effect if `$key` is not specified. 1070 * Default false. 1066 * @param int $site_id Site ID. 1067 * @param string $key Optional. The meta key to retrieve. By default, 1068 * returns data for all keys. Default empty. 1069 * @param bool $single Optional. Whether to return a single value. 1070 * This parameter has no effect if `$key` is not specified. 1071 * Default false. 1072 * @param string $value_type Optional. The expected data type of the value. 1071 1073 * @return mixed An array of values if `$single` is false. 1072 1074 * The value of meta data field if `$single` is true. 1073 1075 * False for an invalid `$site_id` (non-numeric, zero, or negative value). 1074 1076 * An empty string if a valid but non-existing site ID is passed. 1075 1077 */ 1076 function get_site_meta( $site_id, $key = '', $single = false ) {1077 return get_metadata( 'blog', $site_id, $key, $single );1078 function get_site_meta( $site_id, $key = '', $single = false, $value_type = '' ) { 1079 return get_metadata( 'blog', $site_id, $key, $single, $value_type ); 1078 1080 } 1079 1081 1080 1082 /** -
src/wp-includes/option.php
diff --git a/src/wp-includes/option.php b/src/wp-includes/option.php index 48e8676ed2ac..8e00a0d93c7d 100644
a b 18 18 * Not initializing an option and using boolean `false` as a return value 19 19 * is a bad practice as it triggers an additional database query. 20 20 * 21 * The type of the returned value can be different from the type that was passed 21 * When the `$value_type` paramenter is not set the type 22 * of the returned value may be different from the type that was passed 22 23 * when saving or updating the option. If the option value was serialized, 23 24 * then it will be unserialized when it is returned. In this case the type will 24 25 * be the same. For example, storing a non-scalar value like an array will 25 26 * return the same array. 26 27 * 27 28 * In most cases non-string scalar and null values will be converted and returned 28 * as string equivalents. 29 * as string equivalents if the `$value_type` paramenter is not set. If it is set 30 * the values will be of the expected type. 29 31 * 30 32 * Exceptions: 31 33 * … … 35 37 * {@see 'default_option_$option'}, or {@see 'option_$option'}, the returned 36 38 * value may not match the expected type. 37 39 * 3. When the option has just been saved in the database, and get_option() 38 * is used right after, non-string scalar and null values are not converted to 39 * string equivalents and the original type is returned. 40 * is used right after without the `$value_type` paramenter, non-string scalar 41 * and null values are not converted to string equivalents and are returned with 42 * their original types. 40 43 * 41 44 * Examples: 42 45 * … … 52 55 * - `'1'` returns `string(1) "1"` 53 56 * - `null` returns `string(0) ""` 54 57 * 58 * When the `$value_type` parameter is used the returned value will be of the expected type. 59 * Retrieving the first option from the above example with 60 * `get_option( 'my_option_name', false, 'boolean' )` will return `boolean false`. 61 * Retrieving the second example will return `boolean true`. Retrieving the third example 62 * with `get_option( 'my_option_name', false, 'integer' )` will return `integer 0`, etc. 55 63 * When adding options with non-scalar values like 56 64 * `add_option( 'my_array', array( false, 'str', null ) )`, the returned value 57 * will be identical to the original as it is serialized before saving65 * will always be identical to the original as it is serialized before saving 58 66 * it in the database: 59 67 * 60 68 * array(3) { … … 64 72 * } 65 73 * 66 74 * @since 1.5.0 75 * @since 6.3.0 Introduced the `$value_type` parameter. 67 76 * 68 77 * @global wpdb $wpdb WordPress database abstraction object. 69 78 * 70 79 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped. 71 80 * @param mixed $default_value Optional. Default value to return if the option does not exist. 81 * @param string $value_type Optional. The expected data type of the value. 72 82 * @return mixed Value of the option. A value of any type may be returned, including 73 83 * scalar (string, boolean, float, integer), null, array, object. 74 84 * Scalar and null values will be returned as strings as long as they originate 75 85 * from a database stored option value. If there is no option in the database, 76 86 * boolean `false` is returned. 77 87 */ 78 function get_option( $option, $default_value = false ) {88 function get_option( $option, $default_value = false, $value_type = '' ) { 79 89 global $wpdb; 80 90 81 91 if ( is_scalar( $option ) ) { … … function get_option( $option, $default_value = false ) { 106 116 $deprecated_keys[ $option ] 107 117 ) 108 118 ); 109 return get_option( $deprecated_keys[ $option ], $default_value );119 return get_option( $deprecated_keys[ $option ], $default_value, $value_type ); 110 120 } 111 121 112 122 /** … … function get_option( $option, $default_value = false ) { 128 138 * @param string $option Option name. 129 139 * @param mixed $default_value The fallback value to return if the option does not exist. 130 140 * Default false. 141 * @param string $value_type The expected data type of the value. 131 142 */ 132 $pre = apply_filters( "pre_option_{$option}", false, $option, $default_value );143 $pre = apply_filters( "pre_option_{$option}", false, $option, $default_value, $value_type ); 133 144 134 145 /** 135 146 * Filters the value of all existing options before it is retrieved. … … function get_option( $option, $default_value = false ) { 146 157 * @param string $option Name of the option. 147 158 * @param mixed $default_value The fallback value to return if the option does not exist. 148 159 * Default false. 160 * @param string $value_type The expected data type of the value. 149 161 */ 150 $pre = apply_filters( 'pre_option', $pre, $option, $default_value );162 $pre = apply_filters( 'pre_option', $pre, $option, $default_value, $value_type ); 151 163 152 164 if ( false !== $pre ) { 153 return $pre; 165 // Ensure the option value is of the expected type after the filters. 166 return wp_settype_to_value_from_db( $pre, $value_type ); 154 167 } 155 168 156 169 if ( defined( 'WP_SETUP_CONFIG' ) ) { … … function get_option( $option, $default_value = false ) { 184 197 * in the database. 185 198 * @param string $option Option name. 186 199 * @param bool $passed_default Was `get_option()` passed a default value? 200 * @param string $value_type The expected data type of the value. 187 201 */ 188 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );202 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default, $value_type ); 189 203 } 190 204 191 205 $alloptions = wp_load_alloptions(); … … function get_option( $option, $default_value = false ) { 211 225 wp_cache_set( 'notoptions', $notoptions, 'options' ); 212 226 213 227 /** This filter is documented in wp-includes/option.php */ 214 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );228 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default, $value_type ); 215 229 } 216 230 } 217 231 } … … function get_option( $option, $default_value = false ) { 224 238 $value = $row->option_value; 225 239 } else { 226 240 /** This filter is documented in wp-includes/option.php */ 227 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default );241 return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default, $value_type ); 228 242 } 229 243 } 230 244 … … function get_option( $option, $default_value = false ) { 237 251 $value = untrailingslashit( $value ); 238 252 } 239 253 254 $value = wp_decode_value_from_db( $value, $value_type ); 255 240 256 /** 241 257 * Filters the value of an existing option. 242 258 * … … function get_option( $option, $default_value = false ) { 246 262 * @since 3.0.0 247 263 * @since 4.4.0 The `$option` parameter was added. 248 264 * 249 * @param mixed $value Value of the option. If stored serialized, it will be 250 * unserialized prior to being returned. 251 * @param string $option Option name. 265 * @param mixed $value Value of the option. If stored serialized, it will be 266 * unserialized prior to being returned. 267 * @param string $option Option name. 268 * @param string $value_type The expected data type of the value. 252 269 */ 253 return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option);270 return apply_filters( "option_{$option}", $value, $option, $value_type ); 254 271 } 255 272 256 273 /** … … function update_site_option( $option, $value ) { 1415 1432 * Retrieves a network's option value based on the option name. 1416 1433 * 1417 1434 * @since 4.4.0 1435 * @since 6.3.0 Introduced the `$value_type` parameter. 1418 1436 * 1419 1437 * @see get_option() 1420 1438 * … … function update_site_option( $option, $value ) { 1423 1441 * @param int $network_id ID of the network. Can be null to default to the current network ID. 1424 1442 * @param string $option Name of the option to retrieve. Expected to not be SQL-escaped. 1425 1443 * @param mixed $default_value Optional. Value to return if the option doesn't exist. Default false. 1444 * @param string $value_type Optional. The expected data type of the value. 1426 1445 * @return mixed Value set for the option. 1427 1446 */ 1428 function get_network_option( $network_id, $option, $default_value = false ) {1447 function get_network_option( $network_id, $option, $default_value = false, $value_type = '' ) { 1429 1448 global $wpdb; 1430 1449 1431 1450 if ( $network_id && ! is_numeric( $network_id ) ) { … … function get_network_option( $network_id, $option, $default_value = false ) { 1461 1480 * @param int $network_id ID of the network. 1462 1481 * @param mixed $default_value The fallback value to return if the option does not exist. 1463 1482 * Default false. 1483 * @param string $value_type The expected data type of the value. 1464 1484 */ 1465 $pre = apply_filters( "pre_site_option_{$option}", false, $option, $network_id, $default_value );1485 $pre = apply_filters( "pre_site_option_{$option}", false, $option, $network_id, $default_value, $value_type ); 1466 1486 1467 1487 if ( false !== $pre ) { 1468 return $pre; 1488 // Ensure the option value is of the expected type after the filter. 1489 return wp_settype_to_value_from_db( $pre, $value_type ); 1469 1490 } 1470 1491 1471 1492 // Prevent non-existent options from triggering multiple queries. … … function get_network_option( $network_id, $option, $default_value = false ) { 1487 1508 * in the database. 1488 1509 * @param string $option Option name. 1489 1510 * @param int $network_id ID of the network. 1511 * @param string $value_type The expected data type of the value. 1490 1512 */ 1491 return apply_filters( "default_site_option_{$option}", $default_value, $option, $network_id );1513 return apply_filters( "default_site_option_{$option}", $default_value, $option, $network_id, $value_type ); 1492 1514 } 1493 1515 1494 1516 if ( ! is_multisite() ) { 1495 1517 /** This filter is documented in wp-includes/option.php */ 1496 1518 $default_value = apply_filters( 'default_site_option_' . $option, $default_value, $option, $network_id ); 1497 $value = get_option( $option, $default_value );1519 $value = get_option( $option, $default_value, $value_type ); 1498 1520 } else { 1499 1521 $cache_key = "$network_id:$option"; 1500 1522 $value = wp_cache_get( $cache_key, 'site-options' ); … … function get_network_option( $network_id, $option, $default_value = false ) { 1505 1527 // Has to be get_row() instead of get_var() because of funkiness with 0, false, null values. 1506 1528 if ( is_object( $row ) ) { 1507 1529 $value = $row->meta_value; 1508 $value = maybe_unserialize( $value );1530 $value = wp_decode_value_from_db( $value, $value_type ); 1509 1531 wp_cache_set( $cache_key, $value, 'site-options' ); 1510 1532 } else { 1511 1533 if ( ! is_array( $notoptions ) ) { … … function get_network_option( $network_id, $option, $default_value = false ) { 1539 1561 * @param mixed $value Value of network option. 1540 1562 * @param string $option Option name. 1541 1563 * @param int $network_id ID of the network. 1564 * @param string $value_type The expected data type of the value. 1542 1565 */ 1543 return apply_filters( "site_option_{$option}", $value, $option, $network_id );1566 return apply_filters( "site_option_{$option}", $value, $option, $network_id, $value_type ); 1544 1567 } 1545 1568 1546 1569 /** -
src/wp-includes/post.php
diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php index 48906cd89bc8..60ea87eecddb 100644
a b function delete_post_meta( $post_id, $meta_key, $meta_value = '' ) { 2500 2500 * Retrieves a post meta field for the given post ID. 2501 2501 * 2502 2502 * @since 1.5.0 2503 * @since 6.3.0 Introduced the `$value_type` parameter. 2503 2504 * 2504 * @param int $post_id Post ID. 2505 * @param string $key Optional. The meta key to retrieve. By default, 2506 * returns data for all keys. Default empty. 2507 * @param bool $single Optional. Whether to return a single value. 2508 * This parameter has no effect if `$key` is not specified. 2509 * Default false. 2505 * @param int $post_id Post ID. 2506 * @param string $key Optional. The meta key to retrieve. By default, 2507 * returns data for all keys. Default empty. 2508 * @param bool $single Optional. Whether to return a single value. 2509 * This parameter has no effect if `$key` is not specified. 2510 * Default false. 2511 * @param string $value_type Optional. The expected data type of the value. 2510 2512 * @return mixed An array of values if `$single` is false. 2511 2513 * The value of the meta field if `$single` is true. 2512 2514 * False for an invalid `$post_id` (non-numeric, zero, or negative value). 2513 2515 * An empty string if a valid but non-existing post ID is passed. 2514 2516 */ 2515 function get_post_meta( $post_id, $key = '', $single = false ) {2516 return get_metadata( 'post', $post_id, $key, $single );2517 function get_post_meta( $post_id, $key = '', $single = false, $value_type = '' ) { 2518 return get_metadata( 'post', $post_id, $key, $single, $value_type ); 2517 2519 } 2518 2520 2519 2521 /** -
src/wp-includes/taxonomy.php
diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 35031e3befec..b080e2c116fc 100644
a b function delete_term_meta( $term_id, $meta_key, $meta_value = '' ) { 1371 1371 * Retrieves metadata for a term. 1372 1372 * 1373 1373 * @since 4.4.0 1374 * @since 6.3.0 Introduced the `$value_type` parameter. 1374 1375 * 1375 * @param int $term_id Term ID. 1376 * @param string $key Optional. The meta key to retrieve. By default, 1377 * returns data for all keys. Default empty. 1378 * @param bool $single Optional. Whether to return a single value. 1379 * This parameter has no effect if `$key` is not specified. 1380 * Default false. 1376 * @param int $term_id Term ID. 1377 * @param string $key Optional. The meta key to retrieve. By default, 1378 * returns data for all keys. Default empty. 1379 * @param bool $single Optional. Whether to return a single value. 1380 * This parameter has no effect if `$key` is not specified. 1381 * Default false. 1382 * @param string $value_type Optional. The expected data type of the value. 1381 1383 * @return mixed An array of values if `$single` is false. 1382 1384 * The value of the meta field if `$single` is true. 1383 1385 * False for an invalid `$term_id` (non-numeric, zero, or negative value). 1384 1386 * An empty string if a valid but non-existing term ID is passed. 1385 1387 */ 1386 function get_term_meta( $term_id, $key = '', $single = false ) {1387 return get_metadata( 'term', $term_id, $key, $single );1388 function get_term_meta( $term_id, $key = '', $single = false, $value_type = '' ) { 1389 return get_metadata( 'term', $term_id, $key, $single, $value_type ); 1388 1390 } 1389 1391 1390 1392 /** -
src/wp-includes/user.php
diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 8e230708e4ee..2cc6d7884bbe 100644
a b function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) { 1152 1152 * Retrieves user meta field for a user. 1153 1153 * 1154 1154 * @since 3.0.0 1155 * @since 6.3.0 Introduced the `$value_type` parameter. 1155 1156 * 1156 1157 * @link https://developer.wordpress.org/reference/functions/get_user_meta/ 1157 1158 * 1158 * @param int $user_id User ID. 1159 * @param string $key Optional. The meta key to retrieve. By default, 1160 * returns data for all keys. 1161 * @param bool $single Optional. Whether to return a single value. 1162 * This parameter has no effect if `$key` is not specified. 1163 * Default false. 1159 * @param int $user_id User ID. 1160 * @param string $key Optional. The meta key to retrieve. By default, 1161 * returns data for all keys. 1162 * @param bool $single Optional. Whether to return a single value. 1163 * This parameter has no effect if `$key` is not specified. 1164 * Default false. 1165 * @param string $value_type Optional. The expected data type of the value. 1164 1166 * @return mixed An array of values if `$single` is false. 1165 1167 * The value of meta data field if `$single` is true. 1166 1168 * False for an invalid `$user_id` (non-numeric, zero, or negative value). 1167 1169 * An empty string if a valid but non-existing user ID is passed. 1168 1170 */ 1169 function get_user_meta( $user_id, $key = '', $single = false ) {1170 return get_metadata( 'user', $user_id, $key, $single );1171 function get_user_meta( $user_id, $key = '', $single = false, $value_type = '' ) { 1172 return get_metadata( 'user', $user_id, $key, $single, $value_type ); 1171 1173 } 1172 1174 1173 1175 /** -
tests/phpunit/tests/functions.php
diff --git a/tests/phpunit/tests/functions.php b/tests/phpunit/tests/functions.php index 32fa2bd1e64a..c87e6b88c76a 100644
a b public function test_wp_recursive_ksort() { 2150 2150 ); 2151 2151 $this->assertSameSetsWithIndex( $theme_json, $expected_theme_json ); 2152 2152 } 2153 2154 2153 } -
new file tests/phpunit/tests/functions/wpDecodeValueFromDb.php
diff --git a/tests/phpunit/tests/functions/wpDecodeValueFromDb.php b/tests/phpunit/tests/functions/wpDecodeValueFromDb.php new file mode 100644 index 000000000000..d16ae3a07d8b
- + 1 <?php 2 3 /** 4 * Tests for wp_decode_value_from_db(). 5 * 6 * @since 6.3.0 7 * 8 * @group functions.php 9 * @group meta 10 * @group option 11 * 12 * @ticket 55942 13 * 14 * @covers ::wp_decode_value_from_db 15 */ 16 class Tests_Functions_WpDecodeValueFromDb extends WP_UnitTestCase { 17 18 /** 19 * Tests that wp_decode_value_from_db() returns the correct value. 20 * 21 * @dataProvider data_wp_decode_value_from_db 22 * 23 * @param mixed $value The value to decode. 24 * @param string $value_type The type of the value. 25 * @param mixed $expected The expected decoded value. 26 */ 27 public function test_wp_decode_value_from_db( $value, $value_type, $expected ) { 28 $this->assertSame( $expected, wp_decode_value_from_db( $value, $value_type ) ); 29 } 30 31 /** 32 * Data provider. 33 * 34 * @return array 35 */ 36 public function data_wp_decode_value_from_db() { 37 $boolean = array( 38 'boolean "1"' => array( '1', 'boolean', true ), 39 'boolean true' => array( true, 'boolean', true ), 40 'boolean "string"' => array( 'string', 'boolean', true ), 41 'boolean "0"' => array( '0', 'boolean', false ), 42 'boolean ""' => array( '', 'boolean', false ), 43 'boolean false' => array( false, 'boolean', false ), 44 ); 45 46 $integer = array( 47 'integer 42' => array( 42, 'integer', 42 ), 48 'integer "42"' => array( '42', 'integer', 42 ), 49 'integer 0' => array( 0, 'integer', 0 ), 50 'integer "0"' => array( '0', 'integer', 0 ), 51 'integer 1' => array( 1, 'integer', 1 ), 52 'integer "1"' => array( '1', 'integer', 1 ), 53 ); 54 55 $float = array( 56 'float 12.50' => array( 12.50, 'float', 12.50 ), 57 'float "12.50"' => array( '12.50', 'float', 12.50 ), 58 'float 0' => array( 0, 'float', 0.0 ), 59 'float 1' => array( 1, 'float', 1.0 ), 60 ); 61 62 $string = array( 63 'string "test"' => array( 'test', 'string', 'test' ), 64 'string 12' => array( 12, 'string', '12' ), 65 'string true' => array( true, 'string', '1' ), 66 'string false' => array( false, 'string', '' ), 67 'string 12.435' => array( 12.435, 'string', '12.435' ), 68 ); 69 70 $array = array( 71 'serialized array' => array( serialize( array( 'test' => 'value' ) ), 'array', array( 'test' => 'value' ) ), 72 'serialized object array' => array( serialize( (object) array( 'test' => 'value' ) ), 'array', array( 'test' => 'value' ) ), 73 'array' => array( array( 'test' => 'value' ), 'array', array( 'test' => 'value' ) ), 74 'object array' => array( (object) array( 'test' => 'value' ), 'array', array( 'test' => 'value' ) ), 75 ); 76 77 return array_merge( $boolean, $integer, $float, $string, $array ); 78 } 79 80 /** 81 * Tests that wp_decode_value_from_db() returns the correct value for objects. 82 */ 83 public function test_object_wp_decode_value_from_db() { 84 $obj = new \stdClass(); 85 $obj->test = 'value'; 86 $this->assertEquals( $obj, wp_decode_value_from_db( serialize( $obj ), 'object' ) ); 87 $this->assertEquals( $obj, wp_decode_value_from_db( serialize( (array) $obj ), 'object' ) ); 88 $this->assertEquals( $obj, wp_decode_value_from_db( $obj, 'object' ) ); 89 $this->assertEquals( $obj, wp_decode_value_from_db( (array) $obj, 'object' ) ); 90 } 91 }