Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to bulk generate alt texts #6

Merged
merged 14 commits into from
Apr 19, 2024
16 changes: 15 additions & 1 deletion alt-text-generator-gpt-vision.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Plugin Name: AI Alt Text Generator for GPT Vision
* Plugin URI: https://github.com/android-com-pl/wp-ai-alt-generator
* Description: Automatically generate alternative text for images using OpenAI's GPT Vision API.
* Version: 2.0.3
* Version: 2.1.0
* Requires at least: 6.3
* Requires PHP: 8.1
* Author: android.com.pl
Expand Down Expand Up @@ -36,9 +36,17 @@ class AltGeneratorPlugin {
public function __construct() {
add_filter( 'wp_generate_attachment_metadata', [ AltGenerator::class, 'on_attachment_upload' ], 10, 3 );
add_action( 'rest_api_init', [ ( new Api() ), 'register_routes' ] );

add_action( 'enqueue_block_editor_assets', fn()=> $this->enqueue_script( 'editor' ) );
add_action( 'wp_enqueue_media', fn()=> $this->enqueue_script( 'media-modal', true ) );
add_action( 'admin_enqueue_scripts', fn()=> $this->enqueue_attachment_edit_page_script() );

add_action( 'load-upload.php', fn()=> $this->enqueue_script( 'media-upload', true ) );
add_filter(
'bulk_actions-upload',
fn( $actions ) => $actions + [ 'generate_alt_text' => __( 'Generate Alternative Text', 'alt-text-generator-gpt-vision' ) ]
);

add_action( 'activated_plugin', [ $this,'redirect_to_plugin_settings_after_activation' ] );
add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 2 );
}
Expand All @@ -62,6 +70,12 @@ private function enqueue_script( string $file_name, array|bool $args = false ):
$handle = "acpl/ai-alt-generator/$file_name";
wp_enqueue_script( $handle, ACPL_AI_ALT_PLUGIN_URL . "build/$file_name.js", $asset_file['dependencies'], $asset_file['version'], $args );
wp_set_script_translations( $handle, 'alt-text-generator-gpt-vision' );

foreach ( $asset_file['dependencies'] as $dependency ) {
if ( 'wp-components' === $dependency ) {
wp_enqueue_style( 'wp-components' );
}
}
}

private function enqueue_attachment_edit_page_script(): void {
Expand Down
35 changes: 22 additions & 13 deletions includes/AltGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class AltGenerator {
const API_URL = 'https://api.openai.com/v1/chat/completions';
const MODEL = 'gpt-4-vision-preview';

public static function generate_alt_text( int $attachment_id ): string|WP_Error {
public static function generate_alt_text( int $attachment_id, string $user_prompt = '' ): string|WP_Error {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return ErrorCodes::Not_image->to_wp_error( [ 'attachment_id' => $attachment_id ] );
}
Expand All @@ -24,13 +24,6 @@ public static function generate_alt_text( int $attachment_id ): string|WP_Error
$locale = get_locale();
$language = locale_get_display_language( $locale );

$user_prompt = apply_filters(
'acpl/ai_alt_generator/user_prompt',
"Generate a high-quality and concise alt text in $language ($locale) for the provided image without adding any additional comments.",
$locale,
$language
);

$image_mime_type = get_post_mime_type( $attachment_id );
$image_base64 = self::get_image_as_base64( $attachment_id );

Expand All @@ -51,12 +44,28 @@ public static function generate_alt_text( int $attachment_id ): string|WP_Error
[
'model' => self::MODEL,
'messages' => [
[
'role' => 'system',
'content' => apply_filters(
'acpl/ai_alt_generator/system_prompt',
"Generate a high-quality and concise alt text in $language ($locale) for the provided image without adding any additional comments.",
$attachment_id,
$locale,
$language
),
],
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => $user_prompt,
'text' => apply_filters(
'acpl/ai_alt_generator/user_prompt',
$user_prompt,
$attachment_id,
$locale,
$language
),
],
[
'type' => 'image_url',
Expand All @@ -79,7 +88,7 @@ public static function generate_alt_text( int $attachment_id ): string|WP_Error

$completion = json_decode( wp_remote_retrieve_body( $api_response ), true );

if ( $completion['error'] ) {
if ( isset( $completion['error'] ) ) {
return new WP_Error(
$completion['error']['code'],
// translators: %s is the error message from OpenAI's API.
Expand All @@ -90,12 +99,12 @@ public static function generate_alt_text( int $attachment_id ): string|WP_Error
return $completion['choices'][0]['message']['content'] ?? '';
}

public static function generate_and_set_alt_text( int $attachment_id ): ?string {
$alt_text = self::generate_alt_text( $attachment_id );
public static function generate_and_set_alt_text( int $attachment_id, string $user_prompt = '' ): string|WP_Error|null {
$alt_text = self::generate_alt_text( $attachment_id, $user_prompt );
if ( is_wp_error( $alt_text ) ) {
AltGeneratorPlugin::error_log( $alt_text );

return null;
return $alt_text;
}

if ( ! empty( $alt_text ) ) {
Expand Down
22 changes: 20 additions & 2 deletions includes/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,31 @@
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

class Api {
public function register_routes(): void {
register_rest_route(
'acpl',
'/ai-alt-generator',
[
'methods' => 'POST',
'methods' => WP_REST_Server::CREATABLE,
'args' => [
'attachment_id' => [
'required' => true,
'type' => 'integer',
],
'user_prompt' => [
'required' => false,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
],
'save' => [
'required' => false,
'type' => 'boolean',
'default' => false,
'description' => esc_html__( 'Saves the generated alt text to the image when enabled.', 'alt-text-generator-gpt-vision' ),
],
],
'callback' => [ $this, 'generate_alt_text' ],
'permission_callback' => fn() => current_user_can( 'edit_posts' ),
Expand All @@ -27,8 +39,14 @@ public function register_routes(): void {

public function generate_alt_text( WP_REST_Request $request ): WP_REST_Response|WP_Error {
$attachment_id = $request->get_param( 'attachment_id' );
$save_alt = $request->get_param( 'save' );
$user_prompt = $request->get_param( 'user_prompt' ) ?? '';

$alt_text = AltGenerator::generate_alt_text( $attachment_id );
if ( $save_alt ) {
$alt_text = AltGenerator::generate_and_set_alt_text( $attachment_id, $user_prompt );
} else {
$alt_text = AltGenerator::generate_alt_text( $attachment_id, $user_prompt );
}

if ( is_wp_error( $alt_text ) ) {
return $alt_text;
Expand Down
Loading