Вход Регистрация
Файл: admin/sources/classes/editor/class_editor_rte.php
Строк: 862
<?php

/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.3.3
 * Editor Library: RTE (WYSIWYG) Class
 * Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
 * </pre>
 *
 * @author         $Author: bfarber $
 * @copyright    (c) 2001 - 2009 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @link        http://www.invisionpower.com
 * @since        9th March 2005 11:03
 * @version        $Revision: 10721 $
 */

if ( ! defined'IN_IPB' ) )
{
    print 
"<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
    exit();
}

class 
class_editor_module extends class_editor
{
    
/**
     * Clean up HTML on save
     *
     * @access    public
     * @var        boolean
     */
    
public $clean_on_save        true;
    
    
/**
     * Allow HTML
     *
     * @access    public
     * @var        boolean
     */
    
public $allow_html            false;
    
    
/**
     * Debug level
     *
     * @access    public
     * @var        integer
     */
    
public $debug                0;
    
    
/**
     * Parsing array
     *
     * @access    public
     * @var        array
     */
    
public $delimiters            = array( "'"'"' );
    
    
/**
     * Parsing array
     *
     * @access    public
     * @var        array
     */
    
public $non_delimiters        = array( "="' ' );
    
    
/**
     * Start tags
     *
     * @access    public
     * @var        array
     */
    
public $start_tags            = array();
    
    
/**
     * End tags
     *
     * @access    public
     * @var        array
     */
    
public $end_tags                = array();

    
/**
     * Process the content before showing it in the form
     *
     * @access    public
     * @param    string        Raw text
     * @return    string        Text ready for editor
     */
    
public function processBeforeForm$t )
    {
        
//-----------------------------------------
        // Remove comments
        //-----------------------------------------

        
$t preg_replace"#<!--(.+?)-->#is"""$t );
        
        
//-----------------------------------------
        // Trim
        //-----------------------------------------
        
        
$t rtrim($t);
                
        
//-------------------------------
        // Convert all types of single quotes
        //-------------------------------
        
        
if ( strtolower(IPS_DOC_CHAR_SET) != 'utf-8' )
        {
            
$t str_replace(chr(145), chr(39), $t);
            
$t str_replace(chr(146), chr(39), $t);
        }
        
        
$t str_replace"'""&#39;"$t);
        
        
//-------------------------------
        // Convert all types of double quotes
        //-------------------------------
        
        
if ( strtolower(IPS_DOC_CHAR_SET) != 'utf-8' )
        {        
            
$t str_replace(chr(147), chr(34), $t);
            
$t str_replace(chr(148), chr(34), $t);
        }
        
        
$t str_replace"t""{'tab'}"$t );
        
        
//-------------------------------
        // Replace carriage returns & line feeds
        // These used to replace with spaces, but that causes
        // additional spaces to keep adding up when submitting/previewing/editing
        // Need to monitor this to ensure it doesn't cause bugs as I'm not sure
        // why this replaced rn with spaces previously
        // @see http://forums.invisionpower.com/tracker/issue-17869-rtf-editor-problems/
        //-------------------------------

        
if ( $this->memberData['userAgentKey'] == 'firefox' OR $this->memberData['userAgentKey'] == 'gecko' )
        {
            
$t str_ireplace"<br>rn""<br>"$t );
            
$t str_ireplace"<br>n""<br>"$t );
            
$t str_ireplace"<br>r""<br>"$t );
            
$t str_ireplace"<br />rn""<br />"$t );
            
$t str_ireplace"<br />n""<br />"$t );
            
$t str_ireplace"<br />r""<br />"$t );
            
//$t = preg_replace( "/((?:r)?n?(?:[r|n|t| ])+)/", " ", $t );
            
$t preg_replace"/((?:r)?n+)/u"" "$t );

        }
        else
        {
            
$t str_replace(chr(10), ""$t);
            
$t str_replace(chr(13), ""$t);
        }
        
        
//-----------------------------------------
        // Clean up code tags
        //-----------------------------------------

        
$t preg_replace_callback"#[(code)](.+?)[/code]#is", array( $this'_cleanCodeTag' ), $t );
        
$t preg_replace_callback"#[(sql)](.+?)[/sql]#is", array( $this'_cleanCodeTag' ), $t );
        
$t preg_replace_callback"#[(html)](.+?)[/html]#is", array( $this'_cleanCodeTag' ), $t );
        
$t preg_replace_callback"#[(xml)](.+?)[/xml]#is", array( $this'_cleanCodeTag' ), $t );
        
$t preg_replace_callback"#[(codebox)](.+?)[/codebox]#is", array( $this'_cleanCodeTag' ), $t );
        
        
//-----------------------------------------
        // RTE and script don't mix because of other entities
        //-----------------------------------------
        
        
$t    str_replace'&#60;''&lt;'$t );
        
$t    str_replace'&#6e;''&gt;'$t );

        
//-----------------------------------------
        // Clean up quote tags (remove many <br />s
        //-----------------------------------------
        
        
$t preg_replace"#([quote([^]]+?)])(<br />){1,}#is""\1<br />"$t );
        
        
//-----------------------------------------
        // Replace tabs
        //-----------------------------------------
        
        
$t str_replace"{'tab'}""&nbsp;&nbsp;&nbsp; "$t );
        
        
//-----------------------------------------
        // Clean up the rest of the tags
        //-----------------------------------------
        
        
$t str_replace( array( '&lt;br&gt;''&lt;br /&gt;' ), '<br />'IPSText::htmlspecialchars$t ) );
        
        
//-----------------------------------------
        // Fix up stuff
        //-----------------------------------------
        
        
$t str_replace"&lt;#IMG_DIR#&gt;""<#IMG_DIR#>"$t );
        
$t str_replace"&lt;#EMO_DIR#&gt;""<#EMO_DIR#>"$t );
        
        
//-----------------------------------------
        // Convert multiple spaces
        //-----------------------------------------
        
        
$t str_replace"  ""&nbsp;&nbsp;"$t );

        return 
$t;
    }
    
    
/**
     * Clean up content inside the code tag
     *
     * @access    protected
     * @param    array        Matches from preg_replace_callback
     * @return    string        Text ready for editor
     */
    
protected function _cleanCodeTag$matches )
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------

        
$tag $matches[1];
        
$txt $matches[2];
        
        
//-----------------------------------------
        // Fix...
        //-----------------------------------------

        //$txt = str_replace( "&lt;br&gt;"    , "n"   , $txt );
        //$txt = str_replace( "&lt;br /&gt;"  , "n"   , $txt );
        
$txt str_replace"<br>"          "n"   $txt );
        
$txt str_replace"<br />"        "n"   $txt );
        
$txt str_replace"<"             "&lt;" $txt );
        
$txt str_replace">"             "&gt;" $txt );
        
$txt str_replace"&#60;"         "&lt;" $txt );
        
$txt str_replace"&#62;"         "&gt;" $txt );

        return 
'[' $tag ']' nl2br($txt) . '[/' $tag ']';
    }
    
    
/**
     * Process the content before passing off to the bbcode library
     *
     * @access    public
     * @param    string        Form field name OR Raw text
     * @return    string        Text ready for editor
     */
    
public function processAfterForm$form_field$isDefinitelyFullText=false )
    {
        
$t    = ( $isDefinitelyFullText ) ? $form_field : ( isset( $_POST$form_field ] ) ? IPSText::stripslashes($_POST$form_field ]) : $form_field );
        
$ot    $t;

        
//print $t;
        //print "<br><br><br>---------------------<br><br><br>";
        //print nl2br(htmlspecialchars($t));
        //print "<br><br><br>---------------------<br><br><br>";

        //-----------------------------------------
        // Fix up tabs/spaces
        //-----------------------------------------
    
        
$t str_replace'&nbsp;&nbsp;&nbsp; '"{'tab'}"$t );
        
$t str_replace'&nbsp;'' '$t );
        
//print htmlspecialchars($t);print "<br><br><br>---------------------<br><br><br>";
        //-----------------------------------------
        // Fix up lines for safari...
        //-----------------------------------------
        
        
if ( $this->memberData['userAgentKey'] == 'safari' OR $this->memberData['userAgentKey'] == 'chrome' )
        {
            
$t    str_replace"<div><br></div>""<br />"$t );
            
$t    str_replace"<div>""<br />"$t );
        }

        
//-----------------------------------------
        // Gecko engine seems to put rn at edge
        // of iframe when wrapping? If so, add a 
        // space or it'll get weird later
        //-----------------------------------------

        
if ( $this->memberData['userAgentKey'] == 'firefox' OR $this->memberData['userAgentKey'] == 'gecko' )
        {
            
$t str_ireplace"<br>rn""<br>"$t );
            
$t str_ireplace"<br>n""<br>"$t );
            
$t str_ireplace"<br>r""<br>"$t );
            
$t str_ireplace"<br />rn""<br />"$t );
            
$t str_ireplace"<br />n""<br />"$t );
            
$t str_ireplace"<br />r""<br />"$t );
            
//$t = preg_replace( "/((?:r)?n?(?:[r|n|t| ])+)/", " ", $t );
            
$t preg_replace"/((?:r)?n+)/u"" "$t );

        }
        else
        {
            
$t str_replace"rn"""$t );
        }

        
//-----------------------------------------
        // RTE sends newlines as line break tags
        //-----------------------------------------
        
        
$t str_replace"n"""$t );

        
//-----------------------------------------
        // Clean up already encoded HTML
        //-----------------------------------------
        
        
$t str_replace'&quot;''"'$t );
        
$t str_replace'&apos;'"'"$t );
        
        
//-----------------------------------------
        // Fix up incorrectly nested urls / BBcode
        //-----------------------------------------
        
        // @link    http://community.invisionpower.com/tracker/issue-24704-pasting-content-in-rte-with-image-first/
        // Revert the fix for now as it causes more issues than the original one
        
$t preg_replace'#<as+?href=['"]([^>]+?)[(.+?)['"](.+?)'.'>(.+?)[\2</a>#is', '<a href="\1"\3>\4</a>[\2', $t );
        //$t = preg_replace( '#<as+?href=['"]([^>'"]+?)['"](.*?)>(.+?)[([^<]+?)</a>#is', '<a href="\1">\3</a>[\4', $t );

        //-----------------------------------------
        // Make URLs safe (prevent tag stripping)
        //-----------------------------------------

        
$t preg_replace_callback'#<(a href|img src)=(['"])([^>]+?)(\2)#is', array( $this, '_unhtmlUrl' ), $t );

        //-----------------------------------------
        // WYSI-Weirdness #1: BR tags to n
        //-----------------------------------------
    
        
$t = str_ireplace( array( "<br>", "<br />" ), "n", $t );
        
        
$t = trim( $t );
        
        //-----------------------------------------
        // Before we can use strip_tags, we should
        // clean out any javascript and CSS
        //-----------------------------------------
        
        
$t    = preg_replace( "/<script(.*?)>(.*?)</script>/", '', $t );
        
$t    = preg_replace( "/<style(.*?)>(.*?)</style>/", '', $t );
        
        //-----------------------------------------
        // Remove tags we're not bothering with
        // with PHPs wonderful strip tags func
        //-----------------------------------------
        
        if ( ! 
$this->allow_html )
        {
            
$t = strip_tags( $t, '<h1><h2><h3><h4><h5><h6><font><span><div><br><p><img><a><li><ol><ul><b><strong><em><i><u><s><strike><blockquote><sub><sup>' );
        }

        //-----------------------------------------
        // WYSI-Weirdness #2: named anchors
        //-----------------------------------------
        
        
$t = preg_replace( "#<as+?name=.+?".">(.+?)</a>#is", "\1", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #2.1: Empty a hrefs
        //-----------------------------------------
        
        
$t preg_replace"#<as+?href([^>]+)></a>#is"         ""   $t );
        
$t preg_replace"#<as+?href=(['"])>\1(.+?)</a>#is", "\1", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #2.2: Double linked links
        //-----------------------------------------
        
        
$t preg_replace"#href=["']w+://(%27|'|"|&quot;)(.+?)\1["']#is", "href="\2"", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #3: Headline tags
        //-----------------------------------------
        
        $t = preg_replace( "#<(h[0-9])(?:[^>]+?)?>(.+?)</\1>#is", "n[b]\2[/b]n", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #4: Font tags
        //-----------------------------------------
        
        $t = preg_replace( "#<font (color|size|face)="([a-zA-Z0-9s#-]*?)">(s*)</font>#is", " ", $t );

        //-----------------------------------------
        // WYSI-Weirdness #5a: Fix up smilies: IE RTE
        // @see Ticket 623146
        //-----------------------------------------
        
        $t = preg_replace( "#<img class=(S+?) alt=(S+?) src=["'
](.+?)["']>#i""<img src='\3' class='\1' alt='\2' />"$t );
        
$t preg_replace"#alt='["'](S+?)['"]'#i""alt='\1'"$t );
        
$t preg_replace"#class='["'](S+?)['"]'#i""class='\1'"$t );
        
$t preg_replace"#([a-zA-Z0-9])<img src=["'](.+?)["'] class=["'](.+?)["'] alt=["'](.+?)["'] />#i""\1 <img src='\2' class='\3' alt='\4' />"$t );

        
//-----------------------------------------
        // WYSI-Weirdness #6: Image tags
        //-----------------------------------------
        
        
$t preg_replace"#<img alt=["']["'height=["']d+?["'] width=["']d+?["']s+?/>#"""$t );
        
$t preg_replace"#<img.+?src=["'](.+?)["']([^>]+?)?".">#is", "[img]\1[/img]", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #7: Linked URL tags
        //-----------------------------------------
        
        
$t preg_replace"#[url=("|'|&quot;)<as+?href=["'](.*)/??['"]\2/??</a>#is", "[url=\1\2", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #8: Make relative images full links
        //-----------------------------------------
        
        $t = preg_replace( "#[img](/)?style_(emoticons|images)#i", '
[img]' . $this->settings['board_url'] . '/style_' . '\2', $t );
        
        //-----------------------------------------
        // Now, recursively parse the other tags
        // to make sure we get the nested ones
        //-----------------------------------------
        
        $t = $this->_recurseAndParse( 'b'            , $t, "_parseSimpleTag", 'b' );
        $t = $this->_recurseAndParse( '
u'            , $t, "_parseSimpleTag", 'u' );
        $t = $this->_recurseAndParse( '
strong'        , $t, "_parseSimpleTag", 'b' );
        $t = $this->_recurseAndParse( '
i'            , $t, "_parseSimpleTag", 'i' );
        $t = $this->_recurseAndParse( '
em'            , $t, "_parseSimpleTag", 'i' );
        $t = $this->_recurseAndParse( '
strike'        , $t, "_parseSimpleTag", 's' );
        $t = $this->_recurseAndParse( '
s'            , $t, "_parseSimpleTag", 's' );
        $t = $this->_recurseAndParse( '
blockquote'    , $t, "_parseSimpleTag", 'indent' );
        $t = $this->_recurseAndParse( '
sup'         , $t, "_parseSimpleTag", 'sup' );
        $t = $this->_recurseAndParse( '
sub'            , $t, "_parseSimpleTag", 'sub' );
//print htmlspecialchars($t).'
<br><Br><br>'    ;
        //-----------------------------------------
        // More complex tags
        //-----------------------------------------
        
        $t = $this->_recurseAndParse( '
a'          , $t, "_parseAnchorTag" );
        $t = $this->_recurseAndParse( '
font'       , $t, "_parseFontTag" );
        $t = $this->_recurseAndParse( '
div'        , $t, "_parseDivTag" );
        $t = $this->_recurseAndParse( '
span'       , $t, "_parseSpanTag" );
        $t = $this->_recurseAndParse( '
p'          , $t, "_parseParagraphTag" );
//print htmlspecialchars($t);exit;    
        //-----------------------------------------
        // Lists
        //-----------------------------------------
        
        $t = $this->_recurseAndParse( '
ol'         , $t, "_parseListTag" );
        $t = $this->_recurseAndParse( '
ul'         , $t, "_parseListTag" );
        
        //-----------------------------------------
        // WYSI-Weirdness #9: Fix up para tags
        //-----------------------------------------
        
        $t = str_ireplace( array( "<p>", "<p />" ), "nn", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #10: Random junk
        //-----------------------------------------
        
        $t = str_ireplace( array( "<a>", "</a>", "</li>" ), "", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #11: Fix up list stuff
        //-----------------------------------------
        
        $t = preg_replace( '
#<li>(.*)((?=<li>)|</li>)#is', '\1', $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #11.1: Safari badness
        //-----------------------------------------
        
        
$t    str_replace"</div>"""$t );
        
        
//-----------------------------------------
        // WYSI-Weirdness #12: Convert rest to HTML
        //-----------------------------------------
        
        
$t str_replace(  '&lt;' '<'$t );
        
$t str_replace(  '&gt;' '>'$t );
        
$t str_replace(  '&amp;''&'$t );
        
$t preg_replace'#&amp;(quot|lt|gt);#''&\1;'$t );
        
        
//-----------------------------------------
        // WYSI-Weirdness #13: Remove useless tags
        //-----------------------------------------
        
        
while( preg_match"#[(url|img|b|u|i|s|email|list|indent|right|left|center)][/\1]#is"$t ) )
        {
            
$t preg_replace"#[(url|img|b|u|i|s|email|list|indent|right|left|center)][/\1]#is"""$t );
        }
        
        
//-----------------------------------------
        // WYSI-Weirdness #14: Opera crap
        //-----------------------------------------
        
        
$t preg_replace"#[(font|size|color)]=["']([^"']+?)["']][/\1]#is"""$t );
        
        
//-----------------------------------------
        // WYSI-Weirdness #14.1: Safari crap
        //-----------------------------------------
        
        
$t preg_replace"#[(font|size|color)=&quot;([^"']+?)&quot;][/\1]#is", "", $t );
        
        //-----------------------------------------
        // WYSI-Weirdness #15: No domain in FF?
        //-----------------------------------------    
        
        $t = preg_replace( "#(http|https)://index.php(.*?)#is", $this->settings['
board_url'].'/index.php\2', $t );    
        $t = preg_replace( "#[url=['"]index.php(.*?)["']#is", "[url="".$this->settings['
board_url'].'/index.php\1"', $t );    
        
        //-----------------------------------------
        // Replace tabs
        //-----------------------------------------
        
        
$t = str_replace( "{'tab'}", "t", $t );
        
        //-----------------------------------------
        // Now call the santize routine to make
        // html and nasties safe. VITAL!!
        //-----------------------------------------
        
        
$t = $this->_cleanPost$t );
        //print htmlspecialchars(
$t);exit;    
        //-----------------------------------------
        // Debug?
        //-----------------------------------------
        
        if ( 
$this->debug )
        {
            print "
<pre><hr>";
            print nl2br(htmlspecialchars(
$ot));
            print "
<hr>";
            print nl2br(
$t);
            print "
<hr>";
            exit();
        }

        //print 
$t;
        //print "
<br><br><br>---------------------<br><br><br>";
        //print nl2br(htmlspecialchars(
$t));
        //print "
<br><br><br>---------------------<br><br><br>";
        //exit;
        
        //-----------------------------------------
        // Done
        //-----------------------------------------

        return 
$t;
    }

    /**
     * RTE: Parse List tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseListTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        
$list_type = trim( preg_replace( '#"?list-style-type:s+?([dw_-]+);?"?#si', '\1', $this->_getValueOfOption( 'style', $opening_tag ) ) );
        
        //-----------------------------------------
        // Set up a default...
        //-----------------------------------------
        
        if ( ! 
$list_type and $tag == 'ol' )
        {
            
$list_type = 'decimal';
        }
        
        //-----------------------------------------
        // Tricky regex to clean all list items
        //-----------------------------------------

        
$between_text = preg_replace('#<li>((.(?!</li))*)(?=</?ul|</?ol|[list|<li|[/list)#siU', '<li>\1</li>', $between_text);
        
        
$between_text = $this->_recurseAndParse( 'li', $between_text, "_parseListElement" );
        
        
$allowed_types = array( 'upper-alpha' => 'A',
                                'upper-roman' => 'I',
                                'lower-alpha' => 'a',
                                'lower-roman' => 'i',
                                'decimal'     => '1' );
        
        if ( ! 
$allowed_types[ $list_type ] )
        {
            
$open_tag = '[list]';
        }
        else
        {
            
$open_tag = '[list=' . $allowed_types[ $list_type ] . ']';
        }
        
        return 
$open_tag . $this->_recurseAndParse$tag$between_text, '_parseListTag' ) . '[/list]';
    }

    /**
     * RTE: Parse List Element tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseListElement( 
$tag$between_text$opening_tag$parse_tag )
    {
        return '[*]' . rtrim( 
$between_text );
    }
    
    /**
     * RTE: Parse paragraph tags
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseParagraphTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        //-----------------------------------------
        // Reset local start tags
        //-----------------------------------------
        
        
$start_tags = "";
        
$end_tags   = "";
        
        //-----------------------------------------
        // Check for inline style moz may have added
        //-----------------------------------------
        
        
$this->_parseStyles$opening_tag$start_tags$end_tags );
        
        //-----------------------------------------
        // Now parse align and style (if any)
        //-----------------------------------------
        
        
$align = $this->_getValueOfOption( 'align', $opening_tag );
        
$style = $this->_getValueOfOption( 'style', $opening_tag );
        
        if ( 
$align == 'center' )
        {
            
$start_tags .= '[center]';
            
$end_tags   .= '[/center]';
        }
        else if ( 
$align == 'left' )
        {
            
$start_tags .= '[left]';
            
$end_tags   .= '[/left]';
        }
        else if ( 
$align == 'right' )
        {
            
$start_tags .= '[right]';
            
$end_tags   .= '[/right]';
        }
        else
        {
            # No align? Make paragraph
            
$end_tags .= "n";
        }
        
        
$end_tags .= "n";
        
        return 
$start_tags . $this->_recurseAndParse( 'p', $between_text, '_parseParagraphTag' ) . $end_tags;
    }
    
    /**
     * RTE: Parse Span tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseSpanTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        
$start_tags = "";
        
$end_tags   = "";
        
        //-----------------------------------------
        // Check for inline style moz may have added
        //-----------------------------------------

        
$this->_parseStyles$opening_tag$start_tags$end_tags );
        
        return 
$start_tags . $this->_recurseAndParse( 'span', $between_text, '_parseSpanTag' ) . $end_tags;
    }
    
    /**
     * RTE: Parse DIV tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseDivTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        //-----------------------------------------
        // Reset local start tags
        //-----------------------------------------
        
        
$start_tags = "";
        
$end_tags   = "";
        
        //-----------------------------------------
        // #DEBUG
        //-----------------------------------------
        
        if ( 
$this->debug == 2 )
        {
            print "
<b><span style='color:red'>DIV FIRED</b></span><br />Start tags: {$this->start_tags}<br />End tags: {$this->end_tags}<br />Between text:<br />".htmlspecialchars($between_text)."<hr />";
        }
        
        //-----------------------------------------
        // Check for inline style moz may have added
        //-----------------------------------------
        
        
$this->_parseStyles$opening_tag$start_tags$end_tags );
        
        //-----------------------------------------
        // Now parse align (if any)
        //-----------------------------------------
        
        
$align = $this->_getValueOfOption( 'align', $opening_tag );
        
        if ( 
$align == 'center' )
        {
            
$start_tags .= '[center]';
            
$end_tags   .= '[/center]';
        }
        else if ( 
$align == 'left' )
        {
            
$start_tags .= '[left]';
            
$end_tags   .= '[/left]';
        }
        else if ( 
$align == 'right' )
        {
            
$start_tags .= '[right]';
            
$end_tags   .= '[/right]';
        }

        //-----------------------------------------
        // Get recursive text
        //-----------------------------------------
        
        
$final = $this->_recurseAndParse( 'div', $between_text, '_parseDivTag' );
        
        //-----------------------------------------
        // #DEBUG
        //-----------------------------------------
        
        if ( 
$this->debug == 2 )
        {
            print "
n<hr><b style='color:green'>FINISHED</b><br/ >".$start_tags . $final . $end_tags."<hr>";
        }
        
        //-----------------------------------------
        // Now return
        //-----------------------------------------
        
        return 
$start_tags . $final . $end_tags;
    }
    
    /**
     * RTE: Parse style attributes (color, font, size, b, i..etc)
     *
     * @access    protected
     * @param    string    Opening tag
     * @param    string    Start tags
     * @param    string    End tags
     * @return    string    Converted text
     */
    protected function _parseStyles( 
$opening_tag, &$start_tags, &$end_tags )
    {
        
$style_list = array(
                            array('tag' => 'color' , 'rx' => '(?<![w-])color:s*([^;]+);?'    , 'match' => 1),
                            array('tag' => 'font'  , 'rx' => 'font-family:s*([^;]+);?'        , 'match' => 1),
                            array('tag' => 'size'  , 'rx' => 'font-size:s*(.+);?'            , 'match' => 1),
                            array('tag' => 'b'     , 'rx' => 'font-weight:s*(bold);?'),
                            array('tag' => 'i'     , 'rx' => 'font-style:s*(italic);?'),
                            array('tag' => 'u'     , 'rx' => 'text-decoration:s*(underline);?'),
                            array('tag' => 'left'  , 'rx' => 'text-align:s*(left);?'),
                            array('tag' => 'center', 'rx' => 'text-align:s*(center);?'),
                            array('tag' => 'right' , 'rx' => 'text-align:s*(right);?'),
                          );
        
        //-----------------------------------------
        // get style option
        //-----------------------------------------
        
        
$style = $this->_getValueOfOption( 'style', $opening_tag );

        //-----------------------------------------
        // Convert RGB to hex
        //-----------------------------------------

        
$style = preg_replace_callback( '#(?<![w-])color:s+?rgb((d+,s+?d+,s+?d+))(;?)#i', array( &$this, '_rgbToHex' ), $style );
        
        //-----------------------------------------
        // Pick through possible styles
        //-----------------------------------------
        
        foreach( 
$style_list as $data )
        {
            if ( preg_match( '#' . 
$data['rx'] . '#i', $style$match ) )
            {
                if ( 
$data['match'] )
                {
                    if ( 
$data['tag'] != 'size' )
                    {
                        if( 
$data['tag'] != 'font' OR $match[ $data['match'] ] != 'Verdana, arial, sans-serif' )
                        {
                            
$start_tags .= "[{$data['tag']}={$match[$data['match']]}]";
                        }
                    }
                    else
                    {
                        
$start_tags .= "[{$data['tag']}=" . $this->convertRealsizeToBbsize($match[$data['match']]) ."]";
                    }
                }
                else
                {
                    
$start_tags .= "[{$data['tag']}]";
                }
                
                if( 
$data['tag'] != 'font' OR $match[ $data['match'] ] != 'Verdana, arial, sans-serif' )
                {
                    
$end_tags = "[/{$data['tag']}]" . $end_tags;
                }
            }
        }
    }

    /**
     * RTE: Parse FONT tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseFontTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        
$font_tags  = array( 'font' => 'face', 'size' => 'size', 'color' => 'color' );
        
$start_tags = "";
        
$end_tags   = "";
        
        //-----------------------------------------
        // Check for attributes
        //-----------------------------------------
        
        foreach( 
$font_tags as $bbcode => $string )
        {
            
$option = $this->_getValueOfOption$string$opening_tag );
            
            if ( 
$option )
            {
                
$start_tags .= "[{$bbcode}="{$option}"]";
                
$end_tags    = "[/{$bbcode}]" . $end_tags;
                
                if ( 
$this->debug == 2 )
                {
                    print "
<br />Got bbcode=$bbcode opening_tag=$opening_tag";
                    print "
<br />- Adding [$bbcode="$option"] [/$bbcode]";
                    print "
<br />-- start tags now: {$start_tags}";
                    print "
<br />-- end tags now: {$end_tags}";
                }
            }
        }
        
        //-----------------------------------------
        // Now check for inline style moz may have
        // added
        //-----------------------------------------
        
        
$this->_parseStyles$opening_tag$start_tags$end_tags );
        
        return 
$start_tags . $this->_recurseAndParse( 'font', $between_text, '_parseFontTag' ) . $end_tags;
    }

    /**
     * RTE: Simple tags
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseSimpleTag( 
$tag$between_text$opening_tag$parse_tag )
    {
        if ( ! 
$parse_tag )
        {
            
$parse_tag = $tag;
        }
        
        return "
[{$parse_tag}]" . $this->_recurseAndParse$tag$between_text, '_parseSimpleTag', $parse_tag ) . "[/{$parse_tag}]";
    }

    /**
     * RTE: Parse A HREF tag
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Opening tag complete
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _parseAnchorTag( 
$tag$between_text$opening_tag$parse_tag='' )
    {
        
$mytag = 'url';
        
$href  = $this->_getValueOfOption( 'href', $opening_tag );
        
        
$href  = str_replace( '<', '&lt;', $href );
        
$href  = str_replace( '>', '&gt;', $href );
        
$href  = str_replace( ' ', '%20' , $href );
        
        if ( preg_match( '#^mailto:#is', 
$href ) )
        {
            
$mytag = 'email';
            
$href  = str_replace( "mailto:", "", $href );
        }
        
        return "
[{$mytag}="{$href}"]" . $this->_recurseAndParse$tag$between_text, '_parseAnchorTag', $parse_tag ) . "[/{$mytag}]";
    }

    /**
     * RTE: Recursively parse tags
     *
     * @access    protected
     * @param    string    Tag
     * @param    string    Text between opening and closing tag
     * @param    string    Callback Function
     * @param    string    Parse tag
     * @return    string    Converted text
     */
    protected function _recurseAndParse( 
$tag$text$function$parse_tag='' )
    {
        //-----------------------------------------
        // INIT
        //-----------------------------------------
        
        
$tag              = strtolower($tag);
        
$open_tag         = "<" . $tag;
        
$open_tag_len     = strlen($open_tag);
        
$close_tag        = "</" . $tag . ">";
        
$close_tag_len    = strlen($close_tag);
        
$start_search_pos = 0;
        
$tag_begin_loc    = 1;
        
        //-----------------------------------------
        // Start the loop
        //-----------------------------------------

        while ( 
$tag_begin_loc !== FALSE )
        {
            
$lowtext       = mb_strtolower($text);
            
$tag_begin_loc = @strpos( $lowtext$open_tag$start_search_pos );
            
$lentext       = strlen($text);
            
$quoted        = '';
            
$got           = FALSE;
            
$tag_end_loc   = FALSE;
            
            //-----------------------------------------
            // No opening tag? Break
            //-----------------------------------------
        
            if ( 
$tag_begin_loc === FALSE )
            {
                break;
            }
            
            //-----------------------------------------
            // Pick through text looking for delims
            //-----------------------------------------
            
            for ( 
$end_opt = $tag_begin_loc$end_opt <= $lentext$end_opt++ )
            {
                
$chr = $text{$end_opt};
                
                //-----------------------------------------
                // We're now in a quote
                //-----------------------------------------
                
                if ( ( in_array( 
$chr$this->delimiters ) ) AND $quoted == '' )
                {
                    
$quoted = $chr;
                }
                
                //-----------------------------------------
                // We're not in a quote any more
                //-----------------------------------------
                
                else if ( ( in_array( 
$chr$this->delimiters ) ) AND $quoted == $chr )
                {
                    
$quoted = '';
                }
                
                //-----------------------------------------
                // Found the closing bracket of the open tag
                //-----------------------------------------
                
                else if ( 
$chr == '>' AND ! $quoted )
                {
                    
$got = TRUE;
                    break;
                }
                
                else if ( ( in_array( 
$chr$this->non_delimiters ) ) AND ! $tag_end_loc )
                {
                    
$tag_end_loc = $end_opt;
                }
            }
            
            //-----------------------------------------
            // Not got the complete tag?
            //-----------------------------------------
            
            if ( ! 
$got )
            {
                break;
            }
            
            //-----------------------------------------
            // Not got a tag end location?
            //-----------------------------------------
            
            if ( ! 
$tag_end_loc )
            {
                
$tag_end_loc = $end_opt;
            }
            
            //-----------------------------------------
            // Extract tag options...
            //-----------------------------------------
            
            
$tag_opts        = substr( $text   , $tag_begin_loc + $open_tag_len$end_opt - ($tag_begin_loc + $open_tag_len) );
            
$actual_tag_name = substr( $lowtext$tag_begin_loc + 1            , ( $tag_end_loc - $tag_begin_loc ) - 1 );
            
            //-----------------------------------------
            // Check against actual tag name...
            //-----------------------------------------
            
            if ( 
$actual_tag_name != $tag )
            {
                
$start_search_pos = $end_opt;
                continue;
            }
    
            //-----------------------------------------
            // Now find the end tag location
            //-----------------------------------------
            
            
$tag_end_loc = strpos( $lowtext$close_tag$end_opt );
            
            //-----------------------------------------
            // Not got one? Break!
            //-----------------------------------------
            
            if ( 
$tag_end_loc === FALSE )
            {
                break;
            }
    
            //-----------------------------------------
            // Check for nested tags
            //-----------------------------------------
            
            
$nest_open_pos = strpos($lowtext$open_tag$end_opt);
            
            while ( 
$nest_open_pos !== FALSE AND $tag_end_loc !== FALSE )
            {
                //-----------------------------------------
                // It's not actually nested
                //-----------------------------------------
                
                if ( 
$nest_open_pos > $tag_end_loc )
                {
                    break;
                }
                
                if ( 
$this->debug == 2)
                {
                    print "
nn<hr>( ".htmlspecialchars($open_tag)." NEST FOUND</hr>nn";
                }
                
                
$tag_end_loc   = strpos($lowtext$close_tag$tag_end_loc   + $close_tag_len);
                
$nest_open_pos = strpos($lowtext$open_tag , $nest_open_pos + $open_tag_len );
            }
            
            //-----------------------------------------
            // Make sure we have an end location
            //-----------------------------------------
            
            if ( 
$tag_end_loc === FALSE )
            {
                
$start_search_pos = $end_opt;
                continue;
            }
    
            
$this_text_begin  = $end_opt + 1;
            
$between_text     = substr($text$this_text_begin$tag_end_loc - $this_text_begin);
            
$offset           = $tag_end_loc + $close_tag_len - $tag_begin_loc;
            
            //-----------------------------------------
            // Pass to function
            //-----------------------------------------
            
            
$final_text       = $this->$function($tag$between_text$tag_opts$parse_tag);
            
            //-----------------------------------------
            // #DEBUG
            //-----------------------------------------
            
            if ( 
$this->debug == 2)
            {
                print "
<hr><b>REPLACED {$function}($tag, ..., $tag_opts):</b><br />".htmlspecialchars(substr($text$tag_begin_loc$offset))."<br /><b>WITH:</b><br />".htmlspecialchars($final_text)."<hr>NEXT ITERATION";
            }
                
            //-----------------------------------------
            // Swap text
            //-----------------------------------------
            
            
$text             = substr_replace($text$final_text$tag_begin_loc$offset);
            
$start_search_pos = $tag_begin_loc + strlen($final_text);
        } 
    
        return 
$text;
    }

    /**
     * RTE: Extract option HTML
     *
     * @access    protected
     * @param    string    Option
     * @param    string    Text
     * @return    string    Converted text
     */
    protected function _getValueOfOption( 
$option$text )
    {
        if( 
$option == 'face' )
        {
            // Bad font face, bad
            preg_match( "
#{$option}(s+?)?=(s+?)?["']?(.+?)(["']|$|color|size|>)#is", $text, $matches );
        
}
        else
        {
            if( 
$option == 'style' AND ( $this->memberData['userAgentKey'] == 'safari' OR $this->memberData['userAgentKey'] == 'chrome' ) )
            {
                
preg_match"#{$option}(s*?)?=(s*?)?["']?(.+?)(["']|$|>)#is", $text, $matches );
            
}
            else
            {
                
preg_match"#{$option}(s*?)?=(s*?)?["']?(.+?)(["']|$|s|>)#is", $text, $matches );
            
}
        }
        
        if( 
$option == 'style' )
        {
            switch( 
$matches[3] )
            {
                case 
'font-size: x-small;':
                    
$matches[3]    = 'font-size: 8;';
                break;
                
                case 
'font-size: small;':
                    
$matches[3]    = 'font-size: 10;';
                break;
                
                case 
'font-size: medium;':
                    
$matches[3]    = 'font-size: 12;';
                break;
                
                case 
'font-size: large;':
                    
$matches[3]    = 'font-size: 14;';
                break;
                
                case 
'font-size: x-large;':
                    
$matches[3]    = 'font-size: 18;';
                break;
                
                case 
'font-size: xx-large;':
                    
$matches[3]    = 'font-size: 24;';
                break;
                
                case 
'font-size: xxx-large;':
                case 
'font-size: -webkit-xxx-large;':
                    
$matches[3]    = 'font-size: 36;';
                break;
            }
        }

        return isset(
$matches[3]) ? trim$matches[3] ) : '';
    }

    
/**
     * unhtml url: Removes < and >
     *
     * @access    protected
     * @param    array         Matches from preg_replace_callback
     * @return    string        Converted text
     */
    
protected function _unhtmlUrl$matches=array() )
    {
        
$url  stripslashes$matches[3] );
        
$type stripslashes$matches[1] ? $matches[1] : 'a href' );
        
        
$url  str_replace'<''&lt;'$url );
        
$url  str_replace'>''&gt;'$url );
        
$url  str_replace' ''%20' $url );
        
        return 
'<' $type '="' $url '"';
    }

    
/**
     * Converts color:rgb(x,x,x) to color:#xxxxxx
     *
     * @access    protected
     * @param    string    rgb contents: x,x,x
     * @param    string    regex end
     * @return    string    Converted text
     */
    
protected function _rgbToHex($matches)
    {
        
$t  $matches[1];
        
$t2 $matches[2];
        
        
$tmp array_map"trim"explode","$t ) );
        return 
'color: ' sprintf"#%02X%02X%02X" $t2intval($tmp[0]), intval($tmp[1]), intval($tmp[2]) );
    }
}
Онлайн: 0
Реклама