1515 *
1616 * @var string
1717 */
18- $ this_sdk_version = '2.9.0.4 ' ;
18+ $ this_sdk_version = '2.9.0.5 ' ;
1919
2020 #region SDK Selection Logic --------------------------------------------------------------------
2121
3636 require_once dirname ( __FILE__ ) . '/includes/fs-essential-functions.php ' ;
3737 }
3838
39- /**
39+ /**
40+ * We updated the logic to support SDK loading from a subfolder of a theme as well as from a parent theme
41+ * If the SDK is found in the active theme, it sets the relative path accordingly.
42+ * If not, it checks the parent theme and sets the relative path if found there.
43+ * This allows the SDK to be loaded from composer dependencies or from a custom `vendor/freemius` folder.
44+ *
45+ * @author Daniele Alessandra (@DanieleAlessandra)
46+ * @since 2.9.0.5
47+ *
48+ *
4049 * This complex logic fixes symlink issues (e.g. with Vargant). The logic assumes
4150 * that if it's a file from an SDK running in a theme, the location of the SDK
4251 * is in the main theme's folder.
@@ -83,16 +92,32 @@ function_exists( 'wp_is_json_request' ) &&
8392 */
8493 $ themes_directory = get_theme_root ( get_stylesheet () );
8594 $ themes_directory_name = basename ( $ themes_directory );
86- $ theme_candidate_basename = basename ( dirname ( $ fs_root_path ) ) . '/ ' . basename ( $ fs_root_path );
8795
88- if ( $ file_path == fs_normalize_path ( realpath ( trailingslashit ( $ themes_directory ) . $ theme_candidate_basename . '/ ' . basename ( $ file_path ) ) )
89- ) {
90- $ this_sdk_relative_path = '../ ' . $ themes_directory_name . '/ ' . $ theme_candidate_basename ;
91- $ is_theme = true ;
92- } else {
93- $ this_sdk_relative_path = plugin_basename ( $ fs_root_path );
94- $ is_theme = false ;
95- }
96+ // This change ensures that the condition works even if the SDK is located in a subdirectory (e.g., vendor)
97+ $ theme_candidate_sdk_basename = str_replace ( $ themes_directory . '/ ' . get_stylesheet () . '/ ' , '' , $ fs_root_path );
98+
99+ // Check if the current file is part of the active theme.
100+ $ is_current_sdk_from_active_theme = $ file_path == $ themes_directory . '/ ' . get_stylesheet () . '/ ' . $ theme_candidate_sdk_basename . '/ ' . basename ( $ file_path );
101+ $ is_current_sdk_from_parent_theme = false ;
102+
103+ // Check if the current file is part of the parent theme.
104+ if ( ! $ is_current_sdk_from_active_theme ) {
105+ $ theme_candidate_sdk_basename = str_replace ( $ themes_directory . '/ ' . get_template () . '/ ' ,
106+ '' ,
107+ $ fs_root_path );
108+ $ is_current_sdk_from_parent_theme = $ file_path == $ themes_directory . '/ ' . get_template () . '/ ' . $ theme_candidate_sdk_basename . '/ ' . basename ( $ file_path );
109+ }
110+
111+ if ( $ is_current_sdk_from_active_theme ) {
112+ $ this_sdk_relative_path = '../ ' . $ themes_directory_name . '/ ' . get_stylesheet () . '/ ' . $ theme_candidate_sdk_basename ;
113+ $ is_theme = true ;
114+ } else if ( $ is_current_sdk_from_parent_theme ) {
115+ $ this_sdk_relative_path = '../ ' . $ themes_directory_name . '/ ' . get_template () . '/ ' . $ theme_candidate_sdk_basename ;
116+ $ is_theme = true ;
117+ } else {
118+ $ this_sdk_relative_path = plugin_basename ( $ fs_root_path );
119+ $ is_theme = false ;
120+ }
96121
97122 if ( ! isset ( $ fs_active_plugins ) ) {
98123 // Load all Freemius powered active plugins.
@@ -176,7 +201,8 @@ function_exists( 'wp_is_json_request' ) &&
176201 $ this_sdk_version != $ fs_active_plugins ->plugins [ $ this_sdk_relative_path ]->version
177202 ) {
178203 if ( $ is_theme ) {
179- $ plugin_path = basename ( dirname ( $ this_sdk_relative_path ) );
204+ // Saving relative path and not only directory name as it could be a subfolder
205+ $ plugin_path = $ this_sdk_relative_path ;
180206 } else {
181207 $ plugin_path = plugin_basename ( fs_find_direct_caller_plugin_file ( $ file_path ) );
182208 }
@@ -225,25 +251,43 @@ function_exists( 'wp_is_json_request' ) &&
225251
226252 $ is_newest_sdk_type_theme = ( isset ( $ fs_newest_sdk ->type ) && 'theme ' === $ fs_newest_sdk ->type );
227253
228- if ( ! $ is_newest_sdk_type_theme ) {
229- $ is_newest_sdk_plugin_active = is_plugin_active ( $ fs_newest_sdk ->plugin_path );
230- } else {
231- $ current_theme = wp_get_theme ();
232- $ is_newest_sdk_plugin_active = ( $ current_theme ->stylesheet === $ fs_newest_sdk ->plugin_path );
254+ /**
255+ * @var bool $is_newest_sdk_module_active
256+ * True if the plugin with the newest SDK is active.
257+ * True if the newest SDK is part of the current theme or current theme's parent.
258+ * False otherwise.
259+ */
260+ if ( ! $ is_newest_sdk_type_theme ) {
261+ $ is_newest_sdk_module_active = is_plugin_active ( $ fs_newest_sdk ->plugin_path );
262+ } else {
263+ $ current_theme = wp_get_theme ();
264+ // Detect if current theme is the one registered as newer SDK
265+ $ is_newest_sdk_module_active = (
266+ strpos (
267+ $ fs_newest_sdk ->plugin_path ,
268+ '../ ' . $ themes_directory_name . '/ ' . $ current_theme ->get_stylesheet () . '/ '
269+ ) === 0
270+ );
233271
234272 $ current_theme_parent = $ current_theme ->parent ();
235273
236274 /**
237275 * If the current theme is a child of the theme that has the newest SDK, this prevents a redirects loop
238276 * from happening by keeping the SDK info stored in the `fs_active_plugins` option.
239277 */
240- if ( ! $ is_newest_sdk_plugin_active && $ current_theme_parent instanceof WP_Theme ) {
241- $ is_newest_sdk_plugin_active = ( $ fs_newest_sdk ->plugin_path === $ current_theme_parent ->stylesheet );
278+ if ( ! $ is_newest_sdk_module_active && $ current_theme_parent instanceof WP_Theme ) {
279+ // Detect if current theme parent is the one registered as newer SDK
280+ $ is_newest_sdk_module_active = (
281+ strpos (
282+ $ fs_newest_sdk ->plugin_path ,
283+ '../ ' . $ themes_directory_name . '/ ' . $ current_theme_parent ->get_stylesheet () . '/ '
284+ ) === 0
285+ );
242286 }
243287 }
244288
245289 if ( $ is_current_sdk_newest &&
246- ! $ is_newest_sdk_plugin_active &&
290+ ! $ is_newest_sdk_module_active &&
247291 ! $ fs_active_plugins ->newest ->in_activation
248292 ) {
249293 // If current SDK is the newest and the plugin is NOT active, it means
@@ -262,14 +306,14 @@ function_exists( 'wp_is_json_request' ) &&
262306 . '/start.php ' );
263307 }
264308
265- $ is_newest_sdk_path_valid = ( $ is_newest_sdk_plugin_active || $ fs_active_plugins ->newest ->in_activation ) && file_exists ( $ sdk_starter_path );
309+ $ is_newest_sdk_path_valid = ( $ is_newest_sdk_module_active || $ fs_active_plugins ->newest ->in_activation ) && file_exists ( $ sdk_starter_path );
266310
267311 if ( ! $ is_newest_sdk_path_valid && ! $ is_current_sdk_newest ) {
268312 // Plugin with newest SDK is no longer active, or SDK was moved to a different location.
269313 unset( $ fs_active_plugins ->plugins [ $ fs_active_plugins ->newest ->sdk_path ] );
270314 }
271315
272- if ( ! ( $ is_newest_sdk_plugin_active || $ fs_active_plugins ->newest ->in_activation ) ||
316+ if ( ! ( $ is_newest_sdk_module_active || $ fs_active_plugins ->newest ->in_activation ) ||
273317 ! $ is_newest_sdk_path_valid ||
274318 // Is newest SDK downgraded.
275319 ( $ this_sdk_relative_path == $ fs_active_plugins ->newest ->sdk_path &&
@@ -284,7 +328,7 @@ function_exists( 'wp_is_json_request' ) &&
284328 // Find the active plugin with the newest SDK version and update the newest reference.
285329 fs_fallback_to_newest_active_sdk ();
286330 } else {
287- if ( $ is_newest_sdk_plugin_active &&
331+ if ( $ is_newest_sdk_module_active &&
288332 $ this_sdk_relative_path == $ fs_active_plugins ->newest ->sdk_path &&
289333 ( $ fs_active_plugins ->newest ->in_activation ||
290334 ( class_exists ( 'Freemius ' ) && ( ! defined ( 'WP_FS__SDK_VERSION ' ) || version_compare ( WP_FS__SDK_VERSION , $ this_sdk_version , '< ' ) ) )
0 commit comments