page_title = __( 'Website Scanner', 'wpconsent-cookies-banner-privacy-suite' ); $this->menu_title = __( 'Scanner', 'wpconsent-cookies-banner-privacy-suite' ); parent::__construct(); } /** * Page specific Hooks. * * @return void */ public function page_hooks() { $this->views = array( 'scanner' => __( 'Scanner', 'wpconsent-cookies-banner-privacy-suite' ), 'inspector' => __( 'Inspector', 'wpconsent-cookies-banner-privacy-suite' ), 'history' => __( 'History', 'wpconsent-cookies-banner-privacy-suite' ), 'settings' => __( 'Auto Scanning', 'wpconsent-cookies-banner-privacy-suite' ), ); } /** * For this page we output a menu. * * @return void */ public function output_header_bottom() { ?> view || 'settings' === $this->view ) { $this->output_header(); ?>
view ) { $this->output_view_history(); } else { $this->output_view_settings(); } ?>
view ) { echo WPConsent_Admin_page::get_upsell_box( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped esc_html__( 'Scanning History is a PRO feature', 'wpconsent-cookies-banner-privacy-suite' ), '

' . esc_html__( 'Upgrade to WPConsent PRO to track all website scans over time. View detected services, monitor changes, and get notified when new services are found on your website.', 'wpconsent-cookies-banner-privacy-suite' ) . '

', array( 'text' => esc_html__( 'Upgrade to PRO and Unlock "Scanning History"', 'wpconsent-cookies-banner-privacy-suite' ), 'url' => esc_url( wpconsent_utm_url( 'https://wpconsent.com/lite/', 'scanner-history-page', 'main' ) ), ), array( 'text' => esc_html__( 'Learn more about all the features', 'wpconsent-cookies-banner-privacy-suite' ), 'url' => esc_url( wpconsent_utm_url( 'https://wpconsent.com/lite/', 'scanner-history-page', 'features' ) ), ) ); } else { echo WPConsent_Admin_page::get_upsell_box( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped esc_html__( 'Scheduled Automatic Scans is a PRO feature', 'wpconsent-cookies-banner-privacy-suite' ), '

' . esc_html__( 'Upgrade to WPConsent PRO to automatically update your cookie configuration when new services are detected. Get email notifications and control how long scan history is retained.', 'wpconsent-cookies-banner-privacy-suite' ) . '

', array( 'text' => esc_html__( 'Upgrade to PRO and Unlock "Scanner Settings"', 'wpconsent-cookies-banner-privacy-suite' ), 'url' => esc_url( wpconsent_utm_url( 'https://wpconsent.com/lite/', 'scanner-settings-page', 'main' ) ), ), array( 'text' => esc_html__( 'Learn more about all the features', 'wpconsent-cookies-banner-privacy-suite' ), 'url' => esc_url( wpconsent_utm_url( 'https://wpconsent.com/lite/', 'scanner-settings-page', 'features' ) ), ) ); } ?>
scan_results ) ) { $this->scan_results = wpconsent()->scanner->get_scan_data(); } return $this->scan_results; } /** * Output the page content. * * @return void */ public function output_content() { if ( 'inspector' === $this->view ) { $this->output_view_inspector(); return; } $this->metabox( esc_html__( 'Scan Overview', 'wpconsent-cookies-banner-privacy-suite' ), $this->get_scan_overview() ); $scan_data = $this->get_scan_results(); if ( empty( $scan_data['data']['scripts'] ) ) { return; } $this->metabox( __( 'Detailed Report', 'wpconsent-cookies-banner-privacy-suite' ), $this->get_scanner_input(), '', 'wpconsent-scan-detailed-report' ); } /** * Output the inspector review view. * * @return void */ public function output_view_inspector() { $pending_cookies = wpconsent()->inspector->get_pending_cookies(); $data = wpconsent()->inspector->get_categories_and_services(); $categories = $data['categories']; $services = $data['services']; $is_active = wpconsent()->inspector->is_active(); $cookies_url = admin_url( 'admin.php?page=wpconsent-cookies' ); $start_url = wp_nonce_url( admin_url( 'admin-post.php?action=wpconsent_start_inspector' ), 'wpconsent_start_inspector' ); $title = ! empty( $pending_cookies ) ? esc_html__( 'Review Cookies', 'wpconsent-cookies-banner-privacy-suite' ) . ' ' . '1 / ' . count( $pending_cookies ) . '' : esc_html__( 'Cookie Inspector', 'wpconsent-cookies-banner-privacy-suite' ); $this->metabox( $title, $this->get_inspector_unified_content( $pending_cookies, $is_active, $start_url, $cookies_url ) ); // Output data for the wizard JS (needed when pending cookies exist). if ( ! empty( $pending_cookies ) ) { ?> inspector, 'get_blocking_rules' ) ) { $blocking_rules = wpconsent()->inspector->get_blocking_rules(); } ?> output_new_service_modal( $categories ); // Output the service library modal for Pro users. if ( $is_pro ) { $this->output_service_library_modal(); } } } /** * Get the unified inspector content based on current state. * * @param array $pending_cookies Pending cookies. * @param bool $is_active Whether the inspector is currently running. * @param string $start_url URL to start the inspector. * @param string $cookies_url URL to the cookies settings page. * * @return string */ public function get_inspector_unified_content( $pending_cookies, $is_active, $start_url, $cookies_url ) { ob_start(); $mode = wpconsent()->inspector->get_inspector_mode(); if ( ! empty( $pending_cookies ) ) { // State: Pending Review -- show the wizard directly. $this->render_inspector_wizard( $pending_cookies, $start_url, $cookies_url ); } elseif ( $is_active ) { // State: Active -- inspector is running on the frontend. $this->render_inspector_active( $mode ); } else { // State: Ready -- no pending cookies, inspector not running. $this->render_inspector_ready( $start_url, $mode ); } return ob_get_clean(); } /** * Render the inspector mode badge with a short explanation. * * @param string $mode Inspector mode: 'optin', 'optout', or 'discovery'. * * @return void */ protected function render_inspector_mode_badge( $mode ) { $labels = array( 'optin' => __( 'Opt-in mode', 'wpconsent-cookies-banner-privacy-suite' ), 'optout' => __( 'Opt-out mode', 'wpconsent-cookies-banner-privacy-suite' ), 'discovery' => __( 'Discovery mode', 'wpconsent-cookies-banner-privacy-suite' ), ); $descriptions = array( 'optin' => __( 'Scripts are blocked until the visitor consents. Cookies loaded before consent are flagged as violations.', 'wpconsent-cookies-banner-privacy-suite' ), 'optout' => __( 'Scripts are allowed by default. Cookies that persist after the visitor rejects consent are flagged as violations.', 'wpconsent-cookies-banner-privacy-suite' ), 'discovery' => __( 'Script blocking is disabled. The inspector detects cookies but does not verify blocking.', 'wpconsent-cookies-banner-privacy-suite' ), ); $label = isset( $labels[ $mode ] ) ? $labels[ $mode ] : $labels['optin']; $description = isset( $descriptions[ $mode ] ) ? $descriptions[ $mode ] : $descriptions['optin']; ?>
render_inspector_mode_badge( $mode ); ?>

', '' ); ?>

render_inspector_geolocation_notice(); ?> scanner->get_scan_data() ) ) : ?>

', '' ); ?>

metabox_row_separator(); ?>

render_inspector_mode_badge( $mode ); ?>

', '' ); ?>

render_inspector_geolocation_notice(); ?> metabox_row_separator(); ?>

inspector->get_pending_pages_count(); } /** * Get the markup for the scanner. * * @return string */ public function get_scanner_input() { $previous_scan = $this->get_scan_results(); $categories = wpconsent()->cookies->get_categories(); if ( ! empty( $previous_scan ) ) { $previous_data = $previous_scan['data']; } ob_start(); ?>

$services ) { ?>

get_scan_service_template( $service ); } ?>
services_upsell_box( 'scanner' ); ?>

get_scan_results(); if ( ! empty( $scan_results ) ) { $scripts = $scan_results['data']['scripts']; $last_ran_timestamp = $scan_results['date']; $scripts_count = 0; $cookies_count = 0; foreach ( $scripts as $category => $services ) { $scripts_count += count( $services ); foreach ( $services as $service ) { $cookies_count += count( $service['cookies'] ); } } $next_scheduled_scan = esc_html__( 'Not Scheduled', 'wpconsent-cookies-banner-privacy-suite' ); if ( wpconsent()->settings->get_option( 'auto_scanner', 0 ) ) { $interval = wpconsent()->settings->get_option( 'auto_scanner_interval', 1 ); $last_ran = wpconsent()->settings->get_option( 'auto_scanner_last_ran', 0 ); $next_scheduled_scan = date_i18n( get_option( 'date_format' ), strtotime( "+{$interval} days", $last_ran ) ); } $stats_to_show = array( array( 'label' => __( 'Services Detected', 'wpconsent-cookies-banner-privacy-suite' ), 'value' => $scripts_count, ), array( 'label' => __( 'Cookies In Use', 'wpconsent-cookies-banner-privacy-suite' ), 'value' => $cookies_count, ), array( 'label' => __( 'Last Successful Scan', 'wpconsent-cookies-banner-privacy-suite' ), 'value' => date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $last_ran_timestamp ) ), ), array( 'label' => __( 'Cookies Configured', 'wpconsent-cookies-banner-privacy-suite' ), 'value' => isset( $scan_results['configured'] ), ), array( 'label' => __( 'Next Scheduled Scan', 'wpconsent-cookies-banner-privacy-suite' ), 'value' => $next_scheduled_scan, ), ); } ob_start(); if ( ! empty( $stats_to_show ) ) { ?>

metabox_row_separator(); echo $this->get_manual_scan_input(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>

', '', '' ); ?>

auto_populate_important_pages(); ob_start(); $selected_content_ids = wpconsent()->settings->get_option( 'manual_scan_pages', array() ); $pages_args = array( 'number' => 20, 'orderby' => 'title', 'order' => 'ASC', ); if ( ! empty( $selected_content_ids ) ) { $pages_args['exclude'] = $selected_content_ids; } // Let's pre-load 20 pages. $pages = get_pages( $pages_args ); ?>

get_dummy_scan_history(); ob_start(); ?>

0 ) : ?> 0 ) : ?>
metabox( esc_html__( 'Scan History', 'wpconsent-cookies-banner-privacy-suite' ), $content ); } /** * Get dummy scan history data. * * @return array */ protected function get_dummy_scan_history() { return array( array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-1 day' ) ), 'services_detected' => 8, 'new_services' => 2, 'removed_services' => 0, 'status' => array( array( 'class' => 'auto-updated', 'label' => __( 'Auto-Updated', 'wpconsent-cookies-banner-privacy-suite' ), ), array( 'class' => 'email-sent', 'label' => __( 'Email Sent', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-8 days' ) ), 'services_detected' => 6, 'new_services' => 1, 'removed_services' => 0, 'status' => array( array( 'class' => 'auto-updated', 'label' => __( 'Auto-Updated', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-15 days' ) ), 'services_detected' => 5, 'new_services' => 0, 'removed_services' => 1, 'status' => array( array( 'class' => 'neutral', 'label' => __( 'Completed', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-22 days' ) ), 'services_detected' => 6, 'new_services' => 0, 'removed_services' => 0, 'status' => array( array( 'class' => 'neutral', 'label' => __( 'Completed', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-29 days' ) ), 'services_detected' => 6, 'new_services' => 1, 'removed_services' => 0, 'status' => array( array( 'class' => 'auto-updated', 'label' => __( 'Auto-Updated', 'wpconsent-cookies-banner-privacy-suite' ), ), array( 'class' => 'email-sent', 'label' => __( 'Email Sent', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-36 days' ) ), 'services_detected' => 5, 'new_services' => 0, 'removed_services' => 0, 'status' => array( array( 'class' => 'neutral', 'label' => __( 'Completed', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-43 days' ) ), 'services_detected' => 5, 'new_services' => 2, 'removed_services' => 0, 'status' => array( array( 'class' => 'auto-updated', 'label' => __( 'Auto-Updated', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-50 days' ) ), 'services_detected' => 3, 'new_services' => 0, 'removed_services' => 1, 'status' => array( array( 'class' => 'email-sent', 'label' => __( 'Email Sent', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-57 days' ) ), 'services_detected' => 4, 'new_services' => 1, 'removed_services' => 0, 'status' => array( array( 'class' => 'auto-updated', 'label' => __( 'Auto-Updated', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), array( 'scan_date' => wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( '-64 days' ) ), 'services_detected' => 3, 'new_services' => 0, 'removed_services' => 0, 'status' => array( array( 'class' => 'neutral', 'label' => __( 'Completed', 'wpconsent-cookies-banner-privacy-suite' ), ), ), ), ); } /** * Output the settings view with dummy data. * * @return void */ protected function output_view_settings() { ob_start(); ?>

metabox_row_separator(); ?>

metabox_row_separator(); ?>

metabox_row_separator(); ?>

metabox_row_separator(); ?>

metabox( esc_html__( 'Scanner Settings', 'wpconsent-cookies-banner-privacy-suite' ), $content ); } }