PluginProbe
Snippet Shortcodes / 4.0
Snippet Shortcodes v4.0
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/functions.php +110 -427 trunk4.0 View file →
@@ -2,48 +2,8 @@
2 2
3 3 defined('ABSPATH') or die('Jog on!');
4 4
5 5 /**
6 - * Is the Premium plugin enabled and do we have a valid license?
7 - *
8 - * @return bool
9 - */
10 -function sh_cd_is_premium() {
11 -
12 - if ( false === sh_cd_is_premium_plugin_activated() ) {
13 - return false;
14 - }
15 -
16 - return apply_filters( 'sh-cd-license-is-premium', false );
17 -}
18 -
19 -/**
20 - * Is Premium plugin enabled?
21 - */
22 -function sh_cd_is_premium_plugin_activated() {
23 - return defined( 'YK_SS_PLUGIN_NAME' );
24 -}
25 -
26 -/**
27 - * Generate a site hash to identify this site.
28 - **/
29 -function sh_cd_generate_site_hash() {
30 -
31 - $site_hash = get_option( 'sh-cd-hash' );
32 -
33 - // Generate a basic site key from URL and plugin slug
34 - if( false == $site_hash ) {
35 -
36 - $site_hash = md5( 'yeken-sh-cd-' . site_url() );
37 - $site_hash = substr( $site_hash, 0, 6 );
38 -
39 - update_option( 'sh-cd-hash', $site_hash );
40 -
41 - }
42 - return $site_hash;
43 -}
44 -
45 -/**
46 6 * Save / Insert a shortcode
47 7 *
48 8 * @return bool
49 9 */
@@ -48,18 +8,11 @@
48 8 * @return bool
49 9 */
50 10 function sh_cd_shortcodes_save_post() {
51 11
52 - $fields = apply_filters( 'sh-cd-post-field-keys', [ 'id', 'slug', 'previous_slug', 'data', 'disabled', 'multisite', 'editor' ] );
53 -
54 12 // Capture the raw $_POST fields, the save functions will process and validate the data
55 - $shortcode = sh_cd_get_values_from_post( $fields );
13 + $shortcode = sh_cd_get_values_from_post( [ 'id', 'slug', 'previous_slug', 'data', 'disabled', 'multisite' ] );
56 14
57 - // If we are not premium, then the user is not allowed to change the site slug (otherwise they could just re-use variables and by pass the limit)
58 - if ( ! sh_cd_is_premium() && false === empty( $shortcode[ 'previous_slug' ] ) ) {
59 - $shortcode[ 'slug' ] = $shortcode[ 'previous_slug' ];
60 - }
61 -
62 15 return sh_cd_db_shortcodes_save( $shortcode );
63 16 }
64 17
65 18 /**
@@ -64,12 +17,8 @@
64 17
65 18 /**
66 19 * Replace user parameters within a shortcode e.g. look for %%parameter%% and replace
67 20 *
68 - * Values landing inside a URL-bearing attribute (href, src, action, etc.) are escaped
69 - * with esc_url() rather than esc_attr(), so a value such as "javascript:alert(1)" can't
70 - * be substituted straight into a link - esc_attr() alone doesn't strip dangerous schemes.
71 - *
72 21 * @param $shortcode
73 22 * @param $user_defined_parameters
74 23 *
75 24 * @return mixed
@@ -80,31 +29,10 @@
80 29 if ( true === empty( $user_defined_parameters ) || false === is_array( $user_defined_parameters ) ) {
81 30 return $shortcode;
82 31 }
83 32
84 - // HTML attributes whose value is a URL - substitutions landing inside one of these get esc_url() instead of esc_attr().
85 - $url_attributes = apply_filters( 'sh-cd-url-attributes', [ 'href', 'src', 'action', 'formaction', 'cite', 'background', 'poster', 'longdesc', 'usemap' ] );
86 -
87 33 foreach ( $user_defined_parameters as $key => $value ) {
88 -
89 - $placeholder = '%%' . $key . '%%';
90 -
91 - if ( false === strpos( $shortcode, $placeholder ) ) {
92 - continue;
93 - }
94 -
95 - // First, swap in any occurrence sitting inside a URL attribute value, escaped with esc_url().
96 - $shortcode = preg_replace_callback(
97 - '/(?<![\w-])(' . implode( '|', $url_attributes ) . ')(\s*=\s*)("|\')((?:(?!\3).)*)\3/i',
98 - function( $matches ) use ( $placeholder, $value ) {
99 - $attribute_value = str_replace( $placeholder, esc_url( $value ), $matches[4] );
100 - return $matches[1] . $matches[2] . $matches[3] . $attribute_value . $matches[3];
101 - },
102 - $shortcode
103 - );
104 -
105 - // Anything left over (i.e. not inside a URL attribute) is a normal attribute/text substitution.
106 - $shortcode = str_replace( $placeholder, esc_attr( $value ), $shortcode );
34 + $shortcode = str_replace( '%%' . $key . '%%', $value, $shortcode );
107 35 }
108 36
109 37 return $shortcode;
110 38 }
@@ -121,9 +49,9 @@
121 49 if ( true === empty( $slug ) ) {
122 50 return NULL;
123 51 }
124 52
125 - $slug = sanitize_key( $slug );
53 + $slug = sanitize_title( $slug );
126 54
127 55 $original_slug = $slug;
128 56
129 57 $try = 1;
@@ -147,9 +75,9 @@
147 75 * @return bool
148 76 */
149 77 function sh_cd_clone( $id ) {
150 78
151 - if( false === sh_cd_is_premium() ) {
79 + if( false === SH_CD_IS_PREMIUM ) {
152 80 return true;
153 81 }
154 82
155 83 if ( false === is_numeric( $id ) ) {
@@ -214,10 +142,8 @@
214 142
215 143 $key = sh_cd_cache_generate_key( $key );
216 144
217 145 set_transient( $key, $data, $expire );
218 -
219 - do_action( 'sh-cd-global-cache-delete' );
220 146 }
221 147
222 148 /**
223 149 * Delete cache for given shortcode slug / ID
@@ -249,20 +175,15 @@
249 175 * @param $key
250 176 *
251 177 * @return mixed
252 178 */
253 -function sh_cd_cache_delete( $key, $trigger_global_hook = true ) {
179 +function sh_cd_cache_delete( $key ) {
254 180
255 181 $key = sh_cd_cache_generate_key( $key );
256 182
257 - if ( true === $trigger_global_hook ) {
258 - do_action( 'sh-cd-global-cache-delete' );
259 - }
260 -
261 183 return delete_transient( $key );
262 184 }
263 185
264 -
265 186 /**
266 187 * Generate cache key
267 188 *
268 189 * @param $key
@@ -309,8 +230,21 @@
309 230 return esc_url( $link );
310 231 }
311 232
312 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 +/**
313 247 * Either fetch data from the $_POST object or from the array passed in!
314 248 *
315 249 * @param $object
316 250 * @param $key
@@ -394,27 +328,73 @@
394 328
395 329 return NULL;
396 330 }
397 331
332 +
398 333 /**
399 - * Display an upgrade button
334 + * Display a table of premade shortcodes
400 335 *
401 - * @param string $css_class
402 - * @param null $link
336 + * @param string $display
337 + * @return string
403 338 */
404 -function sh_cd_upgrade_button( $css_class = '', $link = NULL ) {
339 +function sh_cd_display_premade_shortcodes( $display = 'all' ) {
405 340
406 - $link = ( false === empty( $link ) ) ? $link : SH_CD_UPGRADE_LINK . '?hash=' . sh_cd_generate_site_hash() ;
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 ) );
407 343
408 - $price = sh_cd_license_price();
409 - $price = ( false === empty( $price ) ) ? sprintf( '- £%s %s', $price, __( 'a year ', SH_CD_SLUG ) ) : '';
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 + }
410 357
411 - echo sprintf('<a href="%s" class="button-primary sh-cd-upgrade-button sh-cd-button %s"><i class="far fa-star"></i> %s %s</a>',
412 - esc_url( $link ),
413 - esc_attr( ' ' . $css_class ),
414 - __( 'Purchase a license ', SH_CD_SLUG ),
415 - $price
416 - );
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;
417 397 }
418 398
419 399 /**
420 400 * Display an upgrade button
@@ -421,22 +401,19 @@
421 401 *
422 402 * @param string $css_class
423 403 * @param null $link
424 404 */
425 -function sh_cd_premium_shortcode_download( $return = false ) {
405 +function sh_cd_upgrade_button( $css_class = '', $link = NULL ) {
426 406
427 - $link = SH_CD_GET_PREMIUM_LINK . '?hash=' . sh_cd_generate_site_hash();
407 + $link = ( false === empty( $link ) ) ? $link : SH_CD_UPGRADE_LINK . '?hash=' . sh_cd_generate_site_hash() ;
428 408
429 - $html = sprintf('<a href="%s" class="button-primary sh-cd-button sh-cd-upgrade-button"><i class="fas fa-download"></i> %s</a>',
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>',
430 410 esc_url( $link ),
431 - __( 'Download Premium Plugin', SH_CD_SLUG )
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 )
432 415 );
433 -
434 - if ( true === $return ) {
435 - return $html;
436 - }
437 -
438 - echo $html;
439 416 }
440 417
441 418 /**
442 419 * Is multsite functionality active for this install?
@@ -444,17 +421,13 @@
444 421 * @return bool
445 422 */
446 423 function sh_cd_is_multisite_enabled() {
447 424
448 - if ( true === defined( 'YK_TEST_IS_MULTISITE' ) && true === YK_TEST_IS_MULTISITE ) {
449 - return true;
450 - }
451 -
452 425 if ( false === is_multisite() ) {
453 426 return false;
454 427 }
455 428
456 - if ( false === sh_cd_is_premium() ) {
429 + if ( false === SH_CD_IS_PREMIUM ) {
457 430 return false;
458 431 }
459 432
460 433 return true;
@@ -478,9 +451,9 @@
478 451 }
479 452
480 453 $slugs = sh_cd_db_shortcodes_multisite_slugs();
481 454
482 - $slugs = ( false === empty( $slugs ) ) ? wp_list_pluck( $slugs, 'slug' ) : [];
455 + $slugs = ( false === empty( $slugs ) ) ? wp_list_pluck( $slugs, 'slug' ) : NULL;
483 456
484 457 // Cache this for a short time
485 458 sh_cd_cache_set( 'sh-cd-multisite-slugs', $slugs, 30 );
486 459
@@ -492,9 +465,9 @@
492 465 * @return bool
493 466 */
494 467 function sh_cd_reached_free_limit() {
495 468
496 - if ( true === sh_cd_is_premium() ) {
469 + if ( true === SH_CD_IS_PREMIUM ) {
497 470 return false;
498 471 }
499 472
500 473 $existing_shortcodes = sh_cd_db_shortcodes_count();
@@ -502,19 +475,12 @@
502 475 if ( true === empty( $existing_shortcodes ) ) {
503 476 return false;
504 477 }
505 478
506 - return ( (int) $existing_shortcodes >= sh_cd_get_free_limit() );
479 + return ( (int) $existing_shortcodes >= SH_CD_FREE_SHORTCODE_LIMIT );
507 480 }
508 481
509 482 /**
510 - * Return free limit for shortcodes
511 - */
512 -function sh_cd_get_free_limit() {
513 - return 10;
514 -}
515 -
516 -/**
517 483 * Get the minimum user role allowed for viewing data pages in admin
518 484 * @return mixed|void
519 485 */
520 486 function sh_cd_permission_role() {
@@ -519,9 +485,9 @@
519 485 */
520 486 function sh_cd_permission_role() {
521 487
522 488 // If not premium, then admin only
523 - if ( false === sh_cd_is_premium() ) {
489 + if ( false === SH_CD_IS_PREMIUM ) {
524 490 return 'manage_options';
525 491 }
526 492
527 493 $permission_role = get_option( 'sh-cd-edit-permissions', 'manage_options' );
@@ -541,72 +507,25 @@
541 507 }
542 508 }
543 509
544 510 /**
545 - * Is the shortcode [sv slug="sc-db-value-by-id"] enabled
546 - * @return bool (default false)
547 - */
548 -function sh_cd_is_shortcode_db_value_by_id_enabled() {
549 -
550 - if ( false === sh_cd_is_premium() ) {
551 - return false;
552 - }
553 -
554 - // Disabling by filter overrides the setting in WP admin
555 - if ( true === apply_filters( 'disable-ss-sc-db-value-by-id', __return_false() ) ) {
556 - return false;
557 - }
558 -
559 - $value = get_option( 'sh-cd-shortcode-db-value-by-id-enabled', false );
560 -
561 - return sh_cd_to_bool( $value );
562 -}
563 -
564 -/**
565 511 * Display upgrade notice
566 512 *
567 513 * @param bool $pro_plus
568 514 */
569 -function sh_cd_display_pro_upgrade_notice( $title = NULL, $content = '', $class = '' ) {
570 -
571 - $title = ( true === empty( $title ) ) ? __( 'Upgrade Snippet Shortcodes and get more features!', SH_CD_SLUG ) : $title;
515 +function sh_cd_display_pro_upgrade_notice( ) {
516 + ?>
572 517
573 - ?>
574 - <div class="postbox sh-cd-advertise-premium <?php echo esc_attr( $class ) ?>">
575 - <h3 class="hndle"><i class="fa-regular fa-star"></i> <?php echo esc_html( $title ) ?></h3>
518 + <div class="postbox sh-cd-advertise-premium">
519 + <h3 class="hndle"><span><?php echo __( 'Upgrade Snippet Shortcodes and get more features!', SH_CD_SLUG ); ?> </span></h3>
576 520 <div style="padding: 0px 15px 0px 15px">
577 - <p><?php echo wp_kses( $content, [ 'ul' => [ 'class' ], 'li' => [], 'strong' => [], 'span' => [], 'div' => [] ] ); ?></p>
578 - <p><a href="<?php echo esc_url( admin_url('admin.php?page=sh-cd-shortcode-variables-upgrade') ); ?>" class="button-primary sh-cd-upgrade-button"><i class="fa-regular fa-star"></i> <?php echo __( 'Get Premium', SH_CD_SLUG ); ?></a></p>
521 + <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>
579 522 </div>
580 523 </div>
581 -<?php
582 -}
583 524
584 -/**
585 - * Display a star to prompt for a Premioum upgrade
586 - *
587 - * @param bool $pro_plus
588 - */
589 -function sh_cd_display_premium_star() {
590 -
591 - if ( true === sh_cd_is_premium() ) {
592 - return ''; // We don't want to show the star if the user has already upgraded
593 - }
594 -
595 - return sprintf ('<a href="%s"><i class="fa-regular fa-star"></i></a>',
596 - esc_url( admin_url('admin.php?page=sh-cd-shortcode-variables-upgrade') )
597 - );
525 + <?php
598 526 }
599 -
600 -/**
601 - * Display info symbol with tooltip
602 - */
603 -function sh_cd_display_info_tooltip( $text ) {
604 527
605 - return sprintf ('<i class="fa-regular fa-circle-question sh-cd-tooltip" title="%s">',
606 - esc_html( $text )
607 - );
608 -}
609 528
610 529 /**
611 530 * Process a CSV attachment and import into database
612 531 *
@@ -617,11 +536,13 @@
617 536 * @return string
618 537 */
619 538 function sh_cd_import_csv( $attachment_id, $dry_run = true ) {
620 539
621 - sh_cd_permission_check();
540 + if ( false === sh_cd_permission_check() ) {
541 + return 'You do not have the correct admin permissions';
542 + }
622 543
623 - if ( false === sh_cd_is_premium() ) {
544 + if ( false === SH_CD_IS_PREMIUM ) {
624 545 return 'This is a premium feature';
625 546 }
626 547
627 548 $csv_path = get_attached_file( $attachment_id );
@@ -636,13 +557,8 @@
636 557 if ( true === empty( $csv ) ) {
637 558 return 'Error: The CSV appears to be empty.';
638 559 }
639 560
640 - // Lowercase the header row up front so it's compared consistently against our
641 - // (lowercase) column names both here and per-row below - previously the header row
642 - // was validated case-sensitively while each data row's keys were lowercased.
643 - $csv[0] = array_map( 'strtolower', $csv[0] );
644 -
645 561 array_walk($csv, function(&$a) use ($csv) {
646 562 $a = array_combine($csv[0], $a);
647 563 });
648 564
@@ -685,19 +601,15 @@
685 601 }
686 602
687 603 if ( false === $dry_run ) {
688 604
689 - $shortcode = [ 'previous_slug' => '' ];
605 + $shortcode = [ 'slug' => $row[ 'slug' ],
606 + 'previous_slug' => '',
607 + 'data' => $row[ 'content' ],
608 + 'disabled' => ! sh_cd_to_bool( $row[ 'enabled' ] ),
609 + 'multisite' => sh_cd_to_bool( $row[ 'global' ] )
610 + ];
690 611
691 - foreach ( sh_cd_csv_columns() as $column_name => $column ) {
692 -
693 - if ( false === isset( $row[ $column_name ] ) ) {
694 - continue;
695 - }
696 -
697 - $shortcode = array_merge( $shortcode, call_user_func( $column[ 'import' ], $row[ $column_name ] ) );
698 - }
699 -
700 612 $result = sh_cd_db_shortcodes_save( $shortcode );
701 613
702 614 if ( false === $result ) {
703 615 $output .= 'Skipped: Error inserting into database (most likely a field contains too many characters or in the wrong format): ' . implode( ',', $row ) . PHP_EOL;
@@ -723,16 +635,14 @@
723 635 * @return bool|string
724 636 */
725 637 function sh_cd_import_csv_validate_header( $header_row ) {
726 638
727 - $required_columns = array_keys( array_filter( sh_cd_csv_columns(), function( $column ) {
728 - return true === $column[ 'required' ];
729 - } ) );
639 + $expected_headers = [ 'slug', 'content', 'global', 'enabled' ];
730 640
731 - foreach ( $required_columns as $column ) {
641 + foreach ( $expected_headers as $column ) {
732 642
733 643 if ( false === isset( $header_row[ $column ] ) ) {
734 - return 'Missing column: ' . $column . '. Expecting at least: ' . implode( ',', $required_columns ) . PHP_EOL;
644 + return 'Missing column: ' . $column . '. Expecting: ' . implode( ',', $expected_headers ) . PHP_EOL;
735 645 }
736 646 }
737 647
738 648 return true;
@@ -749,10 +659,10 @@
749 659 if ( true === empty( $csv_row[ 'slug' ] ) ) {
750 660 return 'Skipped: Missing slug: ' . implode( ',', $csv_row );
751 661 }
752 662
753 - if ( true === empty( $csv_row[ 'content' ] ) ) {
754 - return 'Skipped: Missing content: ' . implode( ',', $csv_row );
663 + if ( false === empty( $isset[ 'content' ] ) ) {
664 + return 'Skipped: Content: ' . implode( ',', $csv_row );
755 665 }
756 666
757 667 $allowed_bools = [ 'yes', 'no', 'true', 'false', '1', '0' ];
758 668
@@ -765,70 +675,12 @@
765 675 false === in_array( $csv_row[ 'enabled' ], $allowed_bools ) ) {
766 676 return 'Skipped: Invalid "enabled" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
767 677 }
768 678
769 - // Give any Premium-registered columns a chance to reject their own value, so dry-run
770 - // mode surfaces bad input instead of it being silently coerced later on save.
771 - foreach ( sh_cd_csv_columns() as $column_name => $column ) {
772 -
773 - if ( false === isset( $csv_row[ $column_name ] ) || false === isset( $column[ 'validate' ] ) ) {
774 - continue;
775 - }
776 -
777 - $validation_result = call_user_func( $column[ 'validate' ], $csv_row[ $column_name ] );
778 -
779 - if ( true !== $validation_result ) {
780 - return $validation_result;
781 - }
782 - }
783 -
784 679 return true;
785 680 }
786 681
787 682 /**
788 - * Ordered map of CSV column name => column definition, used by both sh_cd_import_csv() and
789 - * sh_cd_export_csv(). Extensible via the 'sh-cd-csv-columns' filter so Premium can add columns
790 - * for its own fields without core knowing about them - column names must be unique (a later
791 - * registration silently overwrites an earlier one of the same name, same as any other array-shaped
792 - * filter in this plugin).
793 - *
794 - * Each column definition:
795 - * 'required' => bool column must be present in the CSV header row
796 - * 'export' => callable( array $shortcode ): string decoded shortcode row -> CSV cell value
797 - * 'import' => callable( string $value ): array CSV cell value -> partial $shortcode to merge
798 - * 'validate' => callable( string $value ): true|string optional; true, or an error message
799 - *
800 - * @return array
801 - */
802 -function sh_cd_csv_columns() {
803 -
804 - $columns = [
805 - 'slug' => [
806 - 'required' => true,
807 - 'export' => function( $shortcode ) { return $shortcode[ 'slug' ]; },
808 - 'import' => function( $value ) { return [ 'slug' => $value ]; },
809 - ],
810 - 'content' => [
811 - 'required' => true,
812 - 'export' => function( $shortcode ) { return stripslashes( $shortcode[ 'data' ] ); },
813 - 'import' => function( $value ) { return [ 'data' => $value ]; },
814 - ],
815 - 'global' => [
816 - 'required' => true,
817 - 'export' => function( $shortcode ) { return ( 1 === (int) $shortcode[ 'multisite' ] ) ? 'yes' : 'no'; },
818 - 'import' => function( $value ) { return [ 'multisite' => sh_cd_to_bool( $value ) ? 1 : 0 ]; },
819 - ],
820 - 'enabled' => [
821 - 'required' => true,
822 - 'export' => function( $shortcode ) { return ( 1 === (int) $shortcode[ 'disabled' ] ) ? 'no' : 'yes'; },
823 - 'import' => function( $value ) { return [ 'disabled' => sh_cd_to_bool( $value ) ? 0 : 1 ]; },
824 - ],
825 - ];
826 -
827 - return apply_filters( 'sh-cd-csv-columns', $columns );
828 -}
829 -
830 -/**
831 683 * Convert string to bool
832 684 * @param $string
833 685 * @return mixed
834 686 */
@@ -834,173 +686,4 @@
834 686 */
835 687 function sh_cd_to_bool( $string ) {
836 688 return filter_var( $string, FILTER_VALIDATE_BOOLEAN );
837 689 }
838 -
839 -/**
840 - * Export all shortcodes as a CSV string in the same column format sh_cd_import_csv() expects
841 - * (see sh_cd_csv_columns()), so the output can be re-imported unchanged.
842 - *
843 - * @return string
844 - */
845 -function sh_cd_export_csv() {
846 -
847 - sh_cd_permission_check();
848 -
849 - $shortcodes = sh_cd_db_shortcodes_all();
850 - $columns = sh_cd_csv_columns();
851 -
852 - $stream = fopen( 'php://temp', 'r+' );
853 -
854 - fputcsv( $stream, array_keys( $columns ) );
855 -
856 - foreach ( $shortcodes as $shortcode ) {
857 -
858 - // sh_cd_db_shortcodes_all() returns raw DB rows - run each through the same
859 - // 'sh-cd-db-loaded-shortcode' filter used when loading a single shortcode, so
860 - // Premium's JSON-encoded columns (device_type, roles, etc.) are decoded back into
861 - // arrays before the column export callbacks below run.
862 - $shortcode = sh_cd_db_filter_loaded_shortcode( $shortcode );
863 -
864 - $row = [];
865 -
866 - foreach ( $columns as $column ) {
867 - $row[] = call_user_func( $column[ 'export' ], $shortcode );
868 - }
869 -
870 - fputcsv( $stream, $row );
871 - }
872 -
873 - rewind( $stream );
874 - $csv = stream_get_contents( $stream );
875 - fclose( $stream );
876 -
877 - return $csv;
878 -}
879 -
880 -/**
881 - * Our version of kses and the HTML we are happy with
882 - */
883 -function sh_cd_wp_kses( $value ) {
884 -
885 - $basic_tags = wp_kses_allowed_html( 'html' );
886 -
887 - $basic_tags[ 'a' ] = [ 'id' => true, 'class' => true, 'href' => true, 'title' => true, 'target' => true];
888 - $basic_tags[ 'canvas' ] = [ 'id' => true, 'class' => true ];
889 - $basic_tags[ 'div' ] = [ 'id' => true, 'class' => true, 'style' => true ];
890 - $basic_tags[ 'i' ] = [ 'id' => true, 'class' => true ];
891 - $basic_tags[ 'p' ] = [ 'id' => true, 'class' => true ];
892 - $basic_tags[ 'span' ] = [ 'id' => true, 'class' => true ];
893 - $basic_tags[ 'table' ] = [ 'id' => true, 'class' => true ];
894 - $basic_tags[ 'tr' ] = [ 'id' => true, 'class' => true ];
895 - $basic_tags[ 'td' ] = [ 'id' => true, 'class' => true ];
896 - $basic_tags[ 'li' ] = [ 'class' => true ];
897 -
898 - return wp_kses( $value, $basic_tags );
899 -}
900 -
901 -/**
902 - * Return the current url
903 - */
904 -function sh_cd_get_current_url() {
905 - $protocol = (
906 - ( isset($_SERVER['HTTPS'] ) && 'on' == $_SERVER['HTTPS'] ) ||
907 - ( isset($_SERVER['SERVER_PORT'] ) && 443 == $_SERVER['SERVER_PORT'] )
908 - ) ? 'https://' : 'http://';
909 -
910 - return $protocol . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
911 -}
912 -
913 -/**
914 - * Get selected default editor
915 - */
916 -function sh_cd_default_editor_get() {
917 - return get_option( 'sh-cd-option-default-editor', 'tinymce' );
918 -}
919 -
920 -/**
921 - * Is editor valid
922 - */
923 -function sh_cd_editors_is_valid( $editor ) {
924 - $editors = sh_cd_editors_options();
925 -
926 - return ! empty( $editors[ $editor ] );
927 -}
928 -
929 -/**
930 - * Return valid editors
931 - */
932 -function sh_cd_editors_options( $keys_only = true ) {
933 - return [ 'tinymce' => __( 'WordPress Editor', SH_CD_SLUG ), 'code' => __( 'HTML Editor', SH_CD_SLUG ) ];
934 -}
935 -
936 -/**
937 - * Are tooltips enabled?
938 - */
939 -function sh_cd_tooltips_is_enabled() {
940 - return ( 'yes' === get_option( 'sh-cd-option-tool-tips-enabled', 'yes' ) );
941 -}
942 -
943 -/**
944 - * Is render-count analytics (tracking how many times each shortcode is rendered, incrementing
945 - * a DB counter on every render) enabled? A Premium-only feature, on by default - lets a
946 - * high-traffic site opt out of the extra database write on every shortcode render.
947 - *
948 - * @return bool (default true when Premium, always false otherwise)
949 - */
950 -function sh_cd_is_render_count_enabled() {
951 -
952 - if ( false === sh_cd_is_premium() ) {
953 - return false;
954 - }
955 -
956 - return ( 'yes' === get_option( 'sh-cd-option-render-count-enabled', 'yes' ) );
957 -}
958 -
959 -/**
960 - * Fetch icons for given shortcode
961 - *
962 - * @param [type] $shortcode
963 - * @param boolean $return_array
964 - * @return void
965 - */
966 -function sh_cd_icons_for_shortcode( $shortcode, $return_array = false ) {
967 -
968 - if ( true === empty( $shortcode ) ) {
969 - return [];
970 - }
971 -
972 - $icons = [];
973 -
974 - if ( false === empty( $shortcode[ 'header' ] ) ) {
975 - $icons[] = sprintf( '<i class="fa-solid fa-heading sh-cd-option-icon sh-cd-tooltip" title="%s"></i>', esc_html( __( 'Insert into WP Header', SH_CD_SLUG ) ) );
976 - }
977 -
978 - if ( false === empty( $shortcode[ 'footer' ] ) ) {
979 - $icons[] = sprintf( '<i class="fa-solid fa-shoe-prints sh-cd-option-icon sh-cd-tooltip" title="%s"></i>', esc_html( __( 'Insert into WP Footer', SH_CD_SLUG ) ) );
980 - }
981 -
982 - if ( false === empty( $shortcode[ 'device_type' ] ) ) {
983 - $shortcode[ 'device_type' ] = json_decode( $shortcode[ 'device_type' ] );
984 - }
985 -
986 - if ( true === is_array( $shortcode[ 'device_type' ] ) ) {
987 -
988 - if ( true === in_array( 'desktop', $shortcode[ 'device_type' ] ) ) {
989 - $icons[] = sprintf( '<i class="fa-solid fa-desktop sh-cd-option-icon sh-cd-tooltip" title="%s"></i>', esc_html( __( 'Display only on desktop devices', SH_CD_SLUG ) ) );
990 - }
991 -
992 - if ( true === in_array( 'mobile', $shortcode[ 'device_type' ] ) ) {
993 - $icons[] = sprintf( '<i class="fa-solid fa-mobile-screen sh-cd-option-icon sh-cd-tooltip" title="%s"></i>', esc_html( __( 'Display only on mobile devices', SH_CD_SLUG ) ) );
994 - }
995 -
996 - if ( true === in_array( 'tablet', $shortcode[ 'device_type' ] ) ) {
997 - $icons[] = sprintf( '<i class="fa-solid fa-tablet-screen-button sh-cd-option-icon sh-cd-tooltip" title="%s"></i>', esc_html( __( 'Display only on tablet devices', SH_CD_SLUG ) ) );
998 - }
999 - }
1000 -
1001 - if ( true === $return_array ) {
1002 - return $icons;
1003 - }
1004 -
1005 - return ( false === empty( $icons ) ) ? implode( PHP_EOL, $icons ) : '';
1006 -}