View file MMO-Hide-2.3.4/upload/src/addons/MMO/Hide/BbCode/AbstractTag.php

File size: 6.84Kb
<?php

namespace MMO\Hide\BbCode;

use Carbon\Carbon;
use XF\App;
use XF\BbCode\Renderer\AbstractRenderer;
use XF\BbCode\Renderer\EmailHtml;
use XF\Mvc\Entity\Entity;
use XF\PreEscaped;
use XF\Util\Arr;

abstract class AbstractTag
{
    /**
     * @var App
     */
    protected App $app;

    /**
     * @var AbstractRenderer
     */
    protected $renderer;

    /**
     * @var \XF\Template\Templater
     */
    protected $templater;

    /**
     * @param App $app
     * @param AbstractRenderer $renderer
     */
    public function __construct(App $app, AbstractRenderer $renderer = null)
    {
        $this->app = $app;
        $this->renderer = $renderer;
        $this->templater = $app->templater();
    }

    /**
     * @param $content
     * @param array $tagChildren
     * @param $tagOption
     * @param array $tag
     * @param array $options
     * @return mixed
     */
    abstract public function render($content, array $tagChildren, $tagOption, array $tag, array $options);

    protected function getTitleVisible(string $phraseBase, array $params = []): string
    {
        return \XF::phrase($phraseBase . '.visible', $params)->render('raw');
    }

    protected function getTitleHidden(string $phraseBase, array $params = []): string
    {
        return \XF::phrase($phraseBase . '.hidden', $params)->render('raw');
    }

    /**
     * @param $content
     * @param $title
     * @param array $hide
     *
     * @return string
     */
    public function renderTemplate($content, $title, array $hide)
    {
        $template = $this->renderer instanceof EmailHtml ? 'email:mh_bb_code_hide' : 'public:mh_bb_code_hide';

        $visitor = $this->visitor();
        $tag = ucfirst($hide['tag']);

        $canBypassTag = $visitor->canBypassHideTag($tag);
        $canIgnoreOld = false;

        if (isset($hide['options']['entity']) &&
            ($hide['options']['entity'] instanceof Entity))
        {
            /** @var Entity $entity */
            $entity = $hide['options']['entity'];
            if($entity->isValidRelation('Thread'))
            {
                $postDate = $entity->post_date;
                $lastEdit = $entity->last_edit_date;

                $timeLimitPost = $this->options()->mhHideExpiration;
                $tags = Arr::stringToArray(\XF::options()->mhHideRestrictedTags);
                $isRestrictedTag = \in_array($hide['tag'], $tags);
                if ($timeLimitPost['enabled'] && !$isRestrictedTag)
                {
                    $carbonNow = Carbon::now();
                    $compareDate = $lastEdit > $postDate ? $lastEdit : $postDate;
                    $carbonCompareDate = Carbon::createFromTimestamp($compareDate);
                    $daysDifference = $carbonNow->diffInDays($carbonCompareDate);
                    $canIgnoreOld = $daysDifference >= $timeLimitPost['length'];
                }

                /** @var \XF\Entity\Thread $thread */
                $thread = $entity->getRelation('Thread');
                $canBypassTag = $visitor->canBypassHideTag($tag, $thread->node_id);
            }
        }

        $visible = $hide['canView']
            || $this->isCreator($hide['options'])
            || $visitor->canBypassAnyTag()
            || $canIgnoreOld
            || $canBypassTag;
        if (is_array($title) && isset($title['visible'], $title['hidden']))
        {
            $finalTitle = $visible ? $title['visible'] : $title['hidden'];
        }
        else
        {
            $finalTitle = $title;
        }

        return $this->templater->renderTemplate($template, [
            'tag' => $hide['tag'],
            'visible' => $visible,
            'content' => new PreEscaped($content),
            'title' => $finalTitle ? new PreEscaped($finalTitle) : ''
        ]);
    }

    /**
     * @param $tagChildren
     * @param $tagOption
     * @param $tag
     * @param array $options
     * @param AbstractRenderer $renderer
     *
     * @return string
     */
    public static function renderHide($tagChildren, $tagOption, $tag, array $options, AbstractRenderer $renderer)
    {
        $tagRenderer = new static(\XF::app(), $renderer);
        /** @var AbstractRenderer $content */
        $content = $renderer instanceof EmailHtml ? false : $renderer->renderSubTree($tagChildren, $options);
        if ($content === '')
        {
            return '';
        }

        $tags = Arr::stringToArray(\XF::options()->mhHideRegisterOrAuthTags);
        if(!\XF::visitor()->user_id && !\in_array($tag['tag'], $tags))
        {
            return $renderer->getTemplater()->renderTemplate('public:mh_hide_auth_or_register');
        }

        return $tagRenderer->render($content, $tagChildren, $tagOption, $tag, $options);
    }

    /**
     * @param $options
     * @return bool
     */
    public function isCreator($options): bool
    {
        $visitor = \XF::visitor();
        if (isset($options['user_id']))
        {
            return $options['user_id'] === $visitor->user_id;
        }

        if (!empty($options['entity']['user_id']))
        {
            return $options['entity']['user_id'] === $visitor->user_id;
        }
        else
        {
            return false;
        }
    }

    /**
     * @return \XF\Entity\User|\MMO\Hide\XF\Entity\User
     */
    public function visitor()
    {
        return \XF::visitor();
    }

    /**
     * @return \ArrayObject
     */
    public function options()
    {
        return \XF::options();
    }

    /**
     * @return \XF\Mvc\Entity\Manager
     */
    public function em()
    {
        return $this->app->em();
    }

    /**
     * @template T of \XF\Mvc\Entity\Repository
     *
     * @param class-string<T> $repository
     *
     * @return T
     */
    public function repository($repository)
    {
        return $this->app->repository($repository);
    }

    /**
     * @template T of \XF\Mvc\Entity\Finder
     *
     * @param class-string<T> $identifier
     *
     * @return T
     */
    public function finder($finder)
    {
        return $this->app->finder($finder);
    }

    /**
     * @template T of Entity
     *
     * @param class-string<T> $shortName
     * @param mixed $id
     * @param array|string|null $with
     *
     * @return T|null
     */
    public function find($shortName, $id, $with = null)
    {
        return $this->app->em()->find($shortName, $id, $with);
    }

    /**
     * @template T of Entity
     *
     * @param class-string<T> $shortName
     * @param array $where
     * @param array|string|null $with
     *
     * @return T|null
     */
    public function findOne($finder, array $where, $with = null)
    {
        return $this->app->em()->findOne($finder, $where, $with);
    }
}