<?php
/**
* This file implements the UI controller for Central Antispam module
*
* b2evolution - {@link http://b2evolution.net/}
* Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
* @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
*
* @package admin
* @author fplanque: Francois PLANQUE.
*/
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
global $central_antispam_Module;
load_funcs( 'central_antispam/model/_central_antispam.funcs.php' );
load_class( 'central_antispam/model/_keyword.class.php', 'CaKeyword' );
load_class( 'central_antispam/model/_source.class.php', 'CaSource' );
// Check permission:
check_user_perm( 'centralantispam', 'view', true );
param_action( '', true );
param( 'tab', 'string', 'keywords', true );
switch( $tab )
{
case 'keywords':
if( param( 'cakw_ID', 'integer', '', true ) )
{ // Load keyword from cache:
$CaKeywordCache = & get_CaKeywordCache();
if( ( $edited_CaKeyword = & $CaKeywordCache->get_by_ID( $cakw_ID, false ) ) === false )
{
unset( $edited_CaKeyword );
forget_param( 'cakw_ID' );
$Messages->add( sprintf( TB_('Requested «%s» object does not exist any longer.'), TB_('Keyword') ), 'error' );
$action = 'nil';
}
}
break;
case 'reporters':
if( param( 'casrc_ID', 'integer', '', true ) )
{ // Load source from cache:
$CaSourceCache = & get_CaSourceCache();
if( ( $edited_CaSource = & $CaSourceCache->get_by_ID( $casrc_ID, false ) ) === false )
{
unset( $edited_CaSource );
forget_param( 'casrc_ID' );
$Messages->add( sprintf( TB_('Requested «%s» object does not exist any longer.'), TB_('Reporter') ), 'error' );
$action = 'nil';
}
}
break;
}
switch( $action )
{
case 'keyword_new':
// Check permission:
check_user_perm( 'centralantispam', 'create', true );
if( ! isset( $edited_CaKeyword ) )
{ // We don't have a model to use, start with blank object:
$edited_CaKeyword = new CaKeyword();
$edited_CaKeyword->set( 'status', 'published' );
}
break;
case 'keyword_create':
$edited_CaKeyword = new CaKeyword();
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'cakeyword' );
// Check permission:
check_user_perm( 'centralantispam', 'edit', true );
// load data from request
if( $edited_CaKeyword->load_from_Request() )
{ // We could load data from form without errors:
$DB->begin();
$duplicated_keyword_ID = $edited_CaKeyword->dbexists( 'cakw_keyword', $edited_CaKeyword->keyword );
if( $duplicated_keyword_ID && $duplicated_keyword_ID != $edited_CaKeyword->ID )
{ // We have a duplicate entry:
param_error( 'cakw_keyword',
sprintf( TB_('This keyword already exists. Do you want to <a %s>edit the existing keyword</a>?'),
'href="?ctrl=central_antispam&tab=keywords&action=keyword_edit&cakw_ID='.$duplicated_keyword_ID.'"' ) );
$action = 'keyword_new';
}
else
{
$edited_CaKeyword->set( 'lastreport_ts', $edited_CaKeyword->get( 'statuschange_ts' ) );
$edited_CaKeyword->dbinsert();
// Check if the Reporter/Source already exists in DB
$source_SQL = new SQL( 'Get source of current baseurl for central antispam' );
$source_SQL->SELECT( 'casrc_ID, casrc_status' );
$source_SQL->FROM( 'T_centralantispam__source' );
$source_SQL->WHERE( 'casrc_baseurl = '.$DB->quote( $baseurl ) );
$source_row = $DB->get_row( $source_SQL, ARRAY_A );
$source_ID = empty( $source_row ) ? 0 : intval( $source_row['casrc_ID'] );
if( empty( $source_ID ) )
{ // Create new reporter if it doesn't exist in DB yet:
$DB->query( 'INSERT INTO T_centralantispam__source
( casrc_baseurl, casrc_status ) VALUES
( '.$DB->quote( $baseurl ).', "trusted" )' );
$source_ID = $DB->insert_id;
}
elseif( $source_row['casrc_status'] != 'trusted' )
{ // Make current baseurl as trusted source:
$DB->query( 'UPDATE T_centralantispam__source
SET casrc_status = "trusted"
WHERE casrc_ID = '.$source_ID );
}
// Insert reports to know from what host new keyword was added:
$DB->query( 'INSERT INTO T_centralantispam__report ( carpt_cakw_ID, carpt_casrc_ID, carpt_ts )
VALUES ( '.$edited_CaKeyword->ID.', '.$source_ID.', '.$DB->quote( $edited_CaKeyword->get( 'statuschange_ts' ) ).' )' );
$Messages->add( TB_('New keyword added.'), 'success' );
}
$DB->commit();
if( ! param_errors_detected() )
{
header_redirect( $admin_url.'?ctrl=central_antispam&tab=keywords', 303 );
break;
}
}
break;
case 'keyword_save':
// Update keyword record:
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'cakeyword' );
// Check permission:
check_user_perm( 'centralantispam', 'edit', true );
// load data from request
if( $edited_CaKeyword->load_from_Request() )
{ // We could load data from form without errors:
$duplicated_keyword_ID = $edited_CaKeyword->dbexists( 'cakw_keyword', $edited_CaKeyword->keyword );
if( $duplicated_keyword_ID && $duplicated_keyword_ID != $edited_CaKeyword->ID )
{ // We have a duplicate entry:
param_error( 'cakw_keyword',
sprintf( TB_('This keyword already exists. Do you want to <a %s>edit the existing keyword</a>?'),
'href="?ctrl=central_antispam&tab=keywords&action=keyword_edit&cakw_ID='.$duplicated_keyword_ID.'"' ) );
}
else
{
$edited_CaKeyword->dbupdate();
$Messages->add( TB_('The keyword has been saved.'), 'success' );
header_redirect( $admin_url.'?ctrl=central_antispam&tab=keywords', 303 );
}
}
$action = 'keyword_edit';
break;
case 'source_save':
// Update source record:
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'casource' );
// Check permission:
check_user_perm( 'centralantispam', 'edit', true );
// Load data from request:
if( $edited_CaSource->load_from_Request() )
{ // We could load data from form without errors:
$edited_CaSource->dbupdate();
$Messages->add( TB_('The source has been saved.'), 'success' );
header_redirect( $admin_url.'?ctrl=central_antispam&tab=reporters', 303 );
}
$action = 'source_edit';
break;
case 'import':
if( ! param( 'confirm', 'integer', 0 ) )
{ // The import action must be confirmed:
break;
}
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'cakeywordsimport' );
// Check permission:
check_user_perm( 'centralantispam', 'edit', true );
$import_keywords = param( 'import_keywords', 'array:string' );
if( empty( $import_keywords ) )
{ // No selected keywords to import:
$Messages->add( TB_('Please select keywords to import.'), 'error' );
$action = 'import';
break;
}
// Get start dates for keywords:
$keyword_dates = array();
foreach( $import_keywords as $keyword_source )
{
param_date( 'date_start_'.$keyword_source, TB_('Invalid date'), true );
param_time( 'time_start_'.$keyword_source );
$keyword_dates[ $keyword_source ] = strtotime( form_date( get_param( 'date_start_'.$keyword_source ), get_param( 'time_start_'.$keyword_source ) ) );
}
if( param_errors_detected() )
{ // Don't allow to import with wrong entered data:
break;
}
$DB->begin();
$keywords_SQL = new SQL( 'Get keywords that will be imported as local reports' );
$keywords_SQL->SELECT( 'askw_string, askw_source' );
$keywords_SQL->FROM( 'T_antispam__keyword' );
$keywords_SQL->WHERE( 'askw_string NOT IN ( SELECT cakw_keyword FROM T_centralantispam__keyword )' );
$keywords_SQL->WHERE_and( 'askw_source IN( '.$DB->quote( $import_keywords ).' )' );
$new_keywords = $DB->get_results( $keywords_SQL, ARRAY_A );
$keywords_imported_count = array();
if( count( $new_keywords ) )
{ // If there are new keywords to import:
// Check if the Reporter/Source already exists in DB
$source_SQL = new SQL( 'Get source of current baseurl for central antispam' );
$source_SQL->SELECT( 'casrc_ID, casrc_status' );
$source_SQL->FROM( 'T_centralantispam__source' );
$source_SQL->WHERE( 'casrc_baseurl = '.$DB->quote( $baseurl ) );
$source_row = $DB->get_row( $source_SQL, ARRAY_A );
$source_ID = empty( $source_row ) ? 0 : intval( $source_row['casrc_ID'] );
if( empty( $source_ID ) )
{ // Create new reporter if it doesn't exist in DB yet:
$DB->query( 'INSERT INTO T_centralantispam__source
( casrc_baseurl, casrc_status ) VALUES
( '.$DB->quote( $baseurl ).', "trusted" )' );
$source_ID = $DB->insert_id;
}
elseif( $source_row['casrc_status'] != 'trusted' )
{ // Make current baseurl as trusted source:
$DB->query( 'UPDATE T_centralantispam__source
SET casrc_status = "trusted"
WHERE casrc_ID = '.$source_ID );
}
$keywords_reports = array();
foreach( $new_keywords as $keyword )
{
$keyword_timestamp = date( 'Y-m-d H:i:s', $keyword_dates[ $keyword['askw_source'] ] );
if( $keyword['askw_source'] == 'central' && $keyword_timestamp > '2014-02-24 21:10:18' )
{ // Limit central keywords by this max date:
$keyword_timestamp = '2014-02-24 21:10:18';
}
// Insert new keyword:
$query_result = $DB->query( 'INSERT INTO T_centralantispam__keyword
( cakw_keyword, cakw_status, cakw_statuschange_ts, cakw_lastreport_ts ) VALUES
( '.$DB->quote( $keyword['askw_string'] ).', "published", '.$DB->quote( $keyword_timestamp ).', '.$DB->quote( $keyword_timestamp ).' )' );
if( $query_result )
{ // If new keyword has been inserted:
if( ! isset( $keywords_imported_count[ $keyword['askw_source'] ] ) )
{
$keywords_imported_count[ $keyword['askw_source'] ] = 0;
}
$keywords_imported_count[ $keyword['askw_source'] ]++;
$keyword_ID = $DB->insert_id;
$keywords_reports[] = '( '.$DB->insert_id.', '.$source_ID.', '.$DB->quote( $keyword_timestamp ).' )';
}
// Increase 1 second for next keyword:
$keyword_dates[ $keyword['askw_source'] ]++;
}
if( count( $keywords_imported_count ) )
{ // Insert reports to know from what host new keyword was added:
$DB->query( 'INSERT INTO T_centralantispam__report
( carpt_cakw_ID, carpt_casrc_ID, carpt_ts ) VALUES '
.implode( ', ', $keywords_reports ) );
}
}
foreach( $keywords_imported_count as $keywords_source => $keywords_count )
{
$Messages->add( sprintf( TB_('%d new keywords have been imported as "%s" reports.'), $keywords_count, $keywords_source ), 'success' );
}
$DB->commit();
$action = '';
break;
}
// Highlight the requested tab (if valid):
$AdminUI->set_path( 'central_antispam', $tab );
$AdminUI->breadcrumbpath_init( false );
$AdminUI->breadcrumbpath_add( TB_('Central Antispam'), $admin_url.'?ctrl=central_antispam' );
switch( $tab )
{
case 'keywords':
$AdminUI->breadcrumbpath_add( TB_('Keywords'), $admin_url.'?ctrl=central_antispam&tab='.$tab );
if( $action == 'import' )
{
$AdminUI->breadcrumbpath_add( TB_('Import'), $admin_url.'?ctrl=central_antispam&action='.$action );
// Initialize date picker:
init_datepicker_js();
}
if( empty( $action ) && check_user_perm( 'centralantispam', 'edit' ) )
{ // Load JS to edit keyword status from list:
require_js_defer( '#jquery#', 'rsc_url' );
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js', 'rsc_url' );
}
break;
case 'reporters':
$AdminUI->breadcrumbpath_add( TB_('Reporters'), $admin_url.'?ctrl=central_antispam&tab='.$tab );
if( empty( $action ) && check_user_perm( 'centralantispam', 'edit' ) )
{ // Load JS to edit source status from list:
require_js_defer( '#jquery#', 'rsc_url' );
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js', 'rsc_url' );
}
break;
}
// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
$AdminUI->disp_html_head();
// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
$AdminUI->disp_body_top();
// Begin payload block:
$AdminUI->disp_payload_begin();
switch( $action )
{
case 'keyword_new':
$AdminUI->disp_view( 'central_antispam/views/_keywords.form.php' );
break;
case 'keyword_edit':
$AdminUI->disp_view( 'central_antispam/views/_keywords.form.php' );
break;
case 'source_edit':
$AdminUI->disp_view( 'central_antispam/views/_sources.form.php' );
break;
case 'import':
$AdminUI->disp_view( 'central_antispam/views/_keywords_import.view.php' );
break;
default:
switch( $tab )
{
case 'keywords':
$AdminUI->disp_view( 'central_antispam/views/_keywords.view.php' );
break;
case 'reporters':
$AdminUI->disp_view( 'central_antispam/views/_sources.view.php' );
break;
}
break;
}
// End payload block:
$AdminUI->disp_payload_end();
// Display body bottom, debug info and close </html>:
$AdminUI->disp_global_footer();
?>