Вход Регистрация
Файл: 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 != -&& $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 != -&& ($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 != -&& $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 != -&& $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 && !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;
    }
}
Онлайн: 3
Реклама