PluginProbe
Snippet Shortcodes / 4.2.2
Snippet Shortcodes v4.2.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 / functions.php

functions.php in Snippet Shortcodes 4.2.2, at includes/functions.php

709 lines 15.1 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 * Save / Insert a shortcode
7 *
8 * @return bool
9 */
10 function sh_cd_shortcodes_save_post() {
11
12 // Capture the raw $_POST fields, the save functions will process and validate the data
13 $shortcode = sh_cd_get_values_from_post( [ 'id', 'slug', 'previous_slug', 'data', 'disabled', 'multisite' ] );
14
15 return sh_cd_db_shortcodes_save( $shortcode );
16 }
17
18 /**
19 * Replace user parameters within a shortcode e.g. look for %%parameter%% and replace
20 *
21 * @param $shortcode
22 * @param $user_defined_parameters
23 *
24 * @return mixed
25 */
26 function sh_cd_apply_user_defined_parameters( $shortcode, $user_defined_parameters ){
27
28 // Ensure we have something to do!
29 if ( true === empty( $user_defined_parameters ) || false === is_array( $user_defined_parameters ) ) {
30 return $shortcode;
31 }
32
33 foreach ( $user_defined_parameters as $key => $value ) {
34 $shortcode = str_replace( '%%' . $key . '%%', $value, $shortcode );
35 }
36
37 return $shortcode;
38 }
39
40 /**
41 * Generate a unique slug
42 *
43 * @param $slug
44 *
45 * @return string
46 */
47 function sh_cd_slug_generate( $slug, $exising_id = NULL ) {
48
49 if ( true === empty( $slug ) ) {
50 return NULL;
51 }
52
53 $slug = sanitize_title( $slug );
54
55 $original_slug = $slug;
56
57 $try = 1;
58
59 // Ensure the slug is unique
60 while ( false === sh_cd_slug_is_unique( $slug, $exising_id ) ) {
61
62 $slug = sprintf( '%s_%d', $original_slug, $try );
63
64 $try++;
65 }
66
67 return $slug;
68 }
69
70 /**
71 * Clone an existing shortcode!
72 *
73 * @param $id
74 *
75 * @return bool
76 */
77 function sh_cd_clone( $id ) {
78
79 if( false === SH_CD_IS_PREMIUM ) {
80 return true;
81 }
82
83 if ( false === is_numeric( $id ) ) {
84 return false;
85 }
86
87 $to_be_cloned = sh_cd_db_shortcodes_by_id( $id );
88
89 if ( true === empty( $to_be_cloned ) ) {
90 return false;
91 }
92
93 unset( $to_be_cloned['id'] );
94
95 return sh_cd_db_shortcodes_save( $to_be_cloned );
96 }
97
98 /**
99 * Display message in admin UI
100 *
101 * @param $text
102 * @param bool $error
103 */
104 function sh_cd_message_display( $text, $error = false ) {
105
106 if ( true === empty( $text ) ) {
107 return;
108 }
109
110 printf( '<div class="%s"><p>%s</p></div>',
111 true === $error ? 'error' : 'updated',
112 esc_html( $text )
113 );
114
115 //TODO: Hook this to use admin_notices
116 }
117
118 /**
119 * Fetch cache item
120 *
121 * @param $key
122 *
123 * @return mixed
124 */
125 function sh_cd_cache_get( $key ) {
126
127 $key = sh_cd_cache_generate_key( $key );
128
129 return get_transient( $key );
130 }
131
132 /**
133 * Set cache item
134 *
135 * @param $key
136 * @param $data
137 */
138 function sh_cd_cache_set( $key, $data, $expire = NULL ) {
139
140
141 $expire = ( false === empty( $expire ) ) ? (int) $expire : 1 * HOUR_IN_SECONDS;
142
143 $key = sh_cd_cache_generate_key( $key );
144
145 set_transient( $key, $data, $expire );
146 }
147
148 /**
149 * Delete cache for given shortcode slug / ID
150 *
151 * @param $slug_or_key
152 */
153 function sh_cd_cache_delete_by_slug_or_key( $slug_or_key ) {
154
155 if ( true === is_numeric( $slug_or_key ) ) {
156
157 $slug_or_key = sh_cd_db_shortcodes_get_slug_by_id( $slug_or_key );
158
159 sh_cd_cache_delete( $slug_or_key );
160
161 } else {
162 sh_cd_cache_delete( $slug_or_key );
163 }
164
165 // Delete site option
166 $slug_or_key = SH_CD_PREFIX . $slug_or_key;
167
168 delete_site_option( $slug_or_key );
169
170 }
171
172 /**
173 * Delete cache item
174 *
175 * @param $key
176 *
177 * @return mixed
178 */
179 function sh_cd_cache_delete( $key ) {
180
181 $key = sh_cd_cache_generate_key( $key );
182
183 return delete_transient( $key );
184 }
185
186 /**
187 * Generate cache key
188 *
189 * @param $key
190 *
191 * @return string
192 */
193 function sh_cd_cache_generate_key( $key ) {
194 return SH_CD_SHORTCODE . SH_CD_PLUGIN_VERSION . $key;
195 }
196
197 /**
198 * Return link to list own shortcodes
199 *
200 * @return mixed
201 */
202 function sh_cd_link_your_shortcodes() {
203
204 $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes');
205
206 return esc_url( $link );
207 }
208
209 /**
210 * Return link to add own shortcode
211 *
212 * @return mixed
213 */
214 function sh_cd_link_your_shortcodes_add() {
215
216 $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=add');
217
218 return esc_url( $link );
219 }
220
221 /**
222 * Return link to edit own shortcode
223 *
224 * @return mixed
225 */
226 function sh_cd_link_your_shortcodes_edit( $id ) {
227
228 $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=edit&id=' . (int) $id );
229
230 return esc_url( $link );
231 }
232
233 /**
234 * Return link to delete own shortcode
235 *
236 * @param $id
237 * @return mixed
238 */
239 function sh_cd_link_your_shortcodes_delete( $id ) {
240
241 $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=delete&id=' . (int) $id );
242
243 return esc_url( $link );
244 }
245
246 /**
247 * Either fetch data from the $_POST object or from the array passed in!
248 *
249 * @param $object
250 * @param $key
251 * @return string
252 */
253 function sh_cd_get_value_from_post_or_obj( $object, $key ) {
254
255 if ( true === isset( $_POST[ $key ] ) ) {
256 return $_POST[ $key ];
257 }
258
259 if ( true === isset( $object[ $key ] ) ) {
260 return $object[ $key ];
261 }
262
263 return '';
264 }
265
266 /**
267 * Either fetch data from the $_POST object for the given object keys
268 *
269 * @param $keys
270 * @return array
271 */
272 function sh_cd_get_values_from_post( $keys ) {
273
274 $data = [];
275
276 foreach ( $keys as $key ) {
277
278 if ( true === isset( $_POST[ $key ] ) ) {
279 $data[ $key ] = $_POST[ $key ];
280 } else {
281 $data[ $key ] = '';
282 }
283
284 }
285
286 return $data;
287 }
288
289 /**
290 * Toggle the status of a shortcode
291 *
292 * @param $id
293 */
294 function sh_cd_toggle_status( $id ) {
295
296 $slug = sh_cd_db_shortcodes_by_id( (int) $id );
297
298 if ( false === empty( $slug ) ) {
299
300 $status = ( 1 === (int) $slug['disabled'] ) ? 0 : 1 ;
301
302 sh_cd_db_shortcodes_update_status( $id, $status );
303
304 return $status;
305 }
306
307 return NULL;
308 }
309
310 /**
311 * Toggle the multisite of a shortcode
312 *
313 * @param $id
314 * @return int|null
315 */
316 function sh_cd_toggle_multisite( $id ) {
317
318 $slug = sh_cd_db_shortcodes_by_id( (int) $id );
319
320 if ( false === empty( $slug ) ) {
321
322 $multisite = ( 1 === (int) $slug['multisite'] ) ? 0 : 1 ;
323
324 sh_cd_db_shortcodes_update_multisite( $id, $multisite );
325
326 return $multisite;
327 }
328
329 return NULL;
330 }
331
332
333 /**
334 * Display a table of premade shortcodes
335 *
336 * @param string $display
337 * @return string
338 */
339 function sh_cd_display_premade_shortcodes( $display = 'all' ) {
340
341 $premium_user = SH_CD_IS_PREMIUM;
342 $upgrade_link = sprintf( '<a class="button" href="%1$s"><i class="fas fa-check"></i> %2$s</a>', sh_cd_license_upgrade_link(), __('Upgrade now', SH_CD_SLUG ) );
343
344 switch ( $display ) {
345 case 'free':
346 $shortcodes = sh_cd_shortcode_presets_free_list();
347 $show_premium_col = false;
348 break;
349 case 'premium':
350 $shortcodes = sh_cd_shortcode_presets_premium_list();
351 $show_premium_col = false;
352 break;
353 default:
354 $shortcodes = sh_cd_presets_both_lists();
355 $show_premium_col = true;
356 }
357
358 $html = sprintf('<table class="widefat sh-cd-table" width="100%%">
359 <tr class="row-title">
360 <th class="row-title" width="30%%">%s</th>', __('Shortcode', SH_CD_SLUG ) );
361
362 if ( true === $show_premium_col) {
363 $html .= sprintf( '<th class="row-title">%s</th>', __('Premium', SH_CD_SLUG ) );
364 }
365
366 $html .= sprintf( '<th width="*">%s</th>
367 </tr>', __('Description', SH_CD_SLUG ) );
368
369 $class = '';
370
371 foreach ( $shortcodes as $key => $data ) {
372
373 $class = ($class == 'alternate') ? '' : 'alternate';
374
375 $shortcode = '[' . SH_CD_SHORTCODE. ' slug="' . $key . '"]';
376
377 $premium_shortcode = ( true === isset( $data['premium'] ) && true === $data['premium'] );
378
379 $html .= sprintf( '<tr class="%s"><td>%s</td>', $class, esc_html( $shortcode ) );
380
381
382 if ( true === $show_premium_col) {
383
384 $html .= sprintf( '<td align="middle">%s%s</td>',
385 ( true === $premium_shortcode && true === $premium_user ) ? '<i class="fas fa-check"></i>' : '',
386 ( true == $premium_shortcode && false === $premium_user ) ? $upgrade_link : ''
387 );
388 }
389
390 $html .= sprintf( '<td>%s</td></tr>', wp_kses_post( $data['description'] ) );
391
392 }
393
394 $html .= '</table>';
395
396 return $html;
397 }
398
399 /**
400 * Display an upgrade button
401 *
402 * @param string $css_class
403 * @param null $link
404 */
405 function sh_cd_upgrade_button( $css_class = '', $link = NULL ) {
406
407 $link = ( false === empty( $link ) ) ? $link : SH_CD_UPGRADE_LINK . '?hash=' . sh_cd_generate_site_hash() ;
408
409 echo sprintf('<a href="%s" class="button-primary sh-cd-upgrade-button%s"><i class="far fa-credit-card"></i> %s £%s %s</a>',
410 esc_url( $link ),
411 esc_attr( ' ' . $css_class ),
412 __( 'Upgrade to Premium for ', SH_CD_SLUG ),
413 esc_html( sh_cd_license_price() ),
414 __( 'a year ', SH_CD_SLUG )
415 );
416 }
417
418 /**
419 * Is multsite functionality active for this install?
420 *
421 * @return bool
422 */
423 function sh_cd_is_multisite_enabled() {
424
425 if ( false === is_multisite() ) {
426 return false;
427 }
428
429 if ( false === SH_CD_IS_PREMIUM ) {
430 return false;
431 }
432
433 return true;
434 }
435
436 /**
437 * Fetch all multisite slugs
438 *
439 * @return array|null
440 */
441 function sh_cd_multisite_slugs() {
442
443 if ( false === is_multisite() ) {
444 return [];
445 }
446
447 $cache = sh_cd_cache_get( 'sh-cd-multisite-slugs' );
448
449 if ( false !== $cache ) {
450 return $cache;
451 }
452
453 $slugs = sh_cd_db_shortcodes_multisite_slugs();
454
455 $slugs = ( false === empty( $slugs ) ) ? wp_list_pluck( $slugs, 'slug' ) : [];
456
457 // Cache this for a short time
458 sh_cd_cache_set( 'sh-cd-multisite-slugs', $slugs, 30 );
459
460 return ( true === is_array( $slugs ) ) ? $slugs : [];
461 }
462
463 /**
464 * Have we reached the limit of free shortcodes?
465 * @return bool
466 */
467 function sh_cd_reached_free_limit() {
468
469 if ( true === SH_CD_IS_PREMIUM ) {
470 return false;
471 }
472
473 $existing_shortcodes = sh_cd_db_shortcodes_count();
474
475 if ( true === empty( $existing_shortcodes ) ) {
476 return false;
477 }
478
479 return ( (int) $existing_shortcodes >= SH_CD_FREE_SHORTCODE_LIMIT );
480 }
481
482 /**
483 * Get the minimum user role allowed for viewing data pages in admin
484 * @return mixed|void
485 */
486 function sh_cd_permission_role() {
487
488 // If not premium, then admin only
489 if ( false === SH_CD_IS_PREMIUM ) {
490 return 'manage_options';
491 }
492
493 $permission_role = get_option( 'sh-cd-edit-permissions', 'manage_options' );
494
495 return ( false === empty( $permission_role ) ) ? $permission_role : 'manage_options';
496 }
497
498 /**
499 * Does the user have the correct permissions to view this page?
500 */
501 function sh_cd_permission_check() {
502
503 $allowed_viewer = sh_cd_permission_role();
504
505 if ( false === current_user_can( $allowed_viewer ) ) {
506 wp_die( __( 'You do not have sufficient permissions to access this page.', SH_CD_SLUG ) );
507 }
508 }
509
510 /**
511 * Is the shortcode [sv slug="sc-db-value-by-id"] enabled
512 * @return bool (default false)
513 */
514 function sh_cd_is_shortcode_db_value_by_id_enabled() {
515
516 if ( false === SH_CD_IS_PREMIUM ) {
517 return false;
518 }
519
520 // Disabling by filter overrides the setting in WP admin
521 if ( true === apply_filters( 'disable-ss-sc-db-value-by-id', __return_false() ) ) {
522 return false;
523 }
524
525 $value = get_option( 'sh-cd-shortcode-db-value-by-id-enabled', false );
526
527 return sh_cd_to_bool( $value );
528 }
529
530 /**
531 * Display upgrade notice
532 *
533 * @param bool $pro_plus
534 */
535 function sh_cd_display_pro_upgrade_notice( ) {
536 ?>
537
538 <div class="postbox sh-cd-advertise-premium">
539 <h3 class="hndle"><span><?php echo __( 'Upgrade Snippet Shortcodes and get more features!', SH_CD_SLUG ); ?> </span></h3>
540 <div style="padding: 0px 15px 0px 15px">
541 <p><a href="<?php echo esc_url( admin_url('admin.php?page=sh-cd-shortcode-variables-license') ); ?>" class="button-primary"><?php echo __( 'Upgrade now', SH_CD_SLUG ); ?></a></p>
542 </div>
543 </div>
544
545 <?php
546 }
547
548
549 /**
550 * Process a CSV attachment and import into database
551 *
552 * @param $attachment_id
553 *
554 * @param bool $dry_run
555 *
556 * @return string
557 */
558 function sh_cd_import_csv( $attachment_id, $dry_run = true ) {
559
560 if ( false === sh_cd_permission_check() ) {
561 return 'You do not have the correct admin permissions';
562 }
563
564 if ( false === SH_CD_IS_PREMIUM ) {
565 return 'This is a premium feature';
566 }
567
568 $csv_path = get_attached_file( $attachment_id );
569 $admin_id = get_current_user_id();
570
571 if ( true === empty( $csv_path ) || false === file_exists( $csv_path )) {
572 return 'Error: Error loading CSV from disk.';
573 }
574
575 $csv = array_map('str_getcsv', file( $csv_path ) );
576
577 if ( true === empty( $csv ) ) {
578 return 'Error: The CSV appears to be empty.';
579 }
580
581 array_walk($csv, function(&$a) use ($csv) {
582 $a = array_combine($csv[0], $a);
583 });
584
585 $validate_header_result = sh_cd_import_csv_validate_header( $csv[0] );
586
587 if ( true !== $validate_header_result ) {
588 return $validate_header_result;
589 }
590
591 array_shift($csv );
592
593 if ( true === empty( $csv ) ) {
594 return 'Error: The CSV appears to be empty (when header hs been removed).';
595 }
596
597 $errors = 0;
598
599 $output = sprintf( '%d rows to process...' . PHP_EOL, count( $csv ) );
600
601 if ( true === $dry_run ) {
602 $output .= 'DRY RUN MODE! No data will be imported.' . PHP_EOL;
603 }
604
605 foreach ( $csv as $row ) {
606
607 if ( $errors >= 50 ) {
608 $output .= 'Aborted! More than 50 errors have been detected in this file.' . PHP_EOL;
609 break;
610 }
611
612 $row = array_change_key_case( $row ); // Force CSV headers to lowercase
613
614 $validation_result = sh_cd_import_csv_validate_row( $row );
615
616 // Validate a row before proceeding
617 if ( true !== $validation_result ) {
618 $output .= $validation_result . PHP_EOL;
619 $errors++;
620 continue;
621 }
622
623 if ( false === $dry_run ) {
624
625 $shortcode = [ 'slug' => $row[ 'slug' ],
626 'previous_slug' => '',
627 'data' => $row[ 'content' ],
628 'disabled' => ! sh_cd_to_bool( $row[ 'enabled' ] ),
629 'multisite' => sh_cd_to_bool( $row[ 'global' ] )
630 ];
631
632 $result = sh_cd_db_shortcodes_save( $shortcode );
633
634 if ( false === $result ) {
635 $output .= 'Skipped: Error inserting into database (most likely a field contains too many characters or in the wrong format): ' . implode( ',', $row ) . PHP_EOL;
636 }
637 }
638
639 }
640
641 if ( $errors > 0 ) {
642 $output .= sprintf( '%d errors were detected and the rows skipped.' . PHP_EOL, $errors );
643 }
644
645 $output .= 'Completed.';
646
647 return $output;
648
649 }
650
651 /**
652 * Verify header row
653 * @param $header_row
654 *
655 * @return bool|string
656 */
657 function sh_cd_import_csv_validate_header( $header_row ) {
658
659 $expected_headers = [ 'slug', 'content', 'global', 'enabled' ];
660
661 foreach ( $expected_headers as $column ) {
662
663 if ( false === isset( $header_row[ $column ] ) ) {
664 return 'Missing column: ' . $column . '. Expecting: ' . implode( ',', $expected_headers ) . PHP_EOL;
665 }
666 }
667
668 return true;
669 }
670
671 /**
672 * Validate CSV row
673 * @param $csv_row
674 *
675 * @return bool|string
676 */
677 function sh_cd_import_csv_validate_row( $csv_row ) {
678
679 if ( true === empty( $csv_row[ 'slug' ] ) ) {
680 return 'Skipped: Missing slug: ' . implode( ',', $csv_row );
681 }
682
683 if ( false === empty( $isset[ 'content' ] ) ) {
684 return 'Skipped: Content: ' . implode( ',', $csv_row );
685 }
686
687 $allowed_bools = [ 'yes', 'no', 'true', 'false', '1', '0' ];
688
689 if ( true === empty( $csv_row[ 'global' ] ) ||
690 false === in_array( $csv_row[ 'global' ], $allowed_bools ) ) {
691 return 'Skipped: Invalid "global" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
692 }
693
694 if ( true === empty( $csv_row[ 'enabled' ] ) ||
695 false === in_array( $csv_row[ 'enabled' ], $allowed_bools ) ) {
696 return 'Skipped: Invalid "enabled" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
697 }
698
699 return true;
700 }
701
702 /**
703 * Convert string to bool
704 * @param $string
705 * @return mixed
706 */
707 function sh_cd_to_bool( $string ) {
708 return filter_var( $string, FILTER_VALIDATE_BOOLEAN );
709 }