get_block_parse_rules(); $data = array( 'blockRules' => json_encode( $block_parse_rules ), ); return wp_send_json_success( $data ); exit; } /** * Fetches post meta fields via AJAX request. */ public function fetch_post_meta_fields() { if ( ! check_ajax_referer( 'atfp_fetch_post_meta_fields', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = isset( $_POST['postId']) ? absint(sanitize_text_field($_POST['postId'])) : false; if(!isset($post_id) || false === $post_id){ wp_send_json_error( __( 'Invalid Post ID.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if(!current_user_can('edit_post', $post_id)){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $post_meta_sync = true; if (!isset(PLL()->options['sync']) || (isset(PLL()->options['sync']) && !in_array('post_meta', PLL()->options['sync']))) { $post_meta_sync = false; } if($post_meta_sync){ wp_send_json_success( __( 'Post meta sync is enabled. Please disable post meta sync in Polylang settings.', 'autopoly-ai-translation-for-polylang-pro' ) ); } $allowed_meta_fields=ATFPP_Helper::get_allowed_custom_fields(); $post_meta_fields=get_post_meta($post_id); $existed_meta_fields=array_intersect(array_keys($post_meta_fields), array_keys($allowed_meta_fields)); $filtered_meta_fields=array(); foreach($existed_meta_fields as $key){ if(isset($post_meta_fields[$key]) && !empty($post_meta_fields[$key]) && isset($allowed_meta_fields[$key]['status']) && true === $allowed_meta_fields[$key]['status']){ $value=$allowed_meta_fields[$key]['type'] && is_array($post_meta_fields[$key]) ? maybe_unserialize($post_meta_fields[$key][0]) : maybe_unserialize($post_meta_fields[$key]); $filtered_meta_fields[$key]=$value; } } wp_send_json_success( array( 'metaFields' => $filtered_meta_fields, 'allowedMetaFields' => $allowed_meta_fields ) ); exit; } public function update_post_meta_fields() { if ( ! check_ajax_referer( 'atfp_update_post_meta_fields', 'post_meta_fields_key', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = isset( $_POST['post_id']) ? absint(sanitize_text_field($_POST['post_id'])) : false; if(!isset($post_id) || false === $post_id){ wp_send_json_error( __( 'Invalid Post ID.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if(!current_user_can('edit_post', $post_id)){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $meta_fields = isset( $_POST['meta_fields']) ? json_decode(wp_unslash($_POST['meta_fields']), true) : false; if(!$meta_fields || !is_array($meta_fields) || count($meta_fields) < 1){ wp_send_json_success( __( 'No Meta Fields to update.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 200 ); } $this->update_post_custom_fields($meta_fields, $post_id); wp_send_json_success( __( 'Meta Fields updated successfully.', 'autopoly-ai-translation-for-polylang-pro' ) ); exit; } /** * Fetches post meta fields via AJAX request. /** * Fetches post content via AJAX request. */ public function fetch_post_content() { if ( ! check_ajax_referer( 'atfp_translate_nonce', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = absint(isset( $_POST['postId'] ) ? absint(sanitize_text_field($_POST['postId'])) : false); if(!current_user_can('edit_post', $post_id)){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } if ( false !== $post_id ) { $post_data = get_post( absint($post_id) ); $locale = isset($_POST['local']) ? sanitize_text_field($_POST['local']) : 'en'; $current_locale = isset($_POST['current_local']) ? sanitize_text_field($_POST['current_local']) : 'en'; $slug_translation_option = get_option('atfp_slug_translation_option','title_translate'); $content = $post_data->post_content; $content = ATFPP_Helper::replace_links_with_translations($content, $locale, $current_locale); $data = array( 'title' => $post_data->post_title, 'excerpt' => $post_data->post_excerpt, 'content' => $content, ); if($slug_translation_option === 'slug_translate' || $slug_translation_option === 'slug_keep'){ $data['slug_name']=urldecode(get_post_field('post_name', $post_id)); } return wp_send_json_success( $data ); } else { wp_send_json_error( __( 'Invalid Post ID.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } exit; } public function get_custom_blocks_content() { if ( ! check_ajax_referer( 'atfp_block_update_nonce', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if(!current_user_can('edit_posts')){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $custom_content = get_option( 'atfp_custom_block_data', false ) ? get_option( 'atfp_custom_block_data', false ) : false; if ( $custom_content && is_string( $custom_content ) && ! empty( trim( $custom_content ) ) ) { return wp_send_json_success( array( 'block_data' => $custom_content ) ); } else { return wp_send_json_success( array( 'message' => __( 'No custom blocks found.', 'autopoly-ai-translation-for-polylang-pro' ) ) ); } exit(); } public function update_custom_blocks_content() { if ( ! check_ajax_referer( 'atfp_block_update_nonce', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if(!current_user_can('edit_posts')){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $json = isset($_POST['save_block_data']) ? wp_unslash($_POST['save_block_data']) : false; $updated_blocks_data = json_decode($json, true); if(json_last_error() !== JSON_ERROR_NONE){ wp_send_json_error( __( 'Invalid JSON', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if ( $updated_blocks_data ) { $block_parse_rules = ATFPP_Helper::get_instance()->get_block_parse_rules(); if ( isset( $block_parse_rules['AtfpBlockParseRules'] ) ) { $previous_translate_data = get_option( 'atfp_custom_block_translation', false ); if ( $previous_translate_data && ! empty( $previous_translate_data ) ) { $this->custom_block_data_array = $previous_translate_data; } foreach ( $updated_blocks_data as $key => $block_data ) { $this->verify_block_data( array( $key ), $block_data, $block_parse_rules['AtfpBlockParseRules'][ $key ] ); } if ( count( $this->custom_block_data_array ) > 0 ) { update_option( 'atfp_custom_block_translation', $this->custom_block_data_array ); } delete_option( 'atfp_custom_block_data' ); } } return wp_send_json_success( array( 'message' => __( 'Automatic Translation for Polylang: Custom Blocks data updated successfully', 'autopoly-ai-translation-for-polylang-pro' ) ) ); } private function verify_block_data( $id_keys, $value, $block_rules ) { $block_rules = is_object( $block_rules ) ? json_decode( json_encode( $block_rules ) ) : $block_rules; if ( ! isset( $block_rules ) ) { return $this->create_nested_attribute( $value,$id_keys ); } if ( is_array( $value ) && isset( $block_rules ) ) { foreach ( $value as $key => $item ) { if ( isset( $block_rules[ $key ] ) && is_array( $item ) ) { $this->verify_block_data( array_merge( $id_keys, array( $key ) ), $item, $block_rules[ $key ], false ); continue; } elseif ( ! isset( $block_rules[ $key ] ) && true === $item ) { $this->create_nested_attribute( true,array_merge( $id_keys, array( $key ) ) ); continue; } elseif ( ! isset( $block_rules[ $key ] ) && is_array( $item ) ) { $this->create_nested_attribute( $item,array_merge( $id_keys, array( $key ) ) ); continue; } } } } private function create_nested_attribute( $value,$id_keys = array() ) { $value = is_object( $value ) ? json_decode( json_encode( $value ), true ) : $value; $current_array = &$this->custom_block_data_array; foreach ( $id_keys as $index => $id ) { if ( ! isset( $current_array[ $id ] ) ) { $current_array[ $id ] = array(); } $current_array = &$current_array[ $id ]; } $current_array = $value; } public function atfp_update_translate_data() { if ( ! check_ajax_referer( 'atfp_translate_nonce', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = isset($_POST['post_id']) ? absint(sanitize_text_field($_POST['post_id'])) : 0; $editor_type = isset($_POST['editorType']) ? sanitize_text_field($_POST['editorType']) : ''; $extra_data=isset($_POST['extraData']) ? json_decode(wp_unslash($_POST['extraData']), true) : []; // Require capability based on context if ( $post_id > 0 ) { if ( ! current_user_can('edit_post', $post_id) && $editor_type !== 'taxonomy' ) { wp_send_json_error( __( 'Unauthorized to edit post', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } if($editor_type === 'taxonomy'){ if ( ! current_user_can('edit_posts') ) { wp_send_json_error( __( 'Unauthorized to edit terms', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } } } else { if ( ! current_user_can('edit_posts') ) { wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } } $provider = isset($_POST['provider']) ? sanitize_text_field($_POST['provider']) : ''; $total_string_count = isset($_POST['totalStringCount']) ? absint($_POST['totalStringCount']) : 0; $total_word_count = isset($_POST['totalWordCount']) ? absint($_POST['totalWordCount']) : 0; $total_char_count = isset($_POST['totalCharacterCount']) ? absint($_POST['totalCharacterCount']) : 0; $date = isset($_POST['date']) ? date('Y-m-d H:i:s', strtotime(sanitize_text_field($_POST['date']))) : ''; $source_string_count = isset($_POST['sourceStringCount']) ? absint($_POST['sourceStringCount']) : 0; $source_word_count = isset($_POST['sourceWordCount']) ? absint($_POST['sourceWordCount']) : 0; $source_char_count = isset($_POST['sourceCharacterCount']) ? absint($_POST['sourceCharacterCount']) : 0; $source_lang = isset($_POST['sourceLang']) ? sanitize_text_field($_POST['sourceLang']) : ''; $target_lang = isset($_POST['targetLang']) ? sanitize_text_field($_POST['targetLang']) : ''; $time_taken = isset($_POST['timeTaken']) ? absint($_POST['timeTaken']) : 0; if (class_exists('Atfpp_Dashboard')) { $translation_data = array( 'post_id' => $post_id, 'service_provider' => $provider, 'source_language' => $source_lang, 'target_language' => $target_lang, 'time_taken' => $time_taken, 'string_count' => $total_string_count, 'word_count' => $total_word_count, 'character_count' => $total_char_count, 'source_string_count' => $source_string_count, 'source_word_count' => $source_word_count, 'source_character_count' => $source_char_count, 'editor_type' => $editor_type, 'date_time' => $date, 'version_type' => 'pro' ); if(!empty($extra_data) && is_array($extra_data) && count($extra_data) > 0){ foreach($extra_data as $key => $value){ if(!isset($translation_data[$key]) && !empty($value) && !empty($key)){ $translation_data[sanitize_text_field($key)] = sanitize_text_field($value); } } } Atfpp_Dashboard::store_options( 'atfp', 'post_id', 'update', $translation_data ); wp_send_json_success(array( 'message' => __('Translation data updated successfully', 'autopoly-ai-translation-for-polylang-pro') )); } else { wp_send_json_error(array( 'message' => __('Atfpp_Dashboard class not found', 'autopoly-ai-translation-for-polylang-pro') )); } exit; } public function update_classic_translate_status() { if ( ! check_ajax_referer( 'atfp_classic_translate_nonce', 'atfpp_update_translation_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = isset($_POST['post_id']) ? absint(sanitize_text_field($_POST['post_id'])) : 0; if ( ! $post_id || ! current_user_can('edit_post', $post_id) ) { wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : ''; if ( $status !== 'completed' ) { wp_send_json_error( __( 'Invalid status', 'autopoly-ai-translation-for-polylang-pro' ), 400 ); wp_die( '0', 400 ); } update_post_meta($post_id, '_atfp_classic_translate_status', $status); wp_send_json_success( 'Classic translate status updated.' ); } /** * Handle AJAX request to update Elementor data. */ public function update_elementor_data() { if ( ! check_ajax_referer( 'atfp_translate_nonce', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $post_id = isset($_POST['post_id']) ? absint(sanitize_text_field($_POST['post_id'])) : 0; if ( ! $post_id || ! current_user_can('edit_post', $post_id) ) { wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } // Optional hardening: enforce valid JSON if not using Elementor Document API if ( isset($_POST['elementor_data']) && is_string($_POST['elementor_data']) ) { $decoded = json_decode( stripslashes( $_POST['elementor_data'] ), true ); if ( json_last_error() !== JSON_ERROR_NONE ) { wp_send_json_error( __( 'Invalid data.', 'autopoly-ai-translation-for-polylang-pro' ), 400 ); wp_die( '0', 400 ); } } $parent_post_id=intval( $_POST['parent_post_id'] ); $slug_translation_option = get_option('atfp_slug_translation_option','title_translate'); $current_slug=get_post_field('post_name', $post_id); $new_post_name=false; $new_meta_fields=isset($_POST['meta_fields']) ? json_decode(wp_unslash($_POST['meta_fields']), true) : false; $elementor_data = isset($_POST['elementor_data']) ? sanitize_text_field(wp_unslash($_POST['elementor_data'])) : ''; if('' === $current_slug){ if(isset($_POST['post_name']) && '' !== $_POST['post_name'] && $slug_translation_option === 'slug_translate'){ $new_post_name=sanitize_title($_POST['post_name']); }else if($slug_translation_option === 'slug_keep'){ $new_post_name=sanitize_text_field(get_post_field('post_name', $parent_post_id)); } } // Check if the current post has Elementor data if($elementor_data && '' !== $elementor_data){ if(class_exists('Elementor\Plugin')){ $plugin=\Elementor\Plugin::$instance; $document=$plugin->documents->get($post_id); $elementor_data=json_decode(wp_unslash($_POST['elementor_data']), true); if (json_last_error() !== JSON_ERROR_NONE) { wp_send_json_error( __( 'Invalid Elementor data.', 'autopoly-ai-translation-for-polylang-pro' ), 400 ); wp_die( '0', 400 ); } $document->save( [ 'elements' => $elementor_data, ] ); $plugin->files_manager->clear_cache(); $this->update_post_custom_fields($new_meta_fields, $post_id); update_post_meta($post_id, '_atfp_elementor_translated', 'true'); } } if($new_post_name && '' !== $new_post_name){ wp_update_post(array( 'ID' => $post_id, 'post_name' => $new_post_name )); } wp_send_json_success( 'Elementor data updated.' ); exit; } private function update_post_custom_fields($fields, $post_id){ $post_meta_sync = true; if (!isset(PLL()->options['sync']) || (isset(PLL()->options['sync']) && !in_array('post_meta', PLL()->options['sync']))) { $post_meta_sync = false; } if($post_meta_sync){ return; } $allowed_meta_fields=ATFPP_Helper::get_allowed_custom_fields(); if($fields && is_array($fields) && count($fields) > 0){ $valid_meta_fields=array_intersect(array_keys($fields), array_keys($allowed_meta_fields)); if(count($valid_meta_fields) > 0){ foreach($valid_meta_fields as $key){ if(isset($allowed_meta_fields[$key]) && $allowed_meta_fields[$key]['status']){ $value=is_array($fields[$key]) ? $this->sanitize_array_value($fields[$key], array()) : sanitize_text_field($fields[$key]); update_post_meta(absint($post_id), sanitize_text_field($key), $value); } } } } } private function sanitize_array_value($value, $arr){ foreach($value as $key => $item){ $arr[sanitize_text_field($key)]=is_array($item) ? $this->sanitize_array_value($item, array()) : sanitize_text_field($item); } return $arr; } public function update_custom_fields_content() { if ( ! check_ajax_referer( 'atfp_save_custom_fields', 'atfp_nonce', false ) ) { wp_send_json_error( __( 'Invalid security token sent.', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } if(!current_user_can('edit_posts')){ wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 ); wp_die( '0', 403 ); } $json = isset($_POST['save_custom_fields_data']) ? wp_unslash($_POST['save_custom_fields_data']) : false; $updated_custom_fields_data = json_decode($json, true); $updated_custom_fields_data=array_map('sanitize_text_field', $updated_custom_fields_data); $existing_fields=get_option('atfp_allowed_custom_fields', false); if(json_last_error() !== JSON_ERROR_NONE){ wp_send_json_error( __( 'Invalid JSON', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $allowed_fields=ATFPP_Helper::get_instance()->get_custom_fields_data(); if(!$allowed_fields || !is_array($allowed_fields)){ wp_send_json_error( __( 'Invalid allowed fields', 'autopoly-ai-translation-for-polylang-pro' ) ); wp_die( '0', 400 ); } $allowed_fields_values=array_keys($allowed_fields); $valid_fields=array_intersect($updated_custom_fields_data, $allowed_fields_values); $sanitize_fields=array(); $old_fields=array(); foreach($valid_fields as $field){ if(!isset($existing_fields[$field]) || $existing_fields[$field]['status'] !== true || $existing_fields[$field]['type'] !== $allowed_fields[$field]['type']){ $sanitize_fields[sanitize_text_field($field)]=['status'=>true, 'type'=>sanitize_text_field($allowed_fields[$field]['type'])]; }else{ $old_fields[$field]=$existing_fields[$field]; } } $unset_fields=array_diff(array_keys($existing_fields), $updated_custom_fields_data ); foreach($unset_fields as $field){ if(isset($existing_fields[$field]) && $existing_fields[$field]['status'] === true){ $sanitize_fields[$field]=$existing_fields[$field]; $sanitize_fields[$field]['status']=false; } } if(count($sanitize_fields) < 1){ wp_send_json_success(array( 'message' => __( 'No changes detected. All selected custom fields are already up to date.', 'autopoly-ai-translation-for-polylang-pro' ) )); exit; } update_option('atfp_allowed_custom_fields', array_merge($old_fields, $sanitize_fields)); $save_settings=get_option('atfp_allowed_custom_fields', false); if ( ! $save_settings || ! is_array( $save_settings ) || count( $save_settings ) < 1 ) { wp_send_json_success( array( 'message' => __( 'No custom fields selected. Autopoly cannot translate any fields.', 'autopoly-ai-translation-for-polylang-pro' ) ) ); exit; } wp_send_json_success( array( 'message' => __( 'Custom fields translation settings have been updated successfully. Your selected fields will now be translated automatically.', 'autopoly-ai-translation-for-polylang-pro' ), 'updated_fields' => $sanitize_fields ) ); exit; } } }