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

namespace XF\Entity;

use
XF\Mvc\Entity\Structure;

use function
intval, is_array;

/**
 * @property \XF\Entity\ReactionContent[] Reactions
 */
trait ReactionTrait
{
    abstract public function
canReact(&$error = null);

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

       
/** @var ReactionContent $reactionContent */
       
$reactionContent = $this->Reactions[$visitor->user_id] ?? null;

        return (
$reactionContent && $reactionContent->isReactionActive());
    }

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

        if (!isset(
$this->Reactions[$visitor->user_id]))
        {
            return
null;
        }

        return
$this->Reactions[$visitor->user_id]->reaction_id;
    }

   
/**
     * @return null|ReactionContent
     */
   
public function getReactionContent()
    {
        if (!
$this->isReactedTo())
        {
            return
null;
        }

        return
$this->Reactions[\XF::visitor()->user_id];
    }

    public function
getReactions()
    {
       
$sourceValue = $this->getValueSourceEncoded('reactions');

        if (!
$sourceValue)
        {
            return [];
        }

        if (!
is_array(@json_decode($sourceValue, true)))
        {
           
// legacy data, just a number, convert to an array assuming the number is the count of likes (reaction ID 1)
           
return [
               
'1' => intval($sourceValue)
            ];
        }

       
$reactions = $this->reactions_;
       
arsort($reactions, SORT_NUMERIC);

       
$reactionsCache = $this->app()->container('reactions');

        foreach (
$reactions AS $reactionId => $reaction)
        {
            if (!isset(
$reactionsCache[$reactionId]) || !$reactionsCache[$reactionId]['active'])
            {
                unset(
$reactions[$reactionId]);
                continue;
            }
        }

        return
$reactions;
    }

    public function
getReactionUsers()
    {
       
$reactionUsers = $this->reaction_users_;
        if (
$reactionUsers === null)
        {
            return [];
        }

       
$reactionsCache = $this->app()->container('reactions');

        foreach (
$reactionUsers AS $key => $user)
        {
            if (!isset(
$user['reaction_id']))
            {
               
// likely legacy data with no reaction_id so this relates to a default like so just carry on.
               
continue;
            }

            if (!isset(
$reactionsCache[$user['reaction_id']]) || !$reactionsCache[$user['reaction_id']]['active'])
            {
                unset(
$reactionUsers[$key]);
                continue;
            }
        }

        return
array_values($reactionUsers); // to ensure array is re-indexed from 0
   
}

   
/**
     * @param \XF\Api\Result\EntityResult $result
     *
     * @api-out bool $is_reacted_to True if the viewing user has reacted to this content
     * @api-out int $visitor_reaction_id If the viewer reacted, the ID of the reaction they used
     */
   
protected function addReactionStateToApiResult(\XF\Api\Result\EntityResult $result)
    {
       
$visitor = \XF::visitor();

        if (
$visitor->user_id)
        {
           
$isReactedTo = $this->isReactedTo();
           
$result->is_reacted_to = $isReactedTo;
            if (
$isReactedTo)
            {
               
$result->visitor_reaction_id = $this->getVisitorReactionId();
            }
        }
    }

    public static function
addReactableStructureElements(Structure $structure)
    {
       
$structure->columns['reaction_score'] = ['type' => self::INT, 'default' => 0, 'api' => true];
       
$structure->columns['reactions'] = ['type' => self::JSON_ARRAY, 'default' => []];
       
$structure->columns['reaction_users'] = ['type' => self::JSON_ARRAY, 'default' => []];

       
$structure->relations['Reactions'] = [
           
'entity' => 'XF:ReactionContent',
           
'type' => self::TO_MANY,
           
'conditions' => [
                [
'content_type', '=', $structure->contentType],
                [
'content_id', '=', '$' . $structure->primaryKey]
            ],
           
'key' => 'reaction_user_id',
           
'order' => 'reaction_date'
       
];

       
$structure->getters['reactions'] = true;
       
$structure->getters['reaction_users'] = true;

       
$structure->columnAliases['likes'] = 'reaction_score';
       
$structure->columnAliases['like_users'] = 'reaction_users';

        if (isset(
$structure->withAliases['api']))
        {
           
$structure->withAliases['api'][] = function()
            {
               
$visitorId = \XF::visitor()->user_id;
                if (
$visitorId)
                {
                    return
'Reactions|' . $visitorId;
                }
            };
        }
    }
}