40 |
40 |
41 public static function getPage($page_id, $namespace, $wiki = 1, $smilies = true, $filter_links = true, $redir = true, $render = true) |
41 public static function getPage($page_id, $namespace, $wiki = 1, $smilies = true, $filter_links = true, $redir = true, $render = true) |
42 { |
42 { |
43 global $db, $session, $paths, $template, $plugins; // Common objects |
43 global $db, $session, $paths, $template, $plugins; // Common objects |
44 |
44 |
45 $perms =& $session; |
45 $page = new PageProcessor($page_id, $namespace); |
46 |
46 $text = $page->fetch_text(); |
47 if ( $page_id != $paths->page_id || $namespace != $paths->namespace ) |
47 |
48 { |
48 if ( !$render ) |
49 unset($perms); |
49 return $text; |
50 unset($perms); // PHP <5.1.5 Zend bug |
50 |
51 $perms = $session->fetch_page_acl($page_id, $namespace); |
51 $text = self::render($text, $wiki, $smilies, $filter_links); |
52 if ( !$perms ) |
52 return $text; |
53 { |
|
54 $session->init_permissions(); |
|
55 $perms = $session->fetch_page_acl($page_id, $namespace); |
|
56 }; |
|
57 } |
|
58 |
|
59 if(!$perms->get_permissions('read')) |
|
60 return 'Access denied ('.$paths->nslist[$namespace].$page_id.')'; |
|
61 |
|
62 if($namespace != 'Template' && ($wiki == 0 || $render == false)) |
|
63 { |
|
64 if(!$perms->get_permissions('view_source')) |
|
65 { |
|
66 return 'Access denied ('.$paths->nslist[$namespace].$page_id.')'; |
|
67 } |
|
68 } |
|
69 |
|
70 $q = $db->sql_query('SELECT page_text,char_tag FROM '.table_prefix.'page_text WHERE page_id=\''.$db->escape($page_id).'\' AND namespace=\''.$db->escape($namespace).'\';'); |
|
71 if ( !$q ) |
|
72 { |
|
73 $db->_die('Method called was: RenderMan::getPage(\''.$page_id.'\', \''.$namespace.'\');.'); |
|
74 } |
|
75 if ( $db->numrows() < 1 ) |
|
76 { |
|
77 return false; |
|
78 } |
|
79 $row = $db->fetchrow(); |
|
80 $db->free_result(); |
|
81 |
|
82 $message = $row['page_text']; |
|
83 $chartag = $row['char_tag']; |
|
84 unset($row); // Free some memory |
|
85 |
|
86 if ( preg_match("#^\#redirect \[\[([^\]\r\n\a\t]+?)\]\]#", $message, $m) && $redir && ( !isset($_GET['redirect']) || ( isset($_GET['redirect']) && $_GET['redirect'] != 'no' ) ) ) |
|
87 { |
|
88 $old = $paths->cpage; |
|
89 $a = RenderMan::strToPageID($m[1]); |
|
90 $a[0] = str_replace(' ', '_', $a[0]); |
|
91 |
|
92 $pageid = str_replace(' ', '_', $paths->nslist[$a[1]] . $a[0]); |
|
93 $paths->page = $pageid; |
|
94 $paths->cpage = $paths->pages[$pageid]; |
|
95 //die('<pre>'.print_r($paths->cpage,true).'</pre>'); |
|
96 |
|
97 unset($template); |
|
98 unset($GLOBALS['template']); |
|
99 |
|
100 $GLOBALS['template'] = new template(); |
|
101 global $template; |
|
102 |
|
103 $template->template(); // Tear down and rebuild the template parser |
|
104 $template->load_theme($session->theme, $session->style); |
|
105 |
|
106 $data = '<div><small>(Redirected from <a href="'.makeUrlNS($old['namespace'], $old['urlname_nons'], 'redirect=no', true).'">'.$old['name'].'</a>)</small></div>'.RenderMan::getPage($a[0], $a[1], $wiki, $smilies, $filter_links, false /* Enforces a maximum of one redirect */); |
|
107 |
|
108 return $data; |
|
109 } |
|
110 else if(preg_match('#^\#redirect \[\[(.+?)\]\]#', $message, $m) && isset($_GET['redirect']) && $_GET['redirect'] == 'no') |
|
111 { |
|
112 preg_match('#^\#redirect \[\[(.+)\]\]#', $message, $m); |
|
113 $m[1] = str_replace(' ', '_', $m[1]); |
|
114 $message = preg_replace('#\#redirect \[\[(.+)\]\]#', '<nowiki><div class="mdg-infobox"><table border="0" width="100%" cellspacing="0" cellpadding="0"><tr><td valign="top"><img alt="Cute wet-floor icon" src="'.scriptPath.'/images/redirector.png" /></td><td valign="top" style="padding-left: 10px;"><b>This page is a <i>redirector</i>.</b><br />This means that this page will not show its own content by default. Instead it will display the contents of the page it redirects to.<br /><br />To create a redirect page, make the <i>first characters</i> in the page content <tt>#redirect [[Page_ID]]</tt>. For more information, see the Enano <a href="http://enanocms.org/Help:Wiki_formatting">Wiki formatting guide</a>.<br /><br />This page redirects to <a href="'.makeUrl($m[1]).'">'.$paths->pages[$m[1]]['name'].'</a>.</td></tr></table></div><br /><hr style="margin-left: 1em; width: 200px;" /></nowiki>', $message); |
|
115 } |
|
116 $session->disallow_password_grab(); |
|
117 return ($render) ? RenderMan::render($message, $wiki, $smilies, $filter_links) : $message; |
|
118 } |
53 } |
119 |
54 |
120 public static function getTemplate($id, $parms) |
55 public static function getTemplate($id, $parms) |
121 { |
56 { |
122 global $db, $session, $paths, $template, $plugins; // Common objects |
57 global $db, $session, $paths, $template, $plugins; // Common objects |
213 } |
148 } |
214 |
149 |
215 return $text; |
150 return $text; |
216 } |
151 } |
217 |
152 |
218 public static function render($text, $wiki = 1, $smilies = true, $filter_links = true) |
153 /** |
|
154 * Renders a glob of text. Note that this is PHP-safe, so if returned text (or rather, "?>" . $returned) has PHP it can be eval'ed. |
|
155 * @param string Text to render |
|
156 * @param int Render parameters - see constants.php |
|
157 * @return string Rendered text |
|
158 */ |
|
159 |
|
160 public static function render($text, $flags = RENDER_WIKI_DEFAULT, $smilies = true) |
219 { |
161 { |
220 global $db, $session, $paths, $template, $plugins; // Common objects |
162 global $db, $session, $paths, $template, $plugins; // Common objects |
221 if($smilies) |
163 |
|
164 if ( !$smilies ) |
|
165 $flags |= RENDER_NOSMILIES; |
|
166 |
|
167 if ( $flags & ~RENDER_NOSMILIES ) |
222 { |
168 { |
223 $text = RenderMan::smilieyize($text); |
169 $text = RenderMan::smilieyize($text); |
224 } |
170 } |
225 if($wiki == 1) |
171 if ( $flags & RENDER_WIKI_DEFAULT ) |
226 { |
172 { |
227 $text = RenderMan::next_gen_wiki_format($text); |
173 $text = RenderMan::next_gen_wiki_format($text, $flags); |
228 } |
174 } |
229 elseif($wiki == 2) |
175 else if ( $flags & RENDER_WIKI_TEMPLATE ) |
230 { |
176 { |
231 $text = $template->tplWikiFormat($text); |
177 $text = $template->tplWikiFormat($text); |
232 } |
178 } |
233 return $text; |
179 return $text; |
234 } |
180 } |
235 |
181 |
236 public static function PlainTextRender($text, $wiki = 1, $smilies = false, $filter_links = true) |
182 private static function next_gen_wiki_format($text, $flags = 0) |
237 { |
|
238 global $db, $session, $paths, $template, $plugins; // Common objects |
|
239 if($smilies) |
|
240 { |
|
241 $text = RenderMan::smilieyize($text); |
|
242 } |
|
243 if($wiki == 1) |
|
244 { |
|
245 $text = RenderMan::next_gen_wiki_format($text, true); |
|
246 } |
|
247 elseif($wiki == 2) |
|
248 { |
|
249 $text = $template->tplWikiFormat($text); |
|
250 } |
|
251 return $text; |
|
252 } |
|
253 |
|
254 public static function next_gen_wiki_format($text, $plaintext = false, $filter_links = true, $do_params = false) |
|
255 { |
183 { |
256 global $db, $session, $paths, $template, $plugins; // Common objects |
184 global $db, $session, $paths, $template, $plugins; // Common objects |
257 global $lang; |
185 global $lang; |
258 |
186 |
259 require_once(ENANO_ROOT.'/includes/wikiformat.php'); |
187 require_once(ENANO_ROOT.'/includes/wikiformat.php'); |
289 if ( $paths->namespace == 'Template' ) |
217 if ( $paths->namespace == 'Template' ) |
290 { |
218 { |
291 $text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text); |
219 $text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text); |
292 } |
220 } |
293 |
221 |
294 preg_match_all('/<lang (?:code|id)="([a-z0-9_-]+)">([\w\W]+?)<\/lang>/', $text, $langmatch); |
222 if ( !($flags & RENDER_BLOCKONLY) ) |
295 foreach ( $langmatch[0] as $i => $match ) |
223 { |
296 { |
224 preg_match_all('/<lang (?:code|id)="([a-z0-9_-]+)">([\w\W]+?)<\/lang>/', $text, $langmatch); |
297 if ( $langmatch[1][$i] == $lang->lang_code ) |
225 foreach ( $langmatch[0] as $i => $match ) |
298 { |
226 { |
299 $text = str_replace_once($match, $langmatch[2][$i], $text); |
227 if ( $langmatch[1][$i] == $lang->lang_code ) |
300 } |
228 { |
301 else |
229 $text = str_replace_once($match, $langmatch[2][$i], $text); |
302 { |
230 } |
303 $text = str_replace_once($match, '', $text); |
231 else |
304 } |
232 { |
305 } |
233 $text = str_replace_once($match, '', $text); |
306 |
234 } |
307 $code = $plugins->setHook('render_wikiformat_pre'); |
235 } |
308 foreach ( $code as $cmd ) |
236 |
309 { |
237 $code = $plugins->setHook('render_wikiformat_pre'); |
310 eval($cmd); |
238 foreach ( $code as $cmd ) |
311 } |
239 { |
|
240 eval($cmd); |
|
241 } |
312 |
242 |
313 //$template_regex = "/\{\{([^\]]+?)((\n([ ]*?)[A-z0-9]+([ ]*?)=([ ]*?)(.+?))*)\}\}/is"; |
243 //$template_regex = "/\{\{([^\]]+?)((\n([ ]*?)[A-z0-9]+([ ]*?)=([ ]*?)(.+?))*)\}\}/is"; |
314 $template_regex = "/\{\{(.+)((\n|\|[ ]*([A-z0-9]+)[ ]*=[ ]*(.+))*)\}\}/isU"; |
244 $template_regex = "/\{\{(.+)((\n|\|[ ]*([A-z0-9]+)[ ]*=[ ]*(.+))*)\}\}/isU"; |
315 $i = 0; |
245 $i = 0; |
316 while ( preg_match($template_regex, $text) ) |
246 while ( preg_match($template_regex, $text) ) |
317 { |
247 { |
318 $i++; |
248 $i++; |
319 if ( $i == 5 ) |
249 if ( $i == 5 ) |
320 break; |
250 break; |
321 $text = RenderMan::include_templates($text); |
251 $text = RenderMan::include_templates($text); |
322 } |
252 } |
323 |
253 |
324 $code = $plugins->setHook('render_wikiformat_posttemplates'); |
254 $code = $plugins->setHook('render_wikiformat_posttemplates'); |
325 foreach ( $code as $cmd ) |
255 foreach ( $code as $cmd ) |
326 { |
256 { |
327 eval($cmd); |
257 eval($cmd); |
328 } |
258 } |
329 |
259 |
330 if ( !$plaintext ) |
|
331 { |
|
332 // Process images |
260 // Process images |
333 $text = RenderMan::process_image_tags($text, $taglist); |
261 $text = RenderMan::process_image_tags($text, $taglist); |
334 $text = RenderMan::process_imgtags_stage2($text, $taglist); |
262 $text = RenderMan::process_imgtags_stage2($text, $taglist); |
335 } |
263 } |
336 |
264 |
337 if($do_params) |
|
338 { |
|
339 preg_match_all('#\(_([0-9]+)_\)#', $text, $matchlist); |
|
340 foreach($matchlist[1] as $m) |
|
341 { |
|
342 $text = str_replace('(_'.$m.'_)', $paths->getParam((int)$m), $text); |
|
343 } |
|
344 } |
|
345 |
|
346 // Before shipping it out to the renderer, replace spaces in between headings and paragraphs: |
265 // Before shipping it out to the renderer, replace spaces in between headings and paragraphs: |
347 $text = preg_replace('/<\/(h[0-9]|div|p)>([\s]+)<(h[0-9]|div|p)( .+?)?>/i', '</\\1><\\3\\4>', $text); |
266 $text = preg_replace('/<\/(h[0-9]|div|p)>([\s]+)<(h[0-9]|div|p)( .+?)?>/i', '</\\1><\\3\\4>', $text); |
348 |
267 |
349 $text = process_tables($text); |
268 $text = process_tables($text); |
350 $text = RenderMan::parse_internal_links($text); |
269 |
|
270 if ( !($flags & RENDER_BLOCKONLY) ) |
|
271 $text = RenderMan::parse_internal_links($text); |
351 |
272 |
352 $wiki = Text_Wiki::singleton('Mediawiki'); |
273 $wiki = Text_Wiki::singleton('Mediawiki'); |
353 if($plaintext) |
274 $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath); |
354 { |
275 $wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external'); |
355 $wiki->setRenderConf('Plain', 'wikilink', 'view_url', contentPath); |
276 if ( $flags & RENDER_BLOCKONLY ) |
356 $result = $wiki->transform($text, 'Plain'); |
277 { |
357 } |
278 $wiki->disableRule('Freelink'); |
358 else |
279 $wiki->disableRule('Url'); |
359 { |
280 $wiki->disableRule('Toc'); |
360 $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath); |
281 $wiki->disableRule('Image'); |
361 $wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external'); |
282 } |
362 $result = $wiki->transform($text, 'Xhtml'); |
283 else if ( $flags & RENDER_INLINEONLY ) |
363 } |
284 { |
|
285 foreach ( array('code', 'html', 'raw', 'include', 'embed', 'horiz', 'break', 'blockquote', 'list', 'newline', 'paragraph', 'revise', 'tighten') as $rule ) |
|
286 { |
|
287 $wiki->disableRule($rule); |
|
288 } |
|
289 } |
|
290 $result = $wiki->transform($text, 'Xhtml'); |
364 |
291 |
365 // HTML fixes |
292 // HTML fixes |
366 $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result); |
293 $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result); |
367 $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result); |
294 $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result); |
368 $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result); |
295 $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result); |
375 $result = str_replace("</table><br />", "</table>", $result); |
302 $result = str_replace("</table><br />", "</table>", $result); |
376 $result = preg_replace('/<\/table>$/', "</table><br /><br />", $result); |
303 $result = preg_replace('/<\/table>$/', "</table><br /><br />", $result); |
377 $result = str_replace("<p></div></p>", "</div>", $result); |
304 $result = str_replace("<p></div></p>", "</div>", $result); |
378 $result = str_replace("<p></table></p>", "</table>", $result); |
305 $result = str_replace("<p></table></p>", "</table>", $result); |
379 |
306 |
380 $code = $plugins->setHook('render_wikiformat_post'); |
307 if ( !($flags & RENDER_BLOCKONLY) ) |
381 foreach ( $code as $cmd ) |
308 { |
382 { |
309 $code = $plugins->setHook('render_wikiformat_post'); |
383 eval($cmd); |
310 foreach ( $code as $cmd ) |
|
311 { |
|
312 eval($cmd); |
|
313 } |
384 } |
314 } |
385 |
315 |
386 // Reinsert <nowiki> sections |
316 // Reinsert <nowiki> sections |
387 for($i=0;$i<$nw;$i++) |
317 for($i=0;$i<$nw;$i++) |
388 { |
318 { |
404 public static function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false) |
334 public static function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false) |
405 { |
335 { |
406 global $db, $session, $paths, $template, $plugins; // Common objects |
336 global $db, $session, $paths, $template, $plugins; // Common objects |
407 |
337 |
408 return RenderMan::next_gen_wiki_format($message, $plaintext, $filter_links, $do_params); |
338 return RenderMan::next_gen_wiki_format($message, $plaintext, $filter_links, $do_params); |
409 |
|
410 $random_id = md5( time() . mt_rand() ); |
|
411 |
|
412 // Strip out <nowiki> sections |
|
413 $nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $message, $nowiki); |
|
414 |
|
415 if(!$plaintext) |
|
416 { |
|
417 |
|
418 //return '<pre>'.print_r($nowiki,true).'</pre>'; |
|
419 |
|
420 for($i=0;$i<sizeof($nowiki[1]);$i++) |
|
421 { |
|
422 $message = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $message); |
|
423 } |
|
424 |
|
425 $message = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $message); |
|
426 |
|
427 //return '<pre>'.htmlspecialchars($message).'</pre>'; |
|
428 |
|
429 $message = RenderMan::process_image_tags($message); |
|
430 |
|
431 } |
|
432 |
|
433 if($do_params) |
|
434 { |
|
435 preg_match_all('#\(_([0-9]+)_\)#', $message, $matchlist); |
|
436 foreach($matchlist[1] as $m) |
|
437 { |
|
438 $message = str_replace('(_'.$m.'_)', $paths->getParam((int)$m), $message); |
|
439 } |
|
440 } |
|
441 |
|
442 $message = RenderMan::include_templates($message); |
|
443 |
|
444 // Reinsert <nowiki> sections |
|
445 for($i=0;$i<$nw;$i++) |
|
446 { |
|
447 $message = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $message); |
|
448 } |
|
449 |
|
450 $message = process_tables($message); |
|
451 //if($message2 != $message) return '<pre>'.htmlspecialchars($message2).'</pre>'; |
|
452 //$message = str_replace(array('<table>', '</table>'), array('<nowiki><table>', '</table></nowiki>'), $message); |
|
453 |
|
454 $wiki =& Text_Wiki::singleton('Mediawiki'); |
|
455 if($plaintext) |
|
456 { |
|
457 $wiki->setRenderConf('Plain', 'wikilink', 'view_url', contentPath); |
|
458 $result = $wiki->transform($message, 'Plain'); |
|
459 } else { |
|
460 $wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath); |
|
461 $wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external'); |
|
462 $result = $wiki->transform($message, 'Xhtml'); |
|
463 } |
|
464 |
|
465 // HTML fixes |
|
466 $result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result); |
|
467 $result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result); |
|
468 $result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result); |
|
469 $result = str_replace("<pre><code>\n", "<pre><code>", $result); |
|
470 $result = preg_replace("/<p><table([^>]*?)><\/p>/", "<table\\1>", $result); |
|
471 $result = str_replace("<br />\n</td>", "\n</td>", $result); |
|
472 $result = str_replace("<p><tr>", "<tr>", $result); |
|
473 $result = str_replace("<tr><br />", "<tr>", $result); |
|
474 $result = str_replace("</tr><br />", "</tr>", $result); |
|
475 $result = str_replace("</table></p>", "</table>", $result); |
|
476 $result = str_replace("</table><br />", "</table>", $result); |
|
477 $result = preg_replace('/<\/table>$/', "</table><br /><br />", $result); |
|
478 $result = str_replace("<p></div></p>", "</div>", $result); |
|
479 $result = str_replace("<p></table></p>", "</table>", $result); |
|
480 |
|
481 $result = str_replace('<nowiki>', '<nowiki>', $result); |
|
482 $result = str_replace('</nowiki>', '</nowiki>', $result); |
|
483 |
|
484 return $result; |
|
485 } |
339 } |
486 |
340 |
487 public static function destroy_javascript($message, $_php = false) |
341 public static function destroy_javascript($message, $_php = false) |
488 { |
342 { |
489 $message = preg_replace('#<(script|object|applet|embed|iframe|frame|form|input|select)(.*?)>#is', '<\\1\\2>', $message); |
343 $message = preg_replace('#<(script|object|applet|embed|iframe|frame|form|input|select)(.*?)>#is', '<\\1\\2>', $message); |
518 } |
372 } |
519 return $text; |
373 return $text; |
520 } |
374 } |
521 |
375 |
522 /** |
376 /** |
|
377 * Reverse-renders a blob of text (converts it from XHTML back to wikitext) by using parser hints and educated guesses. |
|
378 * @param string XHTML |
|
379 * @return string Wikitext |
|
380 */ |
|
381 |
|
382 public static function reverse_render($text) |
|
383 { |
|
384 // convert \r\n to \n |
|
385 $text = str_replace("\r\n", "\n", $text); |
|
386 |
|
387 // Separate certain block level elements onto their own lines. This tidies up the tag |
|
388 // soup that TinyMCE sometimes produces. |
|
389 $block_elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'table', 'ul', 'pre'); |
|
390 $block_elements = implode('|', $block_elements); |
|
391 $regex = "#(</(?:$block_elements)>)\n?<($block_elements)(>| .+?>)#i"; |
|
392 $text = preg_replace($regex, "$1\n\n<$2$3", $text); |
|
393 |
|
394 $text = self::reverse_process_parser_hints($text); |
|
395 $text = self::reverse_process_headings($text); |
|
396 $text = self::reverse_process_lists($text); |
|
397 $text = self::reverse_process_tables($text); |
|
398 |
|
399 // Lastly, strip out paragraph tags. |
|
400 $text = preg_replace('|^ *<p>(.+?)</p> *$|m', "\\1", $text); |
|
401 |
|
402 return $text; |
|
403 } |
|
404 |
|
405 public static function reverse_process_parser_hints($text) |
|
406 { |
|
407 global $db, $session, $paths, $template, $plugins; // Common objects |
|
408 |
|
409 if ( !preg_match_all('|<!--#([a-z0-9_]+)(?: (.+?))?-->([\w\W]*?)<!--#/\\1-->|s', $text, $matches) ) |
|
410 return $text; |
|
411 |
|
412 foreach ( $matches[0] as $i => $match ) |
|
413 { |
|
414 $tag =& $matches[1][$i]; |
|
415 $attribs =& $matches[2][$i]; |
|
416 $inner =& $matches[3][$i]; |
|
417 |
|
418 $attribs = self::reverse_process_hint_attribs($attribs); |
|
419 switch($tag) |
|
420 { |
|
421 case 'smiley': |
|
422 case 'internallink': |
|
423 case 'imagelink': |
|
424 if ( isset($attribs['code']) ) |
|
425 { |
|
426 $text = str_replace($match, $attribs['code'], $text); |
|
427 } |
|
428 else if ( isset($attribs['src']) ) |
|
429 { |
|
430 $text = str_replace($match, $attribs['src'], $text); |
|
431 } |
|
432 break; |
|
433 } |
|
434 } |
|
435 |
|
436 return $text; |
|
437 } |
|
438 |
|
439 public static function reverse_process_hint_attribs($attribs) |
|
440 { |
|
441 $return = array(); |
|
442 if ( !preg_match_all('/([a-z0-9_-]+)="([^"]+?)"/', $attribs, $matches) ) |
|
443 return array(); |
|
444 |
|
445 foreach ( $matches[0] as $i => $match ) |
|
446 { |
|
447 $name =& $matches[1][$i]; |
|
448 $value =& $matches[2][$i]; |
|
449 |
|
450 $value = base64_decode($value); |
|
451 |
|
452 $return[$name] = $value; |
|
453 } |
|
454 |
|
455 return $return; |
|
456 } |
|
457 |
|
458 /** |
|
459 * Escapes a string so that it's safe to use as an attribute in a parser hint. |
|
460 * @param string |
|
461 * @return string |
|
462 */ |
|
463 |
|
464 public static function escape_parser_hint_attrib($text) |
|
465 { |
|
466 return base64_encode($text); |
|
467 } |
|
468 |
|
469 public static function reverse_process_headings($text) |
|
470 { |
|
471 if ( !preg_match_all('|^<h([1-6])(?: id="toc[0-9]+")?>(.*?)</h\\1>$|m', $text, $matches) ) |
|
472 return $text; |
|
473 |
|
474 foreach ( $matches[0] as $i => $match ) |
|
475 { |
|
476 // generate heading tag |
|
477 $heading_size = intval($matches[1][$i]); |
|
478 $eq = ''; |
|
479 for ( $j = 0; $j < $heading_size; $j++ ) |
|
480 $eq .= '='; |
|
481 |
|
482 $heading =& $matches[2][$i]; |
|
483 |
|
484 $tag = "$eq $heading $eq"; |
|
485 $text = str_replace($match, $tag, $text); |
|
486 } |
|
487 |
|
488 return $text; |
|
489 } |
|
490 |
|
491 public static function reverse_process_lists($text) |
|
492 { |
|
493 if ( !preg_match('!(</?(?:ul|ol|li)>)!', $text) ) |
|
494 return $text; |
|
495 |
|
496 $split = preg_split('!(</?(?:ul|ol|li)>)!', $text, -1, PREG_SPLIT_DELIM_CAPTURE); |
|
497 |
|
498 $stack_height = 0; |
|
499 $current_list = ''; |
|
500 $old_current_list = ''; |
|
501 $spaces = ''; |
|
502 $marker = '*'; |
|
503 $list_id = 0; |
|
504 $just_terminated = false; |
|
505 foreach ( $split as $tag ) |
|
506 { |
|
507 switch($tag) |
|
508 { |
|
509 case '<ul>': |
|
510 case '<ol>': |
|
511 $stack_height++; |
|
512 $just_terminated = false; |
|
513 if ( $stack_height > 1 ) |
|
514 $spaces .= $marker; |
|
515 |
|
516 $marker = ( $tag == 'ol' ) ? '#' : '*'; |
|
517 if ( $stack_height > 1 ) |
|
518 $current_list .= "\n"; |
|
519 |
|
520 break; |
|
521 case '</ul>': |
|
522 case '</ol>': |
|
523 $stack_height--; |
|
524 $spaces = substr($spaces, 1); |
|
525 |
|
526 if ( $stack_height == 0 ) |
|
527 { |
|
528 // rotate |
|
529 $text = str_replace_once("{$old_current_list}{$tag}", trim($current_list), $text); |
|
530 $current_list = ''; |
|
531 $old_current_list = ''; |
|
532 } |
|
533 $just_terminated = true; |
|
534 break; |
|
535 case '<li>': |
|
536 if ( $stack_height < 1 ) |
|
537 break; |
|
538 |
|
539 $current_list .= "{$spaces}{$marker} "; |
|
540 break; |
|
541 case '</li>': |
|
542 if ( $stack_height < 1 ) |
|
543 break; |
|
544 |
|
545 if ( !$just_terminated ) |
|
546 $current_list .= "\n"; |
|
547 |
|
548 $just_terminated = false; |
|
549 break; |
|
550 default: |
|
551 if ( $stack_height > 0 ) |
|
552 { |
|
553 $current_list .= trim($tag); |
|
554 } |
|
555 break; |
|
556 } |
|
557 if ( $stack_height > 0 ) |
|
558 { |
|
559 $old_current_list .= $tag; |
|
560 } |
|
561 } |
|
562 |
|
563 return $text; |
|
564 } |
|
565 |
|
566 public static function reverse_process_tables($text) |
|
567 { |
|
568 return $text; |
|
569 } |
|
570 |
|
571 /** |
523 * Parses internal links (wikilinks) in a block of text. |
572 * Parses internal links (wikilinks) in a block of text. |
524 * @param string Text to process |
573 * @param string Text to process |
525 * @param string Optional. If included will be used as a template instead of using the default syntax. |
574 * @param string Optional. If included will be used as a template instead of using the default syntax. |
526 * @return string |
575 * @return string |
527 */ |
576 */ |
842 ':]' => 'face-oops.png', |
896 ':]' => 'face-oops.png', |
843 ':oops:' => 'face-oops.png', |
897 ':oops:' => 'face-oops.png', |
844 ':-[' => 'face-embarassed.png', |
898 ':-[' => 'face-embarassed.png', |
845 ':[' => 'face-embarassed.png' |
899 ':[' => 'face-embarassed.png' |
846 ); |
900 ); |
847 /* |
|
848 $keys = array_keys($smileys); |
|
849 foreach($keys as $k) |
|
850 { |
|
851 $regex1 = '#([\W]+)'.preg_quote($k).'([\s\n\r\.]+)#s'; |
|
852 $regex2 = '\\1<img alt="'.$k.'" title="'.$k.'" src="'.scriptPath.'/images/smilies/'.$smileys[$k].'" style="border: 0;" />\\2'; |
|
853 $text = preg_replace($regex1, $regex2, $text); |
|
854 } |
|
855 */ |
|
856 |
901 |
857 // Strip out <nowiki> sections |
902 // Strip out <nowiki> sections |
858 //return '<pre>'.htmlspecialchars($text).'</pre>'; |
903 //return '<pre>'.htmlspecialchars($text).'</pre>'; |
859 $nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki); |
904 $nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki); |
860 |
905 |
861 for($i=0;$i<sizeof($nowiki[1]);$i++) |
906 for ( $i = 0; $i < count($nowiki[1]); $i++ ) |
862 { |
907 { |
863 $text = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text); |
908 $text = str_replace('<nowiki>' . $nowiki[1][$i] . '</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text); |
864 } |
909 } |
865 |
910 |
866 $keys = array_keys($smileys); |
911 foreach ( $smileys as $smiley => $smiley_path ) |
867 foreach($keys as $k) |
912 { |
868 { |
913 $hex_smiley = hexencode($smiley, '&#x', ';'); |
869 $t = hexencode($k, ' ', ''); |
914 $pfx = ( $complete_urls ) ? get_server_url() : ''; |
870 $t = trim($t); |
915 $text = str_replace(' ' . $smiley, |
871 $t = explode(' ', $t); |
916 ' <!--#smiley code="' . self::escape_parser_hint_attrib($smiley) . '"--><nowiki> |
872 $s = ''; |
917 <!-- The above is a reverse-parser hint --> |
873 foreach($t as $b) |
918 <img title="' . $hex_smiley . '" alt="' . $hex_smiley . '" src="' . $pfx . scriptPath . '/images/smilies/' . $smiley_path . '" |
874 { |
919 style="border: 0;" /> |
875 $s.='&#x'.$b.';'; |
920 </nowiki><!--#/smiley-->', $text); |
876 } |
|
877 $pfx = ( $complete_urls ) ? 'http' . ( isset($_SERVER['HTTPS']) ? 's' : '' ) . '://'.$_SERVER['HTTP_HOST'] : ''; |
|
878 $text = str_replace(' '.$k, ' <nowiki><img title="'.$s.'" alt="'.$s.'" src="'.$pfx.scriptPath.'/images/smilies/'.$smileys[$k].'" style="border: 0;" /></nowiki>', $text); |
|
879 } |
921 } |
880 //*/ |
922 //*/ |
881 |
923 |
882 // Reinsert <nowiki> sections |
924 // Reinsert <nowiki> sections |
883 for($i=0;$i<$nw;$i++) |
925 for ( $i = 0; $i < $nw; $i++ ) |
884 { |
926 { |
885 $text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text); |
927 $text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text); |
886 } |
928 } |
887 |
929 |
888 return $text; |
930 return $text; |
889 } |
931 } |
890 |
|
891 /* |
|
892 * **** DEPRECATED **** |
|
893 * Replaces some critical characters in a string with MySQL-safe equivalents |
|
894 * @param $text string the text to escape |
|
895 * @return array key 0 is the escaped text, key 1 is the character tag |
|
896 * / |
|
897 |
|
898 public static function escape_page_text($text) |
|
899 { |
|
900 $char_tag = md5(microtime() . mt_rand()); |
|
901 $text = str_replace("'", "{APOS:$char_tag}", $text); |
|
902 $text = str_replace('"', "{QUOT:$char_tag}", $text); |
|
903 $text = str_replace("\\", "{SLASH:$char_tag}", $text); |
|
904 return Array($text, $char_tag); |
|
905 } |
|
906 */ |
|
907 |
|
908 /* **** DEPRECATED **** |
|
909 * Reverses the result of RenderMan::escape_page_text(). |
|
910 * @param $text string the text to unescape |
|
911 * @param $char_tag string the character tag |
|
912 * @return string |
|
913 * / |
|
914 |
|
915 public static function unescape_page_text($text, $char_tag) |
|
916 { |
|
917 $text = str_replace("{APOS:$char_tag}", "'", $text); |
|
918 $text = str_replace("{QUOT:$char_tag}", '"', $text); |
|
919 $text = str_replace("{SLASH:$char_tag}", "\\", $text); |
|
920 return $text; |
|
921 } |
|
922 */ |
|
923 |
932 |
924 /** |
933 /** |
925 * Generates a summary of the differences between two texts, and formats it as XHTML. |
934 * Generates a summary of the differences between two texts, and formats it as XHTML. |
926 * @param $str1 string the first block of text |
935 * @param $str1 string the first block of text |
927 * @param $str2 string the second block of text |
936 * @param $str2 string the second block of text |