Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Repository/Forum.php
<?php

namespace XF\Repository;

use
XF\Db\AbstractAdapter;
use
XF\Mvc\Entity\Repository;

use function
in_array, is_array;

class
Forum extends Repository
{
    public function
getViewableForums(array $where = [], $with = null)
    {
       
$visitor = \XF::visitor();

       
$forumFinder = $this->finder('XF:Forum')
            ->
with('Node.Permissions|' . $visitor->permission_combination_id);

        if (
$where)
        {
           
$forumFinder->where($where);
        }
        if (
$with)
        {
           
$forumFinder->with($with);
        }

        return
$forumFinder->fetch()->filterViewable();
    }

    public function
markForumReadByUser(\XF\Entity\Forum $forum, $userId, $newRead = null)
    {
        if (!
$userId)
        {
            return
false;
        }

        if (
$newRead === null)
        {
           
$newRead = max(\XF::$time, $forum->last_post_date);
        }

       
$cutOff = \XF::$time - $this->options()->readMarkingDataLifetime * 86400;
        if (
$newRead <= $cutOff)
        {
            return
false;
        }

       
$read = $forum->Read[$userId];
        if (
$read && $newRead <= $read->forum_read_date)
        {
            return
false;
        }

        \
XF::db()->executeTransaction(function(AbstractAdapter $db) use ($forum, $userId, $newRead)
        {
           
$db->insert('xf_forum_read', [
               
'node_id' => $forum->node_id,
               
'user_id' => $userId,
               
'forum_read_date' => $newRead
           
], false, 'forum_read_date = VALUES(forum_read_date)');
        },
AbstractAdapter::ALLOW_DEADLOCK_RERUN);

        return
true;
    }

    public function
markForumReadByVisitor(\XF\Entity\Forum $forum, $newRead = null)
    {
       
$userId = \XF::visitor()->user_id;
        return
$this->markForumReadByUser($forum, $userId, $newRead);
    }

    public function
markForumReadIfPossible(\XF\Entity\Forum $forum, $newRead = null)
    {
       
$userId = \XF::visitor()->user_id;
        if (!
$userId)
        {
            return
false;
        }

       
$threadRepo = $this->repository('XF:Thread');
       
$unread = $threadRepo->countUnreadThreadsInForum($forum);
        if (
$unread)
        {
            return
false;
        }

        return
$this->markForumReadByVisitor($forum, $newRead);
    }

    public function
markForumTreeReadByVisitor(\XF\Entity\AbstractNode $baseNode = null, $newRead = null)
    {
       
$userId = \XF::visitor()->user_id;
        if (!
$userId)
        {
            return [];
        }

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

       
$cutOff = \XF::$time - $this->options()->readMarkingDataLifetime * 86400;
        if (
$newRead <= $cutOff)
        {
            return [];
        }

       
/** @var \XF\Repository\Node $nodeRepo */
       
$nodeRepo = $this->repository('XF:Node');

        if (
$baseNode)
        {
           
$childNodes = $nodeRepo->findDescendants($baseNode->Node, false)->fetch();
           
$nodes = $childNodes->unshift($baseNode->Node);
        }
        else
        {
           
$nodes = $nodeRepo->getFullNodeList();
        }

       
$forumIds = [];
        foreach (
$nodes AS $nodeId => $node)
        {
           
/** @var \XF\Entity\Node $node */
           
if ($node->node_type_id == 'Forum')
            {
               
$forumIds[] = $node->node_id;
            }
        }

       
$forums = $this->em->findByIds(
           
'XF:Forum',
           
$forumIds,
            [
               
'Node.Permissions|' . \XF::visitor()->permission_combination_id,
               
'Read|' . $userId
           
]
        );

       
$markedRead = [];
       
$inserts = [];

        foreach (
$forums AS $forum)
        {
           
/** @var \XF\Entity\Forum $forum */
           
if (!$forum->canView())
            {
                continue;
            }

           
$read = $forum->Read[$userId];
            if (
$read && $newRead <= $read->forum_read_date)
            {
                continue;
            }

           
$inserts[] = [
               
'node_id' => $forum->node_id,
               
'user_id' => $userId,
               
'forum_read_date' => $newRead
           
];
           
$markedRead[] = $forum->node_id;
        }

        if (
$inserts)
        {
            \
XF::db()->executeTransaction(function(AbstractAdapter $db) use ($inserts)
            {
               
$this->db()->insertBulk(
                   
'xf_forum_read',
                   
$inserts,
                   
false,
                   
'forum_read_date = VALUES(forum_read_date)'
               
);
            },
AbstractAdapter::ALLOW_DEADLOCK_RERUN);
        }

        return
$markedRead;
    }

    public function
pruneForumReadLogs($cutOff = null)
    {
        if (
$cutOff === null)
        {
           
$cutOff = \XF::$time - ($this->options()->readMarkingDataLifetime * 86400);
        }

       
$this->db()->delete('xf_forum_read', 'forum_read_date < ?', $cutOff);
    }

    public function
getForumCounterTotals()
    {
        return
$this->db()->fetchRow("
            SELECT SUM(discussion_count) AS threads,
                SUM(message_count) AS messages
            FROM xf_forum
        "
);
    }

   
/**
     * @param bool $includeEmpty
     * @param string[]|string|null $enableTypes
     * @param string|null $type
     * @param bool $checkPerms
     *
     * @return array
     */
   
public function getForumOptionsData(
       
bool $includeEmpty = true,
       
$enableTypes = null,
       
string $type = null,
       
bool $checkPerms = false
   
)
    {
       
$choices = [];

        if (
$includeEmpty)
        {
           
$choices[0] = [
               
'_type' => 'option',
               
'value' => 0,
               
'label' => \XF::phrase('(none)')
            ];
        }

       
/** @var \XF\Repository\Node $nodeRepo */
       
$nodeRepo = $this->repository('XF:Node');
       
$nodeList = $nodeRepo->getFullNodeList();
       
$nodeRepo->loadNodeTypeDataForNodes($nodeList);

        if (
$checkPerms)
        {
           
$nodeList = $nodeList->filterViewable();
        }

        foreach (
$nodeRepo->createNodeTree($nodeList)->getFlattened() AS $entry)
        {
           
/** @var \XF\Entity\Node $node */
           
$node = $entry['record'];

            if (
$node['depth'])
            {
               
$prefix = str_repeat('--', $entry['depth']) . ' ';
            }
            else
            {
               
$prefix = '';
            }

           
$choice = [
               
'value' => $node->node_id,
               
'label' => $prefix . $node->title
           
];

            if (
$node->node_type_id == 'Forum' && $node->Data)
            {
                if (
$enableTypes !== null)
                {
                    if (!
is_array($enableTypes))
                    {
                       
$enableTypes = [$enableTypes];
                    }

                   
/** @var \XF\Entity\Forum $forum */
                   
$forum = $node->Data;
                   
$choice['disabled'] = in_array($forum->forum_type_id, $enableTypes)
                        ?
false
                       
: 'disabled';
                }
                else
                {
                   
$choice['disabled'] = false;
                }
            }
            else
            {
               
$choice['disabled'] = 'disabled';
            }

            if (
$type !== null)
            {
               
$choice['_type'] = $type;
            }

           
$choices[$node->node_id] = $choice;
        }

        return
$choices;
    }
}