<?php /** * Plugin Name: Wpct i18n * Plugin URI: https://git.coopdevs.org/codeccoop/wp/wpct-i18n * Description: String translation * Author: Còdec Cooperativa * Author URI: https://www.codeccoop.org * Text Domain: wpct-i18n * Domain Path: /languages * Version: 1.0.5 * * @package Wpct_i18n */ namespace WPCT_I18N; use WP_Post; use WP_Term; if (!defined('ABSPATH')) { exit; } if (!class_exists('\WPCT_I18N\Wpct_i18n')) : require_once 'abstracts/class-plugin.php'; define('WPCT_I18N_VERSION', '1.0.5'); class Wpct_i18n extends \WPCT_ABSTRACT\Plugin { private $_integration; public static $name = 'Wpct i18n'; public static $textdomain = 'wpct-i18n'; public static function activate() { } public static function deactivate() { } public function __construct() { parent::__construct(); } public function init() { // Hooks add_filter('wpct_i18n_default_language', [$this, 'default_language'], 10, 2); add_filter('wpct_i18n_current_language', [$this, 'current_language'], 10, 2); add_filter('wpct_i18n_active_languages', [$this, 'active_languages'], 10, 2); add_filter('wpct_i18n_post_language', [$this, 'post_language'], 10, 2); add_filter('wpct_i18n_post_translations', [$this, 'post_translations'], 10); add_filter('wpct_i18n_term_translations', [$this, 'term_translations'], 10); add_filter('wpct_i18n_is_translation', [$this, 'is_translation'], 10); add_filter('wpct_i18n_translate_post', [$this, 'translate_post'], 10, 2); add_action('wpct_i18n_language_switcher', [$this, 'language_switcher']); // Configure integration if (apply_filters('wpct_is_plugin_active', false, 'polylang/polylang.php')) { $this->_integration = 'pll'; } elseif (apply_filters('wpct_is_plugin_active', false, 'sitepress-multilingual-cms/sitepress.php')) { $this->_integration = 'wpml'; } $this->trans_status(); } private function get_wpml_language_by_slug($slug) { $languages = apply_filters('wpml_active_languages', null); $codes = array_values(array_filter(array_keys($languages), function ($code) use ($slug, $languages) { $lang = $languages[$code]; return $lang['language_code'] === $slug; })); if (count($codes) === 0) { return null; } return $languages[$codes[0]]; } public function default_language($null = null, $format = 'slug') { switch ($this->_integration) { case 'pll': return pll_default_language($format); case 'wpml': $slug = apply_filters('wpml_default_language', null); if ($format === 'slug') { return $slug; } else { $language = $this->get_wpml_language_by_slug($slug); return $language['default_locale']; } break; default: $locale = get_locale(); if ($format === 'locale') { return $locale; } return strtolower(preg_replace('/_\w+$/', '', $locale)); } } public function current_language($null = null, $format = 'slug') { switch ($this->_integration) { case 'pll': return pll_current_language($format); case 'wpml': $slug = apply_filters('wpml_current_language', null); if ($format === 'slug') { return $slug; } else { $language = $this->get_wpml_language_by_slug($slug); return $language['default_locale']; } // no break default: $locale = get_locale(); if ($format === 'locale') { return $locale; } return strtolower(preg_replace('/_\w+$/', '', $locale)); } } public function active_languages($null = null, $format = 'slug') { switch ($this->_integration) { case 'pll': return pll_languages_list(['fields' => $format, 'hide_empty' => false]); case 'wpml': $languages = apply_filters('wpml_active_languages', null); $field = $format === 'slug' ? 'language_code' : 'default_locale'; return array_map(function ($lng) use ($field) { return $lng[$field]; }, $languages); default: $languages = [get_locale()]; if ($format === 'locale') { return $languages; } return array_map(function ($locale) { return strtolower(preg_replace('/_\w+$/', '', $locale)); }, $languages); } } public function language_switcher($echo = true) { if (!$echo) { ob_start(); } switch ($this->_integration) { case 'pll': pll_the_languages(); break; case 'wpml': do_action('wpml_add_language_selector'); break; default: // do nothing } if (!$echo) { return ob_get_clean(); } } public function post_language($post_id, $format = 'slug') { if ($post_id instanceof WP_Post) { $post_id = $post_id->ID; } switch ($this->_integration) { case 'pll': return pll_get_post_language($post_id, $format); case 'wpml': $details = apply_filters('wpml_post_language_details', null, $post_id); if ($format === 'slug') { return $details['language_code']; } else { return $details['locale']; } break; default: return null; } } public function post_translations($post_id) { if ($post_id instanceof WP_Post) { $post_id = $post_id->ID; } switch ($this->_integration) { case 'pll': return pll_get_post_translations($post_id); case 'wpml': $type = apply_filters('wpml_element_type', get_post_type($post_id)); $trid = apply_filters('wpml_element_trid', false, $post_id, $type); $translations = []; foreach (apply_filters('wpml_get_element_translations', [], $trid, $type) as $trans) { $translations[$trans->language_code] = (int) $trans->element_id; } return $translations; default: $current_lang = $this->current_language(); return [$current_lang => $post_id]; } } public function term_translations($term_id) { if ($term_id instanceof WP_Term) { $term_id = $term_id->term_id; } switch ($this->_integration) { case 'pll': return pll_get_term_translations($term_id); case 'wpml': $type = apply_filters('wpml_element_type', 'category'); $trid = apply_filters('wpml_element_trid', false, $term_id, $type); $translations = []; foreach (apply_filters('wpml_get_element_translations', [], $trid, $type) as $trans) { $translations[$trans->language_code] = (int) $trans->element_id; } return $translations; default: $current_lang = $this->current_language(); return [$current_lang => $term_id]; } } public function is_translation($post_id) { if ($post_id instanceof WP_Post) { $post_id = $post_id->ID; } switch ($this->_integration) { case 'pll': $post_lang = pll_get_post_language($post_id); return $post_lang !== $this->default_language(); case 'wpml': $lang_details = apply_filters('wpml_post_language_details', null, $post_id); return !empty($lang_details['language_code']) && $lang_details['language_code'] !== $this->default_language(); default: return false; } } public function translate_post($post, $lang) { if (is_int($post)) { $post = get_post($post); } $post_data = wp_slash((array) $post); $post_data['_thumbnail_id'] = get_post_thumbnail_id($post_data['ID']); unset($post_data['ID']); $post_data['post_status'] = 'translating'; $trans_id = wp_insert_post($post_data); switch ($this->_integration) { case 'pll': $post_lang = pll_get_post_language($post->ID); pll_set_post_language($trans_id, $lang); pll_save_post_translations([ $lang => $trans_id, $post_lang => $post->ID, ]); break; case 'wpml': $element_type = apply_filters('wpml_element_type', $post->post_type); $lang_details = apply_filters( 'wpml_element_language_details', null, [ 'element_id' => $post->ID, 'element_type' => $element_type ] ); do_action('wpml_set_element_language_details', [ 'element_id' => $trans_id, 'element_type' => $element_type, 'trid' => $lang_details->trid, 'language_code' => $lang, 'source_language_code' => $lang_details->language_code ]); break; default: return null; } wp_update_post([ 'ID' => $trans_id, 'post_status' => $post->post_status ]); return $trans_id; } public function trans_status() { register_post_status('translating', [ 'label' => __('Provisional status while translating post', 'wpct-i18n'), 'public' => false, 'internal' => true ]); } } add_action('plugins_loaded', function () { $plugin = Wpct_i18n::get_instance(); }, 10); register_activation_hook(__FILE__, function () { Wpct_i18n::activate(); }); register_deactivation_hook(__FILE__, function () { Wpct_i18n::deactivate(); }); endif;