[SOLVED] Acorn v3 -> v4 Upgrade | PSR Logger Issue -> Bedrock/WPML | Fatal error: Declaration of Monolog\Logger::emergency

Edit

  • This issue has been solved, the title has been updated to make this post easier to find for others.
  • Looking for a solution?
    • @alexmzk Provided a workaround below
    • @RistoKaalma pinpointed the issue in the WPML plugin and was marked as the solution for this thread

Original Post

As recommended by Log1x on my GitHub issue, I will try discourse to find a solution.

Summary
I have a project that’s kept up to dat using the latest bedrock, and sage theme. When I try to update acorn to v4.x only when my application is set to the development environment I am getting a fatal error caused by Monolog, a dependency to Illuminate Log.

Steps that got me to the error

  • Update the composer.json file to: "roots/acorn": "^4.0"
  • Run composer update "roots/acorn" -W

The Error

Fatal error: Declaration of Monolog\Logger::emergency(Stringable|string $message, array $context = []): void must be compatible with Psr\Log\LoggerInterface::emergency($message, array $context = []) in /Users/yasser/Artcore/artcore_bedrock_sofico_website/vendor/monolog/monolog/src/Monolog/Logger.php on line 681

Stacktrace

Fatal error: Uncaught Error: Class "Monolog\Logger" not found in 
/Users/yasser/project/my_project/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php:60 
Stack trace: 
- 0 /Users/yasser/project/my_project/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php(38): Monolog\Handler\AbstractHandler->setLevel(Object(Monolog\Level)) 
- 1 /Users/yasser/project/my_project/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php(49): Monolog\Handler\AbstractHandler->__construct(Object(Monolog\Level), true) 
- 2 /Users/yasser/project/my_project/vendor/illuminate/log/LogManager.php(189): Monolog\Handler\StreamHandler->__construct('/Users/yasser/M...', Object(Monolog\Level)) 
- 3 /Users/yasser/project/my_project/vendor/illuminate/log/LogManager.php(141): Illuminate\Log\LogManager->createEmergencyLogger() 
- 4 /Users/yasser/project/my_project/vendor/illuminate/log/LogManager.php(124): Illuminate\Log\LogManager->get('stack') 
- 5 /Users/yasser/project/my_project/vendor/illuminate/log/LogManager.php(681): Illuminate\Log\LogManager->driver() 
- 6 /Users/yasser/project/my_project/vendor/roots/acorn/src/Illuminate/Foundation/Exceptions/Handler.php(317): Illuminate\Log\LogManager->error('Declaration of ...', Array) 
- 7 /Users/yasser/project/my_project/vendor/roots/acorn/src/Illuminate/Foundation/Exceptions/Handler.php(278): Illuminate\Foundation\Exceptions\Handler->reportThrowable(Object(Symfony\Component\ErrorHandler\Error\FatalError)) 
- 8 /Users/yasser/project/my_project/vendor/roots/acorn/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(183): Illuminate\Foundation\Exceptions\Handler->report(Object(Symfony\Component\ErrorHandler\Error\FatalError)) 
- 9 /Users/yasser/project/my_project/vendor/roots/acorn/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(231): Illuminate\Foundation\Bootstrap\HandleExceptions->handleException(Object(Symfony\Component\ErrorHandler\Error\FatalError)) 
- 10 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleShutdown() 
- 11 {main} thrown in /Users/yasser/project/my_project/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php on line 60

Anyone has any ideas on how to resolve this?

Thanks in advance!

  • Y
1 Like

Hi, I had the same problem, in my case the error was that a plugin loaded its PSR Log package as global and replaced the one loaded via composer

I was able to identify the problem by entering

var_dump(class_exists('Psr\Log\LoggerInterface'), (new \ReflectionClass('Psr\Log\LoggerInterface'))->getFileName());

In my bedrock-autoloader.php, this way I realized that the project was loading the package from a different folder than the vendor’s.

I hope this helps you.

1 Like

Thank you pcatapan for your answer!

Unfortunately, the class does ‘not exist’, yet it loads it.

Here’s the output from that var_dump()

bool(false) string(91) "/Users/yasser/project/my_project/vendor/psr/log/src/LoggerInterface.php" 
  • The interface does exist within my vendor folder

  • The weird fact is that everything runs fine when I run the project setup with the production environment.

  • When I just add var_dump(class_exists('Psr\Log\LoggerInterface')); before the Autoloader in bedrock-autoloader.php is instantiated. I get a dump saying bool(false) but no more error…

As I understand now, and from various searches. This could have something to do with a php-psr extension. But I have no psr extensions installed.

I’ve found several people and threads about this issue. most blaming psr extensions. Though I have none installed.

Some urls for context

So I really feel like it has something to do with a wrong Psr version? yet I am not requiring any PSR in my composer.json

@yasser_artcore I have the same problem as you, but in my case, the WooCommerce Germanized Plugin is causing the issue by including an old version of PSR.

So far, I don’t have a solution for this other than deactivating the plugin in development and only activating it in staging and production. :confused:

EDIT
I ended up disabling error reporting for the plugin folder in the development environment with a mu-plugin:

<?php
/*
Plugin Name: Error Handler
Description: Sets a custom error handler to disable error reporting for WP_PLUGIN_DIR in the development environment.
*/

if (defined('WP_ENV') && WP_ENV === 'development') {
    set_error_handler('plugin_error_handler');
    add_action('admin_notices', 'error_handler_admin_notice');
}

function plugin_error_handler($errno, $errstr, $errfile, $errline)
{
    $excluded_paths = [
        WP_PLUGIN_DIR,
    ];

    foreach ($excluded_paths as $path) {
        if (strpos($errfile, $path) !== false) {
            return true;
        }
    }

    return true;
}

function error_handler_admin_notice()
{
    $class = 'notice notice-warning';
    $message = 'The Error Handler plugin is activated and disables error reporting for: ' . WP_PLUGIN_DIR;

    printf('<div class="%s"><p>%s</p></div>', esc_attr($class), esc_html($message));
}

1 Like

@yasser_artcore are you using:

  1. Bedrock
  2. WPML

In general, if you are using WPML plugin, try commenting out the following part (~ line 65):

# wpml-multilingual-cms/vendor/composer/autoload_static.php
'Psr\\Log\\' => 
    array (
        0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
    ),

Does it change anything?

@alexmzk , Thanks for your reply!

You helped a lot, thank you for the example. It does prove that it’s probably plugin related code .

Love the solution you found!


@RistoKaalma Amazing! You nailed it :smiley:

It is indeed WPML and your solution fixed it! Thanks a lot!


Unfortunately as this time, even the latest version of WPML has this issue. I’ll open a support thread with them

1 Like

Perhaps you don’t need to start a duplicate support thread on WPML - fellow Roots.io members are on it already:

  1. Fatal error: Declaration of Monolog - WPML
  2. https://github.com/mollie/WooCommerce/issues/892

When using Bedrock for managing plugins with composer, composer-patches (shout-out to @tombro for the suggestion) might be useful until WPML v4.7 is released.

In Bedrock dir:

  1. Run composer require cweagans/composer-patches
  2. Add to "config""allow-plugins" in in composer.json:
[...],
"cweagans/composer-patches": true
  1. Add to "extra" in composer.json:
[...],
"patches": {
      "wpml/wpml-multilingual-cms": {
        "Fix monolog": "patches/wpml-multilingual-cms/monolog-fix.patch"
      }
    }
  1. Write to patches/wpml-multilingual-cms/monolog-fix.patch file:
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -62,10 +62,10 @@
         array (
             0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
         ),
-        'Psr\\Log\\' => 
-        array (
-            0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
-        ),
+        // 'Psr\\Log\\' => 
+        // array (
+        //     0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
+        // ),
         'PhpMyAdmin\\SqlParser\\' => 
         array (
             0 => __DIR__ . '/..' . '/wpml/sql-parser/src',
  1. Manually delete web/app/plugins/wpml-multilingual-cms dir

For me, seemingly it only ran when a plugin is being initially installed (or maybe updated… ultimately the state needs to “change” for it to work) - thus I had to manually delete the existing plugin files.

  1. Run composer update - my output:
xxx@yyy:~/Projects/example-web/site$ composer update
Gathering patches for root package.
Loading composer repositories with package information
Updating dependencies                                 
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
Gathering patches for root package.
Gathering patches for dependencies. This might take a minute.
  - Installing wpml/wpml-multilingual-cms (4.6.9): Extracting archive
  - Applying patches for wpml/wpml-multilingual-cms
    patches/wpml-multilingual-cms/monolog-fix.patch (Fix monolog)

Generating optimized autoload files
> Roots\Acorn\ComposerScripts::postAutoloadDump
68 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
3 Likes

Another incompatible plugin Logger interface incompatible with Psr\Log\LoggerTrait:log() (968) · Issue #1518 · woocommerce/woocommerce-paypal-payments · GitHub

2 Likes

Thanks for your detailed explanation! Still no sign of 4.7

I am failing at this step. Can’t see any patches folder anywhere. Any idea where it could be?

You have the create the directory yourself as it’s not included in the initial Bedrock project - create the new file (relative to your Bedrock directory, where the composer.json is) to ./patches/wpml-multilingual-cms/monolog-fix.patch.

Then copy all the content from code block (step 4) into the created monolog-fix.patch file:

1 Like

Wonderful thank you so much.

That did the trick using sitepress-multilingual-cms 4.6.15
I just changed the folder name.