GithubHelp home page GithubHelp logo

roots / bedrock-autoloader Goto Github PK

View Code? Open in Web Editor NEW
38.0 9.0 16.0 33 KB

Bedrock Autoloader enables standard plugins to be required just like must-use plugins

Home Page: https://roots.io/docs/bedrock/master/mu-plugin-autoloader/

License: MIT License

PHP 100.00%
bedrock wordpress wordpress-mu-plugins

bedrock-autoloader's People

Contributors

aaemnnosttv avatar alexsomeoddpilot avatar austinpray avatar chrisnx avatar foxaii avatar itsme-francesco avatar log1x avatar markjaquith avatar qwp6t avatar retlehs avatar slackday avatar starise avatar swalkinshaw avatar tangrufus avatar vinkla avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bedrock-autoloader's Issues

Changes global availability of variables declared within autoloaded mu-plugins

Description

Variables declared within mu-plugins loaded via the autoloader are not available globally. Technically, this behavior does not match the behavior of WordPress core. WordPress core-loaded mu-plugins can declare variables, and those variables are available globally.

Whether this is right or not is up for interpretation, and maybe this is a wontfix. But here's how to replicate:

Steps to reproduce

  1. Create a Bedrock install
  2. Add an mu-plugin by creating test-plugin.php directly within mu-plugins. This means WordPress core will load it. Like this:
<?php
/**
 * Plugin Name:  Global Test Plugin
 * Version:      1.0.0
 */

$foo = 'bar';
  1. Within a default theme's functions.php, add the following:
global $foo;
var_dump($foo);
die();
  1. Visit site. See 'bar' is dumped.
  2. Move test-plugin.php into a directory within the mu-plugins directory, like test-plugin/test-plugin.php. This triggers the Bedrock autoloader.
  3. Visit site. See $foo is now null.

Expected behavior: $foo is still available globally

Actual behavior: Is is not

Reproduces how often: 100%

Versions

1.0.0

Additional information

I ran into this with WP Rocket on Kinsta's hosting, because WP Rocket has a check for Kinsta's $kinsta_cache variable declared within their mu-plugin. Followed the instructions here..

You could honestly argue that WP Rocket just shouldn't be doing this this way, but it is technically a deviation from core behavior.

Bug: Autoloaded plugins not reflected in `wp plugin list`

Terms

Description

What's wrong?

wp plugin list doesn't show autoloaded mu plugins via this autoloader.

What have you tried?

Nothing additional at this time.

What insights have you gained?/Possible solutions

I notice there's code to show these plugins in the WordPress admin. It's possible the same thing is necessary for WP-CLI.

Temporary workarounds

None

Steps To Reproduce

  1. Create an mu-plugin within a subdirectory on a Bedrock site
  2. See mu-plugin's behavior, if applicable, reflected on site.
  3. See mu-plugin in the list of plugins in the WP admin
  4. Run wp plugin list. See plugin is not listed.

Expected Behavior

Autoloaded mu-plugin would be listed.

Actual Behavior

Autoloaded mu-plugin is not listed.

Relevant Log Output

No response

Versions

1.0.4. Laravel Homestead on Windows, also Kinsta hosting.

Get `show_advanced_plugins` add_filter call out of constructor

Side-effects in constructor are bad, also this hopelessly couples this class's logic to a real wp install

add_filter('show_advanced_plugins', [$this, 'showInAdmin'], 0, 2);

/**
* Filter show_advanced_plugins to display the autoloaded plugins.
* @param $show bool Whether to show the advanced plugins for the specified plugin type.
* @param $type string The plugin type, i.e., `mustuse` or `dropins`
* @return bool We return `false` to prevent WordPress from overriding our work
* {@internal We add the plugin details ourselves, so we return false to disable the filter.}
*/
public function showInAdmin($show, $type)
{
$screen = get_current_screen();
$current = is_multisite() ? 'plugins-network' : 'plugins';
if ($screen->base !== $current || $type !== 'mustuse' || !current_user_can('activate_plugins')) {
return $show;
}
$this->updateCache();
$this->autoPlugins = array_map(function ($auto_plugin) {
$auto_plugin['Name'] .= ' *';
return $auto_plugin;
}, $this->autoPlugins);
$GLOBALS['plugins']['mustuse'] = array_unique(array_merge($this->autoPlugins, $this->muPlugins), SORT_REGULAR);
return false;
}

Unit tests

  1. decouple main logic from the actual wordpress functions
  2. validate logic

Autoloader wont load mu-plugins if plugins directory is a symlink

Not sure if I should put this on roots/bedrock or here, but:

Description

The autoloader doesnt load mu-plugins if plugins directory is a symlink. This is due to opendir failing in get_plugins().

Steps to reproduce

  1. Symlink plugins directory to anywhere
  2. Autoloader fails

Expected behavior: it to work
Actual behavior: opendir fails in the get_plugins function

Reproduces how often: Always if plugins dir is symlinked

Versions

Latest Trellis & Bedrock setup

Additional information

In my Trellis setup I set project_shared_childeren to include the plugins directory. I use this setup for satispress, where I want plugins and themes outside my git, but some plugins installed as mu-plugin (like satispress itself).

Bug: Issue with `plugin_dir_url()` in mu-plugins installed from local path

Terms

Description

When Composer installs mu-plugins from a local directory using symlinks, the plugin_dir_url( __FILE__ ) function returns an incorrect URL. This issue only occurs in mu-plugins and not in regular plugins. Instead of returning a URL like https://example.com/app/mu-plugins/my-plugin/, it returns https://example.com/app/plugins/var/www/domain/packages/plugins/my-plugin/.

Bedrock composer.json:

...
  "repositories": [
    ...
    {
      "type": "path",
      "url": "packages/plugins/*"
    },
    {
      "type": "path",
      "url": "packages/themes/*"
    },
    ...
  ],
...

Plugin composer.json

{
  "name": "my/plugin",
  "type": "wordpress-muplugin",
  "extra": {
    "installer-name": "my-plugin"
  }
}

Steps To Reproduce

  1. Install a mu-plugin in from a local directory using Composer
  2. Use the plugin_dir_url() function in the plugin file
  3. Notice that the returned URL is incorrect

Expected Behavior

The plugin_dir_url() function should return the correct URL for mu-plugins installed via Composer symlink, just as it does for regular plugins.

Actual Behavior

The function returns an incorrect URL for mu-plugins installed via Composer symlink.

Relevant Log Output

No response

Versions

1.21.1

Bug: Autoloader fails is there is no plugins folder

Terms

Description

What's wrong?

If there is no plugins folder then the autoloader does not work to autoload the mu-plugins. This is an issue as we make sites using bedrock for clients, we put every necessary plugin for the site to function as a mu-plugin via composer/bedrock, then when we deploy we exclude the plugins folder from deploy. This provides us 2 benefits, we can put dev plugins in plugins to help for dev, and clients can add/update their own plugins (or 3rd parties like seo companies) and they do not get effected by new deploys. Because of this initial deploys do not have a plugins folder. This does not appear to be a WordPress issue as the built in functions do not seam to throw any errors, and work as you would expect.

What have you tried?

Creating an empty plugins folder fixes it. Removing it again brings back the issue.

What insights have you gained?

Possible solutions

Temporary workarounds

Create an empty plugins folder.

Steps To Reproduce

  1. Have folders in the mu-plugins folder that get autoloaded
  2. Delete the plugins folder
  3. mu-plugins will no longer load

Expected Behavior

Autoloader should load the mu-plugins regardless of the plugins folder, as it does not seam relevant.

Actual Behavior

mu-plugins do not get loaded if there is no plugins folder

Relevant Log Output

No response

Versions

1.0.4

Question: Why filter `show_advanced_plugins` only when `is_admin`

if (is_admin()) {
add_filter('show_advanced_plugins', [$this, 'showInAdmin'], 0, 2);
}

The is_admin check was introduced since the beginning.

Question: Why the is_admin check?
In other words, in what case show_advanced_plugins is triggered in non-admin context?

countPlugins returning wrong number

Description

Hello,

The method \Roots\Bedrock\Autoloader::countPlugins is returning a wrong number of mu-plugins if the mu-plugin isn't one.
Because the way of WordPress is counting mu-plugin is not the same as yours, the number can be wrong in the case of the folder on mu-plugins doesn't contains a php file with WordPress headers.

Steps to reproduce

  1. Add humanmade/mercator dependency
  2. Follow the installation process https://github.com/humanmade/Mercator#installation
  3. Load WordPres 2 times
  4. The updateCache method is called on every page

Expected behavior:
That only the real mu-plugins loaded by WordPress are effectively counted with get_plugins function.

Actual behavior:
The glob only counts the folders.

Reproduces how often:
100%

Versions

1.0.1, but the code haven't changed since.

Maybe strip away the mu-plugins without header to have the right count ?

Call to a member function `get_extra_permastruct()`

Description

Contact Form 7 can causing Fatal error: Uncaught Error: Call to a member function get_extra_permastruct() on null in /path/to/wp-includes/link-template.php on line 274 if installed as mu-plugins on very first time the site run after being installed.

Steps to reproduce

  1. Install brand new bedrock site
  2. Add wpackagist-plugin/contact-form-7 line in extra.installer-paths.web/app/mu-plugins/{$name}/ of your composer.json file. Like this:
{
"extra": {
  "installer-paths": {
    "public/app/mu-plugins/{$name}/": [
      "wpackagist-plugin/contact-form-7",
      "type:wordpress-muplugin"
    ],
    "public/app/plugins/{$name}/": ["type:wordpress-plugin"],
    "public/app/themes/{$name}/": ["type:wordpress-theme"]
  },
  "wordpress-install-dir": "public/wp"
}
}
  1. Install Contact Form 7 using composer require wpackagist-plugin/contact-form-7 command
  2. Setup database and update your .env file
  3. Run wp core install ...
  4. Visit the website url from browser or try to run another wp-cli commands.

Expected behavior: This should not happened

Actual behavior: As described above

Reproduces how often: The issue only happened on the very first time after installing WordPress core, in my case using wp core install command. It could simply reload the page or re-run the same wpcli command and it's just completely gone.

Versions

Any version of autoloader. Since this autoloader still included on bedrock repository, to be exact. And it's happens anywhere. I meant, my local is running Windows & WSL (ubuntu 18.04), also it happened on CI (github action with ubuntu-latest image) and Heroku. See feryardiant/wpdev#39

msedge_LZyxKMZ66E

Additional information

I'm not sure if the issue was solely because of this autoloader, it might be because of latest update of contact-form-7 plugin as well.

Apology for my poor english, I'm doing my best ๐Ÿ˜…
Sincerely ๐Ÿ˜ฌ

Plugin activation hooks fire too early in the WordPress loading sequence

Description

Certain plugins loaded through Bedrock Autoloader will cause fatal errors, because they use pluggable functions (functions from pluggable.php) in their activation hook. Plugin activation hooks are fired by Bedrock Autoloader too early in the WordPress loading sequence โ€” before pluggable.php has been included.

Jetpack is one of the affected plugins.

Steps to reproduce

  1. Download this example plugin: https://gist.github.com/markjaquith/744faad95d66d5bd6c7fd6fadaad11ba
  2. Install it as mu-plugins/some-directory/plugin.php (the subdirectory is required, so that Bedrock Autoloader loads it, not WordPress).
  3. Try to load the site.

Expected behavior: Plugin activation hooks are fired after pluggable functions are available.

Actual behavior: They fire too early.

Reproduces how often: 100%

Versions

Bedrock Autoloader 1.0.3

Additional information

Any additional information, configuration or data that might be necessary to reproduce the issue.

Feature Request: Filter to allowed select plugins not to be loaded

Terms

Summary

In select managed hosting environments, some custom code may be dropped into the applications mu-plugins directory. I would be great to have a filter before the files are required.

Motivation

Why are we doing this?

I have seen vendor specific code for hosts like Pagely, WPEngine, etc add directories into the mu-plugins dir.

What use cases does it support?

Not to autoload vendor code automatically, that may already be loaded via other methods.

What is the expected outcome?

To limit the amount of plugins loaded (twice).

Potential conflicts / foreseeable issues

Uknown.

Additional Context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.