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

Ability to generate an image directly #524

Merged
merged 10 commits into from
Jul 14, 2023
77 changes: 65 additions & 12 deletions includes/Classifai/Providers/OpenAI/DallE.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,29 +57,37 @@ public function __construct( $service ) {
* This only fires if can_register returns true.
*/
public function register() {
$settings = $this->get_settings();

// Check if the current user has permission to generate images.
$roles = $settings['roles'] ?? [];
$user_roles = wp_get_current_user()->roles ?? [];

if (
current_user_can( 'upload_files' )
&& ( ! empty( $roles ) && empty( array_diff( $user_roles, $roles ) ) )
&& ( isset( $settings['enable_image_gen'] ) && 1 === (int) $settings['enable_image_gen'] )
) {
if ( $this->is_feature_enabled() ) {
add_action( 'admin_menu', [ $this, 'register_generate_media_page' ], 0 );
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
add_action( 'print_media_templates', [ $this, 'print_media_templates' ] );
}
}

/**
* Registers a Media > Generate Image submenu
*/
public function register_generate_media_page() {
$settings = $this->get_settings();
$number_of_images = absint( $settings['number'] );

add_submenu_page(
'upload.php',
$number_of_images > 1 ? esc_html__( 'Generate Images', 'classifai' ) : esc_html__( 'Generate Image', 'classifai' ),
$number_of_images > 1 ? esc_html__( 'Generate Images', 'classifai' ) : esc_html__( 'Generate Image', 'classifai' ),
'upload_files',
esc_url( admin_url( 'upload.php?action=classifai-generate-image' ) ),
''
);
}

/**
* Enqueue the admin scripts.
*
* @param string $hook_suffix The current admin page.
*/
public function enqueue_admin_scripts( $hook_suffix = '' ) {
if ( 'post.php' !== $hook_suffix && 'post-new.php' !== $hook_suffix ) {
if ( 'post.php' !== $hook_suffix && 'post-new.php' !== $hook_suffix && 'upload.php' !== $hook_suffix ) {
return;
}

Expand Down Expand Up @@ -134,6 +142,28 @@ public function enqueue_admin_scripts( $hook_suffix = '' ) {
'caption' => $caption,
]
);

if ( 'upload.php' === $hook_suffix ) {
$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

if ( 'classifai-generate-image' === $action ) {
wp_enqueue_script(
'classifai-generate-images-media-upload',
CLASSIFAI_PLUGIN_URL . 'dist/generate-image-media-upload.js',
[ 'jquery' ],
get_asset_info( 'classifai-generate-images-media-upload', 'version' ),
true
);

wp_localize_script(
'classifai-generate-images-media-upload',
'classifaiGenerateImages',
[
'upload_url' => esc_url( admin_url( 'upload.php' ) ),
]
);
}
}
}

/**
Expand Down Expand Up @@ -483,4 +513,27 @@ public function generate_image_callback( string $prompt = '', array $args = [] )
return $response;
}

/**
* Checks whether we can generate images.
*
* @return bool
*/
public function is_feature_enabled() {
$settings = $this->get_settings();

// Check if the current user has permission to generate images.
$roles = $settings['roles'] ?? [];
$user_roles = wp_get_current_user()->roles ?? [];

if (
current_user_can( 'upload_files' )
&& ( ! empty( $roles ) && empty( array_diff( $user_roles, $roles ) ) )
&& ( isset( $settings['enable_image_gen'] ) && 1 === (int) $settings['enable_image_gen'] )
) {
return true;
}

return false;
}

}
53 changes: 53 additions & 0 deletions src/js/media-modal/views/generate-image-media-upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { __ } from '@wordpress/i18n';

// Automatically open Media Modal on Generate Image dashboard
document.addEventListener( 'DOMContentLoaded', function () {
if ( wp.media ) {
const frame = wp.media( {
title: __( 'Generate images', 'classifai' ),
button: { text: __( 'View details', 'classifai' ) },
multiple: false,
frame: 'select',
} );

frame.on( 'open', function () {
const uploadImageTab = frame.$el.find(
'.media-menu-item#menu-item-upload'
);
const generateImageTab = frame.$el.find(
'.media-menu-item#menu-item-generate'
);

// Remove unwanted items
if ( uploadImageTab.length ) {
uploadImageTab.hide();
}

// Open Generate Image Tab
if ( generateImageTab.length ) {
generateImageTab.trigger( 'click' );
}
} );

frame.on( 'close', function () {
// eslint-disable-next-line no-undef
if ( classifaiGenerateImages ) {
window.location.href = classifaiGenerateImages[ 'upload_url' ]; // eslint-disable-line no-undef, dot-notation
}
} );

frame.on( 'select', function () {
// eslint-disable-next-line no-undef
if ( classifaiGenerateImages ) {
const attachment = frame
.state()
.get( 'selection' )
.first()
.toJSON();
window.location.href = `${ classifaiGenerateImages[ 'upload_url' ] }?item=${ attachment[ 'id' ] }`; // eslint-disable-line no-undef, dot-notation
}
} );

frame.open();
}
} );
36 changes: 35 additions & 1 deletion tests/cypress/integration/image-processing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ describe('Image processing Tests', () => {
cy.get( '#enable_image_gen' ).uncheck();
cy.get( '#submit' ).click();

cy.get(
`.wp-has-current-submenu.wp-menu-open li a:contains("Generate Images")`
).should( 'not.exist' );

// Create test post.
cy.createPost( {
title: 'Test DALL-E post disabled',
Expand Down Expand Up @@ -241,6 +245,10 @@ describe('Image processing Tests', () => {
cy.get( '#openai_dalle_roles_administrator' ).uncheck();
cy.get( '#submit' ).click();

cy.get(
`.wp-has-current-submenu.wp-menu-open li a:contains("Generate Images")`
).should( 'not.exist' );

// Create test post.
cy.createPost( {
title: 'Test DALL-E post admin disabled',
Expand Down Expand Up @@ -279,4 +287,30 @@ describe('Image processing Tests', () => {
cy.get( '#menu-item-generate' ).should( 'not.exist' );
} );
} );
});

it( 'Can generate image directly in media library', () => {
cy.visit(
'/wp-admin/tools.php?page=classifai&tab=image_processing&provider=openai_dalle'
);

cy.get( '#enable_image_gen' ).check();
cy.get( '#openai_dalle_roles_administrator' ).check();
cy.get( '#submit' ).click();

cy.visit( '/wp-admin/upload.php' );
cy.get(
`.wp-has-current-submenu.wp-menu-open li a:contains("Generate Images")`
).click();

// Verify tab exists.
cy.get( '#menu-item-generate' ).should( 'exist' );

// Click into the tab and submit a prompt.
cy.get( '#menu-item-generate' ).click();
cy.get( '.prompt-view .prompt' ).type( 'A sunset over the mountains' );
cy.get( '.prompt-view .button-generate' ).click();

// Verify images show up.
cy.get( '.generated-images ul li' ).should( 'have.length', 2 );
} );
} );
3 changes: 3 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ module.exports = {
'generate-title-classic': [
'./src/js/openai/classic-editor-title-generator.js',
],
'generate-image-media-upload': [
'./src/js/media-modal/views/generate-image-media-upload.js',
],
},
module: {
rules: [
Expand Down