analytics_hook_suffix = add_submenu_page( 'edit.php?post_type=affistyle_box', __( 'Click Analytics', 'affistyle' ), __( 'Analytics 📊', 'affistyle' ), 'manage_options', 'affistyle-analytics', array( $this, 'render_analytics_page' ) ); $this->importer_hook_suffix = add_submenu_page( 'edit.php?post_type=affistyle_box', __( 'Import & Migrate', 'affistyle' ), __( 'Import / Migrate 📥', 'affistyle' ), 'manage_options', 'affistyle-importer', array( $this, 'render_importer_page' ) ); } /** * Enqueue assets specifically for AffiStyle admin screens. * * @param string $hook Current admin page hook. */ public function enqueue_admin_assets( $hook ) { if ( $hook === $this->analytics_hook_suffix ) { wp_enqueue_style( 'affistyle-admin-css', AFFISTYLE_URL . 'assets/css/admin-style.css', array(), AFFISTYLE_VERSION ); wp_enqueue_script( 'affistyle-admin-analytics', AFFISTYLE_URL . 'assets/js/admin-analytics.js', array(), AFFISTYLE_VERSION, array( 'strategy' => 'defer', 'in_footer' => true, ) ); $affistyle_date_range = '7'; $affistyle_start_date = ''; $affistyle_end_date = ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['date_range'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $affistyle_date_range = sanitize_text_field( wp_unslash( $_GET['date_range'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $affistyle_start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $affistyle_end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : ''; } $chart_data = class_exists( 'AffiStyle_Database' ) ? AffiStyle_Database::get_clicks_time_series( $affistyle_date_range, $affistyle_start_date, $affistyle_end_date ) : array( 'labels' => array(), 'full_labels' => array(), 'data' => array(), 'interval' => 'daily', 'total_clicks' => 0, 'max_value' => 0, ); wp_localize_script( 'affistyle-admin-analytics', 'affistyleAnalyticsData', array( 'chart' => $chart_data, 'strings' => array( 'clicks' => __( 'Clicks', 'affistyle' ), 'click' => __( 'Click', 'affistyle' ), 'noData' => __( 'No click activity recorded in this period.', 'affistyle' ), 'allZeros' => __( '0 Clicks in this timeframe', 'affistyle' ), ), ) ); } if ( $hook === $this->importer_hook_suffix ) { wp_enqueue_style( 'affistyle-admin-css', AFFISTYLE_URL . 'assets/css/admin-style.css', array(), AFFISTYLE_VERSION ); wp_enqueue_script( 'affistyle-admin-importer', AFFISTYLE_URL . 'assets/js/admin-importer.js', array( 'jquery' ), AFFISTYLE_VERSION, array( 'strategy' => 'defer', 'in_footer' => true, ) ); wp_localize_script( 'affistyle-admin-importer', 'affistyleImporterL10n', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'affistyle_importer_nonce' ), 'scanning' => __( 'Scanning database for affiliate plugins...', 'affistyle' ), 'loadingItems' => __( 'Loading source items...', 'affistyle' ), 'importing' => __( 'Importing items into AffiStyle...', 'affistyle' ), 'importComplete' => __( '✓ Import finished!', 'affistyle' ), 'confirmBatchImport' => __( 'Are you sure you want to import these items into AffiStyle boxes?', 'affistyle' ), 'noItemsSelected' => __( 'Please select at least one item to import.', 'affistyle' ), 'viewBox' => __( 'Edit Box', 'affistyle' ), 'errorOccurred' => __( 'An error occurred during import. Please try again.', 'affistyle' ), ) ); } } /** * Render the Analytics Dashboard view. */ public function render_analytics_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'affistyle' ) ); } $view_file = AFFISTYLE_PATH . 'admin/views/analytics-page.php'; if ( file_exists( $view_file ) ) { include_once $view_file; } else { echo '

' . esc_html__( 'Analytics view file missing.', 'affistyle' ) . '

'; } } /** * Render the Importer Dashboard view. */ public function render_importer_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'affistyle' ) ); } $view_file = AFFISTYLE_PATH . 'admin/views/importer-page.php'; if ( file_exists( $view_file ) ) { include_once $view_file; } else { echo '

' . esc_html__( 'Importer view file missing.', 'affistyle' ) . '

'; } } /** * AJAX handler: Scan database for affiliate sources. */ public function ajax_importer_scan() { check_ajax_referer( 'affistyle_importer_nonce', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Permission denied.', 'affistyle' ) ) ); } if ( ! class_exists( 'AffiStyle_Importer' ) ) { wp_send_json_error( array( 'message' => __( 'Importer engine missing.', 'affistyle' ) ) ); } $sources = AffiStyle_Importer::detect_sources(); wp_send_json_success( array( 'sources' => $sources ) ); } /** * AJAX handler: Fetch items from a given source for preview or selective import. */ public function ajax_importer_get_items() { check_ajax_referer( 'affistyle_importer_nonce', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Permission denied.', 'affistyle' ) ) ); } $source = isset( $_POST['source'] ) ? sanitize_key( wp_unslash( $_POST['source'] ) ) : ''; $limit = isset( $_POST['limit'] ) ? absint( wp_unslash( $_POST['limit'] ) ) : 50; $offset = isset( $_POST['offset'] ) ? absint( wp_unslash( $_POST['offset'] ) ) : 0; if ( empty( $source ) || ! class_exists( 'AffiStyle_Importer' ) ) { wp_send_json_error( array( 'message' => __( 'Invalid source provider specified.', 'affistyle' ) ) ); } $items = AffiStyle_Importer::get_source_items( $source, $limit, $offset ); wp_send_json_success( array( 'items' => $items ) ); } /** * AJAX handler: Import a batch of items chunk by chunk. */ public function ajax_importer_batch_import() { check_ajax_referer( 'affistyle_importer_nonce', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Permission denied.', 'affistyle' ) ) ); } $items = isset( $_POST['items'] ) && is_array( $_POST['items'] ) ? wp_unslash( $_POST['items'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $skip_duplicates = isset( $_POST['skip_duplicates'] ) ? '1' === sanitize_text_field( wp_unslash( $_POST['skip_duplicates'] ) ) : true; $default_style = isset( $_POST['default_style'] ) ? sanitize_key( wp_unslash( $_POST['default_style'] ) ) : 'style-1'; if ( empty( $items ) || ! class_exists( 'AffiStyle_Importer' ) ) { wp_send_json_error( array( 'message' => __( 'No items provided for import.', 'affistyle' ) ) ); } $options = array( 'skip_duplicates' => $skip_duplicates, 'default_style' => $default_style, ); $results = array(); foreach ( $items as $raw_item ) { if ( is_array( $raw_item ) ) { $results[] = AffiStyle_Importer::import_item( $raw_item, $options ); } } wp_send_json_success( array( 'results' => $results ) ); } }