diff --git a/fp-plugins/commentcenter/imgs/copyright b/fp-plugins/commentcenter/imgs/copyright new file mode 100644 index 0000000..79d1fc4 --- /dev/null +++ b/fp-plugins/commentcenter/imgs/copyright @@ -0,0 +1,70 @@ +This icons are taken from the Tango Icon Theme (packed by Debian). +The package is tango-icon-theme and here's its copyright file. + +============ + +This package was debianized by Daniel Holbach on +Mon, 10 Oct 2005 20:50:20 +0200. + +It was downloaded from http://tango.freedesktop.org/releases/ + +Upstream Authors: 2005-2009 + + Ulisse Perusin + Steven Garrity + Lapo Calamandrei + Ryan Collier + Rodney Dawes + Andreas Nilsson + Tuomas Kuosmanen + Garrett LeSage + Jakub Steiner + +Copyright: + + In the preparation of the 0.8.90 release Novell took care of tracking + down all the contributors to get them to relicense their artwork + into Public Domain. + + The COPYING file of the tarball states the following: + | The icons in this repository are herefore released into the Public Domain. + + Additionally the copyright status of the files was tracked in the CVS and the + rdf properties of the SVGs adjusted for all files that were put into Public + Domain (see rdf:about and rdf:resource). Both fields contain a link to the + Creative Commons Public Domain Dediciation[0] as reproduced below: + | Public Domain Dedication + | + | Copyright-Only Dedication (based on United States law) or Public Domain + | Certification + | + | The person or persons who have associated work with this document (the + | "Dedicator" or "Certifier") hereby either (a) certifies that, to the best + | of his knowledge, the work of authorship identified is in the public + | domain of the country from which the work is published, or (b) + | hereby dedicates whatever copyright the dedicators holds in the work + | of authorship identified below (the "Work") to the public domain. A + | certifier, moreover, dedicates any copyright interest he may have in + | the associated work, and for these purposes, is described as a + | "dedicator" below. + | + | A certifier has taken reasonable steps to verify the copyright + | status of this work. Certifier recognizes that his good faith efforts + | may not shield him from liability if in fact the work certified is not + | in the public domain. + | + | Dedicator makes this dedication for the benefit of the public at + | large and to the detriment of the Dedicator's heirs and successors. + | Dedicator intends this dedication to be an overt act of relinquishment + | in perpetuity of all present and future rights under copyright law, + | whether vested or contingent, in the Work. Dedicator understands that + | such relinquishment of all rights includes the relinquishment of all + | rights to enforce (by lawsuit or otherwise) those copyrights in the + | Work. + | + | Dedicator recognizes that, once placed in the public domain, the Work + | may be freely reproduced, distributed, transmitted, used, modified, + | built upon, or otherwise exploited by anyone for any purpose, commercial + | or non-commercial, and in any way, including by methods that have not + | yet been invented or conceived. + [0] http://creativecommons.org/licenses/publicdomain/ diff --git a/fp-plugins/commentcenter/imgs/delete.png b/fp-plugins/commentcenter/imgs/delete.png new file mode 100644 index 0000000..239d16d Binary files /dev/null and b/fp-plugins/commentcenter/imgs/delete.png differ diff --git a/fp-plugins/commentcenter/imgs/down.png b/fp-plugins/commentcenter/imgs/down.png new file mode 100644 index 0000000..8903e94 Binary files /dev/null and b/fp-plugins/commentcenter/imgs/down.png differ diff --git a/fp-plugins/commentcenter/imgs/edit-cut.svg b/fp-plugins/commentcenter/imgs/edit-cut.svg new file mode 100644 index 0000000..b9ac930 --- /dev/null +++ b/fp-plugins/commentcenter/imgs/edit-cut.svg @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Edit Cut + + + Garrett Le Sage + + + + + edit + cut + clipboard + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/edit.png b/fp-plugins/commentcenter/imgs/edit.png new file mode 100644 index 0000000..4cffab3 Binary files /dev/null and b/fp-plugins/commentcenter/imgs/edit.png differ diff --git a/fp-plugins/commentcenter/imgs/go-down.svg b/fp-plugins/commentcenter/imgs/go-down.svg new file mode 100644 index 0000000..95b82af --- /dev/null +++ b/fp-plugins/commentcenter/imgs/go-down.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Down + + + go + lower + down + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/go-up.svg b/fp-plugins/commentcenter/imgs/go-up.svg new file mode 100644 index 0000000..54263df --- /dev/null +++ b/fp-plugins/commentcenter/imgs/go-up.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Up + + + go + higher + up + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/list-add.svg b/fp-plugins/commentcenter/imgs/list-add.svg new file mode 100644 index 0000000..6eaed44 --- /dev/null +++ b/fp-plugins/commentcenter/imgs/list-add.svg @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Add + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + add + plus + + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/process-stop.svg b/fp-plugins/commentcenter/imgs/process-stop.svg new file mode 100644 index 0000000..04ce3a7 --- /dev/null +++ b/fp-plugins/commentcenter/imgs/process-stop.svg @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Stop + 2005-10-16 + + + Andreas Nilsson + + + + + stop + halt + error + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/publish.png b/fp-plugins/commentcenter/imgs/publish.png new file mode 100644 index 0000000..b881378 Binary files /dev/null and b/fp-plugins/commentcenter/imgs/publish.png differ diff --git a/fp-plugins/commentcenter/imgs/spam.png b/fp-plugins/commentcenter/imgs/spam.png new file mode 100644 index 0000000..f9d3ec0 Binary files /dev/null and b/fp-plugins/commentcenter/imgs/spam.png differ diff --git a/fp-plugins/commentcenter/imgs/stock_search-and-replace.svg b/fp-plugins/commentcenter/imgs/stock_search-and-replace.svg new file mode 100644 index 0000000..b7d75dc --- /dev/null +++ b/fp-plugins/commentcenter/imgs/stock_search-and-replace.svg @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + edit + find + locate + search + + + + + + Garrett LeSage + + + + + + Jakub Steiner, Steven Garrity + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fp-plugins/commentcenter/imgs/up.png b/fp-plugins/commentcenter/imgs/up.png new file mode 100644 index 0000000..4b87d2e Binary files /dev/null and b/fp-plugins/commentcenter/imgs/up.png differ diff --git a/fp-plugins/commentcenter/inc/admin.php b/fp-plugins/commentcenter/inc/admin.php new file mode 100644 index 0000000..19a56e0 --- /dev/null +++ b/fp-plugins/commentcenter/inc/admin.php @@ -0,0 +1,814 @@ +plugin=&$GLOBALS['plugin_commentcenter']; + $smarty=&$this->smarty; + + # The default TPL + $smarty->assign('admin_resource', 'plugin:commentcenter/policies'); + $smarty->assign('plugin_url', plugin_geturl('commentcenter')); + + $smarty->register_modifier('idToSubject', array(&$this, '_idToTitle')); + add_filter('wp_title', array(&$this, '_title'), 15, 2); + add_action('wp_head', array(&$this, '_head'), 10); + } + + /** + * This function is the callback for the hook system. + * It sets the title. + * + * @param string $val: The current title + * @param string $sep: The separator + * @return string: The title + */ + function _title($val, $sep) { + return "{$val} {$sep} Comment Center"; + } + + /** + * This function is the callback for the hook system. + * It adds the javascript of the plugin. + */ + function _head() { + if(!function_exists('plugin_jquery_head')) { + return; + } + $src1=plugin_geturl('commentcenter').'res/ajax.js'; + $src2=BLOG_BASEURL.'admin.php?jslang=commentcenter'; + echo '\n"; + echo '\n"; + } + + /** + * This function return the entry title from the id. + * It's made to be called from Smarty. + * + * @param string $id: The entry id + * @return string: The output + */ + function _idToTitle($id) { + $o=new FPDB_Query(array('start'=>0, 'count'=>1, 'fullparse'=>false, 'id'=>$id), null); + if(!$o->hasMore()) { + return false; + } + $arr=$o->getEntry(); + return wp_specialchars($arr[1]['subject']); + } + + /** + * This function is an advanced redirect option. + * + * @param string $cmd: The command + * @param mixed $cmdval: The value for the command + * @param boolean $nosuccess: Don't save the success? + */ + function _redirect($cmd, $cmdval=1, $nosuccess=false) { + global $panel; + $smarty=&$this->smarty; + sess_add("success_{$panel}", $smarty->get_template_vars('success')); + + $action_url=$smarty->get_template_vars('action_url'); + $url=admin_filter_command($action_url, $cmd, $cmdval); + $url=html_entity_decode($url); + $url=substr($url, strlen(BLOG_BASEURL)); + utils_redirect($url); + die; + } + + /** + * This is the main function of the panel. + */ + function main() { + $smarty=&$this->smarty; + $plugin=&$this->plugin; + $plugin->loadPolicies(); + $smarty->assign('policies', $plugin->policies); + } + + /** + * This is the callback for the configure command. + */ + function doconfigure() { + global $lang; + $plugin=&$this->plugin; + $conf=$plugin->getConf(); + + $smarty=&$this->smarty; + $smarty->assign('admin_resource', 'plugin:commentcenter/configure'); + $smarty->assign('pl_conf', $conf); + + $conf=$plugin->getConf(); + if($conf['akismet_check']) { + $akismet=$plugin->akismetLoad(); + if(is_numeric($akismet)) { + $error=$lang['admin']['entry']['commentcenter']['akismet_errors'][$akismet]; + $smarty->assign('warnings', $error); + } + } + } + + /** + * This callback is used when the configuration is saved. + */ + function onconfigure() { + if(!empty($_POST['akismet_url'])) { + $pos=strpos($_POST['akismet_url'], '//'); + if($pos===FALSE || $pos>8) { + $_POST['akismet_url']='http://'.$_POST['akismet_url']; + } + } + + $save=array('log_all'=>isset($_POST['log_all']), + 'email_alert'=>isset($_POST['email_alert']), + 'akismet_check'=>isset($_POST['akismet_check']), + 'akismet_key'=>$_POST['akismet_key'], + 'akismet_url'=>$_POST['akismet_url']); + // It doesn't make very sense: I could just use array_merge but... + foreach($save as $key=>$value) { + plugin_addoption('commentcenter', $key, $value); + } + + $success=plugin_saveoptions() ? 1 : -1; + $this->smarty->assign('success', $success); + $this->_redirect('configure'); + } + + /** + * The edit policy/new policy action callback. + * + * @param integer $id: The policy id. -1 means a new one + * @return integer: The redirect option + */ + function dopoledit($id) { + global $lang; + $plugin=&$this->plugin; + $smarty=&$this->smarty; + $plang=&$lang['admin']['entry']['commentcenter']; + + $plugin->loadPolicies(); + $smarty->assign('policy', array()); + $smarty->assign('admin_resource', 'plugin:commentcenter/editpol'); + $smarty->assign('pol_id', $id); + + if($id!=-1 && isset($plugin->policies[$id])) { + $smarty->assign('policy', $plugin->policies[$id]); + } elseif($id!=-1) { + # Inexistent policy + $smarty->assign('errors', $plang['errors']['pol_nonex']); + } else { + $smarty->assign('polnew', true); + } + return 0; + } + + /** + * The edit policy/new policy save callback. + * + * @return integer: The redirect option + */ + function onedit_policy() { + $plugin=&$this->plugin; + $success=2; + $policy=array(); + @$id=$_POST['policy_id']; + + $plugin->loadPolicies(); + if($id!=-1 && !isset($plugin->policies[$id])) { + $success=-2; + } + + while(true && $success==2) { + if(empty($_POST['apply_to'])) { + $success=-2; + break; + } + if(!isset($_POST['behavoir'])) { + $success=-2; + break; + } + + $behavoir=$_POST['behavoir']; + if($behavoir!=1 && $behavoir!=0 && $behavoir!=-1) { + $success=-2; + break; + } + $policy['do']=$behavoir; + + switch($_POST['apply_to']) { + case 'all_entries': + $policy['is_all']=true; + break 2; + case 'some_entries': + if(empty($_POST['entries'])) { + $success=-2; + } else { + $entries=array(); + foreach($_POST['entries'] as $entry) { + if(entry_exists($entry)) { + $entries[]=$entry; + } + } + if(count($entries)==0) { + $success=-2; + } else { + $entries=array_unique($entries); + $policy['entry']=$entries; + } + } + break 2; + case 'properties': + $policy['is_all']=true; + if(isset($_POST['cats'])) { + $policy['categories']=array_keys($_POST['cats']); + $policy['is_all']=false; + } + if(is_numeric($_POST['older'])) { + # Save in seconds + $policy['older']=$_POST['older']*86400; + $policy['is_all']=false; + } + if(isset($policy['is_all']) && @!$policy['is_all']) { + unset($policy['is_all']); + } + break 2; + default: + $success=-2; + break 2; + } + break; + } + + if($success==2) { + if($id==-1) { + $plugin->policies[]=$policy; + } else { + $plugin->policies[$id]=$policy; + } + $success=$plugin->savePolicies() ? 2 : -2; + } + + $this->smarty->assign('success', $success); + return 2; + } + + /** + * This function is the callback for the poldelete action. + * + * @param integer $id: The id of policy you wish to delete + * @return integer: Redirect option + */ + function dopoldelete($id) { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletepol'); + $plugin->loadPolicies(); + + if(isset($plugin->policies[$id])) { + $smarty->assign('policies', array($id=>$plugin->policies[$id])); + } + $smarty->assign('single', true); + return 0; + } + + /** + * This function is like dopoldelete but it's for multiple policies. + * + * @return integer: Redirect option + */ + function onmultidel() { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + + if(@!count($_POST['select'])) { + $smarty->assign('success', -4); + return 2; + } + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletepol'); + $plugin->loadPolicies(); + $policies=array(); + + foreach($_POST['select'] as $polid=>$checkvalue) { + if(isset($plugin->policies[$polid])) { + $policies[$polid]=$plugin->policies[$polid]; + } + } + + if(count($policies)>0) { + $smarty->assign('policies', $policies); + } else { + $smarty->assign('success', -4); + return 2; + } + + if(count($policies)==1) { + $smarty->assign('single', true); + } + + return 0; + } + + /** + * This is the delete ok command. + * + * @return integer: The redirect option + */ + function ondelok() { + if(empty($_POST['del_policy'])) { + $s=-4; + } else { + $plugin=$this->plugin; + $plugin->loadPolicies(); + foreach($_POST['del_policy'] as $polid) { + if(isset($plugin->policies[$polid])) { + unset($plugin->policies[$polid]); + } + } + $s=$plugin->savePolicies() ? 4 : -4; + } + $this->smarty->assign('success', $s); + return 2; + } + + /** + * This is the cancel callback. It just makes the redirect. + * + * @return integer: The redirect option + */ + function oncancel() { + return 2; + } + + /** + * This function is the callback for the polup action. + * + * @param integer $id: The id of policy you wish to delete + * @return integer: Redirect option + */ + function dopolup($id) { + $s=-3; + + if($id>0) { + $plugin=&$this->plugin; + $plugin->loadPolicies(); + $plugin->policyMove($id, $id-1); + $s=$plugin->savePolicies() ? 3 : -3; + } + + $this->smarty->assign('success', $s); + return 2; + } + + /** + * This function is the callback for the poldown action. + * + * @param integer $id: The id of policy you wish to delete + * @return integer: Redirect option + */ + function dopoldown($id) { + $s=-3; + + $plugin=&$this->plugin; + $plugin->loadPolicies(); + + if($idpolicies)-1) { + $plugin->policyMove($id, $id+1); + $s=$plugin->savePolicies() ? 3 : -3; + } + + $this->smarty->assign('success', $s); + return 2; + } + + /** + * This function is the callback for the approve_list command + * + * @return integer: The redirect option + */ + function doapprove_list() { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + + $conf=$plugin->getConf(); + $smarty->assign('use_akismet', @$conf['akismet_check']); + $smarty->assign('other', @$conf['log_all']); + $smarty->assign('admin_resource', 'plugin:commentcenter/approvelist'); + + $lister=new commentcenter_list($plugin->pl_dir); + $smarty->assign('entries', $lister->toDetails()); + + return 0; + } + + /** + * This function is the callback for the publishcomm command + * + * @param string $id: The comment id + * @param boolean $noredirect: If true, don't redirect + * @param boolean $noham: If it was blocked from Akismet, don't submit as ham + * @return integer: The redirect option + */ + function dopublishcomm($id, $noredirect=false, $noham=false) { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + $f=$plugin->pl_dir.$id.'.txt'; + + if(!file_exists($f)) { + $smarty->assign('success', -5); + $succ=-5; + } else { + + include $f; + + $entry=substr($id, 1, 18); + $ham=false; + + if(isset($comment['log_reason'])) { + $ham=$comment['log_reason']=='akismet' && !$noham; + unset($comment['log_reason']); + } + if(isset($comment['id'])) { + unset($comment['id']); + } + + if($ham) { + $clean=$plugin->akismetClean($comment, $entry); + $akismet=&$plugin->akismetLoad(); + if(is_object($akismet)) { + $akismet->setComment($clean); + $akismet->submitHam(); + } + } + + $id=comment_save($entry, $comment); + do_action('comment_post', $entry, array($id, $comment)); + $succ=$id ? 5 : -5; + $smarty->assign('success', $succ); + + if($succ==5) { + @unlink($f); + } + + } + + if($noredirect) { + return $succ==5; + } + + $this->_redirect('approve_list'); + return 0; + } + + /** + * This is the callback for the action pubnoham. + * + * @param string $id: The comment id + * @return integer: The redirect option. + */ + function dopubnoham($id) { + return $this->dopublishcomm($id, false, true); + } + + /** + * This is the callback to publish multiple comments. + * + * @return integer: The redirect option + */ + function onmpubcomm() { + if(!isset($_POST['select'])) { + $this->dopublishcomm('fake'); + } + + $target=count($_POST['select']); + $noham=!isset($_POST['submitham']); + $i=0; + + foreach((array)$_POST['select'] as $comm=>$check) { + $i++; + $this->dopublishcomm($comm, $i!=$target, $noham); + } + + // If it's correct, we should exited the script before + $this->smarty->assign('success', -5); + $this->_redirect('approve_list'); + return 0; + } + + /** + * This function is the callback for the deletecomm action. + * + * @param integer $id: The id of the comment you wish to delete + * @return integer: Redirect option + */ + function dodeletecomm($id) { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletecomm'); + + $entry=substr($id, 1, 18); + $commid=substr($id, 21, 20); + + $f=$plugin->pl_dir.$id.'.txt'; + if(file_exists($f)) { + include $f; + $delete[$entry]['del'][$commid]=$comment; + $smarty->assign('entries', $delete); + } else { + $smarty->assign('success', -6); + $this->_redirect('approve_list'); + } + + $smarty->assign('single', true); + return 0; + } + + /** + * This function is like dopoldelete but it's for multiple policies. + * + * @return integer: Redirect option + */ + function onmdelcomm() { + $plugin=&$this->plugin; + $smarty=&$this->smarty; + + if(@!count($_POST['select'])) { + $smarty->assign('success', -6); + $this->_redirect('approve_list'); + return 0; + } + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletecomm'); + $remove=array(); + + foreach($_POST['select'] as $commbig=>$check) { + $entry=substr($commbig, 1, 18); + $commid=substr($commbig, 21, 20); + $f=$plugin->pl_dir.$commbig.'.txt'; + if(file_exists($f)) { + include $f; + $remove[$entry]['del'][$commid]=$comment; + } + } + + if(count($remove)>0) { + $smarty->assign('entries', $remove); + } else { + $smarty->assign('success', -6); + $this->_redirect('approve_list'); + return 0; + } + + if(count($remove)==1) { + $smarty->assign('single', true); + } + + return 0; + } + + /** + * This is the delete ok command. + * + * @return integer: The redirect option + */ + function oncommdelok() { + if(empty($_POST['select'])) { + $s=-6; + } else { + foreach($_POST['select'] as $commid=>$check) { + $f=$this->plugin->pl_dir.$commid.'.txt'; + @unlink($f); + } + $s=6; + } + $this->smarty->assign('success', $s); + $this->_redirect('approve_list'); + return 2; + } + + /** + * This is the cancel callback. It just makes the redirect. + * + * @return integer: The redirect option + */ + function onccancel() { + $this->_redirect('approve_list'); + return 2; + } + + /** + * This function is the callback for the action "manage". + * + * @param string $entry: The entry id + * @return integer: The redirect option + */ + function domanage($entry) { + global $lang, $fpdb; + $smarty=&$this->smarty; + + $smarty->assign('admin_resource', 'plugin:commentcenter/manage'); + $smarty->assign('is_managing', true); + + $conf=$this->plugin->getConf(); + if(@$conf['akismet_check']) { + $smarty->assign('use_akismet', true); + } + + if($entry!='search' && !entry_exists($entry)) { + $smarty->assign('error', $lang['admin']['entry']['commentcenter']['errors']['entry_nf']); + } elseif($entry!='search') { + $smarty->assign('entry_id', $entry); + $smarty->assign('fetch', 'list'); + + $fpdb->query("id:{$entry},fullparse:true,comments:true"); + $q=&$fpdb->getQuery(); + $q->getEntry(); + $list=array(); + while($q->comments->hasMore()) { + list($id, $comment)=$q->comments->getComment(); + $list[$entry]['list'][$id]=$comment; + } + $smarty->assign('entries', $list); + } + return 0; + } + + /** + * Since it's impossible to use a GET form in Flatpress, to search entries + * we have to use a POST form, and here's its callback. + * + * @return integer: The redirect option + */ + function onentry_search() { + if(!isset($_POST['entry'])) { + $_POST['entry']=''; + } + // In the function we call 'search' isn't an error, but here yes, so delete it + if($_POST['entry']=='search') { + $_POST['entry']=''; + } + return @$this->domanage($_POST['entry']); + } + + /** + * This function is the callback for the deletecomm2 action. + * + * @param integer $id: The id of the comment you wish to delete + * @return integer: Redirect option + */ + function dodeletecomm2($id) { + $smarty=&$this->smarty; + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletecomm'); + $smarty->assign('is_managing', true); + + $entry=substr($id, 1, 18); + $commid=substr($id, 21, 20); + $smarty->assign('entry', $entry); + + if(comment_exists($entry, $commid)) { + $delete[$entry]['del'][$commid]=comment_parse($entry, $commid); + $smarty->assign('entries', $delete); + } else { + $smarty->assign('success', -6); + $this->_redirect('manage', $entry); + } + + $smarty->assign('single', true); + return 0; + } + + /** + * This function is like dopoldelete but it's for multiple policies. + * + * @return integer: Redirect option + */ + function onmdelcomm_2() { + $smarty=&$this->smarty; + + if(@!count($_POST['select'])) { + $smarty->assign('success', -6); + $this->_redirect('manage', @$_POST['entry_hid']); + return 0; + } + + $smarty->assign('admin_resource', 'plugin:commentcenter/deletecomm'); + $smarty->assign('is_managing', true); + $smarty->assign('entry', @$_POST['entry_hid']); + $remove=array(); + + foreach($_POST['select'] as $commbig=>$check) { + $entry=substr($commbig, 1, 18); + $commid=substr($commbig, 21, 20); + $comment=comment_parse($entry, $commid); + if($comment!==false) { + $remove[$entry]['del'][$commid]=$comment; + } + } + + if(count($remove)>0) { + $smarty->assign('entries', $remove); + } else { + $smarty->assign('success', -6); + $this->_redirect('manage', @$_POST['entry_hid']); + return 0; + } + + if(count($remove)==1) { + $smarty->assign('single', true); + } + + return 0; + } + + /** + * This is the delete ok command. + * + * @return integer: The redirect option + */ + function oncommdelok_2() { + if(empty($_POST['select'])) { + $s=-6; + } else { + $i=0; + foreach($_POST['select'] as $commid=>$check) { + $entry=substr($commid, 1, 18); + $commid=substr($commid, 21, 20); + $i+=comment_delete($entry, $commid) ? 1 : 0; + } + $s=$i>0 ? 6 : -6; + } + $this->smarty->assign('success', $s); + $this->_redirect('manage', @$_POST['entry']); + return 2; + } + + /** + * This is the cancel callback. It just makes the redirect. + * + * @return integer: The redirect option + */ + function onccancel_2() { + $this->_redirect('manage', @$_POST['entry']); + return 2; + } + + /** + * This function is the callback for the action commspam. + * + * @param string $id: The comment id + * @return integer: The redirect option + */ + function docommspam($id) { + $smarty=&$this->smarty; + $plugin=&$this->plugin; + $entry=substr($id, 1, 18); + $commid=substr($id, 21, 20); + + if(!comment_exists($entry, $commid)) { + $smarty->assign('success', -7); + } else { + $comment=comment_parse($entry, $commid); + $clean=$plugin->akismetClean($comment, $entry); + + $akismet=&$plugin->akismetLoad(); + if(is_object($akismet)) { + $akismet->setComment($clean); + $akismet->submitSpam(); + $smarty->assign('success', $akismet->errorsExist() ? -7 : 7); + } else { + $smarty->assign('success', -7); + } + } + + $this->_redirect('manage', $entry); + return 0; + } + +} +admin_addpanelaction('entry', 'commentcenter', true); \ No newline at end of file diff --git a/fp-plugins/commentcenter/inc/akismet.class.php b/fp-plugins/commentcenter/inc/akismet.class.php new file mode 100644 index 0000000..483c6e4 --- /dev/null +++ b/fp-plugins/commentcenter/inc/akismet.class.php @@ -0,0 +1,388 @@ +Usage + * + * $comment = array( + * 'author' => 'viagra-test-123', + * 'email' => 'test@example.com', + * 'website' => 'http://www.example.com/', + * 'body' => 'This is a test comment', + * 'permalink' => 'http://yourdomain.com/yourblogpost.url', + * ); + * + * $akismet = new Akismet('http://www.yourdomain.com/', 'YOUR_WORDPRESS_API_KEY', $comment); + * + * if($akismet->errorsExist()) { + * echo"Couldn't connected to Akismet server!"; + * } else { + * if($akismet->isSpam()) { + * echo"Spam detected"; + * } else { + * echo"yay, no spam!"; + * } + * } + * + * + * @author Bret Kuhns {@link www.bretkuhns.com} + * @link http://code.google.com/p/akismet-php4 + * @version 0.3.5 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + + + +// Error constants +define("AKISMET_SERVER_NOT_FOUND", 0); +define("AKISMET_RESPONSE_FAILED", 1); +define("AKISMET_INVALID_KEY", 2); + + + +// Base class to assist in error handling between Akismet classes +class AkismetObject { + var $errors = array(); + + + /** + * Add a new error to the errors array in the object + * + * @param String $name A name (array key) for the error + * @param String $string The error message + * @return void + */ + // Set an error in the object + function setError($name, $message) { + $this->errors[$name] = $message; + } + + + /** + * Return a specific error message from the errors array + * + * @param String $name The name of the error you want + * @return mixed Returns a String if the error exists, a false boolean if it does not exist + */ + function getError($name) { + if($this->isError($name)) { + return $this->errors[$name]; + } else { + return false; + } + } + + + /** + * Return all errors in the object + * + * @return String[] + */ + function getErrors() { + return (array)$this->errors; + } + + + /** + * Check if a certain error exists + * + * @param String $name The name of the error you want + * @return boolean + */ + function isError($name) { + return isset($this->errors[$name]); + } + + + /** + * Check if any errors exist + * + * @return boolean + */ + function errorsExist() { + return (count($this->errors) > 0); + } + + +} + + + + + +// Used by the Akismet class to communicate with the Akismet service +class AkismetHttpClient extends AkismetObject { + var $akismetVersion = '1.1'; + var $con; + var $host; + var $port; + var $apiKey; + var $blogUrl; + var $errors = array(); + + + // Constructor + function __construct($host, $blogUrl, $apiKey, $port = 80) { + $this->host = $host; + $this->port = $port; + $this->blogUrl = $blogUrl; + $this->apiKey = $apiKey; + } + + + // Use the connection active in $con to get a response from the server and return that response + function getResponse($request, $path, $type = "post", $responseLength = 1160) { + $this->_connect(); + + if($this->con && !$this->isError(AKISMET_SERVER_NOT_FOUND)) { + $request = + strToUpper($type)." /{$this->akismetVersion}/$path HTTP/1.0\r\n" . + "Host: ".((!empty($this->apiKey)) ? $this->apiKey."." : null)."{$this->host}\r\n" . + "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" . + "Content-Length: ".strlen($request)."\r\n" . + "User-Agent: Akismet PHP4 Class\r\n" . + "\r\n" . + $request + ; + $response = ""; + + @fwrite($this->con, $request); + + while(!feof($this->con)) { + $response .= @fgets($this->con, $responseLength); + } + + $response = explode("\r\n\r\n", $response, 2); + return $response[1]; + } else { + $this->setError(AKISMET_RESPONSE_FAILED, "The response could not be retrieved."); + } + + $this->_disconnect(); + } + + + // Connect to the Akismet server and store that connection in the instance variable $con + function _connect() { + if(!($this->con = @fsockopen($this->host, $this->port))) { + $this->setError(AKISMET_SERVER_NOT_FOUND, "Could not connect to akismet server."); + } + } + + + // Close the connection to the Akismet server + function _disconnect() { + @fclose($this->con); + } + + +} + + + + + +// The controlling class. This is the ONLY class the user should instantiate in +// order to use the Akismet service! +class Akismet extends AkismetObject { + var $apiPort = 80; + var $akismetServer = 'rest.akismet.com'; + var $akismetVersion = '1.1'; + var $http; + + var $ignore = array( + 'HTTP_COOKIE', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED_HOST', + 'HTTP_MAX_FORWARDS', + 'HTTP_X_FORWARDED_SERVER', + 'REDIRECT_STATUS', + 'SERVER_PORT', + 'PATH', + 'DOCUMENT_ROOT', + 'SERVER_ADMIN', + 'QUERY_STRING', + 'PHP_SELF', + 'argv' + ); + + var $blogUrl = ""; + var $apiKey = ""; + var $comment = array(); + + + /** + * Constructor + * + * Set instance variables, connect to Akismet, and check API key + * + * @param String $blogUrl The URL to your own blog + * @param String $apiKey Your wordpress API key + * @param String[] $comment A formatted comment array to be examined by the Akismet service + * @return Akismet + */ + function __construct($blogUrl, $apiKey, $comment = array()) { + $this->blogUrl = $blogUrl; + $this->apiKey = $apiKey; + $this->setComment($comment); + + // Connect to the Akismet server and populate errors if they exist + $this->http = new AkismetHttpClient($this->akismetServer, $blogUrl, $apiKey); + if($this->http->errorsExist()) { + $this->errors = array_merge($this->errors, $this->http->getErrors()); + } + + // Check if the API key is valid + if(!$this->_isValidApiKey($apiKey)) { + $this->setError(AKISMET_INVALID_KEY, "Your Akismet API key is not valid."); + } + } + + + /** + * Query the Akismet and determine if the comment is spam or not + * + * @return boolean + */ + function isSpam() { + $response = $this->http->getResponse($this->_getQueryString(), 'comment-check'); + + return ($response == "true"); + } + + + /** + * Submit this comment as an unchecked spam to the Akismet server + * + * @return void + */ + function submitSpam() { + $this->http->getResponse($this->_getQueryString(), 'submit-spam'); + } + + + /** + * Submit a false-positive comment as "ham" to the Akismet server + * + * @return void + */ + function submitHam() { + $this->http->getResponse($this->_getQueryString(), 'submit-ham'); + } + + + /** + * Manually set the comment value of the instantiated object. + * + * @param Array $comment + * @return void + */ + function setComment($comment) { + $this->comment = $comment; + if(!empty($comment)) { + $this->_formatCommentArray(); + $this->_fillCommentValues(); + } + } + + + /** + * Returns the current value of the object's comment array. + * + * @return Array + */ + function getComment() { + return $this->comment; + } + + + /** + * Check with the Akismet server to determine if the API key is valid + * + * @access Protected + * @param String $key The Wordpress API key passed from the constructor argument + * @return boolean + */ + function _isValidApiKey($key) { + $keyCheck = $this->http->getResponse("key=".$this->apiKey."&blog=".$this->blogUrl, 'verify-key'); + + return ($keyCheck == "valid"); + } + + + /** + * Format the comment array in accordance to the Akismet API + * + * @access Protected + * @return void + */ + function _formatCommentArray() { + $format = array( + 'type' => 'comment_type', + 'author' => 'comment_author', + 'email' => 'comment_author_email', + 'website' => 'comment_author_url', + 'body' => 'comment_content' + ); + + foreach($format as $short => $long) { + if(isset($this->comment[$short])) { + $this->comment[$long] = $this->comment[$short]; + unset($this->comment[$short]); + } + } + } + + + /** + * Fill any values not provided by the developer with available values. + * + * @return void + */ + function _fillCommentValues() { + if(!isset($this->comment['user_ip'])) { + $this->comment['user_ip'] = ($_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR')) ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'); + } + if(!isset($this->comment['user_agent'])) { + $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT']; + } + if(!isset($this->comment['referrer'])) { + $this->comment['referrer'] = $_SERVER['HTTP_REFERER']; + } + if(!isset($this->comment['blog'])) { + $this->comment['blog'] = $this->blogUrl; + } + } + + + /** + * Build a query string for use with HTTP requests + * + * @access Protected + * @return String + */ + function _getQueryString() { + foreach($_SERVER as $key => $value) { + if(!in_array($key, $this->ignore)) { + if($key == 'REMOTE_ADDR') { + $this->comment[$key] = $this->comment['user_ip']; + } else { + $this->comment[$key] = $value; + } + } + } + + $query_string = ''; + + foreach($this->comment as $key => $data) { + $query_string .= $key . '=' . urlencode(stripslashes($data)) . '&'; + } + + return $query_string; + } + + +} +?> \ No newline at end of file diff --git a/fp-plugins/commentcenter/inc/editor.php b/fp-plugins/commentcenter/inc/editor.php new file mode 100644 index 0000000..d47750b --- /dev/null +++ b/fp-plugins/commentcenter/inc/editor.php @@ -0,0 +1,44 @@ +get_template_vars('post'); + $panel_url=$smarty->get_template_vars('panel_url'); + + $plugin->loadPolicies(); + $do=$plugin->behavoirFromPolicies($entry, @$arr['categories']); + $do='simple_'.$do; + + $oldact=$action; + $action='commentcenter'; + $policies=admin_filter_action($panel_url, 'commentcenter'); + $manage=admin_filter_command($policies, 'manage', $entry); + $action=$oldact; + + echo "
\n"; + echo "Comment Center\n
\n"; +} +add_filter('simple_edit_form', 'plugin_commentcenter_editor'); \ No newline at end of file diff --git a/fp-plugins/commentcenter/inc/jslang.php b/fp-plugins/commentcenter/inc/jslang.php new file mode 100644 index 0000000..82b9096 --- /dev/null +++ b/fp-plugins/commentcenter/inc/jslang.php @@ -0,0 +1,33 @@ +$value) { + $key=str_replace('-', '_', $key); + $value=str_replace("\n", "\\n", $value); + $value=str_replace("\r", "\\r", $value); + $value=str_replace("\t", "\\t", $value); + $value=str_replace('"', '\\"', $value); + echo "\t'msg{$key}' : \"{$value}\",\n"; + } + + echo '}'; + + die; +} +add_action('init', 'plugin_commentcenter_jslang'); \ No newline at end of file diff --git a/fp-plugins/commentcenter/lang/lang.en-us.php b/fp-plugins/commentcenter/lang/lang.en-us.php new file mode 100644 index 0000000..820bb56 --- /dev/null +++ b/fp-plugins/commentcenter/lang/lang.en-us.php @@ -0,0 +1,187 @@ +'Comment Center', + 'desc1'=>'This panel allows you to manage the comments on your blog.', + 'desc2'=>'Here you can do several things:', + + # Links + 'lpolicies'=>'Manage the policies', + 'lapprove'=>'Show blocked comments', + 'lmanage'=>'Manage comments', + 'lconfig'=>'Configure the plugin', + + # Policies + 'policies'=>'Policies', + 'desc_pol'=>'Here you can edit the policies of comments.', + 'select'=>'Select', + 'criteria'=>'Criteria', + 'behavoir'=>'Behavoir', + 'options'=>'Options', + 'entry'=>'Entry', + 'entries'=>'Entries', + 'categories'=>'Categories', + 'nopolicies'=>'There isn\'t any policy.', + 'all_entries'=>'All Entries', + 'fol_entries'=>'The policy is applied to the following entries:', + 'fol_cats'=>'The policy is applied to entries in the following categories:', + 'older'=>'The policy is applied to entries older than %d day(s).', + 'allow'=>'Allow to comment', + 'block'=>'Block comments', + 'approvation'=>'Comments need to be approved', + 'up'=>'Move up', + 'down'=>'Move down', + 'edit'=>'Edit', + 'delete'=>'Delete', + 'newpol'=>'Add a new policy', + 'del_selected'=>'Delete selected policy(ies)', + 'select_all'=>'Select All', + 'deselect_all'=>'Deselect All', + + # Configuration page + 'configure'=>'Configure the plugin', + 'desc_conf'=>'Here you can modify the options of the plugin.', + 'log_all'=>'Log blocked comments', + 'log_all_long'=>'Check it if you want to log also comments that are blocked.', + 'email_alert'=>'Notify comments via email', + 'email_alert_long'=>'Check it if you want that when there is a comment to approve you want to be '. + 'informed via email.', + 'akismet'=>'Akismet', + 'akismet_use'=>'Enable Akismet check', + 'akismet_key'=>'Akismet Key', + 'akismet_key_long'=>'The Akismet service provide you a key to use it. Insert here.', + 'akismet_url'=>'Blog base URL for Akismet', + 'akismet_url_long'=>'I think for Akismet free service you should use just a domain. '. + 'You can leave blank this field, %s will be used.', + 'save_conf'=>'Save Configuration', + + # Edit policy page + 'apply_to'=>'Apply to', + 'editpol'=>'Edit a policy', + 'createpol'=>'Create a policy', + 'some_entries'=>'Some Entries', + 'properties'=>'Entry with certain properties', + 'se_desc'=>'If you selected the %s option, please insert entries you want to apply to this policy.', + 'se_fill'=>'Please fill the fields with the id of the entries (entryYYMMDD-HHMMSS).', + 'po_title'=>'Properties', + 'po_desc'=>'If you selected the %s option, please fill the properties.', + 'po_comp'=>'The fields aren\'t compulsory but you must fill at least one or the policy '. + 'will apply on all entries.', + 'po_time'=>'Time options', + 'po_older'=>'Apply to entries older than ', + 'days'=>'days.', + 'save_policy'=>'Save Policy', + + # Delete policies page + 'del_policies'=>'Delete Policies', + 'del_descs'=>'You are going to delete this policy: ', + 'del_descm'=>'You are going to delete these policies: ', + 'sure'=>'Are you sure?', + 'del_subs'=>'Yes, please delete it', + 'del_subm'=>'Yes, please delete them', + 'del_cancel'=>'No, take me back to the panel', + + # Approve comments page + 'app_title'=>'Approve comment', + 'app_desc'=>'Here you can approve comments.', + 'app_date'=>'Date', + 'app_content'=>'Comment', + 'app_author'=>'Author', + 'app_email'=>'Email', + 'app_ip'=>'IP', + 'app_actions'=>'Actions', + 'app_publish'=>'Publish', + 'app_delete'=>'Delete', + 'app_nocomms'=>'There isn\'t any comment.', + 'app_pselected'=>'Publish selected comment(s)', + 'app_dselected'=>'Remove selected comment(s)', + 'app_other'=>'Other Comments', + 'app_akismet'=>'Signed as spam', + 'app_spamdesc'=>'These comments were blocked by Akismet.', + 'app_hamsubmit'=>'Submit to Akismet as ham when you publish them.', + 'app_pubnotham'=>'Publish it but dont\'submit as ham', + + # Delete comments page + 'delc_title'=>'Delete Comments', + 'delc_descs'=>'You are going to delete this comment: ', + 'delc_descm'=>'You are going to delete these comments: ', + + # Manage comments page + 'man_searcht'=>'Search an entry', + 'man_searchd'=>'Insert the id of the entry whose you want to manage comments.', + 'man_search'=>'Search', + 'man_commfor'=>'Comments for %s', + 'man_spam'=>'Submit as spam to Akismet', + + # The simple edit + 'simple_pre'=>'Comments for this entry will ', + 'simple_1'=>'be allowed.', + 'simple_0'=>'require your approval.', + 'simple_-1'=>'be blocked.', + 'simple_manage'=>'Manage the comments of this entry.', + 'simple_edit'=>'Edit Policies', + + # Akismet warnings + 'akismet_errors'=>array( + -1=>'The Akismet key is empty. Please insert it.', + -2=>'We couldn\'t call Akismet servers.', + -3=>'The Akismet response failed.', + -4=>'The Akismet key is not valid.', + ), + + # Messages + 'msgs'=>array( + 1=>'Configuration saved.', + -1=>'An error occurred while trying to save the configuration.', + + 2=>'Policy saved.', + -2=>'An error occurred while trying to save the policy (maybe your settings are wrong).', + + 3=>'Policy moved.', + -3=>'An error occurred while trying to move the policy (or it can\'t be moved).', + + 4=>'Policy(ies) removed.', + -4=>'An error occurred while trying to remove the policy(ies) (or you haven\'t selected any policy).', + + 5=>'Comment(s) published.', + -5=>'An error occurred while trying to publish the comment(s).', + + 6=>'Comment(s) removed.', + -6=>'An error occurred while trying to remove the comment(s) (or you haven\'t selected any comment).', + + 7=>'Comment submitted.', + -7=>'An error occurred while trying to submit the comment.', + ), + + # Errors + 'errors'=>array( + 'pol_nonex'=>'The policy you want to edit does not exist.', + 'entry_nf'=>'The entry you have selected does not exist.', + ), +); +$lang['plugin']['commentcenter']=array( + 'akismet_error'=>'Sorry, we\'re encountering technical difficulties.', + 'lock'=>'Comments for this entry are blocked, sorry.', + 'approvation'=>'The comments has been saved but the Administrator must approve it before showing it.', + + # Mail for comments + 'mail_subj'=>'New comment to approve on %s', +); + +$lang['plugin']['commentcenter']['mail_text']=<<'Comment Center', + 'desc1'=>'Questo pannello ti consente di gestire i commenti del tuo blog.', + 'desc2'=>'Qui puoi fare numerose cose:', + + # Links + 'lpolicies'=>'Gestire le regole', + 'lapprove'=>'Elencare i commenti bloccati', + 'lmanage'=>'Gestire i commenti', + 'lconfig'=>'Configurare il plugin', + + # Policies + 'policies'=>'Regole', + 'desc_pol'=>'Qui puoi modificare le regole sui commenti.', + 'select'=>'Seleziona', + 'criteria'=>'Criteri', + 'behavoir'=>'Comportamento', + 'options'=>'Opzioni', + 'entry'=>'Post', + 'entries'=>'Post', + 'categories'=>'Categorie', + 'nopolicies'=>'Non c\'è nessuna regola.', + 'all_entries'=>'Tutti i post', + 'fol_entries'=>'La regola è applicata ai seguenti post:', + 'fol_cats'=>'La regola è applicata ai post nelle seguenti categorie:', + 'older'=>'La regola è applicata ai post più vecchi di %d giorno/i.', + 'allow'=>'Permetti di commentare', + 'block'=>'Blocca i commenti', + 'approvation'=>'I commenti devono essere approvati', + 'up'=>'Sposta in su', + 'down'=>'Sposta in giù', + 'edit'=>'Modifica', + 'delete'=>'Elimina', + 'newpol'=>'Aggiungi una nuova regola', + 'del_selected'=>'Elimina le regole selezionate', + 'select_all'=>'Seleziona tutto', + 'deselect_all'=>'Deseleziona tutto', + + # Configuration page + 'configure'=>'Configura il plugin', + 'desc_conf'=>'Qui puoi modificare le impostazioni del plugin.', + 'log_all'=>'Registra i commenti bloccati', + 'log_all_long'=>'Selezionala se vuoi registrare anche i commenti che sono bloccati.', + 'email_alert'=>'Notifica commenti via email', + 'email_alert_long'=>'Selezionala se vuoi essere informato via email quando c\'è un nuovo commento '. + 'da approvare.', + 'akismet'=>'Akismet', + 'akismet_use'=>'Abilita il controllo di Akismet', + 'akismet_key'=>'Chiave di Akismet', + 'akismet_key_long'=>'Per usare Akismet ti viene fornita una chiave. Inseriscila qui.', + 'akismet_url'=>'Indirizzo di base per Akismet', + 'akismet_url_long'=>'Penso che per il servizio gratuito di Akismet si possa usare un solo indirizzo. '. + 'Puoi anche lasciare vuoto questo campo, al suo posto si utilizzerà %s.', + 'save_conf'=>'Salva configurazione', + + # Edit policy page + 'apply_to'=>'Applica a', + 'editpol'=>'Modifica una regola', + 'createpol'=>'Crea una regola', + 'some_entries'=>'Alcuni post', + 'properties'=>'Post con precise caratteristiche', + 'se_desc'=>'Se hai selezionato l\'opzione %s, per favore inserisci i post a cui la vuoi applicare.', + 'se_fill'=>'Per favore riempi i campi con gli id dei post (entryYYMMDD-HHMMSS).', + 'po_title'=>'Caratteristiche', + 'po_desc'=>'Se hai selezionato l\'opzione %s, per seleziona le caratteristiche.', + 'po_comp'=>'I campi non sono obbligatori ma ne devi selezionare almeno uno, altrimenti la regola '. + 'sarà applicata a tutti i post.', + 'po_time'=>'Opzioni sulle date', + 'po_older'=>'Applica ai post più vecchi di ', + 'days'=>'giorni.', + 'save_policy'=>'Salva regola', + + # Delete policies page + 'del_policies'=>'Elimina regole', + 'del_descs'=>'Stai per eliminare la seguente regola: ', + 'del_descm'=>'Stai per eliminare la seguenti regoli: ', + 'sure'=>'Sei sicuro?', + 'del_subs'=>'Sì, continua l\'eliminazione', + 'del_subm'=>'Sì, continua l\'eliminazione', + 'del_cancel'=>'No, riportami al pannello', + + # Approve comments page + 'app_title'=>'Approva commenti', + 'app_desc'=>'Qui puoi approvare i commenti.', + 'app_date'=>'Data', + 'app_content'=>'Commento', + 'app_author'=>'Autore', + 'app_email'=>'Email', + 'app_ip'=>'IP', + 'app_actions'=>'Azioni', + 'app_publish'=>'Pubblica', + 'app_delete'=>'Elimina', + 'app_nocomms'=>'Non c\'è nessun commento.', + 'app_pselected'=>'Pubblica i commenti selezionati', + 'app_dselected'=>'Elimina i commenti selezionati', + 'app_other'=>'Alti Commenti', + 'app_akismet'=>'Segnalati come spam', + 'app_spamdesc'=>'Questi commenti sono stati bloccati da Akismet.', + 'app_hamsubmit'=>'Inviali ad Akismet come ham quando li pubblichi.', + 'app_pubnotham'=>'Pubblica senza inviarlo come ham', + + # Delete comments page + 'delc_title'=>'Elimina Commenti', + 'delc_descs'=>'Stai per eliminare questo commento: ', + 'delc_descm'=>'Stai per eliminare questi commenti: ', + + # Manage comments page + 'man_searcht'=>'Cerca un post', + 'man_searchd'=>'Inserisci l\'id del post di cui vuoi gestire i commenti.', + 'man_search'=>'Cerca', + 'man_commfor'=>'Commenti di %s', + 'man_spam'=>'Segnala come spam ad Akismet', + + # The simple edit + 'simple_pre'=>'In questo post i commenti ', + 'simple_1'=>'sono ammessi.', + 'simple_0'=>'richiedono la tua approvazione.', + 'simple_-1'=>'sono bloccati.', + 'simple_manage'=>'Gestisci i commenti di questo post.', + 'simple_edit'=>'Modifica le regole', + + # Akismet warnings + 'akismet_errors'=>array( + -1=>'La chiave di Akismet è vuota. Per favore inseriscila.', + -2=>'Non abbiamo potuto chiamare i server di Akismet.', + -3=>'La risposta di Akismet è fallita.', + -4=>'La chiave di Akismet non è valida.', + ), + + # Messages + 'msgs'=>array( + 1=>'Configurazione salvata.', + -1=>'Si è verificato un errore durante il salvataggio della configurazione.', + + 2=>'Regola salvata.', + -2=>'Si è verificato un errore durante il salvataggio della regola (forse le tue opzioni sono scorrette).', + + 3=>'Regola spostata.', + -3=>'Si è verificato un errore nello spostamento della regola (o non la si può muovere).', + + 4=>'Regole rimosse.', + -4=>'Si è verificato un errore durante la rimozione delle regole (o non hai selezionato nessuna regola).', + + 5=>'Commenti pubblicati.', + -5=>'Si è verificato un errore durante la pubblicazione del commento.', + + 6=>'Commenti rimossi.', + -6=>'Si è verificato un errore durante la rimozione dei commenti (o non hai selezionato nessun commento).', + + 7=>'Commento segnalato.', + -7=>'Si è verificato un errore durante la segnalazione del commento.', + ), + + # Errors + 'errors'=>array( + 'pol_nonex'=>'La regola che vuoi modificare non esiste.', + 'entry_nf'=>'Il post da te selezionato non esiste.', + ), +); +$lang['plugin']['commentcenter']=array( + 'akismet_error'=>'Akismet ha rilevato il tuo commento come SPAM.', + 'lock'=>'Siamo spiacenti ma i commenti per questo post sono chiusi.', + 'approvation'=>'Il commento è stato salvato ma l\'Amministratore lo deve approvare prima di farlo vedere.', + + # Mail for comments + 'mail_subj'=>'Nuovo commento da approvare su %s', +); + +$lang['plugin']['commentcenter']['mail_text']=<<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'; +} \ No newline at end of file diff --git a/fp-plugins/commentcenter/res/ajax.js b/fp-plugins/commentcenter/res/ajax.js new file mode 100644 index 0000000..8eba01e --- /dev/null +++ b/fp-plugins/commentcenter/res/ajax.js @@ -0,0 +1,174 @@ +/** + * This function adds an error or a success to Flatpress standard place. + */ +function fpNotify(msg, type) { + $('#errorlist').hide().html('
    \n
  • "+msg+"
  • \n
").fadeIn('slow'); + window.setTimeout(fpRemoveNotifies, 3000); +} + +/** + * This function removes the FP Notifies + */ +function fpRemoveNotifies() { + $('#errorlist ul[class!="msgs warnings"]').fadeOut('slow'); +} + +/** + * This function moves a policy. + * + * @param integer id: The policy id + * @param integer how: The size of the movement + */ +function movePolicy(id, how) { + tarid=parseInt(id)+parseInt(how); + original='tr_policy'+id; + target='tr_policy'+tarid; + tmp='tmp'+target; + + if(how<0) { + $('.'+original).insertBefore('.'+target); + } else if(how>0) { + $('.'+original).insertAfter('.'+target); + } + + $('.'+original).removeClass(original).addClass(tmp); + $('.'+target).removeClass(target).addClass(original).attr('href'); + $('.'+tmp).removeClass(tmp).addClass(target) + $('.'+target+' td').animate({'background-color' : '#78ba91'}, { + 'complete' : function() { + $(this).attr('style', ''); + } + }); + + oruh=$('a[rel=polup\\['+id+'\\]]').attr('rel', 'tmpup').attr('href'); + ordh=$('a[rel=poldown\\['+id+'\\]]').attr('rel', 'tmpdown').attr('href'); + tauh=$('a[rel=polup\\['+tarid+'\\]]').attr('rel', 'polup['+id+']').attr('href'); + tadh=$('a[rel=poldown\\['+tarid+'\\]]').attr('rel', 'poldown['+id+']').attr('href'); + $('a[rel=polup\\['+id+'\\]]').attr('href', oruh); + $('a[rel=poldown\\['+id+'\\]]').attr('href', ordh); + $('a[rel=tmpup]').attr('rel', 'polup['+tarid+']').attr('href', tauh); + $('a[rel=tmpdown]').attr('rel', 'poldown['+tarid+']').attr('href', tadh); +} + +/** + * This function is called on the click event to move up/down with AJAX the policies. + */ +function clickPolicy() { + rel=$(this).attr('rel'); + start_id=rel.indexOf('['); + end_id=rel.indexOf(']'); + id=rel.substr(start_id+1, end_id-start_id-1); + dir=rel.substr(3, start_id-3); + how=dir=='up' ? -1 : 1; + url=$(this).attr('href')+'&mod=ajax'; + succ=0; + $.ajax({ + 'url' : url, + 'success' : function(data) { + succ=1; + if(data==3) { + fpNotify(commentcenter_lang.msg3, 'notifications'); + movePolicy(id, how); + } else if(data==-3) { + fpNotify(commentcenter_lang.msg_3, 'errors'); + } else { + fpNotify(data, 'errors'); + } + } + }); + return succ==1; +} + +/** + * This is the callback for the event click to select all checkbox + */ +function checkboxa() { + rel=$(this).attr('rel'); + tdbegin=rel.indexOf('['); + tdend=rel.indexOf(']'); + td=rel.substr(tdbegin+1, tdend-tdbegin-1); + check=rel.substr(0, tdbegin)=='selectAll'; + $('.'+td+' input[type=checkbox]').attr('checked', check); + return false; +} + +/** + * This function checks for the radio buttons in the edit policy page. + */ +function radioEdit() { + if($('#fill_entries').length<1) { + return; + } + + reDone=false; + + $('input[type=radio]').click(radioClick).each(function() { + if($(this).attr('checked')) { + reDone=true; + $(this).click(); + } + }); + + if(!reDone) { + $('input[value=all_entries]').click().attr('checked', false); + } +} + +/** + * This function is the callback for the event click on radio buttons. + */ +function radioClick() { + val=$(this).attr('value'); + entries='#fill_entries'; + prop='#fill_properties'; + + if(val=='some_entries') { + show=entries; + hide=prop; + } else if(val=='properties') { + show=prop; + hide=entries; + } else { + $(entries).hide(); + $(prop).hide(); + return true; + } + + $(show).show(); + $(hide).hide(); + +} + +/** + * This function shows/hides the Akismet options at the startup. + */ +function akismetOptionsReady() { + if($('label[for=akismet_check]').length<1) { + return; + } + + $('input[name=akismet_check]').click(akismetOptionsReady); + + status=$('input[name=akismet_check]').attr('checked'); + + el=$('.akismet_opts'); + + if(status) { + el.show(); + } else { + el.hide(); + } + + return true; +} + +$(document).ready(function() { + window.setTimeout(fpRemoveNotifies, 3000); + $('a[rel*="polup"]').click(clickPolicy); + $('a[rel*="poldown"]').click(clickPolicy); + + $('.commentcenter_select').css('display', 'block').find('a').click(checkboxa); + + radioEdit(); + akismetOptionsReady(); +}); \ No newline at end of file diff --git a/fp-plugins/commentcenter/tpls/approvelist.tpl b/fp-plugins/commentcenter/tpls/approvelist.tpl new file mode 100644 index 0000000..e4516b3 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/approvelist.tpl @@ -0,0 +1,24 @@ +{include file=plugin:commentcenter/header} +{html_form} +

{$plang.app_title}

+

{$plang.app_desc}

+{assign var="fetch" value="confirm"} +{include file=plugin:commentcenter/listcomments} +{if $use_akismet} +

{$plang.app_akismet}

+

{$plang.app_spamdesc}

+{assign var="fetch" value="akismet"} +{include file=plugin:commentcenter/listcomments} +

+

+{/if} +{if $other} +

{$plang.app_other}

+{assign var="fetch" value="denided"} +{include file=plugin:commentcenter/listcomments} +{/if} +
+ {html_submit name="mpubcomm" id="mpubcomm" value=$plang.app_pselected} + {html_submit name="mdelcomm" id="mdelcomm" value=$plang.app_dselected} +
+{/html_form} diff --git a/fp-plugins/commentcenter/tpls/configure.tpl b/fp-plugins/commentcenter/tpls/configure.tpl new file mode 100644 index 0000000..f5bbf93 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/configure.tpl @@ -0,0 +1,42 @@ +{include file=plugin:commentcenter/header} +{html_form} +

{$plang.configure}

+

{$plang.desc_conf}

+ +
+
+
+
+ {$plang.log_all_long} +
+ +
+
+
+ {$plang.email_alert_long} +
+
+ +

{$plang.akismet}

+
+
+
+ +
+
+
+
+ {$plang.akismet_key_long} +
+
+
+
+ {$plang.akismet_url_long|sprintf:$smarty.const.BLOG_BASEURL} +
+
+ +
+ {html_submit name="configure" id="configure" value=$plang.save_conf} +
+ +{/html_form} diff --git a/fp-plugins/commentcenter/tpls/deletecomm.tpl b/fp-plugins/commentcenter/tpls/deletecomm.tpl new file mode 100644 index 0000000..229c57c --- /dev/null +++ b/fp-plugins/commentcenter/tpls/deletecomm.tpl @@ -0,0 +1,23 @@ +{include file=plugin:commentcenter/header} +

{$plang.delc_title}

+

{if $single}{$plang.delc_descs}{else}{$plang.delc_descm}{/if}

+{html_form} +{assign var="delete" value=true} +{assign var="fetch" value="del"} +{include file=plugin:commentcenter/listcomments} +

{$plang.sure}

+
+{if $is_managing} + +{assign var="button_suff" value="_2"} +{else} +{assign var="button_suff" value=""} +{/if} +{if $single} + {html_submit name="commdelok$button_suff" id="commdelok$button_suff" value=$plang.del_subs} +{else} + {html_submit name="commdelok$button_suff" id="commdelok$button_suff" value=$plang.del_subm} +{/if} + {html_submit name="ccancel$button_suff" id="ccancel$button_suff" value=$plang.del_cancel} +
+{/html_form} diff --git a/fp-plugins/commentcenter/tpls/deletepol.tpl b/fp-plugins/commentcenter/tpls/deletepol.tpl new file mode 100644 index 0000000..dd2a9b4 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/deletepol.tpl @@ -0,0 +1,16 @@ +{include file=plugin:commentcenter/header} +

{$plang.del_policies}

+

{if $single}{$plang.del_descs}{else}{$plang.del_descm}{/if}

+{html_form} +{assign var="delete" value=true} +{include file=plugin:commentcenter/listpolicies} +

{$plang.sure}

+
+{if $single} + {html_submit name="delok" id="delok" value=$plang.del_subs} +{else} + {html_submit name="delok" id="delok" value=$plang.del_subm} +{/if} + {html_submit name="cancel" id="cancel" value=$plang.del_cancel} +
+{/html_form} diff --git a/fp-plugins/commentcenter/tpls/editpol.tpl b/fp-plugins/commentcenter/tpls/editpol.tpl new file mode 100644 index 0000000..ed2dff5 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/editpol.tpl @@ -0,0 +1,72 @@ +{include file=plugin:commentcenter/header} +{html_form} +

{if $polnew}{$plang.newpol}{else}{$plang.editpol}{/if}

+
+
{$plang.apply_to}
+
+ +
+ +
+ +
+
+
+
+ +
+
+ + +
+

{$plang.entries}

+

{$plang.se_desc|sprintf:"`$plang.some_entries`"}

+

{$plang.se_fill}

+ +{if !empty($policy.entry) && !is_array($policy.entry)} +{assign var="parity" value=1} + +{elseif !empty($policy.entry)} +{foreach name=entries_foreach from=$policy.entry item=entry} + {if ($smarty.foreach.entries_foreach.iteration % 2)==0}
{/if} +{if ($smarty.foreach.entries_foreach.iteration % 2)==1 && $smarty.foreach.entries_foreach.last}{assign var="parity" value=1}{/if} +{/foreach} +{/if} +{if $parity==1}
{/if} + + +
+ +
+
+ +
+

{$plang.po_title}

+

{$plang.po_desc|sprintf:"`$plang.properties`"}

+

{$plang.po_comp}

+ + +
+{$plang.categories} +{list_categories type=form selected=$policy.categories} +
+ +
+{$plang.po_time} +

+ +{$plang.days}

+ + + +
+ +
+ + {html_submit name="edit_policy" id="edit_policy" value=$plang.save_policy} +
+{/html_form} diff --git a/fp-plugins/commentcenter/tpls/header.tpl b/fp-plugins/commentcenter/tpls/header.tpl new file mode 100644 index 0000000..8fe80b9 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/header.tpl @@ -0,0 +1,13 @@ +

{$plang.title}

+

{$plang.desc1}

+

{$plang.desc2}

+ + +{include file='shared:errorlist.tpl'} + + diff --git a/fp-plugins/commentcenter/tpls/listcomments.tpl b/fp-plugins/commentcenter/tpls/listcomments.tpl new file mode 100644 index 0000000..f90cbf1 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/listcomments.tpl @@ -0,0 +1,59 @@ + + +{if !$delete}{/if} + + + + + +{if !$delete}{/if} + + +{assign var="i" value=0} +{foreach from=$entries key=entryid item=entry} +{if count($entry.$fetch)>0 && !$is_managing} +{/if} +{foreach from=$entry.$fetch item=comm key=comm_id} +{assign var="i" value=$i+1} + +{if !$delete}{/if} + + + + + +{if !$delete} +{/if} + +{/foreach} +{/foreach} +{if $i==0} +{/if} + +
{$plang.app_date}{$plang.app_content}{$plang.app_author}{$plang.app_email}{$plang.app_ip}{$plang.app_actions}
{$entryid|idToSubject} ({$entryid})
{$comm.date|date_format:"%D, %T"} +{$comm.content|strip_tags} +{if $delete} + +{/if} +{if $comm.url}{$comm.name|wp_specialchars}{else}{$comm.name|wp_specialchars}{/if}{$comm.email|wp_specialchars}{$comm.ip-address} +{if $is_managing && $use_akismet} +{$plang.man_spam} +{elseif !$is_managing} +{$plang.app_publish} +{if $fetch=='akismet'} +{$plang.app_pubnotham} +{/if} +{/if} +{if $is_managing} +{assign var="rm_url" value=$action_url|cmd_link:deletecomm2:"e`$entryid`_c`$comm_id`"} +{else} +{assign var="rm_url" value=$action_url|cmd_link:deletecomm:"e`$entryid`_c`$comm_id`"} +{/if} +{$plang.app_delete} +
{$plang.app_nocomms}
+{if !$delete} + +{/if} diff --git a/fp-plugins/commentcenter/tpls/listpolicies.tpl b/fp-plugins/commentcenter/tpls/listpolicies.tpl new file mode 100644 index 0000000..3f22152 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/listpolicies.tpl @@ -0,0 +1,61 @@ + + + +{if !$delete} {/if} + + +{if !$delete} {/if} + + + +{foreach name=policies from=$policies key=id item=policy} + +{if !$delete} {/if} + +{if $policy.do==1} + +{elseif $policy.do==0} + +{elseif $policy.do==-1} + +{/if} +{if !$delete} {/if} + +{foreachelse} + + + +{/foreach} + +
{$plang.select}{$plang.criteria}{$plang.behavoir}{$plang.options}
+{if $delete} +{/if} +{if $policy.is_all} + {$plang.all_entries} +{elseif is_array($policy.entry) && count($policy.entry)>0} +{$plang.fol_entries} +
    +{foreach from=$policy.entry item=entry} +
  • {$entry|idToSubject}
  • +{/foreach} +
+{elseif !empty($policy.entry)} +{$plang.fol_entries} +
    +
  • {$policy.entry|idToSubject}
  • +
+{else} + {if count($policy.categories)>0} +

{$plang.fol_cats} + {$policy.categories|@filed}

+ {/if} + {if !empty($policy.older)} +

{$plang.older|sprintf:"`$policy.older/86400`"}

+ {/if} +{/if} +
{$plang.allow}{$plang.approvation}{$plang.block} +{$plang.up} +{$plang.down} +{$plang.edit} +{$plang.delete} +
{$plang.nopolicies}
diff --git a/fp-plugins/commentcenter/tpls/manage.tpl b/fp-plugins/commentcenter/tpls/manage.tpl new file mode 100644 index 0000000..8e844e7 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/manage.tpl @@ -0,0 +1,18 @@ +{include file=plugin:commentcenter/header} +{html_form} +

{$plang.man_searcht}

+

{$plang.man_searchd}

+

+{html_submit name="entry_search" id="entry_search" value=$plang.man_search}

+ +{if !empty($entry_id)} +{assign var="titleok" value=$entry_id|idToSubject|wp_specialchars} +

{$plang.man_commfor|sprintf:$titleok}

+{include file=plugin:commentcenter/listcomments} + +
+ {html_submit name="mdelcomm_2" id="mdelcomm_2" value=$plang.app_dselected} +
+{/if} + +{/html_form} diff --git a/fp-plugins/commentcenter/tpls/policies.tpl b/fp-plugins/commentcenter/tpls/policies.tpl new file mode 100644 index 0000000..0fc6564 --- /dev/null +++ b/fp-plugins/commentcenter/tpls/policies.tpl @@ -0,0 +1,16 @@ +{include file=plugin:commentcenter/header} +

{$plang.policies}

+

{$plang.desc_pol}

+{html_form} +{include file=plugin:commentcenter/listpolicies} + + +
+ {html_submit name="multidel" id="multidel" value=$plang.del_selected} +
+{/html_form}