deepseek+n8n翻译wp动态内容预配置

/**
 * Plugin Name: Polylang REST API Extension
 * Description: Custom REST API endpoints for Polylang free version
 * Version: 1.0.0
 * Author: Your Name
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class Polylang_REST_API_Extension {
    
    private $namespace = 'polylang-api/v1';
    
    public function __construct() {
        add_action('rest_api_init', array($this, 'register_routes'));
    }
    
    /**
     * Register all REST API routes
     */
    public function register_routes() {
        // Get untranslated posts
        register_rest_route($this->namespace, '/untranslated-posts', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_untranslated_posts'),
            'permission_callback' => array($this, 'check_permission'),
            'args' => array(
                'post_type' => array(
                    'default' => 'post',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'source_lang' => array(
                    'default' => 'en',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'target_lang' => array(
                    'required' => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ),
            ),
        ));
        
        // Get post content for translation
        register_rest_route($this->namespace, '/post/(?P<id>\d+)', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_post_content'),
            'permission_callback' => array($this, 'check_permission'),
            'args' => array(
                'id' => array(
                    'validate_callback' => function($param) {
                        return is_numeric($param);
                    }
                ),
            ),
        ));
        
        // Create translated post
        register_rest_route($this->namespace, '/translate-post', array(
            'methods' => 'POST',
            'callback' => array($this, 'create_translated_post'),
            'permission_callback' => array($this, 'check_permission'),
        ));
        
        // Get languages
        register_rest_route($this->namespace, '/languages', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_languages'),
            'permission_callback' => array($this, 'check_permission'),
        ));
        
        // Get translation status
        register_rest_route($this->namespace, '/translation-status/(?P<id>\d+)', array(
            'methods' => 'GET',
            'callback' => array($this, 'get_translation_status'),
            'permission_callback' => array($this, 'check_permission'),
        ));
    }
    
    /**
     * Permission callback - check if user can edit posts
     */
    public function check_permission() {
        return current_user_can('edit_posts');
    }
    
    /**
     * Get all untranslated posts for a specific language
     */
    public function get_untranslated_posts($request) {
        if (!function_exists('pll_languages_list')) {
            return new WP_Error('polylang_not_active', 'Polylang is not active', array('status' => 500));
        }
        
        $post_type = $request->get_param('post_type');
        $source_lang = $request->get_param('source_lang');
        $target_lang = $request->get_param('target_lang');
        
        // Get all posts in source language
        $args = array(
            'post_type' => $post_type,
            'posts_per_page' => -1,
            'lang' => $source_lang,
            'post_status' => 'publish',
        );
        
        $posts = get_posts($args);
        $untranslated = array();
        
        foreach ($posts as $post) {
            // Check if translation exists in target language
            $translation_id = pll_get_post($post->ID, $target_lang);
            
            if (!$translation_id) {
                $untranslated[] = array(
                    'id' => $post->ID,
                    'title' => $post->post_title,
                    'slug' => $post->post_name,
                    'status' => $post->post_status,
                    'date' => $post->post_date,
                    'modified' => $post->post_modified,
                    'post_type' => $post->post_type,
                    'language' => $source_lang,
                );
            }
        }
        
        return rest_ensure_response(array(
            'success' => true,
            'count' => count($untranslated),
            'posts' => $untranslated,
        ));
    }
    
    /**
     * Get full post content for translation
     */
    public function get_post_content($request) {
        $post_id = $request->get_param('id');
        $post = get_post($post_id);
        
        if (!$post) {
            return new WP_Error('post_not_found', 'Post not found', array('status' => 404));
        }
        
        // Get post meta
        $post_meta = get_post_meta($post_id);
        
        // Get categories and tags
        $categories = wp_get_post_categories($post_id, array('fields' => 'all'));
        $tags = wp_get_post_tags($post_id, array('fields' => 'all'));
        
        // Get featured image
        $thumbnail_id = get_post_thumbnail_id($post_id);
        $thumbnail_url = $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : null;
        
        // Get ACF fields if ACF is active
        $acf_fields = array();
        if (function_exists('get_fields')) {
            $acf_fields = get_fields($post_id);
        }
        
        // Get current language
        $current_lang = pll_get_post_language($post_id);
        
        return rest_ensure_response(array(
            'success' => true,
            'post' => array(
                'id' => $post->ID,
                'title' => $post->post_title,
                'content' => $post->post_content,
                'excerpt' => $post->post_excerpt,
                'slug' => $post->post_name,
                'status' => $post->post_status,
                'type' => $post->post_type,
                'language' => $current_lang,
                'featured_image' => $thumbnail_url,
                'thumbnail_id' => $thumbnail_id,
                'categories' => $categories,
                'tags' => $tags,
                'meta' => $post_meta,
                'acf_fields' => $acf_fields,
            ),
        ));
    }
    
    /**
     * Create a translated version of a post
     */
    public function create_translated_post($request) {
        $params = $request->get_json_params();
        
        if (!isset($params['source_post_id']) || !isset($params['target_lang'])) {
            return new WP_Error('missing_params', 'Missing required parameters', array('status' => 400));
        }
        
        $source_post_id = intval($params['source_post_id']);
        $target_lang = sanitize_text_field($params['target_lang']);
        $translated_title = sanitize_text_field($params['title']);
        $translated_content = wp_kses_post($params['content']);
        $translated_excerpt = isset($params['excerpt']) ? sanitize_textarea_field($params['excerpt']) : '';
        
        $source_post = get_post($source_post_id);
        
        if (!$source_post) {
            return new WP_Error('post_not_found', 'Source post not found', array('status' => 404));
        }
        
        // Check if translation already exists
        $existing_translation = pll_get_post($source_post_id, $target_lang);
        
        if ($existing_translation) {
            // Update existing translation
            $updated_post = array(
                'ID' => $existing_translation,
                'post_title' => $translated_title,
                'post_content' => $translated_content,
                'post_excerpt' => $translated_excerpt,
            );
            
            $result = wp_update_post($updated_post, true);
            
            if (is_wp_error($result)) {
                return $result;
            }
            
            $translated_post_id = $existing_translation;
            $action = 'updated';
        } else {
            // Create new translation
            $new_post = array(
                'post_title' => $translated_title,
                'post_content' => $translated_content,
                'post_excerpt' => $translated_excerpt,
                'post_status' => $source_post->post_status,
                'post_type' => $source_post->post_type,
                'post_author' => $source_post->post_author,
            );
            
            $translated_post_id = wp_insert_post($new_post, true);
            
            if (is_wp_error($translated_post_id)) {
                return $translated_post_id;
            }
            
            // Set language for the new post
            pll_set_post_language($translated_post_id, $target_lang);
            
            // Link the translation
            pll_save_post_translations(array(
                pll_get_post_language($source_post_id) => $source_post_id,
                $target_lang => $translated_post_id,
            ));
            
            $action = 'created';
        }
        
        // Copy featured image if exists
        $thumbnail_id = get_post_thumbnail_id($source_post_id);
        if ($thumbnail_id) {
            set_post_thumbnail($translated_post_id, $thumbnail_id);
        }
        
        // Translate and assign categories
        if (isset($params['categories']) && is_array($params['categories'])) {
            $translated_category_ids = array();
            foreach ($params['categories'] as $category_data) {
                $cat_id = $this->translate_term($category_data, 'category', $target_lang);
                if ($cat_id) {
                    $translated_category_ids[] = $cat_id;
                }
            }
            wp_set_post_categories($translated_post_id, $translated_category_ids);
        }
        
        // Translate and assign tags
        if (isset($params['tags']) && is_array($params['tags'])) {
            $translated_tag_ids = array();
            foreach ($params['tags'] as $tag_data) {
                $tag_id = $this->translate_term($tag_data, 'post_tag', $target_lang);
                if ($tag_id) {
                    $translated_tag_ids[] = $tag_id;
                }
            }
            wp_set_post_tags($translated_post_id, $translated_tag_ids);
        }
        
        // Handle ACF fields if provided
        if (isset($params['acf_fields']) && function_exists('update_field')) {
            foreach ($params['acf_fields'] as $field_key => $field_value) {
                update_field($field_key, $field_value, $translated_post_id);
            }
        }
        
        return rest_ensure_response(array(
            'success' => true,
            'action' => $action,
            'translated_post_id' => $translated_post_id,
            'source_post_id' => $source_post_id,
            'target_language' => $target_lang,
            'url' => get_permalink($translated_post_id),
        ));
    }
    
    /**
     * Helper function to translate taxonomy terms
     */
    private function translate_term($term_data, $taxonomy, $target_lang) {
        $source_term_id = isset($term_data['term_id']) ? intval($term_data['term_id']) : 0;
        $translated_name = isset($term_data['translated_name']) ? sanitize_text_field($term_data['translated_name']) : '';
        
        if ($source_term_id && function_exists('pll_get_term')) {
            // Check if translation exists
            $existing_translation = pll_get_term($source_term_id, $target_lang);
            
            if ($existing_translation) {
                return $existing_translation;
            }
        }
        
        // Create new term if translation doesn't exist
        if ($translated_name) {
            $new_term = wp_insert_term($translated_name, $taxonomy);
            
            if (!is_wp_error($new_term)) {
                $new_term_id = $new_term['term_id'];
                
                // Set language and link translation
                if (function_exists('pll_set_term_language')) {
                    pll_set_term_language($new_term_id, $target_lang);
                    
                    if ($source_term_id) {
                        $source_lang = pll_get_term_language($source_term_id);
                        pll_save_term_translations(array(
                            $source_lang => $source_term_id,
                            $target_lang => $new_term_id,
                        ));
                    }
                }
                
                return $new_term_id;
            }
        }
        
        return null;
    }
    
    /**
     * Get all configured languages
     */
    public function get_languages() {
        if (!function_exists('pll_languages_list')) {
            return new WP_Error('polylang_not_active', 'Polylang is not active', array('status' => 500));
        }
        
        $languages = pll_languages_list(array('fields' => 'all'));
        $lang_data = array();
        
        foreach ($languages as $lang) {
            $lang_data[] = array(
                'slug' => $lang->slug,
                'name' => $lang->name,
                'locale' => $lang->locale,
                'is_rtl' => $lang->is_rtl,
                'flag' => $lang->flag,
            );
        }
        
        return rest_ensure_response(array(
            'success' => true,
            'languages' => $lang_data,
        ));
    }
    
    /**
     * Get translation status for a specific post
     */
    public function get_translation_status($request) {
        $post_id = $request->get_param('id');
        
        if (!function_exists('pll_get_post_translations')) {
            return new WP_Error('polylang_not_active', 'Polylang is not active', array('status' => 500));
        }
        
        $translations = pll_get_post_translations($post_id);
        $languages = pll_languages_list();
        
        $status = array();
        foreach ($languages as $lang) {
            $status[$lang] = isset($translations[$lang]) ? array(
                'exists' => true,
                'post_id' => $translations[$lang],
                'url' => get_permalink($translations[$lang]),
            ) : array(
                'exists' => false,
                'post_id' => null,
                'url' => null,
            );
        }
        
        return rest_ensure_response(array(
            'success' => true,
            'post_id' => $post_id,
            'translations' => $status,
        ));
    }
}

// Initialize the plugin
new Polylang_REST_API_Extension();
×
deepseek+n8n翻译wp动态内容预配置

deepseek+n8n翻译wp动态内容预配置

/** * Plugin Name: P...