Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Job/ThreadAction.php
<?php

namespace XF\Job;

use function
intval, is_array;

class
ThreadAction extends AbstractJob
{
    protected
$defaultData = [
       
'start' => 0,
       
'count' => 0,
       
'total' => null,
       
'criteria' => null,
       
'threadIds' => null,
       
'actions' => []
    ];

    public function
run($maxRunTime)
    {
        if (
is_array($this->data['criteria']) && is_array($this->data['threadIds']))
        {
            throw new \
LogicException("Cannot have both criteria and threadIds values; one must be null");
        }

       
$startTime = microtime(true);
       
$em = $this->app->em();

       
$ids = $this->prepareThreadIds();
        if (!
$ids)
        {
            return
$this->complete();
        }

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

       
$limitTime = ($maxRunTime > 0);
        foreach (
$ids AS $key => $id)
        {
           
$this->data['count']++;
           
$this->data['start'] = $id;
            unset(
$ids[$key]);

           
/** @var \XF\Entity\Thread $thread */
           
$thread = $em->find('XF:Thread', $id);
            if (
$thread)
            {
                if (
$this->getActionValue('delete'))
                {
                   
$thread->delete(false, false);
                    continue;
// no further action required
               
}

               
$this->applyInternalThreadChange($thread);
               
$thread->save(false, false);

               
$this->applyExternalThreadChange($thread);
            }

            if (
$limitTime && microtime(true) - $startTime > $maxRunTime)
            {
                break;
            }
        }

        if (
is_array($this->data['threadIds']))
        {
           
$this->data['threadIds'] = $ids;
        }

       
$db->commit();

        return
$this->resume();
    }

    protected function
getActionValue($action)
    {
       
$value = null;
        if (!empty(
$this->data['actions'][$action]))
        {
           
$value = $this->data['actions'][$action];
        }
        return
$value;
    }

    protected function
prepareThreadIds()
    {
        if (
is_array($this->data['criteria']))
        {
           
$searcher = $this->app->searcher('XF:Thread', $this->data['criteria']);
           
$results = $searcher->getFinder()
                ->
where('thread_id', '>', $this->data['start'])
                ->
order('thread_id')
                ->
limit(1000)
                ->
fetchColumns('thread_id');
           
$ids = array_column($results, 'thread_id');
        }
        else if (
is_array($this->data['threadIds']))
        {
           
$ids = $this->data['threadIds'];
        }
        else
        {
           
$ids = [];
        }
       
sort($ids, SORT_NUMERIC);
        return
$ids;
    }

    protected function
applyInternalThreadChange(\XF\Entity\Thread $thread)
    {
       
$isRedirect = ($thread->discussion_type == 'redirect');

        if (
$nodeId = $this->getActionValue('node_id'))
        {
           
$thread->node_id = $nodeId;
        }

       
$newThreadType = $this->getActionValue('discussion_type');
        if (
$newThreadType && !$isRedirect)
        {
           
$forum = $thread->Forum;
            if (
               
$forum
               
&& $forum->TypeHandler->isThreadTypeAllowed($newThreadType, $forum)
                &&
$thread->TypeHandler->canThreadTypeBeChanged($thread)
            )
            {
               
$thread->discussion_type = $newThreadType;
            }
        }

        if (
$this->getActionValue('apply_thread_prefix') && !$isRedirect)
        {
           
$thread->prefix_id = intval($this->getActionValue('prefix_id'));
        }

        if (
$this->getActionValue('stick'))
        {
           
$thread->sticky = true;
        }
        if (
$this->getActionValue('unstick'))
        {
           
$thread->sticky = false;
        }

        if (
$this->getActionValue('lock') && !$isRedirect)
        {
           
$thread->discussion_open = false;
        }
        if (
$this->getActionValue('unlock') && !$isRedirect)
        {
           
$thread->discussion_open = true;
        }

        if (
$this->getActionValue('approve') && !$isRedirect)
        {
           
$thread->discussion_state = 'visible';
        }
        if (
$this->getActionValue('unapprove') && !$isRedirect)
        {
           
$thread->discussion_state = 'moderated';
        }

        if (
$this->getActionValue('soft_delete'))
        {
           
$thread->discussion_state = 'deleted';
        }
    }

    protected function
applyExternalThreadChange(\XF\Entity\Thread $thread)
    {
    }

    public function
getStatusMessage()
    {
       
$actionPhrase = \XF::phrase('updating');
       
$typePhrase = \XF::phrase('threads');

        if (
$this->data['total'] !== null)
        {
            return
sprintf('%s... %s (%d/%d)', $actionPhrase, $typePhrase, $this->data['count'], $this->data['total']);
        }
        else
        {
            return
sprintf('%s... %s (%d)', $actionPhrase, $typePhrase, $this->data['start']);
        }
    }

    public function
canCancel()
    {
        return
true;
    }

    public function
canTriggerByChoice()
    {
        return
false;
    }
}