post_id */ abstract public function get_post_translations($post_id); /** * Setup translation relationship between original and translated post * * @param int $original_post_id Original post ID * @param int $translated_post_id Translated post ID * @param string $target_language Target language code (e.g., 'ru', 'es') or full name (e.g., 'Russian') * @return bool|WP_Error Success or error */ abstract public function setup_translation_relationship($original_post_id, $translated_post_id, $target_language); /** * Get translation status for a post across all languages * * @param int $post_id Post ID * @return array Translation status array with language info and translation states */ abstract public function get_translation_status($post_id); /** * Check if a language code exists/is configured in the multilingual plugin * * @param string $lang_code Language code to check * @return bool */ abstract public function language_exists($lang_code); /** * Convert our language name format to the plugin's language code format * * @param string $our_language Our language name (e.g., 'Russian', 'Spanish') * @return string|null Plugin's language code (e.g., 'ru', 'es') or null if not found */ abstract public function get_language_code($our_language); /** * Remove translation relationship for a post * * @param int $post_id Post ID to remove from translations * @return bool Success */ abstract public function remove_translation_relationship($post_id); /** * Get all pages with their translation status * Used for displaying translation overview in admin * * @return array Array of pages with translation status */ abstract public function get_pages_translation_status(); /** * Get language switcher data for admin UI * * @return array Array of language data for switcher */ abstract public function get_language_switcher_data(); /** * Get translation of a post in a specific language * * @param int $post_id Original post ID * @param string $lang_code Target language code * @return int|null Translated post ID or null if not found */ public function get_post_translation($post_id, $lang_code) { $translations = $this->get_post_translations($post_id); return isset($translations[$lang_code]) ? $translations[$lang_code] : null; } /** * Check if a translation exists for a post in a specific language * * @param int $post_id Post ID * @param string $lang_code Language code * @return bool */ public function has_translation($post_id, $lang_code) { return $this->get_post_translation($post_id, $lang_code) !== null; } /** * Language code mapping from full names to ISO codes * This is a shared mapping used by both integrations */ protected static $language_name_map = [ 'English' => 'en', 'Russian' => 'ru', 'Spanish' => 'es', 'French' => 'fr', 'German' => 'de', 'Italian' => 'it', 'Portuguese' => 'pt', 'Ukrainian' => 'uk', 'Belarusian' => 'be', 'Czech' => 'cs', 'Polish' => 'pl', 'Vietnamese' => 'vi', 'Chinese' => 'zh', 'Japanese' => 'ja', 'Korean' => 'ko', 'Arabic' => 'ar', 'Hebrew' => 'he', 'Hindi' => 'hi', 'Turkish' => 'tr', 'Dutch' => 'nl', 'Swedish' => 'sv', 'Norwegian' => 'no', 'Danish' => 'da', 'Finnish' => 'fi', 'Greek' => 'el', 'Hungarian' => 'hu', 'Romanian' => 'ro', 'Bulgarian' => 'bg', 'Croatian' => 'hr', 'Slovak' => 'sk', 'Slovenian' => 'sl', 'Estonian' => 'et', 'Latvian' => 'lv', 'Lithuanian' => 'lt', 'Thai' => 'th', 'Indonesian' => 'id', 'Malay' => 'ms', 'Filipino' => 'fil', 'Catalan' => 'ca', 'Basque' => 'eu', 'Galician' => 'gl' ]; /** * Get language code from full name using shared mapping * * @param string $language_name Full language name * @return string|null ISO language code or null */ protected function get_code_from_name($language_name) { return self::$language_name_map[$language_name] ?? null; } /** * Normalize language code (handle both full names and codes) * * @param string $language Language name or code * @return string|null Normalized language code */ protected function normalize_language_code($language) { if (!is_string($language) || trim($language) === '') { return null; } $clean = str_replace('_', '-', strtolower(trim($language))); // If it's already a configured language in the active integration, return as-is if ($this->language_exists($clean)) { return $clean; } // If it's already a short code (2-3 chars), return as-is if (strlen($clean) <= 3 && preg_match('/^[a-z]{2,3}$/', $clean)) { return $clean; } // If it's a known regional/variant code mapped in Language Mapper (e.g. 'es-mx', 'pt-br') if (class_exists('AITRFOEL_Language_Mapper') && AITRFOEL_Language_Mapper::is_mapped($clean)) { return $clean; } // Check local name map first (e.g. 'Spanish' => 'es') $code = $this->get_code_from_name(trim($language)); if ($code) { return $code; } // Fallback: reverse-lookup via Language Mapper (e.g. 'Spanish (Mexico)' => 'es-mx') if (class_exists('AITRFOEL_Language_Mapper')) { $code = AITRFOEL_Language_Mapper::get_code_from_language_name(trim($language)); if ($code) { return $code; } } // If it matches standard regional language code format (e.g. 'xx-yy' or 'xxx-yyyy') if (preg_match('/^[a-z]{2,3}(-[a-z0-9]{2,4})?$/', $clean)) { return $clean; } return null; } /** * Get the correct permalink for a post in its assigned language * This ensures the multilingual plugin returns the URL with the correct language * Default implementation just uses WordPress get_permalink() * WPML overrides this to use wpml_permalink filter * * @param int $post_id Post ID * @return string The permalink with correct language */ public function get_post_permalink($post_id) { return get_permalink($post_id); } }