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

namespace XF\Entity;

use
XF\Mvc\Entity\Entity;
use
XF\Mvc\Entity\Structure;

use function
intval;

/**
 * COLUMNS
 * @property int|null $message_id
 * @property int $conversation_id
 * @property int $message_date
 * @property int $user_id
 * @property string $username
 * @property string $message
 * @property int $attach_count
 * @property int $ip_id
 * @property array|null $embed_metadata
 * @property int $reaction_score
 * @property array $reactions_
 * @property array $reaction_users_
 *
 * GETTERS
 * @property mixed $Unfurls
 * @property mixed $reactions
 * @property mixed $reaction_users
 *
 * RELATIONS
 * @property \XF\Entity\ConversationMaster $Conversation
 * @property \XF\Entity\User $User
 * @property \XF\Mvc\Entity\AbstractCollection|\XF\Entity\Attachment[] $Attachments
 * @property \XF\Mvc\Entity\AbstractCollection|\XF\Entity\ReactionContent[] $Reactions
 */
class ConversationMessage extends Entity implements LinkableInterface, QuotableInterface, \XF\BbCode\RenderableContentInterface
{
    use
ReactionTrait;

    public function
canView(&$error = null)
    {
        if (!\
XF::visitor()->user_id || !$this->Conversation || !$this->Conversation->canView($error))
        {
            return
false;
        }

        return
true;
    }

    public function
canEdit(&$error = null)
    {
       
/** @var \XF\Entity\ConversationMaster $conversation */
       
$conversation = $this->Conversation;
       
$visitor = \XF::visitor();
        if (!
$visitor->user_id || !$conversation)
        {
            return
false;
        }

        if (!
$conversation->conversation_open)
        {
           
$error = \XF::phraseDeferred('conversation_is_closed');
            return
false;
        }

        if (
$visitor->hasPermission('conversation', 'editAnyMessage'))
        {
            return
true;
        }

        if (
$this->user_id == $visitor->user_id && $visitor->hasPermission('conversation', 'editOwnMessage'))
        {
           
$editLimit = $visitor->hasPermission('conversation', 'editOwnMessageTimeLimit');
            if (
$editLimit != -1 && (!$editLimit || $this->message_date < \XF::$time - 60 * $editLimit))
            {
               
$error = \XF::phraseDeferred('message_edit_time_limit_expired', ['minutes' => $editLimit]);
                return
false;
            }

            return
true;
        }

        return
false;
    }

    public function
canReport(&$error = null, User $asUser = null)
    {
       
$asUser = $asUser ?: \XF::visitor();
        return
$asUser->canReport($error);
    }

    public function
canReact(&$error = null)
    {
       
$visitor = \XF::visitor();
        if (!
$visitor->user_id)
        {
            return
false;
        }

        if (
$this->user_id == $visitor->user_id)
        {
           
$error = \XF::phraseDeferred('reacting_to_your_own_content_is_considered_cheating');
            return
false;
        }

        return
$visitor->hasPermission('conversation', 'react');
    }

    public function
canCleanSpam()
    {
        return (\
XF::visitor()->canCleanSpam() && $this->User && $this->User->isPossibleSpammer());
    }

    public function
isUnread($lastRead = null)
    {
        if (
$lastRead === null)
        {
           
$user = \XF::visitor();
        }
        else if (
$lastRead instanceof User)
        {
           
$user = $lastRead;
           
$lastRead = null;
        }
        else
        {
           
$user = null;
           
$lastRead = intval($lastRead);
        }

        if (
$user)
        {
            if (!isset(
$this->Conversation->Recipients[$user->user_id]))
            {
                return
false;
            }
           
$lastRead = $this->Conversation->Recipients[$user->user_id]->last_read_date;
        }

        return (
$lastRead < $this->message_date);
    }

    public function
isAttachmentEmbedded($attachmentId)
    {
        if (!
$this->embed_metadata)
        {
            return
false;
        }

        if (
$attachmentId instanceof Attachment)
        {
           
$attachmentId = $attachmentId->attachment_id;
        }

        return isset(
$this->embed_metadata['attachments'][$attachmentId]);
    }

    public function
isIgnored()
    {
        return \
XF::visitor()->isIgnoring($this->user_id);
    }

    public function
getQuoteWrapper($inner)
    {
        return
'[QUOTE="'
           
. ($this->User ? $this->User->username : $this->username)
            .
', convMessage: ' . $this->message_id
           
. ($this->User ? ", member: $this->user_id" : '')
            .
'"]'
           
. "\n" . $inner . "\n"
           
. "[/QUOTE]\n";
    }

    public function
getBbCodeRenderOptions($context, $type)
    {
        return [
           
'entity' => $this,
           
'user' => $this->User,
           
'attachments' => $this->attach_count ? $this->Attachments : [],
           
'viewAttachments' => true,
           
'unfurls' => $this->Unfurls ?: []
        ];
    }

    public function
getUnfurls()
    {
        return
$this->_getterCache['Unfurls'] ?? [];
    }

    public function
setUnfurls($unfurls)
    {
       
$this->_getterCache['Unfurls'] = $unfurls;
    }

    protected function
_postSave()
    {
       
$this->updateConversationRecord();
    }

    protected function
updateConversationRecord()
    {
        if (!
$this->Conversation || !$this->Conversation->exists())
        {
           
// inserting a conversation, don't try to write to it
           
return;
        }

        if (
$this->isInsert())
        {
           
$this->Conversation->messageAdded($this);
           
$this->Conversation->save();
        }
    }

   
/**
     * @param \XF\Api\Result\EntityResult $result
     * @param int $verbosity
     * @param array $options
     *
     * @api-out str $username
     * @api-out bool $is_unread <cond> If accessing as a user, true if this conversation message is unread
     * @api-out str $message_parsed HTML parsed version of the message contents.
     * @api-out bool $can_edit
     * @api-out bool $can_react
     * @api-out str $view_url
     * @api-out Conversation $Conversation <cond> If requested by context, the conversation this message is part of.
     * @api-out Attachment[] $Attachments <cond> If there are attachments to this message, a list of attachments.
     * @api-see XF\Entity\ReactionTrait::addReactionStateToApiResult
     */
   
protected function setupApiResultData(
        \
XF\Api\Result\EntityResult $result, $verbosity = self::VERBOSITY_NORMAL, array $options = []
    )
    {
       
$result->username = $this->User ? $this->User->username : $this->username;

       
$visitor = \XF::visitor();

        if (
$visitor->user_id)
        {
           
$result->is_unread = $this->isUnread();
        }

        if (!empty(
$options['with_conversation']))
        {
           
$result->includeRelation('Conversation');
        }

        if (
$this->attach_count)
        {
           
$result->includeRelation('Attachments');
        }

       
$result->message_parsed = $this->app()->bbCode()->render($this->message, 'apiHtml', 'conversation_message:api', $this);

       
$this->addReactionStateToApiResult($result);

       
$result->can_edit = $this->canEdit();
       
$result->can_react = $this->canReact();

       
$result->view_url = $this->getContentUrl(true);
    }

    public function
getContentUrl(bool $canonical = false, array $extraParams = [], $hash = null)
    {
       
$route = $canonical ? 'canonical:conversations/messages' : 'conversations/messages';
        return
$this->app()->router('public')->buildLink($route, $this, $extraParams, $hash);
    }

    public function
getContentPublicRoute()
    {
        return
'conversations/messages';
    }

    public function
getContentTitle(string $context = '')
    {
        return \
XF::phrase('conversation_message_from_x', ['username' => $this->username]);
    }

    public static function
getStructure(Structure $structure)
    {
       
$structure->table = 'xf_conversation_message';
       
$structure->shortName = 'XF:ConversationMessage';
       
$structure->primaryKey = 'message_id';
       
$structure->contentType = 'conversation_message';
       
$structure->columns = [
           
'message_id' => ['type' => self::UINT, 'autoIncrement' => true, 'nullable' => true],
           
'conversation_id' => ['type' => self::UINT, 'required' => true, 'api' => true],
           
'message_date' => ['type' => self::UINT, 'default' => \XF::$time, 'api' => true],
           
'user_id' => ['type' => self::UINT, 'required' => true, 'api' => true],
           
'username' => ['type' => self::STR, 'maxLength' => 50, 'required' => true, 'api' => true],
           
'message' => ['type' => self::STR,
               
'required' => 'please_enter_valid_message', 'api' => true
           
],
           
'attach_count' => ['type' => self::UINT, 'max' => 65535, 'default' => 0, 'api' => true],
           
'ip_id' => ['type' => self::UINT, 'default' => 0],
           
'embed_metadata' => ['type' => self::JSON_ARRAY, 'nullable' => true, 'default' => null],
        ];
       
$structure->getters = [
           
'Unfurls' => true
       
];
       
$structure->relations = [
           
'Conversation' => [
               
'entity' => 'XF:ConversationMaster',
               
'type' => self::TO_ONE,
               
'conditions' => 'conversation_id',
               
'primary' => true
           
],
           
'User' => [
               
'entity' => 'XF:User',
               
'type' => self::TO_ONE,
               
'conditions' => 'user_id',
               
'primary' => true,
               
'api' => true
           
],
           
'Attachments' => [
               
'entity' => 'XF:Attachment',
               
'type' => self::TO_MANY,
               
'conditions' => [
                    [
'content_type', '=', 'conversation_message'],
                    [
'content_id', '=', '$message_id']
                ],
               
'with' => 'Data',
               
'order' => 'attach_date'
           
]
        ];

       
$structure->withAliases = [
           
'full' => [
               
'User',
               
'User.Profile',
               
'User.Privacy',
                function()
                {
                    if (\
XF::options()->showMessageOnlineStatus)
                    {
                        return
'User.Activity';
                    }
                },
                function()
                {
                   
$userId = \XF::visitor()->user_id;
                    if (
$userId)
                    {
                        return
'Reactions|' . $userId;
                    }

                    return
null;
                }
            ],
           
'api' => [
               
'User',
               
'User.api',
               
'Conversation.api'
           
]
        ];

        static::
addReactableStructureElements($structure);

        return
$structure;
    }
}