PluginProbe
Code Snippets / 2.12.1
Code Snippets v2.12.1
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.1, at php/snippet-ops.php

439 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 $db = code_snippets()->db;
163 $table = $db->get_table_name( $multisite );
164
165 $wpdb->update(
166 $table,
167 array( 'active' => '1' ),
168 array( 'id' => $id ),
169 array( '%d' ),
170 array( '%d' )
171 );
172
173 /* Remove snippet from shared network snippet list if it was Network Activated */
174 if ( $table === $db && $shared_network_snippets = get_site_option( 'shared_network_snippets', false ) ) {
175 $shared_network_snippets = array_diff( $shared_network_snippets, array( $id ) );
176 update_site_option( 'shared_network_snippets', $shared_network_snippets );
177 }
178
179 do_action( 'code_snippets/activate_snippet', $id, $multisite );
180 }
181
182 /**
183 * Deactivate a snippet
184 *
185 * @since 2.0
186 *
187 * @uses $wpdb to set the snippets' active status
188 *
189 * @param int $id The ID of the snippet to deactivate
190 * @param bool|null $multisite Are the snippets multisite-wide or site-wide?
191 */
192 function deactivate_snippet( $id, $multisite = null ) {
193 /** @var wpdb $wpdb */
194 global $wpdb;
195 $db = code_snippets()->db;
196 $table = $db->get_table_name( $multisite );
197
198 /* Set the snippet to active */
199
200 $wpdb->update(
201 $table,
202 array( 'active' => '0' ),
203 array( 'id' => $id ),
204 array( '%d' ),
205 array( '%d' )
206 );
207
208 /* Update the recently active list */
209
210 $recently_active = array( $id => time() );
211
212 if ( $table === $db->table ) {
213
214 update_site_option(
215 'recently_activated_snippets',
216 $recently_active + (array) get_site_option( 'recently_activated_snippets' )
217 );
218 } elseif ( $table === $db->ms_table ) {
219
220 update_option(
221 'recently_activated_snippets',
222 $recently_active + (array) get_option( 'recently_activated_snippets' )
223 );
224 }
225
226 do_action( 'code_snippets/deactivate_snippet', $id, $multisite );
227 }
228
229 /**
230 * Deletes a snippet from the database
231 *
232 * @since 2.0
233 * @uses $wpdb to access the database
234 * @uses code_snippets()->db->get_table_name() to dynamically retrieve the name of the snippet table
235 *
236 * @param int $id The ID of the snippet to delete
237 * @param bool|null $multisite Delete from site-wide or network-wide table?
238 */
239 function delete_snippet( $id, $multisite = null ) {
240 /** @var wpdb $wpdb */
241 global $wpdb;
242
243 $wpdb->delete(
244 code_snippets()->db->get_table_name( $multisite ),
245 array( 'id' => $id ),
246 array( '%d' )
247 );
248
249 do_action( 'code_snippets/delete_snippet', $id, $multisite );
250 }
251
252 /**
253 * Saves a snippet to the database.
254 *
255 * @since 2.0
256 *
257 * @uses $wpdb to update/add the snippet to the database
258 * @uses code_snippets()->db->get_table_name() To dynamically retrieve the name of the snippet table
259 *
260 * @param Code_Snippet $snippet The snippet to add/update to the database
261 *
262 * @return int The ID of the snippet
263 */
264 function save_snippet( Code_Snippet $snippet ) {
265 /** @var wpdb $wpdb */
266 global $wpdb;
267
268 $table = code_snippets()->db->get_table_name( $snippet->network );
269
270 /* Build array of data to insert */
271 $data = array(
272 'name' => $snippet->name,
273 'description' => $snippet->desc,
274 'code' => $snippet->code,
275 'tags' => $snippet->tags_list,
276 'scope' => $snippet->scope,
277 'priority' => $snippet->priority,
278 'active' => intval( $snippet->active ),
279 );
280
281 /* Create a new snippet if the ID is not set */
282 if ( 0 == $snippet->id ) {
283
284 $wpdb->insert( $table, $data, '%s' );
285 $snippet->id = $wpdb->insert_id;
286
287 do_action( 'code_snippets/create_snippet', $snippet->id, $table );
288 } else {
289
290 /* Otherwise update the snippet data */
291 $wpdb->update( $table, $data, array( 'id' => $snippet->id ), null, array( '%d' ) );
292
293 do_action( 'code_snippets/update_snippet', $snippet->id, $table );
294 }
295
296 return $snippet->id;
297 }
298
299 /**
300 * Update a snippet entry given a list of fields
301 *
302 * @param int $snippet_id The ID of the snippet to update
303 * @param array $fields An array of fields mapped to their values
304 * @param bool $network Whether the snippet is network-wide or site-wide
305 */
306 function update_snippet_fields( $snippet_id, $fields, $network = null ) {
307 /** @var wpdb $wpdb */
308 global $wpdb;
309
310 $table = code_snippets()->db->get_table_name( $network );
311
312 /* Build a new snippet object for the validation */
313 $snippet = new Code_Snippet();
314 $snippet->id = $snippet_id;
315
316 /* Validate fields through the snippet class and copy them into a clean array */
317 $clean_fields = array();
318
319 foreach ( $fields as $field => $value ) {
320
321 if ( $snippet->set_field( $field, $value ) ) {
322 $clean_fields[ $field ] = $snippet->$field;
323 }
324 }
325
326 /* Update the snippet in the database */
327 $wpdb->update( $table, $clean_fields, array( 'id' => $snippet->id ), null, array( '%d' ) );
328 do_action( 'code_snippets/update_snippet', $snippet->id, $table );
329 }
330
331 /**
332 * Execute a snippet
333 *
334 * Code must NOT be escaped, as
335 * it will be executed directly
336 *
337 * @since 2.0
338 *
339 * @param string $code The snippet code to execute
340 * @param int $id The snippet ID
341 * @param bool $catch_output Whether to attempt to suppress the output of execution using buffers
342 *
343 * @return mixed The result of the code execution
344 */
345 function execute_snippet( $code, $id = 0, $catch_output = true ) {
346
347 if ( empty( $code ) ) {
348 return false;
349 }
350
351 if ( $catch_output ) {
352 ob_start();
353 }
354
355 $result = eval( $code );
356
357 if ( $catch_output ) {
358 ob_end_clean();
359 }
360
361 do_action( 'code_snippets/after_execute_snippet', $id, $code, $result );
362
363 return $result;
364 }
365
366 /**
367 * Run the active snippets
368 *
369 * @since 2.0
370 *
371 * @return bool true on success, false on failure
372 */
373 function execute_active_snippets() {
374
375 if ( ! apply_filters( 'code_snippets/execute_snippets', true ) ) {
376 return false;
377 }
378
379 /** @var wpdb $wpdb */
380 global $wpdb;
381 $db = code_snippets()->db;
382
383 $current_scope = is_admin() ? 'admin' : 'front-end';
384 $queries = array();
385
386 $sql_format = "SELECT id, code, scope FROM %s WHERE scope IN ('global', 'single-use', %%s) ";
387 $order = 'ORDER BY priority ASC, id ASC';
388
389 /* Fetch snippets from site table */
390 if ( $wpdb->get_var( "SHOW TABLES LIKE '$db->table'" ) === $db->table ) {
391 $queries[ $db->table ] = $wpdb->prepare( sprintf( $sql_format, $db->table ) . 'AND active=1 ' . $order, $current_scope );
392 }
393
394 /* Fetch snippets from the network table */
395 if ( is_multisite() && $wpdb->get_var( "SHOW TABLES LIKE '$db->ms_table'" ) === $db->ms_table ) {
396 $active_shared_ids = get_option( 'active_shared_network_snippets', array() );
397
398 /* If there are active shared snippets, include them in the query */
399 if ( count( $active_shared_ids ) ) {
400
401 /* Build a list of "%d, %d, %d ..." for every active network shared snippet we have */
402 $active_shared_ids_format = implode( ',', array_fill( 0, count( $active_shared_ids ), '%d' ) );
403
404 /* Include them in the query */
405 $sql = sprintf( $sql_format, $db->ms_table ) . " AND (active=1 OR id IN ($active_shared_ids_format)) $order";
406
407 /* Add the scope number to the IDs array, so that it is the first variable in the query */
408 array_unshift( $active_shared_ids, $current_scope );
409 $queries[ $db->ms_table ] = $wpdb->prepare( $sql, $active_shared_ids );
410
411 } else {
412 $sql = sprintf( $sql_format, $db->ms_table ) . 'AND active=1 ' . $order;
413 $queries[ $db->ms_table ] = $wpdb->prepare( $sql, $current_scope );
414 }
415 }
416
417 foreach ( $queries as $table_name => $query ) {
418 $active_snippets = $wpdb->get_results( $query, ARRAY_A );
419
420 /* Loop through the returned snippets and execute the PHP code */
421 foreach ( $active_snippets as $snippet ) {
422 $snippet_id = intval( $snippet['id'] );
423 $code = $snippet['code'];
424
425 if ( 'single-use' === $snippet['scope'] ) {
426 $wpdb->update( $table_name, array( 'active' => '0' ), array( 'id' => $snippet_id ), array( '%d' ), array( '%d' ) );
427 }
428
429 if ( apply_filters( 'code_snippets/allow_execute_snippet', true, $snippet_id, $table_name ) ) {
430 execute_snippet( $code, $snippet_id );
431 }
432 }
433 }
434
435 return true;
436 }
437
438
439