| 135 | /** |
| 136 | * Add multiple metadatas for the specified object. Similar to calling add_metadata for each metadata individually, |
| 137 | * and is only applicable for unique meta data. If a meta key already exists for an object it will not be stored. |
| 138 | * |
| 139 | * @since x.x.x |
| 140 | * |
| 141 | * @global wpdb $wpdb WordPress database abstraction object. |
| 142 | * |
| 143 | * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
| 144 | * @param int $object_id ID of the object metadata is for |
| 145 | * @param array $meta_data Metadata as a key/value pair array. Values must be serializable if non-scalar. |
| 146 | * @return int|false The meta ID on success, false on failure. |
| 147 | */ |
| 148 | function add_metadatas( $meta_type, $object_id, $meta_data ) { |
| 149 | global $wpdb; |
| 150 | |
| 151 | if ( ! $meta_type || ! is_numeric( $object_id ) || ! is_array( $meta_data ) ) { |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | $object_id = absint( $object_id ); |
| 156 | if ( ! $object_id ) { |
| 157 | return false; |
| 158 | } |
| 159 | |
| 160 | $table = _get_meta_table( $meta_type ); |
| 161 | if ( ! $table ) { |
| 162 | return false; |
| 163 | } |
| 164 | |
| 165 | $column = sanitize_key( $meta_type . '_id' ); |
| 166 | |
| 167 | /** |
| 168 | * Filters whether to add metadata of a specific type. |
| 169 | * |
| 170 | * The dynamic portion of the hook, `$meta_type`, refers to the meta |
| 171 | * object type (comment, post, or user). Returning a non-null value |
| 172 | * will effectively short-circuit the function. |
| 173 | * |
| 174 | * @since 3.1.0 |
| 175 | * |
| 176 | * @param null|bool $check Whether to allow adding metadata for the given type. |
| 177 | * @param int $object_id Object ID. |
| 178 | * @param array $meta_data Meta data, an array of meta keys and meta datas, meta values must be serializable |
| 179 | * if non-scalar. |
| 180 | */ |
| 181 | $check = apply_filters( "add_{$meta_type}_metadatas", null, $object_id, $meta_data ); |
| 182 | if ( null !== $check ) { |
| 183 | return $check; |
| 184 | } |
| 185 | |
| 186 | $_meta_data = array(); |
| 187 | foreach( $meta_data as $key => $value ) { |
| 188 | if ( 0 == absint( $wpdb->get_var( |
| 189 | $wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE meta_key = %s AND $column = %d", $key, $object_id ) |
| 190 | ) ) ) { |
| 191 | $key = wp_unslash( $key ); |
| 192 | $value = wp_unslash( sanitize_meta( $key, $value, $meta_type ) ); |
| 193 | |
| 194 | $_meta_data[ $key ] = maybe_serialize( $value ); |
| 195 | |
| 196 | /** |
| 197 | * Fires immediately before meta of a specific type is added. |
| 198 | * |
| 199 | * The dynamic portion of the hook, `$meta_type`, refers to the meta |
| 200 | * object type (comment, post, or user). |
| 201 | * |
| 202 | * @since 3.1.0 |
| 203 | * |
| 204 | * @param int $object_id Object ID. |
| 205 | * @param string $meta_key Meta key. |
| 206 | * @param mixed $meta_value Meta value. |
| 207 | */ |
| 208 | do_action( "add_{$meta_type}_meta", $object_id, $key, $value ); |
| 209 | |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | $rows = array(); |
| 214 | if( ! empty( $_meta_data ) ) { |
| 215 | $sql = "INSERT INTO {$table} ({$column}, meta_key, meta_value) VALUES "; |
| 216 | |
| 217 | $comma = false; |
| 218 | foreach( $_meta_data as $key => $value ) { |
| 219 | if( true == $comma ) { |
| 220 | $sql .= ','; |
| 221 | } |
| 222 | |
| 223 | $sql = "({$object_id}, '{$key}', '{$value}')"; |
| 224 | $comma = true; |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | $result = $wpdb->query( $sql ); |
| 229 | |
| 230 | if ( ! $result ) { |
| 231 | return false; |
| 232 | } |
| 233 | |
| 234 | wp_cache_delete($object_id, $meta_type . '_meta'); |
| 235 | |
| 236 | return true; |
| 237 | } |
| 238 | |
| 569 | /** |
| 570 | * Delete metadatas for the specified object. |
| 571 | * |
| 572 | * @since x.x.x |
| 573 | * |
| 574 | * @global wpdb $wpdb WordPress database abstraction object. |
| 575 | * |
| 576 | * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user) |
| 577 | * @param int $object_id ID of the object metadata is for |
| 578 | * @param array $meta_keys Metadata keys to be deleted. |
| 579 | * @return bool True on successful delete, false on failure. |
| 580 | */ |
| 581 | function delete_metadatas( $meta_type, $object_id, $meta_keys ) { |
| 582 | global $wpdb; |
| 583 | |
| 584 | if ( ! $meta_type || ! is_numeric( $object_id ) && ! is_array( $meta_keys ) ) { |
| 585 | return false; |
| 586 | } |
| 587 | |
| 588 | $object_id = absint( $object_id ); |
| 589 | if ( ! $object_id ) { |
| 590 | return false; |
| 591 | } |
| 592 | |
| 593 | $table = _get_meta_table( $meta_type ); |
| 594 | if ( ! $table ) { |
| 595 | return false; |
| 596 | } |
| 597 | |
| 598 | $type_column = sanitize_key( $meta_type . '_id' ); |
| 599 | $id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id'; |
| 600 | // expected_slashed ($meta_key) |
| 601 | $meta_key = array_map( 'wp_unslash', $meta_keys ); |
| 602 | |
| 603 | /** |
| 604 | * Filters whether to delete metadata of a specific type. |
| 605 | * |
| 606 | * The dynamic portion of the hook, `$meta_type`, refers to the meta |
| 607 | * object type (comment, post, or user). Returning a non-null value |
| 608 | * will effectively short-circuit the function. |
| 609 | * |
| 610 | * @since x.x.x |
| 611 | * |
| 612 | * @param null|bool $delete Whether to allow metadata deletion of the given type. |
| 613 | * @param int $object_id Object ID. |
| 614 | * @param array $meta_keys Meta keys. |
| 615 | */ |
| 616 | $check = apply_filters( "delete_{$meta_type}_metadatas", null, $object_id, $meta_keys ); |
| 617 | if ( null !== $check ) { |
| 618 | return (bool) $check; |
| 619 | } |
| 620 | |
| 621 | /** |
| 622 | * Fires immediately before deleting metadata of a specific type. |
| 623 | * |
| 624 | * The dynamic portion of the hook, `$meta_type`, refers to the meta |
| 625 | * object type (comment, post, or user). |
| 626 | * |
| 627 | * @since x.x.x |
| 628 | * |
| 629 | * @param int $object_id Object ID. |
| 630 | * @param string $meta_keys Meta keys. |
| 631 | */ |
| 632 | do_action( "delete_{$meta_type}_metas", $object_id, $meta_keys ); |
| 633 | $sql = "DELETE FROM {$table} WHERE {$type_column} = {$object_id} and meta_key IN( "; |
| 634 | $comma = false; |
| 635 | foreach( $meta_keys as $meta_key ) { |
| 636 | if( true == $comma ) { |
| 637 | $sql .= ', '; |
| 638 | } |
| 639 | $sql .= " `{$meta_key}`"; |
| 640 | $comma = true; |
| 641 | } |
| 642 | $sql .= " )"; |
| 643 | $count = $wpdb->query( $sql ); |
| 644 | |
| 645 | if ( ! $count ) { |
| 646 | return false; |
| 647 | } |
| 648 | wp_cache_delete($object_id, $meta_type . '_meta'); |
| 649 | |
| 650 | /** |
| 651 | * Fires immediately after deleting metadata of a specific type. |
| 652 | * |
| 653 | * The dynamic portion of the hook name, `$meta_type`, refers to the meta |
| 654 | * object type (comment, post, or user). |
| 655 | * |
| 656 | * @since x.x.x |
| 657 | * |
| 658 | * @param int $object_id Object ID. |
| 659 | * @param string $meta_keys Meta key. |
| 660 | */ |
| 661 | do_action( "deleted_{$meta_type}_metas", $object_id, $meta_keys ); |
| 662 | |
| 663 | return true; |
| 664 | } |
| 665 | |