HEX
Server: LiteSpeed
System: Linux emerald.serverdnsnetwork.com 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 11 08:09:09 EST 2025 x86_64
User: mahdetej (1135)
PHP: 8.1.34
Disabled: show_source, system, shell_exec, passthru, exec, popen, proc_open
Upload Files
File: /home/mahdetej/public_html/wp-content/plugins/Melli-shild/admin/class-darkshield-admin.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class DarkShield_Admin {

	private $current_hook = '';
	private $ui;

	public function __construct() {
		$this->ui = Melli_Shield_Admin_UI::instance();
		add_action( 'admin_init', array( $this, 'handle_exports' ) );
		add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
	}

	public function admin_body_class( $classes ) {
		return $classes . ' melli-shield-admin';
	}

	public function add_menu_pages() {
		$icon = 'data:image/svg+xml;base64,' . base64_encode(
			'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#a7f3d0" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>'
		);

		$parent = Melli_Shield_Config::PAGE_DASHBOARD;
		$title  = __( 'ملی شیلد', 'melli-shield' );

		add_menu_page( $title, $title, 'manage_options', $parent, array( $this, 'render_dashboard' ), $icon, 80 );

		$subs = array(
			Melli_Shield_Config::PAGE_DASHBOARD   => __( 'داشبورد', 'melli-shield' ),
			Melli_Shield_Config::PAGE_SCANNER     => __( 'اسکنر', 'melli-shield' ),
			Melli_Shield_Config::PAGE_PERFORMANCE => __( 'عملکرد', 'melli-shield' ),
			Melli_Shield_Config::PAGE_SETTINGS    => __( 'تنظیمات', 'melli-shield' ),
			Melli_Shield_Config::PAGE_LOG         => __( 'گزارش', 'melli-shield' ),
			Melli_Shield_Config::PAGE_WHITELIST   => __( 'لیست سفید', 'melli-shield' ),
			Melli_Shield_Config::PAGE_HELP        => __( 'راهنما', 'melli-shield' ),
		);

		foreach ( $subs as $slug => $label ) {
			add_submenu_page( $parent, $label, $label, 'manage_options', $slug, array( $this, $this->renderer_for( $slug ) ) );
		}
	}

	private function renderer_for( $slug ) {
		$map = array(
			Melli_Shield_Config::PAGE_DASHBOARD   => 'render_dashboard',
			Melli_Shield_Config::PAGE_SCANNER     => 'render_scanner',
			Melli_Shield_Config::PAGE_PERFORMANCE => 'render_performance',
			Melli_Shield_Config::PAGE_SETTINGS    => 'render_settings',
			Melli_Shield_Config::PAGE_LOG         => 'render_log',
			Melli_Shield_Config::PAGE_WHITELIST   => 'render_whitelist',
			Melli_Shield_Config::PAGE_HELP        => 'render_help',
		);
		return isset( $map[ $slug ] ) ? $map[ $slug ] : 'render_dashboard';
	}

	public function enqueue_assets( $hook ) {
		if ( ! in_array( $hook, Melli_Shield_Config::admin_page_hooks(), true ) ) {
			return;
		}

		$this->current_hook = $hook;

		add_action( 'admin_head', array( $this, 'print_css' ), 1 );
		add_action( 'admin_head', array( $this, 'print_config' ), 2 );
		add_action( 'admin_footer', array( $this, 'print_js' ), 1 );
	}

	public function print_css() {
		$v = MELLI_SHIELD_VERSION;
		echo '<link rel="stylesheet" id="melli-shield-admin-css" href="' . esc_url( MELLI_SHIELD_PLUGIN_URL . 'assets/css/admin.css?ver=' . $v ) . '" media="all" />' . "\n";
	}

	public function print_config() {
		$config = array(
			'ajax_url'   => admin_url( 'admin-ajax.php' ),
			'nonce'      => wp_create_nonce( Melli_Shield_Config::NONCE_ACTION ),
			'plugin_url' => MELLI_SHIELD_PLUGIN_URL,
			'strings'    => array(
				'confirm_mode'        => __( 'آیا از تغییر حالت مطمئن هستید؟', 'melli-shield' ),
				'scanning'            => __( 'در حال اسکن...', 'melli-shield' ),
				'scanning_files'      => __( 'اسکن فایل‌ها', 'melli-shield' ),
				'scanning_db'         => __( 'اسکن پایگاه‌داده', 'melli-shield' ),
				'scan_complete'       => __( 'اسکن کامل شد.', 'melli-shield' ),
				'scan_found'          => __( '%total% URL خارجی در %domains% دامنه یافت شد.', 'melli-shield' ),
				'confirm_clear'       => __( 'آیا از پاک کردن نتایج اسکن مطمئن هستید؟', 'melli-shield' ),
				'no_results'          => __( 'هنوز نتیجه‌ای ثبت نشده.', 'melli-shield' ),
				'error'               => __( 'خطایی رخ داد.', 'melli-shield' ),
				'pause'               => __( 'توقف موقت', 'melli-shield' ),
				'resume'              => __( 'ادامه', 'melli-shield' ),
				'paused_status'       => __( 'متوقف شده', 'melli-shield' ),
				'confirm_stop'        => __( 'اسکن متوقف شود؟ نتایج تا این لحظه حفظ می‌شوند.', 'melli-shield' ),
				'scan_stopped'        => __( 'اسکن متوقف شد.', 'melli-shield' ),
				'scan_stopped_detail' => __( 'توقف در %completed% از %total% دسته.', 'melli-shield' ),
			),
		);

		echo '<script type="text/javascript" id="melli-shield-config">' . "\n";
		echo 'var melli_shield_ajax = ' . wp_json_encode( $config ) . ';' . "\n";
		echo 'var darkshield_ajax = melli_shield_ajax;' . "\n";
		echo '</script>' . "\n";
	}

	public function print_js() {
		$base = MELLI_SHIELD_PLUGIN_URL . 'assets/js/';
		$v    = '?ver=' . MELLI_SHIELD_VERSION;

		echo '<script src="' . esc_url( $base . 'admin.js' . $v ) . '"></script>' . "\n";

		$scanner_hook = 'melli-shield_page_' . Melli_Shield_Config::PAGE_SCANNER;
		$perf_hook    = 'melli-shield_page_' . Melli_Shield_Config::PAGE_PERFORMANCE;

		if ( $scanner_hook === $this->current_hook ) {
			echo '<script src="' . esc_url( $base . 'scanner.js' . $v ) . '"></script>' . "\n";
		}

		if ( $perf_hook === $this->current_hook ) {
			echo '<script src="' . esc_url( $base . 'performance.js' . $v ) . '"></script>' . "\n";
		}
	}

	public function admin_bar_status( $wp_admin_bar ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$mode  = DarkShield_Utils::get_mode();
		$dots  = array(
			'normal'   => '#16a34a',
			'national' => '#d97706',
			'offline'  => '#dc2626',
		);
		$color = isset( $dots[ $mode ] ) ? $dots[ $mode ] : '#999';

		$wp_admin_bar->add_node( array(
			'id'    => 'melli-shield-status',
			'title' => '<span style="color:' . esc_attr( $color ) . '">●</span> ' .
				esc_html__( 'ملی شیلد', 'melli-shield' ) . ': ' .
				esc_html( DarkShield_Utils::get_mode_label() ),
			'href'  => Melli_Shield_Config::admin_url(),
		) );

		$subs = array(
			Melli_Shield_Config::PAGE_DASHBOARD   => __( 'داشبورد', 'melli-shield' ),
			Melli_Shield_Config::PAGE_SETTINGS    => __( 'تنظیمات', 'melli-shield' ),
			Melli_Shield_Config::PAGE_LOG         => __( 'گزارش', 'melli-shield' ),
			Melli_Shield_Config::PAGE_PERFORMANCE => __( 'عملکرد', 'melli-shield' ),
		);

		foreach ( $subs as $slug => $label ) {
			$wp_admin_bar->add_node( array(
				'parent' => 'melli-shield-status',
				'id'     => 'msh-bar-' . $slug,
				'title'  => $label,
				'href'   => Melli_Shield_Config::admin_url( $slug ),
			) );
		}

		if ( ! is_admin() ) {
			$wp_admin_bar->add_node( array(
				'parent' => 'melli-shield-status',
				'id'     => 'melli-shield-analyze-page',
				'title'  => __( 'تحلیل این صفحه', 'melli-shield' ),
				'href'   => '#melli-shield-analyze',
				'meta'   => array(
					'class' => 'melli-shield-analyze-btn darkshield-analyze-btn',
				),
			) );
		}
	}

	public function handle_exports() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		if ( isset( $_POST['melli_shield_export_log'] ) || isset( $_POST['darkshield_export_log'] ) ) {
			if ( $this->verify_nonce( 'melli_shield_log_actions' ) || $this->verify_nonce( 'darkshield_log_actions' ) ) {
				$this->export_log_csv();
			}
		}

		if ( isset( $_POST['melli_shield_export_whitelist'] ) || isset( $_POST['darkshield_export_whitelist'] ) ) {
			if ( $this->verify_nonce( 'melli_shield_whitelist_action' ) || $this->verify_nonce( 'darkshield_whitelist_action' ) ) { // phpcs:ignore
				$this->export_whitelist_txt();
			}
		}
	}

	private function export_log_csv() {
		global $wpdb;
		$table = Melli_Shield_Config::log_table();
		if ( ! DarkShield_Utils::table_exists( $table ) ) {
			return;
		}

		$where = array( '1=1' );
		$args  = array();

		$filters = array(
			'log_domain' => 'domain LIKE %s',
			'log_type'   => 'type = %s',
			'log_source' => 'source = %s',
			'log_mode'   => 'mode = %s',
		);
		foreach ( $filters as $param => $sql ) {
			$val = $this->input( $param );
			if ( '' !== $val ) {
				$where[] = $sql;
				$args[]  = ( 'log_domain' === $param ) ? '%' . $wpdb->esc_like( $val ) . '%' : $val;
			}
		}

		$status = $this->input( 'log_status' );
		if ( '' !== $status ) {
			$where[] = 'blocked = %d';
			$args[]  = (int) $status;
		}

		foreach ( array( 'log_date_from' => '>=', 'log_date_to' => '<=' ) as $param => $op ) {
			$val = $this->input( $param );
			if ( '' !== $val ) {
				$where[] = "DATE(created_at) {$op} %s";
				$args[]  = $val;
			}
		}

		$sql  = "SELECT * FROM {$table} WHERE " . implode( ' AND ', $where ) . ' ORDER BY created_at DESC';
		$rows = ! empty( $args ) ? $wpdb->get_results( $wpdb->prepare( $sql, $args ) ) : $wpdb->get_results( $sql );

		while ( ob_get_level() > 0 ) {
			ob_end_clean();
		}

		nocache_headers();
		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename=melli-shield-log-' . gmdate( 'Y-m-d-His' ) . '.csv' );

		$out = fopen( 'php://output', 'w' );
		fprintf( $out, chr( 0xEF ) . chr( 0xBB ) . chr( 0xBF ) );
		fputcsv( $out, array( 'ID', 'URL', 'Domain', 'Type', 'Source', 'Mode', 'Blocked', 'Date' ) );

		foreach ( (array) $rows as $r ) {
			fputcsv( $out, array( $r->id, $r->url, $r->domain, $r->type, $r->source, $r->mode, $r->blocked ? 'Yes' : 'No', $r->created_at ) );
		}

		fclose( $out );
		exit;
	}

	private function export_whitelist_txt() {
		$wl = new DarkShield_Whitelist();

		while ( ob_get_level() > 0 ) {
			ob_end_clean();
		}

		nocache_headers();
		header( 'Content-Type: text/plain; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename=melli-shield-whitelist-' . gmdate( 'Y-m-d' ) . '.txt' );

		echo implode( "\n", $wl->export() );
		exit;
	}

	private function input( $key ) {
		if ( isset( $_POST[ $key ] ) ) {
			return sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
		}
		if ( isset( $_GET[ $key ] ) ) {
			return sanitize_text_field( wp_unslash( $_GET[ $key ] ) );
		}
		return '';
	}

	private function verify_nonce( $action ) {
		return isset( $_POST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), $action );
	}

	public function render_dashboard() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-dashboard.php';
	}

	public function render_scanner() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-scanner.php';
	}

	public function render_performance() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-performance.php';
	}

	public function render_settings() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-settings.php';
	}

	public function render_log() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-log.php';
	}

	public function render_whitelist() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-whitelist.php';
	}

	public function render_help() {
		include MELLI_SHIELD_PLUGIN_DIR . 'admin/views/page-help.php';
	}

	public function enqueue_frontend_perf() {
		if ( is_admin() || ! current_user_can( 'manage_options' ) || ! is_admin_bar_showing() ) {
			return;
		}
		add_action( 'wp_footer', array( $this, 'print_frontend_perf_script' ), 999 );
	}

	public function print_frontend_perf_script() {
		$config = array(
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'nonce'    => wp_create_nonce( Melli_Shield_Config::NONCE_ACTION ),
		);

		echo '<script id="melli-shield-front-config">' . "\n";
		echo 'var melli_shield_front_perf = ' . wp_json_encode( $config ) . ';' . "\n";
		echo 'var darkshield_front_perf = melli_shield_front_perf;' . "\n";
		echo '</script>' . "\n";

		$url = MELLI_SHIELD_PLUGIN_URL . 'assets/js/frontend-perf.js?ver=' . MELLI_SHIELD_VERSION;
		echo '<script src="' . esc_url( $url ) . '"></script>' . "\n";
	}
}