PluginProbe
Snippet Shortcodes / 5.2
Snippet Shortcodes v5.2
5.2.1 5.2 5.1.8 5.1.6 5.1.7 5.1.5 trunk 1.0 1.1 1.2 1.3 1.3.1 1.4 1.5 1.5.1 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.8 2.0 2.0.1 All 74 releases
shortcode-variables / includes / db.php

db.php in Snippet Shortcodes 5.2, at includes/db.php

731 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined('ABSPATH') or die('Jog on!');
4
5 /**
6 * Build database table
7 */
8 function sh_cd_create_database_table() {
9
10 global $wpdb;
11
12 $table_name = $wpdb->prefix . SH_CD_TABLE;
13
14 $charset_collate = $wpdb->get_charset_collate();
15
16 $sql = "CREATE TABLE $table_name (
17 id mediumint(9) NOT NULL AUTO_INCREMENT,
18 slug varchar(100) NOT NULL,
19 previous_slug varchar(100) NOT NULL,
20 editor varchar(10) NULL,
21 data text,
22 disabled bit default 0,
23 multisite bit default 0,
24 header bit default 0,
25 footer bit default 0,
26 device_type varchar(50) NULL DEFAULT '[\"desktop\",\"mobile\",\"tablet\"]',
27 roles varchar(255) NULL DEFAULT NULL,
28 visibility_start datetime NULL DEFAULT NULL,
29 visibility_end datetime NULL DEFAULT NULL,
30 render_count bigint(20) unsigned NOT NULL DEFAULT 0,
31 target_pages text NULL DEFAULT NULL,
32 UNIQUE KEY id (id)
33 ) $charset_collate;";
34
35 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
36
37 dbDelta( $sql );
38 }
39
40 /**
41 * Build database table for multisite
42 */
43 function sh_cd_create_database_table_multisite() {
44
45 global $wpdb;
46
47 $table_name = $wpdb->base_prefix . SH_CD_TABLE_MULTISITE;
48
49 $charset_collate = $wpdb->get_charset_collate();
50
51 $sql = "CREATE TABLE $table_name (
52 id mediumint(9) NOT NULL AUTO_INCREMENT,
53 slug varchar(100) NOT NULL,
54 data text,
55 site_id int default 0,
56 header bit default 0,
57 footer bit default 0,
58 device_type varchar(50) NULL DEFAULT '[\"desktop\",\"mobile\",\"tablet\"]',
59 roles varchar(255) NULL DEFAULT NULL,
60 visibility_start datetime NULL DEFAULT NULL,
61 visibility_end datetime NULL DEFAULT NULL,
62 render_count bigint(20) unsigned NOT NULL DEFAULT 0,
63 target_pages text NULL DEFAULT NULL,
64 UNIQUE KEY id (id)
65 ) $charset_collate;";
66
67 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
68
69 dbDelta( $sql );
70 }
71
72 /**
73 * Build database table for shortcode content revisions
74 */
75 function sh_cd_create_database_table_revisions() {
76
77 global $wpdb;
78
79 $table_name = $wpdb->prefix . SH_CD_TABLE_REVISIONS;
80
81 $charset_collate = $wpdb->get_charset_collate();
82
83 $sql = "CREATE TABLE $table_name (
84 id mediumint(9) NOT NULL AUTO_INCREMENT,
85 shortcode_id mediumint(9) NOT NULL,
86 data text,
87 created_by bigint(20) unsigned NOT NULL DEFAULT 0,
88 created_at datetime NOT NULL,
89 UNIQUE KEY id (id),
90 KEY shortcode_id (shortcode_id)
91 ) $charset_collate;";
92
93 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
94
95 dbDelta( $sql );
96 }
97
98 /**
99 * Fetch all Shortcodes
100 *
101 * @return bool
102 */
103 function sh_cd_db_shortcodes_all() {
104
105 global $wpdb;
106
107 return $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' order by slug asc', ARRAY_A );
108 }
109
110 /**
111 * Fetch all enabled Shortcodes
112 *
113 * @return bool
114 */
115 function sh_cd_db_shortcodes_all_enabled() {
116
117 global $wpdb;
118
119 return $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where disabled = 0 order by slug asc', ARRAY_A );
120 }
121
122 /**
123 * Fetch a count of all shortcodes
124 *
125 * @return bool
126 */
127 function sh_cd_db_shortcodes_count() {
128
129 global $wpdb;
130
131 return $wpdb->get_var( 'SELECT count(id) FROM ' . $wpdb->prefix . SH_CD_TABLE );
132 }
133
134 /**
135 * Fetch a shortcode by ID (mainly used for quick lookups in admin)
136 *
137 * @param $id
138 *
139 * @return mixed
140 */
141 function sh_cd_db_shortcodes_by_id( $id ) {
142
143 global $wpdb;
144
145 $sql = $wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
146 $shortcode = $wpdb->get_row( $sql, ARRAY_A );
147
148 if ( false === empty( $shortcode ) ) {
149 $shortcode = sh_cd_db_filter_loaded_shortcode( $shortcode );
150 }
151
152 return $shortcode;
153 }
154
155 /**
156 * Fetch the content of the shortcode by slug
157 *
158 * @param $slug
159 *
160 * @return null|string
161 */
162 function sh_cd_db_shortcodes_by_slug( $slug ) {
163
164 global $wpdb;
165
166 $sqls = [];
167
168 // If multi site functionality is enabled, look there first for the shortcode!
169 if ( true === sh_cd_is_multisite_enabled() ) {
170
171 $sql = $wpdb->prepare('SELECT * FROM ' . $wpdb->base_prefix . SH_CD_TABLE_MULTISITE . ' where slug = %s', $slug);
172
173 $shortcode = $wpdb->get_row( $sql, ARRAY_A );
174
175 if ( false === empty( $shortcode[ 'data' ] ) ) {
176 $shortcode[ 'data' ] = stripslashes( $shortcode[ 'data' ] );
177 $shortcode[ 'source' ] = 'multisite';
178 return sh_cd_db_filter_loaded_shortcode( $shortcode );
179 }
180 }
181
182 // No multisite slug by this name, so check the main table
183 $sql = $wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s and disabled <> 1', $slug);
184 $shortcode = $wpdb->get_row( $sql, ARRAY_A );
185
186 if ( false === empty( $shortcode[ 'data' ] ) ) {
187 $shortcode[ 'data' ] = stripslashes( $shortcode[ 'data' ] );
188 $shortcode[ 'source' ] = 'local';
189 return sh_cd_db_filter_loaded_shortcode( $shortcode );
190 }
191
192 return NULL;
193 }
194
195 /**
196 * Allow processing of loaded shortcode data. Called both for single by-id/by-slug fetches and,
197 * from sh_cd_export_csv(), in a bulk per-row loop over the entire collection - registered
198 * callbacks must be pure/side-effect-free (no queries, no global state) so they stay safe to
199 * run hundreds of times in one request.
200 */
201 function sh_cd_db_filter_loaded_shortcode( $shortcode ) {
202 return apply_filters( 'sh-cd-db-loaded-shortcode', $shortcode );
203 }
204
205 /**
206 * Get a Shortcode's slug from the slug ID
207 *
208 * @param $id
209 *
210 * @return bool
211 */
212 function sh_cd_db_shortcodes_get_slug_by_id( $id ) {
213
214 global $wpdb;
215
216 $sql = $wpdb->prepare('SELECT slug FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
217
218 return $wpdb->get_var( $sql );
219 }
220
221 /**
222 * Save / Insert a shortcode
223 *
224 * @param $shortcode
225 *
226 * @return bool
227 */
228 function sh_cd_db_shortcodes_save( $shortcode, $return_shortcode = false ) {
229
230 if ( false === is_admin() ) {
231 return false;
232 }
233
234 $multi_site_enabled = sh_cd_is_multisite_enabled();
235
236 $default_values = apply_filters( 'sh-cd-db-default-values', [ 'id' => NULL,
237 'slug' => NULL,
238 'previous_slug' => NULL,
239 'editor' => NULL,
240 'data' => NULL,
241 'disabled' => 0,
242 'multisite' => 0
243 ]);
244
245 $shortcode = wp_parse_args( $shortcode, $default_values );
246
247 // We need either a slug or an ID
248 if ( true === empty( $shortcode['slug'] ) && true === empty( $shortcode['id'] ) ) {
249 return false;
250 }
251
252 $shortcode['disabled'] = (int) $shortcode['disabled'];
253 $shortcode['multisite'] = ( true === $multi_site_enabled ) ? (int) $shortcode['multisite'] : 0;
254
255 global $wpdb;
256
257 $result = false;
258
259 // Updating an existing shortcode?
260 if ( false === empty( $shortcode['id'] ) && true === is_numeric( $shortcode['id'] ) ){
261
262 $shortcode_before_update = sh_cd_db_shortcodes_by_id( $shortcode['id'] );
263
264 $shortcode['slug'] = sh_cd_slug_generate( $shortcode['slug'], $shortcode['id'] );
265
266 $shortcode = apply_filters( 'sh-cd-db-default-shortcode-before-save', $shortcode );
267
268 $formats = sh_cd_db_get_formats( $shortcode );
269
270 $result = $wpdb->update(
271 $wpdb->prefix . SH_CD_TABLE,
272 $shortcode,
273 [ 'id' => $shortcode['id'] ],
274 $formats,
275 [ '%d' ]
276 );
277
278 if ( false !== $result ) {
279
280 do_action( 'sh-cd-shortcode-updated', $shortcode );
281
282 if ( false === empty( $shortcode_before_update ) ) {
283 do_action( 'sh-cd-shortcode-before-update', $shortcode_before_update, $shortcode );
284 }
285 }
286
287 sh_cd_cache_delete_by_slug_or_key( $shortcode['id'] );
288 sh_cd_cache_delete_by_slug_or_key( $shortcode['previous_slug'] );
289
290 // Adding a new shortcode
291 } else {
292
293 unset( $shortcode['id'] );
294
295 // Ensure slug is santised and unique
296 $shortcode['slug'] = sh_cd_slug_generate( $shortcode['slug'] );
297
298 $shortcode = apply_filters( 'sh-cd-db-default-shortcode-before-save', $shortcode );
299
300 $formats = sh_cd_db_get_formats( $shortcode );
301
302 $result = $wpdb->insert(
303 $wpdb->prefix . SH_CD_TABLE,
304 $shortcode,
305 $formats
306 );
307
308 if ( false !== $result ) {
309 do_action( 'sh-cd-shortcode-added', $shortcode );
310 }
311
312 // It's an insert, so there should be no cache... however, just a wee sanity check in case
313 // a shortcode with the same slug previously exists.
314 sh_cd_cache_delete_by_slug_or_key( $shortcode['slug'] );
315 }
316
317 if ( false !== $result ) {
318
319 if ( 1 === $shortcode['multisite'] ) {
320 sh_cd_db_shortcodes_multisite_insert( $shortcode );
321 } else {
322 sh_cd_db_shortcodes_multisite_delete( $shortcode['slug'] );
323 }
324
325 sh_cd_cache_delete( $shortcode['slug'] );
326
327 if ( true === $return_shortcode ) {
328
329 $shortcode['id'] = $result;
330 return $shortcode;
331 }
332
333 return true;
334 }
335
336 return false;
337 }
338
339
340 /**
341 * Insert a multisite shortcode
342 *
343 * @param $shortcode
344 *
345 * @return bool
346 */
347 function sh_cd_db_shortcodes_multisite_insert( $shortcode ) {
348
349 if ( false === is_admin() ) {
350 return false;
351 }
352
353 sh_cd_db_shortcodes_multisite_delete( $shortcode['slug'] );
354
355 global $wpdb;
356
357 $shortcode_multisite = [ 'slug' => $shortcode['slug'],
358 'data' => $shortcode['data'],
359 'header' => $shortcode['header'],
360 'footer' => $shortcode['footer'],
361 'device_type' => $shortcode['device_type'],
362 'site_id' => get_current_blog_id()
363 ];
364
365 $formats = sh_cd_db_get_formats( $shortcode_multisite );
366
367 $result = $wpdb->insert(
368 $wpdb->base_prefix . SH_CD_TABLE_MULTISITE,
369 $shortcode_multisite,
370 $formats
371 );
372
373 sh_cd_cache_delete( $shortcode['slug'] );
374
375 do_action( 'sh_cd_multisite_changed', $shortcode );
376
377 return ( false !== $result );
378 }
379
380 /**
381 * Delete a multisite shortcode
382 *
383 * @param $slug
384 *
385 * @return bool
386 */
387 function sh_cd_db_shortcodes_multisite_delete( $slug ) {
388
389 global $wpdb;
390
391 $result = $wpdb->delete( $wpdb->base_prefix . SH_CD_TABLE_MULTISITE, [ 'slug' => $slug ], [ '%s' ] );
392
393 sh_cd_cache_delete( $slug );
394
395 do_action( 'sh_cd_multisite_changed', $slug );
396
397 return ( false !== $result );
398 }
399
400 /**
401 * Fetch all multisite slugs
402
403 * @return null|array
404 */
405 function sh_cd_db_shortcodes_multisite_slugs() {
406
407 global $wpdb;
408
409 return $wpdb->get_results( 'SELECT slug FROM ' . $wpdb->base_prefix . SH_CD_TABLE_MULTISITE, ARRAY_A );
410 }
411
412
413 /**
414 * Update a shortcode's status
415 *
416 * @param $shortcode
417 *
418 * @return bool
419 */
420 function sh_cd_db_shortcodes_update_status( $id, $status ) {
421
422 if ( false === is_admin() ) {
423 return false;
424 }
425
426 global $wpdb;
427
428 $result = $wpdb->update(
429 $wpdb->prefix . SH_CD_TABLE,
430 [ 'disabled' => $status ],
431 [ 'id' => $id ],
432 [ '%d' ],
433 [ '%d' ]
434 );
435
436 sh_cd_cache_delete_by_slug_or_key( $id );
437
438 return ( false !== $result );
439 }
440
441 /**
442 * Update a shortcode's multisite
443 *
444 * @param $shortcode
445 *
446 * @return bool
447 */
448 function sh_cd_db_shortcodes_update_multisite( $id, $multisite ) {
449
450 if ( false === is_admin() ) {
451 return false;
452 }
453
454 global $wpdb;
455
456 $result = $wpdb->update(
457 $wpdb->prefix . SH_CD_TABLE,
458 [ 'multisite' => $multisite ],
459 [ 'id' => $id ],
460 [ '%d' ],
461 [ '%d' ]
462 );
463
464 $shortcode = sh_cd_db_shortcodes_by_id( $id );
465
466 if ( false === empty( $shortcode ) ) {
467
468 if ( 1 === (int) $multisite ) {
469 sh_cd_db_shortcodes_multisite_insert( $shortcode );
470 } else {
471 sh_cd_db_shortcodes_multisite_delete( $shortcode['slug'] );
472 }
473
474 }
475
476 sh_cd_cache_delete_by_slug_or_key( $id );
477
478 return ( false !== $result );
479 }
480
481 /**
482 * Update a shortcode's content
483 *
484 * @param $shortcode
485 *
486 * @return bool
487 */
488 function sh_cd_db_shortcodes_update_content( $id, $data ) {
489
490 if ( false === is_admin() ) {
491 return false;
492 }
493
494 $shortcode_before_update = sh_cd_db_shortcodes_by_id( $id );
495
496 global $wpdb;
497
498 $result = $wpdb->update(
499 $wpdb->prefix . SH_CD_TABLE,
500 [ 'data' => $data ],
501 [ 'id' => $id ],
502 [ '%s' ],
503 [ '%d' ]
504 );
505
506 $shortcode = sh_cd_db_shortcodes_by_id( $id );
507
508 if ( false === empty( $shortcode ) ) {
509
510 if ( 1 === (int) $shortcode[ 'multisite' ] ) {
511 sh_cd_db_shortcodes_multisite_insert( $shortcode );
512 } else {
513 sh_cd_db_shortcodes_multisite_delete( $shortcode['slug'] );
514 }
515
516 }
517
518 if ( false !== $result && false === empty( $shortcode_before_update ) ) {
519 do_action( 'sh-cd-shortcode-before-update', $shortcode_before_update, $shortcode );
520 }
521
522 sh_cd_cache_delete_by_slug_or_key( $id );
523
524 return ( false !== $result );
525 }
526
527
528 /**
529 * Delete a shortcode
530 *
531 * @param $id
532 *
533 * @return bool
534 */
535 function sh_cd_db_shortcodes_delete( $id ) {
536
537 if ( false === is_admin() || false === is_numeric( $id ) ) {
538 return false;
539 }
540
541 global $wpdb;
542
543 // Clear multi site
544 $shortcode_before_delete = sh_cd_db_shortcodes_by_id( $id );
545 sh_cd_db_shortcodes_multisite_delete( $shortcode_before_delete['slug'] );
546
547 // Clear revisions
548 sh_cd_db_shortcode_revisions_delete_by_shortcode_id( $id );
549
550 // Clear cached version
551 sh_cd_cache_delete_by_slug_or_key( $id );
552
553 $slug = sh_cd_db_shortcodes_get_slug_by_id( $id );
554 $result = $wpdb->delete( $wpdb->prefix . SH_CD_TABLE, [ 'id' => $id ], [ '%d' ] );
555
556 if ( false !== $result ) {
557 do_action( 'sh-cd-shortcode-updated', $id, $slug );
558 }
559
560 return ( false !== $result );
561 }
562
563 /**
564 * For a given key value array, look up and return the expected MySQL data formats.
565 *
566 * @param $data
567 *
568 * @return array
569 */
570 function sh_cd_db_get_formats( $data ) {
571
572 $lookup = [
573 'id' => '%d',
574 'slug' => '%s',
575 'previous_slug' => '%s',
576 'data' => '%s',
577 'disabled' => '%d',
578 'multisite' => '%d',
579 'site_id' => '%d',
580 'editor' => '%s',
581 'header' => '%d',
582 'footer' => '%d',
583 'device_type' => '%s',
584 'roles' => '%s',
585 'visibility_start' => '%s',
586 'visibility_end' => '%s',
587 'render_count' => '%d',
588 'target_pages' => '%s',
589 ];
590
591 $formats = [];
592
593 foreach ( $data as $key => $value ) {
594
595 // $wpdb->update()/insert() match $formats to $data positionally, not by key - so every
596 // key must produce an entry here (even an unrecognised one, defaulted to '%s') or every
597 // column from that point on silently shifts onto the wrong format specifier.
598 $formats[] = $lookup[ $key ] ?? '%s';
599 }
600
601 return $formats;
602 }
603
604 /**
605 * Check if the slug already exists
606 *
607 * @param $slug
608 * @param $existing_id
609 *
610 * @return bool
611 */
612 function sh_cd_slug_is_unique( $slug, $existing_id = NULL ) {
613
614 if ( true === empty( $slug ) ) {
615 return false;
616 }
617
618 global $wpdb;
619
620 $sql = $wpdb->prepare( 'SELECT count(slug) FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s', $slug );
621
622 if ( false === empty( $existing_id ) ) {
623 $sql .= $wpdb->prepare( ' and id <> %d', $existing_id );
624 }
625
626 $row = $wpdb->get_var( $sql );
627
628 return ( empty( $row ) );
629 }
630
631 /**
632 * Save a shortcode content revision, pruning older revisions beyond the retention limit
633 *
634 * @param $shortcode_id
635 * @param $data
636 * @param $user_id
637 *
638 * @return bool
639 */
640 function sh_cd_db_shortcode_revisions_save( $shortcode_id, $data, $user_id = NULL ) {
641
642 global $wpdb;
643
644 $user_id = ( true === empty( $user_id ) ) ? get_current_user_id() : $user_id;
645
646 $result = $wpdb->insert(
647 $wpdb->prefix . SH_CD_TABLE_REVISIONS,
648 [
649 'shortcode_id' => $shortcode_id,
650 'data' => $data,
651 'created_by' => $user_id,
652 'created_at' => current_time( 'mysql' ),
653 ],
654 [ '%d', '%s', '%d', '%s' ]
655 );
656
657 sh_cd_db_shortcode_revisions_prune( $shortcode_id );
658
659 return ( false !== $result );
660 }
661
662 /**
663 * Keep only the most recent $keep revisions for a given shortcode
664 *
665 * @param $shortcode_id
666 * @param $keep
667 */
668 function sh_cd_db_shortcode_revisions_prune( $shortcode_id, $keep = 20 ) {
669
670 global $wpdb;
671
672 $table = $wpdb->prefix . SH_CD_TABLE_REVISIONS;
673
674 $sql = $wpdb->prepare(
675 "DELETE FROM {$table} WHERE shortcode_id = %d AND id NOT IN (
676 SELECT id FROM ( SELECT id FROM {$table} WHERE shortcode_id = %d ORDER BY created_at DESC, id DESC LIMIT %d ) AS keep_revisions
677 )",
678 $shortcode_id, $shortcode_id, $keep
679 );
680
681 $wpdb->query( $sql );
682 }
683
684 /**
685 * Fetch all revisions for a shortcode, most recent first
686 *
687 * @param $shortcode_id
688 *
689 * @return array
690 */
691 function sh_cd_db_shortcode_revisions_get( $shortcode_id ) {
692
693 global $wpdb;
694
695 $sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE_REVISIONS . ' WHERE shortcode_id = %d ORDER BY created_at DESC, id DESC', $shortcode_id );
696
697 return $wpdb->get_results( $sql, ARRAY_A );
698 }
699
700 /**
701 * Fetch a single revision by its ID
702 *
703 * @param $revision_id
704 *
705 * @return array|null
706 */
707 function sh_cd_db_shortcode_revisions_get_by_id( $revision_id ) {
708
709 global $wpdb;
710
711 $sql = $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE_REVISIONS . ' WHERE id = %d', $revision_id );
712
713 return $wpdb->get_row( $sql, ARRAY_A );
714 }
715
716 /**
717 * Delete all revisions for a given shortcode (e.g. when the shortcode itself is deleted)
718 *
719 * @param $shortcode_id
720 *
721 * @return bool
722 */
723 function sh_cd_db_shortcode_revisions_delete_by_shortcode_id( $shortcode_id ) {
724
725 global $wpdb;
726
727 $result = $wpdb->delete( $wpdb->prefix . SH_CD_TABLE_REVISIONS, [ 'shortcode_id' => $shortcode_id ], [ '%d' ] );
728
729 return ( false !== $result );
730 }
731