invis.net

Symlinking breaks freemius library

Having multiple sites, I intended to create a shared mu-plugins directory in /usr/local, and then symlink it to every single site, I host. Also setting up WPMU_PLUGIN_DIR and WPMU_PLUGIN_URL so the URLs are correctly generated.

This will make the mostly work. However some things will fail, as the code will generate rather odd URLs, like https://example.com/wp-content/themes/usr/local/share/wordpress/mu-plugins/wp-fail2ban/vendor/freemius/wordpress-sdk/assets/css/admin/common.css/?ver=5.6.1.

Yes, I tried essentially the same configuration when I first created my development environment for Freemius. After a lot of digging I discovered the root cause is a really stupid decision by the PHP team to have __FILE__ resolve symlinks.

See this bug report for the gory details.

That’s the bad news. The good news is that PHP have moved the src repo to GitHub so this finally stands a chance of getting fixed. I wouldn’t hold your breath though - they really don’t want to admit they made a mistake.

Well, I seem to be able to circumvent that issue with the __FILE__ constant just by setting two things in the WordPress config.php file:

  • WPMU_PLUGIN_DIR to /usr/local/share/wordpress/mu-plugins/;
  • and WPMU_PLUGIN_URL to `/wp-content/mu-plugins.

Which would solve the issue for the files that are part of the plugin code itself. Which in turn simply use __FILE__ to register the CSS and other assets.

However, within the vendor/freemius/wordpress-sdk directory, the .php files seem to have a very elaborate path-lookup…

There are two parts to this: symlinking and the WP constants, and the Freemius SDK.

If you set WPMU_PLUGIN_xxx you don’t need a symlink. If you symlink /mu-plugins/ to somewhere in /usr/local/ things will break due to the problem with __FILE__, hence WP creating the constants.

The Freemius SDK may be in use by multiple plugins which in turn may be using different versions of the SDK, so it has code to ensure that the main Freemius instance is using the newest version. That’s why the path lookup code is so nasty.

However, with a little effort it’s quite easy to work around the problem.

First, in your shared mu-plugins directory:

git clone https://github.com/Freemius/wordpress-sdk.git

(For bonus points, do a shallow clone once you’ve decided which branch to follow; develop is probably best).

Then drop this gist into your shared mu-plugins directory.

As long as you keep the repo current everything should work fine.