• Resolved ziegel

    (@ziegel)


    Hi,

    I got emails stuck in queue.

    Running cron from server where PHP ver 8.2.4 is installed, I got the error notification:

    PHP Fatal error: Uncaught TypeError: DeliciousBrains\WP_Offload_SES\Carbon\Carbon::setLastErrors(): Argument #1 ($lastErrors) must be of type array, bool given, called in /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php on line 487 and defined in /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php:800
    Stack trace:
    
    0 /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php(487): DeliciousBrains\WP_Offload_SES\Carbon\Carbon::setLastErrors()
    
    1 /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/vendor/WP-Queue/Connections/DatabaseConnection.php(166): DeliciousBrains\WP_Offload_SES\Carbon\Carbon->__construct()
    
    2 /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/classes/Queue/Connection.php(160): DeliciousBrains\WP_Offload_SES\WP_Queue\Connections\DatabaseConnection->vitalize_job()
    
    3 /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/classes/Queue/Worker.php(56): DeliciousBrains\WP_Offload_SES\Queue\Connection->pop()
    
    4 /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/classes/Queue/Email-Cron.php(60): DeliciousBrains\WP_Offload_SES\Queue\Worker->process()
    
    5 /var/www/vhosts/example.com/httpdocs/wp-includes/class-wp-hook.php(308): DeliciousBrains\WP_Offload_SES\Queue\Email_Cron->cron_worker()
    
    6 /var/www/vhosts/example.com/httpdocs/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
    
    7 /var/www/vhosts/example.com/httpdocs/wp-includes/plugin.php(565): WP_Hook->do_action()
    
    8 /var/www/vhosts/example.com/httpdocs/wp-cron.php(188): do_action_ref_array()
    
    9 {main}
    
    thrown in /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php on line 800

    Possible Bug:

    The error is seemed to be caused by 2 different, incompatible versions of the same PHP library (in this case PHP Carbon) by 2 plugins. In this case, the other plugin is using a drop-in replace for Carbon, https://github.com/cakephp/chronos which doesn’t appear to support Carbon v2 (which we’re using)

    DIAGNOSTIC INFO is:

    site_url(): https://example.com
    home_url(): https://example.com
    Web Server: Apache
    WordPress: 6.2
    WP Locale: en_US
    PHP: 8.2.4
    PHP Memory Limit: 512M
    WP Memory Limit: 256M
    Memory Usage: 14 MB
    WP Max Upload Size: 3 MB
    PHP Time Limit: 3600
    PHP Error Log: /var/www/vhosts/example.com/logs/PHP_errors.log
    MySQL: 8.0.32
    Database Name: admin_example
    Table Prefix: rOIz1f_
    ext/mysqli: yes
    cURL: 7.81.0
    OpenSSL: OpenSSL 3.0.2 15 Mar 2022
    fsockopen: Enabled
    allow_url_fopen: Enabled
    Zlib Compression: Enabled
    Basic Auth: Disabled
    Proxy: Disabled
    Blocked External HTTP Requests: None Send Mail Using SES: On
    Enable Open Tracking: Off
    Enable Click Tracking: Off
    Region: us-east-1
    Log Duration: 180 WP Cron: Disabled
    Alternate WP Cron: Disabled
    Last Run: 22:56:10 2023-04-17 UTC
    Next Scheduled: 23:02:02 2023-04-17 UTC
    Queued: 2
    Failures: 0 WPOSES_SETTINGS: Not defined
    WPOSES_LICENCE: Not defined
    AWS_USE_EC2_IAM_ROLE: Not defined WP_DEBUG: No
    WP_DEBUG_LOG: No
    WP_DEBUG_DISPLAY: No
    SCRIPT_DEBUG: No
    WP_CONTENT_DIR: /var/www/vhosts/example.com/httpdocs/wp-content
    WP_CONTENT_URL: https://example.com/wp-content
    UPLOADS: Not defined
    WP_PLUGIN_DIR: /var/www/vhosts/example.com/httpdocs/wp-content/plugins
    WP_PLUGIN_URL: https://example.com/wp-content/plugins Active Theme Name: Currenge Theme
    Active Theme Version: 1.0.0
    Active Theme Folder: example Active Plugins:
    ACF Content Analysis for Yoast SEO (v3.0.1) by Thomas Kräftner, ViktorFroberg, marol87, pekz0r, angrycreative, Team Yoast
    Advanced Custom Fields (v6.1.4) by WP Engine
    Advanced Custom Fields Multilingual (v1.8.1) by OnTheGoSystems
    Advanced Custom Fields PRO (v6.1.4) by WP Engine
    Advanced Custom Fields: ACF Code Field (v1.8) by Peter Tasker
    CAPTCHA 4WP (v7.1.0) by WP White Security
    Classic Editor + (v4.2.0) by Pieter Bos, Greg Schoppe
    Classic Widgets (v0.3) by WordPress Contributors
    Conditional Fields for Contact Form 7 (v2.3.7) by Jules Colle
    Contact Form 7 (v5.5.3) by Takayuki Miyoshi
    Contact Form 7 Signature Addon (v4.2.2) by Breizhtorm
    Contact Form CFDB7 (v1.2.6.5) by Arshid
    GDPR Cookie Compliance (v4.10.6) by Moove Agency
    Listo (v1.3) by Takayuki Miyoshi
    NinjaFirewall (WP Edition) (v4.5.7) by The Ninja Technologies Network
    Redirect 404 Error Page to Homepage or Custom Page (v1.7.9) by Fullworks
    SVG Support (v2.5.5) by Benbodhi
    Simple Custom Post Order (v2.5.6) by Colorlib
    Toolset Module Manager (v1.8.6) by OnTheGoSystems
    Toolset Types (v3.4.19) by OnTheGoSystems
    Toolset Views Lite (v2.9.4-lite) by OnTheGoSystems
    Video Background (v2.7.5) by Push Labs
    WP Crontrol (v1.15.1) by John Blackbourn & crontributors
    WP Last Login (v5) by Konstantin Obenland
    WP Offload SES Lite (v1.6.3) by Delicious Brains
    WPBakery Page Builder (v6.10.0) by Michael M - WPBakery.com
    WPML CMS Nav (v1.5.5) by OnTheGoSystems
    WPML Media (v2.7.2) by OnTheGoSystems
    WPML Multilingual CMS (v4.6.3) by OnTheGoSystems
    WPML SEO (v2.1.0) by OnTheGoSystems
    WPML Sticky Links (v1.5.4) by OnTheGoSystems
    Yoast Duplicate Post (v4.5) by Enrico Battocchi & Team Yoast
    Yoast SEO (v20.5) by Team Yoast
    miniOrange 2 Factor Authentication (v5.7.0) by miniOrange
    plugin load filter (v4.0.13) by enomoto@celtislab Must-use Plugins:
    0-ninjafirewall.phpplugin load filter plf-filter by enomoto@celtislab Drop-ins:
    maintenance.php - maintenance.php

    Issue seems to be, as resulting from the above possible bug.

    Can you please assist?

    • This topic was modified 1 year ago by ziegel.
Viewing 15 replies - 1 through 15 (of 17 total)
  • Thread Starter ziegel

    (@ziegel)

    Possibly… the fix would be:

    Old Line

    private static function setLastErrors(array $lastErrors)

    New Line

    private static function setLastErrors($lastErrors)

    Can you please be kind, and have a look?

    Plugin Author Delicious Brains

    (@deliciousbrains)

    Hi Zeigel,

    Many thanks for reporting this issue. From an initial look, this seems to be an issue with PHP 8.2 rather than a conflict with another plugin.

    Side note: We place all external libraries in our own namespace to avoid conflicts with other plugins.

    The root cause of this seems to be that In PHP 8.2, the default return value of DateTime::getLastErrors() changed. Before 8.2, it always returns an array even when there are no warnings or errors. In 8.2, it will return boolean false in this case. That’s what breaking Carbon’s constructor under PHP 8.2.

    The latest release of WP SES (1.6.3) actually downgraded from Carbon V2 back to 1.x. The reason for this is that Carbon V2 is not compatible with PHP 7 unless there are polyfills for the new string functions that were introduced in PHP 8. WordPress has these polyfills in place from 5.9 and later, but that PHP7 incompatibility meant that Carbon made WP SES stop working on a large set of sites with older versions of PHP and WordPress.

    Since that was the only real upgrade in v1.6.3, my best advice here is to downgrade to WP SES 1.6.2. It uses Carbon V2 which should work better on your site. If you give that a try, we will appreciate it if you report back.

    Very sorry for the inconvenience and thanks again for your detailed reporting!

    -et

    Thread Starter ziegel

    (@ziegel)

    Hi,

    Please note, getting and installing, older plugin versions, is not as that simple.

    Thus, I am trying to figure out a possible solution, which seems to me, to be more ‘elegant’. That would be, modifying the Plugin code, on wp-ses/vendor/CarbonCarbon.php line number 800 or so, to suit both PHP versions:

    if(version_compare(PHP_VERSION, "8.2") >= 0) {
    	private static function setLastErrors($lastErrors)
    			{
    			static::$lastErrors = $lastErrors;
    			}
    }
    			
    else {
    	private static function setLastErrors(array $lastErrors)
    			{
    			static::$lastErrors = $lastErrors;
    			}	
    }	

    And, just to be on safe side, I have also restarted some server services, as:

    systemctl restart apache2
    systemctl restart nginx
    systemctl restart plesk-php82-fpm

    What I have done, is placed an IF for the PHP version. version_compare compares two versions and return three boolean values, where PHP_VERSION is a built-in PHP constant returning the numerical value of the used PHP version.

    Thus, if the PHP version used is “8.2” or higher, I have returned a modified plugin code line, suitable for the new PHP version 8.2 data structure. This would mean, changing the previous code line which was private static function setLastErrors(array $lastErrors) to be private static function setLastErrors($lastErrors) (omitting the “array” inside setLastErrors(...).

    For the else condition, where version is lower than PHP version 8.2, I have left the original code, with the data structure containing array, suiting older PHP versions: private static function setLastErrors(array $lastErrors)

    The simple usage of the version_compare() PHP function and PHP_VERSION PHP constant, is simply explained in this link, or in section below:

    The examples below use the PHP_VERSION constant, because it contains the value of the PHP version that is executing the code.
    
    Example #1 version_compare() examples
    
    <?php
    if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
        echo 'I am at least PHP version 7.0.0, my version: ' . PHP_VERSION . "\n";
    }
    
    if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
        echo 'I am at least PHP version 5.3.0, my version: ' . PHP_VERSION . "\n";
    }
    
    if (version_compare(PHP_VERSION, '5.0.0', '>=')) {
        echo 'I am at least PHP version 5.0.0, my version: ' . PHP_VERSION . "\n";
    }
    
    if (version_compare(PHP_VERSION, '5.0.0', '<')) {
        echo 'I am still PHP 4, my version: ' . PHP_VERSION . "\n";
    }
    ?>

    Problem:

    Emails are still stuck in queue. Forcing the cron currently does not release them. I suspect there is another problem in the current plugin version.

    Please note, I have noted that PHP error log, for some reason uses UTC and not the local time zone. I have not fully succeeded in forcing it to use the current time zone set via PHP. I am bring this issue to your attention, as I have noticed on the mySQL data base database_oses_jobs that the time zone of queued emails is also using UTC time zone as is, for the queued emails (which are said to be related to: DeliciousBrains\WP_Offload_SES\Queue\Jobs\Email_Job) fields: available_at and created_at .

    Thus may I ask, if it could be, that a set to error emails, time-zone issue be related to the root problem of emails queued with error not being sent even later on?

    And finally, may I ask for your opinion, and if looking good, suggest you implement it, in a new plugin version release.

    Thread Starter ziegel

    (@ziegel)

    I got the below PHP Error, and would soon look into it.

    PHP Parse error:  syntax error, unexpected token "if", expecting "function" or "const" in /var/www/vhosts/example.com/httpdocs/wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php on line 802
    Thread Starter ziegel

    (@ziegel)

    Still no success

    • This reply was modified 1 year ago by ziegel.
    Thread Starter ziegel

    (@ziegel)

    With the below code, it seems there is no PHP error, however emails are still stuck in the queue state:

    function comprePhpVersion() {
    
    		if(version_compare(phpversion() , "8.2") >= 0) {
    			private static function setLastErrors($lastErrors)
    				{
    				static::$lastErrors = $lastErrors;
    				}
    		}
    				
    		else {
    			private static function setLastErrors(array $lastErrors)
    				{
    				static::$lastErrors = $lastErrors;
    				}	
    		}	
    
    }
    Thread Starter ziegel

    (@ziegel)

    Ok. I get what seems to be the logic of the needed fix, however do not konw the syntax and var name used, to implement it.

    First it should be checked what PHP version is used. For older than version 8.2, the array data structure should be used.

    For version 8.2 and newer, a second IF should be used, to see if there are errors or not. If there are errors, an array data structure should be used, and if there are no errors, the array should be removed from the code, as the result would be a bolean.

    As I can not code the above on my own, although it should not be complicated at all for a junior developer, I would search for an old version of the plugin and install it. I hope disabling current plugin, and setting a new one, doesn’t break anything in the email configuration.

    Can you please advise?

    Thread Starter ziegel

    (@ziegel)

    Ok, I have managed to install WP Offload SES Plugin Version 1.6.1, having it on a server backup file, and it seems to work smoothly.

    Please let me know when version 1.6.4 out there, so I can install it.

    Plugin Author Delicious Brains

    (@deliciousbrains)

    Hi again,

    Thanks for your updates along the way.

    I hope disabling current plugin, and setting a new one, doesn’t break anything in the email configuration.

    This is perfectly safe, the configuration format in the DB has not changed.

    -et

    Any updates? We continue to get errors

    PHP 8.2.5 (fpm-fcgi) (built: Apr 14 2023 04:27:02)

    2023/04/21 17:21:55 [error] 1052024#1052024: *1169 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught TypeError: DeliciousBrains\WP_Offload_SES\Carbon\Carbon::setLastErrors(): Argument #1 ($lastErrors) must be of type array, bool given, called in /wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php on line 487 and defined in /wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php:800
    Stack trace:
    #0 /wp-content/plugins/wp-ses/vendor/Carbon/Carbon.php(487): DeliciousBrains\WP_Offload_SES\Carbon\Carbon::setLastErrors()
    #1 /wp-content/plugins/wp-ses/vendor/WP-Queue/Connections/DatabaseConnection.php(166): DeliciousBrains\WP_Offload_SES\Carbon\Carbon->__construct()
    #2 /wp-content/plugins/wp-ses/classes/Queue/Connection.php(160): DeliciousBrains\WP_Offload_SES\WP_Queue\Connections\DatabaseConnection->vitalize_job()
    tikguy

    (@tikguy)

    this should fix it.

    --- Carbon.php.orig	2023-04-23 22:10:28.395805000 +0200
    +++ Carbon.php	2023-04-23 22:07:28.731780000 +0200
    @@ -797,8 +797,16 @@
          *
          * @return void
          */
    -    private static function setLastErrors(array $lastErrors)
    +    private static function setLastErrors($lastErrors)
         {
    +	if (is_bool($lastErrors)) {
    +		$lastErrors=array(
    +    			"warning_count" => 0,
    +    			"warnings" => Array(),
    +    			"error_count" => 0,
    +    			"errors" => Array()
    +			);
    +	}
             static::$lastErrors = $lastErrors;
         }
         /**
    
    Thread Starter ziegel

    (@ziegel)

    Hi @tikguy ,

    If I got the explanation correctly:

    The root cause of this seems to be that In PHP 8.2, the default return value of DateTime::getLastErrors() changed. Before 8.2, it always returns an array even when there are no warnings or errors. In 8.2, it will return boolean false in this case. That’s what breaking Carbon’s constructor under PHP 8.2.

    I suspect, that the same applies to the function setLastErrors which you have used, i.e., possibly it provides two different data structure, depending if it has an error to report or it hasn’t. Testing it, to the best of my understanding, would require having a PHP error related to it.

    tikguy

    (@tikguy)

    yes. i essentially did nothing more, but
    – removed the type enforcement
    – added an if to check whether the received argument is a boolean (in pre8.2 php this can not happen, with 8.2+ it will only get false if there was no error)
    – in this case (got false) i populate the array just as pre 8.2 php did

    this fix got my queued messages delivered, as the code ran w/o hitting the old exception

    Thread Starter ziegel

    (@ziegel)

    And what would the code do, for the situation where there is an error?

    tikguy

    (@tikguy)

    if there’s an error, the array structure (properly populated with values) will be there as before, because the changed behaviour of php8.2 only affects the situation if there’s no error. the piece of code i added only affects the situation where there’s a boolean value as the argument of the function. if anything else comes (which by default couldn’t be anything else than an array structure) it will be passed along w/o any kind of modification

Viewing 15 replies - 1 through 15 (of 17 total)
  • The topic ‘Plugin Possible Bug – Using Old PHP Carbon, clash with newer on another plugin?’ is closed to new replies.