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
shortcode-variables / includes / functions.php

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

690 lines 14.6 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' ) : NULL;
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 * Display upgrade notice
512 *
513 * @param bool $pro_plus
514 */
515 function sh_cd_display_pro_upgrade_notice( ) {
516 ?>
517
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>
520 <div style="padding: 0px 15px 0px 15px">
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>
522 </div>
523 </div>
524
525 <?php
526 }
527
528
529 /**
530 * Process a CSV attachment and import into database
531 *
532 * @param $attachment_id
533 *
534 * @param bool $dry_run
535 *
536 * @return string
537 */
538 function sh_cd_import_csv( $attachment_id, $dry_run = true ) {
539
540 if ( false === sh_cd_permission_check() ) {
541 return 'You do not have the correct admin permissions';
542 }
543
544 if ( false === SH_CD_IS_PREMIUM ) {
545 return 'This is a premium feature';
546 }
547
548 $csv_path = get_attached_file( $attachment_id );
549 $admin_id = get_current_user_id();
550
551 if ( true === empty( $csv_path ) || false === file_exists( $csv_path )) {
552 return 'Error: Error loading CSV from disk.';
553 }
554
555 $csv = array_map('str_getcsv', file( $csv_path ) );
556
557 if ( true === empty( $csv ) ) {
558 return 'Error: The CSV appears to be empty.';
559 }
560
561 array_walk($csv, function(&$a) use ($csv) {
562 $a = array_combine($csv[0], $a);
563 });
564
565 $validate_header_result = sh_cd_import_csv_validate_header( $csv[0] );
566
567 if ( true !== $validate_header_result ) {
568 return $validate_header_result;
569 }
570
571 array_shift($csv );
572
573 if ( true === empty( $csv ) ) {
574 return 'Error: The CSV appears to be empty (when header hs been removed).';
575 }
576
577 $errors = 0;
578
579 $output = sprintf( '%d rows to process...' . PHP_EOL, count( $csv ) );
580
581 if ( true === $dry_run ) {
582 $output .= 'DRY RUN MODE! No data will be imported.' . PHP_EOL;
583 }
584
585 foreach ( $csv as $row ) {
586
587 if ( $errors >= 50 ) {
588 $output .= 'Aborted! More than 50 errors have been detected in this file.' . PHP_EOL;
589 break;
590 }
591
592 $row = array_change_key_case( $row ); // Force CSV headers to lowercase
593
594 $validation_result = sh_cd_import_csv_validate_row( $row );
595
596 // Validate a row before proceeding
597 if ( true !== $validation_result ) {
598 $output .= $validation_result . PHP_EOL;
599 $errors++;
600 continue;
601 }
602
603 if ( false === $dry_run ) {
604
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 ];
611
612 $result = sh_cd_db_shortcodes_save( $shortcode );
613
614 if ( false === $result ) {
615 $output .= 'Skipped: Error inserting into database (most likely a field contains too many characters or in the wrong format): ' . implode( ',', $row ) . PHP_EOL;
616 }
617 }
618
619 }
620
621 if ( $errors > 0 ) {
622 $output .= sprintf( '%d errors were detected and the rows skipped.' . PHP_EOL, $errors );
623 }
624
625 $output .= 'Completed.';
626
627 return $output;
628
629 }
630
631 /**
632 * Verify header row
633 * @param $header_row
634 *
635 * @return bool|string
636 */
637 function sh_cd_import_csv_validate_header( $header_row ) {
638
639 $expected_headers = [ 'slug', 'content', 'global', 'enabled' ];
640
641 foreach ( $expected_headers as $column ) {
642
643 if ( false === isset( $header_row[ $column ] ) ) {
644 return 'Missing column: ' . $column . '. Expecting: ' . implode( ',', $expected_headers ) . PHP_EOL;
645 }
646 }
647
648 return true;
649 }
650
651 /**
652 * Validate CSV row
653 * @param $csv_row
654 *
655 * @return bool|string
656 */
657 function sh_cd_import_csv_validate_row( $csv_row ) {
658
659 if ( true === empty( $csv_row[ 'slug' ] ) ) {
660 return 'Skipped: Missing slug: ' . implode( ',', $csv_row );
661 }
662
663 if ( false === empty( $isset[ 'content' ] ) ) {
664 return 'Skipped: Content: ' . implode( ',', $csv_row );
665 }
666
667 $allowed_bools = [ 'yes', 'no', 'true', 'false', '1', '0' ];
668
669 if ( true === empty( $csv_row[ 'global' ] ) ||
670 false === in_array( $csv_row[ 'global' ], $allowed_bools ) ) {
671 return 'Skipped: Invalid "global" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
672 }
673
674 if ( true === empty( $csv_row[ 'enabled' ] ) ||
675 false === in_array( $csv_row[ 'enabled' ], $allowed_bools ) ) {
676 return 'Skipped: Invalid "enabled" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
677 }
678
679 return true;
680 }
681
682 /**
683 * Convert string to bool
684 * @param $string
685 * @return mixed
686 */
687 function sh_cd_to_bool( $string ) {
688 return filter_var( $string, FILTER_VALIDATE_BOOLEAN );
689 }
690