PluginProbe
Code Snippets / 2.12.0
Code Snippets v2.12.0
3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 3.0.1 All 64 releases
code-snippets / php / snippet-ops.php

snippet-ops.php in Code Snippets 2.12.0, at php/snippet-ops.php

436 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Functions to perform snippet operations
5 *
6 * @package Code_Snippets
7 */
8
9 /**
10 * Retrieve a list of snippets from the database
11 *
12 * @since 2.0
13 *
14 * @uses $wpdb to query the database for snippets
15 * @uses code_snippets()->db->get_table_name() to dynamically retrieve the snippet table name
16 *
17 * @param array $ids The IDs of the snippets to fetch
18 * @param bool|null $multisite Retrieve multisite-wide or site-wide snippets?
19 * @return array An array of Snippet objects
20 */
21 function get_snippets( array $ids = array(), $multisite = null ) {
22 /** @var wpdb $wpdb */
23 global $wpdb;
24
25 $db = code_snippets()->db;
26 $multisite = $db->validate_network_param( $multisite );
27 $table = $db->get_table_name( $multisite );
28
29 $ids_count = count( $ids );
30
31 /* If only one ID has been passed in, defer to the get_snippet() function */
32 if ( 1 == $ids_count ) {
33 return array( get_snippet( $ids[0] ) );
34 }
35
36 /* Build a query containing the specified IDs if there are any */
37 if ( $ids_count > 1 ) {
38 $sql = sprintf(
39 'SELECT * FROM %s WHERE id IN (%s);',
40 $table,
41 implode( ',', array_fill( 0, $ids_count, '%d' ) )
42 );
43 $sql = $wpdb->prepare( $sql, $ids );
44
45 } else {
46 $sql = "SELECT * FROM $table;";
47 }
48
49 /* Retrieve the results from the database */
50 $snippets = $wpdb->get_results( $sql, ARRAY_A );
51
52 /* Convert snippets to snippet objects */
53 foreach ( $snippets as $index => $snippet ) {
54 $snippet['network'] = $multisite;
55 $snippets[ $index ] = new Code_Snippet( $snippet );
56 }
57
58 return apply_filters( 'code_snippets/get_snippets', $snippets, $multisite );
59 }
60
61 /**
62 * Gets all of the used tags from the database
63 * @since 2.0
64 */
65 function get_all_snippet_tags() {
66 /** @var wpdb $wpdb */
67 global $wpdb;
68
69 /* Grab all tags from the database */
70 $tags = array();
71 $table = code_snippets()->db->get_table_name();
72 $all_tags = $wpdb->get_col( "SELECT `tags` FROM $table" );
73
74 /* Merge all tags into a single array */
75 foreach ( $all_tags as $snippet_tags ) {
76 $snippet_tags = code_snippets_build_tags_array( $snippet_tags );
77 $tags = array_merge( $snippet_tags, $tags );
78 }
79
80 /* Remove duplicate tags */
81 return array_values( array_unique( $tags, SORT_REGULAR ) );
82 }
83 /**
84 * Make sure that the tags are a valid array
85 * @since 2.0
86 *
87 * @param mixed $tags The tags to convert into an array
88 * @return array The converted tags
89 */
90 function code_snippets_build_tags_array( $tags ) {
91
92 /* If there are no tags set, return an empty array */
93 if ( empty( $tags ) ) {
94 return array();
95 }
96
97 /* If the tags are set as a string, convert them into an array */
98 if ( is_string( $tags ) ) {
99 $tags = strip_tags( $tags );
100 $tags = str_replace( ', ', ',', $tags );
101 $tags = explode( ',', $tags );
102 }
103
104 /* If we still don't have an array, just convert whatever we do have into one */
105 return (array) $tags;
106 }
107
108 /**
109 * Retrieve a single snippets from the database.
110 * Will return empty snippet object if no snippet
111 * ID is specified
112 *
113 * @since 2.0
114 *
115 * @uses $wpdb to query the database for snippets
116 * @uses code_snippets()->db->get_table_name() to dynamically retrieve the snippet table name
117 *
118 * @param int $id The ID of the snippet to retrieve. 0 to build a new snippet
119 * @param boolean|null $multisite Retrieve a multisite-wide or site-wide snippet?
120 *
121 * @return Code_Snippet A single snippet object
122 */
123 function get_snippet( $id = 0, $multisite = null ) {
124 /** @var wpdb $wpdb */
125 global $wpdb;
126
127 $id = absint( $id );
128 $table = code_snippets()->db->get_table_name( $multisite );
129
130 if ( 0 !== $id ) {
131
132 /* Retrieve the snippet from the database */
133 $snippet = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table WHERE id = %d", $id ) );
134
135 /* Unescape the snippet data, ready for use */
136 $snippet = new Code_Snippet( $snippet );
137
138 } else {
139
140 /* Get an empty snippet object */
141 $snippet = new Code_Snippet();
142 }
143
144 $snippet->network = $multisite;
145
146 return apply_filters( 'code_snippets/get_snippet', $snippet, $id, $multisite );
147 }
148
149 /**
150 * Activates a snippet
151 *
152 * @since 2.0
153 *
154 * @uses $wpdb to set the snippet's active status
155 *
156 * @param int $id The ID of the snippet to activate
157 * @param bool|null $multisite Are the snippets multisite-wide or site-wide?
158 */
159 function activate_snippet( $id, $multisite = null ) {
160 /** @var wpdb $wpdb */
161 global $wpdb;
162 $table = code_snippets()->db->get_table_name( $multisite );
163
164 $wpdb->update(
165 $table,
166 array( 'active' => '1' ),
167 array( 'id' => $id ),
168 array( '%d' ),
169 array( '%d' )
170 );
171
172 /* Remove snippet from shared network snippet list if it was Network Activated */
173 if ( $table == $wpdb->ms_snippets && $shared_network_snippets = get_site_option( 'shared_network_snippets', false ) ) {
174 $shared_network_snippets = array_diff( $shared_network_snippets, array( $id ) );
175 update_site_option( 'shared_network_snippets', $shared_network_snippets );
176 }
177
178 do_action( 'code_snippets/activate_snippet', $id, $multisite );
179 }
180
181 /**
182 * Deactivate a snippet
183 *
184 * @since 2.0
185 *
186 * @uses $wpdb to set the snippets' active status
187 *
188 * @param int $id The ID of the snippet to deactivate
189 * @param bool|null $multisite Are the snippets multisite-wide or site-wide?
190 */
191 function deactivate_snippet( $id, $multisite = null ) {
192 /** @var wpdb $wpdb */
193 global $wpdb;
194 $table = code_snippets()->db->get_table_name( $multisite );
195
196 /* Set the snippet to active */
197
198 $wpdb->update(
199 $table,
200 array( 'active' => '0' ),
201 array( 'id' => $id ),
202 array( '%d' ),
203 array( '%d' )
204 );
205
206 /* Update the recently active list */
207
208 $recently_active = array( $id => time() );
209
210 if ( $table === $wpdb->ms_snippets ) {
211
212 update_site_option(
213 'recently_activated_snippets',
214 $recently_active + (array) get_site_option( 'recently_activated_snippets' )
215 );
216 } elseif ( $table === $wpdb->snippets ) {
217
218 update_option(
219 'recently_activated_snippets',
220 $recently_active + (array) get_option( 'recently_activated_snippets' )
221 );
222 }
223
224 do_action( 'code_snippets/deactivate_snippet', $id, $multisite );
225 }
226
227 /**
228 * Deletes a snippet from the database
229 *
230 * @since 2.0
231 * @uses $wpdb to access the database
232 * @uses code_snippets()->db->get_table_name() to dynamically retrieve the name of the snippet table
233 *
234 * @param int $id The ID of the snippet to delete
235 * @param bool|null $multisite Delete from site-wide or network-wide table?
236 */
237 function delete_snippet( $id, $multisite = null ) {
238 /** @var wpdb $wpdb */
239 global $wpdb;
240
241 $wpdb->delete(
242 code_snippets()->db->get_table_name( $multisite ),
243 array( 'id' => $id ),
244 array( '%d' )
245 );
246
247 do_action( 'code_snippets/delete_snippet', $id, $multisite );
248 }
249
250 /**
251 * Saves a snippet to the database.
252 *
253 * @since 2.0
254 *
255 * @uses $wpdb to update/add the snippet to the database
256 * @uses code_snippets()->db->get_table_name() To dynamically retrieve the name of the snippet table
257 *
258 * @param Code_Snippet $snippet The snippet to add/update to the database
259 *
260 * @return int The ID of the snippet
261 */
262 function save_snippet( Code_Snippet $snippet ) {
263 /** @var wpdb $wpdb */
264 global $wpdb;
265
266 $table = code_snippets()->db->get_table_name( $snippet->network );
267
268 /* Build array of data to insert */
269 $data = array(
270 'name' => $snippet->name,
271 'description' => $snippet->desc,
272 'code' => $snippet->code,
273 'tags' => $snippet->tags_list,
274 'scope' => $snippet->scope,
275 'priority' => $snippet->priority,
276 'active' => intval( $snippet->active ),
277 );
278
279 /* Create a new snippet if the ID is not set */
280 if ( 0 == $snippet->id ) {
281
282 $wpdb->insert( $table, $data, '%s' );
283 $snippet->id = $wpdb->insert_id;
284
285 do_action( 'code_snippets/create_snippet', $snippet->id, $table );
286 } else {
287
288 /* Otherwise update the snippet data */
289 $wpdb->update( $table, $data, array( 'id' => $snippet->id ), null, array( '%d' ) );
290
291 do_action( 'code_snippets/update_snippet', $snippet->id, $table );
292 }
293
294 return $snippet->id;
295 }
296
297 /**
298 * Update a snippet entry given a list of fields
299 *
300 * @param int $snippet_id The ID of the snippet to update
301 * @param array $fields An array of fields mapped to their values
302 * @param bool $network Whether the snippet is network-wide or site-wide
303 */
304 function update_snippet_fields( $snippet_id, $fields, $network = null ) {
305 /** @var wpdb $wpdb */
306 global $wpdb;
307
308 $table = code_snippets()->db->get_table_name( $network );
309
310 /* Build a new snippet object for the validation */
311 $snippet = new Code_Snippet();
312 $snippet->id = $snippet_id;
313
314 /* Validate fields through the snippet class and copy them into a clean array */
315 $clean_fields = array();
316
317 foreach ( $fields as $field => $value ) {
318
319 if ( $snippet->set_field( $field, $value ) ) {
320 $clean_fields[ $field ] = $snippet->$field;
321 }
322 }
323
324 /* Update the snippet in the database */
325 $wpdb->update( $table, $clean_fields, array( 'id' => $snippet->id ), null, array( '%d' ) );
326 do_action( 'code_snippets/update_snippet', $snippet->id, $table );
327 }
328
329 /**
330 * Execute a snippet
331 *
332 * Code must NOT be escaped, as
333 * it will be executed directly
334 *
335 * @since 2.0
336 *
337 * @param string $code The snippet code to execute
338 * @param int $id The snippet ID
339 * @param bool $catch_output Whether to attempt to suppress the output of execution using buffers
340 *
341 * @return mixed The result of the code execution
342 */
343 function execute_snippet( $code, $id = 0, $catch_output = true ) {
344
345 if ( empty( $code ) ) {
346 return false;
347 }
348
349 if ( $catch_output ) {
350 ob_start();
351 }
352
353 $result = eval( $code );
354
355 if ( $catch_output ) {
356 ob_end_clean();
357 }
358
359 do_action( 'code_snippets/after_execute_snippet', $id, $code, $result );
360
361 return $result;
362 }
363
364 /**
365 * Run the active snippets
366 *
367 * @since 2.0
368 *
369 * @return bool true on success, false on failure
370 */
371 function execute_active_snippets() {
372
373 if ( ! apply_filters( 'code_snippets/execute_snippets', true ) ) {
374 return false;
375 }
376
377 /** @var wpdb $wpdb */
378 global $wpdb;
379
380 $current_scope = is_admin() ? 'admin' : 'front-end';
381 $queries = array();
382
383 $sql_format = "SELECT id, code, scope FROM %s WHERE scope IN ('global', 'single-use', %%s) ";
384 $order = 'ORDER BY priority ASC, id ASC';
385
386 /* Fetch snippets from site table */
387 if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->snippets'" ) === $wpdb->snippets ) {
388 $queries[ $wpdb->snippets ] = $wpdb->prepare( sprintf( $sql_format, $wpdb->snippets ) . 'AND active=1 ' . $order, $current_scope );
389 }
390
391 /* Fetch snippets from the network table */
392 if ( is_multisite() && $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ms_snippets'" ) === $wpdb->ms_snippets ) {
393 $active_shared_ids = get_option( 'active_shared_network_snippets', array() );
394
395 /* If there are active shared snippets, include them in the query */
396 if ( count( $active_shared_ids ) ) {
397
398 /* Build a list of "%d, %d, %d ..." for every active network shared snippet we have */
399 $active_shared_ids_format = implode( ',', array_fill( 0, count( $active_shared_ids ), '%d' ) );
400
401 /* Include them in the query */
402 $sql = sprintf( $sql_format, $wpdb->ms_snippets ) . " AND (active=1 OR id IN ($active_shared_ids_format)) $order";
403
404 /* Add the scope number to the IDs array, so that it is the first variable in the query */
405 array_unshift( $active_shared_ids, $current_scope );
406 $queries[ $wpdb->ms_snippets ] = $wpdb->prepare( $sql, $active_shared_ids );
407
408 } else {
409 $sql = sprintf( $sql_format, $wpdb->ms_snippets ) . 'AND active=1 ' . $order;
410 $queries[ $wpdb->ms_snippets ] = $wpdb->prepare( $sql, $current_scope );
411 }
412 }
413
414 foreach ( $queries as $table_name => $query ) {
415 $active_snippets = $wpdb->get_results( $query, ARRAY_A );
416
417 /* Loop through the returned snippets and execute the PHP code */
418 foreach ( $active_snippets as $snippet ) {
419 $snippet_id = intval( $snippet['id'] );
420 $code = $snippet['code'];
421
422 if ( 'single-use' === $snippet['scope'] ) {
423 $wpdb->update( $table_name, array( 'active' => '0' ), array( 'id' => $snippet_id ), array( '%d' ), array( '%d' ) );
424 }
425
426 if ( apply_filters( 'code_snippets/allow_execute_snippet', true, $snippet_id, $table_name ) ) {
427 execute_snippet( $code, $snippet_id );
428 }
429 }
430 }
431
432 return true;
433 }
434
435
436