PluginProbe
Snippet Shortcodes / trunk
Snippet Shortcodes vtrunk
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
← All changes | includes/db.php +730 -292 2.0trunk View file →
@@ -1,292 +1,730 @@
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 - data text,
20 - disabled bit default 0,
21 - UNIQUE KEY id (id)
22 - ) $charset_collate;";
23 -
24 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
25 -
26 - dbDelta( $sql );
27 -}
28 -
29 -/**
30 - * Fetch all Shortcodes
31 - *
32 - * @return bool
33 - */
34 -function sh_cd_db_shortcodes_all() {
35 -
36 - global $wpdb;
37 -
38 - return $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' order by slug asc', ARRAY_A );
39 -}
40 -
41 -/**
42 - * Fetch a shortcode by ID (mainly used for quick lookups in admin)
43 - *
44 - * @param $id
45 - *
46 - * @return mixed
47 - */
48 -function sh_cd_db_shortcodes_by_id( $id ) {
49 -
50 - global $wpdb;
51 -
52 - $sql = $wpdb->prepare('SELECT id, slug, data, disabled FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
53 -
54 - return $wpdb->get_row( $sql, ARRAY_A );
55 -}
56 -
57 -/**
58 - * Fetch the content of the shortcode by slug
59 - *
60 - * @param $slug
61 - *
62 - * @return null|string
63 - */
64 -function sh_cd_db_shortcodes_by_slug( $slug ) {
65 -
66 - global $wpdb;
67 -
68 - $sql = $wpdb->prepare('SELECT data FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s and disabled <> 1', $slug);
69 -
70 - $row = $wpdb->get_var( $sql );
71 -
72 - return ( false === empty( $row ) ? stripslashes( $row ) : NULL );
73 -}
74 -
75 -/**
76 - * Get a Shortcode's slug from the slug ID
77 - *
78 - * @param $id
79 - *
80 - * @return bool
81 - */
82 -function sh_cd_db_shortcodes_get_slug_by_id( $id ) {
83 -
84 - global $wpdb;
85 -
86 - $sql = $wpdb->prepare('SELECT slug FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
87 -
88 - return $wpdb->get_var( $sql );
89 -}
90 -
91 -/**
92 - * Save / Insert a shortcode
93 - *
94 - * @param $shortcode
95 - *
96 - * @return bool
97 - */
98 -function sh_cd_db_shortcodes_save( $shortcode ) {
99 -
100 - if ( false === is_admin() ) {
101 - return false;
102 - }
103 -
104 - $shortcode = wp_parse_args( $shortcode, [
105 - 'id' => NULL,
106 - 'slug' => NULL,
107 - 'data' => NULL,
108 - 'disabled' => 0
109 - ]);
110 -
111 - // We need either a slug or an ID
112 - if ( true === empty( $shortcode['slug'] ) && true === empty( $shortcode['id'] ) ) {
113 - return false;
114 - }
115 -
116 - $shortcode['disabled'] = (int) $shortcode['disabled'];
117 -
118 - global $wpdb;
119 -
120 - $result = false;
121 -
122 - // Updating an existing shortcode?
123 - if ( false === empty( $shortcode['id'] ) && true === is_numeric( $shortcode['id'] ) ){
124 -
125 - // Once set, a slug cannot be updated.
126 - unset( $shortcode['slug'] );
127 -
128 - $formats = sh_cd_db_get_formats( $shortcode );
129 -
130 - $result = $wpdb->update(
131 - $wpdb->prefix . SH_CD_TABLE,
132 - $shortcode,
133 - [ 'id' => $shortcode['id'] ],
134 - $formats,
135 - [ '%d' ]
136 - );
137 -
138 - sh_cd_cache_delete_by_slug_or_key( $shortcode['id'] );
139 -
140 - // Adding a new shortcode
141 - } else {
142 -
143 - unset( $shortcode['id'] );
144 -
145 - // Ensure slug is santised and unique
146 - $shortcode['slug'] = sh_cd_slug_generate( $shortcode['slug'] );
147 -
148 - $formats = sh_cd_db_get_formats( $shortcode );
149 -
150 - $result = $wpdb->insert(
151 - $wpdb->prefix . SH_CD_TABLE,
152 - $shortcode,
153 - $formats
154 - );
155 -
156 - // It's an insert, so there should be no cache... however, just a wee sanity check in case
157 - // a shortcode with the same slug previously exists.
158 - sh_cd_cache_delete_by_slug_or_key( $shortcode['slug'] );
159 - }
160 -
161 - return ( false !== $result );
162 -}
163 -
164 -/**
165 - * Update a shortcode's status
166 - *
167 - * @param $shortcode
168 - *
169 - * @return bool
170 - */
171 -function sh_cd_db_shortcodes_update_status( $id, $status ) {
172 -
173 - if ( false === is_admin() ) {
174 - return false;
175 - }
176 -
177 - global $wpdb;
178 -
179 - $result = $wpdb->update(
180 - $wpdb->prefix . SH_CD_TABLE,
181 - [ 'disabled' => $status ],
182 - [ 'id' => $id ],
183 - [ '%d' ],
184 - [ '%d' ]
185 - );
186 -
187 - sh_cd_cache_delete_by_slug_or_key( $id );
188 -
189 - return ( false !== $result );
190 -}
191 -
192 -/**
193 - * Update a shortcode's content
194 - *
195 - * @param $shortcode
196 - *
197 - * @return bool
198 - */
199 -function sh_cd_db_shortcodes_update_content( $id, $data ) {
200 -
201 - if ( false === is_admin() ) {
202 - return false;
203 - }
204 -
205 - global $wpdb;
206 -
207 - $result = $wpdb->update(
208 - $wpdb->prefix . SH_CD_TABLE,
209 - [ 'data' => $data ],
210 - [ 'id' => $id ],
211 - [ '%s' ],
212 - [ '%d' ]
213 - );
214 -
215 - sh_cd_cache_delete_by_slug_or_key( $id );
216 -
217 - return ( false !== $result );
218 -}
219 -
220 -
221 -/**
222 - * Delete a shortcode
223 - *
224 - * @param $id
225 - *
226 - * @return bool
227 - */
228 -function sh_cd_db_shortcodes_delete( $id ) {
229 -
230 - if ( false === is_admin() || false === is_numeric( $id ) ) {
231 - return false;
232 - }
233 -
234 - global $wpdb;
235 -
236 - // Clear cached version
237 - sh_cd_cache_delete_by_slug_or_key( $id );
238 -
239 - $result = $wpdb->delete( $wpdb->prefix . SH_CD_TABLE, [ 'id' => $id ], [ '%d' ] );
240 -
241 - return ( false !== $result );
242 -}
243 -
244 -/**
245 - * For a given key value array, look up and return the expected MySQL data formats.
246 - *
247 - * @param $data
248 - *
249 - * @return array
250 - */
251 -function sh_cd_db_get_formats( $data ) {
252 -
253 - $lookup = [
254 - 'id' => '%d',
255 - 'slug' => '%s',
256 - 'data' => '%s',
257 - 'disabled' => '%d'
258 - ];
259 -
260 - $formats = [];
261 -
262 - foreach ( $data as $key => $value ) {
263 -
264 - if ( false === empty( $lookup[ $key ] ) ) {
265 - $formats[] = $lookup[ $key ];
266 - }
267 - }
268 -
269 - return $formats;
270 -}
271 -
272 -/**
273 - * Check if the slug already exists
274 - *
275 - * @param $slug
276 - *
277 - * @return bool
278 - */
279 -function sh_cd_slug_is_unique( $slug ) {
280 -
281 - if ( true === empty( $slug ) ) {
282 - return false;
283 - }
284 -
285 - global $wpdb;
286 -
287 - $sql = $wpdb->prepare( 'SELECT count(slug) FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s', $slug );
288 -
289 - $row = $wpdb->get_var( $sql );
290 -
291 - return ( empty( $row ) );
292 -}
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 +}