I found an issue in the framework's plugin/theme detection logic that affects Azure App Service, and potentially any environment where the same files are accessible through multiple filesystem paths (bind mounts, symlinks, etc.).
The problem is in classes/setup.class.php, specifically in constants():
$dirname = wp_normalize_path( dirname( dirname( self::$file ) ) );
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );
$located_plugin = preg_match(
'#' . self::sanitize_dirname( $plugin_dir ) . '#',
self::sanitize_dirname( $dirname )
);
$directory = $located_plugin ? $plugin_dir : $theme_dir;
$directory_uri = $located_plugin ? WP_PLUGIN_URL : get_parent_theme_file_uri();
$foldername = str_replace( $directory, '', $dirname );
self::$url = $directory_uri . $foldername;
The framework assumes that self::$file (and therefore $dirname) will always share the same filesystem prefix as WP_PLUGIN_DIR.
On Azure App Service this assumption is not always true.
Example values:
self::$file:
/home/site/wwwroot/wp-content/plugins/interactive-geo-maps/vendor/saltus/framework/lib/codestar-framework/classes/setup.class.php
$dirname:
/home/site/wwwroot/wp-content/plugins/interactive-geo-maps/vendor/saltus/framework/lib/codestar-framework
WP_PLUGIN_DIR:
/var/www/html/wp-content/plugins
Because the prefixes differ:
preg_match(...) => false
The framework incorrectly concludes that it is running from a theme:
$directory = $theme_dir;
$directory_uri = get_parent_theme_file_uri();
which ultimately produces invalid asset URLs such as:
https://example.com/wp-content/themes/my-theme/home/site/wwwroot/wp-content/plugins/...
instead of the expected:
https://example.com/wp-content/plugins/interactive-geo-maps/vendor/saltus/framework/lib/codestar-framework/...
Root Cause
The framework determines whether it is inside a plugin by comparing filesystem path prefixes. This is not reliable on environments where:
- bind mounts are used
- symlinks are used
the application is accessible through multiple filesystem paths __FILE__ and WP_PLUGIN_DIR legitimately resolve to different absolute paths
The framework already contains a Bitnami-specific path normalization:
$plugin_dir = str_replace('/opt/bitnami', '/bitnami', $plugin_dir);
which suggests this class of issue is already known.
Suggested Improvement
Instead of relying on filesystem prefix comparison, derive the plugin URL from the plugin's root file using WordPress APIs (plugin_dir_url(), plugins_url(), etc.), or normalize filesystem paths before comparing them. One suggestion is to let developers pass this information from upstream instead of trying to determine myriad of possibilities it in the framework.
At the very least, the plugin/theme detection should not assume that self::$file and WP_PLUGIN_DIR must share the same absolute filesystem prefix.
Environment
Azure App Service (Linux)
WordPress
PHP 8.2
Codestar Framework bundled inside a plugin (map geo)
I found an issue in the framework's plugin/theme detection logic that affects Azure App Service, and potentially any environment where the same files are accessible through multiple filesystem paths (bind mounts, symlinks, etc.).
The problem is in
classes/setup.class.php, specifically inconstants():The framework assumes that
self::$file(and therefore$dirname) will always share the same filesystem prefix asWP_PLUGIN_DIR.On Azure App Service this assumption is not always true.
Example values:
Because the prefixes differ:
preg_match(...) => falseThe framework incorrectly concludes that it is running from a theme:
which ultimately produces invalid asset URLs such as:
https://example.com/wp-content/themes/my-theme/home/site/wwwroot/wp-content/plugins/...instead of the expected:
https://example.com/wp-content/plugins/interactive-geo-maps/vendor/saltus/framework/lib/codestar-framework/...Root Cause
The framework determines whether it is inside a plugin by comparing filesystem path prefixes. This is not reliable on environments where:
the application is accessible through multiple filesystem paths
__FILE__andWP_PLUGIN_DIRlegitimately resolve to different absolute pathsThe framework already contains a Bitnami-specific path normalization:
$plugin_dir = str_replace('/opt/bitnami', '/bitnami', $plugin_dir);which suggests this class of issue is already known.
Suggested Improvement
Instead of relying on filesystem prefix comparison, derive the plugin URL from the plugin's root file using WordPress APIs (plugin_dir_url(), plugins_url(), etc.), or normalize filesystem paths before comparing them. One suggestion is to let developers pass this information from upstream instead of trying to determine myriad of possibilities it in the framework.
At the very least, the plugin/theme detection should not assume that
self::$fileandWP_PLUGIN_DIRmust share the same absolute filesystem prefix.Environment
Azure App Service (Linux)
WordPress
PHP 8.2
Codestar Framework bundled inside a plugin (map geo)