Logo Search packages:      
Sourcecode: dacode version File versions  Download package

board.php3

<?php
/**
 * This class is to make a board like bbs ones
 *
 * daCode http://www.dacode.org/
 * src/phplib/board.php3
 * $Id: board.php3,v 1.75.2.18 2002/09/14 11:24:49 ruffy Exp $
 *
 * Depends: Config Db Utils Html
 *
 *@author Fabien Penso <penso@linuxfr.org>
 */
00013 class Board {
      /**
       * Utils instance
       *@var object Utils
       */
      var $utils;
      
      /**
       * Db abstraction layer
       *@var object DB
       */
      var $db;

      /**
       * HTML subclass instance
       *@var object HTML
       */
      var $html;

      /**
       * Message instance
       *@var object Message
       */
      var $message;

      /**
       * HTTP_REFERER, to avoid using global vars
       *@var array
       */
      var $HTTP_REFERER;

      /**
       * Class cosntructor
       * Loads Db, Session, Cache, Utils, HTML
       */
      Function Board() {
            global $HTTP_SERVER_VARS;

            $this->db = LoadClass('Db');
            $this->session = LoadClass('Session');
            $this->cache = LoadClass('Cache');
            $this->utils = LoadClass('Utils');
            $this->html  = LoadClass('Html');
            $this->message = LoadClass('Message');

            $this->HTTP_REFERER = '';

            if (isset($HTTP_SERVER_VARS['HTTP_REFERER'])) {
                  $this->HTTP_REFERER = $HTTP_SERVER_VARS['HTTP_REFERER'];
            }
      }

      /**
       * This function add a new message to the board
       *Does not return
       *Calls header to redirect to HTTP_REFERER, the calls exit.
       *@access public
       *@param string the message to add
       *@param integer 1 for normal people, 2 for moderators
       *@global array $HTTP_SERVER_VARS environement variables hash.
       */
      Function add($message,$section=1) {
            global $HTTP_SERVER_VARS;
            global $config;
            
            if (!ereg("^".$config->basehref,$this->HTTP_REFERER) &&
                        ($this->session->param & pow(2,3) == 0)) {
                  echo lecho("Might got fucked! :-)<br />\nLook at ").
                        "<a href=\"http://lwn.net/2000/features/Redirect.phtml\">".
                        "http://lwn.net/2000/features/Redirect.phtml</a>".
                        lecho(" to see what happened!<br />\nThen come back here. :-)");
                  exit;
            }

            // Thanks alain@antinea.com
            $maxsize = 30;
            $ar_message = explode (" ", $message);
            while (list($key, $val) = each($ar_message)) {
                  if (strlen($val) > $maxsize &&
                  !ereg("^(https?|ftp)://[^\"><\) ]+", $val)) {
                        echo lecho("Sorry but your message contains too long words");
                        exit;
                  }
            }

            if ($section == 2 && !$this->session->is_moderator) {
                  lecho("you bad boy...");
            }

            if (empty($message)) {
                  if (!empty($this->HTTP_REFERER)) {
                        header ("Location: ".$this->HTTP_REFERER);
                        exit;
                  } else {
                        header ("Location: ".$config->basehref.$config->newsfile);
                        exit;
                  }
            }

            if (strlen($message) > 4 && strlen($message) <= 255) {
                  $sqlc_q = "SELECT ip from ".$config->tables['board']." WHERE section='".
                              addslashes($section)."' ORDER BY id DESC ".$this->db->compat_limit(1);
                  $ret = $this->db->query($sqlc_q);
                  if (!$ret) {
                        echo lecho("SQL Failed: "). $this->db->error();
                        echo lecho("SQL command was: ").$sqlc_q."<br />\n";
                        exit;
                  }
                  $row = $this->db->fetch_array();
                  // Section number 2 is used for admin. So they can post twice.
                  if ($row['ip'] == $this->utils->ip() && $section != 2) {
                        echo lecho("Sorry but you can't add two messages in a row");
                        exit;
                  }
                  $this->db->free();

                  if ($this->session->checked &&
                        !($this->session->param & pow(2,6))) {
                        $userid_tmp = $this->session->user_id;
                  } else {
                        $userid_tmp = 1;
                  }

                  if(!empty($this->HTTP_REFERER)) {
                        $tempo_url = $this->HTTP_REFERER;
                  } else {
                        $tempo_url = $config->basehref.$config->newsfile;
                  };

                  if ($this->privateMessage($message, $tempo_url)) {
                        header("Cache-Control: no-cache, must-revalidate");
                        header("Pragma: no-cache");
                        if (!empty($this->HTTP_REFERER)) {
                              header ("Location: ".$this->HTTP_REFERER);
                              exit;
                        } else {
                              header ("Location: ".$config->basehref.$config->newsfile);
                              exit;
                        }
                  }

                  $sqlc_q = "INSERT INTO ".$config->tables['board'].
                        " (message,ip,info,section,user_id) VALUES ('".
                        addslashes($this->utils->htmlspecial_board($message))."','".
                        addslashes($this->utils->ip())."','".
                        addslashes(substr( $HTTP_SERVER_VARS['HTTP_USER_AGENT'], 0, 60))."','".
                        addslashes($section)."','".
                        addslashes($userid_tmp) . "')";

                  $ret = $this->db->query($sqlc_q);
                  if (!$ret) {
                        echo lecho("SQL Failed: "). $this->db->error();
                        echo lecho("SQL command was: ").$sqlc_q."<br />\n";
                        exit;
                  }

                  if (!empty($config->htmldir)) {
                        //   PHP3 files call $board->print_messages()
                        //   so only .html files have to be removed.
                        $this->cache->delete_htmlfiles('section',0,0,0,'\.html');
                        $this->cache->delete_htmlfiles('topic',0,0,0,'\.html');
                        $this->cache->delete_htmlfiles('.',1,0,0,'^index.*\.html','^[0-9]+$');
                  }
                  if (!empty($config->cachedir)) {
                        $this->cache->delete_boxfiles('board',0,0,0,"^#".$section.'\.');
                        $this->cache->delete_boxfiles('board_remote',0,0,0,"^#".$section.'\.');
                  }

                  $this->gen_xml();
            } else {
                  echo lecho("Messages should have between 5 and 255 characters.");
                  exit;
            }

            header("Cache-Control: no-cache, must-revalidate");
            header("Pragma: no-cache");
            if (!empty($this->HTTP_REFERER)) {
                  header ("Location: ".$this->HTTP_REFERER);
                  exit;
            } else {
                  header ("Location: ".$config->basehref.$config->newsfile);
                  exit;
            }
      }

      /**
       * This will print information about a message
       * Calls exit on SQL error.
       *@access public
       *@param integer the id of the message.
       *@return string infos or error message
       */
      Function print_info($id) {
            global $config;

            if (!ereg("^[0-9]+$",$id)) {
                  return lecho("Id looks wrong. Have id cookie?");
            }
            $sqlc_q = "SELECT timestamp,info from ".$config->tables['board'].
                  " WHERE id='".addslashes($id)."'";
            $ret = $this->db->query($sqlc_q);
            if (!$ret) {
                  echo lecho("SQL Failed: ").$this->db->error();
                  exit;
            }

            $tmp = "";
            while($row = $this->db->fetch_array()) {
                  $tmp .= $this->utils->stamp2date($row['timestamp'],"long");
                  $tmp .= "<br />".htmlentities($row['info']);
            }
            $this->db->free();
            return $tmp;
      }

      /**
       * Print a number of messages to be used by external programs 
       *@param integer number of messages to print
       *@param integer section 1 for normal people, 2 for moderator-only board
       *@access private
       *@return string error message or XML-formatted list of messages
       */
      Function print_raw($nb=10,$section=1) {
            global $config;

            if (!is_integer($nb) || $nb<1 || $nb>5000) {
                  $nb=10;
            }

            $cachetmp = array ($section,$nb);

            $fcontents = $this->cache->check_box("20","board_remote",$cachetmp);
            if (!empty($fcontents)) {
                  return $fcontents;
            }

            $sqlc_q = 'SELECT '.
                  $config->tables['board'].'.message,'.
                  $config->tables['board'].'.timestamp,'.
                  $config->tables['board'].'.id,'.
                  $config->tables['board'].'.info,'.
                  $config->tables['board'].'.user_id,'.
                  $config->tables['users'].'.login,'.
                  $config->tables['users'].'.param FROM '.
                  $config->tables['board'].','.
                  $config->tables['users'].
                  " WHERE section='".addslashes($section)."' AND ".
                  $config->tables['board'].'.user_id='.
                  $config->tables['users'].'.id ORDER BY '.
                  $config->tables['board'].'.id '.
                  'DESC '.$this->db->compat_limit($nb);

            $ret = $this->db->query($sqlc_q);

            if(!$ret) {
                  $tmp = "%%\nERR\n%%";
                  $tmp .= lecho("SQL Failed: "). $this->db->error();
                  $tmp .=  lecho("SQL command was: ").$sql_q."\n";
                  return $tmp;
                  exit -1;//Really useful???
            }

            if ($this->db->num_rows() < $nb) {
                  $nb = $this->db->num_rows();
            }

            $tmp = '<?xml version="1.0" encoding="'.$config->encodingcharset.'" ?>'.
                  "\n<!DOCTYPE tp SYSTEM \"tp-0.1.dtd\">\n";
            $tmp .= '<board site="'.$config->baseurl."\">\n";
            $i = 1;

            while ($row = $this->db->fetch_array()) {
                  $tmp .= "\t<post time=\"".$row["timestamp"].'" id="'.$row["id"]."\">\n";
                  $tmp .= "\t\t<info>".htmlentities($row["info"])."</info>\n";
                  $tmp .= "\t\t<message>".
                        $this->parseUrls($row["message"]).
                        "</message>\n";
                  $tmp .= "\t\t<login>".htmlentities($row['login'])."</login>\n";
                  $tmp .= "\t</post>\n";
                  $i++;
            }
            $tmp .= '</board>';

            $this->db->free();
            $this->cache->write_box('board_remote',$cachetmp,$tmp);
            return $tmp;

      }

      /**
       * Print a number of messages 
       * Calls echo on SQL failure
       *@access public
       *@param integer number of messages to print
       *@param integer section 1 for normal people, 2 for moderator-only board
       *@param integer number of messages to print
       *@return mixed string board sidebox or integer -1 on SQL failure
       */
      Function print_message($nb=10,$section=1,$inputsize=25) {
            global $config;

            if (!is_integer($nb) || $nb<1 || $nb>5000) {
                  $nb = 10; // sqlchecked: it must be in [1..5000];
            }

            $cachetmp = array ($section,$nb,$config->theme,$config->depth);

            $fcontents = $this->cache->check_box('3600','board',$cachetmp);
            if (!empty($fcontents)) {
                  return $fcontents;
            }

            $sqlc_q = 'SELECT '.
                  $config->tables['board'].'.message,'.
                  $config->tables['board'].'.timestamp,'.
                  $config->tables['board'].'.id,'.
                  $config->tables['board'].'.user_id,'.
                  $config->tables['users'].'.login,'.
                  $config->tables['users'].'.param FROM '.
                  $config->tables['board'].','.
                  $config->tables['users'].
                  " WHERE section='".addslashes($section)."' AND ".
                  $config->tables['board'].'.user_id='.
                  $config->tables['users'].'.id ORDER BY '.
                  $config->tables['board'].'.id '.
                  'DESC '.$this->db->compat_limit($nb);

            $ret = $this->db->query($sqlc_q);
            if (!$ret) {
                  echo lecho("SQL Failed: "). $this->db->error();
                  echo lecho("SQL command was: ").$sqlc_q."<br />\n";
                  return -1;
            }

            if ($this->db->num_rows() < $nb) {
                  $nb = $this->db->num_rows();
            }
            $i=$nb;

            while ($row = $this->db->fetch_array()) {
                  $message[$i] = $row["message"];
                  $timestamp[$i] = $row["timestamp"];
                  $login_tmp[$i] = $row['login'];
                  $userid_tmp[$i] = $row['user_id'];
                  $id[$i] = $row["id"];
                  $i--;
            }
            $this->db->free();

            $oldt = "";
            $tmp = "";
            for ($i=1;$i<=$nb;$i++) {
                  $t = substr($timestamp[$i],8,4);
                  if (isset($timestamp[($i+1)])) {
                        $t2 = substr($timestamp[($i+1)],8,4);
                  } else {
                        $t2 = $t;
                  }

                  $tmp .= '&nbsp;<a href="'.$config->basehref.
                              $config->boardinfofile.'?id='.$id[$i].'">';

                  if ($t == $t2 || $oldt == $t) {
                        $tmp .= $this->utils->stamp2time($timestamp[$i],'long');
                  } else {
                        $tmp .= $this->utils->stamp2time($timestamp[$i],'short');
                  }
                  $oldt = $t;

                  $tmp .= '</a> ';

                  if ($userid_tmp[$i] != '1') {
                        $tmp .= "&lt;<a href=\"".$config->basehref."users/?a=vu&amp;user_id=".
                              htmlentities($userid_tmp[$i]).'">'.htmlentities($login_tmp[$i]).'</a>&gt; ';
                  } else {
                        $tmp .= '&lt;'.lecho("Anonymous").'&gt; ';
                  }

                  $tmp .= $this->parseUrls($message[$i])."<br />\n";
            }

            /* We make a link so users can add entries */
            $tmp .= '<div align="center"><form action="'.
                  $config->basehref.$config->boardaddfile.'" method="post">'."\n";
            $tmp .= '<input name="message" type="text" size="'.
                  $inputsize.'" maxlength="255" value="" />'."\n";
            $tmp .= '<input name="board_section" type="hidden" value="'.
                  htmlentities($section).'" />'."\n";
            $tmp .= "</form></div>\n";

            $out = $this->html->sidebox('<a href="'.$config->basehref.
                  $config->boardindexfile.'" class="boxheader">'.lecho("Board").
                  "</a>", $tmp, 'board');

            $this->cache->write_box('board',$cachetmp,$out);
            return $out;
      }

      /**
       * Generate the XML backend for the board
       *@access private
       */
      Function gen_xml() {
            global $config;

            if (file_exists("./".$config->boardfile)) {
                  @unlink("./".$config->boardfile);
            }
            $tmp = $this->print_raw(100);

            if (isset($config->boardfile) && !empty($config->boardfile)) {
                  $this->utils->write_file("./".$config->boardfile, $tmp);
            }
      }

      /**
       * privateMessage: parses input and checks if it begins with "/msg"
       *
       *@access private
       * @param string $message The posted message
       * @param string $url The url where the user will be redirected
       * @return boolean true if message is private false if not
       */
       Function privateMessage($message,$url) {
            global $config;

            if (!$this->session->checked) {
                  return 0;
            }
            
            if (preg_match('/^\/msg ([^\s]*) (.*)/i', $message, $matches)) {
                  if ($matches[1] == lecho("Anonymous")) {
                        return 0;
                  }
                  
                  $post['subject'] = lecho("Message from")." ".$this->session->login;
                  $post['body'] = $matches[2];
                  $post['url'] = $url;

                  $sqlc_q = "SELECT id FROM ".$config->tables['users'].
                        " WHERE login='".addslashes($matches[1])."'";

                  $ret = $this->db->query($sqlc_q);

                  if (!$ret) {
                        $this->utils->debug("Board:".__LINE__." privateMessage: ". 
                              lecho("SQL Failed: ").$this->db->error()." SQL: ".
                              $sqlc_q."\n");
                        exit;
                  }

                  $res = $this->db->fetch_array();

                  $post['user_id_dest'] = $res['id'];
                  
                  $this->db->free();

                  $this->message->add_new_message($post);
                  
                  return 1;
            }
            
            return 0;
       }

      /**
       * parseUrl: parses input and changes urls to HTML links
       *@access private
       * @param string $message string to be parsed
       * @return string parsed string to be printed
       */

       Function parseUrls($message) {
            global $config;

            // PHP3 doesn't like /e, even if the doc says it.
            // Cf pcrelib/pcre.c in PHP3 source code
            $version=explode(".",phpversion());
            if ($version[0] > '3') {
                  $message = preg_replace('/\[login:\s?([^\[\]]*)\]/ie',
                        '$this->parseUrlLogin(\'\\1\')',
                        $message);

                  // phpWiki url code
                  if ($config->wikiUrl != "") {
                        // php3 doesn't like /ie apparently
                        $message = preg_replace('/\[([^\]\[]*)\]/ie',
                              "'<!-- WIKIURL --><a href=\"$config->wikiUrl'.urlencode('\\1').'\">[\\1]</a><!-- /WIKIURL -->'",
                              $message);
                  }
            }

            // "normal" url code
            $message = ereg_replace('((ftp|https?)://[^">< ]+)',
                        "<!-- REALURL --><a href=\"\\0\"><b>[url]</b></a><!-- /REALURL -->",
                        $message);

            // clean up dirty tricks to bypass eachother
            if ($config->wikiUrl != "") {
                  $message = str_replace('\"', '"', $message);
            }
            $message = preg_replace('/ht-tp/i', 'http', $message);
            $message = str_replace('<!-- USERHOMEPAGE -->', '<!-- UHP -->[', $message);
            $message = str_replace('<!-- /USERHOMEPAGE -->', ']<!-- /UHP -->', $message);
            
            return $message;
      }

      /**
       * parseUrlLogin: parses a special type of links
       *@access private
       * @param string $message user name extracted by preg_replace
       * @return string the HTML url form
       */
      Function parseUrlLogin($message) {
            global $config;

            $text = $message;
            
            if(empty($message)) {
                  return $text;
            };

            $tmp = $this->db->clone();
            
            $sqlc_q = 'SELECT id FROM '.$config->tables['users'].
                  " WHERE login LIKE '".addslashes($message)."'";

            $ret = $tmp->query($sqlc_q);

            if (!$ret) {
                  $this->utils->debug("Board:".__LINE__." parseUrlLogin:      ".
                        lecho("SQL Failed: ").$tmp->error()." SQL: ".
                        $sqlc_q."\n");
                  exit;
            }

            if ($tmp->num_rows() == 1) {
                  $res = $tmp->fetch_array();

                  $uid = $res['id'];

                  $baseurl = str_replace("http", "ht-tp", $config->baseurl);

                  $text = '<a href="'.$baseurl.
                        'users/?a=vu&amp;user_id='.$uid.'"><!-- USERHOMEPAGE -->login: '.
                        $message.'<!-- /USERHOMEPAGE --></a>';
            } else {
                  // Either there's a problem, or the specified login
                  // doesn't exist ..
                  $text = $message;
            }

            $tmp->free();

            return $text;
      }

}

?>

Generated by  Doxygen 1.6.0   Back to index