PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.4
Elementor Website Builder – more than just a page builder v3.27.4
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
← All changes | modules/ai/module.php +16 -72 4.3.0-beta13.27.4 View file →
@@ -4,8 +4,9 @@
4 4 use Elementor\Controls_Manager;
5 5 use Elementor\Core\Base\Module as BaseModule;
6 6 use Elementor\Core\Common\Modules\Connect\Module as ConnectModule;
7 7 use Elementor\Element_Base;
8 +use Elementor\Modules\Ai\Feature_Intro\Product_Image_Unification_Intro;
8 9 use Elementor\Plugin;
9 10 use Elementor\Core\Utils\Collection;
10 11 use Elementor\Modules\Ai\Connect\Ai;
11 12 use Elementor\User;
@@ -27,9 +28,8 @@
27 28 self::HISTORY_TYPE_CODE,
28 29 self::HISTORY_TYPE_IMAGE,
29 30 self::HISTORY_TYPE_BLOCK,
30 31 ];
31 - const MIN_PAGES_FOR_CREATE_WITH_AI_BANNER = 10;
32 32
33 33 public function get_name() {
34 34 return 'ai';
35 35 }
@@ -47,10 +47,8 @@
47 47 if ( ! $this->is_ai_enabled() ) {
48 48 return;
49 49 }
50 50
51 - add_filter( 'elementor/core/admin/homescreen', [ $this, 'add_create_with_ai_banner_to_homescreen' ] );
52 -
53 51 add_action( 'elementor/connect/apps/register', function ( ConnectModule $connect_module ) {
54 52 $connect_module->register_app( 'ai', Ai::get_class_name() );
55 53 } );
56 54
@@ -83,9 +81,8 @@
83 81 'ai_delete_history_item' => [ $this, 'ajax_ai_delete_history_item' ],
84 82 'ai_toggle_favorite_history_item' => [ $this, 'ajax_ai_toggle_favorite_history_item' ],
85 83 'ai_get_product_image_unification' => [ $this, 'ajax_ai_get_product_image_unification' ],
86 84 'ai_get_animation' => [ $this, 'ajax_ai_get_animation' ],
87 - 'ai_get_image_to_image_isolate_objects' => [ $this, 'ajax_ai_get_product_image_unification' ],
88 85 ];
89 86
90 87 foreach ( $handlers as $tag => $callback ) {
91 88 $ajax->register_ajax_action( $tag, $callback );
@@ -123,8 +120,9 @@
123 120 add_action( 'admin_init', [ $this, 'enqueue_ai_products_page_scripts' ] );
124 121 add_action( 'current_screen', [ $this, 'enqueue_ai_single_product_page_scripts' ] );
125 122 add_action( 'wp_ajax_elementor-ai-get-product-images', [ $this, 'get_product_images_ajax' ] );
126 123 add_action( 'wp_ajax_elementor-ai-set-product-images', [ $this, 'set_product_images_ajax' ] );
124 + Product_Image_Unification_Intro::add_hooks();
127 125 }
128 126 }
129 127
130 128 add_action( 'enqueue_block_editor_assets', function() {
@@ -304,8 +302,9 @@
304 302 return;
305 303 }
306 304
307 305 $this->add_wc_scripts();
306 +
308 307 }
309 308
310 309 public function enqueue_ai_single_product_page_scripts() {
311 310 if ( 'wc-single-product' !== $this->get_current_screen() ) {
@@ -312,8 +311,9 @@
312 311 return;
313 312 }
314 313
315 314 $this->add_wc_scripts();
315 +
316 316 }
317 317
318 318 private function add_products_bulk_action( $bulk_actions ) {
319 319 $bulk_actions['elementor-ai-unify-product-images'] = __( 'Unify with Elementor AI', 'elementor' );
@@ -594,10 +594,12 @@
594 594 if ( $document->is_built_with_elementor() ) {
595 595 if ( ! $document->is_editable_by_current_user() ) {
596 596 throw new \Exception( 'Access denied' );
597 597 }
598 - } elseif ( ! current_user_can( 'edit_post', $editor_post_id ) ) {
598 + } else {
599 + if ( ! current_user_can( 'edit_post', $editor_post_id ) ) {
599 600 throw new \Exception( 'Access denied' );
601 + }
600 602 }
601 603 }
602 604
603 605 public function ajax_ai_get_image_prompt_enhancer( $data ) {
@@ -703,9 +705,9 @@
703 705 'usage' => $result['usage'],
704 706 ];
705 707 }
706 708
707 - private function get_ai_app(): Ai {
709 + private function get_ai_app() : Ai {
708 710 return Plugin::$instance->common->get_component( 'connect' )->get_app( 'ai' );
709 711 }
710 712
711 713 private function get_request_context( $data ) {
@@ -1018,8 +1020,12 @@
1018 1020 if ( empty( $data['payload']['settings'] ) ) {
1019 1021 throw new \Exception( 'Missing prompt settings' );
1020 1022 }
1021 1023
1024 + if ( ! $app->is_connected() ) {
1025 + throw new \Exception( 'not_connected' );
1026 + }
1027 +
1022 1028 if ( empty( $data['payload']['mask'] ) ) {
1023 1029 throw new \Exception( 'Missing Mask' );
1024 1030 }
1025 1031
@@ -1109,10 +1115,8 @@
1109 1115 ];
1110 1116 }
1111 1117
1112 1118 public function ajax_ai_upload_image( $data ) {
1113 - $this->verify_upload_permissions( $data );
1114 -
1115 1119 if ( empty( $data['image'] ) ) {
1116 1120 throw new \Exception( 'Missing image data' );
1117 1121 }
1118 1122
@@ -1310,24 +1314,10 @@
1310 1314 if ( ! current_user_can( 'upload_files' ) ) {
1311 1315 throw new \Exception( 'Not Allowed to Upload images' );
1312 1316 }
1313 1317
1314 - $uploads_manager = new \Elementor\Core\Files\Uploads_Manager();
1315 - if ( $uploads_manager::are_unfiltered_uploads_enabled() ) {
1316 - Plugin::$instance->uploads_manager->set_elementor_upload_state( true );
1317 - add_filter( 'wp_handle_sideload_prefilter', [ Plugin::$instance->uploads_manager, 'handle_elementor_upload' ] );
1318 - add_filter( 'image_sideload_extensions', function( $extensions ) {
1319 - $extensions[] = 'svg';
1320 - return $extensions;
1321 - });
1322 - }
1323 -
1324 1318 $attachment_id = media_sideload_image( $image_url, $parent_post_id, $image_title, 'id' );
1325 1319
1326 - if ( is_wp_error( $attachment_id ) ) {
1327 - return new \WP_Error( 'upload_error', $attachment_id->get_error_message() );
1328 - }
1329 -
1330 1320 if ( ! empty( $attachment_id['error'] ) ) {
1331 1321 return new \WP_Error( 'upload_error', $attachment_id['error'] );
1332 1322 }
1333 1323
@@ -1410,25 +1400,23 @@
1410 1400 return [];
1411 1401 }
1412 1402
1413 1403 public function ajax_ai_get_product_image_unification( $data ): array {
1414 - if ( ! empty( $data['payload']['postId'] ) ) {
1415 - $data['editor_post_id'] = $data['payload']['postId'];
1416 - }
1404 + $data['editor_post_id'] = $data['payload']['postId'];
1417 1405 $this->verify_upload_permissions( $data );
1418 1406
1419 1407 $app = $this->get_ai_app();
1420 1408
1421 1409 if ( empty( $data['payload']['image'] ) || empty( $data['payload']['image']['id'] ) ) {
1422 - throw new \Exception( 'Missing Image' );
1410 + throw new \Exception( esc_html__( 'Missing Image', 'elementor' ) );
1423 1411 }
1424 1412
1425 1413 if ( empty( $data['payload']['settings'] ) ) {
1426 - throw new \Exception( 'Missing prompt settings' );
1414 + throw new \Exception( esc_html__( 'Missing prompt settings', 'elementor' ) );
1427 1415 }
1428 1416
1429 1417 if ( ! $app->is_connected() ) {
1430 - throw new \Exception( 'not_connected' );
1418 + throw new \Exception( esc_html__( 'not_connected', 'elementor' ) );
1431 1419 }
1432 1420
1433 1421 $context = $this->get_request_context( $data );
1434 1422 $request_ids = $this->get_request_ids( $data['payload'] );
@@ -1435,9 +1423,8 @@
1435 1423
1436 1424 $result = $app->get_unify_product_images( [
1437 1425 'promptSettings' => $data['payload']['settings'],
1438 1426 'attachment_id' => $data['payload']['image']['id'],
1439 - 'featureIdentifier' => $data['payload']['featureIdentifier'] ?? '',
1440 1427 ], $context, $request_ids );
1441 1428
1442 1429 $this->throw_on_error( $result );
1443 1430
@@ -1547,49 +1534,6 @@
1547 1534 }
1548 1535
1549 1536 $product->set_gallery_image_ids( $gallery_image_ids );
1550 1537 $product->save();
1551 - }
1552 -
1553 - private function should_display_create_with_ai_banner() {
1554 - $elementor_pages = new \WP_Query( [
1555 - 'post_type' => 'page',
1556 - 'post_status' => 'publish',
1557 - 'fields' => 'ids',
1558 - 'posts_per_page' => self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER + 1,
1559 - ] );
1560 -
1561 - if ( $elementor_pages->post_count > self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER ) {
1562 - return false;
1563 - }
1564 -
1565 - if ( Utils::is_custom_kit_applied() ) {
1566 - return false;
1567 - }
1568 -
1569 - return true;
1570 - }
1571 -
1572 - private function get_create_with_ai_banner_data() {
1573 - return [
1574 - 'title' => 'Create and launch your site faster with AI',
1575 - 'description' => 'Share your vision with our AI Chat and watch as it becomes a brief, sitemap, and wireframes in minutes:',
1576 - 'input_placeholder' => 'Start describing the site you want to create...',
1577 - 'button_title' => 'Create with AI',
1578 - 'button_cta_url' => 'http://planner.elementor.com/chat.html',
1579 - 'background_image' => ELEMENTOR_ASSETS_URL . 'images/app/ai/ai-site-creator-homepage-bg.svg',
1580 - 'utm_source' => 'editor-home',
1581 - 'utm_medium' => 'wp-dash',
1582 - 'utm_campaign' => 'generate-with-ai',
1583 - ];
1584 - }
1585 -
1586 - public function add_create_with_ai_banner_to_homescreen( $home_screen_data ) {
1587 - if ( $this->should_display_create_with_ai_banner() ) {
1588 - $home_screen_data['create_with_ai'] = $this->get_create_with_ai_banner_data();
1589 - } else {
1590 - $home_screen_data['create_with_ai'] = null;
1591 - }
1592 -
1593 - return $home_screen_data;
1594 1538 }
1595 1539 }