PluginProbe
Tiered Pricing Table for WooCommerce / 8.0.2
Tiered Pricing Table for WooCommerce v8.0.2
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
← All changes | freemius/includes/fs-core-functions.php +402 -248 2.3.2 → 8.0.2 View file →
@@ -62,64 +62,72 @@
62 62
63 63 /* Scripts and styles including.
64 64 --------------------------------------------------------------------------------------------*/
65 65
66 - /**
67 - * Generates an absolute URL to the given path. This function ensures that the URL will be correct whether the asset
68 - * is inside a plugin's folder or a theme's folder.
69 - *
70 - * Examples:
71 - * 1. "themes" folder
72 - * Path: C:/xampp/htdocs/fswp/wp-content/themes/twentytwelve/freemius/assets/css/admin/common.css
73 - * URL: http://fswp:8080/wp-content/themes/twentytwelve/freemius/assets/css/admin/common.css
74 - *
75 - * 2. "plugins" folder
76 - * Path: C:/xampp/htdocs/fswp/wp-content/plugins/rating-widget-premium/freemius/assets/css/admin/common.css
77 - * URL: http://fswp:8080/wp-content/plugins/rating-widget-premium/freemius/assets/css/admin/common.css
78 - *
79 - * @author Leo Fajardo (@leorw)
80 - * @since 1.2.2
81 - *
82 - * @param string $asset_abs_path Asset's absolute path.
83 - *
84 - * @return string Asset's URL.
85 - */
86 - function fs_asset_url( $asset_abs_path ) {
87 - $wp_content_dir = fs_normalize_path( WP_CONTENT_DIR );
88 - $asset_abs_path = fs_normalize_path( $asset_abs_path );
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 );
89 90
90 - if ( 0 === strpos( $asset_abs_path, $wp_content_dir ) ) {
91 - // Handle both theme and plugin assets located in the standard directories.
92 - $asset_rel_path = str_replace( $wp_content_dir, '', $asset_abs_path );
93 - $asset_url = content_url( fs_normalize_path( $asset_rel_path ) );
94 - } else {
95 - $wp_plugins_dir = fs_normalize_path( WP_PLUGIN_DIR );
96 - if ( 0 === strpos( $asset_abs_path, $wp_plugins_dir ) ) {
97 - // Try to handle plugin assets that may be located in a non-standard plugins directory.
98 - $asset_rel_path = str_replace( $wp_plugins_dir, '', $asset_abs_path );
99 - $asset_url = plugins_url( fs_normalize_path( $asset_rel_path ) );
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 ) );
100 95 } else {
101 - // Try to handle theme assets that may be located in a non-standard themes directory.
102 - $active_theme_stylesheet = get_stylesheet();
103 - $wp_themes_dir = fs_normalize_path( trailingslashit( get_theme_root( $active_theme_stylesheet ) ) );
104 - $asset_rel_path = str_replace( $wp_themes_dir, '', fs_normalize_path( $asset_abs_path ) );
105 - $asset_url = trailingslashit( get_theme_root_uri( $active_theme_stylesheet ) ) . fs_normalize_path( $asset_rel_path );
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 + }
106 108 }
109 +
110 + return $asset_url;
107 111 }
108 -
109 - return $asset_url;
110 112 }
111 113
112 - function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
113 - wp_enqueue_style( $handle, fs_asset_url( WP_FS__DIR_CSS . '/' . trim( $path, '/' ) ), $deps, $ver, $media );
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 + }
114 118 }
115 119
116 - function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) {
117 - wp_enqueue_script( $handle, fs_asset_url( WP_FS__DIR_JS . '/' . trim( $path, '/' ) ), $deps, $ver, $in_footer );
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 + }
118 124 }
119 125
120 - function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) {
121 - return ( fs_asset_url( $img_dir . '/' . trim( $path, '/' ) ) );
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 + }
122 130 }
123 131
124 132 #--------------------------------------------------------------------------------
125 133 #region Request handlers.
@@ -124,48 +132,103 @@
124 132 #--------------------------------------------------------------------------------
125 133 #region Request handlers.
126 134 #--------------------------------------------------------------------------------
127 135
128 - if ( ! function_exists( 'fs_request_get' ) ) {
136 + if ( ! function_exists( 'fs_request_get_raw' ) ) {
129 137 /**
130 - * A helper method to fetch GET/POST user input with an optional default value when the input is not set.
131 - * @author Vova Feldman (@svovaf)
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.
132 140 *
141 + * The return of this function is always unslashed.
142 + *
143 + * @since 2.5.10
144 + *
133 145 * @param string $key
134 146 * @param mixed $def
135 - * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when
136 - * set to 'post' will look for the value passed via the POST request's body, otherwise,
137 - * will check if the parameter was passed in any of the two.
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.
138 150 *
139 151 * @return mixed
140 152 */
141 - function fs_request_get( $key, $def = false, $type = false ) {
153 + function fs_request_get_raw( $key, $def = false, $type = false ) {
142 154 if ( is_string( $type ) ) {
143 155 $type = strtolower( $type );
144 156 }
145 157
146 158 /**
147 - * Note to WordPress.org Reviewers:
148 - * This is a helper method 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.
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.
149 161 */
150 162 switch ( $type ) {
151 163 case 'post':
164 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
152 165 $value = isset( $_POST[ $key ] ) ? $_POST[ $key ] : $def;
153 166 break;
154 167 case 'get':
168 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
155 169 $value = isset( $_GET[ $key ] ) ? $_GET[ $key ] : $def;
156 170 break;
157 171 default:
172 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
158 173 $value = isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def;
159 174 break;
160 175 }
161 176
162 - return $value;
177 + // Don't unslash if the value itself is empty (empty string, null, empty array etc).
178 + return empty( $value ) ? $value : wp_unslash( $value );
163 179 }
164 180 }
165 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 +
166 228 if ( ! function_exists( 'fs_request_has' ) ) {
167 229 function fs_request_has( $key ) {
230 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
168 231 return isset( $_REQUEST[ $key ] );
169 232 }
170 233 }
171 234
@@ -222,8 +285,9 @@
222 285 }
223 286
224 287 if ( ! function_exists( 'fs_get_action' ) ) {
225 288 function fs_get_action( $action_key = 'action' ) {
289 + // phpcs:disable WordPress.Security.NonceVerification.Recommended
226 290 if ( ! empty( $_REQUEST[ $action_key ] ) && is_string( $_REQUEST[ $action_key ] ) ) {
227 291 return strtolower( $_REQUEST[ $action_key ] );
228 292 }
229 293
@@ -235,8 +299,9 @@
235 299 }
236 300 }
237 301
238 302 return false;
303 + // phpcs:enable WordPress.Security.NonceVerification.Recommended
239 304 }
240 305 }
241 306
242 307 if ( ! function_exists( 'fs_request_is_action' ) ) {
@@ -314,141 +379,194 @@
314 379 }
315 380
316 381 /* Core UI.
317 382 --------------------------------------------------------------------------------------------*/
318 - /**
319 - * @param number $module_id
320 - * @param string $page
321 - * @param string $action
322 - * @param string $title
323 - * @param string $button_class
324 - * @param array $params
325 - * @param bool $is_primary
326 - * @param bool $is_small
327 - * @param string|bool $icon_class Optional class for an icon (since 1.1.7).
328 - * @param string|bool $confirmation Optional confirmation message before submit (since 1.1.7).
329 - * @param string $method Since 1.1.7
330 - *
331 - * @uses fs_ui_get_action_button()
332 - */
333 - function fs_ui_action_button(
334 - $module_id,
335 - $page,
336 - $action,
337 - $title,
338 - $button_class = '',
339 - $params = array(),
340 - $is_primary = true,
341 - $is_small = false,
342 - $icon_class = false,
343 - $confirmation = false,
344 - $method = 'GET'
345 - ) {
346 - echo fs_ui_get_action_button(
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(
347 400 $module_id,
348 401 $page,
349 402 $action,
350 403 $title,
351 - $button_class,
352 - $params,
353 - $is_primary,
354 - $is_small,
355 - $icon_class,
356 - $confirmation,
357 - $method
358 - );
359 - }
360 -
361 - /**
362 - * @author Vova Feldman (@svovaf)
363 - * @since 1.1.7
364 - *
365 - * @param number $module_id
366 - * @param string $page
367 - * @param string $action
368 - * @param string $title
369 - * @param string $button_class
370 - * @param array $params
371 - * @param bool $is_primary
372 - * @param bool $is_small
373 - * @param string|bool $icon_class Optional class for an icon.
374 - * @param string|bool $confirmation Optional confirmation message before submit.
375 - * @param string $method
376 - *
377 - * @return string
378 - */
379 - function fs_ui_get_action_button(
380 - $module_id,
381 - $page,
382 - $action,
383 - $title,
384 - $button_class = '',
385 - $params = array(),
386 - $is_primary = true,
387 - $is_small = false,
388 - $icon_class = false,
389 - $confirmation = false,
390 - $method = 'GET'
391 - ) {
392 - // Prepend icon (if set).
393 - $title = ( is_string( $icon_class ) ? '<i class="' . $icon_class . '"></i> ' : '' ) . $title;
394 -
395 - if ( is_string( $confirmation ) ) {
396 - 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>',
397 - freemius( $module_id )->_get_admin_page_url( $page, $params ),
398 - $method,
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,
399 415 $action,
400 - wp_nonce_field( $action, '_wpnonce', true, false ),
401 - 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
416 + $title,
417 + $button_class,
418 + $params,
419 + $is_primary,
420 + $is_small,
421 + $icon_class,
402 422 $confirmation,
403 - $title
423 + $method
404 424 );
405 - } else if ( 'GET' !== strtoupper( $method ) ) {
406 - 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>',
407 - freemius( $module_id )->_get_admin_page_url( $page, $params ),
408 - $method,
409 - $action,
410 - wp_nonce_field( $action, '_wpnonce', true, false ),
411 - 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
412 - $title
413 - );
414 - } else {
415 - return sprintf( '<a href="%s" class="%s">%s</a></form>',
416 - wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
417 - 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
418 - $title
419 - );
420 425 }
421 426 }
422 427
423 - function fs_ui_action_link( $module_id, $page, $action, $title, $params = array() ) {
424 - ?><a class=""
425 - 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
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 + }
426 495 }
427 496
428 - /*function fs_error_handler($errno, $errstr, $errfile, $errline)
429 - {
430 - if (false === strpos($errfile, 'freemius/'))
431 - {
432 - // @todo Dump Freemius errors to local log.
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 );
433 513 }
514 + }
434 515
435 -// switch ($errno) {
436 -// case E_USER_ERROR:
437 -// break;
438 -// case E_WARNING:
439 -// case E_USER_WARNING:
440 -// break;
441 -// case E_NOTICE:
442 -// case E_USER_NOTICE:
443 -// break;
444 -// default:
445 -// break;
446 -// }
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 + }
447 567 }
448 568
449 - set_error_handler('fs_error_handler');*/
450 -
451 569 if ( ! function_exists( 'fs_nonce_url' ) ) {
452 570 /**
453 571 * Retrieve URL with nonce added to URL query.
454 572 *
@@ -469,8 +587,35 @@
469 587 return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
470 588 }
471 589 }
472 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 +
473 618 if ( ! function_exists( 'fs_starts_with' ) ) {
474 619 /**
475 620 * Check if string starts with.
476 621 *
@@ -633,73 +778,77 @@
633 778 }
634 779
635 780 #endregion Url Canonization ------------------------------------------------------------------
636 781
637 - /**
638 - * @author Vova Feldman (@svovaf)
639 - *
640 - * @since 1.2.2 Changed to usage of WP_Filesystem_Direct.
641 - *
642 - * @param string $from URL
643 - * @param string $to File path.
644 - *
645 - * @return bool Is successfully downloaded.
646 - */
647 - function fs_download_image( $from, $to ) {
648 - $dir = dirname( $to );
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 );
649 795
650 - if ( 'direct' !== get_filesystem_method( array(), $dir ) ) {
651 - return false;
652 - }
796 + if ( 'direct' !== get_filesystem_method( array(), $dir ) ) {
797 + return false;
798 + }
653 799
654 - if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
655 - require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
656 - require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
657 - }
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 + }
658 804
659 - $fs = new WP_Filesystem_Direct( '' );
660 - $tmpfile = download_url( $from );
805 + $fs = new WP_Filesystem_Direct( '' );
806 + $tmpfile = download_url( $from );
661 807
662 - if ( $tmpfile instanceof WP_Error ) {
663 - // Issue downloading the file.
664 - return false;
665 - }
808 + if ( $tmpfile instanceof WP_Error ) {
809 + // Issue downloading the file.
810 + return false;
811 + }
666 812
667 - $fs->copy( $tmpfile, $to );
668 - $fs->delete( $tmpfile );
813 + $fs->copy( $tmpfile, $to );
814 + $fs->delete( $tmpfile );
669 815
670 - return true;
816 + return true;
817 + }
671 818 }
672 819
673 820 /* General Utilities
674 821 --------------------------------------------------------------------------------------------*/
675 822
676 - /**
677 - * Sorts an array by the value of the priority key.
678 - *
679 - * @author Daniel Iser (@danieliser)
680 - * @since 1.1.7
681 - *
682 - * @param $a
683 - * @param $b
684 - *
685 - * @return int
686 - */
687 - function fs_sort_by_priority( $a, $b ) {
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 ) {
688 836
689 - // If b has a priority and a does not, b wins.
690 - if ( ! isset( $a['priority'] ) && isset( $b['priority'] ) ) {
691 - return 1;
692 - } // If b has a priority and a does not, b wins.
693 - elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
694 - return - 1;
695 - } // If neither has a priority or both priorities are equal its a tie.
696 - elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
697 - return 0;
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;
698 850 }
699 -
700 - // If both have priority return the winner.
701 - return ( $a['priority'] < $b['priority'] ) ? - 1 : 1;
702 851 }
703 852
704 853 #--------------------------------------------------------------------------------
705 854 #region Localization
@@ -704,8 +853,14 @@
704 853 #--------------------------------------------------------------------------------
705 854 #region Localization
706 855 #--------------------------------------------------------------------------------
707 856
857 + global $fs_text_overrides;
858 +
859 + if ( ! isset( $fs_text_overrides ) ) {
860 + $fs_text_overrides = array();
861 + }
862 +
708 863 if ( ! function_exists( 'fs_text' ) ) {
709 864 /**
710 865 * Retrieve a translated text by key.
711 866 *
@@ -716,14 +871,12 @@
716 871 * @param string $slug
717 872 *
718 873 * @return string
719 874 *
720 - * @global $fs_text , $fs_text_overrides
875 + * @global $fs_text_overrides
721 876 */
722 877 function fs_text( $key, $slug = 'freemius' ) {
723 - global $fs_text,
724 - $fs_module_info_text,
725 - $fs_text_overrides;
878 + global $fs_text_overrides;
726 879
727 880 if ( isset( $fs_text_overrides[ $slug ] ) ) {
728 881 if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
729 882 return $fs_text_overrides[ $slug ][ $key ];
@@ -734,24 +887,8 @@
734 887 return $fs_text_overrides[ $slug ][ $lower_key ];
735 888 }
736 889 }
737 890
738 - if ( ! isset( $fs_text ) ) {
739 - $dir = defined( 'WP_FS__DIR_INCLUDES' ) ?
740 - WP_FS__DIR_INCLUDES :
741 - dirname( __FILE__ );
742 -
743 - require_once $dir . '/i18n.php';
744 - }
745 -
746 - if ( isset( $fs_text[ $key ] ) ) {
747 - return $fs_text[ $key ];
748 - }
749 -
750 - if ( isset( $fs_module_info_text[ $key ] ) ) {
751 - return $fs_module_info_text[ $key ];
752 - }
753 -
754 891 return $key;
755 892 }
756 893
757 894 #region Private
@@ -1093,9 +1230,9 @@
1093 1230 * @param string $context Context information for the translators.
1094 1231 * @param string $key String key for overrides.
1095 1232 * @param string $slug Module slug for overrides.
1096 1233 *
1097 - * @return string
1234 + * @return void
1098 1235 */
1099 1236 function fs_esc_js_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1100 1237 echo esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) );
1101 1238 }
@@ -1283,9 +1420,9 @@
1283 1420 */
1284 1421 function fs_is_plugin_uninstall() {
1285 1422 return (
1286 1423 defined( 'WP_UNINSTALL_PLUGIN' ) ||
1287 - ( 0 < did_action( 'update_option_uninstall_plugins' ) )
1424 + ( 0 < did_action( 'pre_uninstall_plugin' ) )
1288 1425 );
1289 1426 }
1290 1427 }
1291 1428
@@ -1347,5 +1484,22 @@
1347 1484 array( "fs_{$tag}_{$module_unique_affix}" ),
1348 1485 array_slice( $args, 2 ) )
1349 1486 );
1350 1487 }
1351 - }
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 + }