PluginProbe ʕ •ᴥ•ʔ
Code Manager / 1.0.0
Code Manager v1.0.0
1.0.47 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.3 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.4 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
code-manager / freemius / start.php
code-manager / freemius Last commit date
assets 5 years ago includes 5 years ago languages 5 years ago templates 5 years ago LICENSE.txt 5 years ago config.php 5 years ago index.php 5 years ago require.php 5 years ago start.php 5 years ago
start.php
522 lines
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 }