<?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);
}
}