Вход Регистрация
Файл: library/XenForo/BbCode/Formatter/BbCode/Filter.php
Строк: 300
<?php

/**
 * Filters BB codes based on rules. BB codes violating these rules will be stripped.
 *
 * @package XenForo_BbCode
 */
class XenForo_BbCode_Formatter_BbCode_Filter extends XenForo_BbCode_Formatter_BbCode_Abstract
{
    
/**
     * Callback for all tags.
     *
     * @var callback
     */
    
protected $_generalTagCallback = array('$this', 'filterTag');

    protected 
$_disabledTags = array();

    protected 
$_nonPrintableTags = array('img', 'media');

    protected 
$_maxTextSize = -1;

    protected 
$_tagTally = array();
    protected 
$_smilieTally = 0;
    protected 
$_printableLength = 0;

    public function 
disableTags($tags)
    {
        if (!
is_array($tags))
        {
            
$tags = array($tags);
        }

        
$this->_disabledTags = array_merge($this->_disabledTags, $tags);
    }

    public function 
setMaxTextSize($value)
    {
        
$value = intval($value);
        if (
$value == 0)
        {
            
$this->disableTags('size');
        }
        
$this->_maxTextSize = $value;
    }

    public function 
configureFromSignaturePermissions(array $perms)
    {
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'basicText'))
        {
            
$this->disableTags(array('b', 'i', 'u', 's'));
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'extendedText'))
        {
            
$this->disableTags(array('color', 'font', 'size'));
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'align'))
        {
            
$this->disableTags(array('left', 'center', 'right', 'indent'));
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'link') || !XenForo_Permission::hasPermission($perms, 'signature', 'maxLinks'))
        {
            
$this->disableTags(array('url', 'email'));
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'image') || !XenForo_Permission::hasPermission($perms, 'signature', 'maxImages'))
        {
            
$this->disableTags('img');
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'media'))
        {
            
$this->disableTags('media');
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'block'))
        {
            
$this->disableTags(array('code', 'php', 'html', 'quote', 'spoiler'));
        }
        if (!
XenForo_Permission::hasPermission($perms, 'signature', 'list'))
        {
            
$this->disableTags('list');
        }

        foreach (
$this->_tags AS $tagName => $tag)
        {
            if (isset(
$tag['allowSignature']) && !$tag['allowSignature'])
            {
                
$this->disableTags($tagName);
            }
        }

        
$this->setMaxTextSize(XenForo_Permission::hasPermission($perms, 'signature', 'maxTextSize'));
    }

    public function 
validateAsSignature($bbCode, array $perms, &$errors = array())
    {
        
$errors = array();

        
$length = XenForo_Permission::hasPermission($perms, 'signature', 'maxPrintable');
        if (
$length != -1 && $this->getPrintableLength() > $length)
        {
            
$diff = $this->getPrintableLength() - $length;
            
$errors[] = new XenForo_Phrase('your_signature_is_x_characters_too_long', array('count' => XenForo_Locale::numberFormat($diff)));
        }

        
$lines = XenForo_Permission::hasPermission($perms, 'signature', 'maxLines');
        if (
$lines != -1)
        {
            
$parser = XenForo_BbCode_Parser::create(XenForo_BbCode_Formatter_Base::create('XenForo_BbCode_Formatter_Base'));
            
$html = $parser->render($bbCode, array(
                
'spoilerTextWithFallback' => true
            
));

            
$processed = preg_replace('#<br />s*<(div|p|pre|ul|ol|blockquote)#i', '<$1', $html);
            
$processed = preg_replace('#(<(ul|ol)[^>]*>)s*<li[^>]*>#i', '$1', $processed);
            
$processed = preg_replace('#</li>s*(</(ul|ol)>)#i', '$1', $processed);
            
$processed = preg_replace('#</?(div|p|pre|ul|ol|li|blockquote)[^>]*>s*<(div|p|pre|ul|ol|li|blockquote)[^>]*>#i', '<br />', $processed);
            
$processed = preg_replace('#</?(div|p|pre|ul|ol|li|blockquote)[^>]*>#i', '<br />', $processed);
            
$processed = preg_replace('#^(<br[^>]*>)+#i', '', $processed);
            
$processed = preg_replace('#(<br[^>]*>)+$#i', '', $processed);

            
$lineCount = substr_count($processed, '<br') + 1;

            if (
$lineCount > $lines)
            {
                
$diff = $lineCount - $lines;
                
$errors[] = new XenForo_Phrase('your_signature_is_x_liness_too_long', array('count' => XenForo_Locale::numberFormat($diff)));
            }
        }

        
$links = XenForo_Permission::hasPermission($perms, 'signature', 'maxLinks');
        if (
$links != -1 && ($this->getTagTally('url') + $this->getTagTally('email')) > $links)
        {
            
$errors[] = new XenForo_Phrase('your_signature_may_only_have_x_links', array('count' => XenForo_Locale::numberFormat($links)));
        }

        
$images = XenForo_Permission::hasPermission($perms, 'signature', 'maxImages');
        if (
$images != -1 && $this->getTagTally('img') > $images)
        {
            
$errors[] = new XenForo_Phrase('your_signature_may_only_have_x_images', array('count' => XenForo_Locale::numberFormat($images)));
        }

        
$smilies = XenForo_Permission::hasPermission($perms, 'signature', 'maxSmilies');
        if (
$smilies != -1 && $this->getSmilieTally() > $smilies)
        {
            
$errors[] = new XenForo_Phrase('your_signature_may_only_have_x_smilies', array('count' => XenForo_Locale::numberFormat($smilies)));
        }

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

    
/**
     * Callback that all tags with go through. Filters tags as necessary.
     *
     * @param array $tag
     * @param array $rendererStates

     * @return string
     */
    
public function filterTag(array $tag, array $rendererStates)
    {
        
$rendererStates['parentTag'] = $tag['tag'];

        
$tag = $this->_manipulateTag($tag, $rendererStates);

        
$text = $this->renderSubTree($tag['children'], $rendererStates);

        
$this->_tallyTags($tag, $text);

        
// non-printable tags shouldn't count
        
if (in_array($tag['tag'], $this->_nonPrintableTags))
        {
            
$this->_printableLength -= $this->_getPrintableLength($text, $rendererStates);
        }

        if (
in_array($tag['tag'], $this->_disabledTags))
        {
            return 
$this->_handleDisabledTag($tag, $text, $rendererStates);
        }

        if (!empty(
$tag['original']) && is_array($tag['original']))
        {
            list(
$prepend, $append) = $tag['original'];
        }
        else
        {
            
$prepend = '';
            
$append = '';
        }

        
// note: necessary to return prepend/append unfiltered to keep them unchanged
        
return $prepend . $text . $append;
    }

    protected function 
_getPrintableLength($text, array $rendererStates)
    {
        if (!empty(
$rendererStates['parentTag']) && $rendererStates['parentTag'] == 'list')
        {
            
$text = preg_replace('/n?[*]/', '', $text);
        }

        
$text = preg_replace('/r?n/', '', $text);

        return 
utf8_strlen($text);
    }

    protected function 
_handleDisabledTag(array $tag, $text, array $rendererStates)
    {
        if (
in_array($tag['tag'], $this->_nonPrintableTags))
        {
            return 
'';
        }

        if (
$tag['tag'] == 'list')
        {
            
$text = preg_replace('/n?[*]/', "n", $text);
        }

        return 
$text;
    }

    protected function 
_manipulateTag(array $tag, array $rendererStates)
    {
        if (
$tag['tag'] == 'size' && $this->_maxTextSize > 0 && !empty($tag['option']))
        {
            
$s = $tag['option'];

            if (
strval(intval($s)) == strval($s))
            {
                
// size is just an int
                
if ($s > $this->_maxTextSize)
                {
                    
$tag['option'] = $this->_maxTextSize;
                    if (!empty(
$tag['original']))
                    {
                        
$tag['original'][0] = preg_replace(
                            
'/(=|'|")s*' . preg_quote($s, '/') . 's*('|"|])/',
                            '
${1}' . $this->_maxTextSize . '${2}',
                            $tag['
original'][0]
                        );
                    }
                }
            }
            else
            {
                // not a size we can reliably parse - ignore it
                $tag['
original'] = false;
            }
        }

        return $tag;
    }

    protected function _tallyTags(array $tag, $text)
    {
        if (isset($this->_tagTally[$tag['
tag']]))
        {
            $this->_tagTally[$tag['
tag']]++;
        }
        else
        {
            $this->_tagTally[$tag['
tag']] = 1;
        }
    }

    public function filterString($string, array $rendererStates)
    {
        if (empty($rendererStates['
stopSmilies']) && $this->_smilieTranslate)
        {
            $translated = strtr($string, $this->_smilieTranslate);
            $this->_smilieTally += preg_match_all("#\0(d+)\0#", $translated, $null);
        }

        $this->_printableLength += $this->_getPrintableLength($string, $rendererStates);

        return parent::filterString($string, $rendererStates);
    }

    public function getTagTally($tag)
    {
        return isset($this->_tagTally[$tag]) ? $this->_tagTally[$tag] : 0;
    }

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

    public function getPrintableLength()
    {
        return $this->_printableLength;
    }
}
Онлайн: 2
Реклама