Skip to content

Plugin detection fails when __FILE__ and WP_PLUGIN_DIR values differ #205

Description

@prionkor

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions