orangelabweb / imagemagick-engine

WordPress plugin to replace image engine with ImageMagick.
https://wordpress.org/plugins/imagemagick-engine/
9 stars 9 forks source link

Fatal Error From WP-CLI #46

Closed slarti-b closed 8 months ago

slarti-b commented 8 months ago

We use the wp-cli to automate some steps around installation and upgrade. Sometimes, we get a fatal error from the this plugin when doing (essentially unrelated) wp-cli commands. We have a network isntallation, and it can be with just some of the sites in the network even though we have the plugin network activated. The actual site works, when called via a browser, but all wp-cli commands fail.

Example stack trace:

PHP Fatal error:  Uncaught TypeError: array_key_exists(): Argument #2 ($array) must be of type array, null given in /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php:184
Stack trace:
#0 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(213): ime_setup_options()
#1 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(115): ime_get_option()
#2 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(91): ime_active()
#3 /path/to/site/wp-includes/class-wp-hook.php(324): ime_init_early()
#4 /path/to/site/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#5 /path/to/site/wp-includes/plugin.php(517): WP_Hook->do_action()
#6 /path/to/site/wp-settings.php(506): do_action()
#7 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1374): require('...')
#8 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1293): WP_CLI\Runner->load_wordpress()
#9 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#10 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process()
#11 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()
#12 phar:///opt/wp-cli/wp-cli.phar/php/boot-phar.php(20): include('...')
#13 /opt/wp-cli/wp-cli.phar(4): include('...')
#14 {main}
  thrown in /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php on line 184
Fatal error: Uncaught TypeError: array_key_exists(): Argument #2 ($array) must be of type array, null given in /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php:184
Stack trace:
#0 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(213): ime_setup_options()
#1 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(115): ime_get_option()
#2 /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php(91): ime_active()
#3 /path/to/site/wp-includes/class-wp-hook.php(324): ime_init_early()
#4 /path/to/site/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#5 /path/to/site/wp-includes/plugin.php(517): WP_Hook->do_action()
#6 /path/to/site/wp-settings.php(506): do_action()
#7 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1374): require('...')
#8 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1293): WP_CLI\Runner->load_wordpress()
#9 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#10 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process()
#11 phar:///opt/wp-cli/wp-cli.phar/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()
#12 phar:///opt/wp-cli/wp-cli.phar/php/boot-phar.php(20): include('...')
#13 /opt/wp-cli/wp-cli.phar(4): include('...')
#14 {main}
  thrown in /path/to/site/wp-content/plugins/imagemagick-engine/imagemagick-engine.php on line 184

I added some debugging and it seems both $ime_options (both globally and after get_option call) and also $ime_options_default are null when it fails. I do not understand how this can happen but it does. I have failed to work out what actually causes it. Deactiviating the plugin solves the problem, re-activate it and it comes back. I have checked and there are no references to ime_options_default in any code outside this plugin.

The network sites that didn't fail had ime_options defined in options, so I'm guessing the problem is the $ime_options_default getting null somehow. I do not understand how. Could $ime_options_default be declared as constant? Or replaced with a private function that returns a hard-coded array instead of being a variable?

This was on WP 6.4.3 (although seen it occasionally earlier on slightly earlier versions). Using PHP 8.1.27 on CentOS 7.

chesio commented 8 months ago

It seems to be the same issue as described here: https://github.com/wp-cli/wp-cli/issues/2200

TLDR: Global variables in a plugin must be explicitly defined as such.

slarti-b commented 8 months ago

It seems to be the same issue as described here: wp-cli/wp-cli#2200

TLDR: Global variables in a plugin must be explicitly defined as such.

Ah! OK. But the fix needs to be in this plugin to explicitly declare it global though? As I read that thread, wp-cli can't help...

slarti-b commented 8 months ago

Can confirm that adding global $ime_options_default; before the declaration of $ime_options_default fixes it for me

chesio commented 8 months ago

But the fix needs to be in this plugin to explicitly declare it global though? As I read that thread, wp-cli can't help...

Exactly. My suggestion to @rickardw would be to avoid global variables at all.

Not sure if this is feasible for your use case, but you can --skip-plugins when invoking WP-CLI - see WP-CLI global parameters.

slarti-b commented 8 months ago

Fully agree with avoiding global variables. However, I did submit a PR that solves this problem at least since it was the minimal change needed.

Yeah, we could run with --skip-plugins sometimes - but sometimes we call CLI commands which are made available by plugins, so not always... That's how I get round it and de-activate the plugin though.