Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/EmailUnsubscribe/Processor.php
<?php

namespace XF\EmailUnsubscribe;

use
XF\App;
use
XF\Entity\User;
use
Laminas\Mail\Storage;
use
XF\Util\File;

class
Processor
{
   
/**
     * @var App
     */
   
protected $app;

    protected
$verpBase;

    public function
__construct(App $app, $verpBase)
    {
       
$this->app = $app;
       
$this->verpBase = $verpBase;
    }

    public function
processFromStorage(Storage\AbstractStorage $storage, $maxRunTime = 0)
    {
       
$s = microtime(true);

       
$total = $storage->countMessages();
        if (!
$total)
        {
            return
true;
        }

       
$finished = true;

        for (
$messageId = $total; $messageId > 0; $messageId--)
        {
            try
            {
               
$message = $storage->getMessage($messageId);
            }
            catch (\
Laminas\Mail\Exception\InvalidArgumentException $e)
            {
                \
XF::logException($e, false, 'Error processing unsubscribe message (see internal_data/temp/email_unsubscribe_error.log): ');

               
$rawHeaders = $storage->getRawHeader($messageId);
               
$rawContent = $storage->getRawContent($messageId);
               
$rawMessage = trim($rawHeaders) . "\r\n\r\n" . trim($rawContent);

               
File::writeFile(
                   
File::getNamedTempFile(
                       
'email_unsubscribe_error.log',
                       
false
                   
),
                   
$rawMessage
               
);

               
$message = null;
            }
            finally
            {
               
$storage->removeMessage($messageId);
            }

            if (
$message)
            {
               
$this->processMessage($message);
            }

            if (
$maxRunTime && microtime(true) - $s > $maxRunTime)
            {
               
$finished = false;
                break;
            }
        }

        return
$finished;
    }

    public function
processMessage(Storage\Message $message)
    {
       
$confirmKey = null;
       
$email = null;

        if (
$this->verpBase && isset($message->to))
        {
           
$matchRegex = str_replace('@', '\+([a-z0-9]+)\+([^@=]+=[^@=]+)@', preg_quote($this->verpBase, '#'));
            if (
preg_match("#$matchRegex#i", $message->to, $matches))
            {
               
$confirmKey = $matches[1];
               
$email = str_replace('=', '@', $matches[2]);
            }
        }

        if (!
$confirmKey && !$email)
        {
           
$subject = trim($message->getHeader('subject', 'string'));

            if (
preg_match('/^\[List-Unsubscribe\[([a-f0-9]{32}),(.*@.*)\]\]$/', $subject, $matches))
            {
               
$confirmKey = $matches[1];
               
$email = $matches[2];
            }
        }

        if (!
$confirmKey || !$email)
        {
            return;
        }

       
/** @var User $user */
       
$user = $this->app->em()->findOne('XF:User', ['email' => $email]);

        if (!
$user || substr($user->getEmailConfirmKey(), 0, 8) !== substr($confirmKey, 0, 8))
        {
            return;
        }

       
$this->applyUserUnsubscribeAction($user);
    }

    public function
applyUserUnsubscribeAction(User $user)
    {
       
$user->Option->receive_admin_email = false;
       
$user->Option->save(false);
    }

   
/**
     * @param App $app
     *
     * @return null|Storage\AbstractStorage
     */
   
public static function getDefaultUnsubscribeHandlerStorage(App $app)
    {
       
$options = $app->options();

        if (!
$options->unsubscribeEmailAddress)
        {
            return
null;
        }

       
$handler = $options->emailUnsubscribeHandler;
        if (!
$handler || empty($handler['enabled']))
        {
            return
null;
        }

       
/** @var \XF\Repository\Option $optionRepo */
       
$optionRepo = $app->repository('XF:Option');
       
$handler = $optionRepo->refreshEmailAccessTokenIfNeeded('emailUnsubscribeHandler');

        try
        {
            if (
$handler['type'] == 'pop3')
            {
               
$connection = \XF\Mail\Storage\Pop3::setupFromHandler($handler);
            }
            else if (
$handler['type'] == 'imap')
            {
               
$connection = \XF\Mail\Storage\Imap::setupFromHandler($handler);
            }
            else
            {
                throw new \
Exception("Unknown email unsubscribe handler $handler[type]");
            }
        }
        catch (\
Laminas\Mail\Exception\ExceptionInterface $e)
        {
           
$app->logException($e, false, "Unsubscribe connection error: ");
            return
null;
        }

        return
$connection;
    }
}