D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
home
/
everqlsh
/
public_html
/
wp-admin
/
user
/
577040
/
Filename :
ai.zip
back
Copy
PK ]G}\����� �� module.phpnu �[��� <?php namespace Elementor\Modules\Ai; use Elementor\Controls_Manager; use Elementor\Core\Base\Module as BaseModule; use Elementor\Core\Common\Modules\Connect\Module as ConnectModule; use Elementor\Element_Base; use Elementor\Modules\Ai\Feature_Intro\Product_Image_Unification_Intro; use Elementor\Plugin; use Elementor\Core\Utils\Collection; use Elementor\Modules\Ai\Connect\Ai; use Elementor\User; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Module extends BaseModule { const HISTORY_TYPE_ALL = 'all'; const HISTORY_TYPE_TEXT = 'text'; const HISTORY_TYPE_CODE = 'code'; const HISTORY_TYPE_IMAGE = 'images'; const HISTORY_TYPE_BLOCK = 'blocks'; const VALID_HISTORY_TYPES = [ self::HISTORY_TYPE_ALL, self::HISTORY_TYPE_TEXT, self::HISTORY_TYPE_CODE, self::HISTORY_TYPE_IMAGE, self::HISTORY_TYPE_BLOCK, ]; const MIN_PAGES_FOR_CREATE_WITH_AI_BANNER = 10; public function get_name() { return 'ai'; } public function __construct() { parent::__construct(); ( new SitePlannerConnect\Module() ); if ( is_admin() ) { ( new Preferences() )->register(); add_action( 'elementor/import-export/import-kit/runner/after-run', [ $this, 'handle_kit_install' ] ); } if ( ! $this->is_ai_enabled() ) { return; } add_filter( 'elementor/core/admin/homescreen', [ $this, 'add_create_with_ai_banner_to_homescreen' ] ); add_action( 'elementor/connect/apps/register', function ( ConnectModule $connect_module ) { $connect_module->register_app( 'ai', Ai::get_class_name() ); } ); add_action( 'elementor/ajax/register_actions', function( $ajax ) { $handlers = [ 'ai_get_user_information' => [ $this, 'ajax_ai_get_user_information' ], 'ai_get_remote_config' => [ $this, 'ajax_ai_get_remote_config' ], 'ai_get_remote_frontend_config' => [ $this, 'ajax_ai_get_remote_frontend_config' ], 'ai_get_completion_text' => [ $this, 'ajax_ai_get_completion_text' ], 'ai_get_excerpt' => [ $this, 'ajax_ai_get_excerpt' ], 'ai_get_featured_image' => [ $this, 'ajax_ai_get_featured_image' ], 'ai_get_edit_text' => [ $this, 'ajax_ai_get_edit_text' ], 'ai_get_custom_code' => [ $this, 'ajax_ai_get_custom_code' ], 'ai_get_custom_css' => [ $this, 'ajax_ai_get_custom_css' ], 'ai_set_get_started' => [ $this, 'ajax_ai_set_get_started' ], 'ai_set_status_feedback' => [ $this, 'ajax_ai_set_status_feedback' ], 'ai_get_image_prompt_enhancer' => [ $this, 'ajax_ai_get_image_prompt_enhancer' ], 'ai_get_text_to_image' => [ $this, 'ajax_ai_get_text_to_image' ], 'ai_get_image_to_image' => [ $this, 'ajax_ai_get_image_to_image' ], 'ai_get_image_to_image_mask' => [ $this, 'ajax_ai_get_image_to_image_mask' ], 'ai_get_image_to_image_mask_cleanup' => [ $this, 'ajax_ai_get_image_to_image_mask_cleanup' ], 'ai_get_image_to_image_outpainting' => [ $this, 'ajax_ai_get_image_to_image_outpainting' ], 'ai_get_image_to_image_upscale' => [ $this, 'ajax_ai_get_image_to_image_upscale' ], 'ai_get_image_to_image_remove_background' => [ $this, 'ajax_ai_get_image_to_image_remove_background' ], 'ai_get_image_to_image_replace_background' => [ $this, 'ajax_ai_get_image_to_image_replace_background' ], 'ai_upload_image' => [ $this, 'ajax_ai_upload_image' ], 'ai_generate_layout' => [ $this, 'ajax_ai_generate_layout' ], 'ai_get_layout_prompt_enhancer' => [ $this, 'ajax_ai_get_layout_prompt_enhancer' ], 'ai_get_history' => [ $this, 'ajax_ai_get_history' ], 'ai_delete_history_item' => [ $this, 'ajax_ai_delete_history_item' ], 'ai_toggle_favorite_history_item' => [ $this, 'ajax_ai_toggle_favorite_history_item' ], 'ai_get_product_image_unification' => [ $this, 'ajax_ai_get_product_image_unification' ], 'ai_get_animation' => [ $this, 'ajax_ai_get_animation' ], 'ai_get_image_to_image_isolate_objects' => [ $this, 'ajax_ai_get_product_image_unification' ], ]; foreach ( $handlers as $tag => $callback ) { $ajax->register_ajax_action( $tag, $callback ); } } ); add_action( 'elementor/editor/before_enqueue_scripts', function() { $this->enqueue_main_script(); $this->enqueue_layout_script(); } ); add_action( 'elementor/editor/after_enqueue_styles', function() { wp_enqueue_style( 'elementor-ai-editor', $this->get_css_assets_url( 'modules/ai/editor' ), [], ELEMENTOR_VERSION ); } ); add_action( 'elementor/preview/enqueue_styles', function() { wp_enqueue_style( 'elementor-ai-layout-preview', $this->get_css_assets_url( 'modules/ai/layout-preview' ), [], ELEMENTOR_VERSION ); } ); if ( is_admin() ) { add_action( 'wp_enqueue_media', [ $this, 'enqueue_ai_media_library' ] ); add_action( 'admin_head', [ $this, 'enqueue_ai_media_library_upload_screen' ] ); if ( current_user_can( 'edit_products' ) || current_user_can( 'publish_products' ) ) { add_action( 'admin_init', [ $this, 'enqueue_ai_products_page_scripts' ] ); add_action( 'current_screen', [ $this, 'enqueue_ai_single_product_page_scripts' ] ); add_action( 'wp_ajax_elementor-ai-get-product-images', [ $this, 'get_product_images_ajax' ] ); add_action( 'wp_ajax_elementor-ai-set-product-images', [ $this, 'set_product_images_ajax' ] ); Product_Image_Unification_Intro::add_hooks(); } } add_action( 'enqueue_block_editor_assets', function() { wp_enqueue_script( 'elementor-ai-gutenberg', $this->get_js_assets_url( 'ai-gutenberg' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'wp-blocks', 'wp-element', 'wp-editor', 'wp-data', 'wp-components', 'wp-compose', 'wp-i18n', 'wp-hooks', 'elementor-ai-media-library', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-gutenberg', 'ElementorAiConfig', [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); wp_set_script_translations( 'elementor-ai-gutenberg', 'elementor' ); }); add_filter( 'elementor/document/save/data', function ( $data ) { return $this->remove_temporary_containers( $data ); } ); add_action( 'elementor/element/common/section_effects/after_section_start', [ $this, 'register_ai_motion_effect_control' ], 10, 1 ); add_action( 'elementor/element/container/section_effects/after_section_start', [ $this, 'register_ai_motion_effect_control' ], 10, 1 ); add_action( 'elementor/element/common/_section_transform/after_section_end', [ $this, 'register_ai_hover_effect_control' ], 10, 1 ); add_action( 'elementor/element/container/_section_transform/after_section_end', [ $this, 'register_ai_hover_effect_control' ], 10, 1 ); } public function is_ai_enabled() { if ( ! Plugin::$instance->experiments->is_feature_active( 'container' ) ) { return false; } return Preferences::is_ai_enabled( get_current_user_id() ); } public function handle_kit_install( $imported_data ) { if ( ! $this->is_ai_enabled() ) { return; } if ( ! isset( $imported_data['status'] ) || 'success' !== $imported_data['status'] ) { return; } if ( ! isset( $imported_data['runner'] ) || 'site-settings' !== $imported_data['runner'] ) { return; } if ( ! isset( $imported_data['configData']['lastImportedSession']['instance_data']['site_settings']['settings']['ai'] ) ) { return; } $is_connected = $this->get_ai_app()->is_connected() && User::get_introduction_meta( 'ai_get_started' ); if ( ! $is_connected ) { return; } $last_imported_session = $imported_data['configData']['lastImportedSession']; $imported_ai_data = $last_imported_session['instance_data']['site_settings']['settings']['ai']; $this->get_ai_app()->send_event( [ 'name' => 'kit_installed', 'data' => $imported_ai_data, 'client' => [ 'name' => 'elementor', 'version' => ELEMENTOR_VERSION, 'session_id' => $last_imported_session['session_id'], ], ] ); } public function register_ai_hover_effect_control( Element_Base $element ) { if ( ! $element->get_controls( 'ai_hover_animation' ) ) { $element->add_control( 'ai_hover_animation', [ 'tabs_wrapper' => '_tabs_positioning', 'inner_tab' => '_tab_positioning_hover', 'label' => esc_html__( 'Animate With AI', 'elementor' ), 'type' => Controls_Manager::RAW_HTML, 'raw' => ' <style> .elementor-control-ai_hover_animation .elementor-control-content { display: flex; flex-direction: row; justify-content: space-between; align-items: center; } .elementor-control-ai_hover_animation .elementor-control-raw-html { display: none; } </style>', 'render_type' => 'none', 'ai' => [ 'active' => true, 'type' => 'hover_animation', ], ], [ 'position' => [ 'of' => '_transform_rotate_popover_hover', 'type' => 'control', 'at' => 'before', ], ] ); } } public function register_ai_motion_effect_control( $element ) { if ( Utils::has_pro() && ! $element->get_controls( 'ai_animation' ) ) { $element->add_control( 'ai_animation', [ 'label' => esc_html__( 'Animate With AI', 'elementor' ), 'type' => Controls_Manager::RAW_HTML, 'raw' => ' <style> .elementor-control-ai_animation .elementor-control-content { display: flex; flex-direction: row; justify-content: space-between; align-items: center; } .elementor-control-ai_animation .elementor-control-raw-html { display: none; } </style>', 'render_type' => 'none', 'ai' => [ 'active' => true, 'type' => 'animation', ], ] ); } } private function get_current_screen() { $is_wc = class_exists( 'WooCommerce' ) && post_type_exists( 'product' ); if ( ! $is_wc ) { return 'other'; } $is_products_page = isset( $_GET['post_type'] ) && 'product' === $_GET['post_type']; if ( $is_products_page ) { return 'wc-products'; } $screen = get_current_screen(); $is_single_product_page = isset( $screen->post_type ) && ( 'product' === $screen->post_type && 'post' === $screen->base ); if ( $is_single_product_page ) { return 'wc-single-product'; } return 'other'; } public function enqueue_ai_products_page_scripts() { if ( 'wc-products' !== $this->get_current_screen() ) { return; } $this->add_wc_scripts(); } public function enqueue_ai_single_product_page_scripts() { if ( 'wc-single-product' !== $this->get_current_screen() ) { return; } $this->add_wc_scripts(); } private function add_products_bulk_action( $bulk_actions ) { $bulk_actions['elementor-ai-unify-product-images'] = __( 'Unify with Elementor AI', 'elementor' ); return $bulk_actions; } public function get_product_images_ajax() { check_ajax_referer( 'elementor-ai-unify-product-images_nonce', 'nonce' ); $post_ids = isset( $_POST['post_ids'] ) ? array_map( 'intval', $_POST['post_ids'] ) : []; $is_galley_only = isset( $_POST['is_galley_only'] ) && sanitize_text_field( wp_unslash( $_POST['is_galley_only'] ) ); $image_ids = []; foreach ( $post_ids as $post_id ) { if ( $is_galley_only ) { $product = wc_get_product( $post_id ); $gallery_image_ids = $product->get_gallery_image_ids(); foreach ( $gallery_image_ids as $image_id ) { $image_ids[] = [ 'productId' => $post_id, 'id' => $image_id, 'image_url' => wp_get_attachment_url( $image_id ), ]; } continue; } $image_id = get_post_thumbnail_id( $post_id ); if ( ! $image_id ) { $product = wc_get_product( $post_id ); $gallery_image_ids = $product->get_gallery_image_ids(); if ( ! empty( $gallery_image_ids ) ) { $image_id = $gallery_image_ids[0]; } } $image_ids[] = [ 'productId' => $post_id, 'id' => $image_id ? $image_id : 'No Image', 'image_url' => $image_id ? wp_get_attachment_url( $image_id ) : 'No Image', ]; } wp_send_json_success( [ 'product_images' => array_slice( $image_ids, 0, 10 ) ] ); wp_die(); } private function get_attachment_id_by_url( $url ) { $attachments = get_posts( [ 'post_type' => 'attachment', 'meta_query' => [ [ 'key' => '_wp_attached_file', 'value' => basename( $url ), 'compare' => 'LIKE', ], ], 'fields' => 'ids', 'numberposts' => 1, ] ); return ! empty( $attachments ) ? $attachments[0] : null; } public function set_product_images_ajax() { check_ajax_referer( 'elementor-ai-unify-product-images_nonce', 'nonce' ); $product_id = isset( $_POST['productId'] ) ? sanitize_text_field( wp_unslash( $_POST['productId'] ) ) : ''; $image_url = isset( $_POST['image_url'] ) ? sanitize_text_field( wp_unslash( $_POST['image_url'] ) ) : ''; $image_to_add = isset( $_POST['image_to_add'] ) ? intval( wp_unslash( $_POST['image_to_add'] ) ) : null; $image_to_remove = isset( $_POST['image_to_remove'] ) ? intval( wp_unslash( $_POST['image_to_remove'] ) ) : null; $is_product_gallery = isset( $_POST['is_product_gallery'] ) && sanitize_text_field( wp_unslash( $_POST['is_product_gallery'] ) ) === 'true'; if ( ! $product_id || ! $image_url ) { throw new \Exception( 'Product ID and Image URL are required' ); } $product = wc_get_product( $product_id ); if ( ! $product ) { throw new \Exception( 'Product not found' ); } $attachment_id = $this->get_attachment_id_by_url( $image_url ); if ( is_wp_error( $attachment_id ) ) { throw new \Exception( 'Image upload failed' ); } if ( $is_product_gallery ) { $this->update_product_gallery( $product, $image_to_remove, $image_to_add ); } else { $product->set_image_id( $attachment_id ); $product->save(); } wp_send_json_success( [ 'message' => __( 'Image added successfully', 'elementor' ), ] ); } public function enqueue_ai_media_library_upload_screen() { $screen = get_current_screen(); if ( ! $screen || 'upload' !== $screen->id ) { return; } $this->enqueue_ai_media_library(); } public function enqueue_ai_media_library() { wp_enqueue_script( 'elementor-ai-media-library', $this->get_js_assets_url( 'ai-media-library' ), [ 'jquery', 'elementor-v2-ui', 'elementor-v2-icons', 'media-grid', ], ELEMENTOR_VERSION, true ); wp_localize_script( 'elementor-ai-media-library', 'ElementorAiConfig', [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ] ); wp_set_script_translations( 'elementor-ai-media-library', 'elementor' ); } private function enqueue_main_script() { wp_enqueue_script( 'elementor-ai', $this->get_js_assets_url( 'ai' ), [ 'react', 'react-dom', 'backbone-marionette', 'elementor-web-cli', 'wp-date', 'elementor-common', 'elementor-editor-modules', 'elementor-editor-document', 'elementor-v2-ui', 'elementor-v2-icons', ], ELEMENTOR_VERSION, true ); $config = [ 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'connect_url' => $this->get_ai_connect_url(), ]; wp_localize_script( 'elementor-ai', 'ElementorAiConfig', $config ); wp_set_script_translations( 'elementor-ai', 'elementor' ); } private function enqueue_layout_script() { wp_enqueue_script( 'elementor-ai-layout', $this->get_js_assets_url( 'ai-layout' ), [ 'react', 'react-dom', 'backbone-marionette', 'elementor-common', 'elementor-web-cli', 'elementor-editor-modules', 'elementor-ai', 'elementor-v2-ui', 'elementor-v2-icons', ], ELEMENTOR_VERSION, true ); wp_set_script_translations( 'elementor-ai-layout', 'elementor' ); } private function remove_temporary_containers( $data ) { if ( empty( $data['elements'] ) || ! is_array( $data['elements'] ) ) { return $data; } // If for some reason the document has been saved during an AI Layout session, // ensure that the temporary containers are removed from the data. $data['elements'] = array_filter( $data['elements'], function( $element ) { $is_preview_container = strpos( $element['id'], 'e-ai-preview-container' ) === 0; $is_screenshot_container = strpos( $element['id'], 'e-ai-screenshot-container' ) === 0; return ! $is_preview_container && ! $is_screenshot_container; } ); return $data; } private function get_ai_connect_url() { $app = $this->get_ai_app(); return $app->get_admin_url( 'authorize', [ 'utm_source' => 'ai-popup', 'utm_campaign' => 'connect-account', 'utm_medium' => 'wp-dash', 'source' => 'generic', ] ); } public function ajax_ai_get_user_information( $data ) { $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { return [ 'is_connected' => false, 'connect_url' => $this->get_ai_connect_url(), ]; } $user_usage = wp_parse_args( $app->get_usage(), [ 'hasAiSubscription' => false, 'usedQuota' => 0, 'quota' => 100, ] ); return [ 'is_connected' => true, 'is_get_started' => User::get_introduction_meta( 'ai_get_started' ), 'usage' => $user_usage, ]; } public function ajax_ai_get_remote_config() { $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { return []; } return $app->get_remote_config(); } public function ajax_ai_get_remote_frontend_config( $data ) { $callback = function () use ( $data ) { return $this->get_ai_app()->get_remote_frontend_config( $data ); }; return Utils::get_cached_callback( $callback, 'ai_remote_frontend_config-' . get_current_user_id(), HOUR_IN_SECONDS ); } public function verify_upload_permissions( $data ) { $referer = wp_get_referer(); if ( str_contains( $referer, 'wp-admin/upload.php' ) && current_user_can( 'upload_files' ) ) { return; } $this->verify_permissions( $data['editor_post_id'] ); } private function verify_permissions( $editor_post_id ) { $document = Plugin::$instance->documents->get( $editor_post_id ); if ( ! $document ) { throw new \Exception( 'Document not found' ); } if ( $document->is_built_with_elementor() ) { if ( ! $document->is_editable_by_current_user() ) { throw new \Exception( 'Access denied' ); } } elseif ( ! current_user_can( 'edit_post', $editor_post_id ) ) { throw new \Exception( 'Access denied' ); } } public function ajax_ai_get_image_prompt_enhancer( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_prompt_enhanced( $data['prompt'], [], $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_completion_text( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } 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_completion_text( $data['payload']['prompt'], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_excerpt( $data ): array { $app = $this->get_ai_app(); if ( empty( $data['payload']['content'] ) ) { throw new \Exception( 'Missing content' ); } 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_excerpt( $data['payload']['content'], $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_featured_image( $data ): array { $this->verify_upload_permissions( $data ); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } $app = $this->get_ai_app(); 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_featured_image( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'images' => $result['images'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } private function get_ai_app(): Ai { return Plugin::$instance->common->get_component( 'connect' )->get_app( 'ai' ); } private function get_request_context( $data ) { if ( empty( $data['context'] ) ) { return []; } return $data['context']; } private function get_request_ids( $data ) { if ( empty( $data['requestIds'] ) ) { return new \stdClass(); } return $data['requestIds']; } public function ajax_ai_get_edit_text( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['payload']['input'] ) ) { throw new \Exception( 'Missing input' ); } if ( empty( $data['payload']['instruction'] ) ) { throw new \Exception( 'Missing instruction' ); } 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_edit_text( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_custom_code( $data ) { $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['language'] ) ) { throw new \Exception( 'Missing language' ); } 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_custom_code( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_get_custom_css( $data ) { $this->verify_permissions( $data['editor_post_id'] ); $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } if ( empty( $data['payload']['html_markup'] ) ) { $data['html_markup'] = ''; } if ( empty( $data['payload']['element_id'] ) ) { throw new \Exception( 'Missing element_id' ); } 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_custom_css( $data, $context, $request_ids ); $this->throw_on_error( $result ); return [ 'text' => $result['text'], 'response_id' => $result['responseId'], 'usage' => $result['usage'], ]; } public function ajax_ai_set_get_started( $data ) { $app = $this->get_ai_app(); User::set_introduction_viewed( [ 'introductionKey' => 'ai_get_started', ] ); return $app->set_get_started(); } public function ajax_ai_set_status_feedback( $data ) { if ( empty( $data['response_id'] ) ) { throw new \Exception( 'Missing response_id' ); } $app = $this->get_ai_app(); if ( ! $app->is_connected() ) { throw new \Exception( 'not_connected' ); } $app->set_status_feedback( $data['response_id'] ); return []; } public function ajax_ai_get_text_to_image( $data ) { $this->verify_upload_permissions( $data ); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } $app = $this->get_ai_app(); 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_text_to_image( $data, $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( $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' ); } $context = $this->get_request_context( $data ); $request_ids = $this->get_request_ids( $data['payload'] ); $result = $app->get_image_to_image( [ 'prompt' => $data['payload']['prompt'], '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_image_to_image_upscale( $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']['promptSettings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } 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_image_to_image_upscale( [ 'promptSettings' => $data['payload']['promptSettings'], '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_image_to_image_replace_background( $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']['prompt'] ) ) { throw new \Exception( 'Prompt Missing' ); } 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_image_to_image_replace_background( [ 'attachment_id' => $data['payload']['image']['id'], 'prompt' => $data['payload']['prompt'], ], $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_remove_background( $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 ( ! $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_image_to_image_remove_background( [ '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_image_to_image_mask( $data ) { $this->verify_upload_permissions( $data ); $app = $this->get_ai_app(); if ( empty( $data['payload']['prompt'] ) ) { throw new \Exception( 'Missing prompt' ); } 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 ( 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' ); } $uploads_manager = new \Elementor\Core\Files\Uploads_Manager(); if ( $uploads_manager::are_unfiltered_uploads_enabled() ) { Plugin::$instance->uploads_manager->set_elementor_upload_state( true ); add_filter( 'wp_handle_sideload_prefilter', [ Plugin::$instance->uploads_manager, 'handle_elementor_upload' ] ); add_filter( 'image_sideload_extensions', function( $extensions ) { $extensions[] = 'svg'; return $extensions; }); } $attachment_id = media_sideload_image( $image_url, $parent_post_id, $image_title, 'id' ); if ( is_wp_error( $attachment_id ) ) { return new \WP_Error( 'upload_error', $attachment_id->get_error_message() ); } 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 { if ( ! empty( $data['payload']['postId'] ) ) { $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( 'Missing Image' ); } if ( empty( $data['payload']['settings'] ) ) { throw new \Exception( 'Missing prompt settings' ); } 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_unify_product_images( [ 'promptSettings' => $data['payload']['settings'], 'attachment_id' => $data['payload']['image']['id'], 'featureIdentifier' => $data['payload']['featureIdentifier'] ?? '', ], $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(); } private function should_display_create_with_ai_banner() { $elementor_pages = new \WP_Query( [ 'post_type' => 'page', 'post_status' => 'publish', 'fields' => 'ids', 'posts_per_page' => self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER + 1, ] ); if ( $elementor_pages->post_count > self::MIN_PAGES_FOR_CREATE_WITH_AI_BANNER ) { return false; } if ( Utils::is_custom_kit_applied() ) { return false; } return true; } private function get_create_with_ai_banner_data() { return [ 'title' => 'Create and launch your site faster with AI', 'description' => 'Share your vision with our AI Chat and watch as it becomes a brief, sitemap, and wireframes in minutes:', 'input_placeholder' => 'Start describing the site you want to create...', 'button_title' => 'Create with AI', 'button_cta_url' => 'http://planner.elementor.com/chat.html', 'background_image' => ELEMENTOR_ASSETS_URL . 'images/app/ai/ai-site-creator-homepage-bg.svg', 'utm_source' => 'editor-home', 'utm_medium' => 'wp-dash', 'utm_campaign' => 'generate-with-ai', ]; } public function add_create_with_ai_banner_to_homescreen( $home_screen_data ) { if ( $this->should_display_create_with_ai_banner() ) { $home_screen_data['create_with_ai'] = $this->get_create_with_ai_banner_data(); } else { $home_screen_data['create_with_ai'] = null; } return $home_screen_data; } } PK ]G}\rY o� � 1 feature-intro/product-image-unification-intro.phpnu �[��� <?php namespace Elementor\Modules\Ai\Feature_Intro; use Elementor\Core\Upgrade\Manager as Upgrade_Manager; use Elementor\User; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Product_Image_Unification_Intro { const RELEASE_VERSION = '3.26.0'; const CURRENT_POINTER_SLUG = 'e-ai-product-image-unification'; public static function add_hooks() { add_action( 'admin_print_footer_scripts', [ __CLASS__, 'product_image_unification_intro_script' ] ); } public static function product_image_unification_intro_script() { if ( static::is_dismissed() ) { return; } $screen = get_current_screen(); if ( ! isset( $screen->post_type ) || 'product' !== $screen->post_type ) { return; } wp_enqueue_script( 'wp-pointer' ); wp_enqueue_style( 'wp-pointer' ); $pointer_content = '<h3>' . esc_html__( 'New! Unify pack-shots with Elementor AI', 'elementor' ) . '</h3>'; $pointer_content .= '<p>' . esc_html__( 'Now you can process images in bulk and standardized the background and ratio - no manual editing required!', 'elementor' ) . '</p>'; $pointer_content .= sprintf( '<p><button style="padding: 0; border: 0"><a class="button button-primary" href="%s" target="_blank">%s</a></button></p>', esc_js( 'https://go.elementor.com/wp-dash-unify-images-learn-more/' ), esc_html__( 'Learn more', 'elementor' ) ); ?> <script> jQuery( document ).ready( function( $ ) { setTimeout( function () { $( '#bulk-action-selector-top' ).pointer( { content: '<?php echo $pointer_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>', position: { edge: <?php echo is_rtl() ? "'right'" : "'left'"; ?>, align: 'center' }, pointerWidth: 360, close: function () { elementorCommon.ajax.addRequest( 'introduction_viewed', { data: { introductionKey: '<?php echo esc_attr( static::CURRENT_POINTER_SLUG ); ?>', }, } ); } } ).pointer( 'open' ); }, 10 ); } ); </script> <?php } private static function is_dismissed() { return User::get_introduction_meta( static::CURRENT_POINTER_SLUG ); } } PK ]G}\��U� site-planner-connect/module.phpnu �[��� <?php namespace Elementor\Modules\Ai\SitePlannerConnect; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Module { const NOT_TRANSLATED_APP_NAME = 'Site Planner'; const PLANNER_ORIGIN = 'https://planner.elementor.com'; const HIDDEN_PAGE_SLUG = ''; public function __construct() { add_action( 'rest_api_init', [ $this, 'on_rest_init' ] ); add_action( 'admin_menu', [ $this, 'register_menu_page' ], 100 ); add_filter( 'rest_prepare_application_password', function ( $response, $item, $request ) { if ( '/wp/v2/users/me/application-passwords' === $request->get_route() && is_user_logged_in() ) { $user = wp_get_current_user(); $response->data['user_login'] = $user->user_login; } return $response; }, 10, 3 ); } public function on_rest_init(): void { ( new Wp_Rest_Api() )->register(); } public function register_menu_page() { add_submenu_page( self::HIDDEN_PAGE_SLUG, 'App Password Generator', 'App Password', 'manage_options', 'e-site-planner-password-generator', [ $this, 'render_menu_page' ] ); } public function render_menu_page() { ob_start(); require_once __DIR__ . '/view.php'; $content = ob_get_clean(); $vars = [ '%app_name%' => self::NOT_TRANSLATED_APP_NAME, '%safe_origin%' => esc_url( self::PLANNER_ORIGIN ), '%domain%' => isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '', '%title%' => esc_html__( 'Connect to Site Planner', 'elementor' ), '%description%' => esc_html__( 'To connect your site to Site Planner, you need to generate an app password.', 'elementor' ), '%cta%' => esc_html__( 'Approve & Connect', 'elementor' ), ]; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo strtr( $content, $vars ); } } PK ]G}\�h�� � $ site-planner-connect/wp-rest-api.phpnu �[��� <?php namespace Elementor\Modules\Ai\SitePlannerConnect; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Just a simple rest api to validate new Site Planner Connect feature exists. */ class Wp_Rest_Api { public function register(): void { register_rest_route('elementor-ai/v1', 'permissions', [ [ 'methods' => \WP_REST_Server::READABLE, 'permission_callback' => function () { return current_user_can( 'manage_options' ); }, 'callback' => function () { try { wp_send_json_success( [ 'site_planner_connect' => true, ] ); } catch ( \Exception $e ) { wp_send_json_error( [ 'message' => $e->getMessage(), ] ); } }, ], ] ); } } PK ]G}\j)�k k site-planner-connect/view.phpnu �[��� <?php namespace Elementor\Modules\Ai\SitePlannerConnect; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } ?> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&display=swap" rel="stylesheet"> <style> #wpwrap { display: none; } .site-planner-consent { position: fixed; top: 0; left: 0; z-index: 99999; /* above admin top bar */ width: 100%; background-color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; } .site-planner-consent-title { color: #0C0D0E; text-align: center; /* typography/h4 */ font-family: Roboto, sans-serif; font-size: 32px; font-style: normal; font-weight: 700; line-height: 123.5%; letter-spacing: 0.25px; } .site-planner-consent-description { width: 393px; color: #69727D; text-align: center; /* typography/body1 */ font-family: Roboto, sans-serif; font-size: 16px; font-style: normal; font-weight: 400; line-height: 150%; /* 24px */ letter-spacing: 0.15px; } .site-planner-consent-connect-names { display: flex; flex-direction: row; justify-content: space-between; width: 500px; } .site-planner-consent-connect-names div { width: 50%; text-align: center; } .site-planner-consent button { cursor: pointer; border: none; display: flex; width: 387px; padding: 8px 22px; flex-direction: column; justify-content: center; align-items: center; border-radius: 4px; background: #F0ABFC; color: #0C0D0E; font-feature-settings: 'liga' off, 'clig' off; /* components/button/button-large */ font-family: Roboto, sans-serif; font-size: 16px; font-style: normal; font-weight: 500; line-height: 26px; /* 162.5% */ letter-spacing: 0.46px; } .site-planner-consent .generating-results { display: none; padding: 8px 16px; margin: 0 32px; } .site-planner-consent .generating-results.error { display: block; background: rgb(253, 236, 236); } </style> <div class="site-planner-consent"> <h1 class="site-planner-consent-title"> %title% </h1> <div style="height: 20px"></div> <p class="site-planner-consent-description"> %description% </p> <div style="height: 40px"></div> <svg width="287" height="40" viewBox="0 0 287 40" fill="none" xmlns="http://www.w3.org/2000/svg"> <line x1="16.5" y1="22.5" x2="271.5" y2="22.5" stroke="#69727D" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="2 4"/> <circle cx="145.623" cy="22" r="11.5" fill="white" stroke="#69727D"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M147.977 19.6467C148.172 19.842 148.172 20.1586 147.977 20.3538L143.977 24.3538C143.782 24.5491 143.465 24.5491 143.27 24.3538C143.074 24.1586 143.074 23.842 143.27 23.6467L147.27 19.6467C147.465 19.4515 147.782 19.4515 147.977 19.6467Z" fill="#69727D"/> <path d="M149.691 18.1948L149.402 17.9058C148.377 16.8804 146.714 16.8804 145.689 17.9058L145.002 18.5922C144.807 18.7875 144.491 18.7875 144.295 18.5922C144.1 18.397 144.1 18.0804 144.295 17.8851L144.982 17.1987C146.398 15.7827 148.693 15.7827 150.109 17.1987L150.398 17.4877C151.814 18.9036 151.814 21.1993 150.398 22.6153L149.712 23.3017C149.517 23.497 149.2 23.497 149.005 23.3017C148.81 23.1065 148.81 22.7899 149.005 22.5946L149.691 21.9082C150.717 20.8828 150.717 19.2202 149.691 18.1948Z" fill="#69727D"/> <path d="M141.529 22.0658C140.503 23.0912 140.503 24.7538 141.529 25.7792L141.818 26.0682C142.843 27.0936 144.506 27.0936 145.531 26.0682L146.218 25.3818C146.413 25.1865 146.73 25.1865 146.925 25.3818C147.12 25.577 147.12 25.8936 146.925 26.0889L146.238 26.7753C144.822 28.1913 142.527 28.1913 141.111 26.7753L140.822 26.4863C139.406 25.0704 139.406 22.7747 140.822 21.3587L141.508 20.6723C141.703 20.477 142.02 20.477 142.215 20.6723C142.411 20.8675 142.411 21.1841 142.215 21.3794L141.529 22.0658Z" fill="#69727D"/> <rect x="247" width="40" height="40" rx="20" fill="#F3F3F4"/> <g clip-path="url(#clip0_7635_41076)"> <path fill-rule="evenodd" clip-rule="evenodd" d="M257.022 26.6668C255.704 24.6934 255 22.3734 255 20C255 16.8174 256.264 13.7652 258.515 11.5147C260.765 9.26428 263.817 8 267 8C269.373 8 271.693 8.70379 273.667 10.0224C275.64 11.3409 277.178 13.2151 278.087 15.4078C278.995 17.6005 279.232 20.0133 278.769 22.3411C278.306 24.6688 277.164 26.807 275.485 28.4853C273.807 30.1635 271.669 31.3064 269.341 31.7694C267.013 32.2324 264.601 31.9948 262.408 31.0865C260.215 30.1783 258.341 28.6402 257.022 26.6668ZM264 14.9996H262.001V24.9999H264V14.9996ZM271.999 14.9996H266V16.9993H271.999V14.9996ZM271.999 18.999H266V20.9987H271.999V18.999ZM271.999 23.0002H266V24.9999H271.999V23.0002Z" fill="#0C0D0E"/> </g> <rect width="40" height="40" rx="20" fill="#F3F3F4"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M20.0004 10.0156C14.4944 10.0156 10.0156 14.494 10.0156 19.9996C10.0156 25.5053 14.4944 29.9844 20.0004 29.9844C25.5056 29.9844 29.9844 25.5053 29.9844 19.9996C29.9844 14.4947 25.5056 10.0156 20.0004 10.0156ZM11.1616 19.9996C11.1616 18.7184 11.4367 17.5017 11.927 16.4031L16.1431 27.9539C13.1948 26.5215 11.1616 23.4984 11.1616 19.9996ZM20.0004 28.8387C19.1327 28.8387 18.2954 28.7106 17.5032 28.4785L20.1549 20.7731L22.8725 28.2154C22.8898 28.2589 22.9115 28.2992 22.9353 28.3372C22.0167 28.6607 21.0292 28.8387 20.0004 28.8387ZM21.218 15.856C21.7501 15.8279 22.2293 15.7715 22.2293 15.7715C22.7058 15.7153 22.65 15.0158 22.1733 15.0438C22.1733 15.0438 20.7415 15.156 19.8176 15.156C18.9495 15.156 17.4894 15.0438 17.4894 15.0438C17.0133 15.0158 16.9579 15.744 17.4336 15.7715C17.4336 15.7715 17.8845 15.8277 18.3602 15.856L19.7373 19.6286L17.8034 25.4297L14.5851 15.8564C15.1178 15.8283 15.5968 15.7721 15.5968 15.7721C16.0725 15.7159 16.0169 15.016 15.54 15.0445C15.54 15.0445 14.1088 15.1564 13.1843 15.1564C13.0178 15.1564 12.823 15.1521 12.6157 15.1457C14.1954 12.7459 16.9123 11.1617 20.0004 11.1617C22.3018 11.1617 24.3964 12.0416 25.9689 13.4816C25.9302 13.4797 25.8937 13.4748 25.854 13.4748C24.9861 13.4748 24.3695 14.2309 24.3695 15.0434C24.3695 15.7715 24.789 16.388 25.2377 17.1159C25.5741 17.7051 25.9662 18.4613 25.9662 19.5537C25.9662 20.3102 25.6758 21.1882 25.2936 22.4107L24.4121 25.3566L21.218 15.856ZM24.4435 27.6389L27.1431 19.8337C27.6481 18.573 27.8152 17.5647 27.8152 16.6679C27.8152 16.343 27.7937 16.0404 27.7557 15.7591C28.4466 17.018 28.8391 18.4629 28.8386 19.9998C28.8386 23.2602 27.0708 26.1068 24.4435 27.6389Z" fill="#0C0D0E"/> <defs> <clipPath id="clip0_7635_41076"> <rect width="24" height="24" fill="white" transform="translate(255 8)"/> </clipPath> </defs> </svg> <div class="site-planner-consent-connect-names"> <div>%domain%</div> <div>%app_name%</div> </div> <div style="height: 40px"></div> <button class="site-planner-consent-button" onclick="sendPassword()"> %cta% </button> <div style="height: 40px"></div> <div class="generating-results"></div> </div> <script> const generatingResults = document.querySelector(".generating-results"); const hideAdminUi = () => { document.body.append(document.querySelector(".site-planner-consent")) } const sendPassword = () => { generatingResults.classList.remove("error"); fetch(`${ wpApiSettings.root}wp/v2/users/me/application-passwords`, { method: "POST", headers: { "Content-Type": "application/json", "X-WP-Nonce": wpApiSettings.nonce, }, body: JSON.stringify({ name: "Site Planner Connect" }) }) .then(response => response.json()) .then(data => { window.opener.postMessage({ type: "app_password", details: { userLogin: data.user_login, appPassword: data.password, uuid: data.uuid, created: data.created } }, '%safe_origin%'); window.close(); }) .catch(error => { console.error("Error:", error); generatingResults.classList.add("error"); generatingResults.innerText = "Error generating password: " + error; }); } hideAdminUi(); </script> PK ]G}\4d�Mv v preferences.phpnu �[��� <?php namespace Elementor\Modules\Ai; use Elementor\User; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Preferences { const ENABLE_AI = 'elementor_enable_ai'; /** * Register actions and hooks. * * @return void */ public function register() { add_action( 'personal_options', function ( \WP_User $user ) { $this->add_personal_options_settings( $user ); } ); add_action( 'personal_options_update', function ( $user_id ) { $this->update_personal_options_settings( $user_id ); } ); add_action( 'edit_user_profile_update', function ( $user_id ) { $this->update_personal_options_settings( $user_id ); } ); } /** * Determine if AI features are enabled for a user. * * @param int $user_id - User ID. * * @return bool */ public static function is_ai_enabled( $user_id ) { return (bool) User::get_user_option_with_default( static::ENABLE_AI, $user_id, true ); } /** * Add settings to the "Personal Options". * * @param \WP_User $user - User object. * * @return void */ protected function add_personal_options_settings( \WP_User $user ) { if ( ! $this->has_permissions_to_edit_user( $user->ID ) ) { return; } $ai_value = User::get_user_option_with_default( static::ENABLE_AI, $user->ID, '1' ); ?> <tr> <th style="padding:0px"> <h2><?php echo esc_html__( 'Elementor - AI', 'elementor' ); ?></h2> </th> </tr> <tr> <th> <label for="<?php echo esc_attr( static::ENABLE_AI ); ?>"> <?php echo esc_html__( 'Status', 'elementor' ); ?> </label> </th> <td> <label for="<?php echo esc_attr( static::ENABLE_AI ); ?>"> <input name="<?php echo esc_attr( static::ENABLE_AI ); ?>" id="<?php echo esc_attr( static::ENABLE_AI ); ?>" type="checkbox" value="1"<?php checked( '1', $ai_value ); ?> /> <?php echo esc_html__( 'Enable Elementor AI functionality', 'elementor' ); ?> </label> </td> </tr> <?php } /** * Save the settings in the "Personal Options". * * @param int $user_id - User ID. * * @return void */ protected function update_personal_options_settings( $user_id ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce already verified in `wp_verify_nonce`. $wpnonce = Utils::get_super_global_value( $_POST, '_wpnonce' ); if ( ! wp_verify_nonce( $wpnonce, 'update-user_' . $user_id ) ) { return; } if ( ! $this->has_permissions_to_edit_user( $user_id ) ) { return; } $ai_value = empty( $_POST[ static::ENABLE_AI ] ) ? '0' : '1'; update_user_option( $user_id, static::ENABLE_AI, sanitize_text_field( $ai_value ) ); } /** * Determine if the current user has permission to view/change preferences of a user. * * @param int $user_id * * @return bool */ protected function has_permissions_to_edit_user( $user_id ) { return current_user_can( 'edit_user', $user_id ); } } PK ]G}\�(Y (Y connect/ai.phpnu �[��� <?php namespace Elementor\Modules\Ai\Connect; use Elementor\Core\Common\Modules\Connect\Apps\Library; use Elementor\Modules\Ai\Module; use Elementor\Utils as ElementorUtils; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Ai extends Library { const API_URL = 'https://my.elementor.com/api/v2/ai/'; const STYLE_PRESET = 'style_preset'; const IMAGE_TYPE = 'image_type'; const IMAGE_STRENGTH = 'image_strength'; const ASPECT_RATIO = 'ratio'; const IMAGE_RESOLUTION = 'image_resolution'; const IMAGE_BACKGROUND_COLOR = 'background_color'; const PROMPT = 'prompt'; public function get_title() { return esc_html__( 'AI', 'elementor' ); } protected function get_api_url() { return static::API_URL . '/'; } public function get_usage() { return $this->ai_request( 'POST', 'status/check', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_remote_config() { return $this->ai_request( 'GET', 'remote-config/config', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_remote_frontend_config( $data ) { return $this->ai_request( 'POST', 'remote-config/frontend-config', [ 'client_name' => $data['payload']['client_name'], 'client_version' => $data['payload']['client_version'], 'client_session_id' => $data['payload']['client_session_id'], 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * @param array $event_data { * @type string $name * @type array $data * @type array $client { * @type string $name * @type string $version * @type string $session_id * } * } */ public function send_event( array $event_data ): void { $this->ai_request( 'POST', 'client-events/events', [ 'payload' => $event_data, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get file upload get_file_payload * * @param $filename * @param $file_type * @param $file_path * @param $boundary * * @return string */ private function get_file_payload( $filename, $file_type, $file_path, $boundary ) { $name = $filename ?? basename( $file_path ); $mine_type = 'image' === $file_type ? image_type_to_mime_type( exif_imagetype( $file_path ) ) : $file_type; $payload = ''; // Upload the file $payload .= '--' . $boundary; $payload .= "\r\n"; $payload .= 'Content-Disposition: form-data; name="' . esc_attr( $name ) . '"; filename="' . esc_attr( $name ) . '"' . "\r\n"; $payload .= 'Content-Type: ' . $mine_type . "\r\n"; $payload .= "\r\n"; $payload .= file_get_contents( $file_path ); $payload .= "\r\n"; return $payload; } private function get_upload_request_body( $body, $file, $boundary, $file_name = '' ) { $payload = ''; // add all body fields as standard POST fields: foreach ( $body as $name => $value ) { $payload .= '--' . $boundary; $payload .= "\r\n"; $payload .= 'Content-Disposition: form-data; name="' . esc_attr( $name ) . '"' . "\r\n\r\n"; $payload .= $value; $payload .= "\r\n"; } if ( is_array( $file ) ) { foreach ( $file as $key => $file_data ) { $payload .= $this->get_file_payload( $file_data['name'], $file_data['type'], $file_data['path'], $boundary ); } } else { $image_mime = image_type_to_mime_type( exif_imagetype( $file ) ); // @todo: add validation for supported image types if ( empty( $file_name ) ) { $file_name = basename( $file ); } $payload .= $this->get_file_payload( $file_name, $image_mime, $file, $boundary ); } $payload .= '--' . $boundary . '--'; return $payload; } private function ai_request( $method, $endpoint, $body, $file = false, $file_name = '', $format = 'default' ) { $headers = [ 'x-elementor-ai-version' => '2', ]; if ( $file ) { $boundary = wp_generate_password( 24, false ); $body = $this->get_upload_request_body( $body, $file, $boundary, $file_name ); // add content type header $headers['Content-Type'] = 'multipart/form-data; boundary=' . $boundary; } elseif ( 'json' === $format ) { $headers['Content-Type'] = 'application/json'; $body = wp_json_encode( $body ); } return $this->http_request( $method, $endpoint, [ 'timeout' => 100, 'headers' => $headers, 'body' => $body, ], [ 'return_type' => static::HTTP_RETURN_TYPE_ARRAY, 'with_error_data' => true, ] ); } public function set_get_started() { return $this->ai_request( 'POST', 'status/get-started', [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function set_status_feedback( $response_id ) { return $this->ai_request( 'POST', 'status/feedback/' . $response_id, [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function set_used_gallery_image( $image_id ) { return $this->ai_request( 'POST', 'status/used-gallery-image/' . $image_id, [ 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_completion_text( $prompt, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/completion', [ 'prompt' => $prompt, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_excerpt( $prompt, $context, $request_ids ) { $excerpt_length = apply_filters( 'excerpt_length', 55 ); return $this->ai_request( 'POST', 'text/get-excerpt', [ 'content' => $prompt, 'maxLength' => $excerpt_length, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get Image Prompt Enhanced get_image_prompt_enhanced * * @param $prompt * * @return mixed|\WP_Error */ public function get_image_prompt_enhanced( $prompt, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/enhance-image-prompt', [ 'prompt' => $prompt, 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_edit_text( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/edit', [ 'input' => $data['payload']['input'], 'instruction' => $data['payload']['instruction'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_custom_code( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/custom-code', [ 'prompt' => $data['payload']['prompt'], 'language' => $data['payload']['language'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_custom_css( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/custom-css', [ 'prompt' => $data['payload']['prompt'], 'html_markup' => $data['payload']['html_markup'], 'element_id' => $data['payload']['element_id'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get text to image get_text_to_image * * @param $prompt * @param $prompt_settings * * @return mixed|\WP_Error */ public function get_text_to_image( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'image/text-to-image', [ self::PROMPT => $data['payload']['prompt'], self::IMAGE_TYPE => $data['payload']['settings'][ self::IMAGE_TYPE ] . '/' . $data['payload']['settings'][ self::STYLE_PRESET ], self::ASPECT_RATIO => $data['payload']['settings'][ self::ASPECT_RATIO ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get_Featured_Image get_featured_image * * @param $data * @param $context * @param $request_ids * @return mixed|\WP_Error */ public function get_featured_image( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'image/text-to-image/featured-image', [ self::PROMPT => $data['payload']['prompt'], self::IMAGE_TYPE => $data['payload']['settings'][ self::IMAGE_TYPE ] . '/' . $data['payload']['settings'][ self::STYLE_PRESET ], self::ASPECT_RATIO => $data['payload']['settings'][ self::ASPECT_RATIO ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } /** * Get Image To Image get_image_to_image * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image', [ self::PROMPT => $image_data[ self::PROMPT ], self::IMAGE_TYPE => $image_data['promptSettings'][ self::IMAGE_TYPE ] . '/' . $image_data['promptSettings'][ self::STYLE_PRESET ], self::IMAGE_STRENGTH => $image_data['promptSettings'][ self::IMAGE_STRENGTH ], self::ASPECT_RATIO => $image_data['promptSettings'][ self::ASPECT_RATIO ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } private function resizeImageIfNeeded( $original_url ) { try { $max_file_size = 4194304; $current_size = filesize( $original_url ); if ( $current_size <= $max_file_size ) { return $original_url; } $image_editor = wp_get_image_editor( $original_url ); if ( is_wp_error( $image_editor ) ) { return $original_url; } $dimensions = $image_editor->get_size(); $original_width = $dimensions['width']; $original_height = $dimensions['height']; $scaling_factor = sqrt( $max_file_size / $current_size ); $new_width = (int) ( $original_width * $scaling_factor ); $new_height = (int) ( $original_height * $scaling_factor ); $image_editor->resize( $new_width, $new_height, true ); $file_extension = pathinfo( $original_url, PATHINFO_EXTENSION ); $temp_image = tempnam( sys_get_temp_dir(), 'resized_' ) . '.' . $file_extension; $image_editor->save( $temp_image ); return $temp_image; } catch ( \Exception $e ) { return $original_url; } } public function get_unify_product_images( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $final_path = $this->resizeImageIfNeeded( $image_file ); $result = $this->ai_request( 'POST', 'image/image-to-image/unify-product-images', [ 'aspectRatio' => $image_data['promptSettings'][ self::ASPECT_RATIO ], 'backgroundColor' => $image_data['promptSettings'][ self::IMAGE_BACKGROUND_COLOR ], 'featureIdentifier' => $image_data['featureIdentifier'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $final_path, 'image' ); if ( $image_file !== $final_path ) { unlink( $final_path ); } return $result; } /** * Get Image To Image Upscale get_image_to_image_upscale * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_upscale( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/upscale', [ self::IMAGE_RESOLUTION => $image_data['promptSettings']['upscale_to'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Get Image To Image Remove Background get_image_to_image_remove_background * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_remove_background( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/remove-background', [ 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Get Image To Image Remove Text get_image_to_image_remove_text * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_replace_background( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/replace-background', [ self::PROMPT => $image_data[ self::PROMPT ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], $image_file, 'image' ); return $result; } /** * Store Temp File store_temp_file * used to store a temp file for the AI request and deletes it once the request is done * * @param $file_content * @param $file_ext * * @return string */ private function store_temp_file( $file_content, $file_ext = '' ) { $temp_file = str_replace( '.tmp', '', wp_tempnam() . $file_ext ); file_put_contents( $temp_file, $file_content ); // make sure the temp file is deleted on shutdown register_shutdown_function( function () use ( $temp_file ) { if ( file_exists( $temp_file ) ) { unlink( $temp_file ); } } ); return $temp_file; } /** * Get Image To Image Out Painting get_image_to_image_out_painting * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_out_painting( $image_data, $context, $request_ids ) { $img_content = str_replace( ' ', '+', $image_data['mask'] ); $img_content = substr( $img_content, strpos( $img_content, ',' ) + 1 ); $img_content = base64_decode( $img_content ); $mask_file = $this->store_temp_file( $img_content, '.png' ); if ( ! $mask_file ) { throw new \Exception( 'Expended Image file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/outpainting', [ 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'size' => wp_json_encode( $image_data['size'] ), 'position' => wp_json_encode( $image_data['position'] ), 'image_base64' => $image_data['image_base64'], $image_data['image'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $mask_file, ], ] ); return $result; } /** * Get Image To Image Mask get_image_to_image_mask * * @param $image_data * @param $context * @param $request_ids * @return mixed|\WP_Error * @throws \Exception If image file not found. */ public function get_image_to_image_mask( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); $mask_file = $this->store_temp_file( $image_data['mask'], '.svg' ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } if ( ! $mask_file ) { throw new \Exception( 'Mask file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/inpainting', [ self::PROMPT => $image_data[ self::PROMPT ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'image_base64' => $image_data['image_base64'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $image_file, ], [ 'name' => 'mask_image', 'type' => 'image/svg+xml', 'path' => $mask_file, ], ] ); return $result; } public function get_image_to_image_mask_cleanup( $image_data, $context, $request_ids ) { $image_file = get_attached_file( $image_data['attachment_id'] ); $mask_file = $this->store_temp_file( $image_data['mask'], '.svg' ); if ( ! $image_file ) { throw new \Exception( 'Image file not found' ); } if ( ! $mask_file ) { throw new \Exception( 'Mask file not found' ); } $result = $this->ai_request( 'POST', 'image/image-to-image/cleanup', [ self::PROMPT => $image_data[ self::PROMPT ], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'image_base64' => $image_data['image_base64'], ], [ [ 'name' => 'image', 'type' => 'image', 'path' => $image_file, ], [ 'name' => 'mask_image', 'type' => 'image/svg+xml', 'path' => $mask_file, ], ] ); return $result; } public function generate_layout( $data, $context ) { $endpoint = 'generate/layout'; $body = [ 'prompt' => $data['prompt'], 'variationType' => (int) $data['variationType'], 'ids' => $data['ids'], ]; if ( ! empty( $data['prevGeneratedIds'] ) ) { $body['generatedBaseTemplatesIds'] = $data['prevGeneratedIds']; } if ( ! empty( $data['attachments'] ) ) { $attachment = $data['attachments'][0]; switch ( $attachment['type'] ) { case 'json': $endpoint = 'generate/generate-json-variation'; $body['json'] = [ 'type' => 'elementor', 'elements' => [ $attachment['content'] ], 'label' => $attachment['label'], 'source' => $attachment['source'], ]; break; case 'url': $endpoint = 'generate/html-to-elementor'; $html = wp_json_encode( $attachment['content'] ); $body['html'] = $html; $body['htmlFetchedUrl'] = $attachment['label']; break; } } $context['currentContext'] = $data['currentContext']; $context['features'] = [ 'supportedFeatures' => [ 'Taxonomy' ], ]; if ( ElementorUtils::has_pro() ) { $context['features']['subscriptions'] = [ 'Pro' ]; } if ( Plugin::instance()->experiments->get_active_features()['nested-elements'] ) { $context['features']['supportedFeatures'][] = 'Nested'; } if ( Plugin::instance()->experiments->get_active_features()['mega-menu'] ) { $context['features']['supportedFeatures'][] = 'MegaMenu'; } if ( class_exists( 'WC' ) ) { $context['features']['supportedFeatures'][] = 'WooCommerce'; } $metadata = [ 'context' => $context, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), 'config' => [ 'generate' => [ 'all' => true, ], ], ]; $body = array_merge( $body, $metadata ); // Temp hack for platforms that filters the http_request_args, and it breaks JSON requests. remove_all_filters( 'http_request_args' ); return $this->ai_request( 'POST', $endpoint, $body, false, '', 'json' ); } public function get_layout_prompt_enhanced( $prompt, $enhance_type, $context ) { return $this->ai_request( 'POST', 'generate/enhance-prompt', [ 'prompt' => $prompt, 'enhance_type' => $enhance_type, 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } public function get_history_by_type( $type, $page, $limit, $context = [] ) { $endpoint = Module::HISTORY_TYPE_ALL === $type ? 'history' : add_query_arg( [ 'page' => $page, 'limit' => $limit, ], "history/{$type}" ); return $this->ai_request( 'POST', $endpoint, [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function delete_history_item( $id, $context = [] ) { return $this->ai_request( 'DELETE', 'history/' . $id, [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function toggle_favorite_history_item( $id, $context = [] ) { return $this->ai_request( 'POST', sprintf( 'history/%s/favorite', $id ), [ 'context' => wp_json_encode( $context ), 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ] ); } public function get_animation( $data, $context, $request_ids ) { return $this->ai_request( 'POST', 'text/get-motion-effect', [ 'prompt' => $data['payload']['prompt'], 'motionEffectType' => $data['payload']['motionEffectType'], 'context' => wp_json_encode( $context ), 'ids' => $request_ids, 'api_version' => ELEMENTOR_VERSION, 'site_lang' => get_bloginfo( 'language' ), ], false, '', 'json' ); } protected function init() {} } PK ]G}\����� �� module.phpnu �[��� PK ]G}\rY o� � 1 2� feature-intro/product-image-unification-intro.phpnu �[��� PK ]G}\��U� � site-planner-connect/module.phpnu �[��� PK ]G}\�h�� � $ y� site-planner-connect/wp-rest-api.phpnu �[��� PK ]G}\j)�k k �� site-planner-connect/view.phpnu �[��� PK ]G}\4d�Mv v p� preferences.phpnu �[��� PK ]G}\�(Y (Y %� connect/ai.phpnu �[��� PK x �G