1: <?php
2: 3: 4: 5: 6:
7:
8: 9: 10: 11: 12: 13:
14: class QWriteBox extends QTextBox {
15: protected $strTextMode = QTextMode::MultiLine;
16: protected $strCrossScripting = QCrossScripting::Allow;
17:
18: protected $strCodeCssClass;
19:
20: public function __construct($objParentObject, $strControlId = null) {
21: parent::__construct($objParentObject, $strControlId);
22:
23: $this->strInstructions = QApplication::Translate('Tags <b> <u> <i> <br> <code> and <http://...> are allowed. Use ** at the beginning of any line for a bulleted list.');
24: }
25:
26: public function __get($strName) {
27: switch ($strName) {
28: case 'DisplayHtml':
29: return QWriteBox::DisplayHtml($this->strText, $this->strCodeCssClass);
30:
31: case 'CodeCssClass':
32: return $this->strCodeCssClass;
33:
34: default:
35: try {
36: return parent::__get($strName);
37: } catch (QCallerException $objExc) {
38: $objExc->IncrementOffset();
39: return $objExc;
40: }
41: }
42: }
43:
44: public function __set($strName, $mixValue) {
45: switch ($strName) {
46: case 'CodeCssClass':
47: try {
48: return ($this->strCodeCssClass = QType::Cast($mixValue, QType::String));
49: } catch (QCallerException $objExc) {
50: $objExc->IncrementOffset();
51: return $objExc;
52: }
53:
54: default:
55: try {
56: return parent::__set($strName, $mixValue);
57: } catch (QCallerException $objExc) {
58: $objExc->IncrementOffset();
59: return $objExc;
60: }
61: }
62: }
63:
64: public static function DisplayHtml($strText, $strCssClass) {
65: $strText = trim(str_replace("\r", '', $strText));
66: $strToReturn = '';
67:
68: $objStateStack = new QStack();
69: $objStateStack->Push(QWriteBox::StateText);
70: $objStateStack->Push(QWriteBox::StateNewLine);
71:
72: $strBufferArray = array();
73:
74: for ($intIndex = 0; $intIndex < mb_strlen($strText, QApplication::$EncodingType); $intIndex++) {
75: $strChar = $strText[$intIndex];
76:
77: switch ($objStateStack->PeekLast()) {
78: case QWriteBox::StateNewLine:
79: switch($strChar) {
80: case '*':
81: $objStateStack->Pop();
82: $objStateStack->Push(QWriteBox::StateStar);
83: break;
84: case "\n":
85: $strToReturn .= "<br/>\n";
86: break;
87: default:
88: $objStateStack->Pop();
89: $intIndex--;
90: }
91: break;
92:
93: case QWriteBox::StateStar:
94: switch($strChar) {
95: case '*':
96: $objStateStack->Pop();
97: if ($objStateStack->PeekLast() != QWriteBox::StateBulletedList) {
98: $objStateStack->Push(QWriteBox::StateBulletedList);
99: $strToReturn .= '<ul>';
100: }
101:
102: $strToReturn .= '<li>';
103: $objStateStack->Push(QWriteBox::StateBulletedListItem);
104: break;
105:
106: default:
107: $objStateStack->Pop();
108: if ($objStateStack->PeekLast() == QWriteBox::StateBulletedList) {
109: $strToReturn .= '</ul>';
110: $objStateStack->Pop();
111: }
112: $strToReturn .= '*';
113: $intIndex--;
114: break;
115: }
116: break;
117:
118: case QWriteBox::StateBulletedList:
119: switch ($strChar) {
120: case '*':
121: $objStateStack->Push(QWriteBox::StateStar);
122: break;
123: case "\n":
124: $strToReturn .= '<br/>';
125: break;
126: default:
127: $strToReturn .= '</ul>';
128: $intIndex--;
129: $objStateStack->Pop();
130: break;
131: }
132: break;
133:
134: case QWriteBox::StateBulletedListItem:
135: if ($strChar == "\n") {
136: $strToReturn .= '</li>';
137: $objStateStack->Pop();
138: break;
139: }
140:
141:
142: case QWriteBox::StateText:
143: switch($strChar) {
144: case '<':
145: $strBufferArray[QWriteBox::StateTag] = '';
146: $objStateStack->Push(QWriteBox::StateTag);
147: break;
148: case "\n":
149: $strToReturn .= "<br/>\n";
150: $objStateStack->Push(QWriteBox::StateNewLine);
151: break;
152: case ' ':
153: $strToReturn .= ' ';
154: break;
155: case ' ':
156: if ((mb_strlen($strText, QApplication::$EncodingType) > ($intIndex + 1)) &&
157: ($strText[$intIndex + 1] == ' ')) {
158: $strToReturn .= ' ';
159: $intIndex++;
160: } else
161: $strToReturn .= ' ';
162: break;
163:
164: default:
165: $strToReturn .= $strChar;
166: break;
167: }
168: break;
169:
170: case QWriteBox::StateTag:
171: switch ($strChar) {
172: case '<':
173: $strToReturn .= '<' . $strBufferArray[QWriteBox::StateTag];
174: $strBufferArray[QWriteBox::StateTag] = '';
175: break;
176: case "\n":
177: $strToReturn .= '<' . $strBufferArray[QWriteBox::StateTag];
178: $objStateStack->Pop();
179: $intIndex--;
180: break;
181: case '>':
182: $strTag = strtolower($strBufferArray[QWriteBox::StateTag]);
183: switch ($strTag) {
184: case 'b':
185: case 'i':
186: case 'u':
187: case 'br/':
188: case '/b':
189: case '/i':
190: case '/u':
191: $strToReturn .= '<' . $strTag . '>';
192: $objStateStack->Pop();
193: break;
194: case 'br':
195: $strToReturn .= '<br/>';
196: $objStateStack->Pop();
197: break;
198: case 'code':
199: $objStateStack->Pop();
200: if ($objStateStack->PeekLast() != QWriteBox::StateBulletedListItem) {
201: $strBufferArray[QWriteBox::StateCode] = '';
202: $objStateStack->Push(QWriteBox::StateCode);
203: } else
204: $strToReturn .= '<' . $strBufferArray[QWriteBox::StateTag] . '>';
205: break;
206: default:
207: if ((mb_strlen($strTag, QApplication::$EncodingType) >= 8) && ((mb_substr($strTag, 0, 7, QApplication::$EncodingType) == 'http://') || (substr($strTag, 0, 8) == 'https://')) &&
208: (mb_strpos($strTag, '"', 0, QApplication::$EncodingType) === false) &&
209: (mb_strpos($strTag, ' ', 0, QApplication::$EncodingType) === false) &&
210: (mb_strpos($strTag, ' ', 0, QApplication::$EncodingType) === false)) {
211: $strToReturn .= sprintf('<<a href="%s">%s</a>>',
212: $strBufferArray[QWriteBox::StateTag], $strBufferArray[QWriteBox::StateTag]);
213: } else
214: $strToReturn .= '<' . $strBufferArray[QWriteBox::StateTag] . '>';
215: $objStateStack->Pop();
216: break;
217: }
218: break;
219: default:
220: $strBufferArray[QWriteBox::StateTag] .= $strChar;
221: break;
222: }
223: break;
224:
225: case QWriteBox::StateCode:
226: $strBufferArray[QWriteBox::StateCode] .= $strChar;
227: $strBuffer = $strBufferArray[QWriteBox::StateCode];
228: if ((mb_strlen($strBuffer, QApplication::$EncodingType) >= 7) &&
229: (mb_strtolower(mb_substr($strBuffer, mb_strlen($strBuffer, QApplication::$EncodingType) - 7, QApplication::$EncodingType), QApplication::$EncodingType) == '</code>')) {
230: $objStateStack->Pop();
231: $strBuffer = mb_substr($strBuffer, 0, mb_strlen($strBuffer, QApplication::$EncodingType) - 7, QApplication::$EncodingType);
232: $strBuffer = highlight_string(trim($strBuffer), true);
233:
234: $strToReturn .= sprintf('<div class="%s">%s</div>', $strCssClass, $strBuffer);
235: if ((mb_strlen($strText, QApplication::$EncodingType) > ($intIndex + 1)) &&
236: ($strText[$intIndex + 1] == "\n"))
237: $intIndex++;
238: }
239: break;
240: }
241: }
242:
243: while (!$objStateStack->IsEmpty()) {
244: switch ($objStateStack->Pop()) {
245: case QWriteBox::StateTag:
246: $strToReturn .= '<' . $strBufferArray[QWriteBox::StateTag];
247: break;
248: case QWriteBox::StateStar:
249: $strToReturn .= '*';
250: break;
251:
252: case QWriteBox::StateBulletedList:
253: $strToReturn .= '</ul>';
254: break;
255:
256: case QWriteBox::StateBulletedListItem:
257: $strToReturn .= '</li>';
258: break;
259:
260: case QWriteBox::StateCode:
261: $strBuffer = $strBufferArray[QWriteBox::StateCode];
262: $strBuffer = highlight_string(trim($strBuffer), true);
263:
264: $strToReturn .= sprintf('<div class="%s">%s</div>', $strCssClass, $strBuffer);
265: break;
266: }
267: }
268: return $strToReturn;
269: }
270:
271: const StateText = 1;
272: const StateNewLine = 2;
273: const StateTag = 3;
274: const StateStar = 4;
275: const StateBulletedList = 5;
276: const StateBulletedListItem = 6;
277: const StateCode = 7;
278: }