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 +529 -322 1.53.6.0 View file →
@@ -62,48 +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 );
89 - $asset_rel_path = str_replace( $wp_content_dir, '', $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 );
90 90
91 - $asset_url = content_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 ) );
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 + }
92 109
93 - return $asset_url;
110 + return $asset_url;
111 + }
94 112 }
95 113
96 - function fs_enqueue_local_style( $handle, $path, $deps = array(), $ver = false, $media = 'all' ) {
97 - 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 + }
98 118 }
99 119
100 - function fs_enqueue_local_script( $handle, $path, $deps = array(), $ver = false, $in_footer = 'all' ) {
101 - 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 + }
102 124 }
103 125
104 - function fs_img_url( $path, $img_dir = WP_FS__DIR_IMG ) {
105 - 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 + }
106 130 }
107 131
108 132 #--------------------------------------------------------------------------------
109 133 #region Request handlers.
@@ -108,57 +132,141 @@
108 132 #--------------------------------------------------------------------------------
109 133 #region Request handlers.
110 134 #--------------------------------------------------------------------------------
111 135
112 - if ( ! function_exists( 'fs_request_get' ) ) {
136 + if ( ! function_exists( 'fs_request_get_raw' ) ) {
113 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 + *
114 145 * @param string $key
115 146 * @param mixed $def
116 - * @param string|bool $type Since 1.2.1.7 - when set to 'get' will look for the value passed via querystring, when
117 - * set to 'post' will look for the value passed via the POST request's body, otherwise,
118 - * 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.
119 150 *
120 151 * @return mixed
121 152 */
122 - function fs_request_get( $key, $def = false, $type = false ) {
153 + function fs_request_get_raw( $key, $def = false, $type = false ) {
123 154 if ( is_string( $type ) ) {
124 155 $type = strtolower( $type );
125 156 }
126 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 + */
127 162 switch ( $type ) {
128 163 case 'post':
164 + // phpcs:ignore WordPress.Security.NonceVerification.Missing
129 165 $value = isset( $_POST[ $key ] ) ? $_POST[ $key ] : $def;
130 166 break;
131 167 case 'get':
168 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
132 169 $value = isset( $_GET[ $key ] ) ? $_GET[ $key ] : $def;
133 170 break;
134 171 default:
172 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
135 173 $value = isset( $_REQUEST[ $key ] ) ? $_REQUEST[ $key ] : $def;
136 174 break;
137 175 }
138 176
139 - 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 );
140 179 }
141 180 }
142 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 +
143 228 if ( ! function_exists( 'fs_request_has' ) ) {
144 229 function fs_request_has( $key ) {
230 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended
145 231 return isset( $_REQUEST[ $key ] );
146 232 }
147 233 }
148 234
149 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 + */
150 246 function fs_request_get_bool( $key, $def = false ) {
151 - if ( ! isset( $_REQUEST[ $key ] ) ) {
247 + $val = fs_request_get( $key, null );
248 +
249 + if ( is_null( $val ) ) {
152 250 return $def;
153 251 }
154 252
155 - if ( 1 == $_REQUEST[ $key ] || 'true' === strtolower( $_REQUEST[ $key ] ) ) {
156 - return true;
157 - }
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 );
158 263
159 - if ( 0 == $_REQUEST[ $key ] || 'false' === strtolower( $_REQUEST[ $key ] ) ) {
160 - return false;
264 + if ( 'true' === $val ) {
265 + return true;
266 + } else if ( 'false' === $val ) {
267 + return false;
268 + }
161 269 }
162 270
163 271 return $def;
164 272 }
@@ -177,8 +285,9 @@
177 285 }
178 286
179 287 if ( ! function_exists( 'fs_get_action' ) ) {
180 288 function fs_get_action( $action_key = 'action' ) {
289 + // phpcs:disable WordPress.Security.NonceVerification.Recommended
181 290 if ( ! empty( $_REQUEST[ $action_key ] ) && is_string( $_REQUEST[ $action_key ] ) ) {
182 291 return strtolower( $_REQUEST[ $action_key ] );
183 292 }
184 293
@@ -190,8 +299,9 @@
190 299 }
191 300 }
192 301
193 302 return false;
303 + // phpcs:enable WordPress.Security.NonceVerification.Recommended
194 304 }
195 305 }
196 306
197 307 if ( ! function_exists( 'fs_request_is_action' ) ) {
@@ -269,141 +379,194 @@
269 379 }
270 380
271 381 /* Core UI.
272 382 --------------------------------------------------------------------------------------------*/
273 - /**
274 - * @param number $module_id
275 - * @param string $page
276 - * @param string $action
277 - * @param string $title
278 - * @param string $button_class
279 - * @param array $params
280 - * @param bool $is_primary
281 - * @param bool $is_small
282 - * @param string|bool $icon_class Optional class for an icon (since 1.1.7).
283 - * @param string|bool $confirmation Optional confirmation message before submit (since 1.1.7).
284 - * @param string $method Since 1.1.7
285 - *
286 - * @uses fs_ui_get_action_button()
287 - */
288 - function fs_ui_action_button(
289 - $module_id,
290 - $page,
291 - $action,
292 - $title,
293 - $button_class = '',
294 - $params = array(),
295 - $is_primary = true,
296 - $is_small = false,
297 - $icon_class = false,
298 - $confirmation = false,
299 - $method = 'GET'
300 - ) {
301 - 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(
302 400 $module_id,
303 401 $page,
304 402 $action,
305 403 $title,
306 - $button_class,
307 - $params,
308 - $is_primary,
309 - $is_small,
310 - $icon_class,
311 - $confirmation,
312 - $method
313 - );
314 - }
315 -
316 - /**
317 - * @author Vova Feldman (@svovaf)
318 - * @since 1.1.7
319 - *
320 - * @param number $module_id
321 - * @param string $page
322 - * @param string $action
323 - * @param string $title
324 - * @param string $button_class
325 - * @param array $params
326 - * @param bool $is_primary
327 - * @param bool $is_small
328 - * @param string|bool $icon_class Optional class for an icon.
329 - * @param string|bool $confirmation Optional confirmation message before submit.
330 - * @param string $method
331 - *
332 - * @return string
333 - */
334 - function fs_ui_get_action_button(
335 - $module_id,
336 - $page,
337 - $action,
338 - $title,
339 - $button_class = '',
340 - $params = array(),
341 - $is_primary = true,
342 - $is_small = false,
343 - $icon_class = false,
344 - $confirmation = false,
345 - $method = 'GET'
346 - ) {
347 - // Prepend icon (if set).
348 - $title = ( is_string( $icon_class ) ? '<i class="' . $icon_class . '"></i> ' : '' ) . $title;
349 -
350 - if ( is_string( $confirmation ) ) {
351 - 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>',
352 - freemius( $module_id )->_get_admin_page_url( $page, $params ),
353 - $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,
354 415 $action,
355 - wp_nonce_field( $action, '_wpnonce', true, false ),
356 - '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,
357 422 $confirmation,
358 - $title
423 + $method
359 424 );
360 - } else if ( 'GET' !== strtoupper( $method ) ) {
361 - 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>',
362 - freemius( $module_id )->_get_admin_page_url( $page, $params ),
363 - $method,
364 - $action,
365 - wp_nonce_field( $action, '_wpnonce', true, false ),
366 - 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
367 - $title
368 - );
369 - } else {
370 - return sprintf( '<a href="%s" class="%s">%s</a></form>',
371 - wp_nonce_url( freemius( $module_id )->_get_admin_page_url( $page, array_merge( $params, array( 'fs_action' => $action ) ) ), $action ),
372 - 'button' . ( ! empty( $button_class ) ? ' ' . $button_class : '' ) . ( $is_primary ? ' button-primary' : '' ) . ( $is_small ? ' button-small' : '' ),
373 - $title
374 - );
375 425 }
376 426 }
377 427
378 - function fs_ui_action_link( $module_id, $page, $action, $title, $params = array() ) {
379 - ?><a class=""
380 - 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 + }
381 495 }
382 496
383 - /*function fs_error_handler($errno, $errstr, $errfile, $errline)
384 - {
385 - if (false === strpos($errfile, 'freemius/'))
386 - {
387 - // @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 );
388 513 }
514 + }
389 515
390 -// switch ($errno) {
391 -// case E_USER_ERROR:
392 -// break;
393 -// case E_WARNING:
394 -// case E_USER_WARNING:
395 -// break;
396 -// case E_NOTICE:
397 -// case E_USER_NOTICE:
398 -// break;
399 -// default:
400 -// break;
401 -// }
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 + }
402 567 }
403 568
404 - set_error_handler('fs_error_handler');*/
405 -
406 569 if ( ! function_exists( 'fs_nonce_url' ) ) {
407 570 /**
408 571 * Retrieve URL with nonce added to URL query.
409 572 *
@@ -424,8 +587,35 @@
424 587 return add_query_arg( $name, wp_create_nonce( $action ), $actionurl );
425 588 }
426 589 }
427 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 +
428 618 if ( ! function_exists( 'fs_starts_with' ) ) {
429 619 /**
430 620 * Check if string starts with.
431 621 *
@@ -588,73 +778,77 @@
588 778 }
589 779
590 780 #endregion Url Canonization ------------------------------------------------------------------
591 781
592 - /**
593 - * @author Vova Feldman (@svovaf)
594 - *
595 - * @since 1.2.2 Changed to usage of WP_Filesystem_Direct.
596 - *
597 - * @param string $from URL
598 - * @param string $to File path.
599 - *
600 - * @return bool Is successfully downloaded.
601 - */
602 - function fs_download_image( $from, $to ) {
603 - $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 );
604 795
605 - if ( 'direct' !== get_filesystem_method( array(), $dir ) ) {
606 - return false;
607 - }
796 + if ( 'direct' !== get_filesystem_method( array(), $dir ) ) {
797 + return false;
798 + }
608 799
609 - if ( ! class_exists( 'WP_Filesystem_Direct' ) ) {
610 - require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
611 - require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
612 - }
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 + }
613 804
614 - $fs = new WP_Filesystem_Direct( '' );
615 - $tmpfile = download_url( $from );
805 + $fs = new WP_Filesystem_Direct( '' );
806 + $tmpfile = download_url( $from );
616 807
617 - if ( $tmpfile instanceof WP_Error ) {
618 - // Issue downloading the file.
619 - return false;
620 - }
808 + if ( $tmpfile instanceof WP_Error ) {
809 + // Issue downloading the file.
810 + return false;
811 + }
621 812
622 - $fs->copy( $tmpfile, $to );
623 - $fs->delete( $tmpfile );
813 + $fs->copy( $tmpfile, $to );
814 + $fs->delete( $tmpfile );
624 815
625 - return true;
816 + return true;
817 + }
626 818 }
627 819
628 820 /* General Utilities
629 821 --------------------------------------------------------------------------------------------*/
630 822
631 - /**
632 - * Sorts an array by the value of the priority key.
633 - *
634 - * @author Daniel Iser (@danieliser)
635 - * @since 1.1.7
636 - *
637 - * @param $a
638 - * @param $b
639 - *
640 - * @return int
641 - */
642 - 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 ) {
643 836
644 - // If b has a priority and a does not, b wins.
645 - if ( ! isset( $a['priority'] ) && isset( $b['priority'] ) ) {
646 - return 1;
647 - } // If b has a priority and a does not, b wins.
648 - elseif ( isset( $a['priority'] ) && ! isset( $b['priority'] ) ) {
649 - return - 1;
650 - } // If neither has a priority or both priorities are equal its a tie.
651 - elseif ( ( ! isset( $a['priority'] ) && ! isset( $b['priority'] ) ) || $a['priority'] === $b['priority'] ) {
652 - 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;
653 850 }
654 -
655 - // If both have priority return the winner.
656 - return ( $a['priority'] < $b['priority'] ) ? - 1 : 1;
657 851 }
658 852
659 853 #--------------------------------------------------------------------------------
660 854 #region Localization
@@ -659,8 +853,14 @@
659 853 #--------------------------------------------------------------------------------
660 854 #region Localization
661 855 #--------------------------------------------------------------------------------
662 856
857 + global $fs_text_overrides;
858 +
859 + if ( ! isset( $fs_text_overrides ) ) {
860 + $fs_text_overrides = array();
861 + }
862 +
663 863 if ( ! function_exists( 'fs_text' ) ) {
664 864 /**
665 865 * Retrieve a translated text by key.
666 866 *
@@ -671,14 +871,12 @@
671 871 * @param string $slug
672 872 *
673 873 * @return string
674 874 *
675 - * @global $fs_text , $fs_text_overrides
875 + * @global $fs_text_overrides
676 876 */
677 877 function fs_text( $key, $slug = 'freemius' ) {
678 - global $fs_text,
679 - $fs_module_info_text,
680 - $fs_text_overrides;
878 + global $fs_text_overrides;
681 879
682 880 if ( isset( $fs_text_overrides[ $slug ] ) ) {
683 881 if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
684 882 return $fs_text_overrides[ $slug ][ $key ];
@@ -689,28 +887,103 @@
689 887 return $fs_text_overrides[ $slug ][ $lower_key ];
690 888 }
691 889 }
692 890
693 - if ( ! isset( $fs_text ) ) {
694 - $dir = defined( 'WP_FS__DIR_INCLUDES' ) ?
695 - WP_FS__DIR_INCLUDES :
696 - dirname( __FILE__ );
891 + return $key;
892 + }
697 893
698 - require_once $dir . '/i18n.php';
699 - }
894 + #region Private
700 895
701 - if ( isset( $fs_text[ $key ] ) ) {
702 - return $fs_text[ $key ];
703 - }
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 );
704 913
705 - if ( isset( $fs_module_info_text[ $key ] ) ) {
706 - return $fs_module_info_text[ $key ];
707 - }
914 + // Avoid misleading Theme Check warning.
915 + $fn = 'translate_with_gettext_context';
708 916
709 - return $key;
917 + return $fn( $text, $context, $text_domain );
710 918 }
711 919
920 + #endregion
921 +
712 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 + /**
713 986 * Get a translatable text override if exists, or `false`.
714 987 *
715 988 * @author Vova Feldman (@svovaf)
716 989 * @since 1.2.1.7
@@ -745,9 +1018,11 @@
745 1018 }
746 1019
747 1020 return false;
748 1021 }
1022 + }
749 1023
1024 + if ( ! function_exists( 'fs_text_and_domain' ) ) {
750 1025 /**
751 1026 * Get a translatable text and its text domain.
752 1027 *
753 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.
@@ -775,11 +1050,11 @@
775 1050 }
776 1051
777 1052 return array( $text, $text_domain );
778 1053 }
1054 + }
779 1055
780 - #region Private
781 -
1056 + if ( ! function_exists( '_fs_text_inline' ) ) {
782 1057 /**
783 1058 * Retrieve an inline translated text by key.
784 1059 *
785 1060 * @author Vova Feldman (@svovaf)
@@ -800,36 +1075,12 @@
800 1075 $fn = 'translate';
801 1076
802 1077 return $fn( $text, $text_domain );
803 1078 }
1079 + }
804 1080
1081 + if ( ! function_exists( 'fs_text_inline' ) ) {
805 1082 /**
806 - * Retrieve an inline translated text by key with a context.
807 - *
808 - * @author Vova Feldman (@svovaf)
809 - * @since 1.2.3
810 - *
811 - * @param string $text Translatable string.
812 - * @param string $context Context information for the translators.
813 - * @param string $key String key for overrides.
814 - * @param string $slug Module slug for overrides.
815 - *
816 - * @return string
817 - *
818 - * @global $fs_text_overrides
819 - */
820 - function _fs_text_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
821 - list( $text, $text_domain ) = fs_text_and_domain( $text, $key, $slug );
822 -
823 - // Avoid misleading Theme Check warning.
824 - $fn = 'translate_with_gettext_context';
825 -
826 - return $fn( $text, $context, $text_domain );
827 - }
828 -
829 - #endregion
830 -
831 - /**
832 1083 * Retrieve an inline translated text by key.
833 1084 *
834 1085 * @author Vova Feldman (@svovaf)
835 1086 * @since 1.2.3
@@ -844,69 +1095,8 @@
844 1095 */
845 1096 function fs_text_inline( $text, $key = '', $slug = 'freemius' ) {
846 1097 return _fs_text_inline( $text, $key, $slug );
847 1098 }
848 -
849 - /**
850 - * Retrieve an inline translated text by key with a context.
851 - *
852 - * @author Vova Feldman (@svovaf)
853 - * @since 1.2.3
854 - *
855 - * @param string $text Translatable string.
856 - * @param string $context Context information for the translators.
857 - * @param string $key String key for overrides.
858 - * @param string $slug Module slug for overrides.
859 - *
860 - * @return string
861 - *
862 - * @global $fs_text_overrides
863 - */
864 - function fs_text_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
865 - return _fs_text_x_inline( $text, $context, $key, $slug );
866 - }
867 -
868 - /**
869 - * Output a translated text by key.
870 - *
871 - * @author Vova Feldman (@svovaf)
872 - * @since 1.2.1.7
873 - *
874 - * @param string $key
875 - * @param string $slug
876 - */
877 - function fs_echo( $key, $slug = 'freemius' ) {
878 - echo fs_text( $key, $slug );
879 - }
880 -
881 - /**
882 - * Output an inline translated text.
883 - *
884 - * @author Vova Feldman (@svovaf)
885 - * @since 1.2.3
886 - *
887 - * @param string $text Translatable string.
888 - * @param string $key String key for overrides.
889 - * @param string $slug Module slug for overrides.
890 - */
891 - function fs_echo_inline( $text, $key = '', $slug = 'freemius' ) {
892 - echo _fs_text_inline( $text, $key, $slug );
893 - }
894 -
895 - /**
896 - * Output an inline translated text with a context.
897 - *
898 - * @author Vova Feldman (@svovaf)
899 - * @since 1.2.3
900 - *
901 - * @param string $text Translatable string.
902 - * @param string $context Context information for the translators.
903 - * @param string $key String key for overrides.
904 - * @param string $slug Module slug for overrides.
905 - */
906 - function fs_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
907 - echo _fs_text_x_inline( $text, $context, $key, $slug );
908 - }
909 1099 }
910 1100
911 1101 if ( ! function_exists( 'fs_esc_attr' ) ) {
912 1102 /**
@@ -1040,9 +1230,9 @@
1040 1230 * @param string $context Context information for the translators.
1041 1231 * @param string $key String key for overrides.
1042 1232 * @param string $slug Module slug for overrides.
1043 1233 *
1044 - * @return string
1234 + * @return void
1045 1235 */
1046 1236 function fs_esc_js_echo_x_inline( $text, $context, $key = '', $slug = 'freemius' ) {
1047 1237 echo esc_js( _fs_text_x_inline( $text, $context, $key, $slug ) );
1048 1238 }
@@ -1230,9 +1420,9 @@
1230 1420 */
1231 1421 function fs_is_plugin_uninstall() {
1232 1422 return (
1233 1423 defined( 'WP_UNINSTALL_PLUGIN' ) ||
1234 - ( 0 < did_action( 'update_option_uninstall_plugins' ) )
1424 + ( 0 < did_action( 'pre_uninstall_plugin' ) )
1235 1425 );
1236 1426 }
1237 1427 }
1238 1428
@@ -1294,5 +1484,22 @@
1294 1484 array( "fs_{$tag}_{$module_unique_affix}" ),
1295 1485 array_slice( $args, 2 ) )
1296 1486 );
1297 1487 }
1298 - }
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 + }