FUDForum PHP Cross Reference Discussion Forums

Source: /scripts/fudapi.inc.php - 1180 lines - 39655 bytes - Summary - Text - Print

   1  <?php
   2  /* If your script does not include GLOBALS.php already,
   3   * uncomment the line below and specify the full path to
   4   * the FUDforum's GLOBALS.php file.
   5   */
   6  // require_once('/path/to/GLOBALS.php');
   7  
   8  /*
   9  General Information
  10  --------------------------------------------
  11   * Most function accept 'id' arguments that allows you to specify
  12   * what data should be retrieved. Unless otherwise indicated this
  13   * argument can be either an integer or an array of integers if you
  14   * want to retrieve more then one item.
  15  
  16   * If you request more then one entry by specifying an array and
  17   * the result has less then the requested number of entries, no
  18   * entries will be returned.
  19   
  20   * On success for single entry data an object containing the data 
  21   * will be returned. For multi-entry data an array of objects will
  22   * be returned.
  23  
  24   * If any functions have optional arguments, they will be indicated
  25   * in the proto by being inside [], all other arguments must be 
  26   * considered as required.
  27  
  28   * If you intend to use FUDAPI from a non-webserver environment,
  29   * make sure that GLOBALS.php, db.inc & err.inc are world readable.
  30   * The GLOBALS.php can be found inside the forum's DATA_DIR/include/
  31   * directory and the inc files can be found inside
  32   * DATA_DIR/include/theme/default/ directory.
  33  */
  34  
  35  /* {{{ proto: mixed fud_fetch_msg(mixed arg) }}}
  36   * This function takes message ids as arguments and returns an object 
  37   * or an array objects representing messages. On failure FALSE will be 
  38   * returned.
  39   * Fields:
  40  stdClass Object
  41  (
  42      [id] => // numeric id of the message
  43      [thread_id] => // numeric id of the topic
  44      [poster_id] => // numeric id of the message author (0 == anonymous)
  45      [reply_to] => // id of the message this message is a reply to
  46      [ip_addr] => // IP address of the poster
  47      [host_name] => // hostname of the poster, !!could be empty!!
  48      [post_stamp] => // unix timestamp representing post date
  49      [update_stamp] => // unix timestamp representing edit date (0 == never edited)
  50      [updated_by] => // id of the person who edited the message (0 == never edited)
  51      [icon] => // message icon, !!could be empty!!
  52      [subject] => // htmlencoded subject
  53      [body] => // htmlencoded body of the message
  54      [attach_cnt] => // number of file attachments
  55      [poll_id] => // id of a poll included in the message, !!could be empty!!
  56      [mlist_msg_id] => // mailing list or nntp message identifier !!could be empty!!
  57      [forum_id] => // of the forum where the message is posted
  58      [login] => // html encoded login mame of the user
  59      [avatar_loc] => // <img src> of the author avatar !!could be empty!!
  60      [email] => // author e-mail address
  61      [posted_msg_count] => // author's post count
  62      [join_date] => // author's join date
  63      [location] => // author's location !!could be empty!!
  64      [sig] => // author's signature !!could be empty!!
  65      [custom_status] =>  // author's custom status (string) !!could be empty!!
  66      [icq] => // author's ICQ uin !!could be empty!!
  67      [jabber] =>  // author's jabber uin !!could be empty!!
  68      [google] =>  // author's google uin !!could be empty!!
  69      [skype] =>  // author's skype uin !!could be empty!!
  70      [twitter] =>  // author's twitter uin !!could be empty!!
  71      [affero] =>  // author's affer uin !!could be empty!!
  72      [aim] => // author's aim uin !!could be empty!!
  73      [msnm] => // author's msn uin !!could be empty!! 
  74      [yahoo] =>  // author's Y! uin !!could be empty!! 
  75      [users_opt] => // author's settings bitmask
  76      [time_sec] => // time of author's last visit
  77      [level_name] => // author's level (based on post count)
  78      [level_img] => // author's level image !!could be empty!!
  79  
  80  --- Poll data, will only be available if a message has a poll ---
  81      [poll_data] => stdClass Object
  82          (
  83              [name] => // poll name
  84              [creation_date] => // poll creation date (unix timestamp) 
  85              [total_votes] => // total # of votes
  86              [id] => // poll id
  87              [options] => // array of option objects
  88                  (
  89                      [0] => stdClass Object
  90                          (
  91                              [name] => fsa
  92                              [count] => 0
  93                          )
  94                  )
  95          )
  96  --- End of Poll data ---
  97  
  98  --- Attachment data, will only be available if a message has file attachments ---
  99      [attachments] => // array of attachments
 100          (
 101              [id] => // attachment id
 102              [location] => // full path to attachment on disk
 103              [original_name] => // attachment's original name
 104              [dlcount] => // number of downloads
 105              [fsize] => // file size
 106              [mime_hdr] => // mime type
 107              [descr] => // text description of the file type
 108              [icon] => // mime type icon
 109              [download_url] => // download URL
 110          )
 111  --- End of Attachment data ---
 112  )
 113  */
 114  function fud_fetch_msg($arg)
 115  {
 116      fud_use('fileio.inc');
 117  
 118      $arg = is_numeric($arg) ? array($arg) : $arg;
 119  
 120      $result = array();
 121      $c = q('SELECT
 122          m.*,
 123          t.forum_id,
 124          u.alias AS login, u.avatar_loc, u.email, u.posted_msg_count, u.join_date, u.location,
 125          u.sig, u.custom_status, u.icq, u.aim, u.msnm, u.yahoo, u.jabber, u.google, u.skype, u.twitter, u.affero, u.users_opt, u.last_visit AS time_sec,
 126          l.name AS level_name, l.img AS level_img
 127      FROM
 128          '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg m
 129          INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread t ON m.thread_id=t.id
 130          LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users u ON m.poster_id=u.id
 131          LEFT JOIN '.$GLOBALS['DBHOST_TBL_PREFIX'] .'level l ON u.level_id=l.id
 132          WHERE m.id IN ('. implode(',', $arg) .') AND m.apr=1');
 133  
 134      while ($r = db_rowobj($c)) {
 135          if ($r->poll_cache && $r->poll_id) {
 136              $r->poll_data = fud_fetch_poll($r->poll_id);
 137              unset($r->poll_data->alias, $r->poll_data->owner);
 138          }
 139          if ($r->attach_cnt && !empty($r->attach_cache)) {
 140              $tmp = @unserialize($r->attach_cache);
 141              $alist = array();
 142              foreach ($tmp as $v) {
 143                  $alist[] = $v[0];
 144              }
 145              $r->attachments = fud_fetch_attachment($alist);
 146          }
 147          $r->body = read_msg_body($r->foff, $r->length, $r->file_id);
 148          unset(
 149              $r->foff, $r->length, $r->file_id, $r->offset_preview, $r->length_preview, $r->file_id_preview,
 150              $r->attach_cache, $r->poll_cache, $r->apr, $r->msg_opt
 151          );
 152          $result[] = $r;
 153      }
 154      unset($c, $r);
 155  
 156      if (count($result) != count($arg)) {
 157          return FALSE;
 158      } else {
 159          if (count($result) == 1) {
 160              return array_pop($result);
 161          } else {
 162              return $result;
 163          }
 164      }
 165  }
 166  
 167  /* {{{ proto: mixed fud_fetch_full_topic(mixed arg) }}}
 168   * This function takes topic id(s) as arguments and returns all of the 
 169   * messages inside the selected topics.
 170   * The output is identical to that of the fud_fetch_msg() function.
 171   */
 172  function fud_fetch_full_topic($arg)
 173  {
 174      return _fud_msg_multi($arg, 'SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg WHERE thread_id IN ({ARG}) AND apr=1');
 175  }
 176  
 177  /* {{{ proto: mixed fud_fetch_recent_msg([float arg = 1]) }}}
 178   * This function retrieves messages that were posted after specified date.
 179   * The date range is in days and is optional, by default messages newer
 180   * then 1 day will be returned.
 181   * The output is identical to that of the fud_fetch_msg() function.
 182   */
 183  function fud_fetch_recent_msg($arg=1)
 184  {
 185      $range = time() - 86400 * (float) $arg;
 186      return _fud_msg_multi(0, 'SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg WHERE apr=1 AND post_stamp > '. $range);
 187  }
 188  
 189  /* {{{ proto: mixed fetch_fetch_msg_by_user(mixed arg) }}}
 190   * This function returns all messages posted by the specified user(s).
 191   * The output is identical to that of the fud_fetch_msg() function.
 192   */
 193  function fetch_fetch_msg_by_user($arg)
 194  {
 195      return _fud_msg_multi(arg, 'SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg WHERE poster_id IN ({ARG}) AND apr=1');
 196  }
 197  
 198  /* {{{ proto: mixed fud_fetch_topic(mixed arg) }}}
 199   * This function returns information about specified topics.
 200   * Fields:
 201  stdClass Object
 202  (
 203      [attach_cnt] => // number of attachments in the 'root' message
 204      [poll_id] => // id of the poll in the the 'root' message
 205      [subject] => // subject of the topic
 206      [icon] => // icon of the 'root' message
 207      [post_stamp] => // creation date (unix timestamp)
 208      [alias] => // author's login (html encoded)
 209      [id] => // author's id
 210      [topic_id] => // topic id
 211      [moved_to] => // moved to forum id
 212      [root_msg_id] => // id of the 'root' message
 213      [replies] => // number of replies
 214      [rating] => // rating
 215      [views] => // number of views
 216      [type] => // sticky || announcement || null (normal topic)
 217      [tdescr] => // description of the topic
 218  )
 219   */
 220  function fud_fetch_topic($arg)
 221  {
 222      $arg = is_numeric($arg) ? array($arg) : $arg;
 223  
 224      $result = array();    
 225  
 226      $c = uq('SELECT
 227          m.attach_cnt, m.poll_id, m.subject, m.icon, m.post_stamp,
 228          u.alias, u.id,
 229          u2.id, u2.alias,
 230          m2.id, m2.post_stamp,
 231          t.id AS topic_id, t.moved_to, t.root_msg_id, t.replies, t.rating, t.thread_opt, t.views, t.tdescr
 232          FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread t
 233              INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg    m    ON t.root_msg_id=m.id
 234              INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg    m2    ON m2.id=t.last_post_id
 235              LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users    u    ON u.id=m.poster_id
 236              LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users    u2    ON u2.id=m2.poster_id
 237              WHERE t.id IN('. implode(',', $arg) .')');
 238  
 239      while ($r = db_rowobj($c)) {
 240          $r->replies++;
 241          $r->type = $r->thread_opt > 1 ? ($r->thread_opt & 4 ? 'sticky' : 'announcement') : NULL;
 242          if ($GLOBALS['FUD_OPT_2'] & 4096 && $r->rating) {
 243              $r->rating = NULL;
 244          }
 245          unset($r->thread_opt);
 246          $result[] = $r;
 247      }
 248      unset($c, $r);
 249  
 250      if (count($result) != count($arg)) {
 251          return FALSE;
 252      } else {
 253          if (count($result) == 1) {
 254              return array_pop($result);
 255          } else {
 256              return $result;
 257          }
 258      }
 259  }
 260  
 261  /* {{{ proto: mixed fud_fetch_poll(mixed arg) }}}
 262   * This function returns information about specified poll(s).
 263   * Fields:
 264  stdClass Object
 265  (
 266      [name] => // poll name
 267      [creation_date] => // creation date (unix timestamp)
 268      [total_votes] => // total number of votes
 269      [alias] => // author's login (html encoded)
 270      [id] => // poll id
 271      [owner] => // author's id
 272      [options] => // Poll options array
 273          (
 274              [0] => stdClass Object
 275                  (
 276                      [name] => // option name
 277                      [count] => // vote count
 278                  )
 279          )
 280  )
 281  */
 282  function fud_fetch_poll($arg)
 283  {
 284      $arg = is_numeric($arg) ? array($arg) : $arg;
 285      $result = array();
 286  
 287      $r = q('SELECT p.name, p.creation_date, p.total_votes, u.alias, p.id, p.owner
 288              FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'poll p
 289              LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX']. 'users u ON u.id=p.owner
 290              WHERE p.id IN('. implode(',', $arg) .')');
 291      while ($row = db_rowobj($r)) {
 292          $opts = array();
 293          $r2 = uq('SELECT name, votes FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'poll_opt WHERE poll_id='. $row->id .' ORDER BY id');
 294          while ($row2 = db_rowobj($r2)) {
 295              $opts[] = $row2;
 296          }
 297          $row->options = $opts;
 298          $result[] = $row;
 299      }
 300      unset($r2, $r, $row, $row2);
 301  
 302      if (count($result) != count($arg)) {
 303          return FALSE;
 304      } else {
 305          if (count($result) == 1) {
 306              return array_pop($result);
 307          } else {
 308              return $result;
 309          }
 310      }
 311  }
 312  
 313  /* {{{ proto: mixed fud_fetch_attachment(mixed arg) }}}
 314   * This function returns information about specified file attachment(s).
 315   * Fields:
 316  stdClass Object
 317  (
 318      [id] => // attachment id
 319      [location] => // path on disk
 320      [original_name] => // original name
 321      [owner] => // owner's id
 322      [message_id] => // associated message id
 323      [dlcount] => // download count
 324      [mime_type] => // mime type
 325      [fsize] => // file size in bytes
 326      [alias] => // owner's login name (html encoded)
 327      [mime_hdr] => // mime header
 328      [descr] => // text description of mime type
 329      [icon] => // mime icon
 330      [download_url] => // download URL
 331  )
 332  */
 333  function fud_fetch_attachment($arg)
 334  {
 335      $res = _fud_simple_fetch_query($arg, 'SELECT 
 336              a.*, u.alias, m.mime_hdr, m.descr, m.icon 
 337              FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'attach a 
 338              LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX']. 'users u ON u.id=a.owner
 339              LEFT JOIN '. $GLOBALS['DBHOST_TBL_PREFIX']. 'mime m ON m.id=a.mime_type
 340              WHERE a.id IN({ARG})');
 341  
 342      if (is_array($res)) {
 343          foreach ($res as $k => $v) {
 344              $res[$k]->download_url = $GLOBALS['WWW_ROOT'] .'index.php?t=getfile&amp;id='. $v->id;
 345              unset($res[$k]->attach_opt);
 346          }
 347      } else {
 348          $res->download_url = $GLOBALS['WWW_ROOT'] .'index.php?t=getfile&amp;id='. $res->id;
 349          unset($res->attach_opt);
 350      }
 351      return $res;
 352  }
 353  
 354  /* {{{ proto: mixed fud_fetch_forum(mixed arg, boolean sort) }}}
 355   * This function returns information about specified forum(s).
 356   * Fields:
 357  stdClass Object
 358  (
 359      [id] => // forum id
 360      [cat_id] => // category id
 361      [name] => // forum name (may contain raw HTML)
 362      [descr] => // forum description (may contain raw HTML)
 363      [post_passwd] => // forum's posting password
 364      [forum_icon] => // forum icon
 365      [date_created] => // forum's creation day
 366      [thread_count] => // number of topics
 367      [post_count] => // number of messages
 368      [last_post_id] => // id of the latest message
 369      [max_attach_size] => // maximum size of attached files in Kbytes
 370      [max_file_attachments] => // maximum number of allowed attachments
 371      [moderators] => Array
 372          (
 373              [// moderator's user id] => // moderator's login name (html encoded)
 374          )
 375  )
 376  */
 377  function fud_fetch_forum( $arg = null, $sort = FALSE )
 378  {
 379      $q = "SELECT * FROM {$GLOBALS['DBHOST_TBL_PREFIX']}forum";
 380      if( null != $arg)
 381          $q .= " WHERE id IN ({ARG})";
 382      if( $sort )
 383          $q .= " ORDER BY view_order";
 384      return _fud_simple_fetch_query( $arg, $q );
 385  }
 386  
 387  /* {{{ proto: mixed fud_fetch_cat(mixed arg, boolean sort) }}}
 388   * This function returns information about the specified categories.
 389   * Fields:
 390  stdClass Object
 391  (
 392      [id] => // category id
 393      [name] => // category name (may contain raw html)
 394      [description] => // category description (may contain raw html)
 395      [cat_opt] => // options for the category (see sql/fud_cat.tbl)
 396      [view_order] => // category viewing order (int)
 397      [parent] => // parent category id (int)
 398  )
 399   */
 400  function fud_fetch_cat($arg = null, $sort = FALSE)
 401  {
 402      $q = "SELECT * FROM {$GLOBALS['DBHOST_TBL_PREFIX']}cat";
 403      if( null != $arg)
 404          $q .= " WHERE id IN ({ARG})";
 405      if( $sort )
 406          $q .= " ORDER BY view_order";
 407      return _fud_simple_fetch_query( $arg, $q );
 408  }
 409  
 410  /* {{{ proto: mixed fud_fetch_cat_forums(mixed arg, boolean sort) }}}
 411   * This function returns information about forum(s) inside specified categories.
 412   * The output is identical to that of the fud_fetch_forum() function.
 413   */
 414  function fud_fetch_cat_forums( $arg = null, $sort = FALSE )
 415  {
 416      $q = "SELECT * FROM {$GLOBALS['DBHOST_TBL_PREFIX']}forum";
 417      if( null != $arg)
 418          $q .= " WHERE cat_id IN ({ARG})";
 419      if( $sort )
 420          $q .= " ORDER BY view_order";
 421      return _fud_simple_fetch_query( $arg, $q );
 422  }
 423  
 424  /* {{{ proto: mixed fud_forum_stats() }}}
 425   * This function returns forum statistics.
 426   * Fields:
 427  Array
 428  (
 429      [total_msg] => // total number of messages in the forum
 430      [total_topic] => // total number of topics in the forum
 431      [total_users] => // total number of forum members
 432      [online_users] => // number of currently online users
 433      [newest_user] => // newest forum member
 434          (
 435              [id] => // user's id
 436              [alias] => // user's login (html encoded)
 437          )
 438  )
 439  */
 440  function fud_forum_stats()
 441  {
 442      $tm_expire = __request_timestamp__ - ($GLOBALS['LOGEDIN_TIMEOUT'] * 60);
 443  
 444      $uid = q_singleval('SELECT MAX(id) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users');
 445  
 446      $stats = array(
 447          'total_msg' => q_singleval('SELECT count(*) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg'),
 448          'total_topic' => q_singleval('SELECT count(*) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread'),
 449          'total_users' => q_singleval('SELECT count(*) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users'),
 450          'online_users' => q_singleval('SELECT count(*) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'ses WHERE time_sec>'. $tm_expire .' AND user_id<2000000000'),
 451          'newest_user' => db_arr_assoc('SELECT id, alias FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE id='. $uid)
 452      );
 453  
 454      return $stats;
 455  }
 456  
 457  /* {{{ proto: mixed fud_fetch_online_users() }}}
 458   * This function returns a list of currently online users.
 459   * Fields:
 460  stdClass Object
 461  (
 462      [id] => // user's id
 463      [alias] => // user's login name 
 464      [time_sec] => // time of last access (unix timestamp)
 465      [private] => // wether or not user want's their online status hidden
 466  )
 467  */
 468  function fud_fetch_online_users()
 469  {
 470      $tm_expire = __request_timestamp__ - ($GLOBALS['LOGEDIN_TIMEOUT'] * 60);
 471  
 472      return _fud_simple_fetch_query(0, 'SELECT 
 473              u.id, u.alias, s.time_sec, '. q_bitand('u.users_opt', 32768) .' as private
 474              FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'ses s
 475              INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users u ON s.user_id=u.id
 476              WHERE time_sec>'. $tm_expire);
 477  }
 478  
 479  /* {{{ proto: mixed fud_fetch_user(mixed arg) }}}
 480   * This function returns profile information about the specified user(s).
 481  stdClass Object
 482  (
 483      [id] => // user's id
 484      [login] => // user's login name
 485      [alias] => // user's alias (html encoded) used for printing
 486      [passwd] => // md5 or sha1 of the password
 487      [salt] => // password salt
 488      [name] => // user's 'real' name
 489      [email] => // user's e-mail address
 490      [location] => // user's geographical location (optional)
 491      [interests] => // user's interests (optional)
 492      [occupation] => // user's occuptation (optional)
 493      [avatar_loc] => // img src of the user's avatar !!could be empty!!
 494      [icq] => // icq uin
 495      [aim] => // aim uin
 496      [yahoo] => // Y! uin
 497      [msnm] => // msn uin
 498      [jabber] => // jabber uin
 499      [google] => // google uin
 500      [skype] => // skype uin
 501      [twitter] => // twitter uin
 502      [affero] => // affero uin
 503      [time_zone] => // user's timezone of choice
 504      [birthday] => // user's b-day MMDDYYYY
 505      [join_date] => // date this user registered on (unix timestamp)
 506      [user_image] => // optional image URL
 507      [theme] => // id of the forum theme used by this user
 508      [posted_msg_count] => // number of messages posted by this user
 509      [last_visit] => // time of last visit (unix timestamp)
 510      [referer_id] => // id of the user who referred this user
 511      [custom_status] => // <br /> separated list of the custom tags this user has
 512      [sig] => signature (html encoded)
 513      [u_last_post_id] => // id last message posted by this user
 514      [home_page] => // homepage URL
 515      [bio] => // HTML safe biography
 516  )
 517  */
 518  function fud_fetch_user($arg)
 519  {
 520      return _fud_simple_fetch_query($arg, 'SELECT * FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE id IN({ARG})');
 521  }
 522  
 523  /* {{{ proto: object fud_fetch_newest_user() }}}
 524   * Return profile information about the forum's newest member.
 525   */
 526  function fud_fetch_newest_user()
 527  {
 528      return fud_fetch_user(q_singleval('SELECT MAX(id) FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users'));
 529  }
 530  
 531  /* {{{ proto: object fud_fetch_random_user() }}}
 532   * Fetch profile information about a random forum member.
 533   */
 534  function fud_fetch_random_user()
 535  {
 536      return _fud_simple_fetch_query(0, 'SELECT * FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users ORDER BY RAND()');
 537  }
 538  
 539  /* {{{ proto: object fud_fetch_top_poster() }}}
 540   * Return profile information about a forum member with a greatest number of posts.
 541   */
 542  function fud_fetch_top_poster()
 543  {
 544      return _fud_simple_fetch_query(0, q_limit('SELECT * FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users ORDER BY posted_msg_count DESC', 1));
 545  }
 546  
 547  /* {{{ proto: user_id fud_add_user($vals, &$err) }}}
 548   * Return the id of a newly created user, on error returns 0 and populates $err with the error message.
 549   * Vals is an array of fields found inside the users table
 550   *    login    - login name for the account, must be unique. **required**
 551   *    passwd    - password for the account (plain-text). **required**
 552   *    email    - e-mail address of the user, must be unique. **required**
 553   *    name    - the user's real first & last name. **required**
 554   *    alias    - must be unique, if not available will be generated based on login.
 555   *     icq    - ICQ IM id (integer)
 556   *    aim    - AIM IM id.
 557   *     yahoo    - Yahoo IM id.
 558   *    msnm    - MSN IM id.
 559   *     jabber    - Jabber IM id.
 560   *    google    - Google IM ID.
 561   *    skype    - Skype handle.
 562   *    twitter    - Twitter handle.
 563   *     affero    - Affero IM id.
 564   *     posts_ppg - Host many messages to display per page, will default to POSTS_PER_PAGE.
 565   *     time_zone - Time zone, will default to server timezone as specified in admin settings.
 566   *     birthday    - Birth day MMDDYYYY format.
 567   *     last_visit -  Unix Timestamp of last visitation date.
 568   *    conf_key - 32 byte confirmation key for unconfirmed accounts.
 569   *    user_image - url to the user's image
 570   *     join_date - Account creation date, will default to current time.
 571   *     location - City/Province/Country
 572   *    theme - the ID of the theme to use, if left blank will pick default theme.
 573   *    occupation - Job
 574   *    interests - Interestes
 575   *    referer_id - User id of the user who referred this user.
 576   *    last_read - Unix timestamp of last "mark all read" will default to current time.
 577   *    sig - Signature
 578   *    home_page - Home Page URL
 579   *    bio - Biography
 580   *    users_opt - Account settings, consult fud_users.sql inside the sql/ directory for details.
 581   *    registration_ip - Registration IP, will default to ::1 (127.0.0.1)
 582   */
 583  function fud_add_user($vals, &$err)
 584  {
 585      // Check for required fields.
 586      foreach (array('login', 'passwd', 'email', 'name') as $v) {
 587          if (empty($vals[$v])) {
 588              $err = 'missing value for a required field '. $v;
 589              return 0;
 590          }
 591      }
 592  
 593      $passwd = $vals['passwd'];
 594  
 595      // Generate unique salt to distrupt rainow tables
 596      if( !array_key_exists('salt', $vals) || empty( $vals['salt'] ) ) {
 597          $vals['salt'] = substr(md5(uniqid(mt_rand(), true)), 0, 9);
 598      }
 599  
 600      $salt = $vals['salt'];
 601  
 602      // Password may already be encrypted (prefixed with 'MD5' or 'SHA1').
 603      if (!strncmp($passwd, 'SHA1:', 5)) {
 604          $vals['passwd'] = substr($passwd, 5);
 605      } else if (!strncmp($vals['passwd'], 'MD5:', 4)) {
 606          $vals['passwd'] = substr($passwd, 4);
 607          $vals['salt']   = '';
 608      } else {
 609          // Probably a plain text password.
 610          $vals['passwd'] = sha1($salt . sha1($passwd));
 611      }
 612  
 613      if (empty($vals['alias'])) {
 614          if (strlen($vals['login']) > $GLOBALS['MAX_LOGIN_SHOW']) {
 615              $vals['alias'] = substr($vals['login'], 0, $GLOBALS['MAX_LOGIN_SHOW']);
 616          } else {
 617              $vals['alias'] = $vals['login'];
 618          }
 619          $vals['alias'] = htmlspecialchars($vals['alias']);
 620      }
 621  
 622      // Some fields must be unique, check them.
 623      foreach (array('login', 'email', 'alias') as $v) {
 624          if (q_singleval('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE '. $v .'='. _esc($vals[$v]))) {
 625              $err = 'value for '. $v .' must be unique, specified value of '. $vals[$v] .' already exists.';
 626              return 0;
 627          }
 628      }
 629  
 630      $o2 =& $GLOBALS['FUD_OPT_2'];
 631      $users_opt = 4|16|32|128|256|512|2048|4096|8192|16384|131072|4194304;
 632      $theme = q_singleval(q_limit('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'themes WHERE theme_opt>=2 AND '. q_bitand('theme_opt', 2) .' > 0', 1));
 633      $time_zone =& $GLOBALS['SERVER_TZ'];
 634      $posts_ppg =& $GLOBALS['POSTS_PER_PAGE'];
 635      if (!($o2 & 4)) {
 636          $users_opt ^= 128;
 637      }
 638      if (!($o2 & 8)) {
 639          $users_opt ^= 256;
 640      }
 641      if ($o2 & 1) {
 642          $o2 ^= 1;
 643      }
 644      $registration_ip = '::1';
 645      $last_visit = $last_read = $join_date = __request_timestamp__;
 646  
 647      // Make sure all fields are set.
 648      foreach( array('login','alias','passwd','name','email','icq','aim','yahoo','msnm','jabber','google','skype','twitter',
 649          'affero','posts_ppg','time_zone','birthday','last_visit','conf_key','user_image',
 650          'join_date','location','theme','occupation','interests','referer_id','last_read',
 651          'sig','home_page','bio','users_opt','registration_ip') as $v) {
 652          if (empty($vals[$v])) {
 653              $vals[$v] = isset($$v) ? $$v : '';
 654          }
 655      }
 656  
 657      return db_qid('INSERT INTO
 658              '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users (
 659                  login,
 660                  alias,
 661                  passwd,
 662                  salt,
 663                  name,
 664                  email,
 665                  icq,
 666                  aim,
 667                  yahoo,
 668                  msnm,
 669                  jabber,
 670                  google,
 671                  skype,
 672                  twitter,
 673                  affero,
 674                  posts_ppg,
 675                  time_zone,
 676                  birthday,
 677                  last_visit,
 678                  conf_key,
 679                  user_image,
 680                  join_date,
 681                  location,
 682                  theme,
 683                  occupation,
 684                  interests,
 685                  referer_id,
 686                  last_read,
 687                  sig,
 688                  home_page,
 689                  bio,
 690                  users_opt,
 691                  registration_ip
 692              ) VALUES (
 693                  '. _esc($vals['login']) .',
 694                  '. _esc($vals['alias']) .',
 695                  \''. $vals['passwd'] .'\',
 696                  \''. $vals['salt'] .'\',
 697                  '. _esc($vals['name']) .',
 698                  '. _esc($vals['email']) .',
 699                  '. (int)$vals['icq'] .',
 700                  '. ssn(urlencode($vals['aim'])) .',
 701                  '. ssn(urlencode($vals['yahoo'])) .',
 702                  '. ssn(urlencode($vals['msnm'])) .',
 703                  '. ssn(htmlspecialchars($vals['jabber'])) .',
 704                  '. ssn(htmlspecialchars($vals['google'])) .',
 705                  '. ssn(htmlspecialchars($vals['skype'])) .',
 706                  '. ssn(htmlspecialchars($vals['twitter'])) .',
 707                  '. ssn(urlencode($vals['affero'])) .',
 708                  '. (int)$vals['posts_ppg'] .',
 709                  '. _esc($vals['time_zone']) .',
 710                  '. ssn($vals['birthday']) .',
 711                  '. (int)$vals['last_visit'] .',
 712                  \''. $vals['conf_key'] .'\',
 713                  '. ssn(htmlspecialchars($vals['user_image'])) .',
 714                  '. $vals['join_date'] .',
 715                  '. ssn($vals['location']) .',
 716                  '. (int)$vals['theme'] .',
 717                  '. ssn($vals['occupation']) .',
 718                  '. ssn($vals['interests']) .',
 719                  '. (int)$vals['referer_id'] .',
 720                  '. (int)$vals['last_read'] .',
 721                  '. ssn($vals['sig']) .',
 722                  '. ssn(htmlspecialchars($vals['home_page'])) .',
 723                  '. ssn($vals['bio']) .',
 724                  '. (int)$vals['users_opt'] .',
 725                  \''. $vals['registration_ip'] .'\'
 726              )
 727          ');
 728  }
 729  
 730  /* {{{ proto: object fud_add_user($vals, &$err) }}}
 731   * Returns 1on success, on error returns 0 and populates $err with the error message.
 732   * Vals is an array of fields found inside the users table (same as for fud_add_user)
 733   * The specified values inside the vals array should ONLY be the ones you wish to modify
 734   */
 735  function fud_update_user($uid, $vals, &$err)
 736  {
 737      $uid = (int) $uid;
 738  
 739      if (!q_singleval('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE id='. $uid)) {
 740          $err = 'Invalid user id';
 741          return 0;
 742      }
 743  
 744      // If user wants to change password generate new salt and hash
 745      if( array_key_exists('passwd', $vals) && !empty($vals['passwd'])) {
 746          $passwd = $vals['passwd'];
 747  
 748          // Generate unique salt to distrupt rainow tables
 749          if( !array_key_exists('salt', $vals) || empty( $vals['salt'] ) ) {
 750              $vals['salt'] = substr(md5(uniqid(mt_rand(), true)), 0, 9);
 751          }
 752  
 753          $salt   = $vals['salt'];
 754  
 755          // Password may already be encrypted (prefixed with 'MD5' or 'SHA1').
 756          if (!strncmp($passwd, 'SHA1:', 5)) {
 757              $vals['passwd'] = substr($passwd, 5);
 758          } else if (!strncmp($vals['passwd'], 'MD5:', 4)) {
 759              $vals['passwd'] = substr($passwd, 4);
 760              $vals['salt']   = '';
 761          } else {
 762              // Probably a plain text password.
 763              $vals['passwd'] = sha1($salt . sha1($passwd));
 764          }
 765      }
 766  
 767      if (empty($vals['alias']) && !empty($vals['login'])) {
 768          if (strlen($vals['login']) > $GLOBALS['MAX_LOGIN_SHOW']) {
 769              $vals['alias'] = substr($vals['login'], 0, $GLOBALS['MAX_LOGIN_SHOW']);
 770          } else {
 771              $vals['alias'] = $vals['login'];
 772          }
 773          $vals['alias'] = htmlspecialchars($vals['alias']);
 774      }
 775  
 776      foreach (array('login','email','alias')    as $v) {
 777          if (empty($vals[$v])) continue;
 778      
 779          if (q_singleval('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE '. $v .'='. _esc($vals[$v]) .' AND id!='. $uid)) {
 780              $err = 'value for '. $v .' must be unique, specified value of '. $vals[$v] .' already exists.';
 781              return 0;
 782          }
 783      }
 784  
 785      $qry = 'UPDATE '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users SET ';
 786      // Apply changes.
 787      foreach( array('login','alias','passwd', 'salt', 'name','email','icq','aim','yahoo','msnm','jabber','google','skype','twitter',
 788          'affero','posts_ppg','time_zone','birthday','last_visit','conf_key','user_image',
 789          'join_date','location','theme','occupation','interests','referer_id','last_read',
 790          'sig','home_page','bio','users_opt','registration_ip') as $v) {
 791          if (isset($vals[$v])) {
 792              $qry .= $v .'='. _esc($vals[$v]) .',';
 793          }
 794      }
 795      uq(rtrim($qry,',') .' WHERE id='. $uid);
 796      return 1;
 797  }
 798  
 799  /* {{{ proto: int message_id fud_new_topic(string subject, string body, int mode *, mixed author, int forum 
 800                          [, string icon [, array attachmet_list ** [, array poll ***]]]) }}}
 801   * Create a new topic based on the provided information. (* denoted variables explained below)
 802   *
 803   * [mode] integer bitmask controlling the following message options, you can 
 804   * OR (|) options if more then one is needed
 805   * 1 - show signature
 806   * 2 - convert emoticons to images
 807   *
 808   * [attachmet_list] a simple array with a list of files to attach to the message
 809   * Ex. array("/vmlinuz", "/home/www/page.html");
 810   *
 811   * [poll] an array containing information about the poll to add
 812   * array(
 813   *    'title' => 'value' // (string containing the poll's title)
 814   *    'options' => array("option1", "option2", "...") // (array of poll's options)
 815   *    'expiry_date' => int // (unix timestamp when to stop allowing votes) **optional**
 816   *    'max_votes' => int // (maximum number of votes to allow) **optional**
 817   * )
 818   */
 819  function fud_new_topic($subject, $body, $mode, $author, $forum, $icon=null, $attach=null, $poll=null, $time=null, $tdescr=null)
 820  {
 821      return _fud_message_post($subject, $body, $mode, $author, $icon, 0, $forum, 0, $attach, $poll, $time, $tdescr);
 822  }
 823  
 824  /* {{{ proto: int message_id fud_new_reply(string subject, string body, int mode *, mixed author, int reply_id 
 825                          [, string icon [, array attachmet_list ** [, array poll ***]]]) }}}
 826   * Post a reply to a message denoted by reply_id parameter. (* denoted variables explained below)
 827   *
 828   * [mode] integer bitmask controlling the following message options, you can 
 829   * OR (|) options if more then one is needed
 830   * 1 - show signature
 831   * 2 - convert emoticons to images
 832   *
 833   * [attachmet_list] a simple array with a list of files to attach to the message
 834   * Ex. array("/vmlinuz", "/home/www/page.html");
 835   *
 836   * [poll] an array containing information about the poll to add
 837   * array(
 838   *    'title' => 'value' // (string containing the poll's title)
 839   *    'options' => array("option1", "option2", "...") // (array of poll's options)
 840   *    'expiry_date' => int // (unix timestamp when to stop allowing votes) **optional**
 841   *    'max_votes' => int // (maximum number of votes to allow) **optional**
 842   * )
 843   */
 844  function fud_new_reply($subject, $body, $mode, $author, $rep_id, $icon=null, $attach=null, $poll=null, $time=null)
 845  {
 846      $forum = q_singleval('SELECT t.forum_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg m INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread t ON t.id=m.thread_id WHERE m.id='. $rep_id);
 847      return _fud_message_post($subject, $body, $mode, $author, $icon, 0, $forum, $rep_id, $attach, $poll, $time);
 848  }
 849  
 850  /* {{{ proto: int message_id fud_update_message(string subject, string body, int mode *, mixed author, int message_id 
 851                          [, string icon [, array attachmet_list ** [, array poll ***]]]) }}}
 852   * Modify an existing message denoted by message_id parameter. (* denoted variables explained below)
 853   *
 854   * [mode] integer bitmask controlling the following message options, you can 
 855   * OR (|) options if more then one is needed
 856   * 1 - show signature
 857   * 2 - convert emoticons to images
 858   *
 859   * [attachmet_list] a simple array with a list of files to attach to the message
 860   * Ex. array("/vmlinuz", "/home/www/page.html");
 861   *
 862   * [poll] an array containing information about the poll to add
 863   * array(
 864   *    'title' => 'value' // (string containing the poll's title)
 865   *    'options' => array("option1", "option2", "...") // (array of poll's options)
 866   *    'expiry_date' => int // (unix timestamp when to stop allowing votes) **optional**
 867   *    'max_votes' => int // (maximum number of votes to allow) **optional**
 868   * )
 869   */
 870  function fud_update_message($subject, $body, $mode, $author, $mid, $icon=null, $attach=null, $poll=null)
 871  {
 872      $forum = q_singleval('SELECT t.forum_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg m INNER JOIN '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread t ON t.id=m.thread_id WHERE m.id='. $mid);
 873      return _fud_message_post($subject, $body, $mode, $author, $icon, $mid, $forum, 0, $attach, $poll);
 874  }
 875  
 876  /* {{{ proto: void fud_fetch_user(mixed arg) }}}
 877   * This function deletes message(s) specified by arg.
 878   */
 879  function fud_delete_msg($arg)
 880  {
 881      if (!$arg) {
 882          return;
 883      }
 884  
 885      if (is_numeric($arg)) {
 886          $arg = array($arg);
 887      }
 888  
 889      fud_use('imsg_edt.inc');
 890      fud_use('ipoll.inc');
 891      fud_use('th_adm.inc');
 892  
 893      $bak = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL;
 894      define('no_session', 1);
 895      unset($_SERVER['REMOTE_ADDR']);
 896  
 897      fud_use('users.inc');
 898  
 899      foreach ($arg as $mid) {
 900          $m = new fud_msg_edit;
 901          $m->delete(true, $mid);
 902      }
 903  
 904      $_SERVER['REMOTE_ADDR'] = $bak;
 905  }
 906  
 907  /* {{{ proto: void fud_delete_topic(mixed arg) }}}
 908   * This function deletes topic(s) specified by arg.
 909   */
 910  function fud_delete_topic($arg)
 911  {
 912      $ent = _fud_simple_fetch_query($arg, 'SELECT root_msg_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'thread WHERE id IN({ARG})');
 913      if (!$ent) {
 914          return;
 915      } else if (is_object($ent)) {
 916          fud_delete_msg($ent->root_msg_id);
 917      } else if (is_array($ent)) {
 918          $del = array();
 919          foreach ($ent as $o) {
 920              $del[] = $o->root_msg_id;
 921          }
 922          fud_delete_msg($del);
 923      }
 924  }
 925  
 926  /* {{{ proto: void fud_delete_poll(mixed arg) }}}
 927   * This function deletes poll(s) specified by arg.
 928   */
 929  function fud_delete_poll($arg)
 930  {
 931      $ent = _fud_simple_fetch_query($arg, 'SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'poll WHERE id IN({ARG})');
 932  
 933      if (!$ent) {
 934          return;
 935      }
 936  
 937      fud_use('ipoll.inc');    
 938  
 939      foreach ((array)$ent as $p) {
 940          poll_delete($p->id);
 941      }
 942  }
 943  
 944  /* {{{ proto: void fud_delete_attachment(mixed arg) }}}
 945   * This function deletes attachment(s) specified by arg.
 946   */
 947  function fud_delete_attachment($arg)
 948  {
 949      $data = _fud_simple_fetch_query($arg, 'SELECT id, message_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'attach WHERE id IN({ARG})');
 950  
 951      if (!$data) {
 952          return;
 953      }
 954  
 955      fud_use('attach.inc');
 956  
 957      foreach ((array)$data as $at) {
 958          q('DELETE FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'attach WHERE id='. $at->id);
 959          $atl = attach_rebuild_cache($at->message_id);
 960          q('UPDATE '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg SET attach_cnt=attach_cnt-1, attach_cache='. _esc(@serialize($atl)) .' WHERE id='. $at->message_id);
 961      }
 962  }
 963  
 964  /* {{{ proto: void fud_delete_user(mixed arg) }}}
 965   * This function deletes users(s) specified by arg.
 966   */
 967  function fud_delete_user($arg)
 968  {
 969      $data = _fud_simple_fetch_query($arg, 'SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE id IN({ARG})');
 970  
 971      if (!$data) {
 972          return;
 973      } else if (!is_array($data)) {
 974          $data = array($data);
 975      }
 976  
 977      fud_use('users_adm.inc', true);
 978  
 979      foreach ($data as $v) {
 980          usr_delete($v->id);
 981      }
 982  }
 983  
 984  /* API FUNCTIONS END HERE */
 985  /* INTERNAL FUNCTIONS, DO NOT TOUCH */
 986  
 987  function _fud_msg_multi($arg, $query)
 988  {
 989      $arg = is_numeric($arg) ? array($arg) : (int)$arg;
 990      $ids = array();
 991      $r = uq(str_replace('{ARG}', implode(',', $arg), $query));
 992      while ($row = db_rowarr($r)) {
 993          $ids[] = $row[0];
 994      }
 995      if (!$ids) {
 996          return FALSE;
 997      }
 998  
 999      return fud_fetch_msg($ids);
1000  }
1001  
1002  function _fud_simple_fetch_query($arg, $query, $check_count = TRUE)
1003  {
1004      if ($arg) {    
1005          $arg = is_numeric($arg) ? array($arg) : $arg;
1006      } else {
1007          $arg = array();
1008      }
1009      $result = array();
1010          
1011      $r = uq(str_replace('{ARG}', implode(',', $arg), $query));
1012      while ($row = db_rowobj($r)) {
1013          $result[] = $row;    
1014      }
1015      unset($r);
1016  
1017      if( $check_count ) {
1018          if ($arg && count($result) != count($arg)) {      
1019                  return FALSE;
1020          } 
1021      }
1022      
1023      if (count($result) == 1) {
1024          return array_pop($result);
1025      } else {
1026          return $result;
1027      }
1028  }
1029  
1030  function _fud_decode_forum($data)
1031  {
1032      if (is_array($data)) {
1033          foreach ($data as $k => $v) {
1034              unset($data[$k]->forum_opt, $data[$k]->message_threshold, $data[$k]->view_order);
1035              $data[$k]->moderators = @unserialize($data[$k]->moderators);
1036          }
1037      } else {
1038          unset($data->forum_opt, $data->message_threshold, $data->view_order);
1039          $data->moderators = @unserialize($data->moderators);
1040      }
1041  
1042      return $data;
1043  }
1044  
1045  function _fud_add_poll($poll, $forum_id, $forum_opt, $mode, $uid)
1046  {    
1047      if (empty($poll['title']) || empty($poll['options']) || !is_array($poll['options'])) {
1048          return;
1049      }
1050  
1051      $exp_date = !empty($poll['expiry_date']) ? (int) $poll['expiry_date'] : 0;
1052      $max_v = !empty($poll['max_votes']) ? (int) $poll['max_votes'] : 0;
1053  
1054      $pl_id =  poll_add($poll['title'], $max_v, $exp_date, $uid);
1055  
1056      foreach ($poll['options'] as $opt) {
1057          if ($forum_opt & 16) {
1058              $opt = tags_to_html($opt, 1);
1059          } else if ($forum_opt & 8) {
1060              $opt = nl2br(htmlspecialchars($opt));
1061          }
1062          if ($mode & 2) {
1063              $opt = smiley_to_post($opt);
1064          }    
1065  
1066          poll_opt_add($opt, $pl_id);
1067      }
1068  
1069      return $pl_id;
1070  }
1071  
1072  function _fud_message_post($subject, $body, $mode, $author, $icon, $id, $forum, $rep_id=0, $attach=null, $poll=null, $time=null, $tdescr=null)
1073  {
1074      fud_use('imsg_edt.inc');
1075      fud_use('post_proc.inc');
1076      fud_use('smiley.inc');
1077      fud_use('th_adm.inc');
1078      fud_use('iemail.inc');
1079      fud_use('isearch.inc');
1080      fud_use('replace.inc');
1081      fud_use('rev_fmt.inc');
1082      fud_use('wordwrap.inc');
1083      fud_use('ipoll.inc');
1084      fud_use('fileio.inc');
1085      fud_use('th.inc');
1086  
1087      $bak = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL;
1088      define('no_session', 1);
1089      unset($_SERVER['REMOTE_ADDR']);
1090  
1091      fud_use('users.inc');
1092      
1093      // Do not resolve host.
1094      if ($GLOBALS['FUD_OPT_1'] & 268435456) {
1095          $GLOBALS['FUD_OPT_1'] ^= 268435456;
1096      }
1097  
1098      $GLOBALS['good_locale'] = setlocale(LC_ALL, q_singleval(q_limit('SELECT locale FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'themes WHERE theme_opt='. (1|2), 1)));
1099      list($forum_opt, $message_threshold) = db_saq('SELECT forum_opt, message_threshold FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'forum WHERE id='. $forum);
1100      if ($rep_id) {
1101          $th_id = q_singleval('SELECT thread_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'msg WHERE id='. $rep_id);
1102      }
1103  
1104      $msg = new fud_msg_edit();
1105      $msg->poster_id = is_numeric($author) ? (int) $author : (int) q_singleval('SELECT id FROM '. $GLOBALS['DBHOST_TBL_PREFIX'] .'users WHERE login='. _esc($author));
1106      $msg->subject = $subject;
1107      $msg->body = apply_custom_replace($body);
1108      $msg->icon = $icon;
1109      $msg->thread_id = $id ? q_singleval('SELECT thread_id FROM '. $GLOBALS['DBHOST_TBL_PREFIX']. 'msg WHERE id='. $id) : 0;
1110      $msg->msg_opt = $mode;
1111      if ($time) {
1112          $msg->post_stamp = $time;
1113      } else {
1114          $msg->post_stamp = time();
1115      }
1116  
1117  
1118      if ($forum_opt & 16) {
1119          $msg->body = tags_to_html($msg->body, 1);
1120      } else if ($forum_opt & 8) {
1121          $msg->body = nl2br(char_fix(htmlspecialchars($msg->body)));
1122      }
1123  
1124      if ($mode & 2) {
1125          $msg->body = smiley_to_post($msg->body);
1126      }
1127  
1128      fud_wordwrap($msg->body);
1129      $msg->subject = char_fix(htmlspecialchars(apply_custom_replace($msg->subject)));
1130  
1131      if ($attach && is_array($attach)) {
1132          fud_use('attach.inc');
1133  
1134          foreach ($attach as $file) {
1135              $file = realpath($file);
1136  
1137              if (!@file_exists($file)) {
1138                  continue;
1139              }            
1140  
1141              $at['name'] = basename($file);
1142              $at['size'] = filesize($file);
1143              $at['tmp_name'] = tempnam($GLOBALS['TMP'], 'fuda_');
1144              copy($file, $at['tmp_name']);
1145              $val = attach_add($at, $msg->poster_id, 0, 1);
1146              $attach_list[$val] = $val;
1147          }
1148  
1149          $msg->attach_cnt = isset($attach_list) ? count($attach_list) : 0;
1150      }
1151  
1152      if ($poll && is_array($poll)) {
1153          $msg->poll_id = _fud_add_poll($poll, $forum, $forum_opt, $mode, $msg->poster_id);
1154      }
1155  
1156      if (!$rep_id && !$id) {
1157          $create_thread = 1;
1158          $msg->add($forum, $message_threshold, $forum_opt, 64|4096, 0, $tdescr);
1159      } else if ($rep_id && !$id) {
1160          $msg->thread_id = $th_id;
1161          $msg->add_reply($rep_id, $th_id, 64|4096, false);
1162      } else if ($id) {
1163          $msg->id = $id;
1164          $msg->sync($msg->poster_id, $forum, $message_threshold, 64|4096, $tdescr);
1165      }
1166  
1167      if (isset($attach_list)) {
1168          attach_finalize($attach_list, $msg->id);
1169      }
1170  
1171      $msg->approve($msg->id);
1172  
1173      $_SERVER['REMOTE_ADDR'] = $bak;
1174  
1175      return $msg->id;
1176  }
1177  
1178  fud_use('err.inc');
1179  fud_use('db.inc');
1180  ?>

title

Description

title

Description

title

Description

title

title

Body