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/start.php +534 -522 1.2.3 → 2.7.3 View file →
@@ -1,522 +1,534 @@
1 -<?php
2 - /**
3 - * @package Freemius
4 - * @copyright Copyright (c) 2015, Freemius, Inc.
5 - * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 - * @since 1.0.3
7 - */
8 -
9 - if ( ! defined( 'ABSPATH' ) ) {
10 - exit;
11 - }
12 -
13 - /**
14 - * Freemius SDK Version.
15 - *
16 - * @var string
17 - */
18 - $this_sdk_version = '2.3.2';
19 -
20 - #region SDK Selection Logic --------------------------------------------------------------------
21 -
22 - /**
23 - * Special logic added on 1.1.6 to make sure that every Freemius powered plugin
24 - * will ALWAYS be loaded with the newest SDK from the active Freemius powered plugins.
25 - *
26 - * Since Freemius SDK is backward compatible, this will make sure that all Freemius powered
27 - * plugins will run correctly.
28 - *
29 - * @since 1.1.6
30 - */
31 -
32 - global $fs_active_plugins;
33 -
34 - if ( ! function_exists( 'fs_find_caller_plugin_file' ) ) {
35 - // Require SDK essentials.
36 - require_once dirname( __FILE__ ) . '/includes/fs-essential-functions.php';
37 - }
38 -
39 - /**
40 - * This complex logic fixes symlink issues (e.g. with Vargant). The logic assumes
41 - * that if it's a file from an SDK running in a theme, the location of the SDK
42 - * is in the main theme's folder.
43 - *
44 - * @author Vova Feldman (@svovaf)
45 - * @since 1.2.2.6
46 - */
47 - $file_path = fs_normalize_path( __FILE__ );
48 - $fs_root_path = dirname( $file_path );
49 - /**
50 - * Get the themes directory where the active theme is located (not passing the stylesheet will make WordPress
51 - * assume that the themes directory is inside `wp-content`.
52 - *
53 - * @author Leo Fajardo (@leorw)
54 - * @since 2.2.3
55 - */
56 - $themes_directory = get_theme_root( get_stylesheet() );
57 - $themes_directory_name = basename( $themes_directory );
58 - $theme_candidate_basename = basename( dirname( $fs_root_path ) ) . '/' . basename( $fs_root_path );
59 -
60 - if ( $file_path == fs_normalize_path( realpath( trailingslashit( $themes_directory ) . $theme_candidate_basename . '/' . basename( $file_path ) ) )
61 - ) {
62 - $this_sdk_relative_path = '../' . $themes_directory_name . '/' . $theme_candidate_basename;
63 - $is_theme = true;
64 - } else {
65 - $this_sdk_relative_path = plugin_basename( $fs_root_path );
66 - $is_theme = false;
67 - }
68 -
69 - if ( ! isset( $fs_active_plugins ) ) {
70 - // Load all Freemius powered active plugins.
71 - $fs_active_plugins = get_option( 'fs_active_plugins', new stdClass() );
72 -
73 - if ( ! isset( $fs_active_plugins->plugins ) ) {
74 - $fs_active_plugins->plugins = array();
75 - }
76 - }
77 -
78 - if ( empty( $fs_active_plugins->abspath ) ) {
79 - /**
80 - * Store the WP install absolute path reference to identify environment change
81 - * while replicating the storage.
82 - *
83 - * @author Vova Feldman (@svovaf)
84 - * @since 1.2.1.7
85 - */
86 - $fs_active_plugins->abspath = ABSPATH;
87 - } else {
88 - if ( ABSPATH !== $fs_active_plugins->abspath ) {
89 - /**
90 - * WordPress path has changed, cleanup the SDK references cache.
91 - * This resolves issues triggered when spinning a staging environments
92 - * while replicating the database.
93 - *
94 - * @author Vova Feldman (@svovaf)
95 - * @since 1.2.1.7
96 - */
97 - $fs_active_plugins->abspath = ABSPATH;
98 - $fs_active_plugins->plugins = array();
99 - unset( $fs_active_plugins->newest );
100 - } else {
101 - /**
102 - * Make sure SDK references are still valid. This resolves
103 - * issues when users hard delete modules via FTP.
104 - *
105 - * @author Vova Feldman (@svovaf)
106 - * @since 1.2.1.7
107 - */
108 - $has_changes = false;
109 - foreach ( $fs_active_plugins->plugins as $sdk_path => $data ) {
110 - if ( ! file_exists( ( isset( $data->type ) && 'theme' === $data->type ? $themes_directory : WP_PLUGIN_DIR ) . '/' . $sdk_path ) ) {
111 - unset( $fs_active_plugins->plugins[ $sdk_path ] );
112 - $has_changes = true;
113 - }
114 - }
115 -
116 - if ( $has_changes ) {
117 - if ( empty( $fs_active_plugins->plugins ) ) {
118 - unset( $fs_active_plugins->newest );
119 - }
120 -
121 - update_option( 'fs_active_plugins', $fs_active_plugins );
122 - }
123 - }
124 - }
125 -
126 - if ( ! function_exists( 'fs_find_direct_caller_plugin_file' ) ) {
127 - require_once dirname( __FILE__ ) . '/includes/supplements/fs-essential-functions-1.1.7.1.php';
128 - }
129 -
130 - if ( ! function_exists( 'fs_get_plugins' ) ) {
131 - require_once dirname( __FILE__ ) . '/includes/supplements/fs-essential-functions-2.2.1.php';
132 - }
133 -
134 - // Update current SDK info based on the SDK path.
135 - if ( ! isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) ||
136 - $this_sdk_version != $fs_active_plugins->plugins[ $this_sdk_relative_path ]->version
137 - ) {
138 - if ( $is_theme ) {
139 - $plugin_path = basename( dirname( $this_sdk_relative_path ) );
140 - } else {
141 - $plugin_path = plugin_basename( fs_find_direct_caller_plugin_file( $file_path ) );
142 - }
143 -
144 - $fs_active_plugins->plugins[ $this_sdk_relative_path ] = (object) array(
145 - 'version' => $this_sdk_version,
146 - 'type' => ( $is_theme ? 'theme' : 'plugin' ),
147 - 'timestamp' => time(),
148 - 'plugin_path' => $plugin_path,
149 - );
150 - }
151 -
152 - $is_current_sdk_newest = isset( $fs_active_plugins->newest ) && ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path );
153 -
154 - if ( ! isset( $fs_active_plugins->newest ) ) {
155 - /**
156 - * This will be executed only once, for the first time a Freemius powered plugin is activated.
157 - */
158 - fs_update_sdk_newest_version( $this_sdk_relative_path, $fs_active_plugins->plugins[ $this_sdk_relative_path ]->plugin_path );
159 -
160 - $is_current_sdk_newest = true;
161 - } else if ( version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '<' ) ) {
162 - /**
163 - * Current SDK is newer than the newest stored SDK.
164 - */
165 - fs_update_sdk_newest_version( $this_sdk_relative_path, $fs_active_plugins->plugins[ $this_sdk_relative_path ]->plugin_path );
166 -
167 - if ( class_exists( 'Freemius' ) ) {
168 - // Older SDK version was already loaded.
169 -
170 - if ( ! $fs_active_plugins->newest->in_activation ) {
171 - // Re-order plugins to load this plugin first.
172 - fs_newest_sdk_plugin_first();
173 - }
174 -
175 - // Refresh page.
176 - fs_redirect( $_SERVER['REQUEST_URI'] );
177 - }
178 - } else {
179 - if ( ! function_exists( 'get_plugins' ) ) {
180 - require_once ABSPATH . 'wp-admin/includes/plugin.php';
181 - }
182 -
183 - $fs_newest_sdk = $fs_active_plugins->newest;
184 - $fs_newest_sdk = $fs_active_plugins->plugins[ $fs_newest_sdk->sdk_path ];
185 -
186 - $is_newest_sdk_type_theme = ( isset( $fs_newest_sdk->type ) && 'theme' === $fs_newest_sdk->type );
187 -
188 - if ( ! $is_newest_sdk_type_theme ) {
189 - $is_newest_sdk_plugin_active = is_plugin_active( $fs_newest_sdk->plugin_path );
190 - } else {
191 - $current_theme = wp_get_theme();
192 - $is_newest_sdk_plugin_active = ( $current_theme->stylesheet === $fs_newest_sdk->plugin_path );
193 -
194 - $current_theme_parent = $current_theme->parent();
195 -
196 - /**
197 - * If the current theme is a child of the theme that has the newest SDK, this prevents a redirects loop
198 - * from happening by keeping the SDK info stored in the `fs_active_plugins` option.
199 - */
200 - if ( ! $is_newest_sdk_plugin_active && $current_theme_parent instanceof WP_Theme ) {
201 - $is_newest_sdk_plugin_active = ( $fs_newest_sdk->plugin_path === $current_theme_parent->stylesheet );
202 - }
203 - }
204 -
205 - if ( $is_current_sdk_newest &&
206 - ! $is_newest_sdk_plugin_active &&
207 - ! $fs_active_plugins->newest->in_activation
208 - ) {
209 - // If current SDK is the newest and the plugin is NOT active, it means
210 - // that the current plugin in activation mode.
211 - $fs_active_plugins->newest->in_activation = true;
212 - update_option( 'fs_active_plugins', $fs_active_plugins );
213 - }
214 -
215 - if ( ! $is_theme ) {
216 - $sdk_starter_path = fs_normalize_path( WP_PLUGIN_DIR . '/' . $this_sdk_relative_path . '/start.php' );
217 - } else {
218 - $sdk_starter_path = fs_normalize_path(
219 - $themes_directory
220 - . '/'
221 - . str_replace( "../{$themes_directory_name}/", '', $this_sdk_relative_path )
222 - . '/start.php' );
223 - }
224 -
225 - $is_newest_sdk_path_valid = ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) && file_exists( $sdk_starter_path );
226 -
227 - if ( ! $is_newest_sdk_path_valid && ! $is_current_sdk_newest ) {
228 - // Plugin with newest SDK is no longer active, or SDK was moved to a different location.
229 - unset( $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ] );
230 - }
231 -
232 - if ( ! ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) ||
233 - ! $is_newest_sdk_path_valid ||
234 - // Is newest SDK downgraded.
235 - ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
236 - version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '>' ) )
237 - ) {
238 - /**
239 - * Plugin with newest SDK is no longer active.
240 - * OR
241 - * The newest SDK was in the current plugin. BUT, seems like the version of
242 - * the SDK was downgraded to a lower SDK.
243 - */
244 - // Find the active plugin with the newest SDK version and update the newest reference.
245 - fs_fallback_to_newest_active_sdk();
246 - } else {
247 - if ( $is_newest_sdk_plugin_active &&
248 - $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
249 - ( $fs_active_plugins->newest->in_activation ||
250 - ( class_exists( 'Freemius' ) && ( ! defined( 'WP_FS__SDK_VERSION' ) || version_compare( WP_FS__SDK_VERSION, $this_sdk_version, '<' ) ) )
251 - )
252 -
253 - ) {
254 - if ( $fs_active_plugins->newest->in_activation && ! $is_newest_sdk_type_theme ) {
255 - // Plugin no more in activation.
256 - $fs_active_plugins->newest->in_activation = false;
257 - update_option( 'fs_active_plugins', $fs_active_plugins );
258 - }
259 -
260 - // Reorder plugins to load plugin with newest SDK first.
261 - if ( fs_newest_sdk_plugin_first() ) {
262 - // Refresh page after re-order to make sure activated plugin loads newest SDK.
263 - if ( class_exists( 'Freemius' ) ) {
264 - fs_redirect( $_SERVER['REQUEST_URI'] );
265 - }
266 - }
267 - }
268 - }
269 - }
270 -
271 - if ( class_exists( 'Freemius' ) ) {
272 - // SDK was already loaded.
273 - return;
274 - }
275 -
276 - if ( version_compare( $this_sdk_version, $fs_active_plugins->newest->version, '<' ) ) {
277 - $newest_sdk = $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ];
278 -
279 - $plugins_or_theme_dir_path = ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) ?
280 - WP_PLUGIN_DIR :
281 - $themes_directory;
282 -
283 - $newest_sdk_starter = fs_normalize_path(
284 - $plugins_or_theme_dir_path
285 - . '/'
286 - . str_replace( "../{$themes_directory_name}/", '', $fs_active_plugins->newest->sdk_path )
287 - . '/start.php' );
288 -
289 - if ( file_exists( $newest_sdk_starter ) ) {
290 - // Reorder plugins to load plugin with newest SDK first.
291 - fs_newest_sdk_plugin_first();
292 -
293 - // There's a newer SDK version, load it instead of the current one!
294 - require_once $newest_sdk_starter;
295 -
296 - return;
297 - }
298 - }
299 -
300 - #endregion SDK Selection Logic --------------------------------------------------------------------
301 -
302 - #region Hooks & Filters Collection --------------------------------------------------------------------
303 -
304 - /**
305 - * Freemius hooks (actions & filters) tags structure:
306 - *
307 - * fs_{filter/action_name}_{plugin_slug}
308 - *
309 - * --------------------------------------------------------
310 - *
311 - * Usage with WordPress' add_action() / add_filter():
312 - *
313 - * add_action('fs_{filter/action_name}_{plugin_slug}', $callable);
314 - *
315 - * --------------------------------------------------------
316 - *
317 - * Usage with Freemius' instance add_action() / add_filter():
318 - *
319 - * // No need to add 'fs_' prefix nor '_{plugin_slug}' suffix.
320 - * my_freemius()->add_action('{action_name}', $callable);
321 - *
322 - * --------------------------------------------------------
323 - *
324 - * Freemius filters collection:
325 - *
326 - * fs_connect_url_{plugin_slug}
327 - * fs_trial_promotion_message_{plugin_slug}
328 - * fs_is_long_term_user_{plugin_slug}
329 - * fs_uninstall_reasons_{plugin_slug}
330 - * fs_is_plugin_update_{plugin_slug}
331 - * fs_api_domains_{plugin_slug}
332 - * fs_email_template_sections_{plugin_slug}
333 - * fs_support_forum_submenu_{plugin_slug}
334 - * fs_support_forum_url_{plugin_slug}
335 - * fs_connect_message_{plugin_slug}
336 - * fs_connect_message_on_update_{plugin_slug}
337 - * fs_uninstall_confirmation_message_{plugin_slug}
338 - * fs_pending_activation_message_{plugin_slug}
339 - * fs_is_submenu_visible_{plugin_slug}
340 - * fs_plugin_icon_{plugin_slug}
341 - * fs_show_trial_{plugin_slug}
342 - *
343 - * --------------------------------------------------------
344 - *
345 - * Freemius actions collection:
346 - *
347 - * fs_after_license_loaded_{plugin_slug}
348 - * fs_after_license_change_{plugin_slug}
349 - * fs_after_plans_sync_{plugin_slug}
350 - *
351 - * fs_after_account_details_{plugin_slug}
352 - * fs_after_account_user_sync_{plugin_slug}
353 - * fs_after_account_plan_sync_{plugin_slug}
354 - * fs_before_account_load_{plugin_slug}
355 - * fs_after_account_connection_{plugin_slug}
356 - * fs_account_property_edit_{plugin_slug}
357 - * fs_account_email_verified_{plugin_slug}
358 - * fs_account_page_load_before_departure_{plugin_slug}
359 - * fs_before_account_delete_{plugin_slug}
360 - * fs_after_account_delete_{plugin_slug}
361 - *
362 - * fs_sdk_version_update_{plugin_slug}
363 - * fs_plugin_version_update_{plugin_slug}
364 - *
365 - * fs_initiated_{plugin_slug}
366 - * fs_after_init_plugin_registered_{plugin_slug}
367 - * fs_after_init_plugin_anonymous_{plugin_slug}
368 - * fs_after_init_plugin_pending_activations_{plugin_slug}
369 - * fs_after_init_addon_registered_{plugin_slug}
370 - * fs_after_init_addon_anonymous_{plugin_slug}
371 - * fs_after_init_addon_pending_activations_{plugin_slug}
372 - *
373 - * fs_after_premium_version_activation_{plugin_slug}
374 - * fs_after_free_version_reactivation_{plugin_slug}
375 - *
376 - * fs_after_uninstall_{plugin_slug}
377 - * fs_before_admin_menu_init_{plugin_slug}
378 - */
379 -
380 - #endregion Hooks & Filters Collection --------------------------------------------------------------------
381 -
382 - if ( ! class_exists( 'Freemius' ) ) {
383 -
384 - if ( ! defined( 'WP_FS__SDK_VERSION' ) ) {
385 - define( 'WP_FS__SDK_VERSION', $this_sdk_version );
386 - }
387 -
388 - $plugins_or_theme_dir_path = fs_normalize_path( trailingslashit( $is_theme ?
389 - $themes_directory :
390 - WP_PLUGIN_DIR ) );
391 -
392 - if ( 0 === strpos( $file_path, $plugins_or_theme_dir_path ) ) {
393 - // No symlinks
394 - } else {
395 - /**
396 - * This logic finds the SDK symlink and set WP_FS__DIR to use it.
397 - *
398 - * @author Vova Feldman (@svovaf)
399 - * @since 1.2.2.5
400 - */
401 - $sdk_symlink = null;
402 -
403 - // Try to load SDK's symlink from cache.
404 - if ( isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
405 - is_object( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
406 - ! empty( $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink )
407 - ) {
408 - $sdk_symlink = $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink;
409 - if ( 0 === strpos( $sdk_symlink, $plugins_or_theme_dir_path ) ) {
410 - /**
411 - * Make the symlink path relative.
412 - *
413 - * @author Leo Fajardo (@leorw)
414 - */
415 - $sdk_symlink = substr( $sdk_symlink, strlen( $plugins_or_theme_dir_path ) );
416 -
417 - $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink = $sdk_symlink;
418 - update_option( 'fs_active_plugins', $fs_active_plugins );
419 - }
420 -
421 - $realpath = realpath( $plugins_or_theme_dir_path . $sdk_symlink );
422 - if ( ! is_string( $realpath ) || ! file_exists( $realpath ) ) {
423 - $sdk_symlink = null;
424 - }
425 - }
426 -
427 - if ( empty( $sdk_symlink ) ) // Has symlinks, therefore, we need to configure WP_FS__DIR based on the symlink.
428 - {
429 - $partial_path_right = basename( $file_path );
430 - $partial_path_left = dirname( $file_path );
431 - $realpath = realpath( $plugins_or_theme_dir_path . $partial_path_right );
432 -
433 - while ( '/' !== $partial_path_left &&
434 - ( false === $realpath || $file_path !== fs_normalize_path( $realpath ) )
435 - ) {
436 - $partial_path_right = trailingslashit( basename( $partial_path_left ) ) . $partial_path_right;
437 - $partial_path_left_prev = $partial_path_left;
438 - $partial_path_left = dirname( $partial_path_left_prev );
439 -
440 - /**
441 - * Avoid infinite loop if for example `$partial_path_left_prev` is `C:/`, in this case,
442 - * `dirname( 'C:/' )` will return `C:/`.
443 - *
444 - * @author Leo Fajardo (@leorw)
445 - */
446 - if ( $partial_path_left === $partial_path_left_prev ) {
447 - $partial_path_left = '';
448 - break;
449 - }
450 -
451 - $realpath = realpath( $plugins_or_theme_dir_path . $partial_path_right );
452 - }
453 -
454 - if ( ! empty( $partial_path_left ) && '/' !== $partial_path_left ) {
455 - $sdk_symlink = fs_normalize_path( dirname( $partial_path_right ) );
456 -
457 - // Cache value.
458 - if ( isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
459 - is_object( $fs_active_plugins->plugins[ $this_sdk_relative_path ] )
460 - ) {
461 - $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink = $sdk_symlink;
462 - update_option( 'fs_active_plugins', $fs_active_plugins );
463 - }
464 - }
465 - }
466 -
467 - if ( ! empty( $sdk_symlink ) ) {
468 - // Set SDK dir to the symlink path.
469 - define( 'WP_FS__DIR', $plugins_or_theme_dir_path . $sdk_symlink );
470 - }
471 - }
472 -
473 - // Load SDK files.
474 - require_once dirname( __FILE__ ) . '/require.php';
475 -
476 - /**
477 - * Quick shortcut to get Freemius for specified plugin.
478 - * Used by various templates.
479 - *
480 - * @param number $module_id
481 - *
482 - * @return Freemius
483 - */
484 - function freemius( $module_id ) {
485 - return Freemius::instance( $module_id );
486 - }
487 -
488 - /**
489 - * @param string $slug
490 - * @param number $plugin_id
491 - * @param string $public_key
492 - * @param bool $is_live Is live or test plugin.
493 - * @param bool $is_premium Hints freemius if running the premium plugin or not.
494 - *
495 - * @return Freemius
496 - *
497 - * @deprecated Please use fs_dynamic_init().
498 - */
499 - function fs_init( $slug, $plugin_id, $public_key, $is_live = true, $is_premium = true ) {
500 - $fs = Freemius::instance( $plugin_id, $slug, true );
501 - $fs->init( $plugin_id, $public_key, $is_live, $is_premium );
502 -
503 - return $fs;
504 - }
505 -
506 - /**
507 - * @param array <string,string> $module Plugin or Theme details.
508 - *
509 - * @return Freemius
510 - * @throws Freemius_Exception
511 - */
512 - function fs_dynamic_init( $module ) {
513 - $fs = Freemius::instance( $module['id'], $module['slug'], true );
514 - $fs->dynamic_init( $module );
515 -
516 - return $fs;
517 - }
518 -
519 - function fs_dump_log() {
520 - FS_Logger::dump();
521 - }
522 - }
1 +<?php
2 + /**
3 + * @package Freemius
4 + * @copyright Copyright (c) 2015, Freemius, Inc.
5 + * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 + * @since 1.0.3
7 + */
8 +
9 + if ( ! defined( 'ABSPATH' ) ) {
10 + exit;
11 + }
12 +
13 + /**
14 + * Freemius SDK Version.
15 + *
16 + * @var string
17 + */
18 + $this_sdk_version = '2.5.12';
19 +
20 + #region SDK Selection Logic --------------------------------------------------------------------
21 +
22 + /**
23 + * Special logic added on 1.1.6 to make sure that every Freemius powered plugin
24 + * will ALWAYS be loaded with the newest SDK from the active Freemius powered plugins.
25 + *
26 + * Since Freemius SDK is backward compatible, this will make sure that all Freemius powered
27 + * plugins will run correctly.
28 + *
29 + * @since 1.1.6
30 + */
31 +
32 + global $fs_active_plugins;
33 +
34 + if ( ! function_exists( 'fs_find_caller_plugin_file' ) ) {
35 + // Require SDK essentials.
36 + require_once dirname( __FILE__ ) . '/includes/fs-essential-functions.php';
37 + }
38 +
39 + /**
40 + * This complex logic fixes symlink issues (e.g. with Vargant). The logic assumes
41 + * that if it's a file from an SDK running in a theme, the location of the SDK
42 + * is in the main theme's folder.
43 + *
44 + * @author Vova Feldman (@svovaf)
45 + * @since 1.2.2.6
46 + */
47 + $file_path = fs_normalize_path( __FILE__ );
48 + $fs_root_path = dirname( $file_path );
49 + /**
50 + * Get the themes directory where the active theme is located (not passing the stylesheet will make WordPress
51 + * assume that the themes directory is inside `wp-content`.
52 + *
53 + * @author Leo Fajardo (@leorw)
54 + * @since 2.2.3
55 + */
56 + $themes_directory = get_theme_root( get_stylesheet() );
57 + $themes_directory_name = basename( $themes_directory );
58 + $theme_candidate_basename = basename( dirname( $fs_root_path ) ) . '/' . basename( $fs_root_path );
59 +
60 + if ( $file_path == fs_normalize_path( realpath( trailingslashit( $themes_directory ) . $theme_candidate_basename . '/' . basename( $file_path ) ) )
61 + ) {
62 + $this_sdk_relative_path = '../' . $themes_directory_name . '/' . $theme_candidate_basename;
63 + $is_theme = true;
64 + } else {
65 + $this_sdk_relative_path = plugin_basename( $fs_root_path );
66 + $is_theme = false;
67 + }
68 +
69 + if ( ! isset( $fs_active_plugins ) ) {
70 + // Load all Freemius powered active plugins.
71 + $fs_active_plugins = get_option( 'fs_active_plugins' );
72 +
73 + if ( ! is_object( $fs_active_plugins ) ) {
74 + $fs_active_plugins = new stdClass();
75 + }
76 +
77 + if ( ! isset( $fs_active_plugins->plugins ) ) {
78 + $fs_active_plugins->plugins = array();
79 + }
80 + }
81 +
82 + if ( empty( $fs_active_plugins->abspath ) ) {
83 + /**
84 + * Store the WP install absolute path reference to identify environment change
85 + * while replicating the storage.
86 + *
87 + * @author Vova Feldman (@svovaf)
88 + * @since 1.2.1.7
89 + */
90 + $fs_active_plugins->abspath = ABSPATH;
91 + } else {
92 + if ( ABSPATH !== $fs_active_plugins->abspath ) {
93 + /**
94 + * WordPress path has changed, cleanup the SDK references cache.
95 + * This resolves issues triggered when spinning a staging environments
96 + * while replicating the database.
97 + *
98 + * @author Vova Feldman (@svovaf)
99 + * @since 1.2.1.7
100 + */
101 + $fs_active_plugins->abspath = ABSPATH;
102 + $fs_active_plugins->plugins = array();
103 + unset( $fs_active_plugins->newest );
104 + } else {
105 + /**
106 + * Make sure SDK references are still valid. This resolves
107 + * issues when users hard delete modules via FTP.
108 + *
109 + * @author Vova Feldman (@svovaf)
110 + * @since 1.2.1.7
111 + */
112 + $has_changes = false;
113 + foreach ( $fs_active_plugins->plugins as $sdk_path => $data ) {
114 + if ( ! file_exists( ( isset( $data->type ) && 'theme' === $data->type ? $themes_directory : WP_PLUGIN_DIR ) . '/' . $sdk_path ) ) {
115 + unset( $fs_active_plugins->plugins[ $sdk_path ] );
116 +
117 + if (
118 + ! empty( $fs_active_plugins->newest ) &&
119 + $sdk_path === $fs_active_plugins->newest->sdk_path
120 + ) {
121 + unset( $fs_active_plugins->newest );
122 + }
123 +
124 + $has_changes = true;
125 + }
126 + }
127 +
128 + if ( $has_changes ) {
129 + if ( empty( $fs_active_plugins->plugins ) ) {
130 + unset( $fs_active_plugins->newest );
131 + }
132 +
133 + update_option( 'fs_active_plugins', $fs_active_plugins );
134 + }
135 + }
136 + }
137 +
138 + if ( ! function_exists( 'fs_find_direct_caller_plugin_file' ) ) {
139 + require_once dirname( __FILE__ ) . '/includes/supplements/fs-essential-functions-1.1.7.1.php';
140 + }
141 +
142 + if ( ! function_exists( 'fs_get_plugins' ) ) {
143 + require_once dirname( __FILE__ ) . '/includes/supplements/fs-essential-functions-2.2.1.php';
144 + }
145 +
146 + // Update current SDK info based on the SDK path.
147 + if ( ! isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) ||
148 + $this_sdk_version != $fs_active_plugins->plugins[ $this_sdk_relative_path ]->version
149 + ) {
150 + if ( $is_theme ) {
151 + $plugin_path = basename( dirname( $this_sdk_relative_path ) );
152 + } else {
153 + $plugin_path = plugin_basename( fs_find_direct_caller_plugin_file( $file_path ) );
154 + }
155 +
156 + $fs_active_plugins->plugins[ $this_sdk_relative_path ] = (object) array(
157 + 'version' => $this_sdk_version,
158 + 'type' => ( $is_theme ? 'theme' : 'plugin' ),
159 + 'timestamp' => time(),
160 + 'plugin_path' => $plugin_path,
161 + );
162 + }
163 +
164 + $is_current_sdk_newest = isset( $fs_active_plugins->newest ) && ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path );
165 +
166 + if ( ! isset( $fs_active_plugins->newest ) ) {
167 + /**
168 + * This will be executed only once, for the first time a Freemius powered plugin is activated.
169 + */
170 + fs_update_sdk_newest_version( $this_sdk_relative_path, $fs_active_plugins->plugins[ $this_sdk_relative_path ]->plugin_path );
171 +
172 + $is_current_sdk_newest = true;
173 + } else if ( version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '<' ) ) {
174 + /**
175 + * Current SDK is newer than the newest stored SDK.
176 + */
177 + fs_update_sdk_newest_version( $this_sdk_relative_path, $fs_active_plugins->plugins[ $this_sdk_relative_path ]->plugin_path );
178 +
179 + if ( class_exists( 'Freemius' ) ) {
180 + // Older SDK version was already loaded.
181 +
182 + if ( ! $fs_active_plugins->newest->in_activation ) {
183 + // Re-order plugins to load this plugin first.
184 + fs_newest_sdk_plugin_first();
185 + }
186 +
187 + // Refresh page.
188 + fs_redirect( $_SERVER['REQUEST_URI'] );
189 + }
190 + } else {
191 + if ( ! function_exists( 'get_plugins' ) ) {
192 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
193 + }
194 +
195 + $fs_newest_sdk = $fs_active_plugins->newest;
196 + $fs_newest_sdk = $fs_active_plugins->plugins[ $fs_newest_sdk->sdk_path ];
197 +
198 + $is_newest_sdk_type_theme = ( isset( $fs_newest_sdk->type ) && 'theme' === $fs_newest_sdk->type );
199 +
200 + if ( ! $is_newest_sdk_type_theme ) {
201 + $is_newest_sdk_plugin_active = is_plugin_active( $fs_newest_sdk->plugin_path );
202 + } else {
203 + $current_theme = wp_get_theme();
204 + $is_newest_sdk_plugin_active = ( $current_theme->stylesheet === $fs_newest_sdk->plugin_path );
205 +
206 + $current_theme_parent = $current_theme->parent();
207 +
208 + /**
209 + * If the current theme is a child of the theme that has the newest SDK, this prevents a redirects loop
210 + * from happening by keeping the SDK info stored in the `fs_active_plugins` option.
211 + */
212 + if ( ! $is_newest_sdk_plugin_active && $current_theme_parent instanceof WP_Theme ) {
213 + $is_newest_sdk_plugin_active = ( $fs_newest_sdk->plugin_path === $current_theme_parent->stylesheet );
214 + }
215 + }
216 +
217 + if ( $is_current_sdk_newest &&
218 + ! $is_newest_sdk_plugin_active &&
219 + ! $fs_active_plugins->newest->in_activation
220 + ) {
221 + // If current SDK is the newest and the plugin is NOT active, it means
222 + // that the current plugin in activation mode.
223 + $fs_active_plugins->newest->in_activation = true;
224 + update_option( 'fs_active_plugins', $fs_active_plugins );
225 + }
226 +
227 + if ( ! $is_theme ) {
228 + $sdk_starter_path = fs_normalize_path( WP_PLUGIN_DIR . '/' . $this_sdk_relative_path . '/start.php' );
229 + } else {
230 + $sdk_starter_path = fs_normalize_path(
231 + $themes_directory
232 + . '/'
233 + . str_replace( "../{$themes_directory_name}/", '', $this_sdk_relative_path )
234 + . '/start.php' );
235 + }
236 +
237 + $is_newest_sdk_path_valid = ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) && file_exists( $sdk_starter_path );
238 +
239 + if ( ! $is_newest_sdk_path_valid && ! $is_current_sdk_newest ) {
240 + // Plugin with newest SDK is no longer active, or SDK was moved to a different location.
241 + unset( $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ] );
242 + }
243 +
244 + if ( ! ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) ||
245 + ! $is_newest_sdk_path_valid ||
246 + // Is newest SDK downgraded.
247 + ( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
248 + version_compare( $fs_active_plugins->newest->version, $this_sdk_version, '>' ) )
249 + ) {
250 + /**
251 + * Plugin with newest SDK is no longer active.
252 + * OR
253 + * The newest SDK was in the current plugin. BUT, seems like the version of
254 + * the SDK was downgraded to a lower SDK.
255 + */
256 + // Find the active plugin with the newest SDK version and update the newest reference.
257 + fs_fallback_to_newest_active_sdk();
258 + } else {
259 + if ( $is_newest_sdk_plugin_active &&
260 + $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
261 + ( $fs_active_plugins->newest->in_activation ||
262 + ( class_exists( 'Freemius' ) && ( ! defined( 'WP_FS__SDK_VERSION' ) || version_compare( WP_FS__SDK_VERSION, $this_sdk_version, '<' ) ) )
263 + )
264 +
265 + ) {
266 + if ( $fs_active_plugins->newest->in_activation && ! $is_newest_sdk_type_theme ) {
267 + // Plugin no more in activation.
268 + $fs_active_plugins->newest->in_activation = false;
269 + update_option( 'fs_active_plugins', $fs_active_plugins );
270 + }
271 +
272 + // Reorder plugins to load plugin with newest SDK first.
273 + if ( fs_newest_sdk_plugin_first() ) {
274 + // Refresh page after re-order to make sure activated plugin loads newest SDK.
275 + if ( class_exists( 'Freemius' ) ) {
276 + fs_redirect( $_SERVER['REQUEST_URI'] );
277 + }
278 + }
279 + }
280 + }
281 + }
282 +
283 + if ( class_exists( 'Freemius' ) ) {
284 + // SDK was already loaded.
285 + return;
286 + }
287 +
288 + if ( version_compare( $this_sdk_version, $fs_active_plugins->newest->version, '<' ) ) {
289 + $newest_sdk = $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ];
290 +
291 + $plugins_or_theme_dir_path = ( ! isset( $newest_sdk->type ) || 'theme' !== $newest_sdk->type ) ?
292 + WP_PLUGIN_DIR :
293 + $themes_directory;
294 +
295 + $newest_sdk_starter = fs_normalize_path(
296 + $plugins_or_theme_dir_path
297 + . '/'
298 + . str_replace( "../{$themes_directory_name}/", '', $fs_active_plugins->newest->sdk_path )
299 + . '/start.php' );
300 +
301 + if ( file_exists( $newest_sdk_starter ) ) {
302 + // Reorder plugins to load plugin with newest SDK first.
303 + fs_newest_sdk_plugin_first();
304 +
305 + // There's a newer SDK version, load it instead of the current one!
306 + require_once $newest_sdk_starter;
307 +
308 + return;
309 + }
310 + }
311 +
312 + #endregion SDK Selection Logic --------------------------------------------------------------------
313 +
314 + #region Hooks & Filters Collection --------------------------------------------------------------------
315 +
316 + /**
317 + * Freemius hooks (actions & filters) tags structure:
318 + *
319 + * fs_{filter/action_name}_{plugin_slug}
320 + *
321 + * --------------------------------------------------------
322 + *
323 + * Usage with WordPress' add_action() / add_filter():
324 + *
325 + * add_action('fs_{filter/action_name}_{plugin_slug}', $callable);
326 + *
327 + * --------------------------------------------------------
328 + *
329 + * Usage with Freemius' instance add_action() / add_filter():
330 + *
331 + * // No need to add 'fs_' prefix nor '_{plugin_slug}' suffix.
332 + * my_freemius()->add_action('{action_name}', $callable);
333 + *
334 + * --------------------------------------------------------
335 + *
336 + * Freemius filters collection:
337 + *
338 + * fs_connect_url_{plugin_slug}
339 + * fs_trial_promotion_message_{plugin_slug}
340 + * fs_is_long_term_user_{plugin_slug}
341 + * fs_uninstall_reasons_{plugin_slug}
342 + * fs_is_plugin_update_{plugin_slug}
343 + * fs_api_domains_{plugin_slug}
344 + * fs_email_template_sections_{plugin_slug}
345 + * fs_support_forum_submenu_{plugin_slug}
346 + * fs_support_forum_url_{plugin_slug}
347 + * fs_connect_message_{plugin_slug}
348 + * fs_connect_message_on_update_{plugin_slug}
349 + * fs_uninstall_confirmation_message_{plugin_slug}
350 + * fs_pending_activation_message_{plugin_slug}
351 + * fs_is_submenu_visible_{plugin_slug}
352 + * fs_plugin_icon_{plugin_slug}
353 + * fs_show_trial_{plugin_slug}
354 + *
355 + * --------------------------------------------------------
356 + *
357 + * Freemius actions collection:
358 + *
359 + * fs_after_license_loaded_{plugin_slug}
360 + * fs_after_license_change_{plugin_slug}
361 + * fs_after_plans_sync_{plugin_slug}
362 + *
363 + * fs_after_account_details_{plugin_slug}
364 + * fs_after_account_user_sync_{plugin_slug}
365 + * fs_after_account_plan_sync_{plugin_slug}
366 + * fs_before_account_load_{plugin_slug}
367 + * fs_after_account_connection_{plugin_slug}
368 + * fs_account_property_edit_{plugin_slug}
369 + * fs_account_email_verified_{plugin_slug}
370 + * fs_account_page_load_before_departure_{plugin_slug}
371 + * fs_before_account_delete_{plugin_slug}
372 + * fs_after_account_delete_{plugin_slug}
373 + *
374 + * fs_sdk_version_update_{plugin_slug}
375 + * fs_plugin_version_update_{plugin_slug}
376 + *
377 + * fs_initiated_{plugin_slug}
378 + * fs_after_init_plugin_registered_{plugin_slug}
379 + * fs_after_init_plugin_anonymous_{plugin_slug}
380 + * fs_after_init_plugin_pending_activations_{plugin_slug}
381 + * fs_after_init_addon_registered_{plugin_slug}
382 + * fs_after_init_addon_anonymous_{plugin_slug}
383 + * fs_after_init_addon_pending_activations_{plugin_slug}
384 + *
385 + * fs_after_premium_version_activation_{plugin_slug}
386 + * fs_after_free_version_reactivation_{plugin_slug}
387 + *
388 + * fs_after_uninstall_{plugin_slug}
389 + * fs_before_admin_menu_init_{plugin_slug}
390 + */
391 +
392 + #endregion Hooks & Filters Collection --------------------------------------------------------------------
393 +
394 + if ( ! class_exists( 'Freemius' ) ) {
395 +
396 + if ( ! defined( 'WP_FS__SDK_VERSION' ) ) {
397 + define( 'WP_FS__SDK_VERSION', $this_sdk_version );
398 + }
399 +
400 + $plugins_or_theme_dir_path = fs_normalize_path( trailingslashit( $is_theme ?
401 + $themes_directory :
402 + WP_PLUGIN_DIR ) );
403 +
404 + if ( 0 === strpos( $file_path, $plugins_or_theme_dir_path ) ) {
405 + // No symlinks
406 + } else {
407 + /**
408 + * This logic finds the SDK symlink and set WP_FS__DIR to use it.
409 + *
410 + * @author Vova Feldman (@svovaf)
411 + * @since 1.2.2.5
412 + */
413 + $sdk_symlink = null;
414 +
415 + // Try to load SDK's symlink from cache.
416 + if ( isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
417 + is_object( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
418 + ! empty( $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink )
419 + ) {
420 + $sdk_symlink = $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink;
421 + if ( 0 === strpos( $sdk_symlink, $plugins_or_theme_dir_path ) ) {
422 + /**
423 + * Make the symlink path relative.
424 + *
425 + * @author Leo Fajardo (@leorw)
426 + */
427 + $sdk_symlink = substr( $sdk_symlink, strlen( $plugins_or_theme_dir_path ) );
428 +
429 + $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink = $sdk_symlink;
430 + update_option( 'fs_active_plugins', $fs_active_plugins );
431 + }
432 +
433 + $realpath = realpath( $plugins_or_theme_dir_path . $sdk_symlink );
434 + if ( ! is_string( $realpath ) || ! file_exists( $realpath ) ) {
435 + $sdk_symlink = null;
436 + }
437 + }
438 +
439 + if ( empty( $sdk_symlink ) ) // Has symlinks, therefore, we need to configure WP_FS__DIR based on the symlink.
440 + {
441 + $partial_path_right = basename( $file_path );
442 + $partial_path_left = dirname( $file_path );
443 + $realpath = realpath( $plugins_or_theme_dir_path . $partial_path_right );
444 +
445 + while ( '/' !== $partial_path_left &&
446 + ( false === $realpath || $file_path !== fs_normalize_path( $realpath ) )
447 + ) {
448 + $partial_path_right = trailingslashit( basename( $partial_path_left ) ) . $partial_path_right;
449 + $partial_path_left_prev = $partial_path_left;
450 + $partial_path_left = dirname( $partial_path_left_prev );
451 +
452 + /**
453 + * Avoid infinite loop if for example `$partial_path_left_prev` is `C:/`, in this case,
454 + * `dirname( 'C:/' )` will return `C:/`.
455 + *
456 + * @author Leo Fajardo (@leorw)
457 + */
458 + if ( $partial_path_left === $partial_path_left_prev ) {
459 + $partial_path_left = '';
460 + break;
461 + }
462 +
463 + $realpath = realpath( $plugins_or_theme_dir_path . $partial_path_right );
464 + }
465 +
466 + if ( ! empty( $partial_path_left ) && '/' !== $partial_path_left ) {
467 + $sdk_symlink = fs_normalize_path( dirname( $partial_path_right ) );
468 +
469 + // Cache value.
470 + if ( isset( $fs_active_plugins->plugins[ $this_sdk_relative_path ] ) &&
471 + is_object( $fs_active_plugins->plugins[ $this_sdk_relative_path ] )
472 + ) {
473 + $fs_active_plugins->plugins[ $this_sdk_relative_path ]->sdk_symlink = $sdk_symlink;
474 + update_option( 'fs_active_plugins', $fs_active_plugins );
475 + }
476 + }
477 + }
478 +
479 + if ( ! empty( $sdk_symlink ) ) {
480 + // Set SDK dir to the symlink path.
481 + define( 'WP_FS__DIR', $plugins_or_theme_dir_path . $sdk_symlink );
482 + }
483 + }
484 +
485 + // Load SDK files.
486 + require_once dirname( __FILE__ ) . '/require.php';
487 +
488 + /**
489 + * Quick shortcut to get Freemius for specified plugin.
490 + * Used by various templates.
491 + *
492 + * @param number $module_id
493 + *
494 + * @return Freemius
495 + */
496 + function freemius( $module_id ) {
497 + return Freemius::instance( $module_id );
498 + }
499 +
500 + /**
501 + * @param string $slug
502 + * @param number $plugin_id
503 + * @param string $public_key
504 + * @param bool $is_live Is live or test plugin.
505 + * @param bool $is_premium Hints freemius if running the premium plugin or not.
506 + *
507 + * @return Freemius
508 + *
509 + * @deprecated Please use fs_dynamic_init().
510 + */
511 + function fs_init( $slug, $plugin_id, $public_key, $is_live = true, $is_premium = true ) {
512 + $fs = Freemius::instance( $plugin_id, $slug, true );
513 + $fs->init( $plugin_id, $public_key, $is_live, $is_premium );
514 +
515 + return $fs;
516 + }
517 +
518 + /**
519 + * @param array <string,string|bool|array> $module Plugin or Theme details.
520 + *
521 + * @return Freemius
522 + * @throws Freemius_Exception
523 + */
524 + function fs_dynamic_init( $module ) {
525 + $fs = Freemius::instance( $module['id'], $module['slug'], true );
526 + $fs->dynamic_init( $module );
527 +
528 + return $fs;
529 + }
530 +
531 + function fs_dump_log() {
532 + FS_Logger::dump();
533 + }
534 + }