PluginProbe
Buttonizer – Floating Menus, Sticky Buttons, & Popup Builder / 3.6.0
Buttonizer – Floating Menus, Sticky Buttons, & Popup Builder v3.6.0
3.6.0 3.5.0 trunk 1.0.10 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.6.1 1.0.7 1.0.8 1.0.9 1.1 1.1.1 1.2 1.3 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.5 1.5.1 All 110 releases
← All changes | freemius/includes/fs-core-functions.php +1505 -629 1.23.6.0 View file →
@@ -1,629 +1,1505 @@
1 -<?php
2 - /**
3 - * @package Freemius
4 - * @copyright Copyright (c) 2015, Freemius, Inc.
5 - * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
6 - * @since 1.0.3
7 - */
8 -
9 - if ( ! defined( 'ABSPATH' ) ) {
10 - exit;
11 - }
12 -
13 - if ( ! function_exists( 'fs_dummy' ) ) {
14 - function fs_dummy() {
15 - }
16 - }
17 -
18 - /* Url.
19 - --------------------------------------------------------------------------------------------*/
20 - function fs_get_url_daily_cache_killer() {
21 - return date( '\YY\Mm\Dd' );
22 - }
23 -
24 - /* Templates / Views.
25 - --------------------------------------------------------------------------------------------*/
26 - if ( ! function_exists( 'fs_get_template_path' ) ) {
27 - function fs_get_template_path( $path ) {
28 - return WP_FS__DIR_TEMPLATES . '/' . trim( $path, '/' );
29 - }
30 -
31 - function fs_include_template( $path, &$params = null ) {
32 - $VARS = &$params;
33 - include fs_get_template_path( $path );
34 - }
35 -
36 - function fs_include_once_template( $path, &$params = null ) {
37 - $VARS = &$params;
38 - include_once fs_get_template_path( $path );
39 - }
40 -
41 - function fs_require_template( $path, &$params = null ) {
42 - $VARS = &$params;
43 - require fs_get_template_path( $path );
44 - }
45 -
46 - function fs_require_once_template( $path, &$params = null ) {
47 - $VARS = &$params;
48 - require_once fs_get_template_path( $path );
49 - }
50 -
51 - function fs_get_template( $path, &$params = null ) {
52 - ob_start();
53 -
54 - $VARS = &$params;
55 - require fs_get_template_path( $path );
56 -
57 - return ob_get_clean();
58 - }
59 - }
60 -
61 - /* Scripts and styles including.
62 - --------------------------------------------------------------------------------------------*/
63 - function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
64 - wp_enqueue_style( $handle, plugins_url( plugin_basename( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $media );
65 - }
66 -
67 - function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) {
68 - wp_enqueue_script( $handle, plugins_url( plugin_basename( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ) ), $deps, $ver, $in_footer );
69 - }
70 -
71 - function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) {
72 - return plugins_url( plugin_basename( $img_dir . '/' . trim( $path, '/' ) ) );
73 - }
74 -
75 - /* Request handlers.
76 - --------------------------------------------------------------------------------------------*/
77 - /**
78 - * @param string $key
79 - * @param mixed $def
80 - * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when
81 - * set to 'post' will look for the value passed via the POST request's body, otherwise,
82 - * will check if the parameter was passed in any of the two.
83 - *
84 - * @return mixed
85 - */
86 - function fs_request_get( $key, $def = false, $type = false ) {
87 - if ( is_string( $type ) ) {
88 - $type = strtolower( $type );
89 - }
90 -
91 - switch ( $type ) {
92 - case 'post':
93 - $value = isset( $_POST[ $key ] ) ? $_POST[ $key ] : $def;
94 - break;
95 - case 'get':
96 - $value = isset( $_GET[ $key ] ) ? $_GET[ $key ] : $def;
97 - break;
98 - default:
99 - $value = isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def;
100 - break;
101 - }
102 -
103 - return $value;
104 - }
105 -
106 - function fs_request_has( $key ) {
107 - return isset( $_REQUEST[ $key ] );
108 - }
109 -
110 - function fs_request_get_bool( $key, $def = false ) {
111 - if ( ! isset( $_REQUEST[ $key ] ) ) {
112 - return $def;
113 - }
114 -
115 - if ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) {
116 - return true;
117 - }
118 -
119 - if ( 0 == $_REQUEST[ $key ] || 'false' === strtolower( $_REQUEST[ $key ] ) ) {
120 - return false;
121 - }
122 -
123 - return $def;
124 - }
125 -
126 - function fs_request_is_post() {
127 - return ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) );
128 - }
129 -
130 - function fs_request_is_get() {
131 - return ( 'get' === strtolower( $_SERVER['REQUEST_METHOD'] ) );
132 - }
133 -
134 - function fs_get_action( $action_key = 'action' ) {
135 - if ( ! empty( $_REQUEST[ $action_key ] ) ) {
136 - return strtolower( $_REQUEST[ $action_key ] );
137 - }
138 -
139 - if ( 'action' == $action_key ) {
140 - $action_key = 'fs_action';
141 -
142 - if ( ! empty( $_REQUEST[ $action_key ] ) ) {
143 - return strtolower( $_REQUEST[ $action_key ] );
144 - }
145 - }
146 -
147 - return false;
148 - }
149 -
150 - function fs_request_is_action( $action, $action_key = 'action' ) {
151 - return ( strtolower( $action ) === fs_get_action( $action_key ) );
152 - }
153 -
154 - /**
155 - * @author Vova Feldman (@svovaf)
156 - * @since 1.0.0
157 - *
158 - * @since 1.2.1.5 Allow nonce verification.
159 - *
160 - * @param string $action
161 - * @param string $action_key
162 - * @param string $nonce_key
163 - *
164 - * @return bool
165 - */
166 - function fs_request_is_action_secure(
167 - $action,
168 - $action_key = 'action',
169 - $nonce_key = 'nonce'
170 - ) {
171 - if ( strtolower( $action ) !== fs_get_action( $action_key ) ) {
172 - return false;
173 - }
174 -
175 - $nonce = ! empty( $_REQUEST[ $nonce_key ] ) ?
176 - $_REQUEST[ $nonce_key ] :
177 - '';
178 -
179 - if ( empty( $nonce ) ||
180 - ( false === wp_verify_nonce( $nonce, $action ) )
181 - ) {
182 - return false;
183 - }
184 -
185 - return true;
186 - }
187 -
188 - function fs_is_plugin_page( $page_slug ) {
189 - return ( is_admin() && $page_slug === fs_request_get('page') );
190 - }
191 -
192 - /* Core UI.
193 - --------------------------------------------------------------------------------------------*/
194 - /**
195 - * @param string $slug
196 - * @param string $page
197 - * @param string $action
198 - * @param string $title
199 - * @param array $params
200 - * @param bool $is_primary
201 - * @param string|bool $icon_class Optional class for an icon (since 1.1.7).
202 - * @param string|bool $confirmation Optional confirmation message before submit (since 1.1.7).
203 - * @param string $method Since 1.1.7
204 - *
205 - * @uses fs_ui_get_action_button()
206 - */
207 - function fs_ui_action_button(
208 - $slug,
209 - $page,
210 - $action,
211 - $title,
212 - $params = array(),
213 - $is_primary = true,
214 - $icon_class = false,
215 - $confirmation = false,
216 - $method = 'GET'
217 - ) {
218 - echo fs_ui_get_action_button(
219 - $slug,
220 - $page,
221 - $action,
222 - $title,
223 - $params,
224 - $is_primary,
225 - $icon_class,
226 - $confirmation,
227 - $method
228 - );
229 - }
230 -
231 - /**
232 - * @author Vova Feldman (@svovaf)
233 - * @since 1.1.7
234 - *
235 - * @param string $slug
236 - * @param string $page
237 - * @param string $action
238 - * @param string $title
239 - * @param array $params
240 - * @param bool $is_primary
241 - * @param string|bool $icon_class Optional class for an icon.
242 - * @param string|bool $confirmation Optional confirmation message before submit.
243 - * @param string $method
244 - *
245 - * @return string
246 - */
247 - function fs_ui_get_action_button(
248 - $slug,
249 - $page,
250 - $action,
251 - $title,
252 - $params = array(),
253 - $is_primary = true,
254 - $icon_class = false,
255 - $confirmation = false,
256 - $method = 'GET'
257 - ) {
258 - // Prepend icon (if set).
259 - $title = ( is_string( $icon_class ) ? '<i class="' . $icon_class . '"></i> ' : '' ) . $title;
260 -
261 - if ( is_string( $confirmation ) ) {
262 - return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="if (confirm(\'%s\')) this.parentNode.submit(); return false;">%s</a></form>',
263 - freemius( $slug )->_get_admin_page_url( $page, $params ),
264 - $method,
265 - $action,
266 - wp_nonce_field( $action, '_wpnonce', true, false ),
267 - 'button' . ( $is_primary ? ' button-primary' : '' ),
268 - $confirmation,
269 - $title
270 - );
271 - } else if ( 'GET' !== strtoupper( $method ) ) {
272 - return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="this.parentNode.submit(); return false;">%s</a></form>',
273 - freemius( $slug )->_get_admin_page_url( $page, $params ),
274 - $method,
275 - $action,
276 - wp_nonce_field( $action, '_wpnonce', true, false ),
277 - 'button' . ( $is_primary ? ' button-primary' : '' ),
278 - $title
279 - );
280 - } else {
281 - return sprintf( '<a href="%s" class="%s">%s</a></form>',
282 - wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
283 - 'button' . ( $is_primary ? ' button-primary' : '' ),
284 - $title
285 - );
286 - }
287 - }
288 -
289 - function fs_ui_action_link( $slug, $page, $action, $title, $params = array() ) {
290 - ?><a class=""
291 - href="<?php echo wp_nonce_url( freemius( $slug )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php
292 - }
293 -
294 - /*function fs_error_handler($errno, $errstr, $errfile, $errline)
295 - {
296 - if (false === strpos($errfile, 'freemius/'))
297 - {
298 - // @todo Dump Freemius errors to local log.
299 - }
300 -
301 -// switch ($errno) {
302 -// case E_USER_ERROR:
303 -// break;
304 -// case E_WARNING:
305 -// case E_USER_WARNING:
306 -// break;
307 -// case E_NOTICE:
308 -// case E_USER_NOTICE:
309 -// break;
310 -// default:
311 -// break;
312 -// }
313 - }
314 -
315 - set_error_handler('fs_error_handler');*/
316 -
317 - if ( ! function_exists( 'fs_nonce_url' ) ) {
318 - /**
319 - * Retrieve URL with nonce added to URL query.
320 - *
321 - * Originally was using `wp_nonce_url()` but the new version
322 - * changed the return value to escaped URL, that's not the expected
323 - * behaviour.
324 - *
325 - * @author Vova Feldman (@svovaf)
326 - * @since ~1.1.3
327 - *
328 - * @param string $actionurl URL to add nonce action.
329 - * @param int|string $action Optional. Nonce action name. Default -1.
330 - * @param string $name Optional. Nonce name. Default '_wpnonce'.
331 - *
332 - * @return string Escaped URL with nonce action added.
333 - */
334 - function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) {
335 - return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
336 - }
337 - }
338 -
339 - if ( ! function_exists( 'fs_starts_with' ) ) {
340 - /**
341 - * Check if string starts with.
342 - *
343 - * @author Vova Feldman (@svovaf)
344 - * @since 1.1.3
345 - *
346 - * @param string $haystack
347 - * @param string $needle
348 - *
349 - * @return bool
350 - */
351 - function fs_starts_with( $haystack, $needle ) {
352 - $length = strlen( $needle );
353 -
354 - return ( substr( $haystack, 0, $length ) === $needle );
355 - }
356 - }
357 -
358 - #region Url Canonization ------------------------------------------------------------------
359 -
360 - if ( ! function_exists( 'fs_canonize_url' ) ) {
361 - /**
362 - * @author Vova Feldman (@svovaf)
363 - * @since 1.1.3
364 - *
365 - * @param string $url
366 - * @param bool $omit_host
367 - * @param array $ignore_params
368 - *
369 - * @return string
370 - */
371 - function fs_canonize_url( $url, $omit_host = false, $ignore_params = array() ) {
372 - $parsed_url = parse_url( strtolower( $url ) );
373 -
374 -// if ( ! isset( $parsed_url['host'] ) ) {
375 -// return $url;
376 -// }
377 -
378 - $canonical = ( ( $omit_host || ! isset( $parsed_url['host'] ) ) ? '' : $parsed_url['host'] ) . $parsed_url['path'];
379 -
380 - if ( isset( $parsed_url['query'] ) ) {
381 - parse_str( $parsed_url['query'], $queryString );
382 - $canonical .= '?' . fs_canonize_query_string( $queryString, $ignore_params );
383 - }
384 -
385 - return $canonical;
386 - }
387 - }
388 -
389 - if ( ! function_exists( 'fs_canonize_query_string' ) ) {
390 - /**
391 - * @author Vova Feldman (@svovaf)
392 - * @since 1.1.3
393 - *
394 - * @param array $params
395 - * @param array $ignore_params
396 - * @param bool $params_prefix
397 - *
398 - * @return string
399 - */
400 - function fs_canonize_query_string( array $params, array &$ignore_params, $params_prefix = false ) {
401 - if ( ! is_array( $params ) || 0 === count( $params ) ) {
402 - return '';
403 - }
404 -
405 - // Url encode both keys and values
406 - $keys = fs_urlencode_rfc3986( array_keys( $params ) );
407 - $values = fs_urlencode_rfc3986( array_values( $params ) );
408 - $params = array_combine( $keys, $values );
409 -
410 - // Parameters are sorted by name, using lexicographical byte value ordering.
411 - // Ref: Spec: 9.1.1 (1)
412 - uksort( $params, 'strcmp' );
413 -
414 - $pairs = array();
415 - foreach ( $params as $parameter => $value ) {
416 - $lower_param = strtolower( $parameter );
417 -
418 - // Skip ignore params.
419 - if ( in_array( $lower_param, $ignore_params ) ||
420 - ( false !== $params_prefix && fs_starts_with( $lower_param, $params_prefix ) )
421 - ) {
422 - continue;
423 - }
424 -
425 - if ( is_array( $value ) ) {
426 - // If two or more parameters share the same name, they are sorted by their value
427 - // Ref: Spec: 9.1.1 (1)
428 - natsort( $value );
429 - foreach ( $value as $duplicate_value ) {
430 - $pairs[] = $lower_param . '=' . $duplicate_value;
431 - }
432 - } else {
433 - $pairs[] = $lower_param . '=' . $value;
434 - }
435 - }
436 -
437 - if ( 0 === count( $pairs ) ) {
438 - return '';
439 - }
440 -
441 - return implode( "&", $pairs );
442 - }
443 - }
444 -
445 - if ( ! function_exists( 'fs_urlencode_rfc3986' ) ) {
446 - /**
447 - * @author Vova Feldman (@svovaf)
448 - * @since 1.1.3
449 - *
450 - * @param string|string[] $input
451 - *
452 - * @return array|mixed|string
453 - */
454 - function fs_urlencode_rfc3986( $input ) {
455 - if ( is_array( $input ) ) {
456 - return array_map( 'fs_urlencode_rfc3986', $input );
457 - } else if ( is_scalar( $input ) ) {
458 - return str_replace( '+', ' ', str_replace( '%7E', '~', rawurlencode( $input ) ) );
459 - }
460 -
461 - return '';
462 - }
463 - }
464 -
465 - #endregion Url Canonization ------------------------------------------------------------------
466 -
467 - function fs_download_image( $from, $to ) {
468 - $ch = curl_init( $from );
469 - $fp = fopen( fs_normalize_path( $to ), 'wb' );
470 - curl_setopt( $ch, CURLOPT_FILE, $fp );
471 - curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
472 - curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
473 - curl_setopt( $ch, CURLOPT_HEADER, 0 );
474 - curl_exec( $ch );
475 - curl_close( $ch );
476 - fclose( $fp );
477 - }
478 -
479 - /* General Utilities
480 - --------------------------------------------------------------------------------------------*/
481 -
482 - /**
483 - * Sorts an array by the value of the priority key.
484 - *
485 - * @author Daniel Iser (@danieliser)
486 - * @since 1.1.7
487 - *
488 - * @param $a
489 - * @param $b
490 - *
491 - * @return int
492 - */
493 - function fs_sort_by_priority( $a, $b ) {
494 -
495 - // If b has a priority and a does not, b wins.
496 - if ( ! isset( $a['priority'] ) && isset( $b['priority'] ) ) {
497 - return 1;
498 - } // If b has a priority and a does not, b wins.
499 - elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
500 - return - 1;
501 - } // If neither has a priority or both priorities are equal its a tie.
502 - elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
503 - return 0;
504 - }
505 -
506 - // If both have priority return the winner.
507 - return ( $a['priority'] < $b['priority'] ) ? - 1 : 1;
508 - }
509 -
510 - #--------------------------------------------------------------------------------
511 - #region Localization
512 - #--------------------------------------------------------------------------------
513 -
514 - if ( ! function_exists( 'fs_text' ) ) {
515 - /**
516 - * Retrieve a translated text by key.
517 - *
518 - * @author Vova Feldman (@svovaf)
519 - * @since 1.2.1.7
520 - *
521 - * @param string $key
522 - * @param string $slug
523 - *
524 - * @return string
525 - *
526 - * @global $fs_text, $fs_text_overrides
527 - */
528 - function fs_text( $key, $slug = 'freemius' ) {
529 - return __fs( $key, $slug );
530 - }
531 -
532 - /**
533 - * Output a translated text by key.
534 - *
535 - * @author Vova Feldman (@svovaf)
536 - * @since 1.2.1.7
537 - *
538 - * @param string $key
539 - * @param string $slug
540 - */
541 - function fs_echo( $key, $slug = 'freemius' ) {
542 - echo fs_text( $key, $slug );
543 - }
544 - }
545 -
546 - /**
547 - * @author Vova Feldman
548 - * @since 1.2.1.6
549 - *
550 - * @param string $key
551 - * @param string $slug
552 - *
553 - * @return string
554 - */
555 - function fs_esc_attr( $key, $slug ) {
556 - return esc_attr( fs_text( $key, $slug ) );
557 - }
558 -
559 - /**
560 - * @author Vova Feldman
561 - * @since 1.2.1.6
562 - *
563 - * @param string $key
564 - * @param string $slug
565 - */
566 - function fs_esc_attr_echo( $key, $slug ) {
567 - echo esc_attr( fs_text( $key, $slug ) );
568 - }
569 -
570 - /**
571 - * @author Vova Feldman
572 - * @since 1.2.1.6
573 - *
574 - * @param string $key
575 - * @param string $slug
576 - *
577 - * @return string
578 - */
579 - function fs_esc_js( $key, $slug ) {
580 - return esc_js( fs_text( $key, $slug ) );
581 - }
582 -
583 - /**
584 - * @author Vova Feldman
585 - * @since 1.2.1.6
586 - *
587 - * @param string $key
588 - * @param string $slug
589 - */
590 - function fs_esc_js_echo( $key, $slug ) {
591 - echo esc_js( fs_text( $key, $slug ) );
592 - }
593 -
594 - /**
595 - * @author Vova Feldman
596 - * @since 1.2.1.6
597 - *
598 - * @param string $key
599 - * @param string $slug
600 - */
601 - function fs_json_encode_echo( $key, $slug ) {
602 - echo json_encode( fs_text( $key, $slug ) );
603 - }
604 -
605 - /**
606 - * @author Vova Feldman
607 - * @since 1.2.1.6
608 - *
609 - * @param string $key
610 - * @param string $slug
611 - *
612 - * @return string
613 - */
614 - function fs_esc_html( $key, $slug ) {
615 - return esc_html( fs_text( $key, $slug ) );
616 - }
617 -
618 - /**
619 - * @author Vova Feldman
620 - * @since 1.2.1.6
621 - *
622 - * @param string $key
623 - * @param string $slug
624 - */
625 - function fs_esc_html_echo( $key, $slug ) {
626 - echo esc_html( fs_text( $key, $slug ) );
627 - }
628 -
629 -#endregion
1 +<?php
2 + /**
3 + * @package Freemius
4 + * @copyright Copyright (c) 2015, Freemius, Inc.
5 + * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 + * @since 1.0.3
7 + */
8 +
9 + if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 + }
12 +
13 + if ( ! function_exists( 'fs_dummy' ) ) {
14 + function fs_dummy() {
15 + }
16 + }
17 +
18 + /* Url.
19 + --------------------------------------------------------------------------------------------*/
20 + if ( ! function_exists( 'fs_get_url_daily_cache_killer' ) ) {
21 + function fs_get_url_daily_cache_killer() {
22 + return date( '\YY\Mm\Dd' );
23 + }
24 + }
25 +
26 + /* Templates / Views.
27 + --------------------------------------------------------------------------------------------*/
28 + if ( ! function_exists( 'fs_get_template_path' ) ) {
29 + function fs_get_template_path( $path ) {
30 + return WP_FS__DIR_TEMPLATES . '/' . trim( $path, '/' );
31 + }
32 +
33 + function fs_include_template( $path, &$params = null ) {
34 + $VARS = &$params;
35 + include fs_get_template_path( $path );
36 + }
37 +
38 + function fs_include_once_template( $path, &$params = null ) {
39 + $VARS = &$params;
40 + include_once fs_get_template_path( $path );
41 + }
42 +
43 + function fs_require_template( $path, &$params = null ) {
44 + $VARS = &$params;
45 + require fs_get_template_path( $path );
46 + }
47 +
48 + function fs_require_once_template( $path, &$params = null ) {
49 + $VARS = &$params;
50 + require_once fs_get_template_path( $path );
51 + }
52 +
53 + function fs_get_template( $path, &$params = null ) {
54 + ob_start();
55 +
56 + $VARS = &$params;
57 + require fs_get_template_path( $path );
58 +
59 + return ob_get_clean();
60 + }
61 + }
62 +
63 + /* Scripts and styles including.
64 + --------------------------------------------------------------------------------------------*/
65 +
66 + if ( ! function_exists( 'fs_asset_url' ) ) {
67 + /**
68 + * Generates an absolute URL to the given path. This function ensures that the URL will be correct whether the asset
69 + * is inside a plugin's folder or a theme's folder.
70 + *
71 + * Examples:
72 + * 1. "themes" folder
73 + * Path: C:/xampp/htdocs/fswp/wp-content/themes/twentytwelve/freemius/assets/css/admin/common.css
74 + * URL: http://fswp:8080/wp-content/themes/twentytwelve/freemius/assets/css/admin/common.css
75 + *
76 + * 2. "plugins" folder
77 + * Path: C:/xampp/htdocs/fswp/wp-content/plugins/rating-widget-premium/freemius/assets/css/admin/common.css
78 + * URL: http://fswp:8080/wp-content/plugins/rating-widget-premium/freemius/assets/css/admin/common.css
79 + *
80 + * @author Leo Fajardo (@leorw)
81 + * @since 1.2.2
82 + *
83 + * @param string $asset_abs_path Asset's absolute path.
84 + *
85 + * @return string Asset's URL.
86 + */
87 + function fs_asset_url( $asset_abs_path ) {
88 + $wp_content_dir = fs_normalize_path( WP_CONTENT_DIR );
89 + $asset_abs_path = fs_normalize_path( $asset_abs_path );
90 +
91 + if ( 0 === strpos( $asset_abs_path, $wp_content_dir ) ) {
92 + // Handle both theme and plugin assets located in the standard directories.
93 + $asset_rel_path = str_replace( $wp_content_dir, '', $asset_abs_path );
94 + $asset_url = content_url( fs_normalize_path( $asset_rel_path ) );
95 + } else {
96 + $wp_plugins_dir = fs_normalize_path( WP_PLUGIN_DIR );
97 + if ( 0 === strpos( $asset_abs_path, $wp_plugins_dir ) ) {
98 + // Try to handle plugin assets that may be located in a non-standard plugins directory.
99 + $asset_rel_path = str_replace( $wp_plugins_dir, '', $asset_abs_path );
100 + $asset_url = plugins_url( fs_normalize_path( $asset_rel_path ) );
101 + } else {
102 + // Try to handle theme assets that may be located in a non-standard themes directory.
103 + $active_theme_stylesheet = get_stylesheet();
104 + $wp_themes_dir = fs_normalize_path( trailingslashit( get_theme_root( $active_theme_stylesheet ) ) );
105 + $asset_rel_path = str_replace( $wp_themes_dir, '', fs_normalize_path( $asset_abs_path ) );
106 + $asset_url = trailingslashit( get_theme_root_uri( $active_theme_stylesheet ) ) . fs_normalize_path( $asset_rel_path );
107 + }
108 + }
109 +
110 + return $asset_url;
111 + }
112 + }
113 +
114 + if ( ! function_exists( 'fs_enqueue_local_style' ) ) {
115 + function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
116 + wp_enqueue_style( $handle, fs_asset_url( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ), $deps, $ver, $media );
117 + }
118 + }
119 +
120 + if ( ! function_exists( 'fs_enqueue_local_script' ) ) {
121 + function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = true ) {
122 + wp_enqueue_script( $handle, fs_asset_url( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ), $deps, $ver, $in_footer );
123 + }
124 + }
125 +
126 + if ( ! function_exists( 'fs_img_url' ) ) {
127 + function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) {
128 + return ( fs_asset_url( $img_dir . '/' . trim( $path, '/' ) ) );
129 + }
130 + }
131 +
132 + #--------------------------------------------------------------------------------
133 + #region Request handlers.
134 + #--------------------------------------------------------------------------------
135 +
136 + if ( ! function_exists( 'fs_request_get_raw' ) ) {
137 + /**
138 + * A helper function to fetch GET/POST user input with an optional default value when the input is not set.
139 + * This function does not do sanitization. It is up to the caller to properly sanitize and validate the input.
140 + *
141 + * The return of this function is always unslashed.
142 + *
143 + * @since 2.5.10
144 + *
145 + * @param string $key
146 + * @param mixed $def
147 + * @param string|bool $type When set to 'get', it will look for the value passed via query string. When
148 + * set to 'post', it will look for the value passed via the POST request's body. Otherwise,
149 + * it will check if the parameter was passed using any of the mentioned two methods.
150 + *
151 + * @return mixed
152 + */
153 + function fs_request_get_raw( $key, $def = false, $type = false ) {
154 + if ( is_string( $type ) ) {
155 + $type = strtolower( $type );
156 + }
157 +
158 + /**
159 + * Note to WordPress.org reviewers:
160 + * This is a helper function to fetch GET/POST user input with an optional default value when the input is not set. The actual sanitization is done in the scope of the function's usage.
161 + */
162 + switch ( $type ) {
163 + case 'post':
164 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
165 + $value = isset( $_POST[ $key ] ) ? $_POST[ $key ] : $def;
166 + break;
167 + case 'get':
168 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
169 + $value = isset( $_GET[ $key ] ) ? $_GET[ $key ] : $def;
170 + break;
171 + default:
172 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
173 + $value = isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def;
174 + break;
175 + }
176 +
177 + // Don't unslash if the value itself is empty (empty string, null, empty array etc).
178 + return empty( $value ) ? $value : wp_unslash( $value );
179 + }
180 + }
181 +
182 + if ( ! function_exists( 'fs_sanitize_input' ) ) {
183 + /**
184 + * Sanitizes input recursively (if an array).
185 + *
186 + * @param mixed $input
187 + *
188 + * @return mixed
189 + * @uses sanitize_text_field()
190 + * @since 2.5.10
191 + */
192 + function fs_sanitize_input( $input ) {
193 + if ( is_array( $input ) ) {
194 + foreach ( $input as $key => $value ) {
195 + $input[ $key ] = fs_sanitize_input( $value );
196 + }
197 + } else {
198 + // Allow empty values to pass through as-is, like `null`, `''`, `0`, `'0'` etc.
199 + $input = empty( $input ) ? $input : sanitize_text_field( $input );
200 + }
201 +
202 + return $input;
203 + }
204 + }
205 +
206 + if ( ! function_exists( 'fs_request_get' ) ) {
207 + /**
208 + * A helper method to fetch GET/POST user input with an optional default value when the input is not set.
209 + *
210 + * @author Vova Feldman (@svovaf)
211 + *
212 + * @note The return value is always sanitized with sanitize_text_field().
213 + *
214 + * @param string $key
215 + * @param mixed $def
216 + * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when
217 + * set to 'post' will look for the value passed via the POST request's body, otherwise,
218 + * will check if the parameter was passed in any of the two.
219 + *
220 + *
221 + * @return mixed
222 + */
223 + function fs_request_get( $key, $def = false, $type = false ) {
224 + return fs_sanitize_input( fs_request_get_raw( $key, $def, $type ) );
225 + }
226 + }
227 +
228 + if ( ! function_exists( 'fs_request_has' ) ) {
229 + function fs_request_has( $key ) {
230 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
231 + return isset( $_REQUEST[ $key ] );
232 + }
233 + }
234 +
235 + if ( ! function_exists( 'fs_request_get_bool' ) ) {
236 + /**
237 + * A helper method to fetch GET/POST user boolean input with an optional default value when the input is not set.
238 + *
239 + * @author Vova Feldman (@svovaf)
240 + *
241 + * @param string $key
242 + * @param bool $def
243 + *
244 + * @return bool|mixed
245 + */
246 + function fs_request_get_bool( $key, $def = false ) {
247 + $val = fs_request_get( $key, null );
248 +
249 + if ( is_null( $val ) ) {
250 + return $def;
251 + }
252 +
253 + if ( is_bool( $val ) ) {
254 + return $val;
255 + } else if ( is_numeric( $val ) ) {
256 + if ( 1 == $val ) {
257 + return true;
258 + } else if ( 0 == $val ) {
259 + return false;
260 + }
261 + } else if ( is_string( $val ) ) {
262 + $val = strtolower( $val );
263 +
264 + if ( 'true' === $val ) {
265 + return true;
266 + } else if ( 'false' === $val ) {
267 + return false;
268 + }
269 + }
270 +
271 + return $def;
272 + }
273 + }
274 +
275 + if ( ! function_exists( 'fs_request_is_post' ) ) {
276 + function fs_request_is_post() {
277 + return ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) );
278 + }
279 + }
280 +
281 + if ( ! function_exists( 'fs_request_is_get' ) ) {
282 + function fs_request_is_get() {
283 + return ( 'get' === strtolower( $_SERVER['REQUEST_METHOD'] ) );
284 + }
285 + }
286 +
287 + if ( ! function_exists( 'fs_get_action' ) ) {
288 + function fs_get_action( $action_key = 'action' ) {
289 + // phpcs:disable WordPress.Security.NonceVerification.Recommended
290 + if ( ! empty( $_REQUEST[ $action_key ] ) && is_string( $_REQUEST[ $action_key ] ) ) {
291 + return strtolower( $_REQUEST[ $action_key ] );
292 + }
293 +
294 + if ( 'action' == $action_key ) {
295 + $action_key = 'fs_action';
296 +
297 + if ( ! empty( $_REQUEST[ $action_key ] ) && is_string( $_REQUEST[ $action_key ] ) ) {
298 + return strtolower( $_REQUEST[ $action_key ] );
299 + }
300 + }
301 +
302 + return false;
303 + // phpcs:enable WordPress.Security.NonceVerification.Recommended
304 + }
305 + }
306 +
307 + if ( ! function_exists( 'fs_request_is_action' ) ) {
308 + function fs_request_is_action( $action, $action_key = 'action' ) {
309 + return ( strtolower( $action ) === fs_get_action( $action_key ) );
310 + }
311 + }
312 +
313 + if ( ! function_exists( 'fs_request_is_action_secure' ) ) {
314 + /**
315 + * @author Vova Feldman (@svovaf)
316 + * @since 1.0.0
317 + *
318 + * @since 1.2.1.5 Allow nonce verification.
319 + *
320 + * @param string $action
321 + * @param string $action_key
322 + * @param string $nonce_key
323 + *
324 + * @return bool
325 + */
326 + function fs_request_is_action_secure(
327 + $action,
328 + $action_key = 'action',
329 + $nonce_key = 'nonce'
330 + ) {
331 + if ( strtolower( $action ) !== fs_get_action( $action_key ) ) {
332 + return false;
333 + }
334 +
335 + $nonce = ! empty( $_REQUEST[ $nonce_key ] ) ?
336 + $_REQUEST[ $nonce_key ] :
337 + '';
338 +
339 + if ( empty( $nonce ) ||
340 + ( false === wp_verify_nonce( $nonce, $action ) )
341 + ) {
342 + return false;
343 + }
344 +
345 + return true;
346 + }
347 + }
348 +
349 + #endregion
350 +
351 + if ( ! function_exists( 'fs_is_plugin_page' ) ) {
352 + function fs_is_plugin_page( $page_slug ) {
353 + return ( is_admin() && $page_slug === fs_request_get( 'page' ) );
354 + }
355 + }
356 +
357 + if ( ! function_exists( 'fs_get_raw_referer' ) ) {
358 + /**
359 + * Retrieves unvalidated referer from '_wp_http_referer' or HTTP referer.
360 + *
361 + * Do not use for redirects, use {@see wp_get_referer()} instead.
362 + *
363 + * @since 1.2.3
364 + *
365 + * @return string|false Referer URL on success, false on failure.
366 + */
367 + function fs_get_raw_referer() {
368 + if ( function_exists( 'wp_get_raw_referer' ) ) {
369 + return wp_get_raw_referer();
370 + }
371 + if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
372 + return wp_unslash( $_REQUEST['_wp_http_referer'] );
373 + } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
374 + return wp_unslash( $_SERVER['HTTP_REFERER'] );
375 + }
376 +
377 + return false;
378 + }
379 + }
380 +
381 + /* Core UI.
382 + --------------------------------------------------------------------------------------------*/
383 + if ( ! function_exists( 'fs_ui_action_button' ) ) {
384 + /**
385 + * @param number $module_id
386 + * @param string $page
387 + * @param string $action
388 + * @param string $title
389 + * @param string $button_class
390 + * @param array $params
391 + * @param bool $is_primary
392 + * @param bool $is_small
393 + * @param string|bool $icon_class Optional class for an icon (since 1.1.7).
394 + * @param string|bool $confirmation Optional confirmation message before submit (since 1.1.7).
395 + * @param string $method Since 1.1.7
396 + *
397 + * @uses fs_ui_get_action_button()
398 + */
399 + function fs_ui_action_button(
400 + $module_id,
401 + $page,
402 + $action,
403 + $title,
404 + $button_class = '',
405 + $params = array(),
406 + $is_primary = true,
407 + $is_small = false,
408 + $icon_class = false,
409 + $confirmation = false,
410 + $method = 'GET'
411 + ) {
412 + echo fs_ui_get_action_button(
413 + $module_id,
414 + $page,
415 + $action,
416 + $title,
417 + $button_class,
418 + $params,
419 + $is_primary,
420 + $is_small,
421 + $icon_class,
422 + $confirmation,
423 + $method
424 + );
425 + }
426 + }
427 +
428 + if ( ! function_exists( 'fs_ui_get_action_button' ) ) {
429 + /**
430 + * @author Vova Feldman (@svovaf)
431 + * @since 1.1.7
432 + *
433 + * @param number $module_id
434 + * @param string $page
435 + * @param string $action
436 + * @param string $title
437 + * @param string $button_class
438 + * @param array $params
439 + * @param bool $is_primary
440 + * @param bool $is_small
441 + * @param string|bool $icon_class Optional class for an icon.
442 + * @param string|bool $confirmation Optional confirmation message before submit.
443 + * @param string $method
444 + *
445 + * @return string
446 + */
447 + function fs_ui_get_action_button(
448 + $module_id,
449 + $page,
450 + $action,
451 + $title,
452 + $button_class = '',
453 + $params = array(),
454 + $is_primary = true,
455 + $is_small = false,
456 + $icon_class = false,
457 + $confirmation = false,
458 + $method = 'GET'
459 + ) {
460 + // Prepend icon (if set).
461 + $title = ( is_string( $icon_class ) ? '<i class="' . $icon_class . '"></i> ' : '' ) . $title;
462 +
463 + if ( is_string( $confirmation ) ) {
464 + return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="if (confirm(\'%s\')) this.parentNode.submit(); return false;">%s</a></form>',
465 + freemius( $module_id )->_get_admin_page_url( $page, $params ),
466 + $method,
467 + $action,
468 + wp_nonce_field( $action, '_wpnonce', true, false ),
469 + 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
470 + $confirmation,
471 + $title
472 + );
473 + } else if ( 'GET' !== strtoupper( $method ) ) {
474 + return sprintf( '<form action="%s" method="%s"><input type="hidden" name="fs_action" value="%s">%s<a href="#" class="%s" onclick="this.parentNode.submit(); return false;">%s</a></form>',
475 + freemius( $module_id )->_get_admin_page_url( $page, $params ),
476 + $method,
477 + $action,
478 + wp_nonce_field( $action, '_wpnonce', true, false ),
479 + 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
480 + $title
481 + );
482 + } else {
483 + return sprintf( '<a href="%s" class="%s">%s</a></form>',
484 + wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
485 + 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
486 + $title
487 + );
488 + }
489 + }
490 +
491 + function fs_ui_action_link( $module_id, $page, $action, $title, $params = array() ) {
492 + ?><a class=""
493 + href="<?php echo wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ) ?>"><?php echo $title ?></a><?php
494 + }
495 + }
496 +
497 + if ( ! function_exists( 'fs_get_entity' ) ) {
498 + /**
499 + * @author Leo Fajardo (@leorw)
500 + * @since 2.3.1
501 + *
502 + * @param mixed $entity
503 + * @param string $class
504 + *
505 + * @return FS_Plugin|FS_User|FS_Site|FS_Plugin_License|FS_Plugin_Plan|FS_Plugin_Tag|FS_Subscription
506 + */
507 + function fs_get_entity( $entity, $class ) {
508 + if ( ! is_object( $entity ) || $entity instanceof $class ) {
509 + return $entity;
510 + }
511 +
512 + return new $class( $entity );
513 + }
514 + }
515 +
516 + if ( ! function_exists( 'fs_get_entities' ) ) {
517 + /**
518 + * @author Leo Fajardo (@leorw)
519 + * @since 2.3.1
520 + *
521 + * @param mixed $entities
522 + * @param string $class_name
523 + *
524 + * @return FS_Plugin[]|FS_User[]|FS_Site[]|FS_Plugin_License[]|FS_Plugin_Plan[]|FS_Plugin_Tag[]|FS_Subscription[]
525 + */
526 + function fs_get_entities( $entities, $class_name ) {
527 + if ( ! is_array( $entities ) || empty( $entities ) ) {
528 + return $entities;
529 + }
530 +
531 + // Get first element.
532 + $first_array_element = reset( $entities );
533 +
534 + if ( $first_array_element instanceof $class_name ) {
535 + /**
536 + * If the first element of the array is an instance of the context class, assume that all other
537 + * elements are instances of the class.
538 + */
539 + return $entities;
540 + }
541 +
542 + if (
543 + is_array( $first_array_element ) &&
544 + ! empty( $first_array_element )
545 + ) {
546 + $first_array_element = reset( $first_array_element );
547 +
548 + if ( $first_array_element instanceof $class_name ) {
549 + /**
550 + * If the first element of the `$entities` array is an array whose first element is an instance of the
551 + * context class, assume that all other objects are instances of the class.
552 + */
553 + return $entities;
554 + }
555 + }
556 +
557 + foreach ( $entities as $key => $entities_or_entity ) {
558 + if ( is_array( $entities_or_entity ) ) {
559 + $entities[ $key ] = fs_get_entities( $entities_or_entity, $class_name );
560 + } else {
561 + $entities[ $key ] = fs_get_entity( $entities_or_entity, $class_name );
562 + }
563 + }
564 +
565 + return $entities;
566 + }
567 + }
568 +
569 + if ( ! function_exists( 'fs_nonce_url' ) ) {
570 + /**
571 + * Retrieve URL with nonce added to URL query.
572 + *
573 + * Originally was using `wp_nonce_url()` but the new version
574 + * changed the return value to escaped URL, that's not the expected
575 + * behaviour.
576 + *
577 + * @author Vova Feldman (@svovaf)
578 + * @since ~1.1.3
579 + *
580 + * @param string $actionurl URL to add nonce action.
581 + * @param int|string $action Optional. Nonce action name. Default -1.
582 + * @param string $name Optional. Nonce name. Default '_wpnonce'.
583 + *
584 + * @return string Escaped URL with nonce action added.
585 + */
586 + function fs_nonce_url( $actionurl, $action = - 1, $name = '_wpnonce' ) {
587 + return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
588 + }
589 + }
590 +
591 + if ( ! function_exists( 'fs_parse_url_params' ) ) {
592 + /**
593 + * Returns the query parameters of the given URL if there are any.
594 + *
595 + * @param string $url
596 + * @param bool $html_entity_decode
597 + *
598 + * @return array<string, string> Key value pair where key represents the parameter name and value represents the parameter value.
599 + */
600 + function fs_parse_url_params( $url, $html_entity_decode = false ) {
601 + $query_str = parse_url( $url, PHP_URL_QUERY );
602 + $url_params = array();
603 +
604 + if ( empty( $query_str ) ) {
605 + return $url_params;
606 + }
607 +
608 + if ( $html_entity_decode ) {
609 + $query_str = html_entity_decode( $query_str );
610 + }
611 +
612 + parse_str( $query_str, $url_params );
613 +
614 + return $url_params;
615 + }
616 + }
617 +
618 + if ( ! function_exists( 'fs_starts_with' ) ) {
619 + /**
620 + * Check if string starts with.
621 + *
622 + * @author Vova Feldman (@svovaf)
623 + * @since 1.1.3
624 + *
625 + * @param string $haystack
626 + * @param string $needle
627 + *
628 + * @return bool
629 + */
630 + function fs_starts_with( $haystack, $needle ) {
631 + $length = strlen( $needle );
632 +
633 + return ( substr( $haystack, 0, $length ) === $needle );
634 + }
635 + }
636 +
637 + if ( ! function_exists( 'fs_ends_with' ) ) {
638 + /**
639 + * Check if string ends with.
640 + *
641 + * @author Vova Feldman (@svovaf)
642 + * @since 2.0.0
643 + *
644 + * @param string $haystack
645 + * @param string $needle
646 + *
647 + * @return bool
648 + */
649 + function fs_ends_with( $haystack, $needle ) {
650 + $length = strlen( $needle );
651 + $start = $length * - 1; // negative
652 +
653 + return ( substr( $haystack, $start ) === $needle );
654 + }
655 + }
656 +
657 + if ( ! function_exists( 'fs_strip_url_protocol' ) ) {
658 + function fs_strip_url_protocol( $url ) {
659 + if ( ! fs_starts_with( $url, 'http' ) ) {
660 + return $url;
661 + }
662 +
663 + $protocol_pos = strpos( $url, '://' );
664 +
665 + if ( $protocol_pos > 5 ) {
666 + return $url;
667 + }
668 +
669 + return substr( $url, $protocol_pos + 3 );
670 + }
671 + }
672 +
673 + #region Url Canonization ------------------------------------------------------------------
674 +
675 + if ( ! function_exists( 'fs_canonize_url' ) ) {
676 + /**
677 + * @author Vova Feldman (@svovaf)
678 + * @since 1.1.3
679 + *
680 + * @param string $url
681 + * @param bool $omit_host
682 + * @param array $ignore_params
683 + *
684 + * @return string
685 + */
686 + function fs_canonize_url( $url, $omit_host = false, $ignore_params = array() ) {
687 + $parsed_url = parse_url( strtolower( $url ) );
688 +
689 +// if ( ! isset( $parsed_url['host'] ) ) {
690 +// return $url;
691 +// }
692 +
693 + $canonical = ( ( $omit_host || ! isset( $parsed_url['host'] ) ) ? '' : $parsed_url['host'] ) . $parsed_url['path'];
694 +
695 + if ( isset( $parsed_url['query'] ) ) {
696 + parse_str( $parsed_url['query'], $queryString );
697 + $canonical .= '?' . fs_canonize_query_string( $queryString, $ignore_params );
698 + }
699 +
700 + return $canonical;
701 + }
702 + }
703 +
704 + if ( ! function_exists( 'fs_canonize_query_string' ) ) {
705 + /**
706 + * @author Vova Feldman (@svovaf)
707 + * @since 1.1.3
708 + *
709 + * @param array $params
710 + * @param array $ignore_params
711 + * @param bool $params_prefix
712 + *
713 + * @return string
714 + */
715 + function fs_canonize_query_string( array $params, array &$ignore_params, $params_prefix = false ) {
716 + if ( ! is_array( $params ) || 0 === count( $params ) ) {
717 + return '';
718 + }
719 +
720 + // Url encode both keys and values
721 + $keys = fs_urlencode_rfc3986( array_keys( $params ) );
722 + $values = fs_urlencode_rfc3986( array_values( $params ) );
723 + $params = array_combine( $keys, $values );
724 +
725 + // Parameters are sorted by name, using lexicographical byte value ordering.
726 + // Ref: Spec: 9.1.1 (1)
727 + uksort( $params, 'strcmp' );
728 +
729 + $pairs = array();
730 + foreach ( $params as $parameter => $value ) {
731 + $lower_param = strtolower( $parameter );
732 +
733 + // Skip ignore params.
734 + if ( in_array( $lower_param, $ignore_params ) ||
735 + ( false !== $params_prefix && fs_starts_with( $lower_param, $params_prefix ) )
736 + ) {
737 + continue;
738 + }
739 +
740 + if ( is_array( $value ) ) {
741 + // If two or more parameters share the same name, they are sorted by their value
742 + // Ref: Spec: 9.1.1 (1)
743 + natsort( $value );
744 + foreach ( $value as $duplicate_value ) {
745 + $pairs[] = $lower_param . '=' . $duplicate_value;
746 + }
747 + } else {
748 + $pairs[] = $lower_param . '=' . $value;
749 + }
750 + }
751 +
752 + if ( 0 === count( $pairs ) ) {
753 + return '';
754 + }
755 +
756 + return implode( "&", $pairs );
757 + }
758 + }
759 +
760 + if ( ! function_exists( 'fs_urlencode_rfc3986' ) ) {
761 + /**
762 + * @author Vova Feldman (@svovaf)
763 + * @since 1.1.3
764 + *
765 + * @param string|string[] $input
766 + *
767 + * @return array|mixed|string
768 + */
769 + function fs_urlencode_rfc3986( $input ) {
770 + if ( is_array( $input ) ) {
771 + return array_map( 'fs_urlencode_rfc3986', $input );
772 + } else if ( is_scalar( $input ) ) {
773 + return str_replace( '+', ' ', str_replace( '%7E', '~', rawurlencode( $input ) ) );
774 + }
775 +
776 + return '';
777 + }
778 + }
779 +
780 + #endregion Url Canonization ------------------------------------------------------------------
781 +
782 + if ( ! function_exists( 'fs_download_image' ) ) {
783 + /**
784 + * @author Vova Feldman (@svovaf)
785 + *
786 + * @since 1.2.2 Changed to usage of WP_Filesystem_Direct.
787 + *
788 + * @param string $from URL
789 + * @param string $to File path.
790 + *
791 + * @return bool Is successfully downloaded.
792 + */
793 + function fs_download_image( $from, $to ) {
794 + $dir = dirname( $to );
795 +
796 + if ( 'direct' !== get_filesystem_method( array(), $dir ) ) {
797 + return false;
798 + }
799 +
800 + if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
801 + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
802 + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
803 + }
804 +
805 + $fs = new WP_Filesystem_Direct( '' );
806 + $tmpfile = download_url( $from );
807 +
808 + if ( $tmpfile instanceof WP_Error ) {
809 + // Issue downloading the file.
810 + return false;
811 + }
812 +
813 + $fs->copy( $tmpfile, $to );
814 + $fs->delete( $tmpfile );
815 +
816 + return true;
817 + }
818 + }
819 +
820 + /* General Utilities
821 + --------------------------------------------------------------------------------------------*/
822 +
823 + if ( ! function_exists( 'fs_sort_by_priority' ) ) {
824 + /**
825 + * Sorts an array by the value of the priority key.
826 + *
827 + * @author Daniel Iser (@danieliser)
828 + * @since 1.1.7
829 + *
830 + * @param $a
831 + * @param $b
832 + *
833 + * @return int
834 + */
835 + function fs_sort_by_priority( $a, $b ) {
836 +
837 + // If b has a priority and a does not, b wins.
838 + if ( ! isset( $a['priority'] ) && isset( $b['priority'] ) ) {
839 + return 1;
840 + } // If b has a priority and a does not, b wins.
841 + elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
842 + return - 1;
843 + } // If neither has a priority or both priorities are equal it's a tie.
844 + elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
845 + return 0;
846 + }
847 +
848 + // If both have priority return the winner.
849 + return ( $a['priority'] < $b['priority'] ) ? - 1 : 1;
850 + }
851 + }
852 +
853 + #--------------------------------------------------------------------------------
854 + #region Localization
855 + #--------------------------------------------------------------------------------
856 +
857 + global $fs_text_overrides;
858 +
859 + if ( ! isset( $fs_text_overrides ) ) {
860 + $fs_text_overrides = array();
861 + }
862 +
863 + if ( ! function_exists( 'fs_text' ) ) {
864 + /**
865 + * Retrieve a translated text by key.
866 + *
867 + * @author Vova Feldman (@svovaf)
868 + * @since 1.2.1.7
869 + *
870 + * @param string $key
871 + * @param string $slug
872 + *
873 + * @return string
874 + *
875 + * @global $fs_text_overrides
876 + */
877 + function fs_text( $key, $slug = 'freemius' ) {
878 + global $fs_text_overrides;
879 +
880 + if ( isset( $fs_text_overrides[ $slug ] ) ) {
881 + if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
882 + return $fs_text_overrides[ $slug ][ $key ];
883 + }
884 +
885 + $lower_key = strtolower( $key );
886 + if ( isset( $fs_text_overrides[ $slug ][ $lower_key ] ) ) {
887 + return $fs_text_overrides[ $slug ][ $lower_key ];
888 + }
889 + }
890 +
891 + return $key;
892 + }
893 +
894 + #region Private
895 +
896 + /**
897 + * Retrieve an inline translated text by key with a context.
898 + *
899 + * @author Vova Feldman (@svovaf)
900 + * @since 1.2.3
901 + *
902 + * @param string $text Translatable string.
903 + * @param string $context Context information for the translators.
904 + * @param string $key String key for overrides.
905 + * @param string $slug Module slug for overrides.
906 + *
907 + * @return string
908 + *
909 + * @global $fs_text_overrides
910 + */
911 + function _fs_text_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
912 + list( $text, $text_domain ) = fs_text_and_domain( $text, $key, $slug );
913 +
914 + // Avoid misleading Theme Check warning.
915 + $fn = 'translate_with_gettext_context';
916 +
917 + return $fn( $text, $context, $text_domain );
918 + }
919 +
920 + #endregion
921 +
922 + /**
923 + * Retrieve an inline translated text by key with a context.
924 + *
925 + * @author Vova Feldman (@svovaf)
926 + * @since 1.2.3
927 + *
928 + * @param string $text Translatable string.
929 + * @param string $context Context information for the translators.
930 + * @param string $key String key for overrides.
931 + * @param string $slug Module slug for overrides.
932 + *
933 + * @return string
934 + *
935 + * @global $fs_text_overrides
936 + */
937 + function fs_text_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
938 + return _fs_text_x_inline( $text, $context, $key, $slug );
939 + }
940 +
941 + /**
942 + * Output a translated text by key.
943 + *
944 + * @author Vova Feldman (@svovaf)
945 + * @since 1.2.1.7
946 + *
947 + * @param string $key
948 + * @param string $slug
949 + */
950 + function fs_echo( $key, $slug = 'freemius' ) {
951 + echo fs_text( $key, $slug );
952 + }
953 +
954 + /**
955 + * Output an inline translated text.
956 + *
957 + * @author Vova Feldman (@svovaf)
958 + * @since 1.2.3
959 + *
960 + * @param string $text Translatable string.
961 + * @param string $key String key for overrides.
962 + * @param string $slug Module slug for overrides.
963 + */
964 + function fs_echo_inline( $text, $key = '', $slug = 'freemius' ) {
965 + echo _fs_text_inline( $text, $key, $slug );
966 + }
967 +
968 + /**
969 + * Output an inline translated text with a context.
970 + *
971 + * @author Vova Feldman (@svovaf)
972 + * @since 1.2.3
973 + *
974 + * @param string $text Translatable string.
975 + * @param string $context Context information for the translators.
976 + * @param string $key String key for overrides.
977 + * @param string $slug Module slug for overrides.
978 + */
979 + function fs_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
980 + echo _fs_text_x_inline( $text, $context, $key, $slug );
981 + }
982 + }
983 +
984 + if ( ! function_exists( 'fs_text_override' ) ) {
985 + /**
986 + * Get a translatable text override if exists, or `false`.
987 + *
988 + * @author Vova Feldman (@svovaf)
989 + * @since 1.2.1.7
990 + *
991 + * @param string $text Translatable string.
992 + * @param string $key String key for overrides.
993 + * @param string $slug Module slug for overrides.
994 + *
995 + * @return string|false
996 + */
997 + function fs_text_override( $text, $key, $slug ) {
998 + global $fs_text_overrides;
999 +
1000 + /**
1001 + * Check if string is overridden.
1002 + */
1003 + if ( ! isset( $fs_text_overrides[ $slug ] ) ) {
1004 + return false;
1005 + }
1006 +
1007 + if ( empty( $key ) ) {
1008 + $key = strtolower( str_replace( ' ', '-', $text ) );
1009 + }
1010 +
1011 + if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
1012 + return $fs_text_overrides[ $slug ][ $key ];
1013 + }
1014 +
1015 + $lower_key = strtolower( $key );
1016 + if ( isset( $fs_text_overrides[ $slug ][ $lower_key ] ) ) {
1017 + return $fs_text_overrides[ $slug ][ $lower_key ];
1018 + }
1019 +
1020 + return false;
1021 + }
1022 + }
1023 +
1024 + if ( ! function_exists( 'fs_text_and_domain' ) ) {
1025 + /**
1026 + * Get a translatable text and its text domain.
1027 + *
1028 + * When the text is overridden by the module, returns the overridden text and the text domain of the module. Otherwise, returns the original text and 'freemius' as the text domain.
1029 + *
1030 + * @author Vova Feldman (@svovaf)
1031 + * @since 1.2.1.7
1032 + *
1033 + * @param string $text Translatable string.
1034 + * @param string $key String key for overrides.
1035 + * @param string $slug Module slug for overrides.
1036 + *
1037 + * @return string[]
1038 + */
1039 + function fs_text_and_domain( $text, $key, $slug ) {
1040 + $override = fs_text_override( $text, $key, $slug );
1041 +
1042 + if ( false === $override ) {
1043 + // No override, use FS text domain.
1044 + $text_domain = 'freemius';
1045 + } else {
1046 + // Found an override.
1047 + $text = $override;
1048 + // Use the module's text domain.
1049 + $text_domain = $slug;
1050 + }
1051 +
1052 + return array( $text, $text_domain );
1053 + }
1054 + }
1055 +
1056 + if ( ! function_exists( '_fs_text_inline' ) ) {
1057 + /**
1058 + * Retrieve an inline translated text by key.
1059 + *
1060 + * @author Vova Feldman (@svovaf)
1061 + * @since 1.2.3
1062 + *
1063 + * @param string $text Translatable string.
1064 + * @param string $key String key for overrides.
1065 + * @param string $slug Module slug for overrides.
1066 + *
1067 + * @return string
1068 + *
1069 + * @global $fs_text_overrides
1070 + */
1071 + function _fs_text_inline( $text, $key = '', $slug = 'freemius' ) {
1072 + list( $text, $text_domain ) = fs_text_and_domain( $text, $key, $slug );
1073 +
1074 + // Avoid misleading Theme Check warning.
1075 + $fn = 'translate';
1076 +
1077 + return $fn( $text, $text_domain );
1078 + }
1079 + }
1080 +
1081 + if ( ! function_exists( 'fs_text_inline' ) ) {
1082 + /**
1083 + * Retrieve an inline translated text by key.
1084 + *
1085 + * @author Vova Feldman (@svovaf)
1086 + * @since 1.2.3
1087 + *
1088 + * @param string $text Translatable string.
1089 + * @param string $key String key for overrides.
1090 + * @param string $slug Module slug for overrides.
1091 + *
1092 + * @return string
1093 + *
1094 + * @global $fs_text_overrides
1095 + */
1096 + function fs_text_inline( $text, $key = '', $slug = 'freemius' ) {
1097 + return _fs_text_inline( $text, $key, $slug );
1098 + }
1099 + }
1100 +
1101 + if ( ! function_exists( 'fs_esc_attr' ) ) {
1102 + /**
1103 + * @author Vova Feldman
1104 + * @since 1.2.1.6
1105 + *
1106 + * @param string $key
1107 + * @param string $slug
1108 + *
1109 + * @return string
1110 + */
1111 + function fs_esc_attr( $key, $slug ) {
1112 + return esc_attr( fs_text( $key, $slug ) );
1113 + }
1114 + }
1115 +
1116 + if ( ! function_exists( 'fs_esc_attr_inline' ) ) {
1117 + /**
1118 + * @author Vova Feldman (@svovaf)
1119 + * @since 1.2.3
1120 + *
1121 + * @param string $text Translatable string.
1122 + * @param string $key String key for overrides.
1123 + * @param string $slug Module slug for overrides.
1124 + *
1125 + * @return string
1126 + */
1127 + function fs_esc_attr_inline( $text, $key = '', $slug = 'freemius' ) {
1128 + return esc_attr( _fs_text_inline( $text, $key, $slug ) );
1129 + }
1130 + }
1131 +
1132 + if ( ! function_exists( 'fs_esc_attr_x_inline' ) ) {
1133 + /**
1134 + * @author Vova Feldman (@svovaf)
1135 + * @since 1.2.3
1136 + *
1137 + * @param string $text Translatable string.
1138 + * @param string $context Context information for the translators.
1139 + * @param string $key String key for overrides.
1140 + * @param string $slug Module slug for overrides.
1141 + *
1142 + * @return string
1143 + */
1144 + function fs_esc_attr_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1145 + return esc_attr( _fs_text_x_inline( $text, $context, $key, $slug ) );
1146 + }
1147 + }
1148 +
1149 + if ( ! function_exists( 'fs_esc_attr_echo' ) ) {
1150 + /**
1151 + * @author Vova Feldman
1152 + * @since 1.2.1.6
1153 + *
1154 + * @param string $key
1155 + * @param string $slug
1156 + */
1157 + function fs_esc_attr_echo( $key, $slug ) {
1158 + echo esc_attr( fs_text( $key, $slug ) );
1159 + }
1160 + }
1161 +
1162 + if ( ! function_exists( 'fs_esc_attr_echo_inline' ) ) {
1163 + /**
1164 + * @author Vova Feldman (@svovaf)
1165 + * @since 1.2.3
1166 + *
1167 + * @param string $text Translatable string.
1168 + * @param string $key String key for overrides.
1169 + * @param string $slug Module slug for overrides.
1170 + */
1171 + function fs_esc_attr_echo_inline( $text, $key = '', $slug = 'freemius' ) {
1172 + echo esc_attr( _fs_text_inline( $text, $key, $slug ) );
1173 + }
1174 + }
1175 +
1176 + if ( ! function_exists( 'fs_esc_js' ) ) {
1177 + /**
1178 + * @author Vova Feldman
1179 + * @since 1.2.1.6
1180 + *
1181 + * @param string $key
1182 + * @param string $slug
1183 + *
1184 + * @return string
1185 + */
1186 + function fs_esc_js( $key, $slug ) {
1187 + return esc_js( fs_text( $key, $slug ) );
1188 + }
1189 + }
1190 +
1191 + if ( ! function_exists( 'fs_esc_js_inline' ) ) {
1192 + /**
1193 + * @author Vova Feldman (@svovaf)
1194 + * @since 1.2.3
1195 + *
1196 + * @param string $text Translatable string.
1197 + * @param string $key String key for overrides.
1198 + * @param string $slug Module slug for overrides.
1199 + *
1200 + * @return string
1201 + */
1202 + function fs_esc_js_inline( $text, $key = '', $slug = 'freemius' ) {
1203 + return esc_js( _fs_text_inline( $text, $key, $slug ) );
1204 + }
1205 + }
1206 +
1207 + if ( ! function_exists( 'fs_esc_js_x_inline' ) ) {
1208 + /**
1209 + * @author Vova Feldman (@svovaf)
1210 + * @since 1.2.3
1211 + *
1212 + * @param string $text Translatable string.
1213 + * @param string $context Context information for the translators.
1214 + * @param string $key String key for overrides.
1215 + * @param string $slug Module slug for overrides.
1216 + *
1217 + * @return string
1218 + */
1219 + function fs_esc_js_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1220 + return esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) );
1221 + }
1222 + }
1223 +
1224 + if ( ! function_exists( 'fs_esc_js_echo_x_inline' ) ) {
1225 + /**
1226 + * @author Vova Feldman (@svovaf)
1227 + * @since 1.2.3
1228 + *
1229 + * @param string $text Translatable string.
1230 + * @param string $context Context information for the translators.
1231 + * @param string $key String key for overrides.
1232 + * @param string $slug Module slug for overrides.
1233 + *
1234 + * @return void
1235 + */
1236 + function fs_esc_js_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1237 + echo esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) );
1238 + }
1239 + }
1240 +
1241 + if ( ! function_exists( 'fs_esc_js_echo' ) ) {
1242 + /**
1243 + * @author Vova Feldman
1244 + * @since 1.2.1.6
1245 + *
1246 + * @param string $key
1247 + * @param string $slug
1248 + */
1249 + function fs_esc_js_echo( $key, $slug ) {
1250 + echo esc_js( fs_text( $key, $slug ) );
1251 + }
1252 + }
1253 +
1254 + if ( ! function_exists( 'fs_esc_js_echo_inline' ) ) {
1255 + /**
1256 + * @author Vova Feldman (@svovaf)
1257 + * @since 1.2.3
1258 + *
1259 + * @param string $text Translatable string.
1260 + * @param string $key String key for overrides.
1261 + * @param string $slug Module slug for overrides.
1262 + */
1263 + function fs_esc_js_echo_inline( $text, $key = '', $slug = 'freemius' ) {
1264 + echo esc_js( _fs_text_inline( $text, $key, $slug ) );
1265 + }
1266 + }
1267 +
1268 + if ( ! function_exists( 'fs_json_encode_echo' ) ) {
1269 + /**
1270 + * @author Vova Feldman
1271 + * @since 1.2.1.6
1272 + *
1273 + * @param string $key
1274 + * @param string $slug
1275 + */
1276 + function fs_json_encode_echo( $key, $slug ) {
1277 + echo json_encode( fs_text( $key, $slug ) );
1278 + }
1279 + }
1280 +
1281 + if ( ! function_exists( 'fs_json_encode_echo_inline' ) ) {
1282 + /**
1283 + * @author Vova Feldman (@svovaf)
1284 + * @since 1.2.3
1285 + *
1286 + * @param string $text Translatable string.
1287 + * @param string $key String key for overrides.
1288 + * @param string $slug Module slug for overrides.
1289 + */
1290 + function fs_json_encode_echo_inline( $text, $key = '', $slug = 'freemius' ) {
1291 + echo json_encode( _fs_text_inline( $text, $key, $slug ) );
1292 + }
1293 + }
1294 +
1295 + if ( ! function_exists( 'fs_esc_html' ) ) {
1296 + /**
1297 + * @author Vova Feldman
1298 + * @since 1.2.1.6
1299 + *
1300 + * @param string $key
1301 + * @param string $slug
1302 + *
1303 + * @return string
1304 + */
1305 + function fs_esc_html( $key, $slug ) {
1306 + return esc_html( fs_text( $key, $slug ) );
1307 + }
1308 + }
1309 +
1310 + if ( ! function_exists( 'fs_esc_html_inline' ) ) {
1311 + /**
1312 + * @author Vova Feldman (@svovaf)
1313 + * @since 1.2.3
1314 + *
1315 + * @param string $text Translatable string.
1316 + * @param string $key String key for overrides.
1317 + * @param string $slug Module slug for overrides.
1318 + *
1319 + * @return string
1320 + */
1321 + function fs_esc_html_inline( $text, $key = '', $slug = 'freemius' ) {
1322 + return esc_html( _fs_text_inline( $text, $key, $slug ) );
1323 + }
1324 + }
1325 +
1326 + if ( ! function_exists( 'fs_esc_html_x_inline' ) ) {
1327 + /**
1328 + * @author Vova Feldman (@svovaf)
1329 + * @since 1.2.3
1330 + *
1331 + * @param string $text Translatable string.
1332 + * @param string $context Context information for the translators.
1333 + * @param string $key String key for overrides.
1334 + * @param string $slug Module slug for overrides.
1335 + *
1336 + * @return string
1337 + */
1338 + function fs_esc_html_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1339 + return esc_html( _fs_text_x_inline( $text, $context, $key, $slug ) );
1340 + }
1341 + }
1342 +
1343 + if ( ! function_exists( 'fs_esc_html_echo_x_inline' ) ) {
1344 + /**
1345 + * @author Vova Feldman (@svovaf)
1346 + * @since 1.2.3
1347 + *
1348 + * @param string $text Translatable string.
1349 + * @param string $context Context information for the translators.
1350 + * @param string $key String key for overrides.
1351 + * @param string $slug Module slug for overrides.
1352 + */
1353 + function fs_esc_html_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1354 + echo esc_html( _fs_text_x_inline( $text, $context, $key, $slug ) );
1355 + }
1356 + }
1357 +
1358 + if ( ! function_exists( 'fs_esc_html_echo' ) ) {
1359 + /**
1360 + * @author Vova Feldman
1361 + * @since 1.2.1.6
1362 + *
1363 + * @param string $key
1364 + * @param string $slug
1365 + */
1366 + function fs_esc_html_echo( $key, $slug ) {
1367 + echo esc_html( fs_text( $key, $slug ) );
1368 + }
1369 + }
1370 +
1371 + if ( ! function_exists( 'fs_esc_html_echo_inline' ) ) {
1372 + /**
1373 + * @author Vova Feldman (@svovaf)
1374 + * @since 1.2.3
1375 + *
1376 + * @param string $text Translatable string.
1377 + * @param string $key String key for overrides.
1378 + * @param string $slug Module slug for overrides.
1379 + */
1380 + function fs_esc_html_echo_inline( $text, $key = '', $slug = 'freemius' ) {
1381 + echo esc_html( _fs_text_inline( $text, $key, $slug ) );
1382 + }
1383 + }
1384 +
1385 + if ( ! function_exists( 'fs_override_i18n' ) ) {
1386 + /**
1387 + * Override default i18n text phrases.
1388 + *
1389 + * @author Vova Feldman (@svovaf)
1390 + * @since 1.1.6
1391 + *
1392 + * @param array[string]string $key_value
1393 + * @param string $slug
1394 + *
1395 + * @global $fs_text_overrides
1396 + */
1397 + function fs_override_i18n( array $key_value, $slug = 'freemius' ) {
1398 + global $fs_text_overrides;
1399 +
1400 + if ( ! isset( $fs_text_overrides[ $slug ] ) ) {
1401 + $fs_text_overrides[ $slug ] = array();
1402 + }
1403 +
1404 + foreach ( $key_value as $key => $value ) {
1405 + $fs_text_overrides[ $slug ][ $key ] = $value;
1406 + }
1407 + }
1408 + }
1409 +
1410 + #endregion
1411 +
1412 + #--------------------------------------------------------------------------------
1413 + #region Multisite Network
1414 + #--------------------------------------------------------------------------------
1415 +
1416 + if ( ! function_exists( 'fs_is_plugin_uninstall' ) ) {
1417 + /**
1418 + * @author Vova Feldman (@svovaf)
1419 + * @since 2.0.0
1420 + */
1421 + function fs_is_plugin_uninstall() {
1422 + return (
1423 + defined( 'WP_UNINSTALL_PLUGIN' ) ||
1424 + ( 0 < did_action( 'pre_uninstall_plugin' ) )
1425 + );
1426 + }
1427 + }
1428 +
1429 + if ( ! function_exists( 'fs_is_network_admin' ) ) {
1430 + /**
1431 + * Unlike is_network_admin(), this one will also work properly when
1432 + * the context execution is WP AJAX handler, and during plugin
1433 + * uninstall.
1434 + *
1435 + * @author Vova Feldman (@svovaf)
1436 + * @since 2.0.0
1437 + */
1438 + function fs_is_network_admin() {
1439 + return (
1440 + WP_FS__IS_NETWORK_ADMIN ||
1441 + ( is_multisite() && fs_is_plugin_uninstall() )
1442 + );
1443 + }
1444 + }
1445 +
1446 + if ( ! function_exists( 'fs_is_blog_admin' ) ) {
1447 + /**
1448 + * Unlike is_blog_admin(), this one will also work properly when
1449 + * the context execution is WP AJAX handler, and during plugin
1450 + * uninstall.
1451 + *
1452 + * @author Vova Feldman (@svovaf)
1453 + * @since 2.0.0
1454 + */
1455 + function fs_is_blog_admin() {
1456 + return (
1457 + WP_FS__IS_BLOG_ADMIN ||
1458 + ( ! is_multisite() && fs_is_plugin_uninstall() )
1459 + );
1460 + }
1461 + }
1462 +
1463 + #endregion
1464 +
1465 + if ( ! function_exists( 'fs_apply_filter' ) ) {
1466 + /**
1467 + * Apply filter for specific plugin.
1468 + *
1469 + * @author Vova Feldman (@svovaf)
1470 + * @since 1.0.9
1471 + *
1472 + * @param string $module_unique_affix Module's unique affix.
1473 + * @param string $tag The name of the filter hook.
1474 + * @param mixed $value The value on which the filters hooked to `$tag` are applied on.
1475 + *
1476 + * @return mixed The filtered value after all hooked functions are applied to it.
1477 + *
1478 + * @uses apply_filters()
1479 + */
1480 + function fs_apply_filter( $module_unique_affix, $tag, $value ) {
1481 + $args = func_get_args();
1482 +
1483 + return call_user_func_array( 'apply_filters', array_merge(
1484 + array( "fs_{$tag}_{$module_unique_affix}" ),
1485 + array_slice( $args, 2 ) )
1486 + );
1487 + }
1488 + }
1489 +
1490 + if ( ! function_exists( 'fs_get_optional_constant' ) ) {
1491 + /**
1492 + * Gets the value of an optional constant. If the constant is not defined, the default value will be returned.
1493 + *
1494 + * @author Swashata Ghosh (@swashata)
1495 + * @since 2.5.12.5
1496 + *
1497 + * @param string $constant_name
1498 + * @param mixed $default_value
1499 + *
1500 + * @return mixed
1501 + */
1502 + function fs_get_optional_constant( $constant_name, $default_value = null ) {
1503 + return defined( $constant_name ) ? constant( $constant_name ) : $default_value;
1504 + }
1505 + }