/ wordpress / restai / includes / class-restai-translation.php
class-restai-translation.php
 1  <?php
 2  /**
 3   * Translation feature. Saves the translated copy as a draft post and links it
 4   * back to the source. Polylang / WPML connectors are stubbed for now.
 5   *
 6   * @package RESTai
 7   */
 8  
 9  namespace RESTai;
10  
11  if ( ! defined( 'ABSPATH' ) ) {
12  	exit;
13  }
14  
15  class Translation {
16  
17  	/** @var Client */
18  	private $client;
19  
20  	public function __construct( Client $client ) {
21  		$this->client = $client;
22  	}
23  
24  	/**
25  	 * @param int    $post_id
26  	 * @param string $language Target language name (e.g. "Spanish").
27  	 * @return array|\WP_Error
28  	 */
29  	public function translate_post( $post_id, $language ) {
30  		$post = get_post( $post_id );
31  		if ( ! $post ) {
32  			return new \WP_Error( 'restai_no_post', __( 'Post not found.', 'restai' ) );
33  		}
34  
35  		$plugin     = Plugin::instance();
36  		$project_id = $plugin->provisioner->project_for( 'translator' );
37  		if ( $project_id <= 0 ) {
38  			return new \WP_Error( 'restai_no_project', __( 'Translator project not configured.', 'restai' ) );
39  		}
40  
41  		$prompt_title = "Translate the following text to {$language}. Return only the translated text.\n\n" . $post->post_title;
42  		$prompt_body  = "Translate the following HTML to {$language}. Preserve all tags. Return only the translated HTML.\n\n" . $post->post_content;
43  
44  		$translated_title = $this->client->ask( $project_id, $prompt_title );
45  		if ( is_wp_error( $translated_title ) ) {
46  			return $translated_title;
47  		}
48  		$translated_body = $this->client->ask( $project_id, $prompt_body );
49  		if ( is_wp_error( $translated_body ) ) {
50  			return $translated_body;
51  		}
52  
53  		$new_id = wp_insert_post(
54  			array(
55  				'post_title'   => wp_strip_all_tags( $translated_title ),
56  				'post_content' => wp_kses_post( $translated_body ),
57  				'post_status'  => 'draft',
58  				'post_type'    => $post->post_type,
59  				'post_author'  => get_current_user_id(),
60  			),
61  			true
62  		);
63  
64  		if ( is_wp_error( $new_id ) ) {
65  			return $new_id;
66  		}
67  
68  		update_post_meta( $new_id, '_restai_translated_from', $post_id );
69  		update_post_meta( $new_id, '_restai_translation_language', $language );
70  
71  		// Polylang integration — register language if available.
72  		if ( function_exists( 'pll_set_post_language' ) ) {
73  			$lang_code = $this->language_to_code( $language );
74  			if ( $lang_code ) {
75  				pll_set_post_language( $new_id, $lang_code );
76  			}
77  		}
78  
79  		return array(
80  			'new_post_id' => $new_id,
81  			'edit_url'    => get_edit_post_link( $new_id, '' ),
82  		);
83  	}
84  
85  	private function language_to_code( $language ) {
86  		$map = array(
87  			'Spanish'              => 'es',
88  			'Portuguese'           => 'pt',
89  			'French'               => 'fr',
90  			'German'               => 'de',
91  			'Italian'              => 'it',
92  			'Dutch'                => 'nl',
93  			'Polish'               => 'pl',
94  			'Japanese'             => 'ja',
95  			'Chinese (Simplified)' => 'zh',
96  		);
97  		return isset( $map[ $language ] ) ? $map[ $language ] : null;
98  	}
99  }