Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Entity/SearchForum.php
<?php

namespace XF\Entity;

use
XF\Mvc\Entity\Structure;

/**
 * COLUMNS
 * @property int $node_id
 * @property array $search_criteria
 * @property string $sort_order
 * @property string $sort_direction
 * @property int $max_results
 * @property int $cache_ttl
 * @property int $discussion_count
 * @property int $message_count
 * @property int $last_post_id
 * @property int $last_post_date
 * @property int $last_post_user_id
 * @property string $last_post_username
 * @property int $last_thread_id
 * @property string $last_thread_title
 * @property int $last_thread_prefix_id
 *
 * GETTERS
 * @property string|null $node_name
 * @property string|null $title
 * @property string|null $description
 * @property int $depth
 *
 * RELATIONS
 * @property \XF\Entity\SearchForumCache $Cache
 * @property \XF\Mvc\Entity\AbstractCollection|\XF\Entity\SearchForumUserCache[] $UserCaches
 * @property \XF\Entity\Post $LastPost
 * @property \XF\Entity\User $LastPostUser
 * @property \XF\Entity\Thread $LastThread
 * @property \XF\Entity\Node $Node
 */
class SearchForum extends AbstractNode
{
    public function
isSearchEngineIndexable(): bool
   
{
        return
false;
    }

   
/**
     * @param int $depth
     *
     * @return string[]
     */
   
public function getNodeTemplateRenderer($depth)
    {
        return [
           
'template' => 'node_list_search_forum',
           
'macro' => $depth <= 2 ? 'depth' . $depth : 'depthN'
       
];
    }

   
/**
     * @return array
     */
   
public function getNodeListExtras()
    {
       
$output = [
           
'max_results' => $this->max_results,
           
'discussion_count' => $this->discussion_count,
           
'message_count' => $this->message_count
       
];

        if (
$this->last_post_date && $this->LastThread && $this->LastThread->canView())
        {
           
$output['last_post_id'] = $this->last_post_id;
           
$output['last_post_date'] = $this->last_post_date;
           
$output['last_post_user_id'] = $this->last_post_user_id;
           
$output['last_post_username'] = $this->last_post_username;
           
$output['last_thread_id'] = $this->last_thread_id;
           
$output['last_thread_title'] = $this->last_thread_title;
           
$output['last_thread_prefix_id'] = $this->last_thread_prefix_id;

           
$output['LastPostUser'] = $this->LastPostUser;
           
$output['LastThread'] = $this->LastThread;
        }

        return
$output;
    }

   
/**
     * @return string[]
     */
   
public static function getListedWith()
    {
       
$with = ['LastPostUser', 'LastThread'];

       
$visitor = \XF::visitor();
        if (
$visitor->user_id)
        {
           
$with[] = "LastThread.Read|{$visitor->user_id}";
        }

        return
$with;
    }

   
/**
     * @param string[] $options
     *
     * @return \XF\Api\Result\EntityResult
     */
   
public function getNodeTypeApiData($verbosity = self::VERBOSITY_NORMAL, array $options = [])
    {
       
$result = parent::getNodeTypeApiData();

       
$result->includeExtra([
           
'discussion_count' => $this->discussion_count,
           
'message_count' => $this->message_count
       
]);

        if (
$this->last_post_date && $this->LastThread->canView())
        {
           
$result->includeExtra([
               
'last_post_id' => $this->last_post_id,
               
'last_post_date' => $this->last_post_date,
               
'last_post_username' => $this->last_post_username,
               
'last_thread_id' => $this->last_thread_id,
               
'last_thread_title' => $this->last_thread_title,
               
'last_thread_prefix_id' => $this->last_thread_prefix_id
           
]);
        }

        return
$result;
    }

    public function
isCacheRebuildNeeded(): bool
   
{
        return !
$this->Cache || $this->Cache->isExpired();
    }

   
/**
     * @param User $user
     * @param bool $isRebuildPending
     *
     * @return \XF\Entity\SearchForumUserCache
     */
   
public function getUserCacheForUser(User $user, bool $isRebuildPending = false): SearchForumUserCache
   
{
       
$userCache = $this->UserCaches[$user->user_id] ?? null;
        if (!
$userCache)
        {
           
/** @var \XF\Entity\SearchForumUserCache $userCache */
           
$userCache = $this->_em->create('XF:SearchForumUserCache');
           
$userCache->node_id = $this->node_id;
           
$userCache->user_id = $user->user_id;

           
$forceCache = true;
        }
        else
        {
           
$forceCache = false;
        }

       
$updateResults = (
            !
$userCache->exists()
            || (
$userCache->isExpired() && !$isRebuildPending)
        );
        if (
$updateResults)
        {
           
$userCache->results = $this->getSearchForumRepo()->getThreadIdsForUserCache($this, $user);
        }

        if (!
$isRebuildPending)
        {
           
// only save if we're not in the process of updating the global cache since this will potentially be
            // based on out of date info
           
try
            {
               
$userCache->saveIfChanged();
            }
            catch (\
XF\Db\DuplicateKeyException $e)
            {
               
$newUserCache = $this->_em->findOne('XF:SearchForumUserCache', [
                   
'node_id' => $this->node_id,
                   
'user_id' => $user->user_id
               
]);
                if (
$newUserCache)
                {
                   
$userCache = $newUserCache;
                   
$forceCache = true;
                }
            }
        }

        if (
$forceCache)
        {
           
$this->UserCaches->forceCache($userCache);
        }

        return
$userCache;
    }

   
/**
     * @return array
     */
   
public function getDefaultSearchCriteria(): array
    {
        return [
           
'discussion_state' => 'visible',
           
'posted_in_last' => ['unit' => 'day'],
           
'last_post_in_last' => ['unit' => 'day'],
           
'thread_type' => 'any'
       
];
    }

    protected function
_postSave()
    {
        if (
$this->isInsert() || $this->areSearchColumnsChanged())
        {
            \
XF::runLater(function()
            {
               
$this->rebuildResultCaches();
            });
        }
    }

    protected function
_postDelete()
    {
       
$this->deleteResultCaches();
    }

   
/**
     * @return bool
     */
   
protected function areSearchColumnsChanged(): bool
   
{
        return
$this->isChanged([
           
'search_criteria',
           
'sort_order',
           
'sort_direction',
           
'max_results'
       
]);
    }

    protected function
rebuildResultCaches()
    {
       
$this->getSearchForumRepo()->rebuildThreadsForSearchForum($this);
    }

    protected function
deleteResultCaches()
    {
       
$this->db()->delete(
           
'xf_search_forum_cache',
           
'node_id = ?',
           
$this->node_id
       
);

       
$this->db()->delete(
           
'xf_search_forum_cache_user',
           
'node_id = ?',
           
$this->node_id
       
);
    }

   
/**
     * @return Structure
     */
   
public static function getStructure(Structure $structure)
    {
       
$structure->table = 'xf_search_forum';
       
$structure->shortName = 'XF:SearchForum';
       
$structure->primaryKey = 'node_id';
       
$structure->columns = [
           
'node_id' => [
               
'type' => self::UINT,
               
'required' => true
           
],
           
'search_criteria' => [
               
'type' => self::JSON_ARRAY,
               
'default' => []
            ],
           
'sort_order' => [
               
'type' => self::STR,
               
'default' => 'last_post_date',
               
'allowedValues' => [
                   
'title',
                   
'post_date',
                   
'reply_count',
                   
'view_count',
                   
'last_post_date'
               
]
            ],
           
'sort_direction' => [
               
'type' => self::STR,
               
'default' => 'desc',
               
'allowedValues' => ['asc', 'desc']
            ],
           
'max_results' => [
               
'type' => self::UINT,
               
'default' => 200,
               
'min' => 20,
               
'max' => 1000
           
],
           
'cache_ttl' => [
               
'type' => self::UINT,
               
'default' => 10,
               
'min' => 1,
               
'max' => 1440
           
],
           
'discussion_count' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'message_count' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'last_post_id' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'last_post_date' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'last_post_user_id' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'last_post_username' => [
               
'type' => self::STR,
               
'default' => '',
               
'maxLength' => 50
           
],
           
'last_thread_id' => [
               
'type' => self::UINT,
               
'default' => 0
           
],
           
'last_thread_title' => [
               
'type' => self::STR,
               
'default' => '',
               
'maxLength' => 150,
               
'censor' => true
           
],
           
'last_thread_prefix_id' => [
               
'type' => self::UINT,
               
'default' => 0
           
]
        ];
       
$structure->getters = [];
       
$structure->relations = [
           
'Cache' => [
               
'entity' => 'XF:SearchForumCache',
               
'type' => self::TO_ONE,
               
'conditions' => 'node_id',
               
'primary' => true
           
],
           
'UserCaches' => [
               
'entity' => 'XF:SearchForumUserCache',
               
'type' => self::TO_MANY,
               
'conditions' => 'node_id',
               
'key' => 'user_id'
           
],
           
'LastPost' => [
               
'entity' => 'XF:Post',
               
'type' => self::TO_ONE,
               
'conditions' => [['post_id', '=', '$last_post_id']],
               
'primary' => true
           
],
           
'LastPostUser' => [
               
'entity' => 'XF:User',
               
'type' => self::TO_ONE,
               
'conditions' => [['user_id', '=', '$last_post_user_id']],
               
'primary' => true
           
],
           
'LastThread' => [
               
'entity' => 'XF:Thread',
               
'type' => self::TO_ONE,
               
'conditions' => [['thread_id', '=', '$last_thread_id']],
               
'primary' => true
           
]
        ];

        static::
addDefaultNodeElements($structure);

        return
$structure;
    }

   
/**
     * @return \XF\Repository\SearchForum
     */
   
protected function getSearchForumRepo()
    {
        return
$this->repository('XF:SearchForum');
    }
}