File: /home/mahdetej/public_html/wp-content/plugins/Melli-shild/admin/views/page-log.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $wpdb;
$table = Melli_Shield_Config::log_table();
Melli_Shield_Utils::ensure_tables();
$ok = Melli_Shield_Utils::table_exists( $table );
$log_cleared = false;
if ( isset( $_POST['melli_shield_clear_log'] ) || isset( $_POST['melli_shield_clear_log'] ) ) {
if ( isset( $_POST['_wpnonce'] ) && (
wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'melli_shield_clear_log' ) ||
wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'melli_shield_clear_log' )
) && $ok ) {
$wpdb->query( "TRUNCATE TABLE {$table}" );
$log_cleared = true;
}
}
// Filters
$fd = isset( $_GET['log_domain'] ) ? sanitize_text_field( wp_unslash( $_GET['log_domain'] ) ) : '';
$ft = isset( $_GET['log_type'] ) ? sanitize_text_field( wp_unslash( $_GET['log_type'] ) ) : '';
$fs = isset( $_GET['log_source'] ) ? sanitize_text_field( wp_unslash( $_GET['log_source'] ) ) : '';
$fm = isset( $_GET['log_mode'] ) ? sanitize_text_field( wp_unslash( $_GET['log_mode'] ) ) : '';
$fb = isset( $_GET['log_status'] ) ? sanitize_text_field( wp_unslash( $_GET['log_status'] ) ) : '';
$fdf = isset( $_GET['log_date_from'] ) ? sanitize_text_field( wp_unslash( $_GET['log_date_from'] ) ) : '';
$fdt = isset( $_GET['log_date_to'] ) ? sanitize_text_field( wp_unslash( $_GET['log_date_to'] ) ) : '';
$w = array( '1=1' );
$a = array();
if ( $fd ) { $w[] = 'domain LIKE %s'; $a[] = '%' . $wpdb->esc_like( $fd ) . '%'; }
if ( $ft ) { $w[] = 'type = %s'; $a[] = $ft; }
if ( $fs ) { $w[] = 'source = %s'; $a[] = $fs; }
if ( $fm ) { $w[] = 'mode = %s'; $a[] = $fm; }
if ( '' !== $fb ) { $w[] = 'blocked = %d'; $a[] = (int) $fb; }
if ( $fdf ) { $w[] = 'DATE(created_at) >= %s'; $a[] = $fdf; }
if ( $fdt ) { $w[] = 'DATE(created_at) <= %s'; $a[] = $fdt; }
$ws = implode( ' AND ', $w );
$paged = max( 1, isset( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1 );
$pp = 50;
$off = ( $paged - 1 ) * $pp;
$total = 0; $logs = array();
$types = array(); $sources = array(); $modes = array();
$st = 0; $sb = 0; $sa = 0;
if ( $ok ) {
if ( ! empty( $a ) ) {
$total = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} WHERE {$ws}", $a ) );
$qa = $a;
$qa[] = $pp;
$qa[] = $off;
$logs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$ws} ORDER BY created_at DESC LIMIT %d OFFSET %d", $qa ) );
} else {
$total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" );
$logs = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} ORDER BY created_at DESC LIMIT %d OFFSET %d", $pp, $off ) );
}
$types = $wpdb->get_col( "SELECT DISTINCT type FROM {$table} WHERE type!='' ORDER BY type" );
$sources = $wpdb->get_col( "SELECT DISTINCT source FROM {$table} WHERE source!='' ORDER BY source" );
$modes = $wpdb->get_col( "SELECT DISTINCT mode FROM {$table} WHERE mode!='' ORDER BY mode" );
$st = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" );
$sb = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table} WHERE blocked=1" );
$sa = $st - $sb;
}
$tp = ceil( $total / max( $pp, 1 ) );
$hf = $fd || $ft || $fs || $fm || '' !== $fb || $fdf || $fdt;
$dash = Melli_Shield_Utils::get_dashboard_stats();
?>
<?php $ui = Melli_Shield_Admin_UI::instance(); ?>
<div class="wrap">
<?php $ui->header( Melli_Shield_Config::PAGE_LOG ); ?>
<?php $ui->page_title( __( 'گزارش', 'melli-shield' ), __( 'جزئیات مسدودسازیها — با فیلتر تاریخ و سایت', 'melli-shield' ) ); ?>
<?php if ( $log_cleared ) : ?>
<div class="msh-notice msh-notice--success"><?php esc_html_e( 'گزارشها پاک شدند.', 'melli-shield' ); ?></div>
<?php endif; ?>
<div class="msh-kpi-strip" role="list">
<span class="msh-kpi msh-kpi--block" role="listitem">
<span class="msh-kpi__num"><?php echo esc_html( number_format_i18n( $dash['blocked_today'] ) ); ?></span>
<span class="msh-kpi__label"><?php esc_html_e( 'امروز', 'melli-shield' ); ?></span>
</span>
<span class="msh-kpi msh-kpi--block" role="listitem">
<span class="msh-kpi__num"><?php echo esc_html( number_format_i18n( $dash['blocked_period'] ) ); ?></span>
<span class="msh-kpi__label">
<?php
printf(
/* translators: %d: retention days */
esc_html__( 'مسدود · %d روز', 'melli-shield' ),
(int) $dash['retention_days']
);
?>
</span>
</span>
<span class="msh-kpi" role="listitem">
<span class="msh-kpi__num"><?php echo esc_html( number_format_i18n( $total ) ); ?></span>
<span class="msh-kpi__label"><?php echo $hf ? esc_html__( 'فیلتر', 'melli-shield' ) : esc_html__( 'همه', 'melli-shield' ); ?></span>
</span>
<span class="msh-kpi" role="listitem">
<span class="msh-kpi__num"><?php echo esc_html( number_format_i18n( $dash['unique_domains'] ) ); ?></span>
<span class="msh-kpi__label"><?php esc_html_e( 'سایت خارجی', 'melli-shield' ); ?></span>
</span>
</div>
<form method="get" class="msh-filters">
<input type="hidden" name="page" value="<?php echo esc_attr( Melli_Shield_Config::PAGE_LOG ); ?>" />
<div class="msh-form-field">
<label><?php esc_html_e( 'دامنه', 'melli-shield' ); ?></label>
<input type="text" name="log_domain" class="msh-input" value="<?php echo esc_attr( $fd ); ?>" />
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'نوع', 'melli-shield' ); ?></label>
<select name="log_type" class="msh-input">
<option value=""><?php esc_html_e( 'همه', 'melli-shield' ); ?></option>
<?php foreach ( $types as $t ) : ?>
<option value="<?php echo esc_attr( $t ); ?>" <?php selected( $ft, $t ); ?>><?php echo esc_html( $t ); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'منبع', 'melli-shield' ); ?></label>
<select name="log_source" class="msh-input">
<option value=""><?php esc_html_e( 'همه', 'melli-shield' ); ?></option>
<?php foreach ( $sources as $s ) : ?>
<option value="<?php echo esc_attr( $s ); ?>" <?php selected( $fs, $s ); ?>><?php echo esc_html( $s ); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'حالت', 'melli-shield' ); ?></label>
<select name="log_mode" class="msh-input">
<option value=""><?php esc_html_e( 'همه', 'melli-shield' ); ?></option>
<?php foreach ( $modes as $m ) : ?>
<option value="<?php echo esc_attr( $m ); ?>" <?php selected( $fm, $m ); ?>><?php echo esc_html( $m ); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'وضعیت', 'melli-shield' ); ?></label>
<select name="log_status" class="msh-input">
<option value=""><?php esc_html_e( 'همه', 'melli-shield' ); ?></option>
<option value="1" <?php selected( $fb, '1' ); ?>><?php esc_html_e( 'مسدود', 'melli-shield' ); ?></option>
<option value="0" <?php selected( $fb, '0' ); ?>><?php esc_html_e( 'مجاز', 'melli-shield' ); ?></option>
</select>
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'از تاریخ', 'melli-shield' ); ?></label>
<input type="date" name="log_date_from" class="msh-input" value="<?php echo esc_attr( $fdf ); ?>" />
</div>
<div class="msh-form-field">
<label><?php esc_html_e( 'تا تاریخ', 'melli-shield' ); ?></label>
<input type="date" name="log_date_to" class="msh-input" value="<?php echo esc_attr( $fdt ); ?>" />
</div>
<button type="submit" class="msh-btn msh-btn--sm"><?php esc_html_e( 'اعمال فیلتر', 'melli-shield' ); ?></button>
<?php if ( $hf ) : ?>
<a href="<?php echo esc_url( Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_LOG ) ); ?>" class="msh-btn msh-btn--ghost msh-btn--sm"><?php esc_html_e( 'بازنشانی', 'melli-shield' ); ?></a>
<?php endif; ?>
</form>
<div class="msh-btn-row msh-mb-md">
<form method="post" onsubmit="return confirm('<?php echo esc_js( __( 'همه گزارشها پاک شوند؟', 'melli-shield' ) ); ?>');">
<?php wp_nonce_field( 'melli_shield_clear_log' ); ?>
<button type="submit" name="melli_shield_clear_log" value="1" class="msh-btn msh-btn--danger msh-btn--sm"><?php esc_html_e( 'پاک کردن همه', 'melli-shield' ); ?></button>
</form>
<form method="post" action="<?php echo esc_url( Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_LOG ) ); ?>">
<?php wp_nonce_field( 'melli_shield_log_actions' ); ?>
<?php
foreach ( array( 'log_domain', 'log_type', 'log_source', 'log_mode', 'log_status', 'log_date_from', 'log_date_to' ) as $ep ) {
$ev = isset( $_GET[ $ep ] ) ? sanitize_text_field( wp_unslash( $_GET[ $ep ] ) ) : '';
if ( '' !== $ev ) {
echo '<input type="hidden" name="' . esc_attr( $ep ) . '" value="' . esc_attr( $ev ) . '" />';
}
}
?>
<button type="submit" name="melli_shield_export_log" value="1" class="msh-btn msh-btn--ghost msh-btn--sm"><?php esc_html_e( 'خروجی CSV', 'melli-shield' ); ?></button>
</form>
<?php if ( $hf ) : ?>
<span class="msh-card__hint msh-mb-md" style="margin-bottom:0;"><?php esc_html_e( 'خروجی فقط شامل نتایج فیلترشده است.', 'melli-shield' ); ?></span>
<?php endif; ?>
</div>
<?php if ( ! empty( $logs ) ) : ?>
<div class="msh-card">
<div class="msh-table-wrap">
<table class="msh-table">
<thead>
<tr>
<th style="width:50px;"><?php esc_html_e( 'شناسه', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'URL', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'سایت', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'نوع', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'منبع', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'حالت', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'وضعیت', 'melli-shield' ); ?></th>
<th><?php esc_html_e( 'تاریخ', 'melli-shield' ); ?></th>
</tr>
</thead>
<tbody>
<?php
$mi = array( 'national' => '🟡', 'offline' => '🔴', 'normal' => '🟢' );
foreach ( $logs as $log ) :
$mode_class = isset( $mi[ $log->mode ] ) ? 'msh-mode-label--' . esc_attr( $log->mode ) : 'msh-text-muted';
$li = isset( $mi[ $log->mode ] ) ? $mi[ $log->mode ] : '';
?>
<tr>
<td><?php echo esc_html( $log->id ); ?></td>
<td><code><?php echo esc_html( Melli_Shield_Utils::truncate( $log->url, 100 ) ); ?></code></td>
<td>
<code><?php echo esc_html( $log->domain ); ?></code>
<?php if ( Melli_Shield_Utils::is_whitelisted( $log->domain ) ) : ?>
<br><span class="msh-badge msh-badge--muted"><?php esc_html_e( 'لیست سفید', 'melli-shield' ); ?></span>
<?php endif; ?>
<?php if ( Melli_Shield_Utils::is_allowed_service( $log->domain ) ) : ?>
<br><span class="msh-badge msh-badge--ok"><?php esc_html_e( 'سرویس', 'melli-shield' ); ?></span>
<?php endif; ?>
</td>
<td><span class="msh-badge msh-badge--muted"><?php echo esc_html( $log->type ); ?></span></td>
<td class="msh-text-sm"><?php echo esc_html( Melli_Shield_Utils::get_log_source_label( $log->source ) ); ?></td>
<td><span class="<?php echo esc_attr( $mode_class ); ?>"><?php echo esc_html( trim( $li . ' ' . ucfirst( $log->mode ) ) ); ?></span></td>
<td>
<?php if ( $log->blocked ) : ?>
<span class="msh-badge msh-badge--fail"><?php esc_html_e( 'مسدود', 'melli-shield' ); ?></span>
<?php else : ?>
<span class="msh-badge msh-badge--ok"><?php esc_html_e( 'مجاز', 'melli-shield' ); ?></span>
<?php endif; ?>
</td>
<td class="msh-text-xs" style="white-space:nowrap;">
<?php echo esc_html( $log->created_at ); ?>
<br><small class="msh-text-muted"><?php printf( esc_html__( '%s پیش', 'melli-shield' ), esc_html( human_time_diff( strtotime( $log->created_at ), current_time( 'timestamp' ) ) ) ); ?></small>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if ( $tp > 1 ) : ?>
<div class="tablenav bottom" style="margin-top:14px;">
<div class="tablenav-pages">
<?php
$base = Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_LOG );
$fmap = array( 'fd' => 'log_domain', 'ft' => 'log_type', 'fs' => 'log_source', 'fm' => 'log_mode', 'fb' => 'log_status', 'fdf' => 'log_date_from', 'fdt' => 'log_date_to' );
foreach ( $fmap as $var => $param ) {
if ( ! empty( $$var ) || '0' === $$var ) {
$base = add_query_arg( $param, $$var, $base );
}
}
echo paginate_links(
array(
'base' => add_query_arg( 'paged', '%#%', $base ),
'format' => '',
'prev_text' => '«',
'next_text' => '»',
'total' => $tp,
'current' => $paged,
)
);
?>
<span class="displaying-num" style="margin-right:10px;">
<?php
printf(
esc_html__( '%1$s تا %2$s از %3$s', 'melli-shield' ),
number_format_i18n( $off + 1 ),
number_format_i18n( min( $off + $pp, $total ) ),
number_format_i18n( $total )
);
?>
</span>
</div>
</div>
<?php endif; ?>
</div>
<?php elseif ( $ok ) : ?>
<div class="msh-empty">
<?php if ( $hf ) : ?>
<?php esc_html_e( 'با این فیلتر نتیجهای نیست.', 'melli-shield' ); ?>
<a href="<?php echo esc_url( Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_LOG ) ); ?>"><?php esc_html_e( 'بازنشانی', 'melli-shield' ); ?></a>
<?php else : ?>
<?php esc_html_e( 'هنوز گزارشی ثبت نشده. در حالت ملی یا آفلاین، مسدودسازیها اینجا ظاهر میشوند.', 'melli-shield' ); ?>
<?php endif; ?>
</div>
<?php else : ?>
<div class="msh-notice msh-notice--error"><?php esc_html_e( 'جدول گزارش یافت نشد. پلاگین را غیرفعال و دوباره فعال کنید.', 'melli-shield' ); ?></div>
<?php endif; ?>
<?php if ( $ok && $st > 0 ) : ?>
<div class="msh-card msh-mt-md">
<div class="msh-btn-row msh-text-sm msh-text-muted">
<span><strong><?php esc_html_e( 'نگهداری گزارش:', 'melli-shield' ); ?></strong> <?php echo esc_html( Melli_Shield_Utils::get_setting( 'log_retention', 30 ) ); ?> <?php esc_html_e( 'روز — بعد از آن خودکار پاک میشود', 'melli-shield' ); ?></span>
<span><strong><?php esc_html_e( 'ثبت گزارش:', 'melli-shield' ); ?></strong>
<?php echo Melli_Shield_Utils::get_setting( 'log_enabled', 1 ) ? esc_html__( 'فعال', 'melli-shield' ) : esc_html__( 'غیرفعال', 'melli-shield' ); ?>
</span>
<a href="<?php echo esc_url( Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_DASHBOARD ) ); ?>" class="msh-btn msh-btn--ghost msh-btn--sm"><?php esc_html_e( 'داشبورد', 'melli-shield' ); ?></a>
<a href="<?php echo esc_url( Melli_Shield_Config::admin_url( Melli_Shield_Config::PAGE_SETTINGS ) ); ?>" class="msh-btn msh-btn--ghost msh-btn--sm" style="margin-right:auto;"><?php esc_html_e( 'تنظیمات گزارش', 'melli-shield' ); ?></a>
</div>
</div>
<?php endif; ?>
<?php $ui->footer(); ?>
</div>