<?php 
 | 
class BotMsgException extends Exception {} 
 | 
interface BotMsgInterface { 
 | 
    function __construct(BotMsg $msg); 
 | 
    function __toString(); 
 | 
    function sendPullResponse(); 
 | 
} 
 | 
  
 | 
class BotMsg { 
 | 
    private $beautiful = TRUE; 
 | 
    private $parser = NULL; 
 | 
    private $html = NULL; 
 | 
    private $text = NULL; 
 | 
    private $raw = ''; 
 | 
     
 | 
    /** 
 | 
     * Włącza lub wyłącza "upiększanie" konwertowanej do czystego tekstu wiadomości, np.: 
 | 
     * <b>abc</b> zamieniane jest na *abc* 
 | 
     * <h1>efg</h1> przechodzi w = efg = 
 | 
     * Domyślnie włączone 
 | 
     * @param bool $set Ustawienie "upiększania" 
 | 
     */ 
 | 
    function beautifulText($set = FALSE) { 
 | 
        $this->beautiful = (bool)$set; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Konstruktor. De facto alias dla {@link BotMsg::append()} 
 | 
     */ 
 | 
    function __construct($str = NULL) { 
 | 
        if($str !== NULL) { 
 | 
            $this->append($str); 
 | 
        } 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Serializacja klasy wymaga zapisania tylko niektórych elementów 
 | 
     */ 
 | 
    function __sleep() { 
 | 
        return array('beautiful', 'raw'); 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Alias dla {@link BotMsg::append()} 
 | 
     */ 
 | 
    function a($str) { 
 | 
        $this->append($str); 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Dodaje kod HTML na koniec wiadomości 
 | 
     * @param string $str Treść do dodania 
 | 
     */ 
 | 
    function append($str) { 
 | 
        $this->text = $this->html = $this->parser = NULL; 
 | 
        $this->raw .= (string)$str; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Zwraca wiadomość jako czysty tekst 
 | 
     * @return string Wiadomość 
 | 
     */ 
 | 
    function getText() { 
 | 
        if($this->text === NULL) { 
 | 
            $this->text = trim($this->parseTextDOM($this->getParser()->getElementsByTagName('body')->item(0))); 
 | 
        } 
 | 
         
 | 
        return $this->text; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Zwraca wiadomość jako kod HTML 
 | 
     * @return string Wiadomość 
 | 
     */ 
 | 
    function getHTML() { 
 | 
        if($this->html === NULL) { 
 | 
            $doc = $this->getParser(); 
 | 
            $this->parseHTMLDOM( $doc->getElementsByTagName('body')->item(0) ); 
 | 
            $this->html = $doc->saveXML( $doc->getElementsByTagName('body')->item(0) ); 
 | 
        } 
 | 
         
 | 
        return (string)substr($this->html, 6, -7); 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Zwraca treść wiadomości zapisaną przy użyciu {@link BotMsg::append()} bez żadnych modyfikacji 
 | 
     * @return string Oryginalna wiadomość 
 | 
     */ 
 | 
    function getRaw() { 
 | 
        return $this->raw; 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Zwraca wiadomość jako kod HTML 
 | 
     * @return string Wiadomość 
 | 
     */ 
 | 
    function __toString() { 
 | 
        return $this->getHTML(); 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * Zwraca kopię drzewa DOM wiadomości 
 | 
     * @return DOMDocument Wiadomość 
 | 
     */ 
 | 
    function getParser() { 
 | 
        if($this->parser === NULL) { 
 | 
            $this->parser = new DOMDocument('1.0', 'utf-8'); 
 | 
            try { 
 | 
                $this->parser->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>'.$this->raw.'</body></html>'); 
 | 
            } 
 | 
            catch(ErrorException $e) { 
 | 
                if($e->getSeverity() != E_WARNING) { 
 | 
                    throw $e; 
 | 
                } 
 | 
            } 
 | 
             
 | 
            foreach($this->parser->getElementsByTagName('a') as $node) { 
 | 
                if(!$node->hasAttribute('href')) { 
 | 
                    $node->setAttribute('href', $node->textContent); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
         
 | 
        return $this->parser->cloneNode(TRUE); 
 | 
    } 
 | 
     
 | 
    private function parseTextDOM($dom) { 
 | 
        if(!($dom instanceof DOMElement)) { 
 | 
            throw new BotMsgException('Nieznany element DOM: '.get_class($dom)); 
 | 
        } 
 | 
         
 | 
        $return = ''; 
 | 
        foreach($dom->childNodes as $node) { 
 | 
            if($node instanceof DOMText || $node instanceof DOMEntity) { 
 | 
                $return .= strtr($node->nodeValue, array("\n" => '', "\r" => '')); 
 | 
            } 
 | 
            elseif($node instanceof DOMElement) { 
 | 
                switch(strtolower($node->tagName)) { 
 | 
                    case 'b': 
 | 
                    case 'strong': 
 | 
                        $return .= ($this->beautiful ? '*' : '').$this->parseTextDOM($node).($this->beautiful ? '*' : ''); 
 | 
                    break; 
 | 
                    case 'u': 
 | 
                        $return .= ($this->beautiful ? '_' : '').$this->parseTextDOM($node).($this->beautiful ? '_' : ''); 
 | 
                    break; 
 | 
                    case 'i': 
 | 
                        $return .= ($this->beautiful ? '/' : '').$this->parseTextDOM($node).($this->beautiful ? '/' : ''); 
 | 
                    break; 
 | 
                    case 'br': 
 | 
                        $return .= "\n"; 
 | 
                    break; 
 | 
                    case 'p': 
 | 
                        if(substr($return, -1) != "\n") { 
 | 
                            $return .= "\n\n"; 
 | 
                        } 
 | 
                        $return .= $this->parseTextDOM($node)."\n\n"; 
 | 
                    break; 
 | 
                    case 'h1': 
 | 
                        if(substr($return, -1) != "\n") { 
 | 
                            $return .= "\n\n"; 
 | 
                        } 
 | 
                        $return .= ($this->beautiful ? '= ' : '').$this->parseTextDOM($node).($this->beautiful ? ' =' : '')."\n"; 
 | 
                    break; 
 | 
                    case 'h2': 
 | 
                        if(substr($return, -1) != "\n") { 
 | 
                            $return .= "\n\n"; 
 | 
                        } 
 | 
                        $return .= ($this->beautiful ? '== ' : '').$this->parseTextDOM($node).($this->beautiful ? ' ==' : '')."\n"; 
 | 
                    break; 
 | 
                    case 'h3': 
 | 
                        if(substr($return, -1) != "\n") { 
 | 
                            $return .= "\n\n"; 
 | 
                        } 
 | 
                        $return .= ($this->beautiful ? '=== ' : '').$this->parseTextDOM($node).($this->beautiful ? ' ===' : '')."\n"; 
 | 
                    break; 
 | 
                    case 'td': 
 | 
                        $return .= $this->parseTextDOM($node)."\t"; 
 | 
                    break; 
 | 
                    case 'th': 
 | 
                        $return .= ($this->beautiful ? '*' : '').$this->parseTextDOM($node).($this->beautiful ? '*' : '')."\t"; 
 | 
                    break; 
 | 
                    case 'tr': 
 | 
                        $return .= $this->parseTextDOM($node)."\n"; 
 | 
                    break; 
 | 
                    case 'a': 
 | 
                        $return .= $this->parseTextDOM($node); 
 | 
                         
 | 
                        if($node->getAttribute('href') != $node->textContent) { 
 | 
                            $return .= ' ('.$node->getAttribute('href').')'; 
 | 
                        } 
 | 
                    break; 
 | 
                    case 'script': 
 | 
                    case 'style': 
 | 
                    case 'img': 
 | 
                    break; 
 | 
                    default: 
 | 
                        $return .= $this->parseTextDOM($node); 
 | 
                    break; 
 | 
                } 
 | 
            } 
 | 
            else 
 | 
            { 
 | 
                throw new BotMsgException('Nieznany element DOM: '.get_class($node)); 
 | 
            } 
 | 
        } 
 | 
         
 | 
        return $return; 
 | 
    } 
 | 
     
 | 
    private function parseHTMLDOM($dom) { 
 | 
        if(!($dom instanceof DOMNode)) { 
 | 
            throw new BotMsgException('Nieznany element DOM: '.get_class($dom)); 
 | 
        } 
 | 
         
 | 
        foreach($dom->childNodes as $node) { 
 | 
            if($node instanceof DOMElement) { 
 | 
                if($node->hasAttribute('color')) { 
 | 
                    $color = trim($node->getAttribute('color')); 
 | 
                    $node->removeAttribute('color'); 
 | 
                    if(substr($color, 0, 1)=='#' AND (strlen($color)==4 OR strlen($color)==7) AND ctype_xdigit(substr($color, 1))) { 
 | 
                        $node->setAttribute('style', 'color:'.$color.';'.$node->getAttribute('style')); 
 | 
                    } 
 | 
                } 
 | 
                 
 | 
                $this->parseHTMLDOM($node); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 | 
?> 
 |