WordPress.org

Make WordPress Core

Ticket #34848: meta-bulk.php

File meta-bulk.php, 5.8 KB (added by boonebgorges, 4 years ago)
Line 
1<?php
2global $wpdb;
3$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE post_id = 123" );
4
5echo "Beginning memory usage: " . memory_get_usage() / 1000000 . "MB\n";
6
7$count = 5000;
8
9$metadata = array();
10for ( $i = 0; $i <= $count; $i++ ) {
11        $metadata[ 'foo' . $i ] = rand_long_str( $i );
12}
13
14$time = microtime( true );
15$mem = memory_get_usage();
16
17//add_metadatas( 'post', 123, $metadata );
18
19$wpdb->query( 'START TRANSACTION;' );
20for ( $i = 0; $i <= $count; $i++ ) {
21        add_metadata( 'post', 123, 'foo' . $i, $i );
22}
23$wpdb->query( 'COMMIT;' );
24
25$ntime = microtime( true );
26$nmem = memory_get_usage();
27
28echo "Time: " . ( $ntime - $time ) . "\n";
29echo "Memory: " . ( ( $nmem - $mem ) / 1000000 ) . "MB\n";
30
31function rand_long_str( $length ) {
32        $chars = 'abcdefghijklmnopqrstuvwxyz';
33        $string = '';
34
35        for ( $i = 0; $i < $length; $i++ ) {
36                $rand = rand( 0, strlen( $chars ) - 1 );
37                $string .= substr( $chars, $rand, 1 );
38        }
39
40        return $string;
41}
42
43/**
44 * Add multiple metadatas for the specified object. Similar to calling add_metadata for each metadata individually,
45 * and is only applicable for unique meta data. If a meta key already exists for an object it will not be stored.
46 *
47 * @since x.x.x
48 *
49 * @global wpdb $wpdb WordPress database abstraction object.
50 *
51 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
52 * @param int    $object_id  ID of the object metadata is for
53 * @param array  $meta_data  Metadata as an key/value pair array
54 *
55 * @return bool  If the metadata was stored successfully.
56 */
57function add_metadatas($meta_type, $object_id, $meta_data) {
58        global $wpdb;
59
60        if ( ! $meta_type || ! is_array( $meta_data ) || ! is_numeric( $object_id ) ) {
61                return false;
62        }
63
64        $object_id = absint( $object_id );
65        if ( ! $object_id ) {
66                return false;
67        }
68
69        $table = _get_meta_table( $meta_type );
70        if ( ! $table ) {
71                return false;
72        }
73
74        $column = sanitize_key($meta_type . '_id');
75
76        /**
77         * Filter whether to add metadatas of a specific type.
78         *
79         * The dynamic portion of the hook, `$meta_type`, refers to the meta
80         * object type (comment, post, or user). Returning a non-null value
81         * will effectively short-circuit the function.
82         *
83         * @since x.x.x
84         *
85         * @param null|bool $check      Whether to allow adding metadata for the given type.
86         * @param int       $object_id  Object ID.
87         * @param string    $meta_key   Meta key.
88         * @param mixed     $meta_value Meta value. Must be serializable if non-scalar.
89         * @param bool      $unique     Whether the specified meta key should be unique
90         *                              for the object. Optional. Default false.
91         */
92        $check = apply_filters( "add_{$meta_type}_metadatas", null, $object_id, $meta_data );
93        if ( null !== $check )
94                return $check;
95
96
97        $sql = false;
98
99        $rows = array();
100        if( ! empty( $meta_data ) ) {
101                $sql = "INSERT INTO {$table} ({$column}, meta_key, meta_value) VALUES ";
102
103                $comma = false;
104                $value_string = '( %d, %s, %s)';
105                foreach( $meta_data as $key => $value ) {
106                        if( true == $comma ) {
107                                $sql .= ', ';
108                        }
109
110                        $sql .= $value_string;
111
112                        $sql = $wpdb->prepare( $sql, $object_id, $key, $value );
113                        $comma = true;
114                }
115        }
116
117        if( $sql ) {
118                $result = $wpdb->query( $sql );
119        } else {
120                return false;
121        }
122
123        if ( ! $result ) {
124                return false;
125        }
126
127        wp_cache_delete($object_id, $meta_type . '_meta');
128
129        return true;
130}
131
132/**
133 * Delete metadata for the specified object.
134 *
135 * @since x.x.x
136 *
137 * @global wpdb $wpdb WordPress database abstraction object.
138 *
139 * @param string $meta_type  Type of object metadata is for (e.g., comment, post, or user)
140 * @param int    $object_id  ID of the object metadata is for
141 * @param string $meta_keys  Metadata keys
142 * @return bool True on successful delete, false on failure.
143 */
144function delete_metadatas($meta_type, $object_id, $meta_keys) {
145        global $wpdb;
146
147        if ( ! $meta_type || ! is_array( $meta_keys ) || ! is_numeric( $object_id ) ) {
148                return false;
149        }
150
151        $object_id = absint( $object_id );
152        if ( ! $object_id ) {
153                return false;
154        }
155
156        $table = _get_meta_table( $meta_type );
157        if ( ! $table ) {
158                return false;
159        }
160
161        $type_column = sanitize_key($meta_type . '_id');
162
163        // expected_slashed ($meta_key)
164        $meta_key = array_map( 'wp_unslash', $meta_keys );
165
166        /**
167         * Filter whether to delete metadata of a specific type.
168         *
169         * The dynamic portion of the hook, `$meta_type`, refers to the meta
170         * object type (comment, post, or user). Returning a non-null value
171         * will effectively short-circuit the function.
172         *
173         * @since x.x.x
174         *
175         * @param null|bool $delete     Whether to allow metadata deletion of the given type.
176         * @param int       $object_id  Object ID.
177         * @param string    $meta_keys  Meta keys.
178         */
179        $check = apply_filters( "delete_{$meta_type}_metadatas", null, $object_id, $meta_keys );
180        if ( null !== $check )
181                return (bool) $check;
182
183        /**
184         * Fires immediately before deleting metadata of a specific type.
185         *
186         * The dynamic portion of the hook, `$meta_type`, refers to the meta
187         * object type (comment, post, or user).
188         *
189         * @since x.x.x
190         *
191         * @param int    $object_id  Object ID.
192         * @param string $meta_keys  Meta keys.
193         */
194        do_action( "delete_{$meta_type}_metas", $object_id, $meta_keys );
195
196        $sql = "DELETE FROM {$table} WHERE {$type_column} = {$object_id} and meta_key IN( ";
197
198        $comma = false;
199        foreach( $meta_keys as $meta_key ) {
200                if( true == $comma ) {
201                        $sql .= ', ';
202                }
203
204                $sql .= " `{$meta_key}`";
205                $comma = true;
206        }
207
208        $sql .= " )";
209
210
211        $count = $wpdb->query( $sql );
212
213        if ( ! $count )
214                return false;
215
216        wp_cache_delete($object_id, $meta_type . '_meta');
217
218        /**
219         * Fires immediately after deleting metadata of a specific type.
220         *
221         * The dynamic portion of the hook name, `$meta_type`, refers to the meta
222         * object type (comment, post, or user).
223         *
224         * @since x.x.x
225         *
226         * @param int    $object_id  Object ID.
227         * @param string $meta_keys  Meta key.
228         */
229        do_action( "deleted_{$meta_type}_metas", $object_id, $meta_keys );
230
231        return true;
232}