capabilities_service = $capabilities_service; } /** * Initialize review notice functionality. * * Runs on `admin_init`, where the current user is already resolved. * * @since 1.0.24 */ public function init(): void { // Only bother users who actually work with the plugin. if (!$this->capabilities_service->can_use_selector()) { return; } if (!$this->should_show_notice()) { return; } add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']); add_action('admin_notices', [$this, 'render_notice']); } /** * Check if notice should be displayed. * * @since 1.0.24 * @return bool True if notice should be shown */ private function should_show_notice(): bool { $user_id = get_current_user_id(); // Get dismissal count $dismissal_count = (int) get_user_meta($user_id, self::DISMISSAL_COUNT_KEY, true); // The notice is shown at most MAX_DISMISSAL_COUNT times. if ($dismissal_count >= self::MAX_DISMISSAL_COUNT) { return false; } // First time: check activation time if ($dismissal_count === 0) { $activation_time = get_option('adsd_activation_time'); if (!$activation_time) { // Set activation time if not set update_option('adsd_activation_time', time()); return false; } $days_since_activation = (time() - (int) $activation_time) / DAY_IN_SECONDS; if ($days_since_activation < self::MIN_DAYS_AFTER_ACTIVATION) { return false; } return true; } // After dismissal: check time since last dismissal $last_dismissal_time = get_user_meta($user_id, self::LAST_DISMISSAL_TIME_KEY, true); if (!$last_dismissal_time) { // If dismissal count > 0 but no last dismissal time, something went wrong // Reset dismissal count and show notice after activation period delete_user_meta($user_id, self::DISMISSAL_COUNT_KEY); return $this->should_show_notice(); } // Determine days to wait based on dismissal count // After 1st dismissal (count = 1): wait 30 days // After 2nd dismissal (count = 2): wait 90 days $days_to_wait = $dismissal_count === 1 ? self::DAYS_AFTER_FIRST_DISMISSAL : self::DAYS_AFTER_SECOND_DISMISSAL; $days_since_dismissal = (time() - (int) $last_dismissal_time) / DAY_IN_SECONDS; return $days_since_dismissal >= $days_to_wait; } /** * Enqueue assets for review notice. * * @since 1.0.24 */ public function enqueue_assets(): void { // Styles are loaded via main plugin stylesheet (style.min.css) // Add inline JavaScript for dismiss functionality add_action('admin_footer', [$this, 'render_notice_script']); } /** * Render review notice HTML. * * @since 1.0.24 */ public function render_notice(): void { ?>
'Invalid nonce']); } if (!$this->capabilities_service->can_use_selector()) { wp_send_json_error(['message' => 'Insufficient permissions'], 403); } $notice_id = isset($_POST['notice_id']) ? sanitize_text_field(wp_unslash($_POST['notice_id'])) : ''; if (empty($notice_id) || $notice_id !== self::NOTICE_ID) { wp_send_json_error(['message' => 'Invalid notice ID']); } $user_id = get_current_user_id(); // Get current dismissal count $dismissal_count = (int) get_user_meta($user_id, self::DISMISSAL_COUNT_KEY, true); // Increment dismissal count $dismissal_count++; update_user_meta($user_id, self::DISMISSAL_COUNT_KEY, $dismissal_count); // Save last dismissal time update_user_meta($user_id, self::LAST_DISMISSAL_TIME_KEY, time()); wp_send_json_success([ 'message' => 'Notice dismissed', 'dismissal_count' => $dismissal_count ]); } }