post_type && current_user_can( 'edit_post', $post->ID ) ) { $has_summary = AI_Summary_Generator_Core::has_summary( $post->ID ); $needs_regen = AI_Summary_Generator_Core::needs_regeneration( $post->ID ); $url = wp_nonce_url( admin_url( 'admin-ajax.php?action=ai_summary_generator_generate_summary&post_id=' . $post->ID ), 'ai_summary_action' ); if ( $has_summary ) { if ( $needs_regen ) { echo '' . esc_html__( 'Regenerate AI Summary (Outdated)', 'ai-summary-generator' ) . ''; } else { echo '' . esc_html__( 'Regenerate AI Summary', 'ai-summary-generator' ) . ''; } } else { echo '' . esc_html__( 'Generate AI Summary', 'ai-summary-generator' ) . ''; } } } /** * Add action buttons to post list * Show different buttons based on whether summary exists * Only show buttons if user can edit the post * * @param array $actions Existing actions. * @param WP_Post $post Post object. * @return array Modified actions */ public static function ai_summary_generator_add_post_list_buttons( $actions, $post ) { if ( 'post' === $post->post_type && current_user_can( 'edit_post', $post->ID ) ) { $has_summary = AI_Summary_Generator_Core::has_summary( $post->ID ); $needs_regen = AI_Summary_Generator_Core::needs_regeneration( $post->ID ); $generate_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=ai_summary_generator_generate_summary&post_id=' . $post->ID ), 'ai_summary_action' ); $regenerate_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=ai_summary_generator_regenerate_summary&post_id=' . $post->ID ), 'ai_summary_action' ); $clear_url = wp_nonce_url( admin_url( 'admin-ajax.php?action=ai_summary_generator_clear_summary&post_id=' . $post->ID ), 'ai_summary_action' ); if ( $has_summary ) { // Show regenerate and clear options. if ( $needs_regen ) { $actions['regenerate_ai_summary'] = '' . esc_html__( 'Regenerate AI Summary (Outdated)', 'ai-summary-generator' ) . ''; } else { $actions['regenerate_ai_summary'] = '' . esc_html__( 'Regenerate AI Summary', 'ai-summary-generator' ) . ''; } $actions['clear_ai_summary'] = '' . esc_html__( 'Clear AI Summary', 'ai-summary-generator' ) . ''; } else { // Show generate option. $actions['generate_ai_summary'] = '' . esc_html__( 'Generate AI Summary', 'ai-summary-generator' ) . ''; } } return $actions; } /** * Add bulk action for generating summaries * Generates for posts without summaries and regenerates outdated ones * * @param array $bulk_actions Existing bulk actions. * @return array Modified bulk actions */ public static function ai_summary_generator_add_bulk_actions( $bulk_actions ) { $bulk_actions['generate_ai_summaries'] = __( 'Generate/Update AI Summaries', 'ai-summary-generator' ); return $bulk_actions; } /** * Handle bulk action * Generate summaries for posts without them and regenerate outdated ones * * @param string $redirect_to Redirect URL. * @param string $doaction Action being performed. * @param array $post_ids Array of post IDs. * @return string Modified redirect URL */ public static function ai_summary_generator_handle_bulk_action( $redirect_to, $doaction, $post_ids ) { if ( 'generate_ai_summaries' !== $doaction ) { return $redirect_to; } // Clear any existing notice parameters. $notice_params = array( 'single_generated', 'single_regenerated', 'single_cleared', 'single_error', 'bulk_generated', 'bulk_errors', 'bulk_skipped' ); foreach ( $notice_params as $param ) { $redirect_to = remove_query_arg( $param, $redirect_to ); } $generated_count = 0; $error_count = 0; $skipped_count = 0; foreach ( $post_ids as $post_id ) { // Check if user can edit this specific post. if ( ! current_user_can( 'edit_post', $post_id ) ) { $skipped_count++; continue; } $has_summary = AI_Summary_Generator_Core::has_summary( $post_id ); $needs_regen = AI_Summary_Generator_Core::needs_regeneration( $post_id ); // Generate if no summary exists OR if summary is outdated. if ( ! $has_summary || $needs_regen ) { if ( AI_Summary_Generator_Core::generate_summary( $post_id ) ) { $generated_count++; } else { $error_count++; } } else { // Summary exists and is current. $skipped_count++; } } // Add appropriate notice. if ( 0 < $error_count && 0 === $generated_count ) { $redirect_to = add_query_arg( 'single_error', rawurlencode( __( 'Failed to generate any AI summaries. Please check your API settings.', 'ai-summary-generator' ) ), $redirect_to ); } else { $redirect_to = add_query_arg( 'bulk_generated', $generated_count, $redirect_to ); if ( $error_count > 0 ) { $redirect_to = add_query_arg( 'bulk_errors', $error_count, $redirect_to ); } if ( $skipped_count > 0 ) { $redirect_to = add_query_arg( 'bulk_skipped', $skipped_count, $redirect_to ); } } return $redirect_to; } /** * Display admin notices */ public static function ai_summary_generator_admin_notices() { // Only show notices in admin and to users who can edit posts. if ( ! is_admin() || ! current_user_can( 'edit_posts' ) ) { return; } // Error notice (highest priority). // phpcs:disable WordPress.Security.NonceVerification.Recommended -- These are read-only admin notices. if ( ! empty( $_GET['single_error'] ) ) { $error_message = sanitize_text_field( wp_unslash( $_GET['single_error'] ) ); printf( '
%s %s
%s
%s
%s
%s
%s