PluginProbe
Snippet Shortcodes / 5.0a
Snippet Shortcodes v5.0a
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 +806 -352 1.7.45.0a View file →
@@ -1,352 +1,806 @@
1 -<?php
2 -
3 -defined('ABSPATH') or die('Jog on!');
4 -
5 -function sh_cd_get_user_defined_arguments($default, $specified) {
6 -
7 - $user_defined = array();
8 -
9 - if(is_array($default) && !empty($default) && is_array($specified) && !empty($specified)) {
10 -
11 - foreach ($specified as $key => $value) {
12 - if(!isset($default[$key])) {
13 - $user_defined[$key] = $value;
14 - }
15 - }
16 -
17 - }
18 -
19 - return (is_array($user_defined) && !empty($user_defined)) ? $user_defined : false;
20 -}
21 -
22 -function sh_cd_apply_user_defined_parameters($shortcode, $user_defined_parameters){
23 -
24 - if(!empty($shortcode) && is_array($user_defined_parameters) && !empty($user_defined_parameters)) {
25 -
26 - foreach ($user_defined_parameters as $key => $value) {
27 - $shortcode = str_replace('%%' . $key . '%%', $value, $shortcode);
28 - }
29 - }
30 -
31 - return $shortcode;
32 -}
33 -
34 -function sh_cd_get_all_shortcodes()
35 -{
36 - global $wpdb;
37 -
38 - $sql = 'SELECT * FROM ' . $wpdb->prefix . SH_CD_TABLE . ' order by slug asc';
39 -
40 - $rows = $wpdb->get_results( $sql );
41 -
42 - if (!is_null($rows))
43 - return $rows;
44 -
45 - return false;
46 -
47 -}
48 -
49 -function sh_cd_get_shortcode($id)
50 -{
51 - if (!is_admin())
52 - return false;
53 -
54 - global $wpdb;
55 -
56 - $sql = $wpdb->prepare('SELECT slug, data, disabled FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
57 -
58 - $row = $wpdb->get_row( $sql );
59 -
60 - if (!is_null($row))
61 - return $row;
62 -
63 - return false;
64 -
65 -}
66 -function sh_cd_get_shortcode_by_slug($slug)
67 -{
68 - global $wpdb;
69 -
70 - $sql = $wpdb->prepare('SELECT data FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s and disabled <> 1', $slug);
71 -
72 - $row = $wpdb->get_var( $sql );
73 -
74 - if (!is_null($row))
75 - return stripslashes($row);
76 -
77 - return false;
78 -
79 -}
80 -function sh_cd_get_slug_by_id($id)
81 -{
82 - global $wpdb;
83 -
84 - $sql = $wpdb->prepare('SELECT slug FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where id = %d', $id);
85 -
86 - $row = $wpdb->get_var( $sql );
87 -
88 - if (!is_null($row))
89 - return $row;
90 -
91 - return false;
92 -
93 -}
94 -
95 -function sh_cd_save_shortcode($slug, $data, $disabled = false, $id = false)
96 -{
97 - if (!is_admin())
98 - return false;
99 -
100 - if (false == $id && empty($slug))
101 - return false;
102 -
103 - global $wpdb;
104 -
105 - $slug = sh_cd_get_slug($slug);
106 -
107 - $result = false;
108 -
109 - $disabled = (true === $disabled) ? 1: 0;
110 -
111 - if ($id)
112 - {
113 - //Update data (Slug can never be updated!)
114 - $result = $wpdb->update(
115 - $wpdb->prefix . SH_CD_TABLE,
116 - array(
117 - 'data' => $data,
118 - 'disabled' => $disabled
119 - ),
120 - array( 'id' => $id),
121 - array(
122 - '%s',
123 - '%d'
124 - ),
125 - array( '%d' )
126 - );
127 -
128 - sh_cd_delete_cache(sh_cd_get_slug_by_id($id));
129 - }
130 - else
131 - {
132 - $result = $wpdb->insert(
133 - $wpdb->prefix . SH_CD_TABLE,
134 - array(
135 - 'slug' => $slug,
136 - 'data' => $data,
137 - 'disabled' => $disabled
138 - ),
139 - array(
140 - '%s',
141 - '%s',
142 - '%d'
143 - )
144 - );
145 -
146 - sh_cd_delete_cache($slug);
147 - }
148 -
149 - if (false === $result) {
150 - return false;
151 - }
152 - else
153 - {
154 - return true;
155 - }
156 -
157 -}
158 -
159 -function sh_cd_delete_shortcode($id)
160 -{
161 - if (!is_admin() || !is_numeric($id))
162 - return false;
163 -
164 - global $wpdb;
165 -
166 - // Clear cached version
167 - sh_cd_delete_cache(sh_cd_get_slug_by_id($id));
168 -
169 - if (false === $wpdb->delete( $wpdb->prefix . SH_CD_TABLE, array( 'id' => $id ) )) {
170 - return false;
171 - }
172 - else {
173 - return true;
174 - }
175 -
176 -}
177 -
178 -function sh_cd_get_slug($text)
179 -{
180 - if(!empty($text))
181 - {
182 - $text = sanitize_title($text);
183 -
184 - $original_slug = $text;
185 -
186 - $try = 1;
187 -
188 - // If slug exists, then fetch a unique one!
189 - // v1.1: and ensure slug isn't a preset
190 - while (!sh_cd_is_slug_unique($text))
191 - {
192 - $text = $original_slug . '_' . $try;
193 -
194 - $try++;
195 - }
196 - }
197 -
198 - return $text;
199 -}
200 -
201 -function sh_cd_is_slug_unique($slug)
202 -{
203 - if (!is_admin() || empty($slug))
204 - return false;
205 -
206 - // 1.1 Ensure slug is not a prefix
207 - if (sh_cd_is_shortcode_preset($slug))
208 - return false;
209 -
210 - global $wpdb;
211 -
212 - $sql = $wpdb->prepare('SELECT count(slug) FROM ' . $wpdb->prefix . SH_CD_TABLE . ' where slug = %s', $slug);
213 -
214 - $row = $wpdb->get_var( $sql );
215 -
216 - if(0 == $row)
217 - {
218 - return true;
219 - }
220 - else
221 - {
222 - return false;
223 - }
224 -
225 -
226 -}
227 -
228 -function sh_cd_create_database_table()
229 -{
230 - global $wpdb;
231 -
232 - $table_name = $wpdb->prefix . SH_CD_TABLE;
233 -
234 - $charset_collate = $wpdb->get_charset_collate();
235 -
236 - $sql = "CREATE TABLE $table_name (
237 - id mediumint(9) NOT NULL AUTO_INCREMENT,
238 - slug varchar(100) NOT NULL,
239 - data text,
240 - disabled bit default 0,
241 - UNIQUE KEY id (id)
242 - ) $charset_collate;";
243 -
244 - require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
245 - dbDelta( $sql );
246 -
247 - update_option('sh-cd-version', SH_CD_PLUGIN_VERSION);
248 -
249 -}
250 -
251 -function sh_cd_display_message($text, $error = false)
252 -{
253 - if (!empty($text))
254 - {
255 - $class = (($error) ? 'error' : 'updated');
256 -
257 - echo '<div class="' . $class . '">
258 - <p>' . $text . '</p>
259 - </div>';
260 - }
261 -}
262 -
263 -function sh_cd_create_dialog_jquery_code($title, $message, $class_used_to_prompt_confirmation, $js_call = false)
264 -{
265 - global $wp_scripts;
266 - $queryui = $wp_scripts->query('jquery-ui-core');
267 - $url = "//ajax.googleapis.com/ajax/libs/jqueryui/".$queryui->ver."/themes/smoothness/jquery-ui.css";
268 - wp_enqueue_script( 'jquery-ui-dialog' );
269 - wp_enqueue_style('jquery-ui-smoothness', $url, false, null);
270 -
271 - $id_hash = md5($title . $message . $class_used_to_prompt_confirmation);
272 -
273 - ?>
274 - <div id='<?php echo $id_hash; ?>' title='<?php echo $title; ?>'>
275 - <p><?php echo $message; ?></p>
276 - </div>
277 - <script>
278 - jQuery(function($) {
279 -
280 - var $info = $('#<?php echo $id_hash; ?>');
281 -
282 - $info.dialog({
283 - 'dialogClass' : 'wp-dialog',
284 - 'modal' : true,
285 - 'autoOpen' : false
286 - });
287 -
288 - $('.<?php echo $class_used_to_prompt_confirmation; ?>').click(function(event) {
289 -
290 - event.preventDefault();
291 -
292 - target_url = $(this).attr('href');
293 -
294 - var $info = $('#<?php echo $id_hash; ?>');
295 -
296 - $info.dialog({
297 - 'dialogClass' : 'wp-dialog',
298 - 'modal' : true,
299 - 'autoOpen' : false,
300 - 'closeOnEscape' : true,
301 - 'buttons' : {
302 - 'Yes': function() {
303 -
304 - <?php if ($js_call != false): ?>
305 - <?php echo $js_call; ?>
306 -
307 - $(this).dialog('close');
308 - <?php else: ?>
309 - window.location.href = target_url;
310 - <?php endif; ?>
311 - },
312 - 'No': function() {
313 - $(this).dialog('close');
314 - }
315 - }
316 - });
317 -
318 - $info.dialog('open');
319 - });
320 -
321 - });
322 -
323 -
324 -
325 -
326 - </script>
327 -
328 - <?php
329 -}
330 -
331 -function sh_cd_get_cache($key)
332 -{
333 - $key = sh_cd_generate_cache_key($key);
334 -
335 - return get_transient($key);
336 -}
337 -function sh_cd_set_cache($key, $data)
338 -{
339 - $key = sh_cd_generate_cache_key($key);
340 -
341 - set_transient($key, $data, SH_CD_CACHING_TIME);
342 -}
343 -function sh_cd_delete_cache($key)
344 -{
345 - $key = sh_cd_generate_cache_key($key);
346 -
347 - return delete_transient($key);
348 -}
349 -function sh_cd_generate_cache_key($key)
350 -{
351 - return SH_CD_SHORTCODE . $key;
352 -}
1 +<?php
2 +
3 +defined('ABSPATH') or die('Jog on!');
4 +
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 + * Save / Insert a shortcode
47 + *
48 + * @return bool
49 + */
50 +function sh_cd_shortcodes_save_post() {
51 +
52 + // Capture the raw $_POST fields, the save functions will process and validate the data
53 + $shortcode = sh_cd_get_values_from_post( [ 'id', 'slug', 'previous_slug', 'data', 'disabled', 'multisite', 'editor' ] );
54 +
55 + // 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)
56 + if ( ! sh_cd_is_premium() && false === empty( $shortcode[ 'previous_slug' ] ) ) {
57 + $shortcode[ 'slug' ] = $shortcode[ 'previous_slug' ];
58 + }
59 +
60 + return sh_cd_db_shortcodes_save( $shortcode );
61 +}
62 +
63 +/**
64 + * Replace user parameters within a shortcode e.g. look for %%parameter%% and replace
65 + *
66 + * @param $shortcode
67 + * @param $user_defined_parameters
68 + *
69 + * @return mixed
70 + */
71 +function sh_cd_apply_user_defined_parameters( $shortcode, $user_defined_parameters ){
72 +
73 + // Ensure we have something to do!
74 + if ( true === empty( $user_defined_parameters ) || false === is_array( $user_defined_parameters ) ) {
75 + return $shortcode;
76 + }
77 +
78 + foreach ( $user_defined_parameters as $key => $value ) {
79 + $shortcode = str_replace( '%%' . $key . '%%', $value, $shortcode );
80 + }
81 +
82 + return $shortcode;
83 +}
84 +
85 +/**
86 + * Generate a unique slug
87 + *
88 + * @param $slug
89 + *
90 + * @return string
91 + */
92 +function sh_cd_slug_generate( $slug, $exising_id = NULL ) {
93 +
94 + if ( true === empty( $slug ) ) {
95 + return NULL;
96 + }
97 +
98 + $slug = sanitize_key( $slug );
99 +
100 + $original_slug = $slug;
101 +
102 + $try = 1;
103 +
104 + // Ensure the slug is unique
105 + while ( false === sh_cd_slug_is_unique( $slug, $exising_id ) ) {
106 +
107 + $slug = sprintf( '%s_%d', $original_slug, $try );
108 +
109 + $try++;
110 + }
111 +
112 + return $slug;
113 +}
114 +
115 +/**
116 + * Clone an existing shortcode!
117 + *
118 + * @param $id
119 + *
120 + * @return bool
121 + */
122 +function sh_cd_clone( $id ) {
123 +
124 + if( false === sh_cd_is_premium() ) {
125 + return true;
126 + }
127 +
128 + if ( false === is_numeric( $id ) ) {
129 + return false;
130 + }
131 +
132 + $to_be_cloned = sh_cd_db_shortcodes_by_id( $id );
133 +
134 + if ( true === empty( $to_be_cloned ) ) {
135 + return false;
136 + }
137 +
138 + unset( $to_be_cloned['id'] );
139 +
140 + return sh_cd_db_shortcodes_save( $to_be_cloned );
141 +}
142 +
143 +/**
144 + * Display message in admin UI
145 + *
146 + * @param $text
147 + * @param bool $error
148 + */
149 +function sh_cd_message_display( $text, $error = false ) {
150 +
151 + if ( true === empty( $text ) ) {
152 + return;
153 + }
154 +
155 + printf( '<div class="%s"><p>%s</p></div>',
156 + true === $error ? 'error' : 'updated',
157 + esc_html( $text )
158 + );
159 +
160 + //TODO: Hook this to use admin_notices
161 +}
162 +
163 +/**
164 + * Fetch cache item
165 + *
166 + * @param $key
167 + *
168 + * @return mixed
169 + */
170 +function sh_cd_cache_get( $key ) {
171 +
172 + $key = sh_cd_cache_generate_key( $key );
173 +
174 + return get_transient( $key );
175 +}
176 +
177 +/**
178 + * Set cache item
179 + *
180 + * @param $key
181 + * @param $data
182 + */
183 +function sh_cd_cache_set( $key, $data, $expire = NULL ) {
184 +
185 +
186 + $expire = ( false === empty( $expire ) ) ? (int) $expire : 1 * HOUR_IN_SECONDS;
187 +
188 + $key = sh_cd_cache_generate_key( $key );
189 +
190 + set_transient( $key, $data, $expire );
191 +}
192 +
193 +/**
194 + * Delete cache for given shortcode slug / ID
195 + *
196 + * @param $slug_or_key
197 + */
198 +function sh_cd_cache_delete_by_slug_or_key( $slug_or_key ) {
199 +
200 + if ( true === is_numeric( $slug_or_key ) ) {
201 +
202 + $slug_or_key = sh_cd_db_shortcodes_get_slug_by_id( $slug_or_key );
203 +
204 + sh_cd_cache_delete( $slug_or_key );
205 +
206 + } else {
207 + sh_cd_cache_delete( $slug_or_key );
208 + }
209 +
210 + // Delete site option
211 + $slug_or_key = SH_CD_PREFIX . $slug_or_key;
212 +
213 + delete_site_option( $slug_or_key );
214 +
215 +}
216 +
217 +/**
218 + * Delete cache item
219 + *
220 + * @param $key
221 + *
222 + * @return mixed
223 + */
224 +function sh_cd_cache_delete( $key ) {
225 +
226 + $key = sh_cd_cache_generate_key( $key );
227 +
228 + return delete_transient( $key );
229 +}
230 +
231 +/**
232 + * Generate cache key
233 + *
234 + * @param $key
235 + *
236 + * @return string
237 + */
238 +function sh_cd_cache_generate_key( $key ) {
239 + return SH_CD_SHORTCODE . SH_CD_PLUGIN_VERSION . $key;
240 +}
241 +
242 +/**
243 + * Return link to list own shortcodes
244 + *
245 + * @return mixed
246 + */
247 +function sh_cd_link_your_shortcodes() {
248 +
249 + $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes');
250 +
251 + return esc_url( $link );
252 +}
253 +
254 +/**
255 + * Return link to add own shortcode
256 + *
257 + * @return mixed
258 + */
259 +function sh_cd_link_your_shortcodes_add() {
260 +
261 + $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=add');
262 +
263 + return esc_url( $link );
264 +}
265 +
266 +/**
267 + * Return link to edit own shortcode
268 + *
269 + * @return mixed
270 + */
271 +function sh_cd_link_your_shortcodes_edit( $id ) {
272 +
273 + $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=edit&id=' . (int) $id );
274 +
275 + return esc_url( $link );
276 +}
277 +
278 +/**
279 + * Return link to delete own shortcode
280 + *
281 + * @param $id
282 + * @return mixed
283 + */
284 +function sh_cd_link_your_shortcodes_delete( $id ) {
285 +
286 + $link = admin_url('admin.php?page=sh-cd-shortcode-variables-your-shortcodes&action=delete&id=' . (int) $id );
287 +
288 + return esc_url( $link );
289 +}
290 +
291 +/**
292 + * Either fetch data from the $_POST object or from the array passed in!
293 + *
294 + * @param $object
295 + * @param $key
296 + * @return string
297 + */
298 +function sh_cd_get_value_from_post_or_obj( $object, $key ) {
299 +
300 + if ( true === isset( $_POST[ $key ] ) ) {
301 + return $_POST[ $key ];
302 + }
303 +
304 + if ( true === isset( $object[ $key ] ) ) {
305 + return $object[ $key ];
306 + }
307 +
308 + return '';
309 +}
310 +
311 +/**
312 + * Either fetch data from the $_POST object for the given object keys
313 + *
314 + * @param $keys
315 + * @return array
316 + */
317 +function sh_cd_get_values_from_post( $keys ) {
318 +
319 + $data = [];
320 +
321 + foreach ( $keys as $key ) {
322 +
323 + if ( true === isset( $_POST[ $key ] ) ) {
324 + $data[ $key ] = $_POST[ $key ];
325 + } else {
326 + $data[ $key ] = '';
327 + }
328 +
329 + }
330 +
331 + return $data;
332 +}
333 +
334 +/**
335 + * Toggle the status of a shortcode
336 + *
337 + * @param $id
338 + */
339 +function sh_cd_toggle_status( $id ) {
340 +
341 + $slug = sh_cd_db_shortcodes_by_id( (int) $id );
342 +
343 + if ( false === empty( $slug ) ) {
344 +
345 + $status = ( 1 === (int) $slug['disabled'] ) ? 0 : 1 ;
346 +
347 + sh_cd_db_shortcodes_update_status( $id, $status );
348 +
349 + return $status;
350 + }
351 +
352 + return NULL;
353 +}
354 +
355 +/**
356 + * Toggle the multisite of a shortcode
357 + *
358 + * @param $id
359 + * @return int|null
360 + */
361 +function sh_cd_toggle_multisite( $id ) {
362 +
363 + $slug = sh_cd_db_shortcodes_by_id( (int) $id );
364 +
365 + if ( false === empty( $slug ) ) {
366 +
367 + $multisite = ( 1 === (int) $slug['multisite'] ) ? 0 : 1 ;
368 +
369 + sh_cd_db_shortcodes_update_multisite( $id, $multisite );
370 +
371 + return $multisite;
372 + }
373 +
374 + return NULL;
375 +}
376 +
377 +/**
378 + * Display an upgrade button
379 + *
380 + * @param string $css_class
381 + * @param null $link
382 + */
383 +function sh_cd_upgrade_button( $css_class = '', $link = NULL ) {
384 +
385 + $link = ( false === empty( $link ) ) ? $link : SH_CD_UPGRADE_LINK . '?hash=' . sh_cd_generate_site_hash() ;
386 +
387 + $price = sh_cd_license_price();
388 + $price = ( false === empty( $price ) ) ? sprintf( '- £%s %s', $price, __( 'a year ', SH_CD_SLUG ) ) : '';
389 +
390 + 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>',
391 + esc_url( $link ),
392 + esc_attr( ' ' . $css_class ),
393 + __( 'Purchase a license ', SH_CD_SLUG ),
394 + $price
395 + );
396 +}
397 +
398 +/**
399 + * Display an upgrade button
400 + *
401 + * @param string $css_class
402 + * @param null $link
403 + */
404 +function sh_cd_premium_shortcode_download( $return = false ) {
405 +
406 + $link = SH_CD_GET_PREMIUM_LINK . '?hash=' . sh_cd_generate_site_hash();
407 +
408 + $html = sprintf('<a href="%s" class="button-primary sh-cd-button sh-cd-upgrade-button"><i class="fas fa-download"></i> %s</a>',
409 + esc_url( $link ),
410 + __( 'Download Premium Plugin', SH_CD_SLUG )
411 + );
412 +
413 + if ( true === $return ) {
414 + return $html;
415 + }
416 +
417 + echo $html;
418 +}
419 +
420 +/**
421 + * Is multsite functionality active for this install?
422 + *
423 + * @return bool
424 + */
425 +function sh_cd_is_multisite_enabled() {
426 +
427 + if ( false === is_multisite() ) {
428 + return false;
429 + }
430 +
431 + if ( false === sh_cd_is_premium() ) {
432 + return false;
433 + }
434 +
435 + return true;
436 +}
437 +
438 +/**
439 + * Fetch all multisite slugs
440 + *
441 + * @return array|null
442 + */
443 +function sh_cd_multisite_slugs() {
444 +
445 + if ( false === is_multisite() ) {
446 + return [];
447 + }
448 +
449 + $cache = sh_cd_cache_get( 'sh-cd-multisite-slugs' );
450 +
451 + if ( false !== $cache ) {
452 + return $cache;
453 + }
454 +
455 + $slugs = sh_cd_db_shortcodes_multisite_slugs();
456 +
457 + $slugs = ( false === empty( $slugs ) ) ? wp_list_pluck( $slugs, 'slug' ) : [];
458 +
459 + // Cache this for a short time
460 + sh_cd_cache_set( 'sh-cd-multisite-slugs', $slugs, 30 );
461 +
462 + return ( true === is_array( $slugs ) ) ? $slugs : [];
463 +}
464 +
465 +/**
466 + * Have we reached the limit of free shortcodes?
467 + * @return bool
468 + */
469 +function sh_cd_reached_free_limit() {
470 +
471 + if ( true === sh_cd_is_premium() ) {
472 + return false;
473 + }
474 +
475 + $existing_shortcodes = sh_cd_db_shortcodes_count();
476 +
477 + if ( true === empty( $existing_shortcodes ) ) {
478 + return false;
479 + }
480 +
481 + return ( (int) $existing_shortcodes >= sh_cd_get_free_limit() );
482 +}
483 +
484 +/**
485 + * Return free limit for shortcodes
486 + */
487 +function sh_cd_get_free_limit() {
488 + return 10;
489 +}
490 +
491 +/**
492 + * Get the minimum user role allowed for viewing data pages in admin
493 + * @return mixed|void
494 + */
495 +function sh_cd_permission_role() {
496 +
497 + // If not premium, then admin only
498 + if ( false === sh_cd_is_premium() ) {
499 + return 'manage_options';
500 + }
501 +
502 + $permission_role = get_option( 'sh-cd-edit-permissions', 'manage_options' );
503 +
504 + return ( false === empty( $permission_role ) ) ? $permission_role : 'manage_options';
505 +}
506 +
507 +/**
508 + * Does the user have the correct permissions to view this page?
509 + */
510 +function sh_cd_permission_check() {
511 +
512 + $allowed_viewer = sh_cd_permission_role();
513 +
514 + if ( false === current_user_can( $allowed_viewer ) ) {
515 + wp_die( __( 'You do not have sufficient permissions to access this page.', SH_CD_SLUG ) );
516 + }
517 +}
518 +
519 +/**
520 + * Is the shortcode [sv slug="sc-db-value-by-id"] enabled
521 + * @return bool (default false)
522 + */
523 +function sh_cd_is_shortcode_db_value_by_id_enabled() {
524 +
525 + if ( false === sh_cd_is_premium() ) {
526 + return false;
527 + }
528 +
529 + // Disabling by filter overrides the setting in WP admin
530 + if ( true === apply_filters( 'disable-ss-sc-db-value-by-id', __return_false() ) ) {
531 + return false;
532 + }
533 +
534 + $value = get_option( 'sh-cd-shortcode-db-value-by-id-enabled', false );
535 +
536 + return sh_cd_to_bool( $value );
537 +}
538 +
539 +/**
540 + * Display upgrade notice
541 + *
542 + * @param bool $pro_plus
543 + */
544 +function sh_cd_display_pro_upgrade_notice( ) {
545 + ?>
546 +
547 + <div class="postbox sh-cd-advertise-premium">
548 + <h3 class="hndle"><span><?php echo __( 'Upgrade Snippet Shortcodes and get more features!', SH_CD_SLUG ); ?> </span></h3>
549 + <div style="padding: 0px 15px 0px 15px">
550 + <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>
551 + </div>
552 + </div>
553 +
554 + <?php
555 +}
556 +
557 +/**
558 + * Display a star to prompt for a Premioum upgrade
559 + *
560 + * @param bool $pro_plus
561 + */
562 +function sh_cd_display_premium_star() {
563 +
564 + if ( true === sh_cd_is_premium() ) {
565 + return ''; // We don't want to show the star if the user has already upgraded
566 + }
567 +
568 + return sprintf ('<a href="%s"><i class="fa-regular fa-star"></i></a>',
569 + esc_url( admin_url('admin.php?page=sh-cd-shortcode-variables-upgrade') )
570 + );
571 +}
572 +
573 +/**
574 + * Display info symbol with tooltip
575 + */
576 +function sh_cd_display_info_tooltip( $text ) {
577 +
578 + return sprintf ('<i class="fa-regular fa-circle-question sh-cd-tooltip" title="%s">',
579 + esc_html( $text )
580 + );
581 +}
582 +
583 +/**
584 + * Process a CSV attachment and import into database
585 + *
586 + * @param $attachment_id
587 + *
588 + * @param bool $dry_run
589 + *
590 + * @return string
591 + */
592 +function sh_cd_import_csv( $attachment_id, $dry_run = true ) {
593 +
594 + if ( false === sh_cd_permission_check() ) {
595 + return 'You do not have the correct admin permissions';
596 + }
597 +
598 + if ( false === sh_cd_is_premium() ) {
599 + return 'This is a premium feature';
600 + }
601 +
602 + $csv_path = get_attached_file( $attachment_id );
603 + $admin_id = get_current_user_id();
604 +
605 + if ( true === empty( $csv_path ) || false === file_exists( $csv_path )) {
606 + return 'Error: Error loading CSV from disk.';
607 + }
608 +
609 + $csv = array_map('str_getcsv', file( $csv_path ) );
610 +
611 + if ( true === empty( $csv ) ) {
612 + return 'Error: The CSV appears to be empty.';
613 + }
614 +
615 + array_walk($csv, function(&$a) use ($csv) {
616 + $a = array_combine($csv[0], $a);
617 + });
618 +
619 + $validate_header_result = sh_cd_import_csv_validate_header( $csv[0] );
620 +
621 + if ( true !== $validate_header_result ) {
622 + return $validate_header_result;
623 + }
624 +
625 + array_shift($csv );
626 +
627 + if ( true === empty( $csv ) ) {
628 + return 'Error: The CSV appears to be empty (when header hs been removed).';
629 + }
630 +
631 + $errors = 0;
632 +
633 + $output = sprintf( '%d rows to process...' . PHP_EOL, count( $csv ) );
634 +
635 + if ( true === $dry_run ) {
636 + $output .= 'DRY RUN MODE! No data will be imported.' . PHP_EOL;
637 + }
638 +
639 + foreach ( $csv as $row ) {
640 +
641 + if ( $errors >= 50 ) {
642 + $output .= 'Aborted! More than 50 errors have been detected in this file.' . PHP_EOL;
643 + break;
644 + }
645 +
646 + $row = array_change_key_case( $row ); // Force CSV headers to lowercase
647 +
648 + $validation_result = sh_cd_import_csv_validate_row( $row );
649 +
650 + // Validate a row before proceeding
651 + if ( true !== $validation_result ) {
652 + $output .= $validation_result . PHP_EOL;
653 + $errors++;
654 + continue;
655 + }
656 +
657 + if ( false === $dry_run ) {
658 +
659 + $shortcode = [ 'slug' => $row[ 'slug' ],
660 + 'previous_slug' => '',
661 + 'data' => $row[ 'content' ],
662 + 'disabled' => ! sh_cd_to_bool( $row[ 'enabled' ] ),
663 + 'multisite' => sh_cd_to_bool( $row[ 'global' ] )
664 + ];
665 +
666 + $result = sh_cd_db_shortcodes_save( $shortcode );
667 +
668 + if ( false === $result ) {
669 + $output .= 'Skipped: Error inserting into database (most likely a field contains too many characters or in the wrong format): ' . implode( ',', $row ) . PHP_EOL;
670 + }
671 + }
672 +
673 + }
674 +
675 + if ( $errors > 0 ) {
676 + $output .= sprintf( '%d errors were detected and the rows skipped.' . PHP_EOL, $errors );
677 + }
678 +
679 + $output .= 'Completed.';
680 +
681 + return $output;
682 +
683 +}
684 +
685 +/**
686 + * Verify header row
687 + * @param $header_row
688 + *
689 + * @return bool|string
690 + */
691 +function sh_cd_import_csv_validate_header( $header_row ) {
692 +
693 + $expected_headers = [ 'slug', 'content', 'global', 'enabled' ];
694 +
695 + foreach ( $expected_headers as $column ) {
696 +
697 + if ( false === isset( $header_row[ $column ] ) ) {
698 + return 'Missing column: ' . $column . '. Expecting: ' . implode( ',', $expected_headers ) . PHP_EOL;
699 + }
700 + }
701 +
702 + return true;
703 +}
704 +
705 +/**
706 + * Validate CSV row
707 + * @param $csv_row
708 + *
709 + * @return bool|string
710 + */
711 +function sh_cd_import_csv_validate_row( $csv_row ) {
712 +
713 + if ( true === empty( $csv_row[ 'slug' ] ) ) {
714 + return 'Skipped: Missing slug: ' . implode( ',', $csv_row );
715 + }
716 +
717 + if ( false === empty( $isset[ 'content' ] ) ) {
718 + return 'Skipped: Content: ' . implode( ',', $csv_row );
719 + }
720 +
721 + $allowed_bools = [ 'yes', 'no', 'true', 'false', '1', '0' ];
722 +
723 + if ( true === empty( $csv_row[ 'global' ] ) ||
724 + false === in_array( $csv_row[ 'global' ], $allowed_bools ) ) {
725 + return 'Skipped: Invalid "global" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
726 + }
727 +
728 + if ( true === empty( $csv_row[ 'enabled' ] ) ||
729 + false === in_array( $csv_row[ 'enabled' ], $allowed_bools ) ) {
730 + return 'Skipped: Invalid "enabled" value. Must be "yes" or "no": ' . implode( ',', $csv_row );
731 + }
732 +
733 + return true;
734 +}
735 +
736 +/**
737 + * Convert string to bool
738 + * @param $string
739 + * @return mixed
740 + */
741 +function sh_cd_to_bool( $string ) {
742 + return filter_var( $string, FILTER_VALIDATE_BOOLEAN );
743 +}
744 +
745 +/**
746 + * Our version of kses and the HTML we are happy with
747 + */
748 +function sh_cd_wp_kses( $value ) {
749 +
750 + $basic_tags = wp_kses_allowed_html( 'html' );
751 +
752 + $basic_tags[ 'a' ] = [ 'id' => true, 'class' => true, 'href' => true, 'title' => true, 'target' => true];
753 + $basic_tags[ 'canvas' ] = [ 'id' => true, 'class' => true ];
754 + $basic_tags[ 'div' ] = [ 'id' => true, 'class' => true, 'style' => true ];
755 + $basic_tags[ 'i' ] = [ 'id' => true, 'class' => true ];
756 + $basic_tags[ 'p' ] = [ 'id' => true, 'class' => true ];
757 + $basic_tags[ 'span' ] = [ 'id' => true, 'class' => true ];
758 + $basic_tags[ 'table' ] = [ 'id' => true, 'class' => true ];
759 + $basic_tags[ 'tr' ] = [ 'id' => true, 'class' => true ];
760 + $basic_tags[ 'td' ] = [ 'id' => true, 'class' => true ];
761 + $basic_tags[ 'li' ] = [ 'class' => true ];
762 +
763 + return wp_kses( $value, $basic_tags );
764 +}
765 +
766 +/**
767 + * Return the current url
768 + */
769 +function sh_cd_get_current_url() {
770 + $protocol = (
771 + ( isset($_SERVER['HTTPS'] ) && 'on' == $_SERVER['HTTPS'] ) ||
772 + ( isset($_SERVER['SERVER_PORT'] ) && 443 == $_SERVER['SERVER_PORT'] )
773 + ) ? 'https://' : 'http://';
774 +
775 + return $protocol . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
776 +}
777 +
778 +/**
779 + * Get selected default editor
780 + */
781 +function sh_cd_default_editor_get() {
782 + return get_option( 'sh-cd-option-default-editor', 'tinymce' );
783 +}
784 +
785 +/**
786 + * Is editor valid
787 + */
788 +function sh_cd_editors_is_valid( $editor ) {
789 + $editors = sh_cd_editors_options();
790 +
791 + return ! empty( $editors[ $editor ] );
792 +}
793 +
794 +/**
795 + * Return valid editors
796 + */
797 +function sh_cd_editors_options( $keys_only = true ) {
798 + return [ 'tinymce' => __( 'WordPress Editor', SH_CD_SLUG ), 'code' => __( 'HTML Editor', SH_CD_SLUG ) ];
799 +}
800 +
801 +/**
802 + * Are tooltips enabled?
803 + */
804 +function sh_cd_tooltips_is_enabled() {
805 + return ( 'yes' === get_option( 'sh-cd-option-tool-tips-enabled', 'yes' ) );
806 +}