Image' );
}
if ( empty( $data['payload']['settings'] ) ) {
throw new \Exception( 'Missing prompt settings' );
}
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
if ( empty( $data['payload']['mask'] ) ) {
throw new \Exception( 'Missing Mask' );
}
$context = $this->get_request_context( $data );
$request_ids = $this->get_request_ids( $data['payload'] );
$result = $app->get_image_to_image_mask( [
'prompt' => $data['payload']['prompt'],
'attachment_id' => $data['payload']['image']['id'],
'mask' => $data['payload']['mask'],
], $context, $request_ids );
$this->throw_on_error( $result );
return [
'images' => $result['images'],
'response_id' => $result['responseId'],
'usage' => $result['usage'],
];
}
public function ajax_ai_get_image_to_image_mask_cleanup( $data ) {
$this->verify_upload_permissions( $data );
$app = $this->get_ai_app();
if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) {
throw new \Exception( 'Missing Image' );
}
if ( empty( $data['payload']['settings'] ) ) {
throw new \Exception( 'Missing prompt settings' );
}
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
if ( empty( $data['payload']['mask'] ) ) {
throw new \Exception( 'Missing Mask' );
}
$context = $this->get_request_context( $data );
$request_ids = $this->get_request_ids( $data['payload'] );
$result = $app->get_image_to_image_mask_cleanup( [
'attachment_id' => $data['payload']['image']['id'],
'mask' => $data['payload']['mask'],
], $context, $request_ids );
$this->throw_on_error( $result );
return [
'images' => $result['images'],
'response_id' => $result['responseId'],
'usage' => $result['usage'],
];
}
public function ajax_ai_get_image_to_image_outpainting( $data ) {
$this->verify_upload_permissions( $data );
$app = $this->get_ai_app();
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
if ( empty( $data['payload']['mask'] ) ) {
throw new \Exception( 'Missing Expended Image' );
}
$context = $this->get_request_context( $data );
$request_ids = $this->get_request_ids( $data['payload'] );
$result = $app->get_image_to_image_out_painting( [
'size' => $data['payload']['size'],
'position' => $data['payload']['position'],
'mask' => $data['payload']['mask'],
'image_base64' => $data['payload']['image_base64'],
], $context, $request_ids );
$this->throw_on_error( $result );
return [
'images' => $result['images'],
'response_id' => $result['responseId'],
'usage' => $result['usage'],
];
}
public function ajax_ai_upload_image( $data ) {
if ( empty( $data['image'] ) ) {
throw new \Exception( 'Missing image data' );
}
$image = $data['image'];
if ( empty( $image['image_url'] ) ) {
throw new \Exception( 'Missing image_url' );
}
$image_data = $this->upload_image( $image['image_url'], $data['prompt'], $data['editor_post_id'] );
if ( is_wp_error( $image_data ) ) {
throw new \Exception( esc_html( $image_data->get_error_message() ) );
}
if ( ! empty( $image['use_gallery_image'] ) && ! empty( $image['id'] ) ) {
$app = $this->get_ai_app();
$app->set_used_gallery_image( $image['id'] );
}
return [
'image' => array_merge( $image_data, $data ),
];
}
public function ajax_ai_generate_layout( $data ) {
$this->verify_permissions( $data['editor_post_id'] );
$app = $this->get_ai_app();
if ( empty( $data['prompt'] ) && empty( $data['attachments'] ) ) {
throw new \Exception( 'Missing prompt / attachments' );
}
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$result = $app->generate_layout(
$data,
$this->prepare_generate_layout_context( $data )
);
if ( is_wp_error( $result ) ) {
$message = $result->get_error_message();
if ( is_array( $message ) ) {
$message = implode( ', ', $message );
throw new \Exception( esc_html( $message ) );
}
$this->throw_on_error( $result );
}
$elements = $result['text']['elements'] ?? [];
$base_template_id = $result['baseTemplateId'] ?? null;
$template_type = $result['templateType'] ?? null;
if ( empty( $elements ) || ! is_array( $elements ) ) {
throw new \Exception( 'unknown_error' );
}
if ( 1 === count( $elements ) ) {
$template = $elements[0];
} else {
$template = [
'elType' => 'container',
'elements' => $elements,
'settings' => [
'content_width' => 'full',
'flex_gap' => [
'column' => '0',
'row' => '0',
'unit' => 'px',
],
'padding' => [
'unit' => 'px',
'top' => '0',
'right' => '0',
'bottom' => '0',
'left' => '0',
'isLinked' => true,
],
],
];
}
return [
'all' => [],
'text' => $template,
'response_id' => $result['responseId'],
'usage' => $result['usage'],
'base_template_id' => $base_template_id,
'template_type' => $template_type,
];
}
public function ajax_ai_get_layout_prompt_enhancer( $data ) {
$this->verify_permissions( $data['editor_post_id'] );
$app = $this->get_ai_app();
if ( empty( $data['prompt'] ) ) {
throw new \Exception( 'Missing prompt' );
}
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$result = $app->get_layout_prompt_enhanced(
$data['prompt'],
$data['enhance_type'],
$this->prepare_generate_layout_context( $data )
);
$this->throw_on_error( $result );
return [
'text' => $result['text'] ?? $data['prompt'],
'response_id' => $result['responseId'] ?? '',
'usage' => $result['usage'] ?? '',
];
}
private function prepare_generate_layout_context( $data ) {
$request_context = $this->get_request_context( $data );
$kit = Plugin::$instance->kits_manager->get_active_kit();
if ( ! $kit ) {
return $request_context;
}
$kits_data = Collection::make( $kit->get_data()['settings'] ?? [] );
$colors = $kits_data
->filter( function ( $_, $key ) {
return in_array( $key, [ 'system_colors', 'custom_colors' ], true );
} )
->flatten()
->filter( function ( $val ) {
return ! empty( $val['_id'] );
} )
->map( function ( $val ) {
return [
'id' => $val['_id'],
'label' => $val['title'] ?? null,
'value' => $val['color'] ?? null,
];
} );
$typography = $kits_data
->filter( function ( $_, $key ) {
return in_array( $key, [ 'system_typography', 'custom_typography' ], true );
} )
->flatten()
->filter( function ( $val ) {
return ! empty( $val['_id'] );
} )
->map( function ( $val ) {
$font_size = null;
if ( isset(
$val['typography_font_size']['unit'],
$val['typography_font_size']['size']
) ) {
$prop = $val['typography_font_size'];
$font_size = 'custom' === $prop['unit']
? $prop['size']
: $prop['size'] . $prop['unit'];
}
return [
'id' => $val['_id'],
'label' => $val['title'] ?? null,
'value' => [
'family' => $val['typography_font_family'] ?? null,
'weight' => $val['typography_font_weight'] ?? null,
'style' => $val['typography_font_style'] ?? null,
'size' => $font_size,
],
];
} );
$request_context['globals'] = [
'colors' => $colors->all(),
'typography' => $typography->all(),
];
return $request_context;
}
private function upload_image( $image_url, $image_title, $parent_post_id = 0 ) {
if ( ! current_user_can( 'upload_files' ) ) {
throw new \Exception( 'Not Allowed to Upload images' );
}
$attachment_id = media_sideload_image( $image_url, $parent_post_id, $image_title, 'id' );
if ( ! empty( $attachment_id['error'] ) ) {
return new \WP_Error( 'upload_error', $attachment_id['error'] );
}
return [
'id' => $attachment_id,
'url' => esc_url( wp_get_attachment_image_url( $attachment_id, 'full' ) ),
'alt' => esc_attr( $image_title ),
'source' => 'library',
];
}
public function ajax_ai_get_history( $data ): array {
$type = $data['type'] ?? self::HISTORY_TYPE_ALL;
if ( ! in_array( $type, self::VALID_HISTORY_TYPES, true ) ) {
throw new \Exception( 'Invalid history type' );
}
$page = sanitize_text_field( $data['page'] ?? 1 );
$limit = sanitize_text_field( $data['limit'] ?? 10 );
$app = $this->get_ai_app();
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$context = $this->get_request_context( $data );
$result = $app->get_history_by_type( $type, $page, $limit, $context );
if ( is_wp_error( $result ) ) {
throw new \Exception( esc_html( $result->get_error_message() ) );
}
return $result;
}
public function ajax_ai_delete_history_item( $data ): array {
if ( empty( $data['id'] ) || ! wp_is_uuid( $data['id'] ) ) {
throw new \Exception( 'Missing id parameter' );
}
$app = $this->get_ai_app();
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$context = $this->get_request_context( $data );
$result = $app->delete_history_item( $data['id'], $context );
if ( is_wp_error( $result ) ) {
throw new \Exception( esc_html( $result->get_error_message() ) );
}
return [];
}
public function ajax_ai_toggle_favorite_history_item( $data ): array {
if ( empty( $data['id'] ) || ! wp_is_uuid( $data['id'] ) ) {
throw new \Exception( 'Missing id parameter' );
}
$app = $this->get_ai_app();
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$context = $this->get_request_context( $data );
$result = $app->toggle_favorite_history_item( $data['id'], $context );
if ( is_wp_error( $result ) ) {
throw new \Exception( esc_html( $result->get_error_message() ) );
}
return [];
}
public function ajax_ai_get_product_image_unification( $data ): array {
$data['editor_post_id'] = $data['payload']['postId'];
$this->verify_upload_permissions( $data );
$app = $this->get_ai_app();
if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) {
throw new \Exception( esc_html__( 'Missing Image', 'elementor' ) );
}
if ( empty( $data['payload']['settings'] ) ) {
throw new \Exception( esc_html__( 'Missing prompt settings', 'elementor' ) );
}
if ( ! $app->is_connected() ) {
throw new \Exception( esc_html__( 'not_connected', 'elementor' ) );
}
$context = $this->get_request_context( $data );
$request_ids = $this->get_request_ids( $data['payload'] );
$result = $app->get_unify_product_images( [
'promptSettings' => $data['payload']['settings'],
'attachment_id' => $data['payload']['image']['id'],
], $context, $request_ids );
$this->throw_on_error( $result );
return [
'images' => $result['images'],
'response_id' => $result['responseId'],
'usage' => $result['usage'],
];
}
public function ajax_ai_get_animation( $data ): array {
$this->verify_upload_permissions( $data );
$app = $this->get_ai_app();
if ( empty( $data['payload']['prompt'] ) ) {
throw new \Exception( 'Missing prompt' );
}
if ( empty( $data['payload']['motionEffectType'] ) ) {
throw new \Exception( 'Missing animation type' );
}
if ( ! $app->is_connected() ) {
throw new \Exception( 'not_connected' );
}
$context = $this->get_request_context( $data );
$request_ids = $this->get_request_ids( $data['payload'] );
$result = $app->get_animation( $data, $context, $request_ids );
$this->throw_on_error( $result );
return [
'text' => $result['text'],
'response_id' => $result['responseId'],
'usage' => $result['usage'],
];
}
/**
* @param mixed $result
*/
private function throw_on_error( $result ): void {
if ( is_wp_error( $result ) ) {
wp_send_json_error( [
'message' => esc_html( $result->get_error_message() ),
'extra_data' => $result->get_error_data(),
] );
}
}
/**
* @return void
*/
public function add_wc_scripts(): void {
wp_enqueue_script( 'elementor-ai-unify-product-images',
$this->get_js_assets_url( 'ai-unify-product-images' ),
[
'jquery',
'elementor-v2-ui',
'elementor-v2-icons',
'wp-components',
'elementor-common',
],
ELEMENTOR_VERSION,
true
);
wp_localize_script(
'elementor-ai-unify-product-images',
'UnifyProductImagesConfig',
[
'get_product_images_url' => admin_url( 'admin-ajax.php' ),
'set_product_images_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'elementor-ai-unify-product-images_nonce' ),
'placeholder' => ELEMENTOR_ASSETS_URL . 'images/app/ai/product-image-unification-example.gif?' . ELEMENTOR_VERSION,
'is_get_started' => User::get_introduction_meta( 'ai_get_started' ),
'connect_url' => $this->get_ai_connect_url(),
]
);
add_filter( 'bulk_actions-edit-product', function ( $data ) {
return $this->add_products_bulk_action( $data );
});
wp_set_script_translations( 'elementor-ai-unify-product-images', 'elementor' );
}
/**
* @param $product
* @param int|null $image_to_remove
* @param int|null $image_to_add
* @return void
*/
private function update_product_gallery( $product, ?int $image_to_remove, ?int $image_to_add ): void {
$gallery_image_ids = $product->get_gallery_image_ids();
$index = array_search( $image_to_remove, $gallery_image_ids, true );
if ( false !== $index ) {
unset( $gallery_image_ids[ $index ] );
}
if ( ! in_array( $image_to_add, $gallery_image_ids, true ) ) {
$gallery_image_ids[] = $image_to_add;
}
$product->set_gallery_image_ids( $gallery_image_ids );
$product->save();
}
}
Fatal error: Uncaught Error: Class 'Elementor\Modules\Ai\Module' not found in /var/www/html/dportilho.com.br/web/wp-content/plugins/elementor/core/modules-manager.php:53
Stack trace:
#0 /var/www/html/dportilho.com.br/web/wp-content/plugins/elementor/includes/plugin.php(755): Elementor\Core\Modules_Manager->__construct()
#1 /var/www/html/dportilho.com.br/web/wp-content/plugins/elementor/includes/plugin.php(673): Elementor\Plugin->init_components()
#2 /var/www/html/dportilho.com.br/web/wp-includes/class-wp-hook.php(324): Elementor\Plugin->init('')
#3 /var/www/html/dportilho.com.br/web/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array)
#4 /var/www/html/dportilho.com.br/web/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#5 /var/www/html/dportilho.com.br/web/wp-settings.php(704): do_action('init')
#6 /var/www/html/dportilho.com.br/web/wp-config.php(126): require_once('/var/www/html/d...')
#7 /var/www/html/dportilho.com.br/web/wp-load.php(50): require_once('/var/www/html/d...')
#8 /var/www/html/dpor in /var/www/html/dportilho.com.br/web/wp-content/plugins/elementor/core/modules-manager.php on line 53