qcubed/framework

View on GitHub
includes/base_controls/QWriteBox.class.php

Summary

Maintainability
D
2 days
Test Coverage
<?php
    /**
     * This file contains the QWriteBox class.
     *
     * @package Controls
     */

    /**
     * @package Controls
     *
     * @property-read string $DisplayHtml
     * @property string $CodeCssClass
     */
    class QWriteBox extends QTextBox {
        protected $strTextMode = QTextMode::MultiLine;
        protected $strCrossScripting = QCrossScripting::Allow;

        protected $strCodeCssClass;

        public function __construct($objParentObject, $strControlId = null) {
            parent::__construct($objParentObject, $strControlId);

            $this->strInstructions = QApplication::Translate('Tags &lt;b&gt; &lt;u&gt; &lt;i&gt; &lt;br&gt; &lt;code&gt; and &lt;http://...&gt; are allowed.  Use ** at the beginning of any line for a bulleted list.');
        }

        public function __get($strName) {
            switch ($strName) {
                case 'DisplayHtml':
                    return QWriteBox::DisplayHtml($this->strText, $this->strCodeCssClass);

                case 'CodeCssClass':
                    return $this->strCodeCssClass;

                default:
                    try {
                        return parent::__get($strName);
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        return $objExc;
                    }
            }
        }

        public function __set($strName, $mixValue) {
            switch ($strName) {
                case 'CodeCssClass':
                    try {
                        return ($this->strCodeCssClass = QType::Cast($mixValue, QType::String));
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        return $objExc;
                    }

                default:
                    try {
                        return parent::__set($strName, $mixValue);
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        return $objExc;
                    }
            }
        }

        public static function DisplayHtml($strText, $strCssClass) {
            $strText = trim(str_replace("\r", '', $strText));
            $strToReturn = '';

            $objStateStack = new QStack();
            $objStateStack->Push(QWriteBox::StateText);
            $objStateStack->Push(QWriteBox::StateNewLine);

            $strBufferArray = array();

            for ($intIndex = 0; $intIndex < mb_strlen($strText, QApplication::$EncodingType); $intIndex++) {
                $strChar = $strText[$intIndex];

                switch ($objStateStack->PeekLast()) {
                    case QWriteBox::StateNewLine:
                        switch($strChar) {
                            case '*':
                                $objStateStack->Pop();
                                $objStateStack->Push(QWriteBox::StateStar);
                                break;
                            case "\n":
                                $strToReturn .= "<br/>\n";
                                break;
                            default:
                                $objStateStack->Pop();
                                $intIndex--;
                        }
                        break;
                        
                    case QWriteBox::StateStar:
                        switch($strChar) {
                            case '*':
                                $objStateStack->Pop();
                                if ($objStateStack->PeekLast() != QWriteBox::StateBulletedList) {
                                    $objStateStack->Push(QWriteBox::StateBulletedList);
                                    $strToReturn .= '<ul>';
                                }

                                $strToReturn .= '<li>';
                                $objStateStack->Push(QWriteBox::StateBulletedListItem);
                                break;

                            default:
                                $objStateStack->Pop();
                                if ($objStateStack->PeekLast() == QWriteBox::StateBulletedList) {
                                    $strToReturn .= '</ul>';
                                    $objStateStack->Pop();
                                }
                                $strToReturn .= '*';
                                $intIndex--;
                                break;
                        }
                        break;

                    case QWriteBox::StateBulletedList:
                        switch ($strChar) {
                            case '*':
                                $objStateStack->Push(QWriteBox::StateStar);
                                break;
                            case "\n":
                                $strToReturn .= '<br/>';
                                break;
                            default:
                                $strToReturn .= '</ul>';
                                $intIndex--;
                                $objStateStack->Pop();
                                break;
                        }
                        break;

                    case QWriteBox::StateBulletedListItem:
                        if ($strChar == "\n") {
                            $strToReturn .= '</li>';
                            $objStateStack->Pop();
                            break;
                        }
                        // Otherwise, treat this like regular text...

                    case QWriteBox::StateText:
                        switch($strChar) {
                            case '<':
                                $strBufferArray[QWriteBox::StateTag] = '';
                                $objStateStack->Push(QWriteBox::StateTag);
                                break;
                            case "\n":
                                $strToReturn .= "<br/>\n";
                                $objStateStack->Push(QWriteBox::StateNewLine);
                                break;
                            case '    ':
                                $strToReturn .= '&nbsp;&nbsp;&nbsp;&nbsp;';
                                break;
                            case ' ':
                                if ((mb_strlen($strText, QApplication::$EncodingType) > ($intIndex + 1)) &&
                                    ($strText[$intIndex + 1] == ' ')) {
                                    $strToReturn .= ' &nbsp;';
                                    $intIndex++;
                                } else
                                    $strToReturn .= ' ';
                                break;

                            default:
                                $strToReturn .= $strChar;
                                break;
                        }
                        break;

                    case QWriteBox::StateTag:
                        switch ($strChar) {
                            case '<':
                                $strToReturn .= '&lt;' . $strBufferArray[QWriteBox::StateTag];
                                $strBufferArray[QWriteBox::StateTag] = '';
                                break;
                            case "\n":
                                $strToReturn .= '&lt;' . $strBufferArray[QWriteBox::StateTag];
                                $objStateStack->Pop();
                                $intIndex--;
                                break;
                            case '>':
                                $strTag = strtolower($strBufferArray[QWriteBox::StateTag]);
                                switch ($strTag) {
                                    case 'b':
                                    case 'i':
                                    case 'u':
                                    case 'br/':
                                    case '/b':
                                    case '/i':
                                    case '/u':
                                        $strToReturn .= '<' . $strTag . '>';
                                        $objStateStack->Pop();
                                        break;
                                    case 'br':
                                        $strToReturn .= '<br/>';
                                        $objStateStack->Pop();
                                        break;
                                    case 'code':
                                        $objStateStack->Pop();
                                        if ($objStateStack->PeekLast() != QWriteBox::StateBulletedListItem) {
                                            $strBufferArray[QWriteBox::StateCode] = '';
                                            $objStateStack->Push(QWriteBox::StateCode);
                                        } else
                                            $strToReturn .= '&lt;' . $strBufferArray[QWriteBox::StateTag] . '&gt;';
                                        break;
                                    default:
                                        if ((mb_strlen($strTag, QApplication::$EncodingType) >= 8) && ((mb_substr($strTag, 0, 7, QApplication::$EncodingType) == 'http://') || (substr($strTag, 0, 8) == 'https://')) &&
                                            (mb_strpos($strTag, '"', 0, QApplication::$EncodingType) === false) &&
                                            (mb_strpos($strTag, ' ', 0, QApplication::$EncodingType) === false) &&
                                            (mb_strpos($strTag, '    ', 0, QApplication::$EncodingType) === false)) {
                                            $strToReturn .= sprintf('&lt;<a href="%s">%s</a>&gt;',
                                                $strBufferArray[QWriteBox::StateTag], $strBufferArray[QWriteBox::StateTag]);
                                        } else
                                            $strToReturn .= '&lt;' . $strBufferArray[QWriteBox::StateTag] . '&gt;';
                                        $objStateStack->Pop();
                                        break;
                                }
                                break;
                            default:
                                $strBufferArray[QWriteBox::StateTag] .= $strChar;
                                break;
                        }
                        break;
                    
                    case QWriteBox::StateCode:
                        $strBufferArray[QWriteBox::StateCode] .= $strChar;
                        $strBuffer = $strBufferArray[QWriteBox::StateCode];
                        if ((mb_strlen($strBuffer, QApplication::$EncodingType) >= 7) && 
                            (mb_strtolower(mb_substr($strBuffer, mb_strlen($strBuffer, QApplication::$EncodingType) - 7, QApplication::$EncodingType), QApplication::$EncodingType) == '</code>')) {
                                $objStateStack->Pop();
                                $strBuffer = mb_substr($strBuffer, 0, mb_strlen($strBuffer, QApplication::$EncodingType) - 7, QApplication::$EncodingType);
                                $strBuffer = highlight_string(trim($strBuffer), true);

                                $strToReturn .= sprintf('<div class="%s">%s</div>', $strCssClass, $strBuffer);
                                if ((mb_strlen($strText, QApplication::$EncodingType) > ($intIndex + 1)) &&
                                    ($strText[$intIndex + 1] == "\n"))
                                    $intIndex++;
                            }
                        break;
                }
            }

            while (!$objStateStack->IsEmpty()) {
                switch ($objStateStack->Pop()) {
                    case QWriteBox::StateTag:
                        $strToReturn .= '&lt;' . $strBufferArray[QWriteBox::StateTag];
                        break;
                    case QWriteBox::StateStar:
                        $strToReturn .= '*';
                        break;

                    case QWriteBox::StateBulletedList:
                        $strToReturn .= '</ul>';
                        break;

                    case QWriteBox::StateBulletedListItem:
                        $strToReturn .= '</li>';
                        break;
                    
                    case QWriteBox::StateCode:
                        $strBuffer = $strBufferArray[QWriteBox::StateCode];
                        $strBuffer = highlight_string(trim($strBuffer), true);

                        $strToReturn .= sprintf('<div class="%s">%s</div>', $strCssClass, $strBuffer);
                        break;
                }
            }
            return $strToReturn;
        }

        const StateText = 1;
        const StateNewLine = 2;
        const StateTag = 3;
        const StateStar = 4;
        const StateBulletedList = 5;
        const StateBulletedListItem = 6;
        const StateCode = 7;
    }