PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.0.1
Jetpack – WP Security, Backup, Speed, & Growth v16.0.1
16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-sync / src / sync-queue / class-queue-storage-options.php
jetpack / jetpack_vendor / automattic / jetpack-sync / src / sync-queue Last commit date
class-queue-storage-options.php 5 months ago class-queue-storage-table.php 5 months ago
class-queue-storage-options.php
294 lines
1 <?php
2 /**
3 * The class responsible for storing Queue events in the `wp_options` table.
4 *
5 * Used by class Queue.
6 *
7 * @see \Automattic\Jetpack\Sync\Queue
8 *
9 * @package automattic/jetpack-sync
10 */
11
12 namespace Automattic\Jetpack\Sync\Queue;
13
14 /**
15 * `wp_options` storage backend for the Queue.
16 */
17 class Queue_Storage_Options {
18 /**
19 * What queue is this instance responsible for.
20 *
21 * @var string
22 */
23 public $queue_id = '';
24
25 /**
26 * Class constructor.
27 *
28 * @param string $queue_id The queue name this instance will be responsible for.
29 *
30 * @throws \Exception If queue name was not provided.
31 */
32 public function __construct( $queue_id ) {
33 if ( empty( $queue_id ) ) {
34 // TODO what should we return here or throw an exception?
35 throw new \Exception( 'Invalid queue_id provided' );
36 }
37
38 // TODO validate the value maybe?
39 $this->queue_id = $queue_id;
40 }
41
42 /**
43 * Insert an item in the queue.
44 *
45 * @param string $item_id The item ID.
46 * @param string $item Serialized item data.
47 *
48 * @return bool If the item was added.
49 */
50 public function insert_item( $item_id, $item ) {
51 global $wpdb;
52
53 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
54 $rows_added = $wpdb->query(
55 $wpdb->prepare(
56 "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES (%s, %s,%s)",
57 $item_id,
58 $item,
59 'no'
60 )
61 );
62
63 return ( 0 !== $rows_added );
64 }
65
66 /**
67 * Fetch items from the queue.
68 *
69 * @param int|null $item_count How many items to fetch from the queue.
70 * Null for no limit.
71 * @param string $order Sort direction for the items. Accepts 'ASC' or 'DESC'.
72 * Any other value will be treated as 'ASC'.
73 *
74 * @return array|object|null Array of result objects on success, or null on failure.
75 */
76 public function fetch_items( $item_count, $order = 'ASC' ) {
77 global $wpdb;
78
79 $order = 'DESC' === $order ? 'DESC' : 'ASC';
80
81 $sql_order = "ORDER BY option_name {$order}";
82
83 $sql = "SELECT option_name AS id, option_value AS value
84 FROM $wpdb->options
85 WHERE option_name LIKE %s
86 {$sql_order}";
87
88 $params = array( "jpsq_{$this->queue_id}-%" );
89
90 if ( $item_count ) {
91 $sql .= ' LIMIT %d';
92 $params[] = $item_count;
93 }
94
95 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
96 $items = $wpdb->get_results(
97 $wpdb->prepare( $sql, $params ), // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
98 OBJECT
99 );
100
101 return $items;
102 }
103
104 /**
105 * Fetches items with specific IDs from the Queue.
106 *
107 * @param array $items_ids Items IDs to fetch from the queue.
108 *
109 * @return \stdClass[]|null
110 */
111 public function fetch_items_by_ids( $items_ids ) {
112 global $wpdb;
113
114 // return early if $items_ids is empty or not an array.
115 if ( empty( $items_ids ) || ! is_array( $items_ids ) ) {
116 return array();
117 }
118
119 $ids_placeholders = implode( ', ', array_fill( 0, count( $items_ids ), '%s' ) );
120
121 $query_with_placeholders = "SELECT option_name AS id, option_value AS value
122 FROM $wpdb->options
123 WHERE option_name IN ( $ids_placeholders )";
124
125 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
126 $items = $wpdb->get_results(
127 $wpdb->prepare(
128 $query_with_placeholders, // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
129 $items_ids
130 ),
131 OBJECT
132 );
133
134 return $items;
135 }
136
137 /**
138 * Clear out the queue.
139 *
140 * @return bool|int|\mysqli_result|resource|null
141 */
142 public function clear_queue() {
143 global $wpdb;
144
145 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
146 return $wpdb->query(
147 $wpdb->prepare(
148 "DELETE FROM $wpdb->options WHERE option_name LIKE %s",
149 "jpsq_{$this->queue_id}-%"
150 )
151 );
152 }
153
154 /**
155 * Check how many items are in the queue.
156 *
157 * @return int
158 */
159 public function get_item_count() {
160 global $wpdb;
161
162 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
163 return (int) $wpdb->get_var(
164 $wpdb->prepare(
165 "SELECT count(*) FROM $wpdb->options WHERE option_name LIKE %s",
166 "jpsq_{$this->queue_id}-%"
167 )
168 );
169 }
170
171 /**
172 * Return the lag amount for the queue.
173 *
174 * @param float|int|null $now A timestamp to use as starting point when calculating the lag.
175 *
176 * @return float|int The lag amount.
177 */
178 public function get_lag( $now = null ) {
179 global $wpdb;
180
181 // TODO replace with peek and a flag to fetch only the name.
182 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
183 $first_item_name = $wpdb->get_var(
184 $wpdb->prepare(
185 "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_name ASC LIMIT 1",
186 "jpsq_{$this->queue_id}-%"
187 )
188 );
189
190 if ( ! $first_item_name ) {
191 return 0;
192 }
193
194 if ( null === $now ) {
195 $now = microtime( true );
196 }
197
198 // Break apart the item name to get the timestamp.
199 $matches = null;
200 if ( preg_match( '/^jpsq_' . $this->queue_id . '-(\d+\.\d+)-/', $first_item_name, $matches ) ) {
201 return $now - (float) $matches[1];
202 } else {
203 return 0;
204 }
205 }
206
207 /**
208 * Add multiple items to the queue at once.
209 *
210 * @param array $items Array of items to add.
211 * @param string $id_prefix Prefix to use for all the items.
212 *
213 * @return bool|int|\mysqli_result|resource|null
214 */
215 public function add_all( $items, $id_prefix ) {
216 global $wpdb;
217
218 $query = "INSERT INTO $wpdb->options (option_name, option_value, autoload) VALUES ";
219
220 $rows = array();
221 $count_items = count( $items );
222 for ( $i = 0; $i < $count_items; ++$i ) {
223 // skip empty items.
224 if ( empty( $items[ $i ] ) ) {
225 continue;
226 }
227 try {
228 $option_name = esc_sql( $id_prefix . '-' . $i );
229 $option_value = esc_sql( serialize( $items[ $i ] ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
230 $rows[] = "('$option_name', '$option_value', 'no')";
231 } catch ( \Exception $e ) {
232 // Item cannot be serialized so skip.
233 continue;
234 }
235 }
236
237 $rows_added = $wpdb->query( $query . implode( ',', $rows ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
238
239 return $rows_added;
240 }
241
242 /**
243 * Return $max_count items from the queue, including their value string length.
244 *
245 * @param int $max_count How many items to fetch from the queue.
246 *
247 * @return object[]|null
248 */
249 public function get_items_ids_with_size( $max_count ) {
250 global $wpdb;
251
252 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
253 return $wpdb->get_results(
254 $wpdb->prepare(
255 "SELECT option_name AS id, LENGTH(option_value) AS value_size FROM $wpdb->options WHERE option_name LIKE %s ORDER BY option_name ASC LIMIT %d",
256 "jpsq_{$this->queue_id}-%",
257 $max_count
258 ),
259 OBJECT
260 );
261 }
262
263 /**
264 * Delete items with specific IDs from the queue.
265 *
266 * @param array $ids IDs of the items to remove from the queue.
267 *
268 * @return bool|int|\mysqli_result|resource|null
269 */
270 public function delete_items_by_ids( $ids ) {
271 global $wpdb;
272
273 if ( ! is_array( $ids ) || empty( $ids ) ) {
274 return false;
275 }
276
277 // TODO check if it's working properly - no need to delete all options in the table if the params are not right
278 $ids_placeholders = implode( ', ', array_fill( 0, count( $ids ), '%s' ) );
279
280 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
281 return $wpdb->query(
282 $wpdb->prepare(
283 /**
284 * Ignoring the linting warning, as there's still no placeholder replacement for DB field name,
285 * in this case this is `$ids_placeholders`, as we're preparing them above and are a dynamic count.
286 */
287 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
288 "DELETE FROM {$wpdb->options} WHERE option_name IN ( $ids_placeholders )",
289 $ids
290 )
291 );
292 }
293 }
294