load_settings(); add_filter( 'cron_schedules', array( $this, 'add_cron_schedules' ) ); if ( Rayetun_AG_Modules::is_enabled( 'email_digest' ) ) { $this->maybe_schedule(); add_action( 'rayetun_ag_send_weekly_digest', array( $this, 'send_digest' ) ); add_action( 'rayetun_ag_send_monthly_digest', array( $this, 'send_digest' ) ); } add_action( 'wp_ajax_rayetun_ag_save_digest_settings', array( $this, 'handle_save_settings' ) ); add_action( 'wp_ajax_rayetun_ag_send_test_digest', array( $this, 'handle_send_test' ) ); } private function load_settings() { $this->settings = wp_parse_args( get_option( 'rayetun_ag_digest_settings', array() ), array( 'enabled' => true, 'frequency' => 'weekly', 'email' => get_option( 'admin_email' ), 'agency_name' => '', ) ); } public function add_cron_schedules( $schedules ) { if ( ! isset( $schedules['rayetun_ag_weekly'] ) ) { $schedules['rayetun_ag_weekly'] = array( 'interval' => WEEK_IN_SECONDS, 'display' => __( 'Once Weekly (AgentGarrison)', 'agentgarrison' ), ); } if ( ! isset( $schedules['rayetun_ag_monthly'] ) ) { $schedules['rayetun_ag_monthly'] = array( 'interval' => 30 * DAY_IN_SECONDS, 'display' => __( 'Once Monthly (AgentGarrison)', 'agentgarrison' ), ); } return $schedules; } private function maybe_schedule() { $freq = $this->settings['frequency']; $hook = 'weekly' === $freq ? 'rayetun_ag_send_weekly_digest' : 'rayetun_ag_send_monthly_digest'; $other = 'weekly' === $freq ? 'rayetun_ag_send_monthly_digest' : 'rayetun_ag_send_weekly_digest'; // Clear the non-active one. $old = wp_next_scheduled( $other ); if ( $old ) { wp_unschedule_event( $old, $other ); } if ( ! wp_next_scheduled( $hook ) ) { wp_schedule_event( time(), 'rayetun_ag_' . $freq, $hook ); } } // ------------------------------------------------------------------------- // Digest builder // ------------------------------------------------------------------------- public function build_digest_data( $days = 7 ) { global $wpdb; $since = gmdate( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) ); $visits_table = $wpdb->prefix . Rayetun_AG_DB::BOT_VISITS_TABLE; $referrals_table = $wpdb->prefix . Rayetun_AG_DB::REFERRALS_TABLE; $total_visits = (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE visited_at > %s', $visits_table, $since ) ); $top_bots = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( 'SELECT bot_name, COUNT(*) as cnt FROM %i WHERE visited_at > %s GROUP BY bot_name ORDER BY cnt DESC LIMIT 5', $visits_table, $since ), ARRAY_A ); $total_referrals = (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( 'SELECT COUNT(*) FROM %i WHERE visited_at > %s', $referrals_table, $since ) ); $top_referral_platforms = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery $wpdb->prepare( 'SELECT platform, COUNT(*) as cnt FROM %i WHERE visited_at > %s GROUP BY platform ORDER BY cnt DESC LIMIT 5', $referrals_table, $since ), ARRAY_A ); $score_data = Rayetun_AG_Visibility_Score::get_instance()->get_score(); return array( 'period' => $days, 'total_visits' => $total_visits, 'top_bots' => $top_bots, 'total_referrals' => $total_referrals, 'top_referral_platforms' => $top_referral_platforms, 'visibility_score' => $score_data['score'] ?? 0, 'visibility_grade' => $score_data['grade'] ?? 'F', 'site_name' => get_bloginfo( 'name' ), 'site_url' => home_url( '/' ), 'dashboard_url' => admin_url( 'admin.php?page=agentgarrison' ), ); } public function send_digest( $days = null ) { $freq = $this->settings['frequency']; $days = is_int( $days ) ? $days : ( 'monthly' === $freq ? 30 : 7 ); $email = sanitize_email( $this->settings['email'] ); if ( ! $email ) { return; } $data = $this->build_digest_data( $days ); $subject = sprintf( /* translators: 1: site name, 2: period label */ __( '[AgentGarrison] %1$s โ %2$s AI Visibility Report', 'agentgarrison' ), $data['site_name'], 'monthly' === $freq ? __( 'Monthly', 'agentgarrison' ) : __( 'Weekly', 'agentgarrison' ) ); $body = $this->build_email_html( $data ); $headers = array( 'Content-Type: text/html; charset=UTF-8' ); wp_mail( $email, $subject, $body, $headers ); } private function build_email_html( $data ) { $agency = sanitize_text_field( $this->settings['agency_name'] ); $from = $agency ? $agency : 'AgentGarrison'; $top_bots_html = ''; foreach ( $data['top_bots'] as $bot ) { $top_bots_html .= '