Source for file _comment.class.php
Documentation is available at _comment.class.php
* This file implements the Comment class.
* This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
* See also {@link http://sourceforge.net/projects/evocms/}.
* @copyright (c)2003-2006 by Francois PLANQUE - {@link http://fplanque.net/}.
* Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.
* @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
* {@internal Open Source relicensing agreement:
* Daniel HAHLER grants Francois PLANQUE the right to license
* Daniel HAHLER's contributions to this file and the b2evolution project
* under any OSI approved OSS license (http://www.opensource.org/licenses/).
* {@internal Below is a list of authors who have contributed to design/coding of this file: }}
* @author blueyed: Daniel HAHLER.
* @author fplanque: Francois PLANQUE
* @version $Id: _comment.class.php,v 1.38.2.10 2007/03/22 00:04:16 blueyed Exp $
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
require_once dirname(__FILE__
).
'/../dataobjects/_dataobject.class.php';
* The item (parent) of this Comment (lazy-filled).
* @see Comment::get_Item()
* @see Comment::set_Item()
* @var integer The ID of the comment's Item.
* The comment's user, this is NULL for (anonymous) visitors (lazy-filled).
* @see Comment::get_author_User()
* @see Comment::set_author_User()
* @var integer|NULLThe ID of the author's user. NULL for anonymous visitors.
* @var string Comment type: 'comment', 'linkback', 'trackback' or 'pingback'
* @var string Comment visibility status: 'published', 'deprecated', 'protected', 'private' or 'draft'
* @var string Name of the (anonymous) visitor (if any).
* @var string Email address of the (anonymous) visitor (if any).
* @var string URL/Homepage of the (anonymous) visitor (if any).
* @var string IP address of the comment's author (while posting).
* @var string Date of the comment (MySQL DATETIME - use e.g. {@link mysql2timestamp()}); local time ({@link $localtimenow})
* @var integer Spam karma of the comment (0-100), 0 being "probably no spam at all"
* @var boolean Does an anonymous commentator allow to send messages through a message form?
// Call parent constructor:
parent::DataObject( 'T_comments', 'comment_', 'comment_ID' );
$this->ID =
$db_row['comment_ID'];
$this->item_ID =
$db_row['comment_post_ID'];
if( ! empty($db_row['comment_author_ID']) )
$this->author_user_ID =
$db_row['comment_author_ID'];
$this->type =
$db_row['comment_type'];
$this->status =
$db_row['comment_status'];
$this->author =
$db_row['comment_author'];
$url =
trim( $db_row['comment_author_url'] );
if( ! empty($url) &&
! preg_match( '~^\w+://~', $url ) )
{ // URL given and does not start with a protocol:
$this->author_IP =
$db_row['comment_author_IP'];
$this->date =
$db_row['comment_date'];
$this->content =
$db_row['comment_content'];
$this->spam_karma =
$db_row['comment_spam_karma'];
* Get the author User of the comment. This is NULL for anonymous visitors.
if( isset
($this->author_user_ID) &&
! isset
($this->author_User) )
$this->author_User =
& $UserCache->get_by_ID( $this->author_user_ID );
* Get the Item this comment relates to
if( ! isset
($this->Item) )
$this->Item =
& $ItemCache->get_by_ID( $this->item_ID );
* Get a member param by its name
* @param mixed Name of parameter
* @return mixed Value of parameter
return T_( $post_statuses[$this->status] );
return parent::get( $parname );
* @param string parameter name
* @param mixed parameter value
* @return boolean true, if a value has been set; false if it has not changed
function set( $parname, $parvalue )
return parent::set_param( $parname, 'string', $parvalue );
* Set Item this comment relates to
parent::set_param( 'post_ID', 'number', $Item->ID );
* Set author User of this comment
parent::set_param( 'author_ID', 'number', $author_User->ID );
* Set the spam karma, as a number.
* @param integer Spam karma (-100 - 100)
return parent::set_param( 'spam_karma', 'number', $spam_karma );
* Get the anchor-ID of the comment
* Template function: display anchor for permalinks to refer to
* Get the comment author's name.
* Get the EMail of the comment's author.
* Get the URL of the comment's author.
* Template function: display author of comment
* @param string String to display before author name if not a user
* @param string String to display after author name if not a user
* @param string String to display before author name if he's a user
* @param string String to display after author name if he's a user
* @param string Output format, see {@link format_to_output()}
* @param boolean true for link, false if you want NO html link
function author( $before =
'', $after =
'#', $before_user =
'', $after_user =
'#',
$format =
'htmlbody', $makelink =
false )
if( $after_user ==
'#' ) $after_user =
' ['.
T_('Member').
']';
if( $makelink ) $r .=
'</a>';
{ // Display info recorded at edit time:
if( $after ==
'#' ) $after =
' ['.
T_('Visitor').
']';
$r .=
$this->dget( 'author', $format );
if( $makelink ) $r .=
'</a>';
$Plugins->trigger_event( 'FilterCommentAuthor', array( 'data' =>
& $r, 'makelink' =>
$makelink, 'Comment' =>
$this ) );
* Template function: display comment's author's IP
* @param string String to display before IP, if IP exists
* @param string String to display after IP, if IP exists
* Template function: display link to comment author's provided email
* @param string String to display for link: leave empty to display email
* @param string String to display before email, if email exists
* @param string String to display after email, if email exists
* @param boolean false if you want NO html link
function author_email( $linktext=
'', $before=
'', $after=
'', $makelink =
true )
if( $makelink ) echo
'<a href="mailto:'.
$email.
'">';
echo
($linktext !=
'') ?
$linktext :
$email;
if( $makelink ) echo
'</a>';
* Template function: display link to comment author's provided URL
* @param string String to display for link: leave empty to display URL
* @param string String to display before link, if link exists
* @param string String to display after link, if link exists
* @param boolean false if you want NO html link
* @return boolean true if URL has been displayed
function author_url( $linktext=
'', $before=
'', $after=
'', $makelink =
true )
$r .=
'<a href="'.
$url.
'">';
$r .=
( empty($linktext) ?
$url :
$linktext );
if( $makelink ) $r .=
'</a>';
$Plugins->trigger_event( 'FilterCommentAuthorUrl', array( 'data' =>
& $r, 'makelink' =>
$makelink, 'Comment' =>
$this ) );
* Template function: display spam karma of the comment (in percent)
* "%s" gets replaced by the karma value
* @param string Template string to display, if we have a karma value
* @param string Template string to display, if we have no karma value (pre-Phoenix)
function spam_karma( $template =
'%s%', $template_unknown =
NULL )
if( ! isset
($template_unknown) )
echo
/* TRANS: "not available" */ T_('N/A');
* Provide link to edit a comment if user has edit rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
function edit_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'' )
global $current_User, $admin_url;
if( ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) )
{ // If User has no permission to edit comments:
if( $text ==
'#' ) $text =
get_icon( 'edit' ).
' '.
T_('Edit...');
if( $title ==
'#' ) $title =
T_('Edit this comment');
echo
'<a href="'.
$admin_url.
'?ctrl=edit&action=editcomment&comment='.
$this->ID;
echo
'" title="'.
$title.
'"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Displays button for deleeing the Comment if user has proper rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param boolean true to make this a button instead of a link
function delete_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $button =
false )
global $current_User, $admin_url;
if( ! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) )
{ // If User has permission to edit comments:
{ // Use icon+text as default, if not displayed as button (otherwise just the text)
$text =
get_icon( 'delete', 'imgtag' ).
' '.
T_('Delete!');
if( $title ==
'#' ) $title =
T_('Delete this comment');
$url =
$admin_url.
'?ctrl=editactions&action=deletecomment&comment_ID='.
$this->ID;
echo
'<input type="button"';
echo
' value="'.
$text.
'" title="'.
$title.
'" onclick="if ( confirm(\'';
echo
TS_('You are about to delete this comment!\\n\'Cancel\' to stop, \'OK\' to delete.');
echo
'\') ) { document.location.href=\''.
$url.
'\' }"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
echo
'<a href="'.
$url.
'" title="'.
$title.
'" onclick="return confirm(\'';
echo
TS_('You are about to delete this comment!\\n\'Cancel\' to stop, \'OK\' to delete.');
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Provide link to deprecate a comment if user has edit rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
* @param boolean save context?
function get_deprecate_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&', $save_context =
false )
global $current_User, $admin_url;
if( ($this->status ==
'deprecated') // Already deprecateded!
||
! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) )
{ // If User has permission to edit comments:
if( $text ==
'#' ) $text =
get_icon( 'deprecate', 'imgtag' ).
' '.
T_('Deprecate!');
if( $title ==
'#' ) $title =
T_('Deprecate this comment!');
$r .=
$admin_url.
'?ctrl=editactions'.
$glue.
'action=deprecate_comment'.
$glue.
'comment_ID='.
$this->ID;
$r .=
'" title="'.
$title.
'"';
if( !empty( $class ) ) $r .=
' class="'.
$class.
'"';
* Display link to deprecate a comment if user has edit rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
* @param boolean save context?
function deprecate_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&', $save_context =
false )
echo
$this->get_deprecate_link( $before, $after, $text, $title, $class, $glue, $save_context );
* Provide link to publish a comment if user has edit rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
* @param boolean save context?
function get_publish_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&', $save_context =
false )
global $current_User, $admin_url;
if( ($this->status ==
'published') // Already published!
||
! $current_User->check_perm( 'blog_comments', '', false, $this->Item->get( 'blog_ID' ) ) )
{ // If User has permission to edit comments:
if( $text ==
'#' ) $text =
get_icon( 'publish', 'imgtag' ).
' '.
T_('Publish!');
if( $title ==
'#' ) $title =
T_('Publish this comment!');
$r .=
$admin_url.
'?ctrl=editactions'.
$glue.
'action=publish_comment'.
$glue.
'comment_ID='.
$this->ID;
$r .=
'" title="'.
$title.
'"';
if( !empty( $class ) ) $r .=
' class="'.
$class.
'"';
* Display link to publish a comment if user has edit rights
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
* @param string glue between url params
* @param boolean save context?
function publish_link( $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'', $glue =
'&', $save_context =
false )
echo
$this->get_publish_link( $before, $after, $text, $title, $class, $glue, $save_context );
* Provide link to message form for this comment's author
* @param string url of the message form
* @param string to display before link
* @param string to display after link
* @param string link text
* @param string link title
* @param string class name
function msgform_link( $form_url, $before =
' ', $after =
' ', $text =
'#', $title =
'#', $class =
'' )
{ // This comment is from a registered user:
{ // We have no email for this Author :(
{ // User does not allow message form
{ // This comment is from a visitor:
{ // We have no email for this comment :(
{ // Anonymous commentator does not allow message form (for this comment)
if( $title ==
'#' ) $title =
T_('Send email to comment author');
if( $text ==
'#' ) $text =
get_icon( 'email', 'imgtag', array( 'class' =>
'middle', 'title' =>
$title ) );
echo
'<a href="'.
$form_url.
'" title="'.
$title.
'"';
if( !empty( $class ) ) echo
' class="'.
$class.
'"';
* Generate permalink to this comment.
* Note: This actually only returns the URL, to get a real link, use Comment::get_permanent_link()
* @param string 'urltitle', 'pid', 'archive#id' or 'archive#title'
* @param string url to use
$mode =
$Settings->get( 'permalink_type' );
// some permalink modes are not acceptable here:
* Template function: display permalink to this comment
* Note: This actually only returns the URL, to get a real link, use Comment::permanent_link()
* @param string 'urltitle', 'pid', 'archive#id' or 'archive#title'
* @param string url to use
* Returns a permalink link to the Comment
* Note: If you only want the permalink URL, use Comment::get_permanent_url()
* @param string link text or special value: '#', '#icon#', '#text#'
* @param string link title
* @param string class name
global $current_User, $baseurl;
if( $title ==
'#' ) $title =
T_('Permanent link to this comment');
$r =
'<a href="'.
$url.
'" title="'.
$title.
'"';
if( !empty( $class ) ) $r .=
' class="'.
$class.
'"';
* Displays a permalink link to the Comment
* Note: If you only want the permalink URL, use Comment::permanent_url()
* @param string link text
* @param string link title
* @param string class name
* Template function: get content of comment
* @param string Output format, see {@link format_to_output()}
$Plugins->trigger_event( 'FilterCommentContent', array( 'data' =>
& $comment, 'Comment' =>
$this ) );
* Template function: display content of comment
* @param string Output format, see {@link format_to_output()}
function content( $format =
'htmlbody' )
* Template function: display date (datetime) of comment
* @param string date/time format: leave empty to use locale default date format
* @param boolean true if you want GMT
function date( $format=
'', $useGM =
false )
* Template function: display time (datetime) of comment
* @param string date/time format: leave empty to use locale default time format
* @param boolean true if you want GMT
function time( $format=
'', $useGM =
false )
* Template function: display status of comment
* @param string Output format, see {@link format_to_output()}
function status( $format =
'htmlbody' )
$this->disp( 'status', 'raw' );
* Send email notifications to subscribed users:
* @todo shall we notify suscribers of blog were this is in extra-cat?
* @todo cache message by locale like {@link Item::send_email_notifications()}
* @todo Indicator in url to see where the user came from (&from=subnote ["subscription notification"]) - Problem: too long urls.
* @todo "Beautify" like {@link Item::send_email_notifications()} ?
* @todo Should include "visibility status" in the mail to the Item's Author
// Get list of users who want to be notfied:
// TODO: also use extra cats/blogs??
// So far you get notifications for everything. We'll need a setting to decide if you want to received unmoderated (aka unpublished) comments or not.
// Note: users receive comments on their own posts. This is done on purpose. Otherwise they think it's broken when they test the app.
$sql =
'SELECT DISTINCT user_email, user_locale
FROM T_subscriptions INNER JOIN T_users ON sub_user_ID = user_ID
AND LENGTH(TRIM(user_email)) > 0';
$notify_list =
$DB->get_results( $sql );
foreach( $notify_list as $notification )
$notify_array[$notification->user_email] =
$notification->user_locale;
// Check if we need to add the author:
if( $item_author_User->notify
&&
( ! empty( $item_author_User->email ) ) )
{ // Author wants to be notified:
$notify_array[$item_author_User->email] =
$item_author_User->locale;
if( ! count($notify_array) )
* We have a list of email addresses to notify:
{ // Comment from a registered user:
elseif( empty( $email ) )
$mail_from =
$notify_from;
foreach( $notify_array as $notify_email =>
$notify_locale )
/* TRANS: Subject of the mail to send on new trackbacks. First %s is the blog's shortname, the second %s is the item's title. */
$subject =
T_('[%s] New trackback on "%s"');
/* TRANS: Subject of the mail to send on new comments. First %s is the blog's shortname, the second %s is the item's title. */
$subject =
T_('[%s] New comment on "%s"');
$subject =
sprintf( $subject, $Blog->get('shortname'), $this->Item->get('title') );
$notify_message =
T_('Blog').
': '.
$Blog->get('shortname')
.
' ( '.
str_replace('&', '&', $Blog->get('blogurl')).
" )\n"
// We use pid to get a short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking
$notify_message .=
T_('Website').
": $this->author (IP: $this->author_IP, $user_domain)\n";
{ // Comment from a registered user:
{ // Comment from visitor:
$notify_message .=
T_('Author').
": $this->author (IP: $this->author_IP, $user_domain)\n";
T_('Comment').
': '.
str_replace('&', '&', $this->get_permanent_url( 'pid' )).
"\n" // We use pid to get a short URL and avoid it to wrap on a new line in the mail which may prevent people from clicking
.
$this->get('content').
"\n\n"
.
T_('Edit/Delete').
': '.
$admin_url.
'?ctrl=browse&tab=posts&blog='.
$this->Item->blog_ID.
'&p='.
$this->Item->ID.
"&c=1\n\n"
.
T_('Edit your subscriptions/notifications').
': '.
str_replace('&', '&', url_add_param( $Blog->get( 'blogurl' ), 'disp=subs' ) ).
"\n";
$mail_dump =
"Sending notification to $notify_email:<pre>Subject: $subject\n$notify_message</pre>";
{ // output mail content - NOTE: this will kill sending of headers.
echo
"<p>DEGUG>=3 dump:</p>$mail_dump";
$Debuglog->add( $mail_dump, 'notification' );
send_mail( $notify_email, $subject, $notify_message, $mail_from );
* Trigger event AfterCommentUpdate after calling parent method.
* @return boolean true on success
$dbchanges =
$this->dbchanges;
$Plugins->trigger_event( 'AfterCommentUpdate', $params =
array( 'Comment' =>
& $this, 'dbchanges' =>
$dbchanges ) );
* Get karma and set it before adding the Comment to DB.
* @return boolean true on success, false if it did not get inserted
// Get karma percentage (interval -100 - 100)
$spam_karma =
$Plugins->trigger_karma_collect( 'GetSpamKarmaForComment', array( 'Comment' =>
& $this ) );
// Change status accordingly:
if( $spam_karma <
$Settings->get('antispam_threshold_publish') )
$this->set( 'status', 'published' );
elseif( $spam_karma >
$Settings->get('antispam_threshold_delete') )
$dbchanges =
$this->dbchanges;
$Plugins->trigger_event( 'AfterCommentInsert', $params =
array( 'Comment' =>
& $this, 'dbchanges' =>
$dbchanges ) );
* Trigger event AfterCommentDelete after calling parent method.
* @return boolean true on success
// remember ID, because parent method resets it to 0
// re-set the ID for the Plugin event
$Plugins->trigger_event( 'AfterCommentDelete', $params =
array( 'Comment' =>
& $this ) );
* $Log: _comment.class.php,v $
* Revision 1.38.2.10 2007/03/22 00:04:16 blueyed
* MFH: Escape author_url and author_User->url in author_url() template function
* Revision 1.38.2.9 2007/01/21 20:13:57 fplanque
* MFH: comments http:// issue
* Revision 1.38.2.8 2006/11/23 01:59:07 fplanque
* Revision 1.38.2.7 2006/11/17 22:36:42 blueyed
* MFH: dbchanges param for AfterItemUpdate, AfterItemInsert, AfterCommentUpdate and AfterCommentInsert
* Revision 1.38.2.6 2006/11/04 19:54:53 fplanque
* Reinjected old Log blocks. Removing them from CVS was a bad idea -- especially since Daniel has decided branch 1.9 was his HEAD...
* Revision 1.38 2006/07/26 17:15:44 blueyed
* Replaced "name" attribute with "id" for anchors
* Revision 1.37 2006/07/04 17:32:29 fplanque
* Revision 1.36 2006/06/22 18:37:47 fplanque
* Revision 1.35 2006/05/30 20:32:56 blueyed
* Lazy-instantiate "expensive" properties of Comment and Item.
* Revision 1.34 2006/05/19 18:15:05 blueyed
* Merged from v-1-8 branch
* Revision 1.33.2.1 2006/05/19 15:06:24 fplanque
* Revision 1.33 2006/05/04 10:05:39 blueyed
* Fixed anchor in notification mails and shortened again, because of length.. probably it does not make sense to have get_anchor() anyway.. dunno..
* Revision 1.32 2006/05/04 04:07:24 blueyed
* After posting a comment, add the anchor to the redirect param; also use more distinctive anchor name for comments
* Revision 1.31 2006/05/02 04:36:24 blueyed
* Spam karma changed (-100..100 instead of abs/max); Spam weight for plugins; publish/delete threshold
* Revision 1.30 2006/05/02 01:27:55 blueyed
* Moved nofollow handling to basic antispam plugin; added Filter events to Comment class
* Revision 1.29 2006/05/01 22:20:20 blueyed
* Made rel="nofollow" optional (enabled); added Antispam settings page
* Revision 1.28 2006/04/29 23:27:10 blueyed
* Only trigger update/insert/delete events if parent returns true
* Revision 1.27 2006/04/24 15:43:35 fplanque
* Revision 1.26 2006/04/21 23:14:16 blueyed
* Add Messages according to Comment's status.
* Revision 1.25 2006/04/21 18:10:53 blueyed
* Revision 1.24 2006/04/20 00:00:21 blueyed
* Fixed delete-link-button
* Revision 1.23 2006/04/19 22:08:16 blueyed
* Revision 1.22 2006/04/19 19:52:27 blueyed
* url-encode redirect_to param
* Revision 1.21 2006/04/19 13:05:21 fplanque
* Revision 1.20 2006/04/18 20:17:25 fplanque
* fast comment status switching
* Revision 1.19 2006/04/18 19:29:51 fplanque
* basic comment status implementation
* Revision 1.18 2006/03/28 22:24:46 blueyed
* Fixed logical spam karma issues
* Revision 1.17 2006/03/28 14:12:19 fplanque
* Revision 1.16 2006/03/23 22:13:50 blueyed
* Revision 1.15 2006/03/19 17:54:26 blueyed
* Opt-out for email through message form.
* Revision 1.14 2006/03/18 23:38:44 blueyed
* Decent getters; allow_msgform added
* Revision 1.13 2006/03/18 19:17:53 blueyed
* Removed remaining use of $img_url
* Revision 1.12 2006/03/12 23:08:58 fplanque
* Revision 1.11 2006/03/12 20:58:59 blueyed
* Revision 1.9 2006/03/11 21:50:16 blueyed
* Display spam_karma with comments
* Revision 1.8 2006/03/11 12:45:54 blueyed
* Revision 1.6 2006/03/09 22:29:59 fplanque
* cleaned up permanent urls
* Revision 1.5 2006/03/09 21:58:52 fplanque
* Revision 1.4 2006/03/09 15:23:26 fplanque
* Revision 1.3 2006/03/06 20:03:40 fplanque
* Revision 1.1 2006/02/23 21:11:57 fplanque
* File reorganization to MVC (Model View Controller) architecture.
* See index.hml files in folders.
* (Sorry for all the remaining bugs induced by the reorg... :/)
* Revision 1.24 2006/01/29 20:36:35 blueyed
* Renamed Item::getBlog() to Item::get_Blog()
* Revision 1.23 2006/01/26 23:08:35 blueyed
* Revision 1.22 2005/12/12 19:21:21 fplanque
* big merge; lots of small mods; hope I didn't make to many mistakes :]
* Revision 1.21 2005/12/11 19:59:51 blueyed
* Renamed gen_permalink() to get_permalink()
* Revision 1.20 2005/11/04 21:42:22 blueyed
* Use setter methods to set parameter values! dataobject::set_param() won't pass the parameter to dbchange() if it is already set to the same member value.
* Revision 1.19 2005/11/04 18:30:59 fplanque
* Revision 1.18 2005/11/04 13:50:57 blueyed
* Dataobject::set_param() / set(): return true if a value has been set and false if it did not change. It will not get considered for dbchange() then, too.
* Revision 1.17 2005/10/07 20:18:57 blueyed
* Revision 1.16 2005/10/03 17:26:44 fplanque
* synched upgrade with fresh DB;
* Revision 1.15 2005/09/29 15:07:30 fplanque
* Revision 1.14 2005/09/06 17:13:54 fplanque
* stop processing early if referer spam has been detected
* Revision 1.13 2005/08/30 18:26:04 fplanque
* Revision 1.12 2005/08/09 15:22:40 fplanque
* Revision 1.11 2005/08/08 22:35:56 blueyed
* DEbuglog for send_email_notifications(), whitespace/code layout.
* Revision 1.10 2005/05/25 18:31:01 fplanque
* implemented email notifications for new posts
* Revision 1.9 2005/05/25 17:13:33 fplanque
* implemented email notifications on new comments/trackbacks
* Revision 1.8 2005/04/28 20:44:20 fplanque
* Revision 1.7 2005/04/12 18:58:16 fplanque
* use TS_() instead of T_() for JavaScript strings
* Revision 1.6 2005/04/07 17:55:50 fplanque
* Revision 1.5 2005/03/06 16:30:40 blueyed
* deprecated global table names.
* Revision 1.4 2005/02/28 09:06:32 blueyed
* removed constants for DB config (allows to override it from _config_TEST.php), introduced EVO_CONFIG_LOADED
* Revision 1.3 2004/12/09 21:21:19 fplanque
* introduced foreign key support
* Revision 1.2 2004/10/14 18:31:25 blueyed
* Revision 1.1 2004/10/13 22:46:32 fplanque
* Revision 1.33 2004/10/11 19:13:14 fplanque
* Edited code documentation.
* Revision 1.32 2004/10/11 19:02:04 fplanque
* Edited code documentation.