| [ Index ] |
PHP Cross Reference of phpBB 3.0 Beta 3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id: message_parser.php,v 1.157 2006/11/12 14:29:31 naderman Exp $ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * @ignore 13 */ 14 if (!defined('IN_PHPBB')) 15 { 16 exit; 17 } 18 19 if (!class_exists('bbcode')) 20 { 21 include($phpbb_root_path . 'includes/bbcode.' . $phpEx); 22 } 23 24 /** 25 * BBCODE FIRSTPASS 26 * BBCODE first pass class (functions for parsing messages for db storage) 27 * @package phpBB3 28 */ 29 class bbcode_firstpass extends bbcode 30 { 31 var $message = ''; 32 var $warn_msg = array(); 33 var $parsed_items = array(); 34 35 /** 36 * Parse BBCode 37 */ 38 function parse_bbcode() 39 { 40 if (!$this->bbcodes) 41 { 42 $this->bbcode_init(); 43 } 44 45 global $user; 46 47 $this->bbcode_bitfield = ''; 48 $bitfield = new bitfield(); 49 50 foreach ($this->bbcodes as $bbcode_name => $bbcode_data) 51 { 52 if (isset($bbcode_data['disabled']) && $bbcode_data['disabled']) 53 { 54 foreach ($bbcode_data['regexp'] as $regexp => $replacement) 55 { 56 if (preg_match($regexp, $this->message)) 57 { 58 $this->warn_msg[] = $user->lang['UNAUTHORISED_BBCODE'] . '[' . $bbcode_name . ']'; 59 continue; 60 } 61 } 62 } 63 else 64 { 65 foreach ($bbcode_data['regexp'] as $regexp => $replacement) 66 { 67 // The pattern gets compiled and cached by the PCRE extension, 68 // it should not demand recompilation 69 if (preg_match($regexp, $this->message)) 70 { 71 $this->message = preg_replace($regexp, $replacement, $this->message); 72 $bitfield->set($bbcode_data['bbcode_id']); 73 } 74 } 75 } 76 } 77 78 $this->bbcode_bitfield = $bitfield->get_base64(); 79 } 80 81 /** 82 * Prepare some bbcodes for better parsing 83 */ 84 function prepare_bbcodes() 85 { 86 // Add newline at the end and in front of each quote block to prevent parsing errors (urls, smilies, etc.) 87 if (strpos($this->message, '[quote') !== false) 88 { 89 $in = str_replace("\r\n", "\n", $this->message); 90 91 $this->message = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $this->message); 92 $this->message = preg_replace(array('#\[quote(=".*?")?\]([^\n])#is', '#([^\n])\[\/quote\]#is'), array("[quote\\1]\n\\2", "\\1\n[/quote]"), $this->message); 93 } 94 95 // Add other checks which needs to be placed before actually parsing anything (be it bbcodes, smilies, urls...) 96 } 97 98 /** 99 * Init bbcode data for later parsing 100 */ 101 function bbcode_init() 102 { 103 static $rowset; 104 105 // This array holds all bbcode data. BBCodes will be processed in this 106 // order, so it is important to keep [code] in first position and 107 // [quote] in second position. 108 $this->bbcodes = array( 109 'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#ise' => "\$this->bbcode_code('\$1', '\$2')")), 110 'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:="(.*?)")?\](.+)\[/quote\]#ise' => "\$this->bbcode_quote('\$0')")), 111 'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#ise' => "\$this->bbcode_attachment('\$1', '\$2')")), 112 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#ise' => "\$this->bbcode_strong('\$1')")), 113 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#ise' => "\$this->bbcode_italic('\$1')")), 114 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](.*)\[/url\]#iUe' => "\$this->validate_url('\$2', '\$3')")), 115 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](https?://)([a-z0-9\-\.,\?!%\*_:;~\\&$@/=\+]+)\[/img\]#ie' => "\$this->bbcode_img('\$1\$2')")), 116 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?[1-2]?[0-9])\](.*?)\[/size\]#ise' => "\$this->bbcode_size('\$1', '\$2')")), 117 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9A-Fa-f]{6}|[a-z\-]+)\](.*?)\[/color\]!ise' => "\$this->bbcode_color('\$1', '\$2')")), 118 'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#ise' => "\$this->bbcode_underline('\$1')")), 119 'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(=[a-z|0-9|(?:disc|circle|square))]+)?\].*\[/list\]#ise' => "\$this->bbcode_parse_list('\$0')")), 120 'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#ise' => "\$this->validate_email('\$1', '\$2')")), 121 'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#ie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')")) 122 ); 123 124 // Zero the parsed items array 125 $this->parsed_items = array(); 126 127 foreach ($this->bbcodes as $tag => $bbcode_data) 128 { 129 $this->parsed_items[$tag] = 0; 130 } 131 132 if (!is_array($rowset)) 133 { 134 global $db; 135 $rowset = array(); 136 137 $sql = 'SELECT * 138 FROM ' . BBCODES_TABLE; 139 $result = $db->sql_query($sql); 140 141 while ($row = $db->sql_fetchrow($result)) 142 { 143 $rowset[] = $row; 144 } 145 $db->sql_freeresult($result); 146 } 147 148 foreach ($rowset as $row) 149 { 150 $this->bbcodes[$row['bbcode_tag']] = array( 151 'bbcode_id' => (int) $row['bbcode_id'], 152 'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace'])) 153 ); 154 } 155 } 156 157 /** 158 * Making some pre-checks for bbcodes as well as increasing the number of parsed items 159 */ 160 function check_bbcode($bbcode, &$in) 161 { 162 // when using the /e modifier, preg_replace slashes double-quotes but does not 163 // seem to slash anything else 164 $in = str_replace("\r\n", "\n", str_replace('\"', '"', $in)); 165 166 // Trimming here to make sure no empty bbcodes are parsed accidently 167 if (trim($in) == '') 168 { 169 return false; 170 } 171 172 $this->parsed_items[$bbcode]++; 173 174 return true; 175 } 176 177 /** 178 * Transform some characters in valid bbcodes 179 */ 180 function bbcode_specialchars($text) 181 { 182 $str_from = array('<', '>', '[', ']', '.', ':'); 183 $str_to = array('<', '>', '[', ']', '.', ':'); 184 185 return str_replace($str_from, $str_to, $text); 186 } 187 188 /** 189 * Parse size tag 190 */ 191 function bbcode_size($stx, $in) 192 { 193 global $user, $config; 194 195 if (!$this->check_bbcode('size', $in)) 196 { 197 return ''; 198 } 199 200 if ($config['max_' . $this->mode . '_font_size'] && $config['max_' . $this->mode . '_font_size'] < $stx) 201 { 202 $this->warn_msg[] = sprintf($user->lang['MAX_FONT_SIZE_EXCEEDED'], $config['max_' . $this->mode . '_font_size']); 203 } 204 205 return '[size=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/size:' . $this->bbcode_uid . ']'; 206 } 207 208 /** 209 * Parse color tag 210 */ 211 function bbcode_color($stx, $in) 212 { 213 if (!$this->check_bbcode('color', $in)) 214 { 215 return ''; 216 } 217 218 return '[color=' . $stx . ':' . $this->bbcode_uid . ']' . $in . '[/color:' . $this->bbcode_uid . ']'; 219 } 220 221 /** 222 * Parse u tag 223 */ 224 function bbcode_underline($in) 225 { 226 if (!$this->check_bbcode('u', $in)) 227 { 228 return ''; 229 } 230 231 return '[u:' . $this->bbcode_uid . ']' . $in . '[/u:' . $this->bbcode_uid . ']'; 232 } 233 234 /** 235 * Parse b tag 236 */ 237 function bbcode_strong($in) 238 { 239 if (!$this->check_bbcode('b', $in)) 240 { 241 return ''; 242 } 243 244 return '[b:' . $this->bbcode_uid . ']' . $in . '[/b:' . $this->bbcode_uid . ']'; 245 } 246 247 /** 248 * Parse i tag 249 */ 250 function bbcode_italic($in) 251 { 252 if (!$this->check_bbcode('i', $in)) 253 { 254 return ''; 255 } 256 257 return '[i:' . $this->bbcode_uid . ']' . $in . '[/i:' . $this->bbcode_uid . ']'; 258 } 259 260 /** 261 * Parse img tag 262 */ 263 function bbcode_img($in) 264 { 265 global $user, $config, $phpEx; 266 267 if (!$this->check_bbcode('img', $in)) 268 { 269 return ''; 270 } 271 272 $in = trim($in); 273 274 if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width']) 275 { 276 $stats = @getimagesize($in); 277 278 if ($stats === false) 279 { 280 $this->warn_msg[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; 281 } 282 else 283 { 284 if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $stats[1]) 285 { 286 $this->warn_msg[] = sprintf($user->lang['MAX_IMG_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']); 287 } 288 289 if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $stats[0]) 290 { 291 $this->warn_msg[] = sprintf($user->lang['MAX_IMG_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']); 292 } 293 } 294 } 295 296 if ($this->path_in_domain($in)) 297 { 298 return '[img]' . $in . '[/img]'; 299 } 300 301 return '[img:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/img:' . $this->bbcode_uid . ']'; 302 } 303 304 /** 305 * Parse flash tag 306 */ 307 function bbcode_flash($width, $height, $in) 308 { 309 global $user, $config, $phpEx; 310 311 if (!$this->check_bbcode('flash', $in)) 312 { 313 return ''; 314 } 315 316 $in = trim($in); 317 318 // Apply the same size checks on flash files as on images 319 if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width']) 320 { 321 if ($config['max_' . $this->mode . '_img_height'] && $config['max_' . $this->mode . '_img_height'] < $height) 322 { 323 $this->warn_msg[] = sprintf($user->lang['MAX_FLASH_HEIGHT_EXCEEDED'], $config['max_' . $this->mode . '_img_height']); 324 } 325 326 if ($config['max_' . $this->mode . '_img_width'] && $config['max_' . $this->mode . '_img_width'] < $width) 327 { 328 $this->warn_msg[] = sprintf($user->lang['MAX_FLASH_WIDTH_EXCEEDED'], $config['max_' . $this->mode . '_img_width']); 329 } 330 } 331 332 if ($this->path_in_domain($in)) 333 { 334 return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]'; 335 } 336 337 return '[flash=' . $width . ',' . $height . ':' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($in) . '[/flash:' . $this->bbcode_uid . ']'; 338 } 339 340 /** 341 * Parse inline attachments [ia] 342 */ 343 function bbcode_attachment($stx, $in) 344 { 345 if (!$this->check_bbcode('attachment', $in)) 346 { 347 return ''; 348 } 349 350 return '[attachment=' . $stx . ':' . $this->bbcode_uid . ']<!-- ia' . $stx . ' -->' . trim($in) . '<!-- ia' . $stx . ' -->[/attachment:' . $this->bbcode_uid . ']'; 351 } 352 353 /** 354 * Parse code tag 355 * Expects the argument to start right after the opening [code] tag and to end with [/code] 356 */ 357 function bbcode_code($stx, $in) 358 { 359 if (!$this->check_bbcode('code', $in)) 360 { 361 return ''; 362 } 363 364 // We remove the hardcoded elements from the code block here because it is not used in code blocks 365 // Having it here saves us one preg_replace per message containing [code] blocks 366 // Additionally, magic url parsing should go after parsing bbcodes, but for safety those are stripped out too... 367 $htm_match = get_preg_expression('bbcode_htm'); 368 // $htm_match[3] = '/&#([0-9]+);/'; 369 unset($htm_match[3], $htm_match[4]); 370 371 $htm_replace = array('\1', '\2', '\1'); //, '&#\1;'); 372 373 $out = ''; 374 375 do 376 { 377 $pos = stripos($in, '[/code]') + 7; 378 $code = substr($in, 0, $pos); 379 $in = substr($in, $pos); 380 381 // $code contains everything that was between code tags (including the ending tag) but we're trying to grab as much extra text as possible, as long as it does not contain open [code] tags 382 while ($in) 383 { 384 $pos = stripos($in, '[/code]') + 7; 385 $buffer = substr($in, 0, $pos); 386 387 if (preg_match('#\[code(?:=([a-z]+))?\]#i', $buffer)) 388 { 389 break; 390 } 391 else 392 { 393 $in = substr($in, $pos); 394 $code .= $buffer; 395 } 396 } 397 398 $code = substr($code, 0, -7); 399 // $code = preg_replace('#^[\r\n]*(.*?)[\n\r\s\t]*$#s', '$1', $code); 400 $code = preg_replace($htm_match, $htm_replace, $code); 401 402 switch (strtolower($stx)) 403 { 404 case 'php': 405 406 $remove_tags = false; 407 $code = str_replace(array('<', '>'), array('<', '>'), $code); 408 409 if (!preg_match('/\<\?.*?\?\>/is', $code)) 410 { 411 $remove_tags = true; 412 $code = "<?php $code ?>"; 413 } 414 415 $conf = array('highlight.bg', 'highlight.comment', 'highlight.default', 'highlight.html', 'highlight.keyword', 'highlight.string'); 416 foreach ($conf as $ini_var) 417 { 418 ini_set($ini_var, str_replace('highlight.', 'syntax', $ini_var)); 419 } 420 421 // Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results 422 $code = htmlspecialchars_decode($code); 423 $code = highlight_string($code, true); 424 425 $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':'); 426 $str_to = array('<span class="', '<span class="syntax', '</span>', '', '', '[', ']', '.', ':'); 427 428 if ($remove_tags) 429 { 430 $str_from[] = '<span class="syntaxdefault"><?php </span>'; 431 $str_to[] = ''; 432 $str_from[] = '<span class="syntaxdefault"><?php '; 433 $str_to[] = '<span class="syntaxdefault">'; 434 } 435 436 $code = str_replace($str_from, $str_to, $code); 437 $code = preg_replace('#^(<span class="[a-z_]+">)\n?(.*?)\n?(</span>)$#is', '$1$2$3', $code); 438 439 if ($remove_tags) 440 { 441 $code = preg_replace('#(<span class="[a-z]+">)?\?></span>#', '', $code); 442 } 443 444 $code = preg_replace('#^<span class="[a-z]+"><span class="([a-z]+)">(.*)</span></span>#s', '<span class="$1">$2</span>', $code); 445 $code = preg_replace('#(?:[\n\r\s\t]| )*</span>$#', '</span>', $code); 446 447 // remove newline at the end 448 if (!empty($code) && $code{strlen($code)-1} == "\n") 449 { 450 $code = substr($code, 0, -1); 451 } 452 453 $out .= "[code=$stx:" . $this->bbcode_uid . ']' . $code . '[/code:' . $this->bbcode_uid . ']'; 454 break; 455 456 default: 457 $out .= '[code:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($code) . '[/code:' . $this->bbcode_uid . ']'; 458 break; 459 } 460 461 if (preg_match('#(.*?)\[code(?:=([a-z]+))?\](.+)#is', $in, $m)) 462 { 463 $out .= $m[1]; 464 $stx = $m[2]; 465 $in = $m[3]; 466 } 467 } 468 while ($in); 469 470 return $out; 471 } 472 473 /** 474 * Parse list bbcode 475 * Expects the argument to start with a tag 476 */ 477 function bbcode_parse_list($in) 478 { 479 if (!$this->check_bbcode('list', $in)) 480 { 481 return ''; 482 } 483 484 $out = '['; 485 486 // Grab item_start with no item_end 487 $in = preg_replace('#\[\*\](.*?)(\[\/list\]|\[list(=?(?:[0-9]|[a-z]|))\]|\[\*\])#is', '[*:' . $this->bbcode_uid . ']\1[/*:m:' . $this->bbcode_uid . ']\2', $in); 488 489 // Grab them again as backreference 490 $in = preg_replace('#\[\*\](.*?)(\[\/list\]|\[list(=?(?:[0-9]|[a-z]|))\]|\[\*\])(^\[\/*\])#is', '[*:' . $this->bbcode_uid . ']\1[/*:m:' . $this->bbcode_uid . ']\2', $in); 491 492 // Grab end tag following start tag 493 $in = preg_replace('#\[\/\*:m:' . $this->bbcode_uid . '\](\n|)\[\*\]#is', '[/*:m:' . $this->bbcode_uid . '][*:' . $this->bbcode_uid . ']', $in); 494 495 // Replace end tag 496 $in = preg_replace('#\[\/\*\]#i', '[/*:' . $this->bbcode_uid . ']', $in); 497 498 // $tok holds characters to stop at. Since the string starts with a '[' we'll get everything up to the first ']' which should be the opening [list] tag 499 $tok = ']'; 500 $out = '['; 501 502 // First character is [ 503 $in = substr($in, 1); 504 $list_end_tags = array(); 505 506 do 507 { 508 $pos = strlen($in); 509 510 for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i) 511 { 512 $tmp_pos = strpos($in, $tok{$i}); 513 514 if ($tmp_pos !== false && $tmp_pos < $pos) 515 { 516 $pos = $tmp_pos; 517 } 518 } 519 520 $buffer = substr($in, 0, $pos); 521 $tok = $in{$pos}; 522 523 $in = substr($in, $pos + 1); 524 525 if ($tok == ']') 526 { 527 // if $tok is ']' the buffer holds a tag 528 if (strtolower($buffer) == '/list' && sizeof($list_end_tags)) 529 { 530 $out .= array_pop($list_end_tags) . ']'; 531 $tok = '['; 532 } 533 else if (preg_match('#list(=?(?:[0-9]|[a-z]|))#i', $buffer, $m)) 534 { 535 // sub-list, add a closing tag 536 if (!$m[1] || preg_match('/^(disc|square|circle)$/i', $m[1])) 537 { 538 array_push($list_end_tags, '/list:u:' . $this->bbcode_uid); 539 } 540 else 541 { 542 array_push($list_end_tags, '/list:o:' . $this->bbcode_uid); 543 } 544 545 if (strtolower(substr($buffer, 0, 4)) == 'list') 546 { 547 $buffer = 'list' . substr($buffer, 4, $pos); 548 } 549 550 $out .= $buffer . ':' . $this->bbcode_uid . ']'; 551 $tok = '['; 552 } 553 else 554 { 555 $out .= $buffer . $tok; 556 $tok = '[]'; 557 } 558 } 559 else 560 { 561 // Not within a tag, just add buffer to the return string 562 $out .= $buffer . $tok; 563 $tok = ($tok == '[') ? ']' : '[]'; 564 } 565 } 566 while ($in); 567 568 if (sizeof($list_end_tags)) 569 { 570 $out .= '[' . implode('][', $list_end_tags) . ']'; 571 } 572 573 return $out; 574 } 575 576 /** 577 * Parse quote bbcode 578 * Expects the argument to start with a tag 579 */ 580 function bbcode_quote($in) 581 { 582 global $config, $user; 583 584 $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in))); 585 586 if (!$in) 587 { 588 return ''; 589 } 590 591 $tok = ']'; 592 $out = '['; 593 594 $in = substr($in, 1); 595 $close_tags = $error_ary = array(); 596 $buffer = ''; 597 598 do 599 { 600 $pos = strlen($in); 601 for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i) 602 { 603 $tmp_pos = strpos($in, $tok{$i}); 604 if ($tmp_pos !== false && $tmp_pos < $pos) 605 { 606 $pos = $tmp_pos; 607 } 608 } 609 610 $buffer .= substr($in, 0, $pos); 611 $tok = $in{$pos}; 612 $in = substr($in, $pos + 1); 613 614 if ($tok == ']') 615 { 616 if ($buffer == '/quote' && sizeof($close_tags)) 617 { 618 // we have found a closing tag 619 // Add space at the end of the closing tag to allow following urls/smilies to be parsed correctly 620 $out .= array_pop($close_tags) . '] '; 621 $tok = '['; 622 $buffer = ''; 623 } 624 else if (preg_match('#^quote(?:="(.*?)")?$#is', $buffer, $m)) 625 { 626 $this->parsed_items['quote']++; 627 628 // the buffer holds a valid opening tag 629 if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth']) 630 { 631 // there are too many nested quotes 632 $error_ary['quote_depth'] = sprintf($user->lang['QUOTE_DEPTH_EXCEEDED'], $config['max_quote_depth']); 633 634 $out .= $buffer . $tok; 635 $tok = '[]'; 636 $buffer = ''; 637 638 continue; 639 } 640 641 array_push($close_tags, '/quote:' . $this->bbcode_uid); 642 643 if (isset($m[1]) && $m[1]) 644 { 645 $username = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '[$1', $m[1]); 646 $end_tags = array(); 647 $error = false; 648 649 preg_match_all('#\[((?:/)?(?:[a-z]+))#i', $username, $tags); 650 foreach ($tags[1] as $tag) 651 { 652 if ($tag[0] != '/') 653 { 654 $end_tags[] = '/' . $tag; 655 } 656 else 657 { 658 $end_tag = array_pop($end_tags); 659 if ($end_tag != $tag) 660 { 661 $error = true; 662 } 663 else 664 { 665 $error = false; 666 } 667 } 668 } 669 670 if ($error) 671 { 672 $username = str_replace('[', '[', str_replace(']', ']', $m[1])); 673 } 674 675 $out .= 'quote="' . $username . '":' . $this->bbcode_uid . ']'; 676 } 677 else 678 { 679 $out .= 'quote:' . $this->bbcode_uid . ']'; 680 } 681 682 $tok = '['; 683 $buffer = ''; 684 } 685 else if (preg_match('#^quote="(.*?)#is', $buffer, $m)) 686 { 687 // the buffer holds an invalid opening tag 688 $buffer .= ']'; 689 } 690 else 691 { 692 $out .= $buffer . $tok; 693 $tok = '[]'; 694 $buffer = ''; 695 } 696 } 697 else 698 { 699 $out .= $buffer . $tok; 700 // $tok = ($tok == '[') ? ']' : '[]'; 701 $tok = '[]'; 702 $buffer = ''; 703 } 704 } 705 while ($in); 706 707 if (sizeof($close_tags)) 708 { 709 $out .= '[' . implode('][', $close_tags) . ']'; 710 } 711 712 foreach ($error_ary as $error_msg) 713 { 714 $this->warn_msg[] = $error_msg; 715 } 716 717 return $out; 718 } 719 720 /** 721 * Validate email 722 */ 723 function validate_email($var1, $var2) 724 { 725 $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1))); 726 $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2))); 727 728 $txt = $var2; 729 $email = ($var1) ? $var1 : $var2; 730 731 $validated = true; 732 733 if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email)) 734 { 735 $validated = false; 736 } 737 738 if (!$validated) 739 { 740 return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]'; 741 } 742 743 $this->parsed_items['email']++; 744 745 if ($var1) 746 { 747 $retval = '[email=' . $this->bbcode_specialchars($email) . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']'; 748 } 749 else 750 { 751 $retval = '[email:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($email) . '[/email:' . $this->bbcode_uid . ']'; 752 } 753 754 return $retval; 755 } 756 757 /** 758 * Validate url 759 */ 760 function validate_url($var1, $var2) 761 { 762 global $config; 763 764 $var1 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var1))); 765 $var2 = str_replace("\r\n", "\n", str_replace('\"', '"', trim($var2))); 766 767 $url = ($var1) ? $var1 : $var2; 768 $valid = false; 769 770 if (!$url || ($var1 && !$var2)) 771 { 772 return ''; 773 } 774 775 // Checking urls 776 if (preg_match('#' . preg_quote(generate_board_url(), '#') . '/([^ \t\n\r<"\']+)#i', $url) || 777 preg_match('#([\w]+?://.*?[^ \t\n\r<"\']*)#i', $url) || 778 preg_match('#(www\.[\w\-]+\.[\w\-.\~]+(?:/[^ \t\n\r<"\']*)?)#i', $url)) 779 { 780 $valid = true; 781 } 782 783 if ($valid) 784 { 785 $this->parsed_items['url']++; 786 787 if (!preg_match('#^[\w]+?://.*?#i', $url)) 788 { 789 $url = 'http://' . $url; 790 } 791 792 // We take our test url and stick on the first bit of text we get to check if we are really at the domain. If so, lets go! 793 if (strpos($url, generate_board_url()) !== false && strpos($url, 'sid=') !== false) 794 { 795 $url = preg_replace('/(&|\?)sid=[0-9a-f]{32}/', '\1', $url); 796 } 797 798 return ($var1) ? '[url=' . $this->bbcode_specialchars($url) . ':' . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']' : '[url:' . $this->bbcode_uid . ']' . $this->bbcode_specialchars($url) . '[/url:' . $this->bbcode_uid . ']'; 799 } 800 801 return '[url' . (($var1) ? '=' . $var1 : '') . ']' . $var2 . '[/url]'; 802 } 803 804 /** 805 * Check if url is pointing to this domain/script_path/php-file 806 * 807 * @param string $url the url to check 808 * @return true if the url is pointing to this domain/script_path/php-file, false if not 809 * 810 * @access private 811 */ 812 function path_in_domain($url) 813 { 814 global $config, $phpEx, $user; 815 816 $check_path = ($user->page['root_script_path'] != '/') ? substr($user->page['root_script_path'], 0, -1) : '/'; 817 818 // Is the user trying to link to a php file in this domain and script path? 819 if (strpos($url, ".{$phpEx}") !== false && strpos($url, $check_path) !== false) 820 { 821 $server_name = (!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'); 822 823 // Forcing server vars is the only way to specify/override the protocol 824 if ($config['force_server_vars'] || !$server_name) 825 { 826 $server_name = $config['server_name']; 827 } 828 829 // Check again in correct order... 830 $pos_ext = strpos($url, ".{$phpEx}"); 831 $pos_path = strpos($url, $check_path); 832 $pos_domain = strpos($url, $server_name); 833 834 if ($pos_domain !== false && $pos_path >= $pos_domain && $pos_ext >= $pos_path) 835 { 836 return true; 837 } 838 } 839 840 return false; 841 } 842 } 843 844 /** 845 * Main message parser for posting, pm, etc. takes raw message 846 * and parses it for attachments, bbcode and smilies 847 * @package phpBB3 848 */ 849 class parse_message extends bbcode_firstpass 850 { 851 var $attachment_data = array(); 852 var $filename_data = array(); 853 854 // Helps ironing out user error 855 var $message_status = ''; 856 857 var $allow_img_bbcode = true; 858 var $allow_flash_bbcode = true; 859 var $allow_quote_bbcode = true; 860 var $allow_url_bbcode = true; 861 862 var $mode; 863 864 /** 865 * Init - give message here or manually 866 */ 867 function parse_message($message = '') 868 { 869 // Init BBCode UID 870 $this->bbcode_uid = substr(md5(time()), 0, BBCODE_UID_LEN); 871 872 if ($message) 873 { 874 $this->message = $message; 875 } 876 } 877 878 /** 879 * Parse Message 880 */ 881 function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post') 882 { 883 global $config, $db, $user; 884 885 $mode = ($mode != 'post') ? 'sig' : 'post'; 886 887 $this->mode = $mode; 888 889 $this->allow_img_bbcode = $allow_img_bbcode; 890 $this->allow_flash_bbcode = $allow_flash_bbcode; 891 $this->allow_quote_bbcode = $allow_quote_bbcode; 892 $this->allow_url_bbcode = $allow_url_bbcode; 893 894 // If false, then $this->message won't be altered, the text will be returned instead. 895 if (!$update_this_message) 896 { 897 $tmp_message = $this->message; 898 $return_message = &$this->message; 899 } 900 901 if ($this->message_status == 'display') 902 { 903 $this->decode_message(); 904 } 905 906 // Do some general 'cleanup' first before processing message, 907 // e.g. remove excessive newlines(?), smilies(?) 908 // Transform \r\n and \r into \n 909 $match = array('#\r\n?#', "#([\n][\s]+){3,}#", '#(script|about|applet|activex|chrome):#i'); 910 $replace = array("\n", "\n\n", "\\1:"); 911 $this->message = preg_replace($match, $replace, trim($this->message)); 912 913 // Message length check. -1 disables this check completely. 914 if ($config['max_' . $mode . '_chars'] != -1) 915 { 916 $msg_len = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#is', ' ', $this->message)); 917 918 if ((!$msg_len && $mode !== 'sig') || $config['max_' . $mode . '_chars'] && $msg_len > $config['max_' . $mode . '_chars']) 919 { 920 $this->warn_msg[] = (!$msg_len) ? $user->lang['TOO_FEW_CHARS'] : $user->lang['TOO_MANY_CHARS']; 921 return $this->warn_msg; 922 } 923 } 924 925 // Prepare BBcode (just prepares some tags for better parsing) 926 if ($allow_bbcode && strpos($this->message, '[') !== false) 927 { 928 $this->bbcode_init(); 929 $disallow = array('img', 'flash', 'quote', 'url'); 930 foreach ($disallow as $bool) 931 { 932 if (!${'allow_' . $bool . '_bbcode'}) 933 { 934 $this->bbcodes[$bool]['disabled'] = true; 935 } 936 } 937 938 $this->prepare_bbcodes(); 939 } 940 941 // Parse smilies 942 if ($allow_smilies) 943 { 944 $this->smilies($config['max_' . $mode . '_smilies']); 945 } 946 947 $num_urls = 0; 948 949 // Parse BBCode 950 if ($allow_bbcode && strpos($this->message, '[') !== false) 951 { 952 $this->parse_bbcode(); 953 $num_urls += $this->parsed_items['url']; 954 } 955 956 // Parse URL's 957 if ($allow_magic_url) 958 { 959 $this->magic_url(generate_board_url()); 960 961 if ($config['max_' . $mode . '_urls']) 962 { 963 $num_urls += preg_match_all('#\<!-- (l|m|w|e) --\>.*?\<!-- \1 --\>#', $this->message, $matches); 964 } 965 } 966 967 // Check number of links 968 if ($config['max_' . $mode . '_urls'] && $num_urls > $config['max_' . $mode . '_urls']) 969 { 970 $this->warn_msg[] = sprintf($user->lang['TOO_MANY_URLS'], $config['max_' . $mode . '_urls']); 971 return $this->warn_msg; 972 } 973 974 if (!$update_this_message) 975 { 976 unset($this->message); 977 $this->message = $tmp_message; 978 return $return_message; 979 } 980 981 $this->message_status = 'parsed'; 982 return false; 983 } 984 985 /** 986 * Formatting text for display 987 */ 988 function format_display($allow_bbcode, $allow_magic_url, $allow_smilies, $update_this_message = true) 989 { 990 // If false, then the parsed message get returned but internal message not processed. 991 if (!$update_this_message) 992 { 993 $tmp_message = $this->message; 994 $return_message = &$this->message; 995 } 996 997 if ($this->message_status == 'plain') 998 { 999 // Force updating message - of course. 1000 $this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, $this->allow_url_bbcode, true); 1001 } 1002 1003 // Parse BBcode 1004 if ($allow_bbcode) 1005 { 1006 $this->bbcode_cache_init(); 1007 1008 // We are giving those parameters to be able to use the bbcode class on its own 1009 $this->bbcode_second_pass($this->message, $this->bbcode_uid); 1010 } 1011 1012 $this->message = smiley_text($this->message, !$allow_smilies); 1013 1014 // Replace naughty words such as farty pants 1015 $this->message = str_replace("\n", '<br />', censor_text($this->message)); 1016 1017 if (!$update_this_message) 1018 { 1019 unset($this->message); 1020 $this->message = $tmp_message; 1021 return $return_message; 1022 } 1023 1024 $this->message_status = 'display'; 1025 return false; 1026 } 1027 1028 /** 1029 * Decode message to be placed back into form box 1030 */ 1031 function decode_message($custom_bbcode_uid = '', $update_this_message = true) 1032 { 1033 // If false, then the parsed message get returned but internal message not processed. 1034 if (!$update_this_message) 1035 { 1036 $tmp_message = $this->message; 1037 $return_message = &$this->message; 1038 } 1039 1040 ($custom_bbcode_uid) ? decode_message($this->message, $custom_bbcode_uid) : decode_message($this->message, $this->bbcode_uid); 1041 1042 if (!$update_this_message) 1043 { 1044 unset($this->message); 1045 $this->message = $tmp_message; 1046 return $return_message; 1047 } 1048 1049 $this->message_status = 'plain'; 1050 return false; 1051 } 1052 1053 /** 1054 * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx. 1055 * Cuts down displayed size of link if over 50 chars, turns absolute links 1056 * into relative versions when the server/script path matches the link 1057 */ 1058 function magic_url($server_url) 1059 { 1060 // We use the global make_clickable function 1061 $this->message = make_clickable($this->message, $server_url); 1062 } 1063 1064 /** 1065 * Parse Smilies 1066 */ 1067 function smilies($max_smilies = 0) 1068 { 1069 global $db, $user, $phpbb_root_path; 1070 static $match; 1071 static $replace; 1072 1073 // See if the static arrays have already been filled on an earlier invocation 1074 if (!is_array($match)) 1075 { 1076 $match = $replace = array(); 1077 1078 // NOTE: obtain_* function? chaching the table contents? 1079 1080 // For now setting the ttl to 10 minutes 1081 switch ($db->sql_layer) 1082 { 1083 case 'mssql': 1084 case 'mssql_odbc': 1085 $sql = 'SELECT * 1086 FROM ' . SMILIES_TABLE . ' 1087 ORDER BY LEN(code) DESC'; 1088 break; 1089 1090 case 'firebird': 1091 $sql = 'SELECT * 1092 FROM ' . SMILIES_TABLE . ' 1093 ORDER BY CHAR_LENGTH(code) DESC'; 1094 break; 1095 1096 // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure... 1097 default: 1098 $sql = 'SELECT * 1099 FROM ' . SMILIES_TABLE . ' 1100 ORDER BY LENGTH(code) DESC'; 1101 break; 1102 } 1103 $result = $db->sql_query($sql, 600); 1104 1105 while ($row = $db->sql_fetchrow($result)) 1106 { 1107 // (assertion) 1108 $match[] = '#(?<=^|[\n ]|\.)' . preg_quote($row['code'], '#') . '#'; 1109 $replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['emotion'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->'; 1110 } 1111 $db->sql_freeresult($result); 1112 } 1113 1114 if (sizeof($match)) 1115 { 1116 if ($max_smilies) 1117 { 1118 $num_matches = preg_match_all('#' . str_replace('#', '', implode('|', $match)) . '#', $this->message, $matches); 1119 unset($matches); 1120 1121 if ($num_matches !== false && $num_matches > $max_smilies) 1122 { 1123 $this->warn_msg[] = sprintf($user->lang['TOO_MANY_SMILIES'], $max_smilies); 1124 return; 1125 } 1126 } 1127 $this->message = trim(preg_replace($match, $replace, $this->message)); 1128 } 1129 } 1130 1131 /** 1132 * Parse Attachments 1133 */ 1134 function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) 1135 { 1136 global $config, $auth, $user, $phpbb_root_path, $phpEx, $db; 1137 1138 $error = array(); 1139 1140 $num_attachments = sizeof($this->attachment_data); 1141 $this->filename_data['filecomment'] = request_var('filecomment', '', true); 1142 utf8_normalize_nfc(&$this->filename_data['filecomment']); 1143 $upload_file = (isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name'])) ? true : false; 1144 1145 $add_file = (isset($_POST['add_file'])) ? true : false; 1146 $delete_file = (isset($_POST['delete_file'])) ? true : false; 1147 $edit_comment = (isset($_POST['edit_comment'])) ? true : false; 1148 1149 $cfg = array(); 1150 $cfg['max_attachments'] = ($is_message) ? $config['max_attachments_pm'] : $config['max_attachments']; 1151 $forum_id = ($is_message) ? 0 : $forum_id; 1152 1153 if ($submit && in_array($mode, array('post', 'reply', 'quote', 'edit')) && $upload_file) 1154 { 1155 if ($num_attachments < $cfg['max_attachments'] || $auth->acl_get('a_') || $auth->acl_get('m_', $forum_id)) 1156 { 1157 $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); 1158 $error = $filedata['error']; 1159 1160 if ($filedata['post_attach'] && !sizeof($error)) 1161 { 1162 $sql_ary = array( 1163 'physical_filename' => $filedata['physical_filename'], 1164 'attach_comment' => $this->filename_data['filecomment'], 1165 'real_filename' => $filedata['real_filename'], 1166 'extension' => $filedata['extension'], 1167 'mimetype' => $filedata['mimetype'], 1168 'filesize' => $filedata['filesize'], 1169 'filetime' => $filedata['filetime'], 1170 'thumbnail' => $filedata['thumbnail'], 1171 'is_orphan' => 1, 1172 'in_message' => ($is_message) ? 1 : 0, 1173 'poster_id' => $user->data['user_id'], 1174 ); 1175 1176 $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); 1177 1178 $new_entry = array( 1179 'attach_id' => $db->sql_nextid(), 1180 'is_orphan' => 1, 1181 'real_filename' => $filedata['real_filename'], 1182 'attach_comment'=> $this->filename_data['filecomment'], 1183 ); 1184 1185 $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); 1186 $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); 1187 1188 $this->filename_data['filecomment'] = ''; 1189 1190 // This Variable is set to false here, because Attachments are entered into the 1191 // Database in two modes, one if the id_list is 0 and the second one if post_attach is true 1192 // Since post_attach is automatically switched to true if an Attachment got added to the filesystem, 1193 // but we are assigning an id of 0 here, we have to reset the post_attach variable to false. 1194 // 1195 // This is very relevant, because it could happen that the post got not submitted, but we do not 1196 // know this circumstance here. We could be at the posting page or we could be redirected to the entered 1197 // post. :) 1198 $filedata['post_attach'] = false; 1199 } 1200 } 1201 else 1202 { 1203 $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); 1204 } 1205 } 1206 1207 if ($preview || $refresh || sizeof($error)) 1208 { 1209 // Perform actions on temporary attachments 1210 if ($delete_file) 1211 { 1212 include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx); 1213 1214 $index = (int) key($_POST['delete_file']); 1215 1216 if (!empty($this->attachment_data[$index])) 1217 { 1218 1219 // delete selected attachment 1220 if ($this->attachment_data[$index]['is_orphan']) 1221 { 1222 $sql = 'SELECT attach_id, physical_filename, thumbnail 1223 FROM ' . ATTACHMENTS_TABLE . ' 1224 WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . ' 1225 AND is_orphan = 1 1226 AND poster_id = ' . $user->data['user_id']; 1227 $result = $db->sql_query($sql); 1228 $row = $db->sql_fetchrow($result); 1229 $db->sql_freeresult($result); 1230 1231 if ($row) 1232 { 1233 phpbb_unlink($row['physical_filename'], 'file'); 1234 1235 if ($row['thumbnail']) 1236 { 1237 phpbb_unlink($row['physical_filename'], 'thumbnail'); 1238 } 1239 1240 $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']); 1241 } 1242 } 1243 else 1244 { 1245 delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); 1246 } 1247 1248 unset($this->attachment_data[$index]); 1249 $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message); 1250 1251 // Reindex Array 1252 $this->attachment_data = array_values($this->attachment_data); 1253 } 1254 } 1255 else if ($edit_comment || $add_file || $preview) 1256 { 1257 if ($edit_comment) 1258 { 1259 $actual_comment_list = request_var('comment_list', array(''), true); 1260 utf8_normalize_nfc(&$actual_comment_list); 1261 1262 $edit_comment = request_var('edit_comment', array(0 => '')); 1263 $edit_comment = key($edit_comment); 1264 $this->attachment_data[$edit_comment]['attach_comment'] = $actual_comment_list[$edit_comment]; 1265 } 1266 1267 if (($add_file || $preview) && $upload_file) 1268 { 1269 if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) 1270 { 1271 $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); 1272 $error = array_merge($error, $filedata['error']); 1273 1274 if (!sizeof($error)) 1275 { 1276 $sql_ary = array( 1277 'physical_filename' => $filedata['physical_filename'], 1278 'attach_comment' => $this->filename_data['filecomment'], 1279 'real_filename' => $filedata['real_filename'], 1280 'extension' => $filedata['extension'], 1281 'mimetype' => $filedata['mimetype'], 1282 'filesize' => $filedata['filesize'], 1283 'filetime' => $filedata['filetime'], 1284 'thumbnail' => $filedata['thumbnail'], 1285 'is_orphan' => 1, 1286 'in_message' => ($is_message) ? 1 : 0, 1287 'poster_id' => $user->data['user_id'], 1288 ); 1289 1290 $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); 1291 1292 $new_entry = array( 1293 'attach_id' => $db->sql_nextid(), 1294 'is_orphan' => 1, 1295 'real_filename' => $filedata['real_filename'], 1296 'attach_comment'=> $this->filename_data['filecomment'], 1297 ); 1298 1299 $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); 1300 $this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message); 1301 $this->filename_data['filecomment'] = ''; 1302 } 1303 } 1304 else 1305 { 1306 $error[] = sprintf($user->lang['TOO_MANY_ATTACHMENTS'], $cfg['max_attachments']); 1307 } 1308 } 1309 } 1310 } 1311 1312 foreach ($error as $error_msg) 1313 { 1314 $this->warn_msg[] = $error_msg; 1315 } 1316 } 1317 1318 /** 1319 * Get Attachment Data 1320 */ 1321 function get_submitted_attachment_data($check_user_id = false) 1322 { 1323 global $user, $db, $phpbb_root_path, $phpEx, $config; 1324 1325 $this->filename_data['filecomment'] = request_var('filecomment', '', true); 1326 utf8_normalize_nfc(&$this->filename_data['filecomment']); 1327 $attachment_data = (isset($_POST['attachment_data'])) ? $_POST['attachment_data'] : array(); 1328 $this->attachment_data = array(); 1329 1330 $check_user_id = ($check_user_id === false) ? $user->data['user_id'] : $check_user_id; 1331 1332 if (!sizeof($attachment_data)) 1333 { 1334 return; 1335 } 1336 1337 $not_orphan = $orphan = array(); 1338 1339 foreach ($attachment_data as $pos => $var_ary) 1340 { 1341 if ($var_ary['is_orphan']) 1342 { 1343 $orphan[(int) $var_ary['attach_id']] = $pos; 1344 } 1345 else 1346 { 1347 $not_orphan[(int) $var_ary['attach_id']] = $pos; 1348 } 1349 } 1350 1351 // Regenerate already posted attachments 1352 if (sizeof($not_orphan)) 1353 { 1354 // Get the attachment data, based on the poster id... 1355 $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment 1356 FROM ' . ATTACHMENTS_TABLE . ' 1357 WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . ' 1358 AND poster_id = ' . $check_user_id; 1359 $result = $db->sql_query($sql); 1360 1361 while ($row = $db->sql_fetchrow($result)) 1362 { 1363 $pos = $not_orphan[$row['attach_id']]; 1364 $this->attachment_data[$pos] = $row; 1365 set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true); 1366 1367 unset($not_orphan[$row['attach_id']]); 1368 } 1369 $db->sql_freeresult($result); 1370 } 1371 1372 if (sizeof($not_orphan)) 1373 { 1374 trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); 1375 } 1376 1377 // Regenerate newly uploaded attachments 1378 if (sizeof($orphan)) 1379 { 1380 $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment 1381 FROM ' . ATTACHMENTS_TABLE . ' 1382 WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . ' 1383 AND poster_id = ' . $user->data['user_id'] . ' 1384 AND is_orphan = 1'; 1385 $result = $db->sql_query($sql); 1386 1387 while ($row = $db->sql_fetchrow($result)) 1388 { 1389 $pos = $orphan[$row['attach_id']]; 1390 $this->attachment_data[$pos] = $row; 1391 set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true); 1392 1393 unset($orphan[$row['attach_id']]); 1394 } 1395 $db->sql_freeresult($result); 1396 } 1397 1398 if (sizeof($orphan)) 1399 { 1400 trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); 1401 } 1402 1403 ksort($this->attachment_data); 1404 } 1405 1406 /** 1407 * Parse Poll 1408 */ 1409 function parse_poll(&$poll) 1410 { 1411 global $auth, $user, $config; 1412 1413 $poll_max_options = $poll['poll_max_options']; 1414 1415 // Parse Poll Option text ;) 1416 $tmp_message = $this->message; 1417 $this->message = $poll['poll_option_text']; 1418 1419 1420 $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false); 1421 1422 $this->message = $tmp_message; 1423 1424 // Parse Poll Title 1425 $tmp_message = $this->message; 1426 $this->message = $poll['poll_title']; 1427 1428 1429 $poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false); 1430 1431 $this->message = $tmp_message; 1432 1433 unset($tmp_message); 1434 1435 $poll['poll_options'] = explode("\n", trim($poll['poll_option_text'])); 1436 $poll['poll_options_size'] = sizeof($poll['poll_options']); 1437 1438 if (sizeof($poll['poll_options']) == 1) 1439 { 1440 $this->warn_msg[] = $user->lang['TOO_FEW_POLL_OPTIONS']; 1441 } 1442 else if ($poll['poll_options_size'] > (int) $config['max_poll_options']) 1443 { 1444 $this->warn_msg[] = $user->lang['TOO_MANY_POLL_OPTIONS']; 1445 } 1446 else if ($poll_max_options > $poll['poll_options_size']) 1447 { 1448 $this->warn_msg[] = $user->lang['TOO_MANY_USER_OPTIONS']; 1449 } 1450 1451 if (!$poll['poll_title'] && $poll['poll_options_size']) 1452 { 1453 $this->warn_msg[] = $user->lang['NO_POLL_TITLE']; 1454 } 1455 1456 $poll['poll_max_options'] = ($poll['poll_max_options'] < 1) ? 1 : (($poll['poll_max_options'] > $config['max_poll_options']) ? $config['max_poll_options'] : $poll['poll_max_options']); 1457 } 1458 } 1459 1460 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Nov 22 00:35:05 2006 | Cross-referenced by PHPXref 0.6 |