[ Index ]

PHP Cross Reference of MyBB 1.8.37

title

Body

[close]

/ -> xmlhttp.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.8
   4   * Copyright 2014 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://www.mybb.com
   7   * License: http://www.mybb.com/about/license
   8   *
   9   */
  10  
  11  /**
  12   * The deal with this file is that it handles all of the XML HTTP Requests for MyBB.
  13   *
  14   * It contains a stripped down version of the MyBB core which does not load things
  15   * such as themes, who's online data, all of the language packs and more.
  16   *
  17   * This is done to make response times when using XML HTTP Requests faster and
  18   * less intense on the server.
  19   */
  20  
  21  define("IN_MYBB", 1);
  22  
  23  // We don't want visits here showing up on the Who's Online
  24  define("NO_ONLINE", 1);
  25  
  26  define('THIS_SCRIPT', 'xmlhttp.php');
  27  
  28  // Load MyBB core files
  29  require_once dirname(__FILE__)."/inc/init.php";
  30  
  31  $shutdown_queries = $shutdown_functions = array();
  32  
  33  // Load some of the stock caches we'll be using.
  34  $groupscache = $cache->read("usergroups");
  35  
  36  if(!is_array($groupscache))
  37  {
  38      $cache->update_usergroups();
  39      $groupscache = $cache->read("usergroups");
  40  }
  41  
  42  // Send no cache headers
  43  header("Expires: Sat, 1 Jan 2000 01:00:00 GMT");
  44  header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  45  header("Cache-Control: no-cache, must-revalidate");
  46  header("Pragma: no-cache");
  47  
  48  // Create the session
  49  require_once  MYBB_ROOT."inc/class_session.php";
  50  $session = new session;
  51  $session->init();
  52  
  53  // Load the language we'll be using
  54  if(!isset($mybb->settings['bblanguage']))
  55  {
  56      $mybb->settings['bblanguage'] = "english";
  57  }
  58  if(isset($mybb->user['language']) && $lang->language_exists($mybb->user['language']))
  59  {
  60      $mybb->settings['bblanguage'] = $mybb->user['language'];
  61  }
  62  $lang->set_language($mybb->settings['bblanguage']);
  63  
  64  if(function_exists('mb_internal_encoding') && !empty($lang->settings['charset']))
  65  {
  66      @mb_internal_encoding($lang->settings['charset']);
  67  }
  68  
  69  // Load the theme
  70  // 1. Check cookies
  71  if(!$mybb->user['uid'] && !empty($mybb->cookies['mybbtheme']))
  72  {
  73      $mybb->user['style'] = (int)$mybb->cookies['mybbtheme'];
  74  }
  75  
  76  // 2. Load style
  77  if(isset($mybb->user['style']) && (int)$mybb->user['style'] != 0)
  78  {
  79      $loadstyle = "tid='".(int)$mybb->user['style']."'";
  80  }
  81  else
  82  {
  83      $loadstyle = "def='1'";
  84  }
  85  
  86  // Load basic theme information that we could be needing.
  87  if($loadstyle != "def='1'")
  88  {
  89      $query = $db->simple_select('themes', 'name, tid, properties, allowedgroups', $loadstyle, array('limit' => 1));
  90      $theme = $db->fetch_array($query);
  91  
  92      if($theme && !is_member($theme['allowedgroups']) && $theme['allowedgroups'] != 'all')
  93      {
  94          if(isset($mybb->cookies['mybbtheme']))
  95          {
  96              my_unsetcookie('mybbtheme');
  97          }
  98  
  99          $loadstyle = "def='1'";
 100      }
 101  }
 102  
 103  if($loadstyle == "def='1'")
 104  {
 105      if(!$cache->read('default_theme'))
 106      {
 107          $cache->update_default_theme();
 108      }
 109  
 110      $theme = $cache->read('default_theme');
 111  }
 112  
 113  // No theme was found - we attempt to load the master or any other theme
 114  if(!isset($theme['tid']) || isset($theme['tid']) && !$theme['tid'])
 115  {
 116      // Missing theme was from a user, run a query to set any users using the theme to the default
 117      $db->update_query('users', array('style' => 0), "style = '{$mybb->user['style']}'");
 118  
 119      // Attempt to load the master or any other theme if the master is not available
 120      $query = $db->simple_select('themes', 'name, tid, properties, stylesheets', '', array('order_by' => 'tid', 'limit' => 1));
 121      $theme = $db->fetch_array($query);
 122  }
 123  $theme = @array_merge($theme, my_unserialize($theme['properties']));
 124  
 125  // Set the appropriate image language directory for this theme.
 126  // Are we linking to a remote theme server?
 127  if(my_validate_url($theme['imgdir']))
 128  {
 129      // If a language directory for the current language exists within the theme - we use it
 130      if(!empty($mybb->user['language']))
 131      {
 132          $theme['imglangdir'] = $theme['imgdir'].'/'.$mybb->user['language'];
 133      }
 134      else
 135      {
 136          // Check if a custom language directory exists for this theme
 137          if(!empty($mybb->settings['bblanguage']))
 138          {
 139              $theme['imglangdir'] = $theme['imgdir'].'/'.$mybb->settings['bblanguage'];
 140          }
 141          // Otherwise, the image language directory is the same as the language directory for the theme
 142          else
 143          {
 144              $theme['imglangdir'] = $theme['imgdir'];
 145          }
 146      }
 147  }
 148  else
 149  {
 150      $img_directory = $theme['imgdir'];
 151  
 152      if($mybb->settings['usecdn'] && !empty($mybb->settings['cdnpath']))
 153      {
 154          $img_directory = rtrim($mybb->settings['cdnpath'], '/') . '/' . ltrim($theme['imgdir'], '/');
 155      }
 156  
 157      if(!@is_dir($img_directory))
 158      {
 159          $theme['imgdir'] = 'images';
 160      }
 161  
 162      // If a language directory for the current language exists within the theme - we use it
 163      if(!empty($mybb->user['language']) && is_dir($img_directory.'/'.$mybb->user['language']))
 164      {
 165          $theme['imglangdir'] = $theme['imgdir'].'/'.$mybb->user['language'];
 166      }
 167      else
 168      {
 169          // Check if a custom language directory exists for this theme
 170          if(is_dir($img_directory.'/'.$mybb->settings['bblanguage']))
 171          {
 172              $theme['imglangdir'] = $theme['imgdir'].'/'.$mybb->settings['bblanguage'];
 173          }
 174          // Otherwise, the image language directory is the same as the language directory for the theme
 175          else
 176          {
 177              $theme['imglangdir'] = $theme['imgdir'];
 178          }
 179      }
 180  
 181      $theme['imgdir'] = $mybb->get_asset_url($theme['imgdir']);
 182      $theme['imglangdir'] = $mybb->get_asset_url($theme['imglangdir']);
 183  }
 184  
 185  $templatelist = "postbit_editedby,xmlhttp_buddyselect_online,xmlhttp_buddyselect_offline,xmlhttp_buddyselect";
 186  $templates->cache($db->escape_string($templatelist));
 187  
 188  if($lang->settings['charset'])
 189  {
 190      $charset = $lang->settings['charset'];
 191  }
 192  // If not, revert to UTF-8
 193  else
 194  {
 195      $charset = "UTF-8";
 196  }
 197  
 198  $lang->load("global");
 199  $lang->load("xmlhttp");
 200  
 201  $closed_bypass = array("refresh_captcha", "validate_captcha");
 202  
 203  $mybb->input['action'] = $mybb->get_input('action');
 204  
 205  $plugins->run_hooks("xmlhttp");
 206  
 207  // If the board is closed, the user is not an administrator and they're not trying to login, show the board closed message
 208  if($mybb->settings['boardclosed'] == 1 && $mybb->usergroup['canviewboardclosed'] != 1 && !in_array($mybb->input['action'], $closed_bypass))
 209  {
 210      // Show error
 211      if(!$mybb->settings['boardclosed_reason'])
 212      {
 213          $mybb->settings['boardclosed_reason'] = $lang->boardclosed_reason;
 214      }
 215  
 216      $lang->error_boardclosed .= "<br /><em>{$mybb->settings['boardclosed_reason']}</em>";
 217  
 218      xmlhttp_error($lang->error_boardclosed);
 219  }
 220  
 221  // Fetch a list of usernames beginning with a certain string (used for auto completion)
 222  if($mybb->input['action'] == "get_users")
 223  {
 224      $mybb->input['query'] = ltrim($mybb->get_input('query'));
 225      $search_type = $mybb->get_input('search_type', MyBB::INPUT_INT); // 0: starts with, 1: ends with, 2: contains
 226  
 227      // If the string is less than 2 characters, quit.
 228      if(my_strlen($mybb->input['query']) < 2)
 229      {
 230          exit;
 231      }
 232  
 233      if($mybb->get_input('getone', MyBB::INPUT_INT) == 1)
 234      {
 235          $limit = 1;
 236      }
 237      else
 238      {
 239          $limit = 15;
 240      }
 241  
 242      // Send our headers.
 243      header("Content-type: application/json; charset={$charset}");
 244  
 245      // Query for any matching users.
 246      $query_options = array(
 247          "order_by" => "username",
 248          "order_dir" => "asc",
 249          "limit_start" => 0,
 250          "limit" => $limit
 251      );
 252  
 253      $plugins->run_hooks("xmlhttp_get_users_start");
 254  
 255      $likestring = $db->escape_string_like($mybb->input['query']);
 256      if($search_type == 1)
 257      {
 258          $likestring = '%'.$likestring;
 259      }
 260      elseif($search_type == 2)
 261      {
 262          $likestring = '%'.$likestring.'%';
 263      }
 264      else
 265      {
 266          $likestring .= '%';
 267      }
 268  
 269      $query = $db->simple_select("users", "uid, username", "username LIKE '{$likestring}'", $query_options);
 270      if($limit == 1)
 271      {
 272          $user = $db->fetch_array($query);
 273          $data = array('uid' => $user['uid'], 'id' => $user['username'], 'text' => $user['username']);
 274      }
 275      else
 276      {
 277          $data = array();
 278          while($user = $db->fetch_array($query))
 279          {
 280              $data[] = array('uid' => $user['uid'], 'id' => $user['username'], 'text' => $user['username']);
 281          }
 282      }
 283  
 284      $plugins->run_hooks("xmlhttp_get_users_end");
 285  
 286      echo json_encode($data);
 287      exit;
 288  }
 289  // This action provides editing of thread/post subjects from within their respective list pages.
 290  else if($mybb->input['action'] == "edit_subject" && $mybb->request_method == "post")
 291  {
 292      // Verify POST request
 293      if(!verify_post_check($mybb->get_input('my_post_key'), true))
 294      {
 295          xmlhttp_error($lang->invalid_post_code);
 296      }
 297  
 298      // We're editing a thread subject.
 299      if($mybb->get_input('tid', MyBB::INPUT_INT))
 300      {
 301          // Fetch the thread.
 302          $thread = get_thread($mybb->get_input('tid', MyBB::INPUT_INT));
 303          if(!$thread)
 304          {
 305              xmlhttp_error($lang->thread_doesnt_exist);
 306          }
 307  
 308          // Fetch some of the information from the first post of this thread.
 309          $query_options = array(
 310              "order_by" => "dateline, pid",
 311          );
 312          $query = $db->simple_select("posts", "pid,uid,dateline", "tid='".$thread['tid']."'", $query_options);
 313          $post = $db->fetch_array($query);
 314      }
 315      else
 316      {
 317          exit;
 318      }
 319  
 320      // Fetch the specific forum this thread/post is in.
 321      $forum = get_forum($thread['fid']);
 322  
 323      // Missing thread, invalid forum? Error.
 324      if(!$forum || $forum['type'] != "f")
 325      {
 326          xmlhttp_error($lang->thread_doesnt_exist);
 327      }
 328  
 329      // Fetch forum permissions.
 330      $forumpermissions = forum_permissions($forum['fid']);
 331  
 332      $plugins->run_hooks("xmlhttp_edit_subject_start");
 333  
 334      // If this user is not a moderator with "caneditposts" permissions.
 335      if(!is_moderator($forum['fid'], "caneditposts"))
 336      {
 337          // Thread is closed - no editing allowed.
 338          if($thread['closed'] == 1)
 339          {
 340              xmlhttp_error($lang->thread_closed_edit_subjects);
 341          }
 342          // Forum is not open, user doesn't have permission to edit, or author doesn't match this user - don't allow editing.
 343          else if($forum['open'] == 0 || $forumpermissions['caneditposts'] == 0 || $mybb->user['uid'] != $post['uid'] || $mybb->user['uid'] == 0)
 344          {
 345              xmlhttp_error($lang->no_permission_edit_subject);
 346          }
 347          // If we're past the edit time limit - don't allow editing.
 348          else if($mybb->usergroup['edittimelimit'] != 0 && $post['dateline'] < (TIME_NOW-($mybb->usergroup['edittimelimit']*60)))
 349          {
 350              $lang->edit_time_limit = $lang->sprintf($lang->edit_time_limit, $mybb->usergroup['edittimelimit']);
 351              xmlhttp_error($lang->edit_time_limit);
 352          }
 353          $ismod = false;
 354      }
 355      else
 356      {
 357          $ismod = true;
 358      }
 359      $subject = $mybb->get_input('value');
 360      if(my_strtolower($charset) != "utf-8")
 361      {
 362          if(function_exists("iconv"))
 363          {
 364              $subject = iconv($charset, "UTF-8//IGNORE", $subject);
 365          }
 366          else if(function_exists("mb_convert_encoding"))
 367          {
 368              $subject = @mb_convert_encoding($subject, $charset, "UTF-8");
 369          }
 370          else if(my_strtolower($charset) == "iso-8859-1")
 371          {
 372              $subject = utf8_decode($subject);
 373          }
 374      }
 375  
 376      // Only edit subject if subject has actually been changed
 377      if($thread['subject'] != $subject)
 378      {
 379          // Set up posthandler.
 380          require_once  MYBB_ROOT."inc/datahandlers/post.php";
 381          $posthandler = new PostDataHandler("update");
 382          $posthandler->action = "post";
 383  
 384          // Set the post data that came from the input to the $post array.
 385          $updatepost = array(
 386              "pid" => $post['pid'],
 387              "tid" => $thread['tid'],
 388              "fid" => $forum['fid'],
 389              "prefix" => $thread['prefix'],
 390              "subject" => $subject,
 391              "edit_uid" => $mybb->user['uid']
 392          );
 393          $posthandler->set_data($updatepost);
 394  
 395          // Now let the post handler do all the hard work.
 396          if(!$posthandler->validate_post())
 397          {
 398              $post_errors = $posthandler->get_friendly_errors();
 399              xmlhttp_error($post_errors);
 400          }
 401          // No errors were found, we can call the update method.
 402          else
 403          {
 404              $posthandler->update_post();
 405              if($ismod == true)
 406              {
 407                  $modlogdata = array(
 408                      "tid" => $thread['tid'],
 409                      "fid" => $forum['fid']
 410                  );
 411                  log_moderator_action($modlogdata, $lang->edited_post);
 412              }
 413          }
 414      }
 415  
 416      require_once  MYBB_ROOT."inc/class_parser.php";
 417      $parser = new postParser;
 418  
 419      // Send our headers.
 420      header("Content-type: application/json; charset={$charset}");
 421  
 422      $plugins->run_hooks("xmlhttp_edit_subject_end");
 423  
 424      $mybb->input['value'] = $parser->parse_badwords($mybb->get_input('value'));
 425  
 426      // Spit the subject back to the browser.
 427      $subject = substr($mybb->input['value'], 0, 120); // 120 is the varchar length for the subject column
 428      echo json_encode(array("subject" => '<a href="'.get_thread_link($thread['tid']).'">'.htmlspecialchars_uni($subject).'</a>'));
 429  
 430      // Close the connection.
 431      exit;
 432  }
 433  else if($mybb->input['action'] == "edit_post")
 434  {
 435      // Fetch the post from the database.
 436      $post = get_post($mybb->get_input('pid', MyBB::INPUT_INT));
 437  
 438      // No result, die.
 439      if(!$post || $post['visible'] == -1)
 440      {
 441          xmlhttp_error($lang->post_doesnt_exist);
 442      }
 443  
 444      // Fetch the thread associated with this post.
 445      $thread = get_thread($post['tid']);
 446  
 447      // Fetch the specific forum this thread/post is in.
 448      $forum = get_forum($thread['fid']);
 449  
 450      // Missing thread, invalid forum? Error.
 451      if(!$thread || !$forum || $forum['type'] != "f")
 452      {
 453          xmlhttp_error($lang->thread_doesnt_exist);
 454      }
 455  
 456      // Check if this forum is password protected and we have a valid password
 457      if(check_forum_password($forum['fid'], 0, true))
 458      {
 459          xmlhttp_error($lang->wrong_forum_password);
 460      }
 461  
 462      // Fetch forum permissions.
 463      $forumpermissions = forum_permissions($forum['fid']);
 464  
 465      $plugins->run_hooks("xmlhttp_edit_post_start");
 466  
 467      // If this user is not a moderator with "caneditposts" permissions.
 468      if(!is_moderator($forum['fid'], "caneditposts"))
 469      {
 470          // Thread is closed - no editing allowed.
 471          if($thread['closed'] == 1)
 472          {
 473              xmlhttp_error($lang->thread_closed_edit_message);
 474          }
 475          // Forum is not open, user doesn't have permission to edit, or author doesn't match this user - don't allow editing.
 476          else if($forum['open'] == 0 || $forumpermissions['caneditposts'] == 0 || $mybb->user['uid'] != $post['uid'] || $mybb->user['uid'] == 0 || $mybb->user['suspendposting'] == 1)
 477          {
 478              xmlhttp_error($lang->no_permission_edit_post);
 479          }
 480          // If we're past the edit time limit - don't allow editing.
 481          else if($mybb->usergroup['edittimelimit'] != 0 && $post['dateline'] < (TIME_NOW-($mybb->usergroup['edittimelimit']*60)))
 482          {
 483              $lang->edit_time_limit = $lang->sprintf($lang->edit_time_limit, $mybb->usergroup['edittimelimit']);
 484              xmlhttp_error($lang->edit_time_limit);
 485          }
 486          // User can't edit unapproved post unless permitted for own
 487          if($post['visible'] == 0 && !($mybb->settings['showownunapproved'] && $post['uid'] == $mybb->user['uid']))
 488          {
 489              xmlhttp_error($lang->post_moderation);
 490          }
 491      }
 492  
 493      $plugins->run_hooks("xmlhttp_edit_post_end");
 494  
 495      if($mybb->get_input('do') == "get_post")
 496      {
 497          // Send our headers.
 498          header("Content-type: application/json; charset={$charset}");
 499  
 500          // Send the contents of the post.
 501          echo json_encode($post['message']);
 502          exit;
 503      }
 504      else if($mybb->get_input('do') == "update_post")
 505      {
 506          // Verify POST request
 507          if(!verify_post_check($mybb->get_input('my_post_key'), true))
 508          {
 509              xmlhttp_error($lang->invalid_post_code);
 510          }
 511  
 512          $message = $mybb->get_input('value');
 513          $editreason = $mybb->get_input('editreason');
 514          if(my_strtolower($charset) != "utf-8")
 515          {
 516              if(function_exists("iconv"))
 517              {
 518                  $message = iconv($charset, "UTF-8//IGNORE", $message);
 519                  $editreason = iconv($charset, "UTF-8//IGNORE", $editreason);
 520              }
 521              else if(function_exists("mb_convert_encoding"))
 522              {
 523                  $message = @mb_convert_encoding($message, $charset, "UTF-8");
 524                  $editreason = @mb_convert_encoding($editreason, $charset, "UTF-8");
 525              }
 526              else if(my_strtolower($charset) == "iso-8859-1")
 527              {
 528                  $message = utf8_decode($message);
 529                  $editreason = utf8_decode($editreason);
 530              }
 531          }
 532  
 533          // Set up posthandler.
 534          require_once  MYBB_ROOT."inc/datahandlers/post.php";
 535          $posthandler = new PostDataHandler("update");
 536          $posthandler->action = "post";
 537  
 538          // Set the post data that came from the input to the $post array.
 539          $updatepost = array(
 540              "pid" => $post['pid'],
 541              "message" => $message,
 542              "editreason" => $editreason,
 543              "edit_uid" => $mybb->user['uid']
 544          );
 545  
 546          // If this is the first post set the prefix. If a forum requires a prefix the quick edit would throw an error otherwise
 547          if($post['pid'] == $thread['firstpost'])
 548          {
 549              $updatepost['prefix'] = $thread['prefix'];
 550          }
 551  
 552          $posthandler->set_data($updatepost);
 553  
 554          // Now let the post handler do all the hard work.
 555          if(!$posthandler->validate_post())
 556          {
 557              $post_errors = $posthandler->get_friendly_errors();
 558              xmlhttp_error($post_errors);
 559          }
 560          // No errors were found, we can call the update method.
 561          else
 562          {
 563              $postinfo = $posthandler->update_post();
 564              $visible = $postinfo['visible'];
 565              if($visible == 0 && !is_moderator($post['fid'], "canviewunapprove"))
 566              {
 567                  // Is it the first post?
 568                  if($thread['firstpost'] == $post['pid'])
 569                  {
 570                      echo json_encode(array("moderation_thread" => $lang->thread_moderation, 'url' => $mybb->settings['bburl'].'/'.get_forum_link($thread['fid']), "message" => $post['message']));
 571                      exit;
 572                  }
 573                  else
 574                  {
 575                      echo json_encode(array("moderation_post" => $lang->post_moderation, 'url' => $mybb->settings['bburl'].'/'.get_thread_link($thread['tid']), "message" => $post['message']));
 576                      exit;
 577                  }
 578              }
 579          }
 580  
 581          require_once  MYBB_ROOT."inc/class_parser.php";
 582          $parser = new postParser;
 583  
 584          $parser_options = array(
 585              "allow_html" => $forum['allowhtml'],
 586              "allow_mycode" => $forum['allowmycode'],
 587              "allow_smilies" => $forum['allowsmilies'],
 588              "allow_imgcode" => $forum['allowimgcode'],
 589              "allow_videocode" => $forum['allowvideocode'],
 590              "me_username" => $post['username'],
 591              "filter_badwords" => 1
 592          );
 593  
 594          $post['username'] = htmlspecialchars_uni($post['username']);
 595  
 596          if($post['smilieoff'] == 1)
 597          {
 598              $parser_options['allow_smilies'] = 0;
 599          }
 600  
 601          if($mybb->user['uid'] != 0 && $mybb->user['showimages'] != 1 || $mybb->settings['guestimages'] != 1 && $mybb->user['uid'] == 0)
 602          {
 603              $parser_options['allow_imgcode'] = 0;
 604          }
 605  
 606          if($mybb->user['uid'] != 0 && $mybb->user['showvideos'] != 1 || $mybb->settings['guestvideos'] != 1 && $mybb->user['uid'] == 0)
 607          {
 608              $parser_options['allow_videocode'] = 0;
 609          }
 610  
 611          $post['message'] = $parser->parse_message($message, $parser_options);
 612  
 613          // Now lets fetch all of the attachments for these posts.
 614          if($mybb->settings['enableattachments'] != 0)
 615          {
 616              $query = $db->simple_select("attachments", "*", "pid='{$post['pid']}'");
 617              while($attachment = $db->fetch_array($query))
 618              {
 619                  $attachcache[$attachment['pid']][$attachment['aid']] = $attachment;
 620              }
 621  
 622              require_once  MYBB_ROOT."inc/functions_post.php";
 623  
 624              get_post_attachments($post['pid'], $post);
 625          }
 626  
 627          // Figure out if we need to show an "edited by" message
 628          // Only show if at least one of "showeditedby" or "showeditedbyadmin" is enabled
 629          if($mybb->settings['showeditedby'] != 0 && $mybb->settings['showeditedbyadmin'] != 0)
 630          {
 631              $post['editdate'] = my_date('relative', TIME_NOW);
 632              $post['editnote'] = $lang->sprintf($lang->postbit_edited, $post['editdate']);
 633              $mybb->user['username'] = htmlspecialchars_uni($mybb->user['username']);
 634              $post['editedprofilelink'] = build_profile_link($mybb->user['username'], $mybb->user['uid']);
 635              $post['editreason'] = trim($editreason);
 636              $editreason = "";
 637              if($post['editreason'] != "")
 638              {
 639                  $post['editreason'] = $parser->parse_badwords($post['editreason']);
 640                  $post['editreason'] = htmlspecialchars_uni($post['editreason']);
 641                  eval("\$editreason = \"".$templates->get("postbit_editedby_editreason")."\";");
 642              }
 643              eval("\$editedmsg = \"".$templates->get("postbit_editedby")."\";");
 644          }
 645  
 646          // Send our headers.
 647          header("Content-type: application/json; charset={$charset}");
 648  
 649          $editedmsg_response = null;
 650          if(!empty($editedmsg))
 651          {
 652              $editedmsg_response = str_replace(array("\r", "\n"), "", $editedmsg);
 653          }
 654  
 655          $plugins->run_hooks("xmlhttp_update_post");
 656  
 657          echo json_encode(array("message" => $post['message']."\n", "editedmsg" => $editedmsg_response));
 658          exit;
 659      }
 660  }
 661  // Fetch the list of multiquoted posts which are not in a specific thread
 662  else if($mybb->input['action'] == "get_multiquoted")
 663  {
 664      // If the cookie does not exist, exit
 665      if(!array_key_exists("multiquote", $mybb->cookies))
 666      {
 667          exit;
 668      }
 669      // Divide up the cookie using our delimeter
 670      $multiquoted = explode("|", $mybb->cookies['multiquote']);
 671  
 672      $plugins->run_hooks("xmlhttp_get_multiquoted_start");
 673  
 674      // No values - exit
 675      if(!is_array($multiquoted))
 676      {
 677          exit;
 678      }
 679  
 680      // Loop through each post ID and sanitize it before querying
 681      foreach($multiquoted as $post)
 682      {
 683          $quoted_posts[$post] = (int)$post;
 684      }
 685  
 686      // Join the post IDs back together
 687      $quoted_posts = implode(",", $quoted_posts);
 688  
 689      // Fetch unviewable forums
 690      $unviewable_forums = get_unviewable_forums();
 691      $inactiveforums = get_inactive_forums();
 692      if($unviewable_forums)
 693      {
 694          $unviewable_forums = "AND t.fid NOT IN ({$unviewable_forums})";
 695      }
 696      if($inactiveforums)
 697      {
 698          $inactiveforums = "AND t.fid NOT IN ({$inactiveforums})";
 699      }
 700  
 701      // Check group permissions if we can't view threads not started by us
 702      $group_permissions = forum_permissions();
 703      $onlyusfids = array();
 704      foreach($group_permissions as $gpfid => $forum_permissions)
 705      {
 706          if(isset($forum_permissions['canonlyviewownthreads']) && $forum_permissions['canonlyviewownthreads'] == 1)
 707          {
 708              $onlyusfids[] = $gpfid;
 709          }
 710      }
 711  
 712      $message = '';
 713  
 714      // Are we loading all quoted posts or only those not in the current thread?
 715      if(empty($mybb->input['load_all']))
 716      {
 717          $from_tid = "p.tid != '".$mybb->get_input('tid', MyBB::INPUT_INT)."' AND ";
 718      }
 719      else
 720      {
 721          $from_tid = '';
 722      }
 723  
 724      require_once  MYBB_ROOT."inc/class_parser.php";
 725      $parser = new postParser;
 726  
 727      require_once  MYBB_ROOT."inc/functions_posting.php";
 728  
 729      $plugins->run_hooks("xmlhttp_get_multiquoted_intermediate");
 730  
 731      // Query for any posts in the list which are not within the specified thread
 732      $query = $db->query("
 733          SELECT p.subject, p.message, p.pid, p.tid, p.username, p.dateline, t.fid, t.uid AS thread_uid, p.visible, u.username AS userusername
 734          FROM ".TABLE_PREFIX."posts p
 735          LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
 736          LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=p.uid)
 737          WHERE {$from_tid}p.pid IN ({$quoted_posts}) {$unviewable_forums} {$inactiveforums}
 738          ORDER BY p.dateline, p.pid
 739      ");
 740      while($quoted_post = $db->fetch_array($query))
 741      {
 742          if(
 743              (!is_moderator($quoted_post['fid'], "canviewunapprove") && $quoted_post['visible'] == 0) ||
 744              (!is_moderator($quoted_post['fid'], "canviewdeleted") && $quoted_post['visible'] == -1) ||
 745              (in_array($quoted_post['fid'], $onlyusfids) && (!$mybb->user['uid'] || $quoted_post['thread_uid'] != $mybb->user['uid']))
 746          )
 747          {
 748              // Allow quoting from own unapproved post
 749              if($quoted_post['visible'] == 0 && !($mybb->settings['showownunapproved'] && $quoted_post['uid'] == $mybb->user['uid']))
 750              {
 751                  continue;
 752              }
 753          }
 754  
 755          $message .= parse_quoted_message($quoted_post, false);
 756      }
 757      if($mybb->settings['maxquotedepth'] != '0')
 758      {
 759          $message = remove_message_quotes($message);
 760      }
 761  
 762      // Send our headers.
 763      header("Content-type: application/json; charset={$charset}");
 764  
 765      $plugins->run_hooks("xmlhttp_get_multiquoted_end");
 766  
 767      echo json_encode(array("message" => $message));
 768      exit;
 769  }
 770  else if($mybb->input['action'] == "refresh_captcha")
 771  {
 772      $imagehash = $db->escape_string($mybb->get_input('imagehash'));
 773      $query = $db->simple_select("captcha", "dateline", "imagehash='$imagehash'");
 774      if($db->num_rows($query) == 0)
 775      {
 776          xmlhttp_error($lang->captcha_not_exists);
 777      }
 778      $db->delete_query("captcha", "imagehash='$imagehash'");
 779      $randomstr = random_str(5);
 780      $imagehash = md5(random_str(12));
 781      $regimagearray = array(
 782          "imagehash" => $imagehash,
 783          "imagestring" => $randomstr,
 784          "dateline" => TIME_NOW
 785      );
 786  
 787      $plugins->run_hooks("xmlhttp_refresh_captcha");
 788  
 789      $db->insert_query("captcha", $regimagearray);
 790      header("Content-type: application/json; charset={$charset}");
 791      echo json_encode(array("imagehash" => $imagehash));
 792      exit;
 793  }
 794  else if($mybb->input['action'] == "validate_captcha")
 795  {
 796      header("Content-type: application/json; charset={$charset}");
 797      $imagehash = $db->escape_string($mybb->get_input('imagehash'));
 798      $query = $db->simple_select("captcha", "imagestring", "imagehash='$imagehash'");
 799      if($db->num_rows($query) == 0)
 800      {
 801          echo json_encode($lang->captcha_valid_not_exists);
 802          exit;
 803      }
 804      $imagestring = $db->fetch_field($query, 'imagestring');
 805  
 806      $plugins->run_hooks("xmlhttp_validate_captcha");
 807  
 808      if(my_strtolower($imagestring) == my_strtolower($mybb->get_input('imagestring')))
 809      {
 810          //echo json_encode(array("success" => $lang->captcha_matches));
 811          echo json_encode("true");
 812          exit;
 813      }
 814      else
 815      {
 816          echo json_encode($lang->captcha_does_not_match);
 817          exit;
 818      }
 819  }
 820  else if($mybb->input['action'] == "refresh_question" && $mybb->settings['securityquestion'])
 821  {
 822      header("Content-type: application/json; charset={$charset}");
 823  
 824      $sid = $db->escape_string($mybb->get_input('question_id'));
 825      $query = $db->query("
 826          SELECT q.qid, s.sid
 827          FROM ".TABLE_PREFIX."questionsessions s
 828          LEFT JOIN ".TABLE_PREFIX."questions q ON (q.qid=s.qid)
 829          WHERE q.active='1' AND s.sid='{$sid}'
 830      ");
 831  
 832      if($db->num_rows($query) == 0)
 833      {
 834          xmlhttp_error($lang->answer_valid_not_exists);
 835      }
 836  
 837      $qsession = $db->fetch_array($query);
 838  
 839      // Delete previous question session
 840      $db->delete_query("questionsessions", "sid='$sid'");
 841  
 842      require_once  MYBB_ROOT."inc/functions_user.php";
 843  
 844      $sid = generate_question($qsession['qid']);
 845      $query = $db->query("
 846          SELECT q.question, s.sid
 847          FROM ".TABLE_PREFIX."questionsessions s
 848          LEFT JOIN ".TABLE_PREFIX."questions q ON (q.qid=s.qid)
 849          WHERE q.active='1' AND s.sid='{$sid}' AND q.qid!='{$qsession['qid']}'
 850      ");
 851  
 852      $plugins->run_hooks("xmlhttp_refresh_question");
 853      
 854      require_once  MYBB_ROOT."inc/class_parser.php";
 855      $parser = new postParser;
 856      
 857      $parser_options = array(
 858          "allow_html" => 0,
 859          "allow_mycode" => 1,
 860          "allow_smilies" => 1,
 861          "allow_imgcode" => 1,
 862          "allow_videocode" => 1,
 863          "filter_badwords" => 1,
 864          "me_username" => 0,
 865          "shorten_urls" => 0,
 866          "highlight" => 0,
 867      );    
 868  
 869      if($db->num_rows($query) > 0)
 870      {
 871          $question = $db->fetch_array($query);
 872  
 873          echo json_encode(array("question" => $parser->parse_message($question['question'], $parser_options), 'sid' => htmlspecialchars_uni($question['sid'])));
 874          exit;
 875      }
 876      else
 877      {
 878          xmlhttp_error($lang->answer_valid_not_exists);
 879      }
 880  }
 881  elseif($mybb->input['action'] == "validate_question" && $mybb->settings['securityquestion'])
 882  {
 883      header("Content-type: application/json; charset={$charset}");
 884      $sid = $db->escape_string($mybb->get_input('question'));
 885      $answer = $db->escape_string($mybb->get_input('answer'));
 886  
 887      $query = $db->query("
 888          SELECT q.*, s.sid
 889          FROM ".TABLE_PREFIX."questionsessions s
 890          LEFT JOIN ".TABLE_PREFIX."questions q ON (q.qid=s.qid)
 891          WHERE q.active='1' AND s.sid='{$sid}'
 892      ");
 893  
 894      if($db->num_rows($query) == 0)
 895      {
 896          echo json_encode($lang->answer_valid_not_exists);
 897          exit;
 898      }
 899      else
 900      {
 901          $question = $db->fetch_array($query);
 902          $valid_answers = preg_split("/\r\n|\n|\r/", $question['answer']);
 903          $validated = 0;
 904  
 905          foreach($valid_answers as $answers)
 906          {
 907              if(my_strtolower($answers) == my_strtolower($answer))
 908              {
 909                  $validated = 1;
 910              }
 911          }
 912  
 913          $plugins->run_hooks("xmlhttp_validate_question");
 914  
 915          if($validated != 1)
 916          {
 917              echo json_encode($lang->answer_does_not_match);
 918              exit;
 919          }
 920          else
 921          {
 922              echo json_encode("true");
 923              exit;
 924          }
 925      }
 926  
 927      exit;
 928  }
 929  else if($mybb->input['action'] == "complex_password")
 930  {
 931      $password = trim($mybb->get_input('password'));
 932      $password = str_replace(array(unichr(160), unichr(173), unichr(0xCA), dec_to_utf8(8238), dec_to_utf8(8237), dec_to_utf8(8203)), array(" ", "-", "", "", "", ""), $password);
 933  
 934      header("Content-type: application/json; charset={$charset}");
 935  
 936      $plugins->run_hooks("xmlhttp_complex_password");
 937  
 938      if(!preg_match("/^.*(?=.{".$mybb->settings['minpasswordlength'].",})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/", $password))
 939      {
 940          echo json_encode($lang->complex_password_fails);
 941      }
 942      else
 943      {
 944          // Return nothing but an OK password if passes regex
 945          echo json_encode("true");
 946      }
 947  
 948      exit;
 949  }
 950  else if($mybb->input['action'] == "username_availability")
 951  {
 952      if(!verify_post_check($mybb->get_input('my_post_key'), true))
 953      {
 954          xmlhttp_error($lang->invalid_post_code);
 955      }
 956  
 957      require_once  MYBB_ROOT."inc/functions_user.php";
 958      $username = $mybb->get_input('username');
 959  
 960      // Fix bad characters
 961      $username = trim_blank_chrs($username);
 962      $username = str_replace(array(unichr(160), unichr(173), unichr(0xCA), dec_to_utf8(8238), dec_to_utf8(8237), dec_to_utf8(8203)), array(" ", "-", "", "", "", ""), $username);
 963  
 964      // Remove multiple spaces from the username
 965      $username = preg_replace("#\s{2,}#", " ", $username);
 966  
 967      header("Content-type: application/json; charset={$charset}");
 968  
 969      if(empty($username))
 970      {
 971          echo json_encode($lang->banned_characters_username);
 972          exit;
 973      }
 974  
 975      // Check if the username belongs to the list of banned usernames.
 976      $banned_username = is_banned_username($username, true);
 977      if($banned_username)
 978      {
 979          echo json_encode($lang->banned_username);
 980          exit;
 981      }
 982  
 983      // Check for certain characters in username (<, >, &, and slashes)
 984      if(strpos($username, "<") !== false || strpos($username, ">") !== false || strpos($username, "&") !== false || my_strpos($username, "\\") !== false || strpos($username, ";") !== false || strpos($username, ",") !== false || !validate_utf8_string($username, false, false))
 985      {
 986          echo json_encode($lang->banned_characters_username);
 987          exit;
 988      }
 989  
 990      // Check if the username is actually already in use
 991      $user = get_user_by_username($username);
 992  
 993      $plugins->run_hooks("xmlhttp_username_availability");
 994  
 995      if($user)
 996      {
 997          $lang->username_taken = $lang->sprintf($lang->username_taken, htmlspecialchars_uni($username));
 998          echo json_encode($lang->username_taken);
 999          exit;
1000      }
1001      else
1002      {
1003          //$lang->username_available = $lang->sprintf($lang->username_available, htmlspecialchars_uni($username));
1004          echo json_encode("true");
1005          exit;
1006      }
1007  }
1008  else if($mybb->input['action'] == "email_availability")
1009  {
1010      if(!verify_post_check($mybb->get_input('my_post_key'), true))
1011      {
1012          xmlhttp_error($lang->invalid_post_code);
1013      }
1014  
1015      require_once  MYBB_ROOT."inc/datahandlers/user.php";
1016      $userhandler = new UserDataHandler("insert");
1017  
1018      $email = $mybb->get_input('email');
1019  
1020      header("Content-type: application/json; charset={$charset}");
1021  
1022      $user = array(
1023          'email' => $email
1024      );
1025  
1026      $userhandler->set_data($user);
1027  
1028      $errors = array();
1029  
1030      if(!$userhandler->verify_email())
1031      {
1032          $errors = $userhandler->get_friendly_errors();
1033      }
1034  
1035      $plugins->run_hooks("xmlhttp_email_availability");
1036  
1037      if(!empty($errors))
1038      {
1039          echo json_encode($errors[0]);
1040          exit;
1041      }
1042      else
1043      {
1044          echo json_encode("true");
1045          exit;
1046      }
1047  }
1048  else if($mybb->input['action'] == "get_buddyselect")
1049  {
1050      // Send our headers.
1051      header("Content-type: text/plain; charset={$charset}");
1052  
1053      if($mybb->user['buddylist'] != "")
1054      {
1055          $query_options = array(
1056              "order_by" => "username",
1057              "order_dir" => "asc"
1058          );
1059  
1060          $plugins->run_hooks("xmlhttp_get_buddyselect_start");
1061  
1062          $timecut = TIME_NOW - $mybb->settings['wolcutoff'];
1063          $query = $db->simple_select("users", "uid, username, usergroup, displaygroup, lastactive, lastvisit, invisible", "uid IN ({$mybb->user['buddylist']})", $query_options);
1064          $online = array();
1065          $offline = array();
1066          while($buddy = $db->fetch_array($query))
1067          {
1068              $buddy['username'] = htmlspecialchars_uni($buddy['username']);
1069              $buddy_name = format_name($buddy['username'], $buddy['usergroup'], $buddy['displaygroup']);
1070              $profile_link = build_profile_link($buddy_name, $buddy['uid'], '_blank');
1071              if($buddy['lastactive'] > $timecut && ($buddy['invisible'] == 0 || $mybb->user['usergroup'] == 4) && $buddy['lastvisit'] != $buddy['lastactive'])
1072              {
1073                  eval("\$online[] = \"".$templates->get("xmlhttp_buddyselect_online")."\";");
1074              }
1075              else
1076              {
1077                  eval("\$offline[] = \"".$templates->get("xmlhttp_buddyselect_offline")."\";");
1078              }
1079          }
1080          $online = implode("", $online);
1081          $offline = implode("", $offline);
1082  
1083          $plugins->run_hooks("xmlhttp_get_buddyselect_end");
1084  
1085          eval("\$buddy_select = \"".$templates->get("xmlhttp_buddyselect")."\";");
1086          echo $buddy_select;
1087      }
1088      else
1089      {
1090          xmlhttp_error($lang->buddylist_error);
1091      }
1092  }
1093  else if($mybb->input['action'] == 'get_referrals')
1094  {
1095      $lang->load('member');
1096      $uid = $mybb->get_input('uid', MYBB::INPUT_INT);
1097  
1098      if (!$uid) {
1099          xmlhttp_error($lang->referrals_no_user_specified);
1100      }
1101  
1102      $referrals = get_user_referrals($uid);
1103  
1104      if (empty($referrals)) {
1105          eval("\$referral_rows = \"".$templates->get('member_no_referrals')."\";");
1106      } else {
1107          foreach($referrals as $referral)
1108          {
1109              $bg_color = alt_trow();
1110              // Format user name link
1111              $username = htmlspecialchars_uni($referral['username']);
1112              $username = format_name($username, $referral['usergroup'], $referral['displaygroup']);
1113              $username = build_profile_link($username, $referral['uid']);
1114  
1115              $regdate = my_date('normal', $referral['regdate']);
1116  
1117              eval("\$referral_rows .= \"".$templates->get('member_referral_row')."\";");
1118          }
1119      }
1120  
1121      $plugins->run_hooks('xmlhttp_referrals_end');
1122  
1123      eval("\$referrals = \"".$templates->get('member_referrals_popup', 1, 0)."\";");
1124  
1125      // Send our headers and output.
1126      header("Content-type: text/plain; charset={$charset}");
1127      echo $referrals;
1128  }
1129  
1130  /**
1131   * Spits an XML Http based error message back to the browser
1132   *
1133   * @param string $message The message to send back.
1134   */
1135  function xmlhttp_error($message)
1136  {
1137      global $charset;
1138  
1139      // Send our headers.
1140      header("Content-type: application/json; charset={$charset}");
1141  
1142      // Do we have an array of messages?
1143      if(is_array($message))
1144      {
1145          $response = array();
1146          foreach($message as $error)
1147          {
1148              $response[] = $error;
1149          }
1150  
1151          // Send the error messages.
1152          echo json_encode(array("errors" => array($response)));
1153  
1154          exit;
1155      }
1156  
1157      // Just a single error? Send it along.
1158      echo json_encode(array("errors" => array($message)));
1159  
1160      exit;
1161  }


2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup Cross-referenced by PHPXref