flatpress/fp-plugins/commentcenter/plugin.commentcenter.php

444 lines
12 KiB
PHP

<?php
/*
Plugin Name: Flatpress Comment Center
Version: 1.1.1.azifix
Plugin URI: http://www.vdfn.altervista.org/redirect/plugin_commentcenter.html
Description: This plugin is a Comment Center for Flatpress
Author: Piero VDFN
Author URI: http://www.vdfn.altervista.org/
*/
/**
* This class interacts with Flaptress comment system.
*/
class plugin_commentcenter {
# The plugin configuration
var $conf=array();
# The policies
var $policies=array();
# The plugin_dir
var $pl_dir='fp-content/plugin_commentcenter/';
/**
* This is the constructor.
*/
function __construct() {
add_action('entry_block', array(&$this, 'lock'));
add_filter('comment_validate', array(&$this, 'validate'), 5, 2);
$this->pl_dir=FP_CONTENT.'plugin_commentcenter/';
if(!file_exists($this->pl_dir)) {
fs_mkdir($this->pl_dir);
}
}
/**
* This function loads the configuration of the plugin.
*
* @param boolean $foce: Force to load it?
* @return array: The configuration
*/
function getConf($force=false) {
if(!empty($this->conf) && $force) {
return $this->conf;
}
$this->conf=plugin_getoptions('commentcenter');
return $this->conf;
}
/**
* This function check if comment must be locked.
*/
function lock() {
global $fp_params, $post, $smarty;
$this->loadPolicies();
$cats=is_array($post['categories']) ? $post['categories'] : array();
$behavoir=$this->behavoirFromPolicies($fp_params['entry'], $cats);
if($behavoir==-1 && !user_loggedin()) {
$smarty->assign('entry_commslock', true);
}
}
/**
* This function validates a comment.
*
* @param boolean $status: The current status of the comment validation
* @param array $comment: The comment data
* @return boolean: Is the comment valid?
*/
function validate($status, $comment) {
global $smarty, $fp_params, $lang;
# If the comment has been already stopped or this is the contact page, stop here our check
if(!$status || function_exists('contact_display')) {
return $status;
}
# If the comment has been made from an administrator, don't check it
if(@$comment['loggedin']) {
return true;
}
$entry=$fp_params['entry'];
if (!isset($comment['date'])) {
$comment['date'] = date_time();
}
$comment['id']=bdb_idfromtime(BDB_COMMENT, $comment['date']);
$conf=$this->getConf();
# This variables defines how the system has to behave.
$behavoir=1;
$this->loadPolicies();
# To get categories of the entry, we use the same method of PrettyURLs...
global $post;
$behavoir=$this->behavoirFromPolicies($entry, $post['categories']);
// If comments are locked we don't send to Akismet
if(@$conf['akismet_check'] && $behavoir!=-1) {
$akismet=$this->akismetCheck($comment, $entry);
if(!$akismet) {
$smarty->append('error', $lang['plugin']['commentcenter']['akismet_error']);
$this->logComment($comment, $entry, 'akismet');
return false;
}
}
if($behavoir==0) {
$this->logComment($comment, $entry, 'confirm');
$smarty->append('warnings', $lang['plugin']['commentcenter']['approvation']);
if(@$conf['email_alert']) {
$this->commentMail($comment, $post['subject']);
}
} elseif($behavoir==-1 && @$conf['log_all']) {
$this->logComment($comment, $entry, 'denided');
$smarty->append('error', $lang['plugin']['commentcenter']['lock']);
}
if($behavoir!=1) {
// Delete the comment content
$_POST['content']='';
}
# Also if the comment need to be approved, we return false.
return $behavoir==1;
}
/**
* This function create an akismet instance.
* An Akismet object is returned by reference. But if an error
* happens, the function return a negative integer:
* -1 if we can't find the key
* -2 if we can't contact Akismet servers
* -3 if the response failed
* -4 if the key isn't valid
*
* @param string $key: A key for the service
* @return object: The akismet object
*/
function &akismetLoad($key='') {
$conf=$this->getConf();
if(!empty($key)) {
} elseif(empty($conf['akismet_key'])) {
$e=-1;
return $e;
} else {
$key=$conf['akismet_key'];
}
$url=empty($conf['akismet_url']) ? BLOG_BASEURL : $conf['akismet_url'];
include_once dirname(__FILE__).'/inc/akismet.class.php';
$akismet=new Akismet($url, $key);
if($akismet->errorsExist()) {
$e=0;
switch(true) {
case $akismet->isError(AKISMET_SERVER_NOT_FOUND):
$e=-2;
break;
case $akismet->isError(AKISMET_RESPONSE_FAILED):
$e=-3;
break;
case $akismet->isError(AKISMET_INVALID_KEY):
$e=-4;
break;
}
return $e;
} else {
return $akismet;
}
}
/**
* This function clean a comment to send it to Akismet.
*
* @param array $comment: The comment data
* @param string $entry: The entry id
* @return array: $comment cleaned
*/
function akismetClean($comment, $entry) {
global $post;
$conf=$this->getConf();
$oldpost=$post;
$o=new FPDB_Query("id:{$entry},fullparse:false", null);
$arr=$o->getEntry();
$post=$arr[1];
$link=get_permalink($entry);
if(!empty($conf['akismet_url'])) {
$link=$conf['akismet_url'].substr($link, strlen(BLOG_BASEURL));
}
$post=$oldpost;
$clean=array(
'author'=>$comment['name'],
'email'=>@$comment['email'],
'website'=>@$comment['url'],
'body'=>$comment['content'],
'user_ip'=>@$comment['ip-address'],
'permalink'=>$link
);
return $clean;
}
/**
* This function manages the Akismet Check
*
* @param array $comment: The comment data
* @param string $entry: The entry id
* @return boolean: Is the comment allowed?
*/
function akismetCheck($comment, $entry) {
$akismet=&$this->akismetLoad();
if(!is_object($akismet)) {
# Failed to load it. We return true, but the comment isn't checked
// TODO: Add an error logger? Or make different, configurable behaves?
return true;
}
$clean=$this->akismetClean($comment, $entry);
$akismet->setComment($clean);
if($akismet->isSpam()) {
# Akismet sign the comment as spam. Let's stop it.
return false;
} else {
return true;
}
}
/**
* This function loads the comment policies.
*
* @param boolean $force: Force to load them?
* @return array: The policies
*/
function &loadPolicies($force=false) {
if(!$force && !empty($this->policies)) {
return $this->policies;
}
if(!file_exists($f=$this->pl_dir.'policies.txt')) {
$this->policies=array();
return $this->policies;
}
include $f;
$this->policies=$policies;
return $this->policies;
}
/**
* This function saves the policies.
*
* @return boolean
*/
function savePolicies() {
$this->policies=array_values($this->policies);
return system_save($this->pl_dir.'policies.txt', array('policies'=>$this->policies));
}
/**
* This function adds a policy in a certain position.
*
* @param mixed $policy: The policy
* @param integer $position: The position
*/
function addPolicyAt($policy, $position) {
if($position<0) {
$position=count($this->policies)+$position+1;
}
$before=array_slice($this->policies, 0, $position);
$after=array_slice($this->policies, $position);
$this->policies=array_merge($before, array($policy), $after);
}
/**
* This function moves a policy from a postition to another one.
*
* @param integer $old: The old position
* @param integer $new: The new position
*/
function policyMove($old, $new) {
if(!isset($this->policies[$old])) {
return false;
}
$new=$new>$old ? $new+1 : $new;
$del=$new>$old ? $old : $old+1;
$this->addPolicyAt($this->policies[$old], $new);
if(isset($this->policies[$del])) {
unset($this->policies[$del]);
}
$this->policies=array_values($this->policies);
return true;
}
/**
* Get behavoir from policies.
* 1: The user can comment
* 0: The comment need to be approved
* -1: The user can't comment
*
* @param string $entry: The entry id
* @param array $cats: The categories
* @return integer: The behavoir
*/
function behavoirFromPolicies($entry, $cats=array()) {
$date=date_from_id($entry);
$time=$date['time'];
$return=1;
$pols=&$this->policies;
if(count($pols)) {
foreach($pols as $policy) {
if(@$policy['is_all']) {
$return=$policy['do'];
} elseif(!empty($policy['entry']) && is_array($policy['entry'])) {
if(in_array($entry, $policy['entry'])) {
$return=$policy['do'];
}
} elseif(!empty($policy['entry'])) {
if($entry==$policy['entry']) {
$return=$policy['do'];
}
} else {
$consider=true;
if(!empty($policy['categories'])) {
$consider=count(array_intersect($policy['categories'], $cats))>0;
}
if(!empty($policy['older'])) {
$consider=(time()-$time)>$policy['older'];
} else {
if(!empty($policy['time_less'])) {
$consider=$time>$policy['time_less'];
}
if(!empty($policy['time_more'])) {
$consider=$time<$policy['time_more'];
}
}
$return=$consider ? $policy['do'] : $return;
}
}
}
return $return;
}
/**
* This function saves a comment into the plugin directory.
* Maybe it's considered SPAM by Akismet or the comment requires
* the Administrator's approvation.
*
* @param array $comment: The comment data
* @param string $entry: The entry id
* @param string $why: The reason of the log
* @return boolean: Can it saves the log?
*/
function logComment($comment, $entry, $why='') {
$f=$this->pl_dir."e{$entry}_c{$comment['id']}.txt";
if(!empty($why)) {
$comment['log_reason']=$why;
}
return system_save($f, array('comment'=>$comment));
}
/**
* This function send an email to the administrator with the comment data.
* It's based on the code of comment.php
*
* @param array $comment: The comment data
* @param string $entry_title: The title of the entry
* @return boolean
*/
function commentMail($comment, $entry_title) {
global $lang, $fp_config;
$subject=$lang['plugin']['commentcenter']['mail_subj'];
$subject=sprintf($subject, $fp_config['general']['title']);
$comm_mail=empty($comment['email'])? '' : "<{$comment['email']}>";
$from_mail=$fp_config['general']['email'];
$text=$lang['plugin']['commentcenter']['mail_text'];
$text=str_replace(array('%toname%', '%fromname%', '%frommail%',
'%entrytitle%', '%content%', '%blogtitle%'
), array($fp_config['general']['author'], $comment['name'], $comm_mail,
$entry_title, $comment['content'], $fp_config['general']['title']
), $text
);
return @utils_mail($from_mail, $subject, $text);
}
}
$GLOBALS['plugin_commentcenter']=new plugin_commentcenter();
/**
* This class makes the list of comments that needs to be approved.
*/
class commentcenter_list extends fs_filelister {
/**
* This is the constructor of the class.
*
* @params string $dir: The directory to list
*/
function commentcenter_list($dir) {
parent::__construct($dir);
}
function _checkFile($directory, $file) {
if(fnmatch('eentry*.txt', $file)) {
$entry=substr($file, 1, 18);
$comment=substr($file, 21, 20);
$this->_list[$entry][]=$comment;
}
return 0;
}
function toDetails($entry=null) {
$list=array();
if(!is_null($entry) && @is_array($this->_list[$entry])) {
foreach($this->_list[$entry] as $commentid) {
include $this->_directory."/e{$entry}_c{$commentid}.txt";
if(empty($comment['log_reason'])) {
$comment['log_reason']='nd';
}
$list[$comment['log_reason']][$commentid]=$comment;
}
} else {
foreach($this->_list as $key=>$comments) {
$list[$key]=$this->toDetails($key);
}
}
return $list;
}
}
# If we're in administration area, we load admin panel
if(defined('MOD_ADMIN_PANEL')) {
include dirname(__FILE__).'/inc/admin.php';
include dirname(__FILE__).'/inc/jslang.php';
include dirname(__FILE__).'/inc/editor.php';
}