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