1
+ − 1
<?php
+ − 2
/*
+ − 3
* Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
21
663fcf528726
Updated all version numbers back to Banshee; a few preliminary steps towards full UTF-8 support in page URLs
Dan
diff
changeset
+ − 4
* Version 1.0 (Banshee)
1
+ − 5
* render.php - handles fetching pages and parsing them into HTML
+ − 6
* Copyright (C) 2006-2007 Dan Fuhry
+ − 7
*
+ − 8
* This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ − 9
* as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ − 10
*
+ − 11
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ − 12
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ − 13
*/
+ − 14
+ − 15
class RenderMan {
+ − 16
+ − 17
function strToPageID($string)
+ − 18
{
+ − 19
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 20
$k = array_keys($paths->nslist);
+ − 21
for($i=0;$i<sizeof($paths->nslist);$i++)
+ − 22
{
+ − 23
$ln = strlen($paths->nslist[$k[$i]]);
+ − 24
if(substr($string, 0, $ln) == $paths->nslist[$k[$i]])
+ − 25
{
+ − 26
$ns = $k[$i];
+ − 27
$pg = substr($string, strlen($paths->nslist[$ns]), strlen($string));
+ − 28
}
+ − 29
}
+ − 30
return Array($pg, $ns);
+ − 31
}
+ − 32
+ − 33
function getPage($page_id, $namespace, $wiki = 1, $smilies = true, $filter_links = true, $redir = true, $render = true)
+ − 34
{
+ − 35
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 36
dc_here('render: page requested<br />ID/namespace: '."$page_id, $namespace<br />Wiki mode: $wiki<br />Smilies: ".(string)$smilies."<br />Allow redirects: ".(string)$redir);
+ − 37
+ − 38
$perms =& $session;
+ − 39
+ − 40
if ( $page_id != $paths->cpage['urlname_nons'] || $namespace != $paths->namespace )
+ − 41
{
+ − 42
unset($perms);
+ − 43
unset($perms); // PHP <5.1.5 Zend bug
+ − 44
$perms = $session->fetch_page_acl($page_id, $namespace);
+ − 45
}
+ − 46
+ − 47
if(!$perms->get_permissions('read'))
+ − 48
return 'Access denied ('.$paths->nslist[$namespace].$page_id.')';
+ − 49
+ − 50
if($wiki == 0 || $render == false)
+ − 51
{
+ − 52
if(!$perms->get_permissions('view_source'))
+ − 53
{
+ − 54
return 'Access denied ('.$paths->nslist[$namespace].$page_id.')';
+ − 55
}
+ − 56
}
+ − 57
+ − 58
$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).'\';');
+ − 59
if ( !$q )
+ − 60
{
+ − 61
$db->_die('Method called was: RenderMan::getPage(\''.$page_id.'\', \''.$namespace.'\');.');
+ − 62
}
+ − 63
if ( $db->numrows() < 1 )
+ − 64
{
+ − 65
return false;
+ − 66
}
+ − 67
$row = $db->fetchrow();
+ − 68
$db->free_result();
+ − 69
+ − 70
$message = $row['page_text'];
+ − 71
$chartag = $row['char_tag'];
+ − 72
unset($row); // Free some memory
+ − 73
+ − 74
if ( preg_match('#^\#redirect \[\[(.+?)\]\]#', $message, $m) && $redir && !isset($_GET['redirect']) || ( isset($_GET['redirect']) && $_GET['redirect'] != 'no' ) )
+ − 75
{
+ − 76
dc_here('render: looks like a redirect page to me...');
+ − 77
$old = $paths->cpage;
+ − 78
$a = RenderMan::strToPageID($m[1]);
+ − 79
$a[0] = str_replace(' ', '_', $a[0]);
+ − 80
+ − 81
$pageid = str_replace(' ', '_', $paths->nslist[$a[1]] . $a[0]);
+ − 82
$paths->page = $pageid;
+ − 83
$paths->cpage = $paths->pages[$pageid];
+ − 84
//die('<pre>'.print_r($paths->cpage,true).'</pre>');
+ − 85
+ − 86
dc_here('render: wreckin\' $template, and reloading the theme vars to match the new page<br />This might get messy!');
+ − 87
+ − 88
unset($template);
+ − 89
unset($GLOBALS['template']);
+ − 90
+ − 91
$GLOBALS['template'] = new template();
+ − 92
global $template;
+ − 93
+ − 94
$template->template(); // Tear down and rebuild the template parser
+ − 95
$template->load_theme($session->theme, $session->style);
+ − 96
+ − 97
$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 */);
+ − 98
+ − 99
return $data;
+ − 100
}
+ − 101
else if(preg_match('#^\#redirect \[\[(.+?)\]\]#', $message, $m) && isset($_GET['redirect']) && $_GET['redirect'] == 'no')
+ − 102
{
+ − 103
dc_here('render: looks like a redirect page to me...');
+ − 104
dc_here('render: skipping redirect as requested on URI');
+ − 105
preg_match('#^\#redirect \[\[(.+)\]\]#', $message, $m);
+ − 106
$m[1] = str_replace(' ', '_', $m[1]);
+ − 107
$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);
+ − 108
}
+ − 109
$session->disallow_password_grab();
+ − 110
dc_here('render: alright, got the text, formatting...');
+ − 111
return ($render) ? RenderMan::render($message, $wiki, $smilies, $filter_links) : $message;
+ − 112
}
+ − 113
+ − 114
function getTemplate($id, $parms)
+ − 115
{
+ − 116
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 117
dc_here('render: template requested: '.$id);
+ − 118
if(!isset($paths->pages[$paths->nslist['Template'].$id]))
+ − 119
{
+ − 120
return '[['.$paths->nslist['Template'].$id.']]';
+ − 121
}
+ − 122
if(isset($paths->template_cache[$id]))
+ − 123
{
+ − 124
$text = $paths->template_cache[$id];
+ − 125
}
+ − 126
else
+ − 127
{
+ − 128
$text = RenderMan::getPage($id, 'Template', 0, true, true, 0);
+ − 129
$paths->template_cache[$id] = $text;
+ − 130
}
+ − 131
+ − 132
$text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '', $text);
+ − 133
$text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '\\1', $text);
+ − 134
+ − 135
preg_match_all('#\(_([0-9]+)_\)#', $text, $matchlist);
+ − 136
+ − 137
foreach($matchlist[1] as $m)
+ − 138
{
+ − 139
if(isset($parms[((int)$m)+1]))
+ − 140
{
+ − 141
$p = $parms[((int)$m)+1];
+ − 142
}
+ − 143
else
+ − 144
{
+ − 145
$p = '<b>Notice:</b> RenderMan::getTemplate(): Parameter '.$m.' is not set';
+ − 146
}
+ − 147
$text = str_replace('(_'.$m.'_)', $p, $text);
+ − 148
}
+ − 149
$text = RenderMan::include_templates($text);
+ − 150
return $text;
+ − 151
}
+ − 152
+ − 153
function fetch_template_text($id)
+ − 154
{
+ − 155
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 156
dc_here('render: template raw data requested: '.$id);
+ − 157
if(!isset($paths->pages[$paths->nslist['Template'].$id]))
+ − 158
{
+ − 159
return '[['.$paths->nslist['Template'].$id.']]';
+ − 160
}
+ − 161
if(isset($paths->template_cache[$id]))
+ − 162
{
+ − 163
$text = $paths->template_cache[$id];
+ − 164
}
+ − 165
else
+ − 166
{
+ − 167
$text = RenderMan::getPage($id, 'Template', 0, false, false, false, false);
+ − 168
$paths->template_cache[$id] = $text;
+ − 169
}
+ − 170
+ − 171
if ( is_string($text) )
+ − 172
{
+ − 173
$text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '', $text);
+ − 174
$text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '\\1', $text);
+ − 175
}
+ − 176
+ − 177
return $text;
+ − 178
}
+ − 179
+ − 180
function render($text, $wiki = 1, $smilies = true, $filter_links = true)
+ − 181
{
+ − 182
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 183
if($smilies)
+ − 184
{
+ − 185
$text = RenderMan::smilieyize($text);
+ − 186
}
+ − 187
if($wiki == 1)
+ − 188
{
+ − 189
$text = RenderMan::next_gen_wiki_format($text);
+ − 190
}
+ − 191
elseif($wiki == 2)
+ − 192
{
+ − 193
$text = $template->tplWikiFormat($text);
+ − 194
}
+ − 195
return $text;
+ − 196
}
+ − 197
+ − 198
function PlainTextRender($text, $wiki = 1, $smilies = false, $filter_links = true)
+ − 199
{
+ − 200
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 201
if($smilies)
+ − 202
{
+ − 203
$text = RenderMan::smilieyize($text);
+ − 204
}
+ − 205
if($wiki == 1)
+ − 206
{
+ − 207
$text = RenderMan::next_gen_wiki_format($text, true);
+ − 208
}
+ − 209
elseif($wiki == 2)
+ − 210
{
+ − 211
$text = $template->tplWikiFormat($text);
+ − 212
}
+ − 213
return $text;
+ − 214
}
+ − 215
+ − 216
function next_gen_wiki_format($text, $plaintext = false, $filter_links = true, $do_params = false)
+ − 217
{
+ − 218
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 219
$random_id = md5( time() . mt_rand() );
+ − 220
+ − 221
// Strip out <nowiki> sections and PHP code
+ − 222
+ − 223
$php = preg_match_all('#<\?php(.*?)\?>#is', $text, $phpsec);
+ − 224
+ − 225
for($i=0;$i<sizeof($phpsec[1]);$i++)
+ − 226
{
+ − 227
$text = str_replace('<?php'.$phpsec[1][$i].'?>', '{PHP:'.$random_id.':'.$i.'}', $text);
+ − 228
}
+ − 229
+ − 230
$nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki);
+ − 231
+ − 232
for($i=0;$i<sizeof($nowiki[1]);$i++)
+ − 233
{
+ − 234
$text = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text);
+ − 235
}
+ − 236
+ − 237
$text = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $text);
+ − 238
if ( $paths->namespace == 'Template' )
+ − 239
{
+ − 240
$text = preg_replace('/<nodisplay>(.*?)<\/nodisplay>/is', '', $text);
+ − 241
}
+ − 242
+ − 243
if ( !$plaintext )
+ − 244
{
+ − 245
// Process images
+ − 246
+ − 247
$j = preg_match_all('#\[\[:'.$paths->nslist['File'].'([\w\s0-9_\(\)!@%\^\+\|\.-]+?)\|([0-9]+)\|([0-9]+)\]\]#is', $text, $matchlist);
+ − 248
$matches = Array();
+ − 249
$matches['images'] =& $matchlist[1];
+ − 250
$matches['widths'] =& $matchlist[2];
+ − 251
$matches['heights'] =& $matchlist[3];
+ − 252
for($i=0;$i<sizeof($matchlist[1]);$i++)
+ − 253
{
+ − 254
if(isPage($paths->nslist['File'].$matches['images'][$i])) $text = str_replace('[[:'.$paths->nslist['File'].$matches['images'][$i].'|'.$matches['widths'][$i].'|'.$matches['heights'][$i].']]',
+ − 255
'<nowiki><a href="'.makeUrlNS('File', $matches['images'][$i]).'"><img alt="'.$matches['images'][$i].'" style="border: 0" src="'.makeUrlNS('Special', 'DownloadFile/'.$matches['images'][$i], 'preview&width='.$matches['widths'][$i].'&height='.$matches['heights'][$i]).'" /></a></nowiki>',
+ − 256
$text);
+ − 257
}
+ − 258
+ − 259
$j = preg_match_all('#\[\[:'.$paths->nslist['File'].'([\w\s0-9_\(\)!@%\^\+\|\.-]+?)\]\]#is', $text, $matchlist);
+ − 260
$matches = Array();
+ − 261
$matches['images'] = $matchlist[1];
+ − 262
for($i=0;$i<sizeof($matchlist[1]);$i++)
+ − 263
{
+ − 264
if(isPage($paths->nslist['File'].$matches['images'][$i])) $text = str_replace('[[:'.$paths->nslist['File'].$matches['images'][$i].']]',
+ − 265
'<nowiki><a href="'.makeUrlNS('File', $matches['images'][$i]).'"><img alt="'.$matches['images'][$i].'" style="border: 0" src="'.makeUrlNS('Special', 'DownloadFile/'.$matches['images'][$i]).'" /></a></nowiki>',
+ − 266
$text);
+ − 267
}
+ − 268
+ − 269
}
+ − 270
+ − 271
if($do_params)
+ − 272
{
+ − 273
preg_match_all('#\(_([0-9]+)_\)#', $text, $matchlist);
+ − 274
foreach($matchlist[1] as $m)
+ − 275
{
+ − 276
$text = str_replace('(_'.$m.'_)', $paths->getParam((int)$m), $text);
+ − 277
}
+ − 278
}
+ − 279
+ − 280
$text = RenderMan::include_templates($text);
+ − 281
+ − 282
$text = process_tables($text);
+ − 283
+ − 284
$wiki =& Text_Wiki::singleton('Mediawiki');
+ − 285
if($plaintext)
+ − 286
{
+ − 287
$wiki->setRenderConf('Plain', 'wikilink', 'view_url', contentPath);
+ − 288
$result = $wiki->transform($text, 'Plain');
+ − 289
}
+ − 290
else
+ − 291
{
+ − 292
$wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath);
+ − 293
$wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external');
+ − 294
$result = $wiki->transform($text, 'Xhtml');
+ − 295
}
+ − 296
+ − 297
// Reinsert <nowiki> sections
+ − 298
for($i=0;$i<$nw;$i++)
+ − 299
{
+ − 300
$result = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', $nowiki[1][$i], $result);
+ − 301
}
+ − 302
+ − 303
// Reinsert PHP
+ − 304
for($i=0;$i<$php;$i++)
+ − 305
{
+ − 306
$result = str_replace('{PHP:'.$random_id.':'.$i.'}', '<?php'.$phpsec[1][$i].'?>', $result);
+ − 307
}
+ − 308
+ − 309
return $result;
+ − 310
+ − 311
}
+ − 312
+ − 313
function wikiFormat($message, $filter_links = true, $do_params = false, $plaintext = false) {
+ − 314
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 315
+ − 316
return RenderMan::next_gen_wiki_format($message, $plaintext, $filter_links, $do_params);
+ − 317
+ − 318
$random_id = md5( time() . mt_rand() );
+ − 319
+ − 320
// Strip out <nowiki> sections
+ − 321
$nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $message, $nowiki);
+ − 322
+ − 323
if(!$plaintext)
+ − 324
{
+ − 325
+ − 326
//return '<pre>'.print_r($nowiki,true).'</pre>';
+ − 327
+ − 328
for($i=0;$i<sizeof($nowiki[1]);$i++)
+ − 329
{
+ − 330
$message = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $message);
+ − 331
}
+ − 332
+ − 333
$message = preg_replace('/<noinclude>(.*?)<\/noinclude>/is', '\\1', $message);
+ − 334
+ − 335
//return '<pre>'.htmlspecialchars($message).'</pre>';
+ − 336
+ − 337
$j = preg_match_all('#\[\[:'.$paths->nslist['File'].'([\w\s0-9_\(\)!@%\^\+\|\.-]+?)\|([0-9]+)\|([0-9]+)\]\]#is', $message, $matchlist);
+ − 338
$matches = Array();
+ − 339
$matches['images'] = $matchlist[1];
+ − 340
$matches['widths'] = $matchlist[2];
+ − 341
$matches['heights'] = $matchlist[3];
+ − 342
for($i=0;$i<sizeof($matchlist[1]);$i++)
+ − 343
{
+ − 344
if(isPage($paths->nslist['File'].$matches['images'][$i])) $message = str_replace('[[:'.$paths->nslist['File'].$matches['images'][$i].'|'.$matches['widths'][$i].'|'.$matches['heights'][$i].']]',
+ − 345
'<nowiki><a href="'.makeUrlNS('File', $matches['images'][$i]).'"><img alt="'.$matches['images'][$i].'" style="border: 0" src="'.makeUrlNS('Special', 'DownloadFile/'.$matches['images'][$i], 'preview&width='.$matches['widths'][$i].'&height='.$matches['heights'][$i]).'" /></a></nowiki>',
+ − 346
$message);
+ − 347
}
+ − 348
+ − 349
$j = preg_match_all('#\[\[:'.$paths->nslist['File'].'([\w\s0-9_\(\)!@%\^\+\|\.-]+?)\]\]#is', $message, $matchlist);
+ − 350
$matches = Array();
+ − 351
$matches['images'] = $matchlist[1];
+ − 352
for($i=0;$i<sizeof($matchlist[1]);$i++)
+ − 353
{
+ − 354
if(isPage($paths->nslist['File'].$matches['images'][$i])) $message = str_replace('[[:'.$paths->nslist['File'].$matches['images'][$i].']]',
+ − 355
'<nowiki><a href="'.makeUrlNS('File', $matches['images'][$i]).'"><img alt="'.$matches['images'][$i].'" style="border: 0" src="'.makeUrlNS('Special', 'DownloadFile/'.$matches['images'][$i]).'" /></a></nowiki>',
+ − 356
$message);
+ − 357
}
+ − 358
+ − 359
}
+ − 360
+ − 361
if($do_params)
+ − 362
{
+ − 363
preg_match_all('#\(_([0-9]+)_\)#', $message, $matchlist);
+ − 364
foreach($matchlist[1] as $m)
+ − 365
{
+ − 366
$message = str_replace('(_'.$m.'_)', $paths->getParam((int)$m), $message);
+ − 367
}
+ − 368
}
+ − 369
+ − 370
$message = RenderMan::include_templates($message);
+ − 371
+ − 372
// Reinsert <nowiki> sections
+ − 373
for($i=0;$i<$nw;$i++)
+ − 374
{
+ − 375
$message = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $message);
+ − 376
}
+ − 377
+ − 378
$message = process_tables($message);
+ − 379
//if($message2 != $message) return '<pre>'.htmlspecialchars($message2).'</pre>';
+ − 380
//$message = str_replace(array('<table>', '</table>'), array('<nowiki><table>', '</table></nowiki>'), $message);
+ − 381
+ − 382
$wiki =& Text_Wiki::singleton('Mediawiki');
+ − 383
if($plaintext)
+ − 384
{
+ − 385
$wiki->setRenderConf('Plain', 'wikilink', 'view_url', contentPath);
+ − 386
$result = $wiki->transform($message, 'Plain');
+ − 387
} else {
+ − 388
$wiki->setRenderConf('Xhtml', 'wikilink', 'view_url', contentPath);
+ − 389
$wiki->setRenderConf('Xhtml', 'Url', 'css_descr', 'external');
+ − 390
$result = $wiki->transform($message, 'Xhtml');
+ − 391
}
+ − 392
+ − 393
// HTML fixes
+ − 394
$result = preg_replace('#<tr>([\s]*?)<\/tr>#is', '', $result);
+ − 395
$result = preg_replace('#<p>([\s]*?)<\/p>#is', '', $result);
+ − 396
$result = preg_replace('#<br />([\s]*?)<table#is', '<table', $result);
+ − 397
$result = str_replace("<pre><code>\n", "<pre><code>", $result);
+ − 398
$result = preg_replace("/<p><table([^>]*?)><\/p>/", "<table\\1>", $result);
+ − 399
$result = str_replace("<br />\n</td>", "\n</td>", $result);
+ − 400
$result = str_replace("<p><tr>", "<tr>", $result);
+ − 401
$result = str_replace("<tr><br />", "<tr>", $result);
+ − 402
$result = str_replace("</tr><br />", "</tr>", $result);
+ − 403
$result = str_replace("</table></p>", "</table>", $result);
+ − 404
$result = str_replace("</table><br />", "</table>", $result);
+ − 405
$result = preg_replace('/<\/table>$/', "</table><br /><br />", $result);
+ − 406
+ − 407
$result = str_replace('<nowiki>', '<nowiki>', $result);
+ − 408
$result = str_replace('</nowiki>', '</nowiki>', $result);
+ − 409
+ − 410
return $result;
+ − 411
}
+ − 412
+ − 413
function destroy_javascript($message, $_php = false)
+ − 414
{
+ − 415
$message = preg_replace('#<(script|object|applet|embed|iframe|frame|form|input|select)(.*?)>#is', '<\\1\\2>', $message);
+ − 416
$message = preg_replace('#</(script|object|applet|embed|iframe|frame|form|input|select)(.*?)>#is', '</\\1\\2>', $message);
+ − 417
$message = preg_replace('#(javascript|script|activex|chrome|about|applet):#is', '\\1:', $message);
+ − 418
if ( $_php )
+ − 419
{
+ − 420
// Left in only for compatibility
+ − 421
$message = preg_replace('#<(.*?)>#is', '<\\1>', $message);
+ − 422
$message = preg_replace('#<(.*?)>#is', '<\\1>', $message);
+ − 423
$message = preg_replace('#<(\?|\?php|%)(.*?)(\?|%)>#is', '<\\1\\2\\3>', $message);
+ − 424
// strip <a href="foo" onclick="bar();">-type attacks
+ − 425
$message = preg_replace('#<([a-zA-Z:\-]+) (.*?)on([A-Za-z]*)=(.*?)>#is', '<\\1\\2on\\3=\\4>', $message);
+ − 426
}
+ − 427
return $message;
+ − 428
}
+ − 429
+ − 430
function strip_php($message)
+ − 431
{
+ − 432
return RenderMan::destroy_javascript($message, true);
+ − 433
}
+ − 434
+ − 435
function sanitize_html($text)
+ − 436
{
+ − 437
$text = htmlspecialchars($text);
+ − 438
$allowed_tags = Array('b', 'i', 'u', 'pre', 'code', 'tt', 'br', 'p', 'nowiki', '!--([^.]+)--');
+ − 439
foreach($allowed_tags as $t)
+ − 440
{
+ − 441
$text = preg_replace('#<'.$t.'>(.*?)</'.$t.'>#is', '<'.$t.'>\\1</'.$t.'>', $text);
+ − 442
$text = preg_replace('#<'.$t.' />#is', '<'.$t.' />', $text);
+ − 443
$text = preg_replace('#<'.$t.'>#is', '<'.$t.'>', $text);
+ − 444
}
+ − 445
return $text;
+ − 446
}
+ − 447
+ − 448
/* *
+ − 449
* Replaces template inclusions with the templates
+ − 450
* @param string $message The text to format
+ − 451
* @return string
+ − 452
* /
+ − 453
+ − 454
function old_include_templates($message)
+ − 455
{
+ − 456
$random_id = md5( time() . mt_rand() );
+ − 457
preg_match_all('#\{\{(.+?)\}\}#s', $message, $matchlist);
+ − 458
foreach($matchlist[1] as $m)
+ − 459
{
+ − 460
$mn = $m;
+ − 461
// Strip out wikilinks and re-add them after the explosion (because of the "|")
+ − 462
preg_match_all('#\[\[(.+?)\]\]#i', $m, $linklist);
+ − 463
//echo '<pre>'.print_r($linklist, true).'</pre>';
+ − 464
for($i=0;$i<sizeof($linklist[1]);$i++)
+ − 465
{
+ − 466
$mn = str_replace('[['.$linklist[1][$i].']]', '{WIKILINK:'.$random_id.':'.$i.'}', $mn);
+ − 467
}
+ − 468
+ − 469
$ar = explode('|', $mn);
+ − 470
+ − 471
for($j=0;$j<sizeof($ar);$j++)
+ − 472
{
+ − 473
for($i=0;$i<sizeof($linklist[1]);$i++)
+ − 474
{
+ − 475
$ar[$j] = str_replace('{WIKILINK:'.$random_id.':'.$i.'}', '[['.$linklist[1][$i].']]', $ar[$j]);
+ − 476
}
+ − 477
}
+ − 478
+ − 479
$tp = $ar[0];
+ − 480
unset($ar[0]);
+ − 481
$tp = str_replace(' ', '_', $tp);
+ − 482
$message = str_replace('{{'.$m.'}}', RenderMan::getTemplate($tp, $ar), $message);
+ − 483
}
+ − 484
return $message;
+ − 485
}
+ − 486
*/
+ − 487
+ − 488
/**
+ − 489
* Parses a partial template tag in wikitext, and return an array with the parameters.
+ − 490
* @param string The portion of the template tag that contains the parameters. Example:
+ − 491
* <code>
+ − 492
* foo = lorem ipsum
+ − 493
* bar = dolor sit amet
+ − 494
* </code>
+ − 495
* @return array Example:
+ − 496
* [foo] => lorem ipsum
+ − 497
* [bar] => dolor sit amet
+ − 498
*/
+ − 499
+ − 500
function parse_template_vars($input)
+ − 501
{
+ − 502
$input = explode("\n", trim( $input ));
+ − 503
$parms = Array();
+ − 504
$current_line = '';
+ − 505
$current_parm = '';
+ − 506
foreach ( $input as $num => $line )
+ − 507
{
+ − 508
if ( preg_match('/^([ ]*?)([A-z0-9_]+?)([ ]*?)=([ ]*?)(.+?)$/i', $line, $matches) )
+ − 509
{
+ − 510
$parm =& $matches[2];
+ − 511
$text =& $matches[5];
+ − 512
if ( $parm == $current_parm )
+ − 513
{
+ − 514
$current_line .= $text;
+ − 515
}
+ − 516
else
+ − 517
{
+ − 518
// New parameter
+ − 519
if ( $current_parm != '' )
+ − 520
$parms[$current_parm] = $current_line;
+ − 521
$current_line = $text;
+ − 522
$current_parm = $parm;
+ − 523
}
+ − 524
}
+ − 525
else if ( $num == 0 )
+ − 526
{
+ − 527
// Syntax error
+ − 528
return false;
+ − 529
}
+ − 530
else
+ − 531
{
+ − 532
$current_line .= "\n$line";
+ − 533
}
+ − 534
}
+ − 535
if ( !empty($current_parm) && !empty($current_line) )
+ − 536
{
+ − 537
$parms[$current_parm] = $current_line;
+ − 538
}
+ − 539
return $parms;
+ − 540
}
+ − 541
+ − 542
/**
+ − 543
* Processes all template tags within a block of wikitext.
+ − 544
* @param string The text to process
+ − 545
* @return string Formatted text
+ − 546
* @example
+ − 547
* <code>
+ − 548
$text = '{{Template
+ − 549
parm1 = Foo
+ − 550
parm2 = Bar
+ − 551
}}';
+ − 552
$text = include_templates($text);
+ − 553
* </code>
+ − 554
*/
+ − 555
+ − 556
function include_templates($text)
+ − 557
{
+ − 558
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 559
$template_regex = "/\{\{([A-z0-9_-]+?)((\n([ ]*?)[A-z0-9]+([ ]*?)=([ ]*?)(.+?))*)\}\}/is";
+ − 560
if ( $count = preg_match_all($template_regex, $text, $matches) )
+ − 561
{
+ − 562
for ( $i = 0; $i < $count; $i++ )
+ − 563
{
+ − 564
$parmsection = trim($matches[2][$i]);
+ − 565
if ( !empty($parmsection) )
+ − 566
{
+ − 567
$parms = RenderMan::parse_template_vars($parmsection);
+ − 568
foreach ( $parms as $j => $parm )
+ − 569
{
+ − 570
$parms[$j] = $parm;
+ − 571
}
+ − 572
}
+ − 573
else
+ − 574
{
+ − 575
$parms = Array();
+ − 576
}
+ − 577
if ( $tpl_code = RenderMan::fetch_template_text($matches[1][$i]) )
+ − 578
{
+ − 579
$parser = $template->makeParserText($tpl_code);
+ − 580
$parser->assign_vars($parms);
+ − 581
$text = str_replace($matches[0][$i], $parser->run(), $text);
+ − 582
}
+ − 583
}
+ − 584
}
+ − 585
return $text;
+ − 586
}
+ − 587
+ − 588
/**
+ − 589
* Preprocesses an HTML text string prior to being sent to MySQL.
+ − 590
* @param string $text
+ − 591
* @param bool $strip_all_php - if true, strips all PHP regardless of user permissions. Else, strips PHP only if user level < USER_LEVEL_ADMIN.
+ − 592
*/
+ − 593
function preprocess_text($text, $strip_all_php = true, $sqlescape = true)
+ − 594
{
+ − 595
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 596
$random_id = md5( time() . mt_rand() );
+ − 597
+ − 598
$can_do_php = ( $session->get_permissions('php_in_pages') && !$strip_all_php );
+ − 599
+ − 600
if ( !$can_do_php )
+ − 601
{
24
+ − 602
$text = sanitize_html($text, true);
1
+ − 603
// If we can't do PHP, we can't do Javascript either.
+ − 604
$text = RenderMan::destroy_javascript($text);
+ − 605
}
+ − 606
+ − 607
// Strip out <nowiki> sections and PHP code
+ − 608
+ − 609
$php = preg_match_all('#(<|<)\?php(.*?)\?(>|>)#is', $text, $phpsec);
+ − 610
+ − 611
//die('<pre>'.htmlspecialchars(print_r($phpsec, true))."\n".htmlspecialchars(print_r($text, true)).'</pre>');
+ − 612
+ − 613
for($i=0;$i<sizeof($phpsec[1]);$i++)
+ − 614
{
+ − 615
$text = str_replace($phpsec[0][$i], '{PHP:'.$random_id.':'.$i.'}', $text);
+ − 616
}
+ − 617
+ − 618
$nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki);
+ − 619
+ − 620
for($i=0;$i<sizeof($nowiki[1]);$i++)
+ − 621
{
+ − 622
$text = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text);
+ − 623
}
+ − 624
+ − 625
$text = str_replace('~~~~~', date('G:i, j F Y (T)'), $text);
+ − 626
$text = str_replace('~~~~', "[[User:$session->username|$session->username]] ".date('G:i, j F Y (T)'), $text);
+ − 627
$text = str_replace('~~~', "[[User:$session->username|$session->username]] ", $text);
+ − 628
+ − 629
// Reinsert <nowiki> sections
+ − 630
for($i=0;$i<$nw;$i++)
+ − 631
{
+ − 632
$text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text);
+ − 633
}
+ − 634
// Reinsert PHP
+ − 635
for($i=0;$i<$php;$i++)
+ − 636
{
+ − 637
$phsec = ''.$phpsec[1][$i].'?php'.$phpsec[2][$i].'?'.$phpsec[3][$i].'';
+ − 638
if ( $strip_all_php )
+ − 639
$phsec = htmlspecialchars($phsec);
+ − 640
$text = str_replace('{PHP:'.$random_id.':'.$i.'}', $phsec, $text);
+ − 641
}
+ − 642
+ − 643
$text = ( $sqlescape ) ? $db->escape($text) : $text;
+ − 644
+ − 645
return $text;
+ − 646
}
+ − 647
+ − 648
function smilieyize($text, $complete_urls = false)
+ − 649
{
+ − 650
+ − 651
$random_id = md5( time() . mt_rand() );
+ − 652
+ − 653
// Smileys array - eventually this will be fetched from the database by
+ − 654
// RenderMan::initSmileys during initialization, but it will all be hardcoded for beta 2
+ − 655
+ − 656
$smileys = Array(
+ − 657
'O:-)' => 'face-angel.png',
+ − 658
'O:)' => 'face-angel.png',
+ − 659
'O=)' => 'face-angel.png',
+ − 660
':-)' => 'face-smile.png',
+ − 661
':)' => 'face-smile.png',
+ − 662
'=)' => 'face-smile-big.png',
+ − 663
':-(' => 'face-sad.png',
+ − 664
':(' => 'face-sad.png',
+ − 665
';(' => 'face-sad.png',
+ − 666
':-O' => 'face-surprise.png',
+ − 667
';-)' => 'face-wink.png',
+ − 668
';)' => 'face-wink.png',
+ − 669
'8-)' => 'face-glasses.png',
+ − 670
'8)' => 'face-glasses.png',
+ − 671
':-D' => 'face-grin.png',
+ − 672
':D' => 'face-grin.png',
+ − 673
'=D' => 'face-grin.png',
+ − 674
':-*' => 'face-kiss.png',
+ − 675
':*' => 'face-kiss.png',
+ − 676
'=*' => 'face-kiss.png',
+ − 677
':\'(' => 'face-crying.png',
+ − 678
':-|' => 'face-plain.png',
+ − 679
':-\\' => 'face-plain.png',
+ − 680
':-/' => 'face-plain.png',
+ − 681
':joke:' => 'face-plain.png',
+ − 682
']:->' => 'face-devil-grin.png',
+ − 683
':kiss:' => 'face-kiss.png',
+ − 684
':-P' => 'face-tongue-out.png',
+ − 685
':P' => 'face-tongue-out.png',
+ − 686
':-p' => 'face-tongue-out.png',
+ − 687
':p' => 'face-tongue-out.png',
+ − 688
':-X' => 'face-sick.png',
+ − 689
':X' => 'face-sick.png',
+ − 690
':sick:' => 'face-sick.png',
+ − 691
':-]' => 'face-oops.png',
+ − 692
':]' => 'face-oops.png',
+ − 693
':oops:' => 'face-oops.png',
+ − 694
':-[' => 'face-embarassed.png',
+ − 695
':[' => 'face-embarassed.png'
+ − 696
);
+ − 697
/*
+ − 698
$keys = array_keys($smileys);
+ − 699
foreach($keys as $k)
+ − 700
{
+ − 701
$regex1 = '#([\W]+)'.preg_quote($k).'([\s\n\r\.]+)#s';
+ − 702
$regex2 = '\\1<img alt="'.$k.'" title="'.$k.'" src="'.scriptPath.'/images/smilies/'.$smileys[$k].'" style="border: 0;" />\\2';
+ − 703
$text = preg_replace($regex1, $regex2, $text);
+ − 704
}
+ − 705
*/
+ − 706
+ − 707
// Strip out <nowiki> sections
+ − 708
//return '<pre>'.htmlspecialchars($text).'</pre>';
+ − 709
$nw = preg_match_all('#<nowiki>(.*?)<\/nowiki>#is', $text, $nowiki);
+ − 710
+ − 711
for($i=0;$i<sizeof($nowiki[1]);$i++)
+ − 712
{
+ − 713
$text = str_replace('<nowiki>'.$nowiki[1][$i].'</nowiki>', '{NOWIKI:'.$random_id.':'.$i.'}', $text);
+ − 714
}
+ − 715
+ − 716
$keys = array_keys($smileys);
+ − 717
foreach($keys as $k)
+ − 718
{
+ − 719
$t = str_hex($k);
+ − 720
$t = explode(' ', $t);
+ − 721
$s = '';
+ − 722
foreach($t as $b)
+ − 723
{
+ − 724
$s.='&#x'.$b.';';
+ − 725
}
+ − 726
$pfx = ( $complete_urls ) ? 'http' . ( isset($_SERVER['HTTPS']) ? 's' : '' ) . '://'.$_SERVER['HTTP_HOST'] : '';
+ − 727
$text = str_replace(' '.$k, ' <nowiki><img title="'.$s.'" alt="'.$s.'" src="'.$pfx.scriptPath.'/images/smilies/'.$smileys[$k].'" style="border: 0;" /></nowiki>', $text);
+ − 728
}
+ − 729
//*/
+ − 730
+ − 731
// Reinsert <nowiki> sections
+ − 732
for($i=0;$i<$nw;$i++)
+ − 733
{
+ − 734
$text = str_replace('{NOWIKI:'.$random_id.':'.$i.'}', '<nowiki>'.$nowiki[1][$i].'</nowiki>', $text);
+ − 735
}
+ − 736
+ − 737
return $text;
+ − 738
}
+ − 739
+ − 740
/*
+ − 741
* **** DEPRECATED ****
+ − 742
* Replaces some critical characters in a string with MySQL-safe equivalents
+ − 743
* @param $text string the text to escape
+ − 744
* @return array key 0 is the escaped text, key 1 is the character tag
+ − 745
* /
+ − 746
+ − 747
function escape_page_text($text)
+ − 748
{
+ − 749
$char_tag = md5(microtime() . mt_rand());
+ − 750
$text = str_replace("'", "{APOS:$char_tag}", $text);
+ − 751
$text = str_replace('"', "{QUOT:$char_tag}", $text);
+ − 752
$text = str_replace("\\", "{SLASH:$char_tag}", $text);
+ − 753
return Array($text, $char_tag);
+ − 754
}
+ − 755
*/
+ − 756
+ − 757
/* **** DEPRECATED ****
+ − 758
* Reverses the result of RenderMan::escape_page_text().
+ − 759
* @param $text string the text to unescape
+ − 760
* @param $char_tag string the character tag
+ − 761
* @return string
+ − 762
* /
+ − 763
+ − 764
function unescape_page_text($text, $char_tag)
+ − 765
{
+ − 766
$text = str_replace("{APOS:$char_tag}", "'", $text);
+ − 767
$text = str_replace("{QUOT:$char_tag}", '"', $text);
+ − 768
$text = str_replace("{SLASH:$char_tag}", "\\", $text);
+ − 769
return $text;
+ − 770
}
+ − 771
*/
+ − 772
+ − 773
/**
+ − 774
* Generates a summary of the differences between two texts, and formats it as XHTML.
+ − 775
* @param $str1 string the first block of text
+ − 776
* @param $str2 string the second block of text
+ − 777
* @return string
+ − 778
*/
+ − 779
function diff($str1, $str2)
+ − 780
{
+ − 781
global $db, $session, $paths, $template, $plugins; // Common objects
+ − 782
$str1 = explode("\n", $str1);
+ − 783
$str2 = explode("\n", $str2);
+ − 784
$diff = new Diff($str1, $str2);
+ − 785
$renderer = new TableDiffFormatter();
+ − 786
return '<table class="diff">'.$renderer->format($diff).'</table>';
+ − 787
}
+ − 788
+ − 789
}
+ − 790
+ − 791
?>