PluginProbe ʕ •ᴥ•ʔ
Strong Testimonials / 2.38
Strong Testimonials v2.38
3.3.2 3.3.1 trunk 1.0.1 2.30.9 2.31.10 2.32 2.32.1 2.32.2 2.32.3 2.32.4 2.33 2.34 2.35 2.36 2.37 2.38 2.38.1 2.39 2.39.1 2.39.2 2.39.3 2.40.0 2.40.1 2.40.2 2.40.3 2.40.4 2.40.5 2.40.6 2.40.7 2.41.0 2.41.1 2.50.0 2.50.1 2.50.2 2.50.3 2.50.4 2.51.0 2.51.1 2.51.2 2.51.3 2.51.4 2.51.5 2.51.6 2.51.7 2.51.8 2.51.9 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.20 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.17 3.2.18 3.2.19 3.2.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0
strong-testimonials / includes / functions.php
strong-testimonials / includes Last commit date
integrations 7 years ago class-strong-form.php 7 years ago class-strong-log.php 7 years ago class-strong-mail.php 7 years ago class-strong-templates.php 7 years ago class-strong-testimonials-order.php 7 years ago class-strong-testimonials-privacy.php 7 years ago class-strong-testimonials-render.php 7 years ago class-strong-testimonials-shortcode-average.php 7 years ago class-strong-testimonials-shortcode-count.php 7 years ago class-strong-testimonials-shortcode.php 7 years ago class-strong-view-display.php 7 years ago class-strong-view-form.php 7 years ago class-strong-view-slideshow.php 7 years ago class-strong-view.php 7 years ago class-walker-strong-category-checklist-front.php 7 years ago deprecated.php 7 years ago filters.php 7 years ago functions-activation.php 7 years ago functions-content.php 7 years ago functions-image.php 7 years ago functions-rating.php 7 years ago functions-template-form.php 7 years ago functions-template.php 7 years ago functions-views.php 7 years ago functions.php 7 years ago l10n-polylang.php 7 years ago l10n-wpml.php 7 years ago post-types.php 7 years ago retro.php 7 years ago scripts.php 7 years ago widget2.php 7 years ago
functions.php
885 lines
1 <?php
2 /**
3 * Functions
4 */
5
6 function wpmtst_support_url() {
7 return esc_url( '#' );
8 }
9
10 /**
11 * Return default translation from po/mo files if no active translation plugin.
12 *
13 * @since 2.23.2
14 * @param $string
15 *
16 * @return string
17 */
18 function wpmtst_l10n_default( $string ) {
19 return $string;
20 }
21 add_filter( 'wpmtst_l10n', 'wpmtst_l10n_default' );
22
23 /**
24 * Append custom fields to post object.
25 * Add thumbnail if included in field group.
26 *
27 * @param $post
28 *
29 * @return mixed
30 */
31 function wpmtst_get_post( $post ) {
32 $custom = get_post_custom( $post->ID );
33 $fields = wpmtst_get_custom_fields();
34
35 foreach ( $fields as $key => $field ) {
36 $name = $field['name'];
37
38 if ( 'featured_image' == $name ) {
39 $post->thumbnail_id = get_post_thumbnail_id( $post->ID );
40 }
41 else {
42 if ( isset( $custom[ $name ] ) ) {
43 $post->$name = $custom[ $name ][0];
44 }
45 else {
46 $post->$name = '';
47 }
48 }
49 }
50
51 return $post;
52 }
53
54 /**
55 * Helper: Format URL
56 *
57 * @param $url
58 * @return string
59 */
60 function wpmtst_get_website( $url ) {
61 if ( !preg_match( "~^(?:f|ht)tps?://~i", $url ) )
62 $url = 'https://' . $url;
63
64 return $url;
65 }
66
67 /**
68 * Check whether a common script is already registered by file name
69 * instead of handle.
70 *
71 * === Used in older versions to check for Cycle script. ===
72 *
73 * Why? Plugins are loaded before themes. Our plugin includes the Cycle
74 * slider. Some themes include it too. We only want to load it once.
75 *
76 * Load jQuery Cycle plugin (http://jquery.malsup.com/cycle/) only if
77 * any version of Cycle is not already registered by a theme or another
78 * plugin. Both versions of Cycle use same function name so we can't load
79 * both but either version will work for our purposes.
80 * http://jquery.malsup.com/cycle2/faq/
81 *
82 * The WordPress function `wp_script_is` checks by *handle* within a plugin
83 * or theme but handles can be different so it misses it.
84 * wp_script_is( 'jquery-cycle', 'registered' )
85 * http://codex.wordpress.org/Function_Reference/wp_script_is
86 *
87 * Jetpack's slideshow shortcode simply enqueues its own version of Cycle
88 * without registering first if and when the shortcode is rendered. No way
89 * to check for that. It does not seem to create a conflict now. (1.16)
90 *
91 * @param array $filenames possible versions of one script,
92 * e.g. plugin.js, plugin-min.js, plugin-1.2.js
93 * @return string
94 */
95 function wpmtst_is_registered( $filenames ) {
96 global $wp_scripts;
97
98 // Bail if called too early.
99 if ( ! $wp_scripts ) return false;
100
101 $script_handle = '';
102
103 foreach ( $wp_scripts->registered as $handle => $script ) {
104 if ( in_array( basename( $script->src ), $filenames ) ) {
105 $script_handle = $handle;
106 break;
107 }
108 }
109
110 return $script_handle;
111 }
112
113 if ( ! function_exists( 'get_page_by_slug' ) ) {
114 /**
115 * Get page ID by slug.
116 *
117 * Thanks http://wordpress.stackexchange.com/a/102845/32076
118 * Does not require parent slug.
119 *
120 * @since 1.11.0
121 */
122 function get_page_by_slug( $page_slug, $output = OBJECT, $post_type = 'page' ) {
123 global $wpdb;
124 $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s AND post_status = 'publish'", $page_slug, $post_type ) );
125 if ( $page )
126 return get_post($page, $output);
127 else
128 return null;
129 }
130 }
131
132 /**
133 * Reverse auto-p wrap shortcodes that stand alone
134 *
135 * @since 1.11.0
136 */
137 if ( ! function_exists( 'reverse_wpautop' ) ) {
138 function reverse_wpautop( $s ) {
139 // remove any new lines already in there
140 $s = str_replace("\n", "", $s);
141
142 // remove all <p>
143 $s = str_replace("<p>", "", $s);
144
145 // remove <br>
146 $s = str_replace(array("<br />", "<br/>", "<br>"), "", $s);
147
148 // remove </p>
149 $s = str_replace("</p>", "", $s);
150
151 return $s;
152 }
153 }
154
155 /**
156 * Sort array based on 'order' element.
157 *
158 * @since 1.13
159 */
160 function wpmtst_uasort( $a, $b ) {
161 if ( $a['order'] == $b['order'] ) {
162 return 0;
163 }
164 return ( $a['order'] < $b['order'] ) ? -1 : 1;
165 }
166
167 function wpmtst_get_custom_form_count() {
168 $forms = get_option( 'wpmtst_custom_forms' );
169 return count( $forms );
170 }
171
172 function wpmtst_get_form_fields( $form_id = 1 ) {
173 $forms = get_option( 'wpmtst_custom_forms' );
174 if ( isset( $forms[ $form_id ] ) ) {
175 $form = $forms[ $form_id ];
176 } else {
177 $form = $forms[1];
178 }
179 $fields = $form['fields'];
180
181 return $fields;
182 }
183
184 /**
185 * Get only custom fields from all field groups.
186 *
187 * Used in post editor.
188 *
189 * @return array
190 */
191 function wpmtst_get_custom_fields() {
192 $all_fields = array();
193 $forms = get_option( 'wpmtst_custom_forms' );
194 if ( ! $forms ) {
195 return $all_fields;
196 }
197
198 // use default group as base
199 $fields = $forms[1]['fields'];
200 if ( ! $fields ) {
201 return $all_fields;
202 }
203
204 // replace key with field name
205 foreach ( $fields as $field ) {
206 if ( 'post' != $field['record_type'] ) {
207 $all_fields[ $field['name'] ] = $field;
208 }
209 }
210
211 // merge remaining form fields
212 foreach ( $forms as $form ) {
213 $custom_fields = array();
214 $fields = $form['fields'];
215 foreach ( $fields as $field ) {
216 if ( 'post' != $field['record_type'] ) {
217 $custom_fields[ $field['name'] ] = $field;
218 }
219 }
220 $all_fields = array_merge( $all_fields, $custom_fields );
221 }
222
223 return $all_fields;
224 }
225
226 /**
227 * Get all fields from all field groups.
228 *
229 * Used for admin list columns.
230 *
231 * @return array
232 */
233 function wpmtst_get_all_fields() {
234 $forms = get_option( 'wpmtst_custom_forms' );
235 $all_fields = array();
236
237 /**
238 * Use first custom form as the base because if we use 'default'
239 * and a field has 'admin_table' enabled in 'default'
240 * but not in any custom form, the column will still be shown.
241 */
242 $fields = $forms[1]['fields'];
243
244 // replace key with field name
245 foreach ( $fields as $field ) {
246 $all_fields[ $field['name'] ] = $field;
247 }
248
249 // merge remaining form fields
250 foreach ( $forms as $form ) {
251 $custom_fields = array();
252 $fields = $form['fields'];
253 foreach ( $fields as $field ) {
254 $custom_fields[ $field['name'] ] = $field;
255 }
256 $all_fields = array_merge( $all_fields, $custom_fields );
257 }
258
259 return $all_fields;
260 }
261
262 /**
263 * Get all rating fields
264 *
265 * @return array
266 */
267 function wpmtst_get_all_rating_fields() {
268
269 $all_fields = wpmtst_get_all_fields();
270
271 $rating_fields = array();
272
273 foreach ( $all_fields as $key => $field ) :
274 if ( $field['input_type'] !== 'rating' ) {
275 continue;
276 }
277 $rating_fields[] = $field;
278 endforeach;
279
280 return $rating_fields;
281 }
282
283 /**
284 * Get the built-in fields.
285 *
286 * @since 2.29.0
287 */
288 function wpmtst_get_builtin_fields() {
289 return array(
290 'post_date' => array(
291 'name' => 'post_date',
292 'label' => 'Post Date',
293 'input_type' => 'date',
294 'type' => 'date',
295 'record_type' => 'builtin',
296 ),
297 'submit_date' => array(
298 'name' => 'submit_date',
299 'label' => 'Submit Date',
300 'input_type' => 'date',
301 'type' => 'date',
302 'record_type' => 'builtin',
303 ),
304 'category' => array(
305 'name' => 'category',
306 'label' => 'Category',
307 'input_type' => 'category',
308 'type' => 'category',
309 'record_type' => 'builtin',
310 ),
311 );
312 }
313
314 /**
315 * Get defined images sizes.
316 *
317 * @link http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
318 * @since 1.21.0
319 * @param string $size
320 *
321 * @return array|bool|mixed
322 */
323 /*
324 wpmtst_get_image_sizes = Array
325 (
326 [widget-thumbnail] => Array
327 (
328 [width] => 75
329 [height] => 75
330 [crop] =>
331 [label] => widget-thumbnail - 75 x 75
332 )
333 [thumbnail] => Array
334 (
335 [width] => 150
336 [height] => 150
337 [crop] => 1
338 [label] => thumbnail - 150 x 150
339 )
340 [medium] => Array
341 (
342 [width] => 300
343 [height] => 300
344 [crop] =>
345 [label] => medium - 300 x 300
346 )
347 [post-thumbnail] => Array
348 (
349 [width] => 825
350 [height] => 510
351 [crop] => 1
352 [label] => post-thumbnail - 825 x 510
353 )
354 [large] => Array
355 (
356 [width] => 1024
357 [height] => 1024
358 [crop] =>
359 [label] => large - 1024 x 1024
360 )
361 [full] => Array
362 (
363 [label] => original size uploaded
364 [width] => 0
365 [height] => 0
366 )
367 [custom] => Array
368 (
369 [label] => enter dimensions:
370 [width] => 0
371 [height] => 0
372 )
373 )
374 */
375 function wpmtst_get_image_sizes( $size = '' ) {
376
377 global $_wp_additional_image_sizes;
378
379 $sizes = array();
380 $get_intermediate_image_sizes = get_intermediate_image_sizes();
381
382 /**
383 * Catch possibility of missing standard sizes.
384 * @since 2.2.5
385 */
386 if ( $get_intermediate_image_sizes ) {
387 // Create the full array with sizes and crop info
388 foreach ( $get_intermediate_image_sizes as $_size ) {
389
390 if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
391
392 $sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
393 $sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
394 $sizes[ $_size ]['crop'] = (bool)get_option( $_size . '_crop' );
395 }
396 elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
397
398 $sizes[ $_size ] = array(
399 'width' => $_wp_additional_image_sizes[ $_size ]['width'],
400 'height' => $_wp_additional_image_sizes[ $_size ]['height'],
401 'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
402 );
403
404 }
405
406 }
407
408 // Sort by width
409 uasort( $sizes, 'wpmtst_compare_width' );
410
411 // Add option labels
412 foreach ( $sizes as $key => $dimensions ) {
413 $sizes[ $key ]['label'] = sprintf( '%s - %d x %d', $key, $dimensions['width'], $dimensions['height'] );
414 }
415 }
416
417 // Add extra options
418 $sizes['full'] = array( 'label' => 'original size uploaded', 'width' => 0, 'height' => 0 );
419 $sizes['custom'] = array( 'label' => 'custom size', 'width' => 0, 'height' => 0 );
420
421 // Get only one size if found
422 if ( $size ) {
423 if ( isset( $sizes[ $size ] ) ) {
424 return $sizes[ $size ];
425 } else {
426 return false;
427 }
428 }
429
430 return $sizes;
431 }
432
433 /**
434 * @param $a
435 * @param $b
436 *
437 * @return int
438 */
439 function wpmtst_compare_width( $a, $b ) {
440 if ( $a['width'] == $b['width'] ) {
441 return 0;
442 }
443 return ($a['width'] < $b['width']) ? -1 : 1;
444 }
445
446 /**
447 * @return int
448 */
449 function wpmtst_get_cat_count() {
450 return count( get_terms( 'wpm-testimonial-category', array( 'hide_empty' => false ) ) );
451 }
452
453 /**
454 * Return a list of categories after removing any orderby filters.
455 *
456 * @since 2.2.3 If WPML is active, will find corresponding term ID in current language.
457 *
458 * @param int $parent
459 *
460 * @return array|int|WP_Error
461 */
462 function wpmtst_get_cats( $parent = 0 ) {
463 return get_terms( 'wpm-testimonial-category', array(
464 'hide_empty' => false,
465 'parent' => $parent,
466 ) );
467 }
468
469 /**
470 * @param $value
471 * @param int $parent
472 * @param int $level
473 */
474 function wpmtst_nested_cats( $value, $parent = 0, $level = 0 ) {
475 $cats = wpmtst_get_cats( $parent );
476 if ( $cats ) {
477 foreach ( $cats as $cat ) {
478 $selected = in_array( $cat->term_id, $value ) ? ' selected' : '';
479 printf( '<option value="%s"%s>%s%s</option>', $cat->term_id, $selected, str_repeat( '&nbsp;&nbsp;&nbsp;', $level ), $cat->name );
480 wpmtst_nested_cats( $value, $cat->term_id, $level + 1 );
481 }
482 }
483 }
484
485 function wpmtst_sort_array_by_name( $a, $b ) {
486 if ( $a['name'] == $b['name'] )
487 return 0;
488
489 return ( $a['name'] < $b['name'] ) ? -1 : 1;
490 }
491
492 /**
493 * Allow disabling of client-side form validation via filter.
494 *
495 * @since 1.21.0
496 * @deprecated since 2.18.1
497 */
498 function wpmtst_using_form_validation_script() {
499 return true;
500 }
501
502 /**
503 * Set iframe width of embedded videos.
504 *
505 * @since 2.6.0
506 * @param $dimensions
507 * @param $url
508 *
509 * @return array
510 */
511 function wpmtst_embed_size( $dimensions, $url ) {
512 $options = get_option( 'wpmtst_options' );
513 $width = (int) $options['embed_width'];
514 if ( $width ) {
515 $dimensions = array(
516 'width' => $width,
517 'height' => min( ceil( $width * 1.5 ), 1000 )
518 );
519 }
520
521 return $dimensions;
522 }
523
524 /**
525 * Allow empty posts.
526 *
527 * @since 2.6.0
528 * @param $maybe_empty
529 * @param $postarr
530 *
531 * @return bool
532 */
533 function wpmtst_insert_post_empty_content( $maybe_empty, $postarr ) {
534 if ( 'wpm-testimonial' == $postarr['post_type'] )
535 return false;
536
537 return $maybe_empty;
538 }
539 add_filter( 'wp_insert_post_empty_content', 'wpmtst_insert_post_empty_content', 10, 2 );
540
541 /**
542 * Display submit_date in Publish meta box under Published date.
543 *
544 * @param $post @since WordPress 4.4
545 * @since 2.12.0
546 */
547 function wpmtst_post_submitbox_misc_actions( $post ) {
548 if ( ! $post ) {
549 global $post;
550 }
551
552 if ( 'wpm-testimonial' == $post->post_type ) {
553 echo '<div class="wpmtst-pub-section">';
554 echo '<span id="submit-timestamp">&nbsp;';
555 $submit_date = get_post_meta( $post->ID, 'submit_date', true );
556 if ( $submit_date ) {
557 echo 'Submitted on: <strong>' . wp_kses_post( date_i18n( 'M j, Y @ H:i', strtotime( $submit_date ) ) ) . '</strong>';
558 } else {
559 echo 'No submit date';
560 }
561 echo '</span>';
562 echo '</div>';
563 }
564 }
565 add_action( 'post_submitbox_misc_actions', 'wpmtst_post_submitbox_misc_actions' );
566
567 /**
568 * @return mixed
569 */
570 function wpmtst_get_background_defaults() {
571 return apply_filters( 'wpmtst_default_template_background', array(
572 'color' => '',
573 'type' => '',
574 'preset' => '',
575 'gradient1' => '',
576 'gradient2' => '',
577 ) );
578 }
579
580 /**
581 * @param null $preset
582 *
583 * TODO Move to options and add a filter.
584 * @return array|bool
585 */
586 function wpmtst_get_background_presets( $preset = null ) {
587 $presets = array(
588 'light-blue-gradient' => array(
589 'label' => __( 'light blue gradient', 'strong-testimonials' ),
590 'color' => '#E7EFFE',
591 'color2' => '#B8CFFB',
592 ),
593 'light-gray-gradient' => array(
594 'label' => __( 'light gray gradient', 'strong-testimonials' ),
595 'color' => '#FBFBFB',
596 'color2' => '#EDEDED',
597 ),
598 'light-green-mist-gradient' => array(
599 'label' => __( 'light green mist gradient', 'strong-testimonials' ),
600 'color' => '#F2FBE9',
601 'color2' => '#E0F7CC',
602 ),
603 'light-latte-gradient' => array(
604 'label' => __( 'light latte gradient', 'strong-testimonials' ),
605 'color' => '#F8F3EC',
606 'color2' => '#E0C8AB',
607 ),
608 'light-plum-gradient' => array(
609 'label' => __( 'light plum gradient', 'strong-testimonials' ),
610 'color' => '#F7EEF7',
611 'color2' => '#E9D0E9',
612 ),
613 'sky-blue-gradient' => array(
614 'label' => __( 'sky blue gradient', 'strong-testimonials' ),
615 'color' => '#E9F6FB',
616 'color2' => '#C8E9F6',
617 ),
618 );
619
620 if ( $preset ) {
621 if ( isset( $presets[ $preset ] ) ) {
622 return $presets[ $preset ];
623 } else {
624 return wpmtst_get_background_defaults();
625 }
626 }
627
628 return $presets;
629 }
630
631 /**
632 * Return the form success message.
633 *
634 * @since 2.18.0
635 *
636 * @return mixed
637 */
638 function wpmtst_get_success_message() {
639 $message = wpautop( do_shortcode( wpmtst_get_form_message( 'submission-success' ) ) );
640 $message = sprintf( '<div class="%s">%s</div>', 'testimonial-success', $message );
641
642 return apply_filters( 'wpmtst_form_success_message', $message );
643 }
644
645 /**
646 * Does callback exist?
647 *
648 * @param $callback
649 * @since 2.18.0
650 *
651 * @return bool
652 */
653 // TODO Move to Utils class
654 function wpmtst_callback_exists( $callback ) {
655 if ( is_array( $callback ) ) {
656 $exists = method_exists( $callback[0], $callback[1] );
657 } else {
658 $exists = function_exists( $callback );
659 }
660
661 return $exists;
662 }
663
664 /**
665 * Check for Divi Builder plugin.
666 *
667 * Its plugin version constant is inaccurate so get the version from the file header.
668 *
669 * @since 2.22.0
670 *
671 * @return bool
672 */
673 function wpmtst_divi_builder_active() {
674 $active = false;
675 if ( wpmtst_is_plugin_active( 'divi-builder/divi-builder.php' ) ) {
676 $plugin = get_file_data( WP_PLUGIN_DIR . '/divi-builder/divi-builder.php', array( 'version' => 'Version' ) );
677 if ( isset( $plugin['version'] ) && version_compare( $plugin['version'], '2' ) > 0 ) {
678 $active = true;
679 }
680 }
681
682 return $active;
683 }
684
685 /**
686 * Append custom fields to testimonial content in theme's single post template.
687 *
688 * @param $content
689 * @since 2.22.0
690 *
691 * @return string
692 */
693 function wpmtst_single_template_add_content( $content ) {
694 if ( is_singular( 'wpm-testimonial' ) || is_tax( 'wpm-testimonial-category' ) ) {
695 $content .= wpmtst_single_template_client();
696 }
697
698 return $content;
699 }
700 add_filter( 'the_content', 'wpmtst_single_template_add_content' );
701
702 /**
703 * Frequent plugin checks.
704 *
705 * A combination of an array of frequent plugin names, and core's is_plugin_active functions
706 * which are not available in front-end without loading plugin.php which is uncecessary.
707 *
708 * @param $plugin
709 *
710 * @return bool
711 */
712 function wpmtst_is_plugin_active( $plugin = '' ) {
713 if ( ! $plugin )
714 return false;
715
716 $plugins = array(
717 'wpml' => 'sitepress-multilingual-cms/sitepress.php',
718 'polylang' => 'polylang/polylang.php',
719 'lazy-loading-responsive-images' => 'lazy-loading-responsive-images/lazy-load-responsive-images.php',
720 );
721 if ( isset( $plugins[ $plugin ] ) ) {
722 $plugin = $plugins[ $plugin ];
723 }
724
725 if ( in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) )
726 return true;
727
728 if ( ! is_multisite() )
729 return false;
730
731 $plugins = get_site_option( 'active_sitewide_plugins');
732 if ( isset( $plugins[ $plugin ] ) )
733 return true;
734
735 return false;
736 }
737
738 /**
739 * Sanitize a textarea from user input. Based on sanitize_text_field.
740 *
741 * Check for invalid UTF-8,
742 * Convert single < characters to entity,
743 * strip all tags,
744 * strip octets.
745 *
746 * @since 2.11.8
747 *
748 * @param string $text
749 *
750 * @return string
751 */
752 function wpmtst_sanitize_textarea( $text ) {
753 $filtered = wp_check_invalid_utf8( $text );
754
755 if ( strpos( $filtered, '<' ) !== false ) {
756 $filtered = wp_pre_kses_less_than( $filtered );
757 // This will NOT strip extra whitespace.
758 $filtered = wp_strip_all_tags( $filtered, false );
759 }
760
761 while ( preg_match( '/%[a-f0-9]{2}/i', $filtered, $match ) ) {
762 $filtered = str_replace( $match[0], '', $filtered );
763 }
764
765 /**
766 * Filter a sanitized textarea string.
767 *
768 * @param string $filtered The sanitized string.
769 * @param string $str The string prior to being sanitized.
770 */
771 return apply_filters( 'wpmtst_sanitize_textarea', $filtered, $text );
772 }
773
774 /**
775 * Store values as 1 or 0 (never blank).
776 *
777 * Checked checkbox value is "on" but unchecked checkboxes are _not_ submitted.
778 *
779 * @param $input
780 * @param $key string Must be explicit. Do not simply loop through an input array.
781 *
782 * @return int
783 */
784 function wpmtst_sanitize_checkbox( $input, $key ) {
785 if ( isset( $input[ $key ] ) ) {
786 if ( 'on' == $input[ $key ] ) { // checked checkbox
787 return true;
788 } else { // hidden input
789 return $input[ $key ] ? true : false; // 0 or 1
790 }
791 } else { // unchecked checkbox
792 return false;
793 }
794 }
795
796 /**
797 * Trims a entire array recursively.
798 *
799 * @since 2.26.6
800 *
801 * @props Jonas John
802 * @version 0.2
803 * @link http://www.jonasjohn.de/snippets/php/trim-array.htm
804 * @param $input array|string
805 *
806 * @return array|string
807 */
808 function wpmtst_trim_array( $input ) {
809 if ( ! is_array( $input ) ) {
810 return trim( $input );
811 }
812
813 return array_map( 'wpmtst_trim_array', $input );
814 }
815
816 if ( ! function_exists( 'normalize_empty_atts' ) ) {
817 /**
818 * Normalize empty shortcode attributes.
819 *
820 * Turns atts into tags - brilliant!
821 * Thanks http://wordpress.stackexchange.com/a/123073/32076
822 *
823 * @param $atts
824 *
825 * @return mixed
826 */
827 function normalize_empty_atts( $atts ) {
828 if ( ! empty( $atts ) ) {
829 foreach ( $atts as $attribute => $value ) {
830 if ( is_int( $attribute ) ) {
831 $atts[ strtolower( $value ) ] = true;
832 unset( $atts[ $attribute ] );
833 }
834 }
835 }
836
837 return $atts;
838 }
839 }
840
841 if ( ! function_exists( 'wpmtst_round_to_half' ) ) {
842 /**
843 * Round to the nearest half.
844 *
845 * @param $value
846 *
847 * @since 2.31.0
848 * @return float|int
849 */
850 function wpmtst_round_to_half( $value ) {
851 if ( is_string( $value ) ) {
852 $value = (float) str_replace( ',', '.', $value );
853 }
854 return round( (float) $value * 2 ) / 2;
855 }
856 }
857
858
859 if ( ! function_exists( 'wpmtst_strip_whitespace' ) ) {
860 /**
861 * Remove whitespace from HTML output.
862 *
863 * @param $html
864 *
865 * @return string
866 */
867 function wpmtst_strip_whitespace( $html ) {
868 return preg_replace( '~>\s+<~', '><', trim( $html ) );
869 }
870 }
871
872 if ( ! function_exists( 'wpmtst_current_url' ) ) {
873 /**
874 * Assemble and return the current URL.
875 *
876 * @since 2.31.0
877 * @return string
878 */
879 function wpmtst_current_url() {
880 global $wp;
881
882 return home_url( add_query_arg( array(), $wp->request ) );
883 }
884 }
885