PluginProbe
BlockSpare – Gutenberg Blocks, AI Content Generator & Site Builder for News, Magazine & Blogs / 2.7.3
BlockSpare – Gutenberg Blocks, AI Content Generator & Site Builder for News, Magazine & Blogs v2.7.3
5.0.1 4.1.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 2.1.2 2.5.0 2.5.3 All 39 releases
← All changes | freemius/includes/fs-essential-functions.php +409 -482 1.2.3 → 2.7.3 View file →
@@ -1,483 +1,410 @@
1 -<?php
2 - /**
3 - * IMPORTANT:
4 - * This file will be loaded based on the order of the plugins/themes load.
5 - * If there's a theme and a plugin using Freemius, the plugin's essential
6 - * file will always load first.
7 - *
8 - * @package Freemius
9 - * @copyright Copyright (c) 2015, Freemius, Inc.
10 - * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
11 - * @since 1.1.5
12 - */
13 -
14 - if ( ! function_exists( 'fs_normalize_path' ) ) {
15 - if ( function_exists( 'wp_normalize_path' ) ) {
16 - /**
17 - * Normalize a filesystem path.
18 - *
19 - * Replaces backslashes with forward slashes for Windows systems, and ensures
20 - * no duplicate slashes exist.
21 - *
22 - * @param string $path Path to normalize.
23 - *
24 - * @return string Normalized path.
25 - */
26 - function fs_normalize_path( $path ) {
27 - return wp_normalize_path( $path );
28 - }
29 - } else {
30 - function fs_normalize_path( $path ) {
31 - $path = str_replace( '\\', '/', $path );
32 - $path = preg_replace( '|/+|', '/', $path );
33 -
34 - return $path;
35 - }
36 - }
37 - }
38 -
39 - require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-2.2.1.php';
40 -
41 - #region Core Redirect (copied from BuddyPress) -----------------------------------------
42 -
43 - if ( ! function_exists( 'fs_redirect' ) ) {
44 - /**
45 - * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
46 - *
47 - * @link http://support.microsoft.com/kb/q176113/
48 - * @since 1.5.1
49 - * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
50 - *
51 - * @param string $location The path to redirect to.
52 - * @param bool $exit If true, exit after redirect (Since 1.2.1.5).
53 - * @param int $status Status code to use.
54 - *
55 - * @return bool False if $location is not set
56 - */
57 - function fs_redirect( $location, $exit = true, $status = 302 ) {
58 - global $is_IIS;
59 -
60 - $file = '';
61 - $line = '';
62 - if ( headers_sent($file, $line) ) {
63 - if ( WP_FS__DEBUG_SDK && class_exists( 'FS_Admin_Notices' ) ) {
64 - $notices = FS_Admin_Notices::instance( 'global' );
65 -
66 - $notices->add( "Freemius failed to redirect the page because the headers have been already sent from line <b><code>{$line}</code></b> in file <b><code>{$file}</code></b>. If it's unexpected, it usually happens due to invalid space and/or EOL character(s).", 'Oops...', 'error' );
67 - }
68 -
69 - return false;
70 - }
71 -
72 - if ( defined( 'DOING_AJAX' ) ) {
73 - // Don't redirect on AJAX calls.
74 - return false;
75 - }
76 -
77 - if ( ! $location ) // allows the wp_redirect filter to cancel a redirect
78 - {
79 - return false;
80 - }
81 -
82 - $location = fs_sanitize_redirect( $location );
83 -
84 - if ( $is_IIS ) {
85 - header( "Refresh: 0;url=$location" );
86 - } else {
87 - if ( php_sapi_name() != 'cgi-fcgi' ) {
88 - status_header( $status );
89 - } // This causes problems on IIS and some FastCGI setups
90 - header( "Location: $location" );
91 - }
92 -
93 - if ( $exit ) {
94 - exit();
95 - }
96 -
97 - return true;
98 - }
99 -
100 - if ( ! function_exists( 'fs_sanitize_redirect' ) ) {
101 - /**
102 - * Sanitizes a URL for use in a redirect.
103 - *
104 - * @since 2.3
105 - *
106 - * @param string $location
107 - *
108 - * @return string redirect-sanitized URL
109 - */
110 - function fs_sanitize_redirect( $location ) {
111 - $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location );
112 - $location = fs_kses_no_null( $location );
113 -
114 - // remove %0d and %0a from location
115 - $strip = array( '%0d', '%0a' );
116 - $found = true;
117 - while ( $found ) {
118 - $found = false;
119 - foreach ( (array) $strip as $val ) {
120 - while ( strpos( $location, $val ) !== false ) {
121 - $found = true;
122 - $location = str_replace( $val, '', $location );
123 - }
124 - }
125 - }
126 -
127 - return $location;
128 - }
129 - }
130 -
131 - if ( ! function_exists( 'fs_kses_no_null' ) ) {
132 - /**
133 - * Removes any NULL characters in $string.
134 - *
135 - * @since 1.0.0
136 - *
137 - * @param string $string
138 - *
139 - * @return string
140 - */
141 - function fs_kses_no_null( $string ) {
142 - $string = preg_replace( '/\0+/', '', $string );
143 - $string = preg_replace( '/(\\\\0)+/', '', $string );
144 -
145 - return $string;
146 - }
147 - }
148 - }
149 -
150 - #endregion Core Redirect (copied from BuddyPress) -----------------------------------------
151 -
152 - if ( ! function_exists( '__fs' ) ) {
153 - global $fs_text_overrides;
154 -
155 - if ( ! isset( $fs_text_overrides ) ) {
156 - $fs_text_overrides = array();
157 - }
158 -
159 - /**
160 - * Retrieve a translated text by key.
161 - *
162 - * @deprecated Use `fs_text()` instead since methods starting with `__` trigger warnings in Php 7.
163 - * @todo Remove this method in the future.
164 - *
165 - * @author Vova Feldman (@svovaf)
166 - * @since 1.1.4
167 - *
168 - * @param string $key
169 - * @param string $slug
170 - *
171 - * @return string
172 - *
173 - * @global $fs_text, $fs_text_overrides
174 - */
175 - function __fs( $key, $slug = 'freemius' ) {
176 - _deprecated_function( __FUNCTION__, '2.0.0', 'fs_text()' );
177 -
178 - global $fs_text,
179 - $fs_module_info_text,
180 - $fs_text_overrides;
181 -
182 - if ( isset( $fs_text_overrides[ $slug ] ) ) {
183 - if ( isset( $fs_text_overrides[ $slug ][ $key ] ) ) {
184 - return $fs_text_overrides[ $slug ][ $key ];
185 - }
186 -
187 - $lower_key = strtolower( $key );
188 - if ( isset( $fs_text_overrides[ $slug ][ $lower_key ] ) ) {
189 - return $fs_text_overrides[ $slug ][ $lower_key ];
190 - }
191 - }
192 -
193 - if ( ! isset( $fs_text ) ) {
194 - $dir = defined( 'WP_FS__DIR_INCLUDES' ) ?
195 - WP_FS__DIR_INCLUDES :
196 - dirname( __FILE__ );
197 -
198 - require_once $dir . '/i18n.php';
199 - }
200 -
201 - if ( isset( $fs_text[ $key ] ) ) {
202 - return $fs_text[ $key ];
203 - }
204 -
205 - if ( isset( $fs_module_info_text[ $key ] ) ) {
206 - return $fs_module_info_text[ $key ];
207 - }
208 -
209 - return $key;
210 - }
211 -
212 - /**
213 - * Output a translated text by key.
214 - *
215 - * @deprecated Use `fs_echo()` instead for consistency with `fs_text()`.
216 - *
217 - * @todo Remove this method in the future.
218 - *
219 - * @author Vova Feldman (@svovaf)
220 - * @since 1.1.4
221 - *
222 - * @param string $key
223 - * @param string $slug
224 - */
225 - function _efs( $key, $slug = 'freemius' ) {
226 - fs_echo( $key, $slug );
227 - }
228 - }
229 -
230 - if ( ! function_exists( 'fs_get_ip' ) ) {
231 - /**
232 - * Get client IP.
233 - *
234 - * @author Vova Feldman (@svovaf)
235 - * @since 1.1.2
236 - *
237 - * @return string|null
238 - */
239 - function fs_get_ip() {
240 - $fields = array(
241 - 'HTTP_CF_CONNECTING_IP',
242 - 'HTTP_CLIENT_IP',
243 - 'HTTP_X_FORWARDED_FOR',
244 - 'HTTP_X_FORWARDED',
245 - 'HTTP_FORWARDED_FOR',
246 - 'HTTP_FORWARDED',
247 - 'REMOTE_ADDR',
248 - );
249 -
250 - foreach ( $fields as $ip_field ) {
251 - if ( ! empty( $_SERVER[ $ip_field ] ) ) {
252 - return $_SERVER[ $ip_field ];
253 - }
254 - }
255 -
256 - return null;
257 - }
258 - }
259 -
260 - /**
261 - * Leverage backtrace to find caller plugin main file path.
262 - *
263 - * @author Vova Feldman (@svovaf)
264 - * @since 1.0.6
265 - *
266 - * @return string
267 - */
268 - function fs_find_caller_plugin_file() {
269 - /**
270 - * All the code below will be executed once on activation.
271 - * If the user changes the main plugin's file name, the file_exists()
272 - * will catch it.
273 - */
274 - if ( ! function_exists( 'get_plugins' ) ) {
275 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
276 - }
277 -
278 - $all_plugins = fs_get_plugins( true );
279 - $all_plugins_paths = array();
280 -
281 - // Get active plugin's main files real full names (might be symlinks).
282 - foreach ( $all_plugins as $relative_path => $data ) {
283 - $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
284 - }
285 -
286 - $plugin_file = null;
287 - for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
288 - if ( empty( $bt[ $i ]['file'] ) ) {
289 - continue;
290 - }
291 -
292 - if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
293 - $plugin_file = $bt[ $i ]['file'];
294 - break;
295 - }
296 - }
297 -
298 - if ( is_null( $plugin_file ) ) {
299 - // Throw an error to the developer in case of some edge case dev environment.
300 - wp_die(
301 - 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact [email protected] with the current error.',
302 - 'Error',
303 - array( 'back_link' => true )
304 - );
305 - }
306 -
307 - return $plugin_file;
308 - }
309 -
310 - require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-1.1.7.1.php';
311 -
312 - /**
313 - * Update SDK newest version reference.
314 - *
315 - * @author Vova Feldman (@svovaf)
316 - * @since 1.1.6
317 - *
318 - * @param string $sdk_relative_path
319 - * @param string|bool $plugin_file
320 - *
321 - * @global $fs_active_plugins
322 - */
323 - function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
324 - /**
325 - * If there is a plugin running an older version of FS (1.2.1 or below), the `fs_update_sdk_newest_version()`
326 - * function in the older version will be used instead of this one. But since the older version is using
327 - * the `is_plugin_active` function to check if a plugin is active, passing the theme's `plugin_path` to the
328 - * `is_plugin_active` function will return false since the path is not a plugin path, so `in_activation` will be
329 - * `true` for theme modules and the upgrading of the SDK version to 1.2.2 or newer version will work fine.
330 - *
331 - * Future versions that will call this function will use the proper logic here instead of just relying on the
332 - * `is_plugin_active` function to fail for themes.
333 - *
334 - * @author Leo Fajardo (@leorw)
335 - * @since 1.2.2
336 - */
337 -
338 - global $fs_active_plugins;
339 -
340 - $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ];
341 -
342 - if ( ! is_string( $plugin_file ) ) {
343 - $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
344 - }
345 -
346 - if ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) {
347 - if ( ! function_exists( 'is_plugin_active' ) ) {
348 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
349 - }
350 -
351 - $in_activation = ( ! is_plugin_active( $plugin_file ) );
352 - } else {
353 - $theme = wp_get_theme();
354 - $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet );
355 - }
356 -
357 - $fs_active_plugins->newest = (object) array(
358 - 'plugin_path' => $plugin_file,
359 - 'sdk_path' => $sdk_relative_path,
360 - 'version' => $newest_sdk->version,
361 - 'in_activation' => $in_activation,
362 - 'timestamp' => time(),
363 - );
364 -
365 - // Update DB with latest SDK version and path.
366 - update_option( 'fs_active_plugins', $fs_active_plugins );
367 - }
368 -
369 - /**
370 - * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
371 - *
372 - * @author Vova Feldman (@svovaf)
373 - * @since 1.1.6
374 - *
375 - * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
376 - *
377 - * @global $fs_active_plugins
378 - */
379 - function fs_newest_sdk_plugin_first() {
380 - global $fs_active_plugins;
381 -
382 - /**
383 - * @todo Multi-site network activated plugin are always loaded prior to site plugins so if there's a a plugin activated in the network mode that has an older version of the SDK of another plugin which is site activated that has new SDK version, the fs-essential-functions.php will be loaded from the older SDK. Same thing about MU plugins (loaded even before network activated plugins).
384 - *
385 - * @link https://github.com/Freemius/wordpress-sdk/issues/26
386 - */
387 -
388 - $newest_sdk_plugin_path = $fs_active_plugins->newest->plugin_path;
389 -
390 - $active_plugins = get_option( 'active_plugins', array() );
391 - $newest_sdk_plugin_key = array_search( $newest_sdk_plugin_path, $active_plugins );
392 - if ( 0 === $newest_sdk_plugin_key ) {
393 - // if it's 0 it's the first plugin already, no need to continue
394 - return false;
395 - } else if ( is_numeric( $newest_sdk_plugin_key ) ) {
396 - // Remove plugin from its current position.
397 - array_splice( $active_plugins, $newest_sdk_plugin_key, 1 );
398 -
399 - // Set it to be included first.
400 - array_unshift( $active_plugins, $newest_sdk_plugin_path );
401 -
402 - update_option( 'active_plugins', $active_plugins );
403 -
404 - return true;
405 - } else if ( is_multisite() && false === $newest_sdk_plugin_key ) {
406 - // Plugin is network active.
407 - $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
408 -
409 - if (isset($network_active_plugins[$newest_sdk_plugin_path])) {
410 - reset($network_active_plugins);
411 - if ( $newest_sdk_plugin_path === key($network_active_plugins) ) {
412 - // Plugin is already activated first on the network level.
413 - return false;
414 - } else if ( is_numeric( $newest_sdk_plugin_key ) ) {
415 - $time = $network_active_plugins[$newest_sdk_plugin_path];
416 -
417 - // Remove plugin from its current position.
418 - unset($network_active_plugins[$newest_sdk_plugin_path]);
419 -
420 - // Set it to be included first.
421 - $network_active_plugins = array($newest_sdk_plugin_path => $time) + $network_active_plugins;
422 -
423 - update_site_option( 'active_sitewide_plugins', $network_active_plugins );
424 -
425 - return true;
426 - }
427 - }
428 - }
429 -
430 - return false;
431 - }
432 -
433 - /**
434 - * Go over all Freemius SDKs in the system and find and "remember"
435 - * the newest SDK which is associated with an active plugin.
436 - *
437 - * @author Vova Feldman (@svovaf)
438 - * @since 1.1.6
439 - *
440 - * @global $fs_active_plugins
441 - */
442 - function fs_fallback_to_newest_active_sdk() {
443 - global $fs_active_plugins;
444 -
445 - /**
446 - * @var object $newest_sdk_data
447 - */
448 - $newest_sdk_data = null;
449 - $newest_sdk_path = null;
450 -
451 - foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
452 - if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
453 - ) {
454 - // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
455 - if ( 'plugin' === $data->type ) {
456 - $is_module_active = is_plugin_active( $data->plugin_path );
457 - } else {
458 - $active_theme = wp_get_theme();
459 - $is_module_active = ( $data->plugin_path === $active_theme->get_template() );
460 - }
461 -
462 - $is_sdk_exists = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) );
463 -
464 - if ( ! $is_module_active || ! $is_sdk_exists ) {
465 - unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
466 -
467 - // No need to store the data since it will be stored in fs_update_sdk_newest_version()
468 - // or explicitly with update_option().
469 - } else {
470 - $newest_sdk_data = $data;
471 - $newest_sdk_path = $sdk_relative_path;
472 - }
473 - }
474 - }
475 -
476 - if ( is_null( $newest_sdk_data ) ) {
477 - // Couldn't find any SDK reference.
478 - $fs_active_plugins = new stdClass();
479 - update_option( 'fs_active_plugins', $fs_active_plugins );
480 - } else {
481 - fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
482 - }
1 +<?php
2 + /**
3 + * IMPORTANT:
4 + * This file will be loaded based on the order of the plugins/themes load.
5 + * If there's a theme and a plugin using Freemius, the plugin's essential
6 + * file will always load first.
7 + *
8 + * @package Freemius
9 + * @copyright Copyright (c) 2015, Freemius, Inc.
10 + * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
11 + * @since 1.1.5
12 + */
13 +
14 + if ( ! function_exists( 'fs_normalize_path' ) ) {
15 + if ( function_exists( 'wp_normalize_path' ) ) {
16 + /**
17 + * Normalize a filesystem path.
18 + *
19 + * Replaces backslashes with forward slashes for Windows systems, and ensures
20 + * no duplicate slashes exist.
21 + *
22 + * @param string $path Path to normalize.
23 + *
24 + * @return string Normalized path.
25 + */
26 + function fs_normalize_path( $path ) {
27 + return wp_normalize_path( $path );
28 + }
29 + } else {
30 + function fs_normalize_path( $path ) {
31 + $path = str_replace( '\\', '/', $path );
32 + $path = preg_replace( '|/+|', '/', $path );
33 +
34 + return $path;
35 + }
36 + }
37 + }
38 +
39 + require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-2.2.1.php';
40 +
41 + #region Core Redirect (copied from BuddyPress) -----------------------------------------
42 +
43 + if ( ! function_exists( 'fs_redirect' ) ) {
44 + /**
45 + * Redirects to another page, with a workaround for the IIS Set-Cookie bug.
46 + *
47 + * @link http://support.microsoft.com/kb/q176113/
48 + * @since 1.5.1
49 + * @uses apply_filters() Calls 'wp_redirect' hook on $location and $status.
50 + *
51 + * @param string $location The path to redirect to.
52 + * @param bool $exit If true, exit after redirect (Since 1.2.1.5).
53 + * @param int $status Status code to use.
54 + *
55 + * @return bool False if $location is not set
56 + */
57 + function fs_redirect( $location, $exit = true, $status = 302 ) {
58 + global $is_IIS;
59 +
60 + $file = '';
61 + $line = '';
62 + if ( headers_sent($file, $line) ) {
63 + if ( WP_FS__DEBUG_SDK && class_exists( 'FS_Admin_Notices' ) ) {
64 + $notices = FS_Admin_Notices::instance( 'global' );
65 +
66 + $notices->add( "Freemius failed to redirect the page because the headers have been already sent from line <b><code>{$line}</code></b> in file <b><code>{$file}</code></b>. If it's unexpected, it usually happens due to invalid space and/or EOL character(s).", 'Oops...', 'error' );
67 + }
68 +
69 + return false;
70 + }
71 +
72 + if ( defined( 'DOING_AJAX' ) ) {
73 + // Don't redirect on AJAX calls.
74 + return false;
75 + }
76 +
77 + if ( ! $location ) // allows the wp_redirect filter to cancel a redirect
78 + {
79 + return false;
80 + }
81 +
82 + $location = fs_sanitize_redirect( $location );
83 +
84 + if ( $is_IIS ) {
85 + header( "Refresh: 0;url=$location" );
86 + } else {
87 + if ( php_sapi_name() != 'cgi-fcgi' ) {
88 + status_header( $status );
89 + } // This causes problems on IIS and some FastCGI setups
90 + header( "Location: $location" );
91 + }
92 +
93 + if ( $exit ) {
94 + exit();
95 + }
96 +
97 + return true;
98 + }
99 +
100 + if ( ! function_exists( 'fs_sanitize_redirect' ) ) {
101 + /**
102 + * Sanitizes a URL for use in a redirect.
103 + *
104 + * @since 2.3
105 + *
106 + * @param string $location
107 + *
108 + * @return string redirect-sanitized URL
109 + */
110 + function fs_sanitize_redirect( $location ) {
111 + $location = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:%!]|i', '', $location );
112 + $location = fs_kses_no_null( $location );
113 +
114 + // remove %0d and %0a from location
115 + $strip = array( '%0d', '%0a' );
116 + $found = true;
117 + while ( $found ) {
118 + $found = false;
119 + foreach ( (array) $strip as $val ) {
120 + while ( strpos( $location, $val ) !== false ) {
121 + $found = true;
122 + $location = str_replace( $val, '', $location );
123 + }
124 + }
125 + }
126 +
127 + return $location;
128 + }
129 + }
130 +
131 + if ( ! function_exists( 'fs_kses_no_null' ) ) {
132 + /**
133 + * Removes any NULL characters in $string.
134 + *
135 + * @since 1.0.0
136 + *
137 + * @param string $string
138 + *
139 + * @return string
140 + */
141 + function fs_kses_no_null( $string ) {
142 + $string = preg_replace( '/\0+/', '', $string );
143 + $string = preg_replace( '/(\\\\0)+/', '', $string );
144 +
145 + return $string;
146 + }
147 + }
148 + }
149 +
150 + #endregion Core Redirect (copied from BuddyPress) -----------------------------------------
151 +
152 + if ( ! function_exists( 'fs_get_ip' ) ) {
153 + /**
154 + * Get server IP.
155 + *
156 + * @since 2.5.1 This method returns the server IP.
157 + *
158 + * @author Vova Feldman (@svovaf)
159 + * @since 1.1.2
160 + *
161 + * @return string|null
162 + */
163 + function fs_get_ip() {
164 + return empty( $_SERVER[ 'SERVER_ADDR' ] ) ?
165 + null :
166 + $_SERVER[ 'SERVER_ADDR' ];
167 + }
168 + }
169 +
170 + /**
171 + * Leverage backtrace to find caller plugin main file path.
172 + *
173 + * @author Vova Feldman (@svovaf)
174 + * @since 1.0.6
175 + *
176 + * @return string
177 + */
178 + function fs_find_caller_plugin_file() {
179 + /**
180 + * All the code below will be executed once on activation.
181 + * If the user changes the main plugin's file name, the file_exists()
182 + * will catch it.
183 + */
184 + if ( ! function_exists( 'get_plugins' ) ) {
185 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
186 + }
187 +
188 + $all_plugins = fs_get_plugins( true );
189 + $all_plugins_paths = array();
190 +
191 + // Get active plugin's main files real full names (might be symlinks).
192 + foreach ( $all_plugins as $relative_path => $data ) {
193 + $all_plugins_paths[] = fs_normalize_path( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) );
194 + }
195 +
196 + $plugin_file = null;
197 + for ( $i = 1, $bt = debug_backtrace(), $len = count( $bt ); $i < $len; $i ++ ) {
198 + if ( empty( $bt[ $i ]['file'] ) ) {
199 + continue;
200 + }
201 +
202 + if ( in_array( fs_normalize_path( $bt[ $i ]['file'] ), $all_plugins_paths ) ) {
203 + $plugin_file = $bt[ $i ]['file'];
204 + break;
205 + }
206 + }
207 +
208 + if ( is_null( $plugin_file ) ) {
209 + // Throw an error to the developer in case of some edge case dev environment.
210 + wp_die(
211 + 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact [email protected] with the current error.',
212 + 'Error',
213 + array( 'back_link' => true )
214 + );
215 + }
216 +
217 + return $plugin_file;
218 + }
219 +
220 + require_once dirname( __FILE__ ) . '/supplements/fs-essential-functions-1.1.7.1.php';
221 +
222 + /**
223 + * Update SDK newest version reference.
224 + *
225 + * @author Vova Feldman (@svovaf)
226 + * @since 1.1.6
227 + *
228 + * @param string $sdk_relative_path
229 + * @param string|bool $plugin_file
230 + *
231 + * @global $fs_active_plugins
232 + */
233 + function fs_update_sdk_newest_version( $sdk_relative_path, $plugin_file = false ) {
234 + /**
235 + * If there is a plugin running an older version of FS (1.2.1 or below), the `fs_update_sdk_newest_version()`
236 + * function in the older version will be used instead of this one. But since the older version is using
237 + * the `is_plugin_active` function to check if a plugin is active, passing the theme's `plugin_path` to the
238 + * `is_plugin_active` function will return false since the path is not a plugin path, so `in_activation` will be
239 + * `true` for theme modules and the upgrading of the SDK version to 1.2.2 or newer version will work fine.
240 + *
241 + * Future versions that will call this function will use the proper logic here instead of just relying on the
242 + * `is_plugin_active` function to fail for themes.
243 + *
244 + * @author Leo Fajardo (@leorw)
245 + * @since 1.2.2
246 + */
247 +
248 + global $fs_active_plugins;
249 +
250 + $newest_sdk = $fs_active_plugins->plugins[ $sdk_relative_path ];
251 +
252 + if ( ! is_string( $plugin_file ) ) {
253 + $plugin_file = plugin_basename( fs_find_caller_plugin_file() );
254 + }
255 +
256 + if ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) {
257 + if ( ! function_exists( 'is_plugin_active' ) ) {
258 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
259 + }
260 +
261 + $in_activation = ( ! is_plugin_active( $plugin_file ) );
262 + } else {
263 + $theme = wp_get_theme();
264 + $in_activation = ( $newest_sdk->plugin_path == $theme->stylesheet );
265 + }
266 +
267 + $fs_active_plugins->newest = (object) array(
268 + 'plugin_path' => $plugin_file,
269 + 'sdk_path' => $sdk_relative_path,
270 + 'version' => $newest_sdk->version,
271 + 'in_activation' => $in_activation,
272 + 'timestamp' => time(),
273 + );
274 +
275 + // Update DB with latest SDK version and path.
276 + update_option( 'fs_active_plugins', $fs_active_plugins );
277 + }
278 +
279 + /**
280 + * Reorder the plugins load order so the plugin with the newest Freemius SDK is loaded first.
281 + *
282 + * @author Vova Feldman (@svovaf)
283 + * @since 1.1.6
284 + *
285 + * @return bool Was plugin order changed. Return false if plugin was loaded first anyways.
286 + *
287 + * @global $fs_active_plugins
288 + */
289 + function fs_newest_sdk_plugin_first() {
290 + global $fs_active_plugins;
291 +
292 + /**
293 + * @todo Multi-site network activated plugin are always loaded prior to site plugins so if there's a plugin activated in the network mode that has an older version of the SDK of another plugin which is site activated that has new SDK version, the fs-essential-functions.php will be loaded from the older SDK. Same thing about MU plugins (loaded even before network activated plugins).
294 + *
295 + * @link https://github.com/Freemius/wordpress-sdk/issues/26
296 + */
297 +
298 + $newest_sdk_plugin_path = $fs_active_plugins->newest->plugin_path;
299 +
300 + $active_plugins = get_option( 'active_plugins', array() );
301 + $updated_active_plugins = array( $newest_sdk_plugin_path );
302 +
303 + $plugin_found = false;
304 + $is_first_path = true;
305 +
306 + foreach ( $active_plugins as $key => $plugin_path ) {
307 + if ( $plugin_path === $newest_sdk_plugin_path ) {
308 + if ( $is_first_path ) {
309 + // if it's the first plugin already, no need to continue
310 + return false;
311 + }
312 +
313 + $plugin_found = true;
314 +
315 + // Skip the plugin (it is already added as the 1st item of $updated_active_plugins).
316 + continue;
317 + }
318 +
319 + $updated_active_plugins[] = $plugin_path;
320 +
321 + if ( $is_first_path ) {
322 + $is_first_path = false;
323 + }
324 + }
325 +
326 + if ( $plugin_found ) {
327 + update_option( 'active_plugins', $updated_active_plugins );
328 +
329 + return true;
330 + }
331 +
332 + if ( is_multisite() ) {
333 + // Plugin is network active.
334 + $network_active_plugins = get_site_option( 'active_sitewide_plugins', array() );
335 +
336 + if ( isset( $network_active_plugins[ $newest_sdk_plugin_path ] ) ) {
337 + reset( $network_active_plugins );
338 + if ( $newest_sdk_plugin_path === key( $network_active_plugins ) ) {
339 + // Plugin is already activated first on the network level.
340 + return false;
341 + } else {
342 + $time = $network_active_plugins[ $newest_sdk_plugin_path ];
343 +
344 + // Remove plugin from its current position.
345 + unset( $network_active_plugins[ $newest_sdk_plugin_path ] );
346 +
347 + // Set it to be included first.
348 + $network_active_plugins = array( $newest_sdk_plugin_path => $time ) + $network_active_plugins;
349 +
350 + update_site_option( 'active_sitewide_plugins', $network_active_plugins );
351 +
352 + return true;
353 + }
354 + }
355 + }
356 +
357 + return false;
358 + }
359 +
360 + /**
361 + * Go over all Freemius SDKs in the system and find and "remember"
362 + * the newest SDK which is associated with an active plugin.
363 + *
364 + * @author Vova Feldman (@svovaf)
365 + * @since 1.1.6
366 + *
367 + * @global $fs_active_plugins
368 + */
369 + function fs_fallback_to_newest_active_sdk() {
370 + global $fs_active_plugins;
371 +
372 + /**
373 + * @var object $newest_sdk_data
374 + */
375 + $newest_sdk_data = null;
376 + $newest_sdk_path = null;
377 +
378 + foreach ( $fs_active_plugins->plugins as $sdk_relative_path => $data ) {
379 + if ( is_null( $newest_sdk_data ) || version_compare( $data->version, $newest_sdk_data->version, '>' )
380 + ) {
381 + // If plugin inactive or SDK starter file doesn't exist, remove SDK reference.
382 + if ( 'plugin' === $data->type ) {
383 + $is_module_active = is_plugin_active( $data->plugin_path );
384 + } else {
385 + $active_theme = wp_get_theme();
386 + $is_module_active = ( $data->plugin_path === $active_theme->get_template() );
387 + }
388 +
389 + $is_sdk_exists = file_exists( fs_normalize_path( WP_PLUGIN_DIR . '/' . $sdk_relative_path . '/start.php' ) );
390 +
391 + if ( ! $is_module_active || ! $is_sdk_exists ) {
392 + unset( $fs_active_plugins->plugins[ $sdk_relative_path ] );
393 +
394 + // No need to store the data since it will be stored in fs_update_sdk_newest_version()
395 + // or explicitly with update_option().
396 + } else {
397 + $newest_sdk_data = $data;
398 + $newest_sdk_path = $sdk_relative_path;
399 + }
400 + }
401 + }
402 +
403 + if ( is_null( $newest_sdk_data ) ) {
404 + // Couldn't find any SDK reference.
405 + $fs_active_plugins = new stdClass();
406 + update_option( 'fs_active_plugins', $fs_active_plugins );
407 + } else {
408 + fs_update_sdk_newest_version( $newest_sdk_path, $newest_sdk_data->plugin_path );
409 + }
483 410 }