Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/User/SignatureEdit.php
<?php

namespace XF\Service\User;

use
XF\Entity\User;

use function
count;

class
SignatureEdit extends \XF\Service\AbstractService
{
   
/**
     * @var User
     */
   
protected $user;

    protected
$perms = [
       
'basic' => true,
       
'extended' => true,
       
'align' => true,
       
'link' => true,
       
'image' => true,
       
'media' => true,
       
'block' => true,
       
'list' => true,
       
'smilie' => true,

       
'maxPrintable' => -1,
       
'maxLines' => -1,
       
'maxLinks' => -1,
       
'maxImages' => -1,
       
'maxSmilies' => -1,
       
'maxTextSize' => -1
   
];

    protected
$permTagMap = [
       
'basic' => ['b', 'i', 'u', 's'],
       
'extended' => ['color', 'font', 'size', 'icode', 'heading'],
       
'align' => ['left', 'center', 'right', 'indent'],
       
'link' => ['url', 'email', 'user'],
       
'image' => ['img', 'attach'],
       
'media' => ['media'],
       
'block' => ['code', 'php', 'html', 'quote', 'spoiler', 'table', 'tr', 'th', 'td', 'hr'],
       
'list' => ['list']
    ];

    protected
$signature;

    protected
$skipSpamCheck = false;
    protected
$allowAutoLink = true;

    public function
__construct(\XF\App $app, User $user)
    {
       
parent::__construct($app);
       
$this->setUser($user);
    }

    public function
setUser(User $user)
    {
       
$this->user = $user;
       
$this->applyPermissions();
    }

   
/**
     * @return User
     */
   
public function getUser()
    {
        return
$this->user;
    }

    protected function
applyPermissions()
    {
       
$user = $this->user;

       
$this->perms['basic'] = $user->hasPermission('signature', 'basicText');
       
$this->perms['extended'] = $user->hasPermission('signature', 'extendedText');
       
$this->perms['align'] = $user->hasPermission('signature', 'align');
       
$this->perms['link'] = $user->hasPermission('signature', 'link');
       
$this->perms['image'] = $user->hasPermission('signature', 'image');
       
$this->perms['media'] = $user->hasPermission('signature', 'media');
       
$this->perms['block'] = $user->hasPermission('signature', 'block');
       
$this->perms['list'] = $user->hasPermission('signature', 'list');

       
$this->perms['maxPrintable'] = $user->hasPermission('signature', 'maxPrintable');
       
$this->perms['maxLines'] = $user->hasPermission('signature', 'maxLines');
       
$this->perms['maxTextSize'] = $user->hasPermission('signature', 'maxTextSize');

       
$this->perms['maxLinks'] = $user->hasPermission('signature', 'maxLinks');
        if (!
$this->perms['maxLinks'])
        {
           
$this->perms['link'] = false;
        }

       
$this->perms['maxImages'] = $user->hasPermission('signature', 'maxImages');
        if (!
$this->perms['maxImages'])
        {
           
$this->perms['image'] = false;
        }

       
$this->perms['maxSmilies'] = $user->hasPermission('signature', 'maxSmilies');
       
$this->perms['smilie'] = $this->perms['maxSmilies'] != 0;
    }

    public function
getDisabledEditorButtons()
    {
       
$disabled = [];

        if (!
$this->perms['basic'])
        {
           
$disabled[] = '_basic';
        }
        if (!
$this->perms['extended'])
        {
           
$disabled[] = '_extended';
        }
        if (!
$this->perms['link'])
        {
           
$disabled[] = '_link';
        }
        if (!
$this->perms['align'])
        {
           
$disabled[] = '_align';
           
$disabled[] = '_indent';
        }
        if (!
$this->perms['list'])
        {
           
$disabled[] = '_list';
           
$disabled[] = '_indent';
        }
        if (!
$this->perms['smilie'])
        {
           
$disabled[] = '_smilies';
        }
        if (!
$this->perms['image'])
        {
           
$disabled[] = '_image';
        }
        if (!
$this->perms['media'])
        {
           
$disabled[] = '_media';
        }
        if (!
$this->perms['block'])
        {
           
$disabled[] = '_block';
        }

        foreach (
$this->app->bbCode()->get('custom') AS $tag => $info)
        {
            if (!
$info['allow_signature'])
            {
               
// make sure this matches with the name in editor.js
               
$disabled[] = 'xfCustom_' . $tag;
            }
        }

        return
$disabled;
    }

    public function
setSkipSpamCheck($skip)
    {
       
$this->skipSpamCheck = (bool)$skip;

        return
$this;
    }

    public function
setSignature($signature, &$errors = [])
    {
       
$signature = trim($signature);
        if (
$signature === '')
        {
           
$this->signature = $signature;
            return
true;
        }

       
$bbCodeContainer = $this->app->bbCode();
       
$parser = $bbCodeContainer->parser();
       
$rules = $bbCodeContainer->rules('user:signature');

       
$processor = $bbCodeContainer->processor();
       
$usage = $bbCodeContainer->processorAction('usage');

       
/** @var \XF\BbCode\ProcessorAction\LimitTags $limit */
       
$limit = $bbCodeContainer->processorAction('limit');

       
$this->setupBbCodeLimits($limit);

       
$processor->addProcessorAction('usage', $usage)
            ->
addProcessorAction('limit', $limit);

        if (
$this->allowAutoLink && $this->perms['link'])
        {
           
/** @var \XF\BbCode\ProcessorAction\AutoLink $autoLinker */
           
$autoLinker = $bbCodeContainer->processorAction('autolink');
           
$autoLinker->enableUnfurling(false);

           
$processor->addProcessorAction('autolink', $autoLinker);
        }

       
$renderOptions = [
           
'user' => $this->user
       
];

       
$signature = $processor->render($signature, $parser, $rules, $renderOptions);

        if (
$limit->hasDisabledTags())
        {
           
$limit->setStripDisabled(false);
           
$signature = $processor->render($signature, $parser, $rules, $renderOptions);
        }

        if (!
$this->validateSignature($signature, $processor, $errors))
        {
           
$this->signature = null;
            return
false;
        }

        if (!
$this->skipSpamCheck && $this->user->isSpamCheckRequired())
        {
           
$checker = $this->app->spam()->contentChecker();
           
$checker->check($this->user, $signature, [
               
'content_type' => 'user_signature'
           
]);

            switch (
$checker->getFinalDecision())
            {
                case
'moderated':
                case
'denied':
                   
$checker->logSpamTrigger('user_signature', $this->user->user_id);
                   
$errors[] = \XF::phrase('your_content_cannot_be_submitted_try_later');

                   
$this->signature = null;
                    return
false;
            }
        }

       
$this->signature = $signature;

        return
true;
    }

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

    public function
save()
    {
       
$profile = $this->user->Profile;
        if (!
$profile)
        {
            throw new \
LogicException("User profile record missing");
        }

        if (
$this->signature === null)
        {
            return
false;
        }

       
$profile->signature = $this->signature;
       
$profile->save();

        return
true;

    }

    protected function
setupBbCodeLimits(\XF\BbCode\ProcessorAction\LimitTags $limit)
    {
        foreach (
$this->permTagMap AS $perm => $disabledTags)
        {
            if (!
$this->perms[$perm])
            {
               
$limit->disableTag($disabledTags);
            }
        }

        foreach (
$this->app->bbCode()->get('custom') AS $tag => $info)
        {
            if (!
$info['allow_signature'])
            {
               
$limit->disableTag($tag);
            }
        }

       
$limit->setMaxTextSize($this->perms['maxTextSize']);
    }

    protected function
validateSignature($signature, \XF\BbCode\Processor $processor, &$errors = [])
    {
       
$errors = [];

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

       
$maxPrintable = $this->perms['maxPrintable'];
        if (
$maxPrintable != -1 && $usage->getPrintableLength() > $maxPrintable)
        {
           
$diff = $usage->getPrintableLength() - $maxPrintable;
           
$errors[] = \XF::phraseDeferred('your_signature_is_x_characters_too_long', ['count' => $diff]);
        }

       
$maxLines = $this->perms['maxLines'];
        if (
$maxLines != -1)
        {
           
$bbCodeContainer = $this->app->bbCode();
           
$parser = $bbCodeContainer->parser();
           
$rules = $bbCodeContainer->rules('user:signature');
           
/** @var \XF\BbCode\Renderer\SimpleHtml $renderer */
           
$renderer = $bbCodeContainer->renderer('simpleHtml');

           
$options = $bbCodeContainer->getFullRenderOptions(
               
$this->user, 'user:signature', 'simpleHtml', ['allowUnfurl' => false]
            );

           
$lines = $renderer->countLines($signature, $parser, $rules, $options);
            if (
$lines > $maxLines)
            {
               
$diff = $lines - $maxLines;
               
$errors[] = \XF::phraseDeferred('your_signature_is_x_liness_too_long', ['count' => $diff]);
            }
        }

       
$maxLinks = $this->perms['maxLinks'];
       
$linkCount = $usage->getTagCount('url') + $usage->getTagCount('email');
        if (
$maxLinks != -1 && $linkCount > $maxLinks)
        {
           
$errors[] = \XF::phraseDeferred('your_signature_may_only_have_x_links', ['count' => $maxLinks]);
        }

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

       
$maxSmilies = $this->perms['maxSmilies'];
        if (
$maxSmilies != -1 && $usage->getSmilieCount() > $maxSmilies)
        {
           
$errors[] = \XF::phraseDeferred('your_signature_may_only_have_x_smilies', ['count' => $maxSmilies]);
        }

       
/** @var \XF\BbCode\ProcessorAction\LimitTags $limit */
       
$limit = $processor->getFilterer('limit');
        if (
$limit->hasDisabledTags())
        {
           
$errors[] = \XF::phraseDeferred('your_signature_may_not_contain_disabled_tags');
        }

        return
count($errors) == 0;
    }
}