<?php
/* daCode http://www.dacode.org/
 * src/phplib/comments.php3
 * $Id: comments.php3,v 1.165 2001/07/21 22:04:45 penso Exp $
 * Fabien Penso <penso@linuxfr.org>
 *
 * This Class will handle comments
 *
 * Depends: Config Db Utils Session Html News
*/

Class Comments {
	var $com_urls;
	var $html;
	var $utils;
	var $session;
	var $comments;
	var $HTTP_REFERER;
	var $news;
	var $news_id;

	Function Comments($w="") {
		global $news_id,$HTTP_REFERER;
		$this->db = LoadClass('Db');
		$this->session = LoadClass('Session');
		$this->cache = LoadClass('Cache');
		$this->utils = LoadClass('Utils');
		$this->html  = LoadClass('Html');
		$this->news  = LoadClass('News');
		$this->user  = LoadClass('User');

		$this->HTTP_REFERER = $HTTP_REFERER;
		$this->comments = array();
		if (empty($w)) {
			$this->init($news_id);
		}
		$this->news_id = $news_id;
	}

	/*
	 * Will be used to preload few things ...
	 */
	Function init($news_id="",$com_id="") {
		global $config;

		if (empty($news_id)) {
			return 0;
		}

		/* We can choose what comments are preloaded with the parameter $com_id.
		 * - If you want all the comments, you should set it empty:
		 *       $com_id=""
		 * - If you want only one Id, simply set it:
		 *       $com_id=6
		 * - If you know which comments you want to load, use en array:
		 *       $com_id=array(3,5,12,9)
		 */
		if (empty($com_id)) {
			$sqlc_n = "";   // all of them
		} elseif (is_array($com_id)) {
			$sqlc_n = "AND ".$config->tables['comments'].".id IN ('".
				join("','",$com_id)."')";
		} else {
			$sqlc_n = "AND ".$config->tables['comments'].".id='$com_id'";
			// only this one
		}


		/* We Build the SQL Command */
		$sqlc_q = "SELECT ".$config->tables['comments'].".news_id,".
			$config->tables['comments'].".id,".
			$config->tables['comments'].".com_parent,".
			$config->tables['comments'].".subject,".
			$config->tables['comments'].".body,".
			$config->tables['comments'].".timestamp,".
			$config->tables['comments'].".ip,".
			$config->tables['users'].".login,".
			$config->tables['users'].".lname,".
			$config->tables['users'].".fname,".
			$config->tables['users'].".fake_email,".
			$config->tables['users'].".email,".
			$config->tables['users'].".homesite,".
			$config->tables['users'].".param,".
			$config->tables['comments_scored'].".score,".
			$config->tables['comments'].".user_id,".
			$config->tables['sig'].".sig,".
			$config->tables['comments_scored'].".info ".
			"FROM ".
			$config->tables['comments'].",".
			$config->tables['comments_scored'].",".
			$config->tables['users'].",".
			$config->tables['sig'].
			" WHERE ".$config->tables['comments'].".news_id='".
			addslashes($news_id)."' AND ".
			$config->tables['comments'].".user_id=".
			$config->tables['users'].".id AND ".
			$config->tables['sig'].".id =".
			$config->tables['comments'].".sig_id AND ".
			$config->tables['comments'].".id =".
			$config->tables['comments_scored'].".comments_id ".
			$sqlc_n.
			" ORDER BY ".$config->tables['comments'].".timestamp";
		// Built ! Pffiou :)

		$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 ;
		}

		$i=0;
		while($row_tmp = $this->db->fetch_array()) {
			$this->comments[$i]['news_id']      = $row_tmp[0];
			$this->comments[$i]['id']           = $row_tmp[1];
			$this->comments[$i]['com_parent']   = $row_tmp[2];
			$this->comments[$i]['subject']      = $row_tmp[3];
			$this->comments[$i]['body']         = $row_tmp[4];
			$this->comments[$i]['timestamp']    = $row_tmp[5];
			$this->comments[$i]['ip']           = $row_tmp[6];
			$this->comments[$i]['login']        = $row_tmp[7];
			$this->comments[$i]['lname']        = $row_tmp[8];
			$this->comments[$i]['fname']        = $row_tmp[9];
			$this->comments[$i]['fake_email']   = $row_tmp[10];
			$this->comments[$i]['email']        = $row_tmp[11];
			$this->comments[$i]['homesite']     = $row_tmp[12];
			$this->comments[$i]['param']        = $row_tmp[13];
			$this->comments[$i]['score']        = $row_tmp[14];
			$this->comments[$i]['user_id']      = $row_tmp[15];
			$this->comments[$i]['sig']          = $row_tmp[16];
			$this->comments[$i]['score_info']   = $row_tmp[17];
			$i++;
		}

		$this->db->free();
	}

	Function cmp ($a, $b) {
		// return strcmp($a['timestamp'],$b['timestamp']);
		return 1;
	}

	/* New function which will print comment, have to be used with init()*/
	Function com_print2 ($comm_id=0,$com_parent=0,$score="0",$type="thread") {
		static $ulnb=0;
		$ulmax=9;
		$out = "";
		$tmp = "";

		if (!$com_parent) {
			$out .= $this->html->commentbanner($score);
		}

		// usort($this->comments, "\$this->cmp");

		/* If we have no parent comment */
		if ($com_parent==0) {

			if (empty($comm_id)) {
				reset($this->comments);

				while (list (, $val) = each ($this->comments)) {
					$tmp="";
					if ($val['com_parent'] != 0) {
						continue;
					}

					if ($val['score'] >= $score && $val['com_parent'] == 0) {
						switch($type) {

						case "thread":
							$tmp .= $this->ac($val,$val['news_id']);
							$tmp .= $this->com_print2(0,$val['id'],$score);
							break;

						default:
							break;
						}
					} elseif ($val['score'] < $score && $val['com_parent'] == 0) {
						$tmp .= $this->ac($val,$val['news_id'],"scoredown");
						$tmp .= $this->com_print2(0,$val['id'],$score);
					} else {
						// $tmp .= "COMPARENT: ".$val['com_parent']."<br>";
						// $tmp .= "Score: ".$val['score']."<br>";
						// $tmp .= $this->com_print2(0,$val['id'],$score);
					}

					if (!empty($tmp)) {
						$out .= $this->html->simplebox($tmp);
					}

				}


			} else {
				reset($this->comments);
				while (list (, $val) = each ($this->comments)) {
					if ($val['id'] == $comm_id) {
						$tmp .= $this->ac($val,$val['news_id']);
					}
				}
			}

		} else {
			//static $ok=0;
			$ulnb++;
			if ($ulnb < $ulmax) {
				$tmp .= "<ul>\n";
			}
			$tmpcomments = $this->comments;
			reset($tmpcomments);
			$ok=0;
			while (list (, $val) = each ($tmpcomments)) {
				if ($val['com_parent'] == $com_parent) {
					if ($val['score'] >= $score) {
						$tmp .= "<li>".$this->ac($val,$val['news_id']);
						$tmp .= $this->com_print2(0,$val['id'],$score)."</li>";
						$ok=1;
					} else {
						$tmp .= "<li>".$this->ac($val,$val['news_id'],"scoredown");
						$tmp .= $this->com_print2(0,$val['id'],$score)."</li>";
						$ok=1;
					}
				}
			}
			if ($ulnb < $ulmax) {
				$tmp .= "</ul>\n";
			}
			$ulnb--;
			if ($ok) {
				$out .= $tmp;
			}
		}
		return $out;
	}

	/* This will display comment */
	Function ac($c,$news_id,$mode="full") {
		global $config;

		$tmp = "<span class=\"newstext\">\n".
			' <a name="c'.$c['id'].'"><b>'.$c['subject']."</b></a>\n".
			' (Score: '.$c['score'];
		if(!empty($c['score_info']))
			$tmp .= ' - '.$c['score_info'];
		$tmp .= ")\n";

		if ($mode=="scoredown") {
			return '<a href="'.
					$config->basehref."comments/view.".$config->php.
					"?news_id=$news_id&amp;com_id=".$c['id']."&amp;theme=".$config->theme.
					"\" OnClick=\"window.open('".
						$config->basehref."comments/view.".$config->php.
						"?news_id=$news_id&amp;com_id=".$c['id']."&amp;theme=".$config->theme."',".
						"'comment','".
						'toolbar=no,location=no,directories=no,status=no,'.
						'menubar=no,scrollbars=yes,width=566,height=333'.
						"'); return false;\" ".
					"onMouseOut=\"window.status=''; return true;\" ".
					"onMouseOver=\"window.status='View'; return true;\"".
				">[+]\n".
				$tmp.
				"</a></span>\n";
		}

		$c['subject'] = ereg_replace(
			"((ftp|https?)://(([[:alnum:]]|[[:punct:]]){1,40})([[:alnum:]]|[[:punct:]])*)",
			"<a href=\"\\0\">\\3</a>",$c['subject']);
		$c['body'] = ereg_replace(
			"((ftp|https?)://(([[:alnum:]]|[[:punct:]]){1,40})([[:alnum:]]|[[:punct:]])*)",
			"<a href=\"\\0\">\\3</a>",$c['body']);
		$c['sig'] = ereg_replace(
			"((ftp|https?)://(([[:alnum:]]|[[:punct:]]){1,40})([[:alnum:]]|[[:punct:]])*)",
			"<a href=\"\\0\">\\3</a>",$c['sig']);

		$c['body'] = nl2br($c['body']);
		$c['sig'] =  nl2br($c['sig']);


		// Don t remove this line !
		$tmp .= "<!-- ADMINSCORE:".$c['user_id'].":".$c['id']." -->";
		if ($this->session->is_scoror &&
			$this->session->user_id != $c['user_id']) {
			$tmp .= "&nbsp; <b>[</b> ";

			for ($i=-1;$i<=5;$i++) {
				$tmp .= '<a href="'.
					$config->basehref."comments/score.".$config->php.
					"?news_id=$news_id&amp;id=".$c['id']."&amp;score=$i&amp;theme=".$config->theme.
					"\" OnClick=\"window.open('".
						$config->basehref."comments/score.".$config->php.
						"?news_id=$news_id&amp;id=".$c['id']."&amp;score=$i&amp;theme=".$config->theme."',".
						"'score',".
						"'toolbar=no,location=no,directories=no,status=no,".
						"menubar=no,scrollbars=no,".
						"resizable=no,width=100,height=50'); return false;\" ".
					"onMouseOut=\"window.status=''; return true;\" ".
					"onMouseOver=\"window.status='Scorer $i'; return true;\"".
					">$i</a> ";
			}
			$tmp .= "<b>]</b>";
		}
		// Don t remove this line !
		$tmp .= "<!-- /ADMINSCORE -->";


		// Now we choose to show login or fname/lname
		if (($c['param'] & pow(2,0)) && $c['user_id'] != 1 &&
			(!empty($c['lname']) || !empty($c['fname']))) {
			$usermask = $c['fname']." ".$c['lname'];
		} else {
			$usermask = $c['login'];
		}

		$tmp .= "<br>".lecho("Added by")." " ;
		if (!empty($c['fake_email'])) {
			$tmp .= '<a href="mailto:'.htmlentities($c['fake_email']).'">'.
				$usermask.'</a> ';
		} elseif (!empty($c['email'])) {
			$tmp .= '<a href="mailto:'.$c['email'].'">'.$usermask.'</a> ';
		} else {
			$tmp .= "$usermask ";
		}

		if ($c['user_id'] > 1) {
			$tmp .= "( <a href=\"".$config->basehref."users/?a=vu&user_id=".$c['user_id'].
			  "\">#".$c['user_id']."</a> ) ";
		}

		if ($this->session->checked && $c['user_id'] != 1) {
			$tmp .= '<a href="'.$config->basehref.
				'/messages/post.'.$config->php.
				'?user_id_dest='.$c['user_id'].
				'"><img alt="message" border="0" src="'.
				$this->session->imgurl('mail').'"></a> ';
		}

		$tmp .= "- ".$this->utils->stamp2date($c['timestamp'],"long")."<br>\n";

		if (!empty($c['homesite'])) {
			$tmp .= '<a href="'.$c['homesite'].
				'">'.$c['homesite']."</a><br>\n";
		}

		$tmp .= "<br>".$c['body'];

		if (!empty($c['sig']) && !$config->hide_sig) {
			$tmp .= "<br><br>-- <br>\n".$c['sig']."\n";
		}

		// Reply
		$url = $config->basehref.$config->commaddfile.
			"?news_id=$news_id&amp;com_id=".$c['id'];
		return $tmp.'<br>[ <a href="'.$url.
			'" onclick="'."opener.location='$url'; return false;\">".
			htmlentities(lecho("Reply"))."</a> ]\n".
			"</span><br>\n";
	}


	/* This will get all url in comments */
	Function _com($d) {
		$n=preg_match_all("/(f|ht)tps?:\/\/[^ \"\r\n\t\>\)]+/i",$d,$t);
		// $d=preg_replace( "/((f|ht)tps?:\/\/[^ \r\n\t]+)/i" , "<a href=\"\\1\">\\1</a>" ,$d);
		for($i=0;$i<$n;$i++) {
			$u = $t[0][$i];
			/* 
			 * If the url is not already in the array, we add it 
			 */
			if(!isset($l[$u])) { 
				$this->com_urls[] = $u;
			}
			$l[$u]=1;
		}
	}

	// This will return all the urls from comments
	Function get_hrefs() {
		global $config;

		reset($this->comments);
		while (list (, $val) = each ($this->comments)) {
			if ($val['score'] >= $config->score) {
				$this->_com($val['body']);
				$this->_com($val['subject']);
			}
		}

		$tmp_comhrefs = $this->com_hrefs();

		if (!empty($tmp_comhrefs)) {
			return $this->html->sidebox(lecho("Proposed links"),
			$tmp_comhrefs."<BR>");
		} else {
			return;
		}
	}

	Function com_hrefs() {
		$max_href_chars = 40;
		$r = array();
		if (isset($this->com_urls) && is_array($this->com_urls)) {
			reset($this->com_urls);
			while($t=each($this->com_urls)) {
				$r[]="&nbsp;-&nbsp;<a href=\"$t[1]\">";

				$t[1] = eregi_replace("^(https?|ftp)://","",$t[1]);

				if (eregi("^www.",$t[1])) {
					$t[1] = substr ($t[1], 4);
				}

				if (strlen($t[1]) > $max_href_chars) {
					$t[1] = substr ($t[1], 0, $max_href_chars);
					$t[1] .= "&nbsp;(...)";
				}

				$t[1] = ereg_replace("/$","",$t[1]);

				$r[].= $t[1]."</A><BR>";
			}
		}
		if (isset($r) && is_array($r)) {
			return implode("",$r);
		}
		return $r;
	}

	Function get_subject($id) {
		global $config;

		$sqlc_q = "SELECT subject FROM ".$config->tables['comments'].
			" WHERE id='".addslashes($id)."'";

		$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();

		return $row[0];
	}

	// Function to modify score
	Function mod_score($row) {
		global $config;

		$sqlc_q = "UPDATE ".$config->tables['comments_scored']." SET ".
			"user_id='".addslashes($this->session->user_id)."',".
			"score='".addslashes($row['score'])."',".
			"info='".addslashes($row['info'])."' WHERE ".
			"comments_id='".addslashes($row['comments_id'])."'";

		$ret = $this->db->query($sqlc_q);
		if (!$ret) {
			echo "<!-- SQL failed:".$this->db->error(). " -->\n";
			echo "<!-- SQL request: $sqlc_q -->\n";
			exit;
		}
	}

	/*  These `Submit Comment' functions are used to add a new comment
	 *      Function check_news
	 *      Function preview
	 */
	Function check_news($news_id,$com_id) {
		// We check if the news exists.
		$sqlc_q = "SELECT state FROM news WHERE id='".
			addslashes($news_id)."'";
		$ret = $this->db->query($sqlc_q);
		if (!$ret) return $this->db->error();
		list($state_of_news) = $this->db->fetch_array();
		$this->db->free();
		if ($state_of_news != 1) {
			return lecho("Sorry, no results.").
				" : News ".
				lecho("Not Found");
		}

		// We check if the comment exists.
		if (isset($com_id)) {
			$sqlc_q = "SELECT id FROM comments WHERE ".
				"id='".addslashes($com_id)."' AND ".
				"news_id='".addslashes($news_id)."'";
			$ret = $this->db->query($sqlc_q);
			if (!$ret) return $this->db->error();
			list($com_id_ok) = $this->db->fetch_array();
			$this->db->free();
			if (! $com_id_ok) {
				return lecho("Sorry, no results.")." : ".
					lecho("Comment")." ".
					lecho("Not Found");
			}
		}
	}

	Function preview($news_id,$com_id,$table) {
		global $config;

		// we calculate the preview of our future comment
		if ($this->session->checked && ! $table['anon']) {
			$score = 1;
			$perso = $this->user->identity().
				' ( #'.$this->session->user_id.' ) '.
				'<img alt="message" src="'.$this->session->imgurl('mail').'">';
			if ($this->user->get_sig($this->session->sig_id)) {
				$sig = "<br><br>-- <br>".$this->user->signature;
			} else {
				$sig = "";
			}
		} else {
			$perso = lecho("Anonymous");
			$score = 0;
		}
		if ($table['troll']) {
			$score = -1;
		}
		$perso .= " - ". $this->utils->stamp2date(date("YmdHis"),"long") . "<br>\n";
		if (empty($table['subject'])) {
			$subject = lecho("Check your text here...");
		} else {
			$subject = $table['subject'];
		}
		$preview = "  <span class=\"newstext\">\n".
			"   <b>\n".
			"    ".$this->utils->htmlspecial($subject)."\n".
			"   </b>\n".
			"   (Score: $score - )\n".
			"   <br>\n".
			"   ".lecho("Added by")." $perso\n".
			"   <br>\n".
			"    ".nl2br($this->utils->htmlspecial($table['body'],1))."\n".
			"    ".$sig."\n".
			"   <br>\n".
			"   [ ".lecho("Reply")." ]\n".
			"  </span>\n".
			"  <br>\n";
		// and now we can print the box.
		// maybe there is an upper comment that we can integrate ?
		//
		if ($com_id) {
			// yes, the upper comment is integrated in the preview
			$this->init($news_id,$com_id);  // we get its info.
			$preview = $this->html->simplebox(
				$this->ac(
					$this->comments[0],
					$this->comments[0]['news_id'],
					"full"
					)."\n".
				"<br>\n".
				"<ul>\n".
				" <li>\n".
					$preview.
				" </li>\n".
				"</ul>\n");
		} else {
			// there is no upper comment,
			// so the preview is simple...
			//
			$preview = $this->html->simplebox($preview);
		}
		return $preview;
	}

	Function submit($news_id,$com_id=0) {
		global $config;
		global $HTTP_POST_VARS;

		$pass = 1;
		$table = ($HTTP_POST_VARS['table']?$HTTP_POST_VARS['table']:"");
		$table2 = ($HTTP_POST_VARS['table2']?$HTTP_POST_VARS['table2']:"");

		$check_error = $this->check_news($news_id,$com_id);
		if (!empty($check_error)) {
			return $check_error;
		}

		if (is_array($table)) {
			//  Check whether $table and $table2 are identical
			//  but we except the field 'stack_history'
			$newstack = $table['stack_history'] + 1;
			$table['stack_history'] = $table2['stack_history'];
			if ($this->utils->cmp_array($table,$table2)) {
				$table['stack_history'] = $newstack;
				return $this->submit_confirm($table);
			} else {
				$table['stack_history'] = $newstack;
				$pass = 2;
			}
		} else {
			$table = array();
			$table['body'] = "";
			$table['troll']= "";
			$table['stack_history'] = "";
		}

		if ($pass == 1) {
			if (!empty($com_id)) {
				$temposub = $this->get_subject($com_id);
				if (ereg("^Re: ",$temposub)) {
					$table['subject'] = $temposub;
				} else {
					$table['subject'] = "Re: ".$temposub;
				}
			}
			$subject = $table['subject'];
		} else {
			$subject = $this->utils->htmlspecial($table['subject']);
		}

		$out = "<form method=\"post\" action=\"".
			$config->basehref.$config->commaddfile."\">\n";

		//  Previous answers are stored in hidden fields
		reset($table);
		while(list($key,$value)=each($table)) {
			$out .= "<input type=\"hidden\" name=\"table2[$key]\"".
				" value=\"".htmlspecialchars($table[$key])."\">\n";
		}

		$out .= " <table>\n".
			"  <tr>\n".
			"   <td align=\"right\">\n".
			"    ".$this->user->identity()."\n".
			"   </td>\n".
			"   <td>\n".
			"    <b>\n".
			"     [ ";

		if ($this->session->checked) {
			$out .= $this->session->login;
		} else {
			$out .= lecho("Anonymous")." (".lecho("You are not authenticated").
					")";
		}

		$out .= " ]\n".
			"    </b>\n".
			"   </td>\n".
			"  </tr>\n".
			"  <tr>\n".
			"   <td align=\"right\">\n".
			"    ".lecho("Subject")."\n".
			"   </td>\n".
			"   <td>\n".
			'    <input type="text" name="table[subject]" value="'.
				$subject.
				"\" size=\"50\" maxlength=\"80\">\n".
			"   </td>\n".
			"  </tr>\n".
			"  <tr>\n".
			"   <td valign=\"top\" align=\"right\">\n".
			"    ".ucfirst(lecho("Comment"))."\n".
			"   </td>\n".
			"   <td>\n".
			"    <textarea name=\"table[body]\" rows=\"10\" cols=\"50\" wrap=\"virtual\">".
			$this->utils->htmlspecial($table['body'])."</textarea>\n".
			"   </td>\n".
			"  </tr>\n".
			"  <tr>\n".
			"   <td>&nbsp;</td>\n".
			"   <td colspan=\"2\" align=\"right\">\n".
			"    ".
			lecho("URLs must be written http://... without &lt;a&gt; tag. Following HTML tags are valid, but must be closed by the adequate &lt;/X&gt; tag:").
			"\n".
			($config->valid_tags ?
				'&lt;'.join('&gt; &lt;', $config->valid_tags).'&gt;' : ' nono').
			"   </td>\n".
			"  </tr>\n";

		if ($this->session->checked && $config->anonymous_comments) {
			$out .= "  <tr>\n   <td>&nbsp;</td>\n   <td colspan=\"2\" align=\"left\">\n".
				"    <input type=\"checkbox\" name=\"table[anon]\" value=\"1\"";
			if ($table['anon']) {
				$out .= " checked";
			}
			$out .= ">&nbsp;".lecho("Post Anonymously")."\n".
				"   </td>\n  </tr>\n";
		}
		$out .= "  <tr>\n   <td>&nbsp;</td>\n   <td colspan=\"2\" align=\"left\">\n".
			"    <input type=\"checkbox\" name=\"table[troll]\" value=\"1\"".
			($table['troll'] ? " checked" : "") . ">&nbsp;Score -1\n </td>\n  </tr>\n";

		$out .= "  <tr>\n   <td colspan=\"3\" align=\"center\">\n".
			"    <input type=\"submit\" name=\"submit\" value=\"".lecho("Next")."\">\n".
			"   </td>\n".
			"  </tr>\n".
			" </table>\n".
			' <input type="hidden" name="table[stack_history]" value="'.$table['stack_history']."\">\n".
			" <input type=\"hidden\" name=\"table[news_id]\" value=\"";

		if (!empty($table['news_id'])) {
			$out .= $table['news_id'];
		} elseif (!empty($news_id)) {
			$out .= $news_id;
		}
		$out .= "\">\n";

		if (ereg("^[0-9]+$",$com_id) && $com_id > 0) {
			$out .= " <input type=\"hidden\" name=\"table[com_id]\" value=\"$com_id\">\n";
		} elseif (!empty($table['com_id'])) {
			$out .= " <input type=\"hidden\" name=\"table[com_id]\" value=\"".$table['com_id']."\">\n";
		}

		$out .= "</form>\n".
			"<p><center>".lecho("Step")." $pass/3</center>";

		return $this->html->simplebox($out);
	}

	/* Add a new comment. Called from /comments/add.php3 */
	Function submit_confirm($table) {
		global $config;

		if (!ereg("^".$config->basehref,$this->HTTP_REFERER) &&
				($this->session->param & pow(2,3) == 0)) {
			return $this->news->warn_referer() .
				"<p><center>".lecho("Step")." 3/3</center>";
		}

		if (empty($table['subject']) || empty($table['body'])) {
			return lecho("Both subject and body must be filled").
				"<p><center>".lecho("Step")." 3/3</center>";
		}

		// If user isn't authentified and anonymous comment not allowed
		if (!$this->session->user_id && !$config->anonymous_comments) {
			return lecho("You are not authenticated").
				"<p><center>".lecho("Step")." 3/3</center>";
		}
		$table['subject'] = $this->utils->htmlspecial($table['subject']);
		$table['body'] = $this->utils->htmlspecial($table['body']);

		/* We Build the SQL Commands:
		 * $sqlc_q will publish the new comment and
		 * $r will check if the comment does already exist
		 */
		$sqlc_q = 'INSERT INTO '.$config->tables['comments'].
			' (subject,body,news_id,user_id,ip,com_parent,sig_id)'.
			" VALUES ('".
			addslashes($table['subject'])."','".
			addslashes($table['body'])."','".
			addslashes($table['news_id'])."','";
		$sqlc_r = 'SELECT id FROM '.$config->tables['comments']." WHERE ".
			"subject='".addslashes($table['subject'])."' AND ".
			"body='".addslashes($table['body'])."' AND ".
			"news_id='".addslashes($table['news_id'])."'";

		// If anonymous is allowed and used, we go for it
		if (($table['anon'] && $config->anonymous_comments) ||
			!$this->session->user_id) {
			$sqlc_q .= "1";
		} else {
			$sqlc_q .= addslashes($this->session->user_id);
		}

		$sqlc_q .= "','".addslashes($this->utils->ip())."',";

		// Now we put parent comment
		if (ereg("^[0-9]+$",$table['com_id']) && $table['com_id'] > 0) {
			$sqlc_q .= "'".addslashes($table['com_id'])."',";
			$sqlc_r .= " AND com_parent='".addslashes($table['com_id'])."'";
		} else {
			$sqlc_q .= "'0',";
			$sqlc_r .= " AND com_parent='0'";
		}

		// If anonymous comment => default sig is 1
		if (($table['anon'] && $config->anonymous_comments) ||
			!$this->session->user_id) {
			$sqlc_q .= "'1'";
		} else {
			$sqlc_q .= "'".addslashes($this->session->sig_id)."'";
		}
		$sqlc_q .= ")";

		$ret = $this->db->query($sqlc_r);
		if (!$ret) {
			echo "<!-- SQL failed: ".$this->db->error() . " -->\n";
			echo "<!-- SQL Command: $sqlc_r -->\n";
			return;
		}
		$count = $this->db->num_rows();
		if ($count > 0) {
			return lecho("Sorry, a similar comment has already been registered for this news.  If for some reason you really want to post the same comment, you may add some spaces anywhere.");
		}

		$ret = $this->db->query($sqlc_q);
		if (!$ret) {
			echo "<!-- SQL failed: ".$this->db->error() . " -->\n";
			echo "<!-- SQL Command: $sqlc_q -->\n";
			return;
		}
		$comments_id = $this->db->last_insert_id();
		$sqlc_q = "INSERT INTO ".$config->tables['comments_scored'].
			" (comments_id,user_id,score,info) VALUES ('".
			addslashes($comments_id)."','1','";

		if ($table['troll']) {
			$sqlc_q .= "-1";
		} elseif (($table['anon'] && $config->anonymous_comments) ||
				!$this->session->user_id) {
			$sqlc_q .= "0";
		} else {
			$sqlc_q .= "1";
		}

		$sqlc_q .= "','')";

		/* We remove the HTML pages for this news */
		$this->cache->delete_obsolete_news($table['news_id']);

		$ret = $this->db->query($sqlc_q);
		if (!$ret) {
			echo "<!-- SQL failed:".$this->db->error(). " -->\n";
			echo "<!-- SQL request: $sqlc_q -->\n";
			return;
		}

		$ts = $this->utils->gettimestampnews($table['news_id']);
		$news_url = $this->session->newsurls($table['news_id'], "",
				"", $ts[0], $ts[1], $ts[2]);
		$news_url = ereg_replace(',[^/]+$', '', $news_url);

		return "<div class=\"commentconfirm\">\n".
			" <p>".lecho("Your comment has been registered. You can find it").
			lecho(" at the url ")."<a href=\"".$news_url."\">".$news_url.
			"</a><br>\n".lecho("  Follow this link to come back to it by ").
			'<a href="javascript:history.go(-'.++$table['stack_history'].')">'.
			lecho("back")."</a>."." <p>".
			lecho("If you don't see it on this page it").
			lecho(" means that your webbrowser put this page").
			lecho(" in his cache. You have to reload the page.\n").
			" <p><center>".lecho("Step")." 3/3</center>\n".
			"</div>\n";
	}


	/* These `Load N Show' functions are used to select Nodes of comments
	 *      in the SQL database and to print these selections. A Branch
	 *      is a List of comments (the last one is $com_id), and a Subtree
	 *      is Tree of comments (the root is $com_id).
	 *
	 *      Function load_branch($news_id,$com_id)
	 *      Function load_subtree($news_id,$com_id)
	 *      Function show_branch($news_id,$com_id)
	 *      Function show_subtree($news_id,$com_id)
	 */


	Function load_branch($news_id,$com_id,$list='all') {
		global $config;

		$branch = array();
		$sqlc_q = "SELECT id,com_parent".
			" FROM ".$config->tables['comments'];

		if ($list=='last') {
			$sqlc_q .= " WHERE id='".addslashes($com_id)."'";
		} else {
			$sqlc_q .= " WHERE news_id='".addslashes($news_id).
				"' AND id<='".addslashes($com_id).
				"' ORDER BY id DESC";
		}

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

		if (!$ret) {
			echo "<!-- SQL failed:".$this->db->error()."\n";
			echo "SQL command was: $sqlc_q -->\n";
			exit ;
		}

		$expected_node = $com_id;
		while(list($id,$father) = $this->db->fetch_array()) {
			if ($expected_node==$id) {
				$branch[] = $id;
				$expected_node = $father;
			}
		}
		$this->db->free();

		return $branch;
	}

	Function load_subtree($news_id,$com_id) {
		global $config;

		$sqlc_q = "SELECT id,com_parent".
			" FROM ".$config->tables['comments'].
			" WHERE news_id='".addslashes($news_id)."' AND ".
			"id>'".addslashes($com_id)."'".
			" ORDER BY id ASC";

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

		if (!$ret) {
			echo "<!-- SQL failed:".$this->db->error();
			echo "SQL Command: $sqlc_q -->\n";
			exit ;
		}

		$node_in_subtree[$com_id]=1;
		while(list($id,$father) = $this->db->fetch_array()) {
			if ($node_in_subtree[$father]) {
				$subtree[$father][] = $id;
				$node_in_subtree[$id] = 1;
				$set[] = $id;
			}
		}

		$this->db->free();

		$this->init($news_id,$set);
		return $subtree;
	}

	Function show_branch($news_id,$com_id,$list='all') {
		$branch = $this->load_branch($news_id,$com_id,$list);
		$this->init($news_id,$branch);
		rsort($branch);
		reset($branch);
		$out = '';
		while (list($k,$v) = each($branch)) {
			$out .= " <li>\n".
				"  ".$this->ac(
					$this->comments[$k],
					$this->comments[$k]['news_id'],
					"full"
					)."\n".
				" </li>\n";
		}
		/* Ici vous pouvez voir le Contexte ou la Branche.
		 * C est une liste dont le dernier élément est le
		 * commentaire référencé $com_id dans l URL.
		 */
		return $this->html->simplebox("<ul>\n$out</ul>\n");
	}

	Function show_subtree($news_id,$com_id) {
		$subtree = $this->load_subtree($news_id,$com_id);
		return "Ici vous pouvez voir le <b>sous-arbre</b> du <b>noeud</b> numéroté $com_id.\n".
			$this->html->simplebox($this->com_print2(0,$com_id));
	}

}

?>
