Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Spam/Cleaner.php
<?php

namespace XF\Spam;

use
XF\Entity\User;

use function
boolval, count, strval;

class
Cleaner
{
    protected
$app;
    protected
$db;

   
/** @var User */
   
protected $user;

    protected
$log = [];
    protected
$errors = [];

    protected
$inTransaction = false;

    public function
__construct(\XF\App $app, User $user)
    {
       
$this->app = $app;

       
$this->db = $app->db();

       
$this->setUser($user);
    }

    public function
setUser(User $user)
    {
       
$this->user = $user;
    }

    public function
isAlreadyCleaned()
    {
       
$db = $this->db;

        return
boolval($db->fetchOne('
            SELECT COUNT(*)
            FROM xf_spam_cleaner_log
            WHERE user_id = ?
            AND restored_date = 0
        '
, $this->user->user_id));
    }

    public function
isRecentlyCleaned(int $recentSeconds = null): bool
   
{
       
$db = $this->db;

       
// done this way to give us future flexibility without requiring a method signature change
       
if ($recentSeconds === null)
        {
           
$recentSeconds = 120;
        }

        return
boolval($db->fetchOne('
            SELECT COUNT(*)
            FROM xf_spam_cleaner_log
            WHERE user_id = ?
            AND restored_date = 0
            AND application_date >= ?
        '
, [$this->user->user_id, time() - $recentSeconds]));
    }

    public function
banUser()
    {
       
$this->forceTransaction();

       
$this->log('user', 'banned');

       
$user = $this->user;

       
$reason = strval(\XF::phrase('spam_cleaner_ban_reason'));

       
/** @var \XF\Repository\Banning $banningRepo */
       
$banningRepo = $this->app->repository('XF:Banning');

       
$success = $banningRepo->banUser($user, 0, $reason, $error);
        if (!
$success)
        {
           
$this->logError('ban', $error);
            return;
        }

        if (
$user->avatar_date > 0 || $user->gravatar)
        {
           
/** @var \XF\Service\User\Avatar $avatarService */
           
$avatarService = $this->app->service('XF:User\Avatar', $user);
           
$avatarService->logIp(false);
           
$avatarService->deleteAvatar();
        }

        if (
$user->Profile && $user->Profile->banner_date > 0)
        {
           
/** @var \XF\Service\User\ProfileBanner $bannerService */
           
$bannerService = $this->app->service('XF:User\ProfileBanner', $user);
           
$bannerService->logIp(false);
           
$bannerService->deleteBanner();
        }

       
$this->submitData();
    }

    public function
submitData()
    {
       
$submitter = $this->app->container('spam.userSubmitter');
       
$submitter->submit($this->user);
    }

    protected function
getDefaultActions()
    {
        return [
           
'action_threads' => false,
           
'delete_messages' => false,
           
'delete_conversations' => false,
           
'ban_user' => false,
           
'check_ips' => false
       
];
    }

    protected function
prepareActions(array $actions)
    {
        return
array_replace($this->getDefaultActions(), $actions);
    }

    public function
cleanUp(array $actions)
    {
       
$actions = $this->prepareActions($actions);

       
$this->forceTransaction();

        if (
$actions['ban_user'])
        {
           
$this->banUser();
        }

       
$this->cleanUpContent($actions);
    }

    public function
cleanUpContent(array $actions)
    {
       
$actions = $this->prepareActions($actions);

       
$this->forceTransaction();

       
/** @var \XF\Repository\Spam $spamRepo */
       
$spamRepo = $this->app->repository('XF:Spam');

       
$spamHandlers = $spamRepo->getSpamHandlers($this->user);
        foreach (
$spamHandlers AS $contentType => $spamHandler)
        {
            if (
$spamHandler->canCleanUp($actions))
            {
                if (!
$spamHandler->cleanUp($this->log, $error))
                {
                   
$this->logError($contentType, $error);

                    return;
                }
            }
        }

        if (
$actions['delete_messages'])
        {
           
$reports = $this->app->finder('XF:Report')->where('content_user_id', $this->user->user_id);
            foreach (
$reports->fetch() AS $report)
            {
               
$report->report_state = 'resolved';
               
$report->save();
            }
        }
    }

    public function
finalize()
    {
       
$db = $this->db;

        if (
count($this->errors))
        {
            if (
$this->inTransaction)
            {
               
$db->rollback();
               
$this->inTransaction = false;
            }

            return
false;
        }

       
$this->user->save();
       
$this->writeLog();

        if (
$this->inTransaction)
        {
           
$db->commit();
           
$this->inTransaction = false;
        }

        return
true;
    }

    protected function
writeLog()
    {
       
$db = $this->db;

       
$user = $this->user;
       
$visitor = \XF::visitor();

       
// log progress
       
$db->insert('xf_spam_cleaner_log', [
           
'user_id' => $user->user_id,
           
'username' => $user->username,
           
'applying_user_id' => $visitor->user_id,
           
'applying_username' => $visitor->username,
           
'application_date' => time(),
           
'data' => (count($this->log) ? json_encode($this->log) : '')
        ]);

       
$this->app->logger()->logModeratorAction('user', $user, 'spam_clean');
    }

    protected function
forceTransaction()
    {
        if (!
$this->inTransaction)
        {
           
$this->db->beginTransaction();
           
$this->inTransaction = true;
        }
    }

    public function
getErrors()
    {
        return
$this->errors;
    }

    protected function
log($logKey, $value)
    {
       
$this->log[$logKey] = $value;
    }

    protected function
logError($logKey, $value)
    {
       
$this->errors[$logKey] = $value;
    }
}