Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/ControllerPlugin/Reaction.php
<?php

namespace XF\ControllerPlugin;

use
XF\Entity\ReactionTrait;
use
XF\Mvc\Entity\Entity;

use function
count;

class
Reaction extends AbstractPlugin
{
    public function
actionReactSimple(Entity $content, $contentRoute)
    {
        return
$this->actionReact($content, $contentRoute, "$contentRoute/react", "$contentRoute/reactions");
    }

    public function
actionReact(Entity $content, $contentRoute, $actionRoute, $listRoute)
    {
        if (
$this->isPost())
        {
            return
$this->actionToggleReaction($content, $listRoute, $contentRoute);
        }
        else
        {
            return
$this->actionConfirmReaction($content, $actionRoute, $contentRoute);
        }
    }

   
/**
     * @param Entity|ReactionTrait $content
     * @param string|array $actionRoute
     * @param string|array $contentRoute
     *
     * @throws \XF\Mvc\Reply\Exception
     */
   
public function actionConfirmReaction(Entity $content, $actionRoute, $contentRoute)
    {
       
$reaction = $this->validateReactionAction($content, $existingReaction);

       
$isUnreact = ($existingReaction && $existingReaction->reaction_id == $reaction->reaction_id);

       
$viewParams = [
           
'confirmUrl' => $this->buildLink($actionRoute, $content),
           
'reaction' => $reaction,
           
'isUnreact' => $isUnreact
       
];
        return
$this->view('XF:Reaction\Confirm', 'reaction_confirm', $viewParams);
    }

   
/**
     * @param Entity|ReactionTrait $content
     * @param string|array $listRoute Route to display the reactions for this content; if array, use: [route, params as array]
     * @param string|array $contentRoute Route to return to the content
     *
     * @return \XF\Mvc\Reply\View
     * @throws \XF\Mvc\Reply\Exception
     */
   
public function actionToggleReaction(Entity $content, $listRoute, $contentRoute)
    {
       
$requestedReaction = $this->validateReactionAction($content);

       
$reaction = $this->getReactionRepo()->reactToContent(
           
$requestedReaction->reaction_id,
           
$content->getEntityContentType(),
           
$content->getEntityId(),
            \
XF::visitor(),
           
true
       
);

        if (
$this->filter('_xfWithData', 'bool'))
        {
           
$viewParams = [
               
'reaction' => $reaction ?: $this->app->container('reactionDefault'),
               
'content' => $content,
               
'link' => $listRoute
           
];
           
$reply = $this->view('XF:Reaction\React', '', $viewParams);

            if (
$reaction)
            {
               
$reply->setJsonParams([
                   
'reactionId' => $reaction['reaction_id'],
                   
'linkReactionId' => $reaction['reaction_id']
                ]);
            }
            else
            {
               
$reactionDefault = $this->app->container('reactionDefault');

               
$reply->setJsonParams([
                   
'reactionId' => null,
                   
'linkReactionId' => $reactionDefault['reaction_id']
                ]);
            }

            return
$reply;
        }
        else
        {
            throw
$this->exception(
               
$this->redirect(
                   
$this->buildLink($contentRoute, $content)
                )
            );
        }
    }

   
/**
     * @param Entity|ReactionTrait $content
     * @param null|\XF\Entity\ReactionContent Existing reaction if there is one
     *
     * @return \XF\Entity\Reaction
     */
   
protected function validateReactionAction(Entity $content, &$existingReaction = null)
    {
       
$existingReaction = null;

        if (!
$content->canReact($error))
        {
            throw
$this->exception($this->noPermission($error));
        }

       
$reactionId = $this->filter('reaction_id', 'uint');
        if (!
$reactionId)
        {
            throw
$this->exception($this->notFound());
        }

       
$visitor = \XF::visitor();

       
$contentType = $content->getEntityContentType();
       
$contentId = $content->getEntityId();

        if (!
$contentType)
        {
            throw new \
InvalidArgumentException("Provided entity must define a content type in its structure");
        }

       
/** @var \XF\Entity\Reaction $reaction */
       
$reaction = $this->em()->find('XF:Reaction', $reactionId);
        if (!
$reaction)
        {
            throw
$this->exception($this->notFound());
        }

       
$reactRepo = $this->getReactionRepo();
       
$existingReaction = $reactRepo->getReactionByContentAndReactionUser(
           
$contentType, $contentId, $visitor->user_id
       
);

        if (!
$reaction->active)
        {
            if (!
$existingReaction || $existingReaction->reaction_id != $reaction->reaction_id)
            {
                throw
$this->exception($this->notFound());
            }
        }

        return
$reaction;
    }

    public function
actionReactions(Entity $content, $link, $title = null, array $breadcrumbs = [], array $linkParams = [])
    {
       
$contentType = $content->getEntityContentType();
       
$contentId = $content->getEntityId();

        if (!
$contentType)
        {
            throw new \
InvalidArgumentException("Provided entity must defined a content type in its structure");
        }

       
$reactionRepo = $this->getReactionRepo();

       
$page = $this->filterPage();
       
$perPage = 50;

       
$reactionId = $this->filter('reaction_id', 'uint');

       
$reactionsFinder = $reactionRepo->findContentReactions($contentType, $contentId, $reactionId)
            ->
limitByPage($page, $perPage, 1);

       
$reactions = $reactionsFinder->fetch();

        if (!
count($reactions))
        {
            return
$this->message(\XF::phrase('no_one_has_reacted_to_this_content_yet'));
        }

       
$hasNext = count($reactions) > $perPage;
       
$reactions = $reactions->slice(0, $perPage);

       
$tabSummary = $reactionRepo->getContentTabSummary($contentType, $contentId);

       
$viewParams = [
           
'type' => $contentType,
           
'id' => $contentId,

           
'content' => $content,
           
'link' => $link,
           
'linkParams' => $linkParams,

           
'tabSummary' => $tabSummary,

           
'activeReactionId' => $reactionId,
           
'reactions' => $reactions,
           
'hasNext' => $hasNext,
           
'page' => $page,

           
'title' => $title,
           
'breadcrumbs' => $breadcrumbs,

           
'listOnly' => $this->filter('list_only', 'bool')
        ];
        return
$this->view('XF:Reaction\Listing', 'reaction_list', $viewParams);
    }

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