<?PHP
/*
* Filename.....: class_comment.php
* Class........: comment
* Purpose......: Allow comments on different items
* Parameter....: none
* Erstellt am..: 2006-05-20
* _ __ _ _
* ||| | |/ / (_) | Wirtschaftsinformatiker IHK
* \. ./| ' / _ __ _| |_ ___ www.ingoknito.de
* - ^ -| < | '_ \| | __/ _ \
* / - \| . \| | | | | || (_) | Peter Klauer
* ||| |_|\_\_| |_|_|\__\___/ 06136-909093
* mailto.......: hide@address.com
*
* Changes/Änderungen:
*/
class comment
{
var $cssdir = './css/'; // where is my stylesheet?
var $id_for = 0;
var $code_for = '';
/**
* If the client already has made a comment on a specific
* subject, he is not allowed to make another if
* $prevent_multiple is true. However, he may edit his
* already made comment.
*/
var $prevent_multiple = true;
/**
* Trying to find links by the '://' indicator
* Comments with links are not allowed.
*/
var $prevent_spam = true;
var $showcomments = false; // expand comment list without being asked
# this class needs sqltable already installed and running!
var $comments_per_page = 10;
var $sqltable = 0;
# tweaking section - - - - - - - - - - - - - - - - - - -
var $newline = "\n";
var $SQLTYPE = 'mysql'; // mssql works, too
var $debug = false;
var $comment_rows = 4; // height of comment input field
var $comment_cols = 60; // width of comment input field
var $before_insert = ''; // string before insert form
var $after_insert = '';
var $before_comments = ''; // string before comments table is shown
var $after_comments = '';
# callback function ( id_for, code_for, comment, nickname )
var $onnew = ''; // callback function evaluated when new comment
# callback function ( id_for, code_for, comment, nickname, old_comment )
var $onchange = ''; // callback function evaluated when comment is changed
# callback function ( id_for, code_for )
var $onalias = ''; // callback function to prepare alias name
var $edit_alias = true; // alias field can be edited by user
var $show_alias = true; // alias field is shown
# language specific - - - - - - - - - - - - - - - - - - -
var $say_comment = 'Comment';
var $say_comments = 'Comments';
var $say_addcomment = 'Add a comment';
var $say_submit = 'Submit';
var $say_nickname = 'Nickname';
var $say_update = 'Update';
var $say_updated = 'Entry updated.';
var $say_close = 'Close (X)';
var $say_nomultiple = 'Sorry, no multiple comments allowed.';
var $say_entered = 'First entered on';
var $say_lastchanged= 'Last change';
var $say_nolinks = 'Sorry, no links allowed.';
# internal - - - - - - - - - - - - - - - - - - - - - - - -
var $funcname = ''; // for comment::error
/**
* You may have more than one comment-types on your websites:
* Comments may be on articles, polls, designs, news or even on comments.
* Using the $code_for "articles" you may have a comment for an article with id 13
* and using the $code_for "polls" you may have a comment for a poll with id 13
* in another table.
*
* @param integer $id_for = id of article in article-table
* @param string $code_for = abbreviation for "kind-of-article" (may be empty)
* @param rewource $sqltable = reference to an object of class sqltable
* @param string $cssdir = Directory of the cssfile for the comments
*/
function comment( $id_for, $code_for, &$sqltable, $cssdir = './css/' )
{
$this->funcname = 'comment';
if( ! is_dir( $cssdir ) )
{
$this->error("[$cssdir] is not a directory!" );
}
$this->cssdir = $cssdir;
if( ! get_class( $sqltable ) == 'newsqltable')
{
$this->error( 'I need a reference to sqltable (http://www.phpclasses.org/browse/package/1981.html) to work properly!' );
}
$this->sqltable =& $sqltable;
$this->id_for = $id_for;
$this->code_for = $code_for;
$this->sqltable->mousehighlight= false;
} // eof comment (constructor)
/**
* Install the style sheet into the head section of the page.
* Check whether the MYSQL-table exists and try installing it if missing.
* As you see, it does not open any connection to a db here. The class assumes
* that the sql connection is already open. The sql type is in var $this->SQLTYPE
* Shall work with both mysql and mssql.
*/
function install( )
{
$this->funcname = 'install';
# just to be sure: add a slash / at the end of $this->cssdir if missing
if( ! (substr( $this->cssdir, strlen($this->cssdir )-1, 1) == '/' ) ) $this->cssdir .= '/';
if( ! file_exists( $this->cssdir.$this->code_for.'comment.css') )
{
#
# Try to write it!
#
$css = '
/* css for class comment written on '.date( 'Y-m-d H:i:s' ).' */
.commentinput{ margin: 1em }
.commentinput label{
float:left;
width: 7em;
text-align:right;
margin: 0 1em 0 0;
}
.commenttopbar{
background-color: #ccc;
color: #000;
border: solid 2px #888;
margin: 0 0 1px 0;
}
.commentnickname{
width: 20ex;
font-size: 120%;
}
.commentdatetime{
font-size: 80%;
color: #888;
width: 45ex;
float: right;
}
.comment{
margin:0 0 1ex 0;
}
.comment form{
margin:0;
}
.comment textarea{
width: 90%;
background-color: #ddd;
color: black;
font-family:Arial, sans-serif;
border: solid 1px #888;
}
.comment span{
display: block;
background-color: #ddd;
color: black;
font-family:Arial, sans-serif;
border: solid 1px #888;
}
';
$handle = fopen( $this->cssdir.$this->code_for.'comment.css', 'w' );
if( fwrite( $handle, $css, strlen( $css ) ) === FALSE )
{
$this->error( 'Can not write CSS file ['.$this->cssdir.$this->code_for.'comment.css]');
}
fclose( $handle );
} // end of if css file does not exist
echo $this->newline.'<link rel="stylesheet" type="text/css" href="'.
$this->cssdir.$this->code_for.'comment.css">';
if( !class_exists('sqltable') ) $this->error( 'sqltable not loaded!' );
if( ! get_class( $this->sqltable ) == 'sqltable')
{
$this->error( 'I need a reference to sqltable (http://www.phpclasses.org/browse/package/1981.html) to work properly!' );
}
# $this->sqltable->showstart =
# isset( $_GET['showstart'.$this->code_for] ) ? $_GET['showstart'.$this->code_for] :
# isset( $_POST['showstart'.$this->code_for] ) ? $_POST['showstart'.$this->code_for] : 0;
$this->sqltable->showcount = $this->comments_per_page;
$this->sqltable->SQLTYPE = $this->SQLTYPE;
$this->sqltable->instance = $this->code_for; // rename showstart and showcount
$this->sqltable->third =& $this; // 3rd arg for udf
$this->sqltable->width='100%'; // take all the space available
$this->sqltable->showcaptions = false; // we rearrange everything into one cell
switch( $this->SQLTYPE )
{
/**
* The indexes are all needed. If you plan to have sql statements which
* contain a "where" statement then be sure to have an index for every
* column that is withing the "where" clause. You will slow down your
* sql otherwise, resulting in a slow server response time.
* Here the indexes are needed to check whether the client is allowed
* re-editing or if a similar item already exists (POST data refreshed).
*/
case 'mysql':
mysql_query(
"CREATE TABLE IF NOT EXISTS comments
(
`id` bigint(20) unsigned NOT NULL auto_increment,
`id_for` bigint(20) unsigned NOT NULL default '0',
`code_for` varchar(8) NOT NULL default '''''',
`datetime` datetime NOT NULL default '0000-00-00 00:00:00',
`lastchanged` datetime NOT NULL default '0000-00-00 00:00:00',
`nickname` varchar(15) NOT NULL default '',
`comment` longtext NOT NULL,
`ip` varchar(15) NOT NULL default '',
`dns` varchar(180) NOT NULL default '',
`user_agent` varchar(180) NOT NULL default '',
`hash` varchar(32) NOT NULL default '',
`validated` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `id_for` (`id_for`),
KEY `code_for` (`code_for`),
KEY `datetime` (`datetime`),
KEY `ip` (`ip`),
KEY `user_agent` (`user_agent`),
KEY `nickname` (`nickname`),
KEY `validated` (`validated`),
KEY `hash` (`hash`)
) TYPE=MyISAM AUTO_INCREMENT=1") ;
break;
case 'mssql':
mssql_query(
"
-- this will seldom work because of missing rights. Copy this text
-- and let it execute in the SQL Query Analyzer
-- if you work with mssql, you need to know what you do,
-- sorry.
IF NOT EXISTS( SELECT NAME FROM SYSOBJECTS WHERE NAME='comments' )
BEGIN
CREATE TABLE [comments] (
[id] [bigint] IDENTITY (1, 1) NOT NULL ,
[id_for] [bigint] NOT NULL ,
[code_for] [varchar] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[datetime] [datetime] NOT NULL ,
[lastchanged] [datetime] NOT NULL ,
[nickname] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[comment] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ip] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[dns] [varchar] (180) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[user_agent] [varchar] (180) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[hash] [varchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[validated] [tinyint] not null
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE UNIQUE CLUSTERED INDEX [comment_id] ON [comments]([id]) WITH PAD_INDEX ON [PRIMARY]
ALTER TABLE [comments] ADD
CONSTRAINT [DF_comments_id_for] DEFAULT (0) FOR [id_for]
ALTER TABLE [comments] ADD
CONSTRAINT [DF_comments_validated] DEFAULT (0) FOR [validated]
CREATE INDEX [comment_id_for] ON [comments]([id_for]) ON [PRIMARY]
CREATE INDEX [comment_code_for] ON [comments]([code_for]) ON [PRIMARY]
CREATE INDEX [comment_ip] ON [comments]([ip]) ON [PRIMARY]
CREATE INDEX [comment_user_agent] ON [comments]([user_agent]) ON [PRIMARY]
CREATE INDEX [comment_nickname] ON [comments]([nickname]) ON [PRIMARY]
CREATE INDEX [comment_validated] on [comments]([validated]) on [PRIMARY]
CREATE INDEX [comment_hash] on [comments]([hash]) on [PRIMARY]
GRANT SELECT , UPDATE , INSERT , DELETE ON [comments] TO [public]
END
");
break;
default: $this->error( "Wrong SQLTYPE: [$this->SQLTYPE]" );
}
}
/**
* Output an error and terminate
* @param string $what = error message
*/
function error( $what )
{
die( "<br>COMMENT::$this->funcname() <b>$what</b>" );
}
/**
* temporal support function
*/
function showsummary()
{
$this->put();
}
/**
* Shows, how many comments there are for this subject.
* Outputs a link to the comments list.
* Outputs comments list
* @param boolean $inputbox = whether to show an input field or not
*/
function put()
{
global $_SERVER; // not always superglobal!?
$p = $_SERVER['PHP_SELF'];
$q = $_SERVER['QUERY_STRING'];
$this->funcname = 'showsummary';
#
# insert new comment
#
if( isset( $_POST['savecomment'] ) and ($_POST['savecomment'] == '1' ) )
{
# mssql and mysql have different date functions. I take the PHP date for that.
$dt = date('Y-m-d H:i:s');
$ip = $_SERVER['REMOTE_ADDR'];
$dns = gethostbyaddr($ip);
$ua = $_SERVER['HTTP_USER_AGENT'];
# get posts
$nickname = trim( $_POST['nickname'] );
$nickname = $this->checkspam($nickname);
$comment = trim($_POST['comment']);
$comment = $this->checkspam($comment);
$comment = stripslashes( $comment );
$comment = htmlentities( $comment );
$comment = str_replace( "'", ''', $comment );
$comment = str_replace( '\\', '\', $comment );
$hash = md5( $comment );
# empty name or comment? Go back.
$ok = true;
if( strlen( $nickname ) == 0 ) $ok = false;
if( strlen( $nickname ) > 15 ) $nickname = substr( $nickname, 0, 15 );
if( strlen( $comment ) == 0 ) $ok = false;
if( $ok )
{
# is there already such a comment (double trouble when refreshing post data)
$anzahl = 0;
# mssql cannot compare TEXT columns.
# that is why a md5 hash field is in the table and this hash is compared instead.
$query = "select count(*) from comments where ".
"nickname='$nickname' and ip='$ip' and hash='$hash' ".
"and id_for='$this->id_for' and code_for='$this->code_for' ".
"and user_agent='$ua'";
$r = $this->execute( 'query', $query );
if( $r and $this->execute( 'num_rows', $r ) == 1 )
{
list( $count ) = $this->execute( 'fetch_row', $r );
$this->execute( 'free_result', $r );
}
#
# save the comment when it does not exist yet
#
if( $count == 0 )
{
#
# if there is a function comment::onalias
# and the user is not allowed to change the name ( comment::edit_alias == false )
# (because we are in an intranet (AD) and the name does not need to be changed)
# then just call the function again to receive the name.
# Else take what you get.
#
if( $this->edit_alias == false and strlen(trim( $this->onalias ) )> 0 and function_exists( $this->onalias ) )
{
$nickname = eval( 'return('.$this->onalias.'('.$this->id_for.', \''.$this->code_for."'));");
}
$query =
"insert into comments ".
"(id_for, code_for, datetime, lastchanged, nickname, comment, ip, dns, user_agent, hash) ".
"values ".
"('$this->id_for','$this->code_for', '$dt', '$dt', '$nickname', '$comment', '$ip', '$dns', '$ua', '$hash')";
$r = $this->execute( 'query', $query );
$_GET['addcomment'] = 0;
#
# if comment::onnew is set, then evaluate it!
# the callback function receives id_for and code_for as parameters.
#
if( strlen( trim( $this->onnew ) ) > 0 and function_exists( $this->onnew ))
{
#
# The target function will output all necessary user information, if any.
#
eval( 'return('.$this->onnew.'('.$this->id_for.', \''.$this->code_for."', '$comment', '$nickname' ));");
}
}
else
{
# just do nothing and throw it away!
}
}
}
#
# Update a comment
#
if( isset($_POST['updatecomment']) and $_POST['updatecomment']==1)
{
$update = 0; // some checks against tampered data
$today = date('Y-m-d');
#
# Check if the useragent, date, ip and nickname fit together.
# If yes, then let the user update his input.
# Otherwise, just display the text.
#
$id_comment = $_POST['id_comment'];
$dt = $this->sqlisodate('datetime');
$lc = $this->sqlisodate('lastchanged');
$query = "select $dt, ip, user_agent, comment, nickname, hash, $lc from comments where id='$id_comment'";
$r = $this->execute('query',$query);
if( $r and $this->execute('num_rows', $r ) == 1 )
{
list( $datetime, $ip, $user_agent, $old_comment, $nickname, $old_hash, $old_lastchanged ) = $this->execute('fetch_row', $r );
$this->execute( 'free_result', $r );
# this could be a long "AND" statement
if( strpos( '@'.$datetime, $today ) > 0 )
{
if( $_SERVER['REMOTE_ADDR'] == $ip )
{
if( $_SERVER['HTTP_USER_AGENT'] == $user_agent )
{
$update = 1;
} // same user agent
} // correct $ip
} // $datetime is $today
if( $update == 1 )
{
$comment = trim($_POST['comment']);
$comment = $this->checkspam($comment);
$comment = stripslashes( $comment );
$comment = htmlentities( $comment );
$comment = str_replace( "'", ''', $comment );
$comment = str_replace( '\\', '\', $comment );
$hash = md5( $comment );
if( $hash <> $old_hash )
{
$lastchanged = date( 'Y-m-d H:i:s' ); // different in mysql and mssql, use PHP!
if( $this->execute( 'query',
"update comments set comment='$comment', hash='$hash', ".
"lastchanged='$lastchanged' where id='$id_comment'") )
{
echo $this->say_updated ;
}
#
# if comment::onchange is set, then evaluate it!
# the callback function receives id_for, code_for and old_comment as parameters.
#
if( strlen( trim( $this->onchange ) ) > 0 and function_exists( $this->onchange ))
{
#
# The target function will output all necessary user information, if any.
#
eval( 'return('.$this->onchange.'('.$this->id_for.', \''.$this->code_for."','$comment', '$nickname', '$old_comment'));");
} // end if( has callback function )
} // end if( $hash <> $old_hash ) check if it is still the same message
} // end if( $update == 1 )
} // end if( $r and $this->execute('num_rows', $r ) == 1 )
} // end if( isset($_POST['updatecomment']) and $_POST['updatecomment']==1)
#
# Official comments link
#
echo '<a name="comments"></a>';
$numcomments = $this->getcount();
if( $numcomments > 0 )
{
$what = ( $this->showcomments or (isset($_GET['showcomments'] ) and $_GET['showcomments'] == '1' ) ) ? 0 : 1;
$anchor = $what == 0 ? '#comments' : '#commentsqltable';
$q2 = $this->sqltable->adjust_query_string( $q, 'showcomments='.$what );
$link_start = "<a href='$p?$q2$anchor' title='$this->say_comments'>";
$link_end = '</a>';
}
else
{
$link_start = '';
$link_end = '';
}
echo "$link_start$this->say_comments: $numcomments$link_end ";
#
# if no infobox, say add comment
#
if(!isset($_GET['addcomment']) or $_GET['addcomment'] == '0' )
{
if( $this->prevent_multiple and $this->client_made_comment_today() )
{
echo $this->say_nomultiple;
}
else
{
$qs = $this->sqltable->adjust_query_string( $q, 'addcomment=1' );
echo "<a href='$p?$qs#comments'>$this->say_addcomment</a>";
}
}
#
# having an empty line between (text) and (input box or comments) is nice
#
$x = 0;
$x += ( isset( $_GET['showcomments'] ) ? intval($_GET['showcomments']) : 0 );
$x += ( isset( $_GET['addcomment'] ) ? intval($_GET['addcomment'] ) : 0 );
if( $x > 0 ) echo '<br><br>';
#
# Show inputbox
#
if(isset($_GET['addcomment']) and $_GET['addcomment'] == '1' )
{
$this->inputbox();
}
#
# show comments in sqltable
#
if( $this->showcomments or ( isset( $_GET['showcomments']) and $_GET['showcomments'] == '1' ) )
{
# date is different on mysql and mssql.
# to have the iso sql date, mysql does not need any help.
# mssql is different.
# use a switch -statement if more SQLTYPEs arrive
$datesql = $this->sqlisodate('datetime').', '.
$this->sqlisodate('lastchanged'); // get a valid date sql string for iso date YYYY-mm-dd HH:ii:ss
$query = "select id, $datesql, nickname, comment, ip, dns, user_agent from comments where id_for='$this->id_for'
and code_for='$this->code_for' order by datetime desc";
$r = $this->execute( 'query', $query );
if( $r and ( $this->execute( 'num_rows', $r ) > 0 ) )
{
$this->sqltable->udf['datetime'] = 'comment::udf_commentsarrangedata';
$this->sqltable->hidden['nickname'] = 1;
$this->sqltable->hidden['ip'] = 1;
$this->sqltable->hidden['dns'] = 1;
$this->sqltable->hidden['id'] = 1;
$this->sqltable->hidden['user_agent'] = 1;
$this->sqltable->hidden['comment'] = 1;
$this->sqltable->hidden['lastchanged'] = 1;
$this->sqltable->fillup = false;
$this->sqltable->index = false;
echo $this->before_comments;
echo '<a name="commentsqltable"></a>';
$this->sqltable->anchor = '#commentsqltable';
$this->sqltable->put( $r );
$this->sqltable->anchor = '';
echo $this->after_comments;
$this->execute( 'free_result', $r );
}
}
} // eof comment::showsummary()
/**
* Output form for input or
* write the POST data into the table.
*/
function inputbox()
{
global $_SERVER;
if( $this->prevent_multiple and $this->client_made_comment_today() )
{
# sorry, no inputbox possible!
echo $this->before_insert;
echo $this->say_nomultiple;
echo $this->after_insert;
}
else
{
$ps = $_SERVER['PHP_SELF'];
$qs = $_SERVER['QUERY_STRING'];
$qs = $this->sqltable->adjust_query_string( $qs, 'addcomment=0' );
#
# The following avoids the generation of &amp;
#
$qs = str_replace( '&','&', $qs ); # make & to &
$qs = str_replace( '&', '&', $qs ); # make & to &
echo $this->before_insert;
$nickname = '';
########
# For your INTRANET:
# Get a hint about the users' name
# user defined callback function checks remote_user or similar server variable of the intranet
#
if( strlen( trim( $this->onalias ) ) > 0 and function_exists( $this->onalias ) )
{
$nickname = eval( 'return('.$this->onalias.'('.$this->id_for.', \''.$this->code_for."'));");
}
echo "<table summary='' width='100%'><tr><td><big>$this->say_addcomment</big></td><td align='right'>
<a href='$ps?$qs#comments'>$this->say_close</a></td></tr></table>
<div class='commentinput'><form action='$ps?$qs#comments' method='POST'>";
if( $this->show_alias )
{
echo "
<label for='idname'>$this->say_nickname</label>";
if( $this->edit_alias )
{
echo "
<input type='text' name='nickname' id='idname' size='15' maxlength='15' value='$nickname'><br>";
}
else
{
echo "
<span id='idname'>$nickname</span><input type='hidden' name='nickname' value='$nickname'><br>";
}
}
else
{
echo "
<input type='hidden' name='nickname' value='$nickname'>";
}
echo "
<label for='idcomm'>$this->say_comment</label>
<textarea name='comment' id='idcomm' rows='$this->comment_rows' cols='$this->comment_cols'></textarea><br>
<input type='hidden' name='savecomment' value='1'>
<label for='idsubm'> </label><input type='submit' name='btn' value='$this->say_submit' id='idsubm'>
</form></div>";
echo $this->after_insert;
}
echo '<br>';
} // eof comment::inputbox
/**
* Execute a mysql or mssql or whateversql statement.
* Take any number of arguments.
* First arg is name of sql-function to execute:
* say "query" for mysql_query or mssql_query
* Second and following args are params for sql-function.
*
* @param variing multiple
* @return resource sql result
*/
function execute( )
{
$this->funcname = 'execute';
$numargs = func_num_args();
if( $numargs > 0 )
{
$args = func_get_args();
$func = $args[0].'(';
if( strpos( "+$func", '@' ) === false )
{
$at = '';
}
else
{
$at = '@';
$func = substr( $func,1 );
}
$func = $at . $this->SQLTYPE.'_'.$func;
$anz = count( $args );
for( $i = 1; $i < $anz; $i++ )
{
$func = str_replace( '"',"'",$func );
if( is_resource($args[$i]) )
{
$varname = 'resource'.$i;
global $$varname;
$$varname = $args[$i];
$func .= '$'.$varname;
}
else
{
$func .= '"'. $args[$i].'"';
}
if( $i < ( $anz-1 ) ) $func .= ','; // Separate entries with a comma
}
$func .= ')'; // close bracket
$s = 'return( '.$func.');';
if( $this->debug) echo "<br>eval: $s";
$val = eval( $s );
if( $this->debug ) echo "<br>$s => $val<br>";
}
return $val;
} // eof comment::execute()
/**
* UDF for sqltable column "datetime"
* Used to arrange multiple columns into one cell
* @param string $a = original cell value
* @param object $sqlrowvars = key-value-paired array
* @param object $myself = initialized object of comment ($this)
*/
function udf_commentsarrangedata($a, $sqlrowvars, $myself)
{
static $counter = 1;
global $_SERVER;
#
# top row of comment contains nickname and dates
#
$s1 = '<a name="comment'.$counter.'"></a><div class="commenttopbar">'.
'<table width="100%" summary="commentheadline"><tr><td class="commentnickname">'.
($myself->show_alias ? $sqlrowvars['nickname'] : '' ).
'</td><td align="right" class="commentdatetime">'.$myself->say_entered.': '.
$sqlrowvars['datetime'].'<br>';
if( $sqlrowvars['lastchanged'] <> $sqlrowvars['datetime'] )
{
$changed = substr( $sqlrowvars['lastchanged'], 10 );
$s1 .= $myself->say_lastchanged.': '.$changed;
}
$s1 .= '</td></tr></table></div>';
$text = $sqlrowvars['comment'];
$edit = 0;
$today = date( 'Y-m-d' );
$ps = $_SERVER['PHP_SELF'];
$qs = $_SERVER['QUERY_STRING'];
#
# The following avoids when tidying the generation of &amp;
#
$qs = str_replace( '&','&', $qs ); # make & to &
$qs = str_replace( '&', '&', $qs ); # make & to &
#
# Check if the useragent, date, ip and nickname fit together.
# If yes, then let the user edit his input.
# Otherwise, just display the text.
#
if( strpos( '@'.$sqlrowvars['datetime'], $today ) > 0 )
{
if( $_SERVER['REMOTE_ADDR'] == $sqlrowvars['ip'] )
{
if( $_SERVER['HTTP_USER_AGENT'] == $sqlrowvars['user_agent'] )
{
$edit = 1;
}
}
}
$begin = '<div class="comment">';
if( $edit == 1 )
{
$s = "<form action='$ps?$qs#comment$counter' method='POST'>
<textarea name='comment' rows='$myself->comment_rows' cols='$myself->comment_cols'>$text</textarea>
<input type='hidden' name='id_comment' value='".$sqlrowvars['id']."'>
<input type='hidden' name='updatecomment' value='1'>
<input type='submit' name='btn' value='$myself->say_update'>
</form>";
}
else
{
$s = '<span>'.$text.'</span>'; // span for css
}
$end = '</div>';
$counter ++; // increase at each row
return $begin.$s1.$s.$end;
} // eof udf for sqltable comment::udf_commentsarrangedata
/**
* count() only displays $this->say_comments along with
* the number of comments and does
* nothing else. No links. No lights.
*/
function count()
{
echo $this->say_comments.': '.$this->getcount();
} // eof comment::count()
/**
* How much is inside? See www.cockeyed.com for the answer.
* Get the count of comments
* for $this->code_for and $this->id_for
* @return integer
*/
function getcount()
{
$result = 0;
$query = 'select count(*) from comments where id_for=\''.$this->id_for.
'\' and code_for=\''.$this->code_for.'\'';
$r = $this->execute('query', $query );
if( $r and $this->execute( 'num_rows', $r ) == 1 )
{
list( $result ) = $this->execute( 'fetch_row', $r );
$this->execute( 'free_result' , $r );
}
return $result;
} // eof comment::getcount()
/**
* Make the sql return an ISO date YYYY-MM-DD HH:II:SS which is always the
* case for mysql, afaik but you need to convert things for mssql
* @param string $which = name of the date field
* @return string sqlstatement
*/
function sqlisodate($which, $as = true)
{
$result = $which; // for mysql
$lb = $this->SQLTYPE == 'mssql' ? '[' : '';
$rb = $lb == '[' ? ']' : '';
switch( $this->SQLTYPE )
{
case 'mssql':
$result = 'convert( varchar, '.$lb.$which.$rb.', 20 ) ';
if( $as ) $result .= 'as '.$lb.$which.$rb;
break;
# put other SQLTYPEs here
}
return $result;
} // eof comment::sqlisodate()
/**
* if prevent_multiple is ON, then this function will stop
* a client from entering multiple comments
*
* @return boolean true if the client did already
*/
function client_made_comment_today()
{
#
# Test to see if the client already has made a comment
# - does the "client" (= ip + user_agent)
# - today (front part of datetime)
# - about this subject (code_for, id_for)
# - have a comment in the table?
#
global $_SERVER;
$count = 0;
$ip = $_SERVER['REMOTE_ADDR'];
$ua = $_SERVER['HTTP_USER_AGENT'];
$today = date( 'Y-m-d' ).'%';
$dt = $this->sqlisodate( 'datetime', false );
$query = 'select count(*) from comments where '.
"code_for='$this->code_for' and id_for='$this->id_for'".
" and $dt like '$today' and ip='$ip' and user_agent='$ua' ";
if( $this->debug ) echo "<pre>$query</pre>";
$r = $this->execute('query', $query );
if( $r and $this->execute( 'num_rows', $r ) == 1 )
{
list( $count ) = $this->execute( 'fetch_row', $r );
$this->execute( 'free_result', $r );
}
return ( $count > 0 ? true : false );
} // eof comment::client_made_comment_today()
/**
* Anti "drugs guestbook spam"
* Kill string completely if there is an indicator for a link inside!
* @param string $s = string to test
* @return string
*/
function checkspam( $s )
{
if( $this->prevent_spam )
{
# link found ?
if( strpos( $s, '://' ) > 0 )
{
$s = $this->say_nolinks;
}
}
return $s;
} // eof comment::checkspam()
} // eoc comment
?>