Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/antispam/antispam.ctrl.php
<?php
/**
 * This file implements the UI controller for the antispam management.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
 * Parts of this file are copyright (c)2004 by Vegar BERG GULDAL - {@link http://funky-m.com/}.
 *
 * @package admin
 *
 * @todo Allow applying / re-checking of the known data, not just after an update!
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );

param( 'display_mode', 'string' );

if(
$display_mode != 'js' )
{
   
$AdminUI->set_path( 'options', 'antispam' );
}
else
{    
// This is an Ajax response
    // fp> TODO: have a more systematic way of handling AJAX responses
   
header_content_type( 'text/html', $io_charset );
}

param_action( '' );
param( 'confirm', 'string' );
param( 'keyword', 'string', '', true );
param( 'domain', 'string' );
param( 'filteron', 'string', '', true );
if(
$action == 'iprange_edit' )
{    
// Memorize action for users and sessions list below edit form:
   
memorize_param( 'action', 'string', '', $action );
}
else
{    
// Don't initialize this param as array because it must be string for UserList:
   
param( 'filter', 'array:string', array() );
}

$tab = param( 'tab', 'string', '', true );
$tab3 = param( 'tab3', 'string', '', true );
$tool = param( 'tool', 'string', '', true );

if( isset(
$filter['off']) )
{
    unset(
$filteron );
   
forget_param( 'filteron' );
}

// Check permission:
if( ! ( check_user_perm( 'admin', 'normal' ) && check_user_perm( 'spamblacklist', 'view' ) ) &&
        ! (
check_user_perm( 'users', 'moderate' ) && ( ( $tab3 == 'tools' && $tool == 'whois' && empty( $action ) ) || $action == 'whois' ) ) )
{
   
debug_die( sprintf( /* %s is the application name, usually "b2evolution" */ TB_('Group/user permission denied by %s!'), $app_name ) );
}


if(
param( 'iprange_ID', 'integer', '', true) )
{    
// Load IP Range object
   
load_class( 'antispam/model/_iprange.class.php', 'IPRange' );
   
$IPRangeCache = & get_IPRangeCache();
    if( (
$edited_IPRange = & $IPRangeCache->get_by_ID( $iprange_ID, false ) ) === false )
    {    
// We could not find the goal to edit:
       
unset( $edited_IPRange );
       
forget_param( 'iprange_ID' );
       
$Messages->add( sprintf( TB_('Requested &laquo;%s&raquo; object does not exist any longer.'), TB_('IP Range') ), 'error' );
    }
}

switch(
$action )
{
    case
'ban': // only an action if further "actions" given
        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true ); // TODO: This should become different for 'edit'/'add' perm level - check for 'add' here.

       
$keyword = utf8_substr( $keyword, 0, 80 );
       
param( 'delhits', 'integer', 0 );
       
$all_statuses = get_visibility_statuses( 'keys', array( 'trash', 'redirected' ) );
       
$delstatuses = array();
        foreach(
$all_statuses as $status )
        {
// collect which comments should be delteded
           
if( param( 'del'.$status, 'integer', 0 ) )
            {
// matching comments with this status should be deleted
               
$delstatuses[] = $status;
            }
        }
       
$delcomments = count( $delstatuses );
       
param( 'blacklist_locally', 'integer', 0 );
       
param( 'report', 'integer', 0 );

       
// Check if the string is too short,
        // it has to be a minimum of 5 characters to avoid being too generic
       
if( utf8_strlen( $keyword ) < 5 )
        {
           
$Messages->add( sprintf( TB_('The keyword &laquo;%s&raquo; is too short, it has to be a minimum of 5 characters!'), htmlspecialchars( $keyword ) ), 'error' );
            break;
        }

        if( empty(
$confirm ) )
        {
// No confirmed action, Execute the ban actions only after confirmation
           
break;
        }

        if(
$delhits )
        {
// Delete all banned hit-log entries
           
$r = $DB->query( 'DELETE FROM T_hitlog
                                                WHERE hit_referer LIKE '
.$DB->quote( '%'.$keyword.'%' ),
                                               
'Delete all banned hit-log entries' );

           
$Messages->add_to_group( sprintf( TB_('Deleted %d logged hits matching &laquo;%s&raquo;.'), $r, htmlspecialchars( $keyword ) ), 'success', TB_('Banning keyword:') );
        }

        if(
$delcomments )
        {
// select banned comments
           
$del_condition = blog_restrict( $delstatuses );
           
$keyword_cond = '(comment_author LIKE '.$DB->quote( '%'.$keyword.'%' ).'
                            OR comment_author_email LIKE '
.$DB->quote( '%'.utf8_strtolower( $keyword ).'%' ).'
                            OR comment_author_url LIKE '
.$DB->quote( '%'.$keyword.'%' ).'
                            OR comment_content LIKE '
.$DB->quote( '%'.$keyword.'%' ).')';
           
// asimo> we don't need transaction here
           
$query = 'SELECT comment_ID FROM T_comments
                            WHERE '
.$keyword_cond.$del_condition;
           
$deleted_ids = $DB->get_col( $query, 0, 'Get comment ids awaiting for delete' );
           
$r = count( $deleted_ids );
           
$deleted_ids = implode( ',', $deleted_ids );

           
// Delete all comments data from DB
           
Comment::db_delete_where( $keyword_cond.$del_condition );

           
$Messages->add_to_group( sprintf( TB_('Deleted %d comments matching &laquo;%s&raquo;.'), $r, htmlspecialchars( $keyword ) ), 'success', TB_('Banning keyword:') );
        }

        if(
$blacklist_locally )
        {
// Local blacklist:
           
if( antispam_create( $keyword ) )
            {
// Success
               
$Messages->add_to_group( sprintf( TB_('The keyword &laquo;%s&raquo; has been blacklisted locally.'), htmlspecialchars( $keyword ) ), 'success', TB_('Banning keyword:') );
            }
            else
            {
// Failed
               
$Messages->add( sprintf( TB_('Failed to add the keyword %s to black list locally.'), '<b>'.htmlspecialchars( $keyword ).'</b>' ), 'error' );
            }
        }

        if(
$report )
        {
// Report this keyword as abuse remotely:
           
antispam_report_abuse( $keyword );
        }

        if( !
$blacklist_locally && ! $report && ! $delhits && ! $delcomments )
        {
// If no action has been selected
           
$Messages->add( TB_('Please select at least one action to ban the keyword.' ), 'error' );
        }

        if(
$display_mode != 'js' && ! $Messages->has_errors() )
        {
           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=antispam', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}

        if(
$display_mode == 'js' && ! $Messages->has_errors() )
        {    
// Initialize JS functions to execute after action from modal window:
           
$javascript_messages = array();
            if(
$delcomments && $r ) // $r not null => means the commentlist was deleted successfully
           
{
               
$javascript_messages['refreshAfterBan'] = array( $deleted_ids );
            }
           
$javascript_messages['closeModalAfterBan'] = array();
        }

       
// We'll ask the user later what to do, if no "sub-action" given.
       
break;


    case
'remove':
       
// Remove a domain from ban list:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
param( 'hit_ID', 'integer', true );    // Required!
       
$Messages->add( sprintf( TB_('Removing entry #%d from the ban list...'), $hit_ID), 'note' );
       
antispam_delete( $hit_ID );
        break;


    case
'report':
       
// Report an entry as abuse to centralized blacklist:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
// Report this keyword as abuse:
       
antispam_report_abuse( $keyword );
        break;


    case
'poll':
       
// request abuse list from central blacklist:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
ob_start();
       
antispam_poll_abuse();
       
$Debuglog->add( ob_get_contents(), 'antispam_poll' );
       
ob_end_clean();
        break;

    case
'update':
       
// Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// fp> Restore defaults has been removed because it's extra maintenance work and no real benefit to the user.

       
param_integer_range( 'antispam_threshold_publish', -100, 100, TB_('The threshold must be between -100 and 100.') );
       
$Settings->set( 'antispam_threshold_publish', $antispam_threshold_publish );

       
param_integer_range( 'antispam_threshold_delete', -100, 100, TB_('The threshold must be between -100 and 100.') );
       
$Settings->set( 'antispam_threshold_delete', $antispam_threshold_delete );

       
param( 'antispam_block_contact_form', 'integer', 0 );
       
$Settings->set( 'antispam_block_contact_form', $antispam_block_contact_form );

       
param( 'antispam_block_spam_referers', 'integer', 0 );
       
$Settings->set( 'antispam_block_spam_referers', $antispam_block_spam_referers );

       
param( 'antispam_report_to_central', 'integer', 0 );
       
$Settings->set( 'antispam_report_to_central', $antispam_report_to_central );

       
$changed_weight = false;
       
param( 'antispam_plugin_spam_weight', 'array:integer', array() );
        foreach(
$antispam_plugin_spam_weight as $l_plugin_ID => $l_weight )
        {
            if( !
is_numeric($l_weight) )
            {
                continue;
            }
            if(
$l_weight < 0 || $l_weight > 100 )
            {
               
param_error( 'antispam_plugin_spam_weight['.$l_plugin_ID.']', TB_('Spam weight has to be in the range of 0-100.') );
                continue;
            }
            if(
$DB->query( '
                    UPDATE T_plugins
                         SET plug_spam_weight = '
.$DB->quote($l_weight).'
                     WHERE plug_ID = '
.(int)$l_plugin_ID ) )
            {
               
$changed_weight = true;
            }
        }
        if(
$changed_weight )
        {
// Reload plugins table (for display):
           
$Plugins->loaded_plugins_table = false;
           
$Plugins->load_plugins_table();
        }

       
// Suspicious users
       
$Settings->set( 'antispam_suspicious_group', param( 'antispam_suspicious_group', 'integer', 0 ) );

       
// Trust groups
       
$trust_groups = param( 'antispam_trust_groups', 'array:integer', array() );
       
$Settings->set( 'antispam_trust_groups', implode( ',', $trust_groups ) );

        if( !
$Messages->has_errors() )
        {
           
$Settings->dbupdate();

           
$Messages->add( TB_('Settings updated.'), 'success' );
           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=antispam&tab3=settings', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}

    case
'find_spam_comments':
       
// Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
$keywords = $DB->get_col( 'SELECT askw_string FROM T_antispam__keyword' );
       
$keywords = array_chunk( $keywords, 100 );
       
$rows_affected = 0;

        @
ignore_user_abort(true);
       
set_max_execution_time(900);

       
// Delete comments in chunks of 100 keywords per SQL query
       
foreach( $keywords as $chunk )
        {
           
$arr = array();
            foreach(
$chunk as $word )
            {
               
$arr[] = $DB->quote('%'.$word.'%');
            }

           
$DB->query('DELETE FROM T_comments
                        WHERE (comment_author LIKE '
.implode(' OR comment_author LIKE ', $arr).')
                        OR (comment_author_email LIKE '
.implode(' OR comment_author_email LIKE ', $arr).')
                        OR (comment_author_url LIKE '
.implode(' OR comment_author_url LIKE ', $arr).')
                        OR (comment_content LIKE '
.implode(' OR comment_content LIKE ', $arr).')',
                       
'Delete spam comments');

           
$rows_affected = $rows_affected + $DB->rows_affected;
        }
       
$Messages->add( sprintf( TB_('Deleted %d comments'), $rows_affected ), 'success' );
        break;

    case
'find_spam_referers':
       
// Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
$keywords = $DB->get_col( 'SELECT askw_string FROM T_antispam__keyword' );
       
$keywords = array_chunk( $keywords, 100 );
       
$rows_affected = 0;

        @
ignore_user_abort(true);
       
set_max_execution_time(900);

       
// Delete hits in chunks of 100 keywords per SQL query
       
foreach( $keywords as $chunk )
        {
           
$arr = array();
            foreach(
$chunk as $word )
            {
               
$arr[] = $DB->quote('%'.$word.'%');
            }

           
$DB->query('DELETE FROM T_hitlog
                        WHERE hit_referer LIKE '
.implode(' OR hit_referer LIKE ', $arr),
                       
'Delete all banned hit-log entries' );

           
$rows_affected = $rows_affected + $DB->rows_affected;
        }
       
$Messages->add( sprintf( TB_('Deleted %d logged hits'), $rows_affected ), 'success' );
        break;

    case
'iprange_create':
       
// Create new IP Range...

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'iprange' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
$edited_IPRange = new IPRange();

       
// load data from request
       
if( $edited_IPRange->load_from_Request() )
        {    
// We could load data from form without errors:
            // Insert in DB:
           
$edited_IPRange->dbinsert();
           
$Messages->add( TB_('New IP Range created.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=antispam&tab3=ipranges&iprange_ID='.$edited_IPRange->ID.'&action=iprange_edit&filter=new', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'iprange_new';
        break;

    case
'iprange_update':
       
// Update IP Range...

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'iprange' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
// Make sure we got an iprange_ID:
       
param( 'iprange_ID', 'integer', true );

       
// load data from request
       
if( $edited_IPRange->load_from_Request() )
        {    
// We could load data from form without errors:
            // Update IP Range in DB:
           
$edited_IPRange->dbupdate();
           
$Messages->add( TB_('IP Range updated.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=antispam&tab='.$tab.'&tab3=ipranges&iprange_ID='.$edited_IPRange->ID.'&action=iprange_edit', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'iprange_edit';
        break;

    case
'iprange_delete':
       
// Delete IP Range...

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'iprange' );

       
// Check permission:
       
check_user_perm( 'spamblacklist', 'edit', true );

       
// Make sure we got an iprange_ID:
       
param( 'iprange_ID', 'integer', true );

        if(
$edited_IPRange->dbdelete() )
        {
           
$Messages->add( TB_('IP Range deleted.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( '?ctrl=antispam&tab='.$tab.'&tab3=ipranges', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
        break;

    case
'bankruptcy_delete':
       
// Delete ALL comments from selected blogs

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'antispam' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
$bankruptcy_blogs_IDs = param( 'bankruptcy_blogs', 'array:integer', array() );

        if( empty(
$bankruptcy_blogs ) )
        {
           
$Messages->add( TB_('Please select at least one blog.'), 'error' );
        }

        if( !
param_errors_detected() )
        {
// Try to obtain some serious time to do some serious processing (15 minutes)
           
set_max_execution_time( 900 );
           
// Turn off the output buffering to do the correct work of the function flush()
           
@ini_set( 'output_buffering', 'off' );
           
// Set this to start deleting in the template file
           
$delete_bankruptcy_blogs = true;
        }
        break;

    case
'whois':
       
$tab = '';
       
$tab3 = 'tools';
       
$tool = 'whois';
       
$query = param( 'query', 'string', NULL );
        if( empty(
$query ) )
        {
           
param_error( 'query', TB_('You must specify an IP address or domain to query') );
        }
        else
        {
           
$template_action = 'whois';
        }
        break;
}

if(
$display_mode != 'js' )
{
    if(
$tab == 'stats' )
    {
       
// We should activate toolbar menu items for this controller and tab
       
$activate_collection_toolbar = true;

        if( isset(
$collections_Module ) )
        {
// Display list of blogs:
           
if( check_user_perm( 'stats', 'view' ) )
            {
               
$AdminUI->set_coll_list_params( 'stats', 'view', array( 'ctrl' => 'antispam', 'tab' => $tab, 'tab3' => $tab3 ), TB_('All'),
                               
$admin_url.'?ctrl=antispam&amp;tab='.$tab.'&amp;tab3='.$tab3.'&amp;blog=0', NULL, false, true );
            }
            else
            {
// No permission to view aggregated stats:
               
$AdminUI->set_coll_list_params( 'stats', 'view', array( 'ctrl' => 'antispam', 'tab' => $tab, 'tab3' => $tab3 ), NULL,
                       
'', NULL, false, true );
            }
        }
       
$AdminUI->breadcrumbpath_init( true, array( 'text' => TB_('Analytics'), 'url' => '?ctrl=stats&amp;blog=$blog$' ) );
       
$AdminUI->breadcrumbpath_add( TB_('IPs'), $admin_url.'?ctrl=stats&amp;blog=$blog$&amp;tab='.$tab );
       
$AdminUI->breadcrumbpath_add( TB_('IP Ranges'), $admin_url.'?ctrl=stats&amp;blog=$blog$&amp;tab='.$tab.'&amp;tab3='.$tab3 );
       
$AdminUI->set_path( 'stats', 'ips', 'ranges' );
    }
    else
    {
       
$AdminUI->breadcrumbpath_init( false );  // fp> I'm playing with the idea of keeping the current blog in the path here...
       
$AdminUI->breadcrumbpath_add( TB_('System'), $admin_url.'?ctrl=system' );
       
$AdminUI->breadcrumbpath_add( TB_('Antispam'), $admin_url.'?ctrl=antispam' );
    }

    if( empty(
$tab3 ) )
    {
       
$tab3 = 'blacklist';
    }
    switch(
$tab3 )
    {
        case
'settings':
           
$AdminUI->breadcrumbpath_add( TB_('Settings'), '?ctrl=antispam&amp;tab3='.$tab3 );
           
init_hotkeys_js();

           
// Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'antispam-settings' );
            break;

        case
'tools':
           
$AdminUI->breadcrumbpath_add( TB_('Tools'), '?ctrl=antispam&amp;tab3='.$tab3 );

           
// Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'antispam-tools' );
            break;

        case
'blacklist':
           
$AdminUI->breadcrumbpath_add( TB_('Blacklist'), '?ctrl=antispam' );

           
// Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'antispam-tab' );
            break;

        case
'ipranges':
            if( empty(
$action ) )
            {    
// View a list of IP ranges
               
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js', 'rsc_url' );
            }
            elseif( !
check_user_perm( 'spamblacklist', 'edit' ) )
            {    
// Check permission to create/edit IP range
               
$Messages->add( TB_('You have no permission to edit this IP range!'), 'error' );
               
$action = '';
            }
           
$AdminUI->breadcrumbpath_add( TB_('IP Ranges'), '?ctrl=antispam&amp;tab3='.$tab3 );

           
// Set an url for manual page:
           
if( $action == 'iprange_new' || $action == 'iprange_edit' )
            {
               
init_tokeninput_js();
               
$AdminUI->set_page_manual_link( 'ip-range-editing' );
            }
            else
            {
               
$AdminUI->set_page_manual_link( 'ip-ranges' );
            }
            break;

        case
'countries':
            if(
check_user_perm( 'options', 'edit' ) )
            {
               
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js' );
            }

           
// Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'countries-list' );

           
$AdminUI->breadcrumbpath_add( TB_('Countries'), '?ctrl=antispam&amp;tab3='.$tab3 );
            break;

        case
'domains':
           
load_funcs('sessions/model/_hitlog.funcs.php');
           
$AdminUI->breadcrumbpath_add( TB_('Referring domains'), '?ctrl=antispam&amp;tab3='.$tab3 );
            if(
check_user_perm( 'stats', 'edit' ) )
            {
               
require_js_defer( 'customized:jquery/jeditable/jquery.jeditable.js' );
            }
           
// Load jquery UI to highlight cell on change domain type
           
require_js_defer( '#jqueryUI#' );
           
// Used for edit form
           
$tab_from = 'antispam';
           
$blog = 0; // Don't restrict domains by blog ID on this controller

            // Set an url for manual page:
           
$AdminUI->set_page_manual_link( 'referring-domains-tab' );
            break;
    }

    if( !empty(
$tab3 ) )
    {
       
$AdminUI->append_path_level( $tab3 );
    }
}

if(
in_array( $action, array( 'iprange_edit' ) ) )
{
// Initialize date picker
   
init_datepicker_js();
   
// Load jQuery QueryBuilder plugin files for user list filters:
   
init_querybuilder_js( 'rsc_url' );
   
// Initialize Hotkeys
   
init_hotkeys_js();
}

// 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(
$tab3 )
{
    case
'settings':
       
$AdminUI->disp_view( 'antispam/views/_antispam_settings.form.php' );
        break;

    case
'tools':
       
// Check permission:
       
if( $tool != 'whois' )
        {
           
check_user_perm( 'options', 'edit', true );
        }

        switch(
$tool )
        {
            case
'bankruptcy':
               
$comment_status = param( 'comment_status', 'string', 'draft' );
               
$AdminUI->disp_view( 'antispam/views/_antispam_tools_bankruptcy.view.php' );
                break;

            case
'whois';
               
$AdminUI->disp_view( 'antispam/views/_antispam_whois.view.php' );
                break;

            default:
               
$AdminUI->disp_view( 'antispam/views/_antispam_tools.view.php' );
                break;
        }
        break;

    case
'ipranges':
        switch(
$action )
        {
            case
'iprange_new':
                if( ! isset(
$edited_IPRange ) )
                {
// Define new IPRange object only when it was not defined before, e.g. in action 'iprange_create'
                   
$edited_IPRange = new IPRange();
                }
               
// Set IP Start and End from _GET request
               
$ip = param( 'ip', 'string', '' );
               
$ip_start = param( 'ip_start', 'string', '' );
               
$ip_end = param( 'ip_end', 'string', '' );
                if( ! empty(
$ip ) && is_valid_ip_format( $ip ) &&
                    (
$ip = explode( '.', $ip ) ) && count( $ip ) == 4 )
                {    
// Prefill from single IP address:
                   
$edited_IPRange->set( 'IPv4start', ip2int( implode( '.', array( $ip[0], $ip[1], $ip[2], 0 ) ) ) );
                   
$edited_IPRange->set( 'IPv4end', ip2int( implode( '.', array( $ip[0], $ip[1], $ip[2], 255 ) ) ) );
                }
                else
                {    
// Prefill from start and end IP addresses:
                   
if( ! empty( $ip_start ) && is_valid_ip_format( $ip_start ) )
                    {
                       
$edited_IPRange->set( 'IPv4start', ip2int( $ip_start ) );
                    }
                    if( ! empty(
$ip_end ) && is_valid_ip_format( $ip_end ) )
                    {
                       
$edited_IPRange->set( 'IPv4end', ip2int( $ip_end ) );
                    }
                }
               
$AdminUI->disp_view( 'antispam/views/_antispam_ipranges.form.php' );
                break;

            case
'iprange_edit':
               
$AdminUI->disp_view( 'antispam/views/_antispam_ipranges.form.php' );
                break;

            default:    
// View list of the IP Ranges
               
$AdminUI->disp_view( 'antispam/views/_antispam_ipranges.view.php' );
                break;
        }
        break;

    case
'countries':
       
$AdminUI->disp_view( 'regional/views/_country_list.view.php' );
        break;

    case
'domains':
       
$AdminUI->disp_view( 'sessions/views/_stats_refdomains.view.php' );
        break;

    case
'blacklist':
    default:
        if( ! empty(
$javascript_messages ) )
        {    
// Don't display form and list when we should update a content from modal window by JS:
           
break;
        }

        if(
$action == 'ban' && ( ! $Messages->has_errors() || ! empty( $confirm ) ) && !( $delhits || $delcomments ) )
        {    
// Nothing to do, ask user:
           
$AdminUI->disp_view( 'antispam/views/_antispam_ban.form.php' );
        }
        else
        {    
// Display blacklist:
           
$AdminUI->disp_view( 'antispam/views/_antispam_list.view.php' );
        }
        break;
}

// End payload block:
$AdminUI->disp_payload_end();

// Display body bottom, debug info and close </html>:
$AdminUI->disp_global_footer();


if( ! empty(
$javascript_messages ) )
{    
// Execute JS functions after action from modal window:
   
send_javascript_message( $javascript_messages, true, 'window.parent' );
}
?>