XF 2.2 HashContext for algorithm "sha256" cannot be serialized

Same here.

This seems to work so far , replace the file;
  • src/XF/Mail/Queue.php
Code:
<?php

namespace XF\Mail;

class Queue
{
    /**
     * @var \XF\Db\AbstractAdapter
     */
    protected $db;

    protected $preventJobEnqueue = false;

    public function __construct(\XF\Db\AbstractAdapter $db)
    {
        $this->db = $db;
    }

    public function preventJobEnqueue($prevent)
    {
        $this->preventJobEnqueue = $prevent;
    }

    public function queue(\Swift_Mime_SimpleMessage $message)
    {
        $messageData = [
            'body' => $message->getBody(),
            'headers' => $message->getHeaders()->toString(),
        ];

        $this->db->insert('xf_mail_queue', [
            'mail_data' => serialize($messageData),
            'queue_date' => time()
        ]);

        $this->enqueueJob();

        return true;
    }

    public function queueForRetry(\Swift_Mime_SimpleMessage $message, $queueEntry)
    {
        $sendDate = $this->calculateNextSendDate($queueEntry ? $queueEntry['fail_count'] : 0);
        if (!$sendDate)
        {
            // Mail has failed too many times, delete
            $this->db->delete('xf_mail_queue', 'mail_queue_id = ?', $queueEntry['mail_queue_id']);
            return;
        }

        $messageData = [
            'body' => $message->getBody(),
            'headers' => $message->getHeaders()->toString(),
        ];

        if ($queueEntry)
        {
            $this->db->update('xf_mail_queue', [
                'send_date' => $sendDate,
                'fail_date' => time(),
                'fail_count' => $queueEntry['fail_count'] + 1
            ], 'mail_queue_id = ?', $queueEntry['mail_queue_id']);
        }
        else
        {
            $this->db->insert('xf_mail_queue', [
                'mail_data' => serialize($messageData),
                'queue_date' => time(),
                'send_date' => $sendDate,
                'fail_date' => time(),
                'fail_count' => 1
            ]);
        }

        $this->enqueueJob($sendDate);
    }

    protected function enqueueJob($triggerDate = null)
    {
        if ($this->preventJobEnqueue)
        {
            return;
        }

        if ($triggerDate === null)
        {
            $triggerDate = \XF::$time;
        }

        $jobManager = \XF::app()->jobManager();
        $mailQueueJob = $jobManager->getUniqueJob('MailQueue');

        if (!$mailQueueJob || $mailQueueJob['trigger_date'] > $triggerDate)
        {
            try
            {
                $jobManager->enqueueLater('MailQueue', $triggerDate, 'XF\Job\MailQueue', [], false);
            } catch (\Exception $e)
            {
                // need to just ignore this and let it get picked up later;
                // not doing this could lose email on a deadlock
            }
        }
    }

    protected function calculateNextSendDate($previousFailCount)
    {
        switch ($previousFailCount)
        {
            case 0: $delay = 5 * 60; break; // 5 minutes
            case 1: $delay = 1 * 60 * 60; break; // 1 hour
            case 2: $delay = 2 * 60 * 60; break; // 2 hours
            case 3: $delay = 6 * 60 * 60; break; // 6 hours
            case 4: $delay = 12 * 60 * 60; break; // 12 hours
            default: return null; // give up
        }

        return time() + $delay;
    }

    public function run($maxRunTime)
    {
        $s = microtime(true);
        $db = $this->db;
        $mailer = \XF::mailer();

        do
        {
            $queue = $this->getQueue();

            foreach ($queue AS $id => $record)
            {
                $updated = $db->update('xf_mail_queue', [
                    'send_date' => time() + 15 * 60
                ], 'mail_queue_id = ? AND send_date = ?', [$id, $record['send_date']]);
                if (!$updated)
                {
                    // already been run recently
                    continue;
                }

                $messageData = @unserialize($record['mail_data']);
                if (!is_array($messageData) || !isset($messageData['body'], $messageData['headers']))
                {
                    if (\XF::$debugMode)
                    {
                        \XF::logError('Mail queue entry failed to be sent due to a mail_data error. The queue entry remains in the database.');
                    }
                    else
                    {
                        \XF::logError('Mail queue entry failed to be sent due to a mail_data error. The queue entry has been deleted.');
                        $this->deleteQueueEntry($record['mail_queue_id']);
                    }

                    continue;
                }

                $message = $mailer->createMessage()
                    ->setBody($messageData['body'])
                    ->setHeaders($messageData['headers']);

                if ($mailer->send($message, null, $record))
                {
                    $this->deleteQueueEntry($record['mail_queue_id']);
                }

                if ($maxRunTime && microtime(true) - $s > $maxRunTime)
                {
                    break 2;
                }
            }
        }
        while ($queue);
    }

    protected function deleteQueueEntry(int $queueId)
    {
        $this->db->delete('xf_mail_queue', 'mail_queue_id = ?', $queueId);
    }

    public function getQueue($limit = 20)
    {
        $db = $this->db;

        return $db->fetchAllKeyed($db->limit('
            SELECT *
            FROM xf_mail_queue
            WHERE send_date <= ?
            ORDER BY send_date, queue_date
        ', $limit), 'mail_queue_id', [\XF::$time]);
    }

    public function hasMore(&$nextSendDate = null)
    {
        $nextSendDate = $this->db->fetchOne('
            SELECT MIN(send_date)
            FROM xf_mail_queue
        ');

        return $nextSendDate !== null;
    }
}

Revert back the original once done.

1701021442324.webp
 
I got this today as I just moved my mail from Google Workspace to Zoho. Tried to search the web but found only this thread. Any confirmed work around for this error, please share with me! Thanks!
 
Top Bottom