Skip to content

Commit

Permalink
[composer] [autoload] Added start.php to autoload.files in composer.j…
Browse files Browse the repository at this point in the history
…son supporting both plugins and themes (#756)

* [composer] [autoload] Added start.php to autoload.files in composer.json

* [composer] [vendor] [themes] Changed logic related to theme to make it work also when SDK is stored in a subfolder (e.g. vendor folder)

* [themes] [child theme] [load priority] Correctly determine SDK file to load, even with themes and child themes

* Code style, renamed variables, removed unused $is_theme check.

* Code Style (wordpress)

* Code styling (spaces instead of tabs)

* Revert indent spacing

* Fix strpos index and use get_stylesheet() instead of private property stylesheet

---------

Co-authored-by: Daniele Alessandra <[email protected]>
  • Loading branch information
DanieleAlessandra and DanieleFreemius authored Nov 28, 2024
1 parent 2ec8717 commit 84bbdb1
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 23 deletions.
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"require": {
"php": ">=5.6"
},
"autoload": {
"files": [
"start.php"
]
},
"require-dev": {
"wp-coding-standards/wpcs": "^2.3",
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
Expand Down
90 changes: 67 additions & 23 deletions start.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @var string
*/
$this_sdk_version = '2.9.0.4';
$this_sdk_version = '2.9.0.5';

#region SDK Selection Logic --------------------------------------------------------------------

Expand All @@ -36,7 +36,16 @@
require_once dirname( __FILE__ ) . '/includes/fs-essential-functions.php';
}

/**
/**
* We updated the logic to support SDK loading from a subfolder of a theme as well as from a parent theme
* If the SDK is found in the active theme, it sets the relative path accordingly.
* If not, it checks the parent theme and sets the relative path if found there.
* This allows the SDK to be loaded from composer dependencies or from a custom `vendor/freemius` folder.
*
* @author Daniele Alessandra (@DanieleAlessandra)
* @since 2.9.0.5
*
*
* This complex logic fixes symlink issues (e.g. with Vargant). The logic assumes
* that if it's a file from an SDK running in a theme, the location of the SDK
* is in the main theme's folder.
Expand Down Expand Up @@ -83,16 +92,32 @@ function_exists( 'wp_is_json_request' ) &&
*/
$themes_directory = get_theme_root( get_stylesheet() );
$themes_directory_name = basename( $themes_directory );
$theme_candidate_basename = basename( dirname( $fs_root_path ) ) . '/' . basename( $fs_root_path );

if ( $file_path == fs_normalize_path( realpath( trailingslashit( $themes_directory ) . $theme_candidate_basename . '/' . basename( $file_path ) ) )
) {
$this_sdk_relative_path = '../' . $themes_directory_name . '/' . $theme_candidate_basename;
$is_theme = true;
} else {
$this_sdk_relative_path = plugin_basename( $fs_root_path );
$is_theme = false;
}
// This change ensures that the condition works even if the SDK is located in a subdirectory (e.g., vendor)
$theme_candidate_sdk_basename = str_replace( $themes_directory . '/' . get_stylesheet() . '/', '', $fs_root_path );

// Check if the current file is part of the active theme.
$is_current_sdk_from_active_theme = $file_path == $themes_directory . '/' . get_stylesheet() . '/' . $theme_candidate_sdk_basename . '/' . basename( $file_path );
$is_current_sdk_from_parent_theme = false;

// Check if the current file is part of the parent theme.
if ( ! $is_current_sdk_from_active_theme ) {
$theme_candidate_sdk_basename = str_replace( $themes_directory . '/' . get_template() . '/',
'',
$fs_root_path );
$is_current_sdk_from_parent_theme = $file_path == $themes_directory . '/' . get_template() . '/' . $theme_candidate_sdk_basename . '/' . basename( $file_path );
}

if ( $is_current_sdk_from_active_theme ) {
$this_sdk_relative_path = '../' . $themes_directory_name . '/' . get_stylesheet() . '/' . $theme_candidate_sdk_basename;
$is_theme = true;
} else if ( $is_current_sdk_from_parent_theme ) {
$this_sdk_relative_path = '../' . $themes_directory_name . '/' . get_template() . '/' . $theme_candidate_sdk_basename;
$is_theme = true;
} else {
$this_sdk_relative_path = plugin_basename( $fs_root_path );
$is_theme = false;
}

if ( ! isset( $fs_active_plugins ) ) {
// Load all Freemius powered active plugins.
Expand Down Expand Up @@ -176,7 +201,8 @@ function_exists( 'wp_is_json_request' ) &&
$this_sdk_version != $fs_active_plugins->plugins[ $this_sdk_relative_path ]->version
) {
if ( $is_theme ) {
$plugin_path = basename( dirname( $this_sdk_relative_path ) );
// Saving relative path and not only directory name as it could be a subfolder
$plugin_path = $this_sdk_relative_path;
} else {
$plugin_path = plugin_basename( fs_find_direct_caller_plugin_file( $file_path ) );
}
Expand Down Expand Up @@ -225,25 +251,43 @@ function_exists( 'wp_is_json_request' ) &&

$is_newest_sdk_type_theme = ( isset( $fs_newest_sdk->type ) && 'theme' === $fs_newest_sdk->type );

if ( ! $is_newest_sdk_type_theme ) {
$is_newest_sdk_plugin_active = is_plugin_active( $fs_newest_sdk->plugin_path );
} else {
$current_theme = wp_get_theme();
$is_newest_sdk_plugin_active = ( $current_theme->stylesheet === $fs_newest_sdk->plugin_path );
/**
* @var bool $is_newest_sdk_module_active
* True if the plugin with the newest SDK is active.
* True if the newest SDK is part of the current theme or current theme's parent.
* False otherwise.
*/
if ( ! $is_newest_sdk_type_theme ) {
$is_newest_sdk_module_active = is_plugin_active( $fs_newest_sdk->plugin_path );
} else {
$current_theme = wp_get_theme();
// Detect if current theme is the one registered as newer SDK
$is_newest_sdk_module_active = (
strpos(
$fs_newest_sdk->plugin_path,
'../' . $themes_directory_name . '/' . $current_theme->get_stylesheet() . '/'
) === 0
);

$current_theme_parent = $current_theme->parent();

/**
* If the current theme is a child of the theme that has the newest SDK, this prevents a redirects loop
* from happening by keeping the SDK info stored in the `fs_active_plugins` option.
*/
if ( ! $is_newest_sdk_plugin_active && $current_theme_parent instanceof WP_Theme ) {
$is_newest_sdk_plugin_active = ( $fs_newest_sdk->plugin_path === $current_theme_parent->stylesheet );
if ( ! $is_newest_sdk_module_active && $current_theme_parent instanceof WP_Theme ) {
// Detect if current theme parent is the one registered as newer SDK
$is_newest_sdk_module_active = (
strpos(
$fs_newest_sdk->plugin_path,
'../' . $themes_directory_name . '/' . $current_theme_parent->get_stylesheet() . '/'
) === 0
);
}
}

if ( $is_current_sdk_newest &&
! $is_newest_sdk_plugin_active &&
! $is_newest_sdk_module_active &&
! $fs_active_plugins->newest->in_activation
) {
// If current SDK is the newest and the plugin is NOT active, it means
Expand All @@ -262,14 +306,14 @@ function_exists( 'wp_is_json_request' ) &&
. '/start.php' );
}

$is_newest_sdk_path_valid = ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) && file_exists( $sdk_starter_path );
$is_newest_sdk_path_valid = ( $is_newest_sdk_module_active || $fs_active_plugins->newest->in_activation ) && file_exists( $sdk_starter_path );

if ( ! $is_newest_sdk_path_valid && ! $is_current_sdk_newest ) {
// Plugin with newest SDK is no longer active, or SDK was moved to a different location.
unset( $fs_active_plugins->plugins[ $fs_active_plugins->newest->sdk_path ] );
}

if ( ! ( $is_newest_sdk_plugin_active || $fs_active_plugins->newest->in_activation ) ||
if ( ! ( $is_newest_sdk_module_active || $fs_active_plugins->newest->in_activation ) ||
! $is_newest_sdk_path_valid ||
// Is newest SDK downgraded.
( $this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
Expand All @@ -284,7 +328,7 @@ function_exists( 'wp_is_json_request' ) &&
// Find the active plugin with the newest SDK version and update the newest reference.
fs_fallback_to_newest_active_sdk();
} else {
if ( $is_newest_sdk_plugin_active &&
if ( $is_newest_sdk_module_active &&
$this_sdk_relative_path == $fs_active_plugins->newest->sdk_path &&
( $fs_active_plugins->newest->in_activation ||
( class_exists( 'Freemius' ) && ( ! defined( 'WP_FS__SDK_VERSION' ) || version_compare( WP_FS__SDK_VERSION, $this_sdk_version, '<' ) ) )
Expand Down

0 comments on commit 84bbdb1

Please sign in to comment.