Files
Jacek Pyziak cd264483f8 Add PSR HTTP Message Interfaces and Dependencies
- Implemented StreamInterface, UploadedFileInterface, and UriInterface as per PSR standards.
- Added getallheaders function to retrieve HTTP headers in a compatible manner.
- Included LICENSE files for ralouphie/getallheaders and symfony/deprecation-contracts.
- Introduced function for triggering deprecation notices in Symfony.
2025-12-28 12:44:00 +01:00

619 lines
24 KiB
PHP

<?php
/**
* ATFPP Ajax Handler
*
* @package ATFPP
*/
/**
* Do not access the page directly
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use ATFPP\AI_Translate\Services\API\Enums\AI_Capability;
use ATFPP\AI_Translate\Services\API\Helpers;
/**
* Handle ATFPP ajax requests
*/
if ( ! class_exists( 'ATFPP_Ajax_Handler' ) ) {
class ATFPP_Ajax_Handler {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Stores custom block data for processing and retrieval.
*
* This static array holds the data related to custom blocks that are
* used within the plugin. It can be utilized to manage and manipulate
* the custom block information as needed during AJAX requests.
*
* @var array
*/
private $custom_block_data_array = array();
/**
* Gets an instance of our plugin.
*
* @param object $settings_obj timeline settings.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*
* @param object $settings_obj Plugin settings.
*/
public function __construct() {
if ( is_admin() ) {
add_action( 'wp_ajax_atfp_fetch_post_content', array( $this, 'fetch_post_content' ) );
add_action('wp_ajax_atfp_fetch_post_meta_fields', array($this, 'fetch_post_meta_fields'));
add_action('wp_ajax_atfp_update_post_meta_fields', array($this, 'update_post_meta_fields'));
add_action( 'wp_ajax_atfp_block_parsing_rules', array( $this, 'block_parsing_rules' ) );
add_action( 'wp_ajax_atfp_get_custom_blocks_content', array( $this, 'get_custom_blocks_content' ) );
add_action( 'wp_ajax_atfp_update_custom_blocks_content', array( $this, 'update_custom_blocks_content' ) );
add_action('wp_ajax_atfp_update_translate_data', array($this, 'atfp_update_translate_data'));
add_action( 'wp_ajax_atfp_update_elementor_data', array( $this, 'update_elementor_data' ) );
add_action('wp_ajax_atfp_update_classic_translate_status', array($this, 'update_classic_translate_status'));
add_action('wp_ajax_atfp_update_custom_fields_content', array($this, 'update_custom_fields_content'));
}
}
/**
* Block Parsing Rules
*
* Handles the block parsing rules AJAX request.
*/
public function block_parsing_rules() {
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 );
}
if(!current_user_can('edit_posts')){
wp_send_json_error( __( 'Unauthorized', 'autopoly-ai-translation-for-polylang-pro' ), 403 );
wp_die( '0', 403 );
}
$block_parse_rules = ATFPP_Helper::get_instance()->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;
}
}
}