Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/Message/Preparer.php
<?php

namespace XF\Service\Message;

use
XF\Mvc\Entity\Entity;

use function
count, strlen;

class
Preparer extends \XF\Service\AbstractService
{
    protected
$context;

   
/**
     * @var Entity|null
     */
   
protected $messageEntity;

   
/**
     * @var \XF\BbCode\Processor
     */
   
protected $bbCodeProcessor;

    protected
$filters = [
       
'autolink' => true,
       
'mentions' => true,
       
'markdown' => true,
       
'shortToEmoji' => true,
       
'structuredText' => false
   
];

    protected
$attachments = [];

    protected
$quotes = [];

    protected
$mentionedUsers = [];

    protected
$unfurls = [];

    protected
$isValid = false;

    protected
$errors = [];

    protected
$constraints = [
       
'maxLength' => 0,
       
'maxImages' => 0,
       
'maxMedia' => 0,
       
'allowEmpty' => false
   
];

    public function
__construct(\XF\App $app, $context, Entity $messageEntity = null)
    {
       
$this->context = $context;
       
$this->messageEntity = $messageEntity;
       
parent::__construct($app);
    }

    protected function
setup()
    {
       
$options = $this->app->options();

       
$this->setConstraints([
           
'maxLength' => $options->messageMaxLength,
           
'maxImages' => $options->messageMaxImages,
           
'maxMedia' => $options->messageMaxMedia
       
]);
    }

    public function
getMessageEntity()
    {
        return
$this->messageEntity;
    }

    public function
setMessageEntity(Entity $messageEntity = null)
    {
       
$this->messageEntity = $messageEntity;
    }

    public function
setConstraint($key, $value)
    {
       
$this->constraints[$key] = $value;

        return
$this;
    }

    public function
getConstraint($key)
    {
        return
$this->constraints[$key] ?? null;
    }

    public function
setConstraints(array $constraints)
    {
       
$this->constraints = array_replace($this->constraints, $constraints);

        return
$this;
    }

    public function
disableAllFilters()
    {
        foreach (
$this->filters AS $key => $value)
        {
           
$this->filters[$key] = false;
        }

        return
$this;
    }

    public function
disableFilter($key)
    {
        if (isset(
$this->filters[$key]))
        {
           
$this->filters[$key] = false;
        }

        return
$this;
    }

    public function
enableFilter($key)
    {
        if (isset(
$this->filters[$key]))
        {
           
$this->filters[$key] = true;
        }

        return
$this;
    }

    public function
prepare($message, $checkValidity = true)
    {
       
$message = $this->processMessage($message);

        if (
$checkValidity)
        {
           
$this->checkValidity($message);
        }
        else
        {
           
$this->isValid = true;
        }

       
/** @var \XF\BbCode\ProcessorAction\AnalyzeUsage $usage */
       
$usage = $this->bbCodeProcessor->getAnalyzer('usage');

       
/** @var \XF\BbCode\ProcessorAction\MentionUsers|null $mentions */
       
$mentions = $this->bbCodeProcessor->getFilterer('mentions');

       
$this->attachments = $usage->getAttachments();
       
$this->quotes = $usage->getQuotes();
       
$this->mentionedUsers = $mentions ? $mentions->getMentionedUsers() : [];
       
$this->unfurls = $usage->getUnfurls();

        return
$message;
    }

    protected function
processMessage($message)
    {
       
$this->bbCodeProcessor = $this->getBbCodeProcessor();

       
$bbCodeContainer = $this->app->bbCode();

       
$renderContext = $this->context . ':prepare';
       
$options = $bbCodeContainer->getFullRenderOptions($this->messageEntity, $renderContext, null);

        return
$this->bbCodeProcessor->render(
           
$message,
           
$bbCodeContainer->parser(),
           
$bbCodeContainer->rules($renderContext),
           
$options
       
);
    }

    protected function
getBbCodeProcessor()
    {
       
$bbCodeContainer = $this->app->bbCode();

       
$processor = $bbCodeContainer->processor();

       
$processor->addProcessorAction('usage', $bbCodeContainer->processorAction('usage'));

        if (
$this->filters['mentions'])
        {
           
$processor->addProcessorAction('mentions', $bbCodeContainer->processorAction('mentions'));
        }
        if (
$this->filters['markdown'])
        {
           
$processor->addProcessorAction('markdown', $bbCodeContainer->processorAction('markdown'));
        }
        if (
$this->filters['autolink'])
        {
           
$processor->addProcessorAction('autolink', $bbCodeContainer->processorAction('autolink'));
        }
        if (
$this->filters['shortToEmoji'])
        {
           
$processor->addProcessorAction('shortToEmoji', $bbCodeContainer->processorAction('shortToEmoji'));
        }
        if (
$this->filters['structuredText'])
        {
           
$processor->addProcessorAction('structuredText', $bbCodeContainer->processorAction('structuredText'));
        }

        return
$processor;
    }

    public function
getEmbeddedAttachments()
    {
        return
$this->attachments;
    }

    public function
getEmbeddedUnfurls()
    {
        return
$this->unfurls;
    }

    public function
getEmbedMetadata()
    {
       
$metadata = [];

        if (
$this->attachments)
        {
           
$metadata['attachments'] = $this->attachments;
        }

        if (
$this->unfurls)
        {
           
$metadata['unfurls'] = $this->unfurls;
        }

        return
$metadata;
    }

    public function
getQuotes()
    {
        return
$this->quotes;
    }

    public function
getQuotesKeyed($key)
    {
       
$quotes = [];
        foreach (
$this->quotes AS $quote)
        {
            if (isset(
$quote[$key]))
            {
               
$quotes[$quote[$key]] = $quote;
            }
        }

        return
$quotes;
    }

    public function
getMentionedUsers()
    {
        return
$this->mentionedUsers;
    }

    public function
checkValidity($message)
    {
       
$this->errors = [];

       
/** @var \XF\BbCode\ProcessorAction\AnalyzeUsage $usage */
       
$usage = $this->bbCodeProcessor->getAnalyzer('usage');

       
$maxLength = $this->constraints['maxLength'];
        if (
$maxLength && utf8_strlen($message) > $maxLength)
        {
           
$this->errors[] = \XF::phraseDeferred(
               
'please_enter_message_with_no_more_than_x_characters',
                [
'count' => $maxLength]
            );
        }

       
$maxImages = $this->constraints['maxImages'];
        if (
$maxImages && $usage->getTagCount('img') > $maxImages)
        {
           
$this->errors[] = \XF::phraseDeferred(
               
'please_enter_message_with_no_more_than_x_images',
                [
'count' => $maxImages]
            );
        }

       
$maxMedia = $this->constraints['maxMedia'];
        if (
$maxMedia && $usage->getTagCount('media') > $maxMedia)
        {
           
$this->errors[] = \XF::phraseDeferred(
               
'please_enter_message_with_no_more_than_x_media',
                [
'count' => $maxMedia]
            );
        }

        if (!
$this->constraints['allowEmpty'])
        {
           
$rendered = $this->app->bbCode()->render(
               
$message, 'simpleHtml', $this->context . ':prepare', $this->messageEntity
           
);
            if (!
strlen(trim($rendered)))
            {
               
$this->errors[] = \XF::phraseDeferred('please_enter_valid_message');
            }
        }

       
$this->isValid = (count($this->errors) == 0);

        return
$this->isValid;
    }

    public function
isValid()
    {
        return
$this->isValid;
    }

    public function
pushEntityErrorIfInvalid(\XF\Mvc\Entity\Entity $entity, $fieldName = 'message')
    {
        if (!
$this->isValid())
        {
           
$entity->error($this->getFirstError(), $fieldName);
            return
false;
        }
        else
        {
            return
true;
        }
    }

    public function
getErrors()
    {
        return
$this->errors;
    }

    public function
getFirstError()
    {
        return
reset($this->errors);
    }
}