first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Admin_Lang_Switcher {
|
||||
|
||||
private $package;
|
||||
private $args;
|
||||
|
||||
public function __construct( $package, $args ) {
|
||||
$this->package = new WPML_Package( $package );
|
||||
$this->args = $args;
|
||||
add_action( 'wp_before_admin_bar_render', array( $this, 'admin_language_switcher' ) );
|
||||
add_action( 'wp_after_admin_bar_render', array( $this, 'add_meta_box' ) );
|
||||
}
|
||||
|
||||
function admin_language_switcher() {
|
||||
global $wp_admin_bar, $wpdb, $sitepress;
|
||||
|
||||
$parent = 'WPML_PACKAGE_LANG';
|
||||
|
||||
$package_language = $this->package->get_package_language();
|
||||
if ( ! $package_language ) {
|
||||
$package_language = $sitepress->get_default_language();
|
||||
}
|
||||
|
||||
$wpml_pt_meta = new WPML_Package_Translation_Metabox( $this->package, $wpdb, $sitepress, $this->args );
|
||||
$package_language_name = $wpml_pt_meta->get_package_language_name();
|
||||
$wp_admin_bar->add_menu(
|
||||
array(
|
||||
'parent' => false,
|
||||
'id' => $parent,
|
||||
'title' => '<img width="18" height="12" src="' . $sitepress->get_flag_url( $package_language ) . '"> ' . $package_language_name,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function add_meta_box() {
|
||||
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
$metabox = '<div id="wpml-package-admin-bar-popup" class="wpml-package-popup">';
|
||||
|
||||
$wpml_pt_meta = new WPML_Package_Translation_Metabox( $this->package, $wpdb, $sitepress, $this->args );
|
||||
$metabox .= $wpml_pt_meta->get_metabox();
|
||||
|
||||
$metabox .= '</div>';
|
||||
|
||||
$metabox .= $this->add_js();
|
||||
|
||||
// This is required when a new package is created but it doesn't have any translated content yet.
|
||||
// https://onthegosystems.myjetbrains.com/youtrack/issue/wpmlst-556
|
||||
WPML_Simple_Language_Selector::enqueue_scripts();
|
||||
|
||||
wp_enqueue_style( 'wpml-package-adminbar-popup', WPML_ST_URL . '/res/css/wpml-package-adminbar-popup.css', array(), ICL_SITEPRESS_VERSION );
|
||||
|
||||
echo $metabox;
|
||||
}
|
||||
|
||||
function add_js() {
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
var WPML_Package_Translation = WPML_Package_Translation || {};
|
||||
|
||||
WPML_Package_Translation.AdminLanguageSwitcher = function () {
|
||||
var self = this;
|
||||
|
||||
self.init = function () {
|
||||
self.link = jQuery('#wp-admin-bar-WPML_PACKAGE_LANG').find('.ab-item');
|
||||
self.link.hover(self.show_lang_box, self.hide_lang_box);
|
||||
self.popup = jQuery('#wpml-package-admin-bar-popup');
|
||||
self.popup.css('left', self.link.offset().left);
|
||||
self.popup.hover(self.show_lang_box, self.hide_on_leave);
|
||||
|
||||
jQuery('#icl_package_language').off('wpml-package-language-changed');
|
||||
jQuery('#icl_package_language').on('wpml-package-language-changed', self.package_language_changed);
|
||||
};
|
||||
|
||||
self.show_lang_box = function() {
|
||||
self.popup.css('top', self.link.offset().top + self.link.height() - window.scrollTop);
|
||||
self.popup.show();
|
||||
};
|
||||
|
||||
self.hide_lang_box = function() {
|
||||
self.popup.hide();
|
||||
};
|
||||
|
||||
self.hide_on_leave = function(e) {
|
||||
// Make sure we are fully leaving the popup because this is sometimes
|
||||
// triggered when we open the language select and then move the mouse.
|
||||
var x = e.clientX;
|
||||
var y = e.clientY;
|
||||
var pos = self.popup.offset();
|
||||
if ( x < pos.left || x > pos.left + self.popup.width() || y < pos.top || y > pos.top + self.popup.height()) {
|
||||
self.popup.fadeOut(800);
|
||||
}
|
||||
};
|
||||
|
||||
self.package_language_changed = function( e, lang ) {
|
||||
self.link.html( self.find_flag(lang) + ' ' + lang);
|
||||
self.popup.hide();
|
||||
};
|
||||
|
||||
self.find_flag = function( lang ) {
|
||||
var flag = '';
|
||||
jQuery('.js-simple-lang-selector option').each( function() {
|
||||
if (jQuery(this).text().trim() == lang.trim()) {
|
||||
flag = '<img width="18" height="12" src="' + jQuery(this).data('flag_url') + '">';
|
||||
}
|
||||
|
||||
});
|
||||
return flag;
|
||||
};
|
||||
self.init();
|
||||
};
|
||||
|
||||
jQuery(document).ready(
|
||||
function () {
|
||||
WPML_Package_Translation.admin_language_switcher = new WPML_Package_Translation.AdminLanguageSwitcher();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
define( 'LINE', 0 );
|
||||
define( 'AREA', 1 );
|
||||
define( 'VISUAL', 2 );
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class WPML_ST_Package_Factory {
|
||||
|
||||
/** @var WPML_WP_Cache_Factory $cache_factory */
|
||||
private $cache_factory;
|
||||
|
||||
public function __construct( WPML_WP_Cache_Factory $cache_factory = null ) {
|
||||
$this->cache_factory = $cache_factory;
|
||||
wp_cache_add_non_persistent_groups( __CLASS__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass|\WPML_Package|array|int $package_data
|
||||
*
|
||||
* @return WPML_Package
|
||||
*/
|
||||
public function create( $package_data ) {
|
||||
$cache_item = $this->get_cache_item( $package_data );
|
||||
|
||||
if ( ! $cache_item->exists() ) {
|
||||
$cache_item->set( new WPML_Package( $package_data ) );
|
||||
}
|
||||
|
||||
return $cache_item->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|WPML_Package $package_data
|
||||
*
|
||||
* @return WPML_WP_Cache_Item
|
||||
*/
|
||||
private function get_cache_item( $package_data ) {
|
||||
if ( ! $this->cache_factory ) {
|
||||
$this->cache_factory = new WPML_WP_Cache_Factory();
|
||||
}
|
||||
|
||||
$package_key = md5( json_encode( $package_data ) );
|
||||
|
||||
return $this->cache_factory->create_cache_item( __CLASS__, $package_key );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
class WPML_Package_Exception extends Exception {
|
||||
public $type;
|
||||
|
||||
public function __construct( $type = '', $message = '', $code = 0 ) {
|
||||
parent::__construct( $message, $code );
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,720 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Helper {
|
||||
const PREFIX_BATCH_STRING = 'batch-string-';
|
||||
|
||||
private $default_language;
|
||||
private $last_registered_string_id;
|
||||
protected $registered_strings;
|
||||
private $package_cleanup;
|
||||
private $package_factory;
|
||||
|
||||
private $cache_group;
|
||||
|
||||
function __construct() {
|
||||
$this->registered_strings = array();
|
||||
$this->cache_group = 'string_package';
|
||||
$this->package_cleanup = new WPML_ST_Package_Cleanup();
|
||||
$this->package_factory = new WPML_ST_Package_Factory();
|
||||
}
|
||||
|
||||
public function set_package_factory( WPML_ST_Package_Factory $factory ) {
|
||||
$this->package_factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
*/
|
||||
protected function delete_package( $package_id ) {
|
||||
// delete the strings and the translations
|
||||
|
||||
$this->delete_package_strings( $package_id );
|
||||
|
||||
$tm = new WPML_Package_TM( $this->package_factory->create( $package_id ) );
|
||||
$tm->delete_translation_jobs();
|
||||
$tm->delete_translations();
|
||||
|
||||
global $wpdb;
|
||||
$delete_query = "DELETE FROM {$wpdb->prefix}icl_string_packages WHERE id=%d";
|
||||
$delete_prepare = $wpdb->prepare( $delete_query, $package_id );
|
||||
$wpdb->query( $delete_prepare );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_strings_ids_from_package_id( $package_id ) {
|
||||
global $wpdb;
|
||||
$string_ids_query = "SELECT id FROM {$wpdb->prefix}icl_strings WHERE string_package_id=%d";
|
||||
$string_ids_prepare = $wpdb->prepare( $string_ids_query, $package_id );
|
||||
$string_ids = $wpdb->get_col( $string_ids_prepare );
|
||||
|
||||
return $string_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
*/
|
||||
protected function delete_package_strings( $package_id ) {
|
||||
$strings = $this->get_strings_ids_from_package_id( $package_id );
|
||||
|
||||
foreach ( $strings as $string_id ) {
|
||||
do_action( 'wpml_st_delete_all_string_data', $string_id );
|
||||
}
|
||||
}
|
||||
|
||||
protected function loaded() {
|
||||
$this->default_language = icl_get_default_language();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string_value
|
||||
* @param string $string_name
|
||||
* @param array|WPML_Package $package
|
||||
* @param string $string_title
|
||||
* @param string $string_type
|
||||
*/
|
||||
final function register_string_action( $string_value, $string_name, $package, $string_title, $string_type ) {
|
||||
$this->register_string_for_translation( $string_value, $string_name, $package, $string_title, $string_type );
|
||||
|
||||
return $this->last_registered_string_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $default
|
||||
* @param \stdClass|\WPML_Package|array|int $package
|
||||
* @param string $string_name
|
||||
* @param string $string_value
|
||||
*
|
||||
* @return bool|int|mixed
|
||||
*/
|
||||
function string_id_from_package_filter( $default, $package, $string_name, $string_value ) {
|
||||
$string_id = $this->get_string_id_from_package( $package, $string_name, $string_value );
|
||||
if ( ! $string_id ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $string_id;
|
||||
}
|
||||
|
||||
function string_title_from_id_filter( $default, $string_id ) {
|
||||
global $wpdb;
|
||||
$string_title_query = 'SELECT title FROM ' . $wpdb->prefix . 'icl_strings WHERE id=%d';
|
||||
$string_title_sql = $wpdb->prepare( $string_title_query, array( $string_id ) );
|
||||
|
||||
$string_title = $wpdb->get_var( $string_title_sql );
|
||||
|
||||
if ( ! $string_title ) {
|
||||
$string_title = $default;
|
||||
}
|
||||
|
||||
return $string_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string_value
|
||||
* @param string $string_name
|
||||
* @param array|WPML_Package $package
|
||||
* @param string $string_title
|
||||
* @param string $string_type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final public function register_string_for_translation( $string_value, $string_name, $package, $string_title, $string_type ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
$package_id = $package->ID;
|
||||
if ( ! $package_id ) {
|
||||
|
||||
// Need to create a new record.
|
||||
if ( $package->has_kind_and_name() ) {
|
||||
$package_id = self::create_new_package( $package );
|
||||
$package = $this->package_factory->create( $package );
|
||||
}
|
||||
}
|
||||
if ( $package_id ) {
|
||||
$this->maybe_update_package( $package );
|
||||
$tm = new WPML_Package_TM( $package );
|
||||
$tm->validate_translations();
|
||||
|
||||
$this->init_package_registered_strings( $package_id );
|
||||
|
||||
$string_name = $package->sanitize_string_name( $string_name );
|
||||
|
||||
$this->set_package_registered_strings( $package_id, $string_type, $string_title, $string_name, $string_value );
|
||||
$this->last_registered_string_id = $this->register_string_with_wpml( $package, $string_name, $string_title, $string_type, $string_value );
|
||||
$this->package_cleanup->record_register_string( $package, $this->last_registered_string_id );
|
||||
}
|
||||
|
||||
return $string_value;
|
||||
}
|
||||
|
||||
final function get_string_context_from_package( $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
|
||||
return $package->get_string_context_from_package();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Package $package
|
||||
* @param string $string_name
|
||||
* @param string $string_title
|
||||
* @param string $string_type
|
||||
* @param string $string_value
|
||||
*
|
||||
* @return bool|int|mixed
|
||||
*/
|
||||
final function register_string_with_wpml( $package, $string_name, $string_title, $string_type, $string_value ) {
|
||||
global $wpdb;
|
||||
|
||||
$string_id = $this->get_string_id_from_package( $package, $string_name, $string_value );
|
||||
|
||||
if ( $string_id ) {
|
||||
$package_storage = new WPML_ST_Package_Storage( $package->ID, $wpdb );
|
||||
$did_update = $package_storage->update( $string_title, $string_type, $string_value, $string_id );
|
||||
|
||||
if ( $did_update ) {
|
||||
$this->flush_cache();
|
||||
$package->flush_cache();
|
||||
}
|
||||
}
|
||||
|
||||
return $string_id;
|
||||
}
|
||||
|
||||
final function translate_string( $string_value, $string_name, $package ) {
|
||||
$result = $string_value;
|
||||
|
||||
if ( is_string( $string_value ) ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
|
||||
if ( $package ) {
|
||||
$sanitized_string_name = $package->sanitize_string_name( $string_name );
|
||||
|
||||
$result = $package->translate_string( $string_value, $sanitized_string_name );
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
final function get_translated_strings( $strings, $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
|
||||
return $package->get_translated_strings( $strings );
|
||||
}
|
||||
|
||||
final function set_translated_strings( $translations, $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
$package->set_translated_strings( $translations );
|
||||
}
|
||||
|
||||
final function get_translatable_types( $types ) {
|
||||
global $wpdb;
|
||||
|
||||
$package_kinds = $wpdb->get_results( "SELECT kind, kind_slug FROM {$wpdb->prefix}icl_string_packages WHERE id>0" );
|
||||
|
||||
// Add any packages found to the $types array
|
||||
foreach ( $package_kinds as $package_data ) {
|
||||
$package_kind_slug = $package_data->kind_slug;
|
||||
$package_kind = $package_data->kind;
|
||||
$kinds_added = array_keys( $types );
|
||||
if ( ! in_array( $package_kind_slug, $kinds_added ) ) {
|
||||
$translatable_type = new stdClass();
|
||||
$translatable_type->name = $package_kind_slug;
|
||||
$translatable_type->label = $package_kind;
|
||||
$translatable_type->prefix = 'package';
|
||||
$translatable_type->labels = new stdClass();
|
||||
$translatable_type->labels->singular_name = $package_kind;
|
||||
$translatable_type->labels->name = $package_kind;
|
||||
$translatable_type->external_type = 1;
|
||||
$types[ $package_kind_slug ] = $translatable_type;
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Package $item
|
||||
* @param int|WP_Post|WPML_Package $package
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool|WPML_Package
|
||||
*/
|
||||
final public function get_translatable_item( $item, $package, $type = 'package' ) {
|
||||
if ( $type === 'package' || explode( '_', $type )[0] === 'package' ) {
|
||||
$tm = new WPML_Package_TM( $item );
|
||||
|
||||
return $tm->get_translatable_item( $package );
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
final function get_post_title( $title, $package_id ) {
|
||||
$package = $this->package_factory->create( $package_id );
|
||||
if ( $package ) {
|
||||
$title = $package->kind . ' - ' . $package->title;
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
final function get_editor_string_name( $name, $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
$package_id = $package->ID;
|
||||
$title = $this->get_editor_string_element( $name, $package_id, 'title' );
|
||||
if ( $title && $title != '' ) {
|
||||
$name = $title;
|
||||
} elseif (
|
||||
\WPML\FP\Str::includes( self::PREFIX_BATCH_STRING, $name )
|
||||
&& ( $string = $this->get_st_string_by_batch_name( $name ) )
|
||||
) {
|
||||
$name = $this->empty_if_md5( $string->get_name() )
|
||||
?: ( $string->get_gettext_context() ?: ( $string->get_context() ?: $name ) );
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function empty_if_md5( $str ) {
|
||||
return preg_replace( '#^((.+)( - ))?([a-z0-9]{32})$#', '$2', $str );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $batch_string_name
|
||||
*
|
||||
* @return WPML_ST_String|null
|
||||
* @throws \WPML\Auryn\InjectionException
|
||||
*/
|
||||
private function get_st_string_by_batch_name( $batch_string_name ) {
|
||||
$string_id = (int) \WPML\FP\Str::replace( self::PREFIX_BATCH_STRING, '', $batch_string_name );
|
||||
if ( $string_id ) {
|
||||
$string_factory = WPML\Container\make( WPML_ST_String_Factory::class );
|
||||
|
||||
return $string_factory->find_by_id( $string_id );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
final function get_editor_string_style( $style, $field_type, $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
$package_id = $package->ID;
|
||||
$element_style = $this->get_editor_string_element( $field_type, $package_id, 'type' );
|
||||
if ( $element_style ) {
|
||||
$style = 0;
|
||||
if ( defined( $element_style ) ) {
|
||||
$style = constant( $element_style );
|
||||
}
|
||||
}
|
||||
|
||||
return $style;
|
||||
}
|
||||
|
||||
final public function get_element_id_from_package_filter( $default, $package_id ) {
|
||||
global $wpdb;
|
||||
$element_id_query = 'SELECT name FROM ' . $wpdb->prefix . 'icl_string_packages WHERE ID=%d';
|
||||
$element_id_prepare = $wpdb->prepare( $element_id_query, $package_id );
|
||||
$element_id = $wpdb->get_var( $element_id_prepare );
|
||||
if ( ! $element_id ) {
|
||||
$element_id = $default;
|
||||
}
|
||||
|
||||
return $element_id;
|
||||
}
|
||||
|
||||
final public function get_package_type( $type, $post_id ) {
|
||||
$package = $this->package_factory->create( $post_id );
|
||||
if ( $package ) {
|
||||
return $this->get_package_context( $package );
|
||||
} else {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
final public function get_package_type_prefix( $type, $post_id ) {
|
||||
if ( $type == 'package' ) {
|
||||
$package = $this->package_factory->create( $post_id );
|
||||
if ( $package ) {
|
||||
$type = $package->get_string_context_from_package();
|
||||
}
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language_for_element
|
||||
* @param \WPML_Package $current_document
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
final public function get_language_for_element( $language_for_element, $current_document ) {
|
||||
if ( $this->is_a_package( $current_document ) ) {
|
||||
global $sitepress;
|
||||
$language_for_element = $sitepress->get_language_for_element( $current_document->ID, $current_document->get_translation_element_type() );
|
||||
}
|
||||
|
||||
return $language_for_element;
|
||||
}
|
||||
|
||||
final protected function get_package_context( $package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
|
||||
return $package->kind_slug . '-' . $package->name;
|
||||
}
|
||||
|
||||
final function delete_packages_ajax() {
|
||||
if ( ! $this->verify_ajax_call( 'wpml_package_nonce' ) ) {
|
||||
die( 'verification failed' );
|
||||
}
|
||||
$packages_ids = $_POST['packages'];
|
||||
|
||||
$this->delete_packages( $packages_ids );
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
final function delete_package_action( $name, $kind ) {
|
||||
$package_data['name'] = $name;
|
||||
$package_data['kind'] = $kind;
|
||||
|
||||
$package = $this->package_factory->create( $package_data );
|
||||
if ( $package && $package->ID && $this->is_a_package( $package ) ) {
|
||||
$this->delete_package( $package->ID );
|
||||
$this->flush_cache();
|
||||
}
|
||||
}
|
||||
|
||||
/** @param int $post_id */
|
||||
final public function remove_post_packages( $post_id ) {
|
||||
$packages = $this->get_post_string_packages( array(), $post_id );
|
||||
|
||||
foreach ( $packages as $package ) {
|
||||
$this->delete_package( $package->ID );
|
||||
}
|
||||
}
|
||||
|
||||
final protected function delete_packages( $packages_ids ) {
|
||||
$flush_cache = false;
|
||||
|
||||
foreach ( $packages_ids as $package_id ) {
|
||||
$this->delete_package( $package_id );
|
||||
|
||||
$flush_cache = true;
|
||||
}
|
||||
if ( $flush_cache ) {
|
||||
$this->flush_cache();
|
||||
}
|
||||
}
|
||||
|
||||
final function change_package_lang_ajax() {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
if ( ! $this->verify_ajax_call( 'wpml_package_nonce' ) ) {
|
||||
die( 'verification failed' );
|
||||
}
|
||||
|
||||
$package_id = $_POST['package_id'];
|
||||
|
||||
$package = $this->package_factory->create( $package_id );
|
||||
$package->set_strings_language( $_POST['package_lang'] );
|
||||
|
||||
$package_job = new WPML_Package_TM( $package );
|
||||
$package_job->set_language_details( $_POST['package_lang'] );
|
||||
|
||||
$args = filter_var_array( json_decode( base64_decode( $_POST['args'] ) ), FILTER_SANITIZE_STRING );
|
||||
|
||||
$package_metabox = new WPML_Package_Translation_Metabox( $package, $wpdb, $sitepress, $args );
|
||||
$response = array(
|
||||
'metabox' => $package_metabox->get_metabox_status(),
|
||||
'lang' => $package_metabox->get_package_language_name(),
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string_name
|
||||
* @param int $package_id
|
||||
* @param string $column
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_editor_string_element( $string_name, $package_id, $column ) {
|
||||
global $wpdb;
|
||||
|
||||
$element_query = 'SELECT ' . $column . "
|
||||
FROM {$wpdb->prefix}icl_strings
|
||||
WHERE string_package_id=%d AND name=%s";
|
||||
$element_prepared = $wpdb->prepare( $element_query, array( $package_id, $string_name ) );
|
||||
$element = $wpdb->get_var( $element_prepared );
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
private function flush_cache() {
|
||||
// delete the cache key we use
|
||||
wp_cache_delete( 'get_all_packages', $this->cache_group );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Package $package
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
final public static function create_new_package( WPML_Package $package ) {
|
||||
$package_id = $package->create_new_package_record();
|
||||
|
||||
$tm = new WPML_Package_TM( $package );
|
||||
|
||||
$tm->update_package_translations( true );
|
||||
|
||||
return (int) $package_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
*/
|
||||
private function init_package_registered_strings( $package_id ) {
|
||||
if ( ! isset( $this->registered_strings[ $package_id ] ) ) {
|
||||
$this->registered_strings[ $package_id ] = array( 'strings' => array() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $package_id
|
||||
* @param string $string_type
|
||||
* @param string $string_title
|
||||
* @param string $string_name
|
||||
* @param string $string_value
|
||||
*/
|
||||
private function set_package_registered_strings( $package_id, $string_type, $string_title, $string_name, $string_value ) {
|
||||
$this->registered_strings[ $package_id ]['strings'][ $string_name ] = array(
|
||||
'title' => $string_title,
|
||||
'kind' => $string_type,
|
||||
'value' => $string_value,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass|\WPML_Package|array|int $package
|
||||
* @param string $string_name
|
||||
* @param string $string_value
|
||||
*
|
||||
* @return bool|int|mixed
|
||||
*/
|
||||
private function get_string_id_from_package( $package, $string_name, $string_value ) {
|
||||
if ( ! $package instanceof WPML_Package ) {
|
||||
$package = $this->package_factory->create( $package );
|
||||
}
|
||||
|
||||
return $package->get_string_id_from_package( $string_name, $string_value );
|
||||
}
|
||||
|
||||
final function get_external_id_from_package( $package ) {
|
||||
return 'external_' . $package['kind_slug'] . '_' . $package['ID'];
|
||||
}
|
||||
|
||||
final function get_string_context( $package ) {
|
||||
return sanitize_title_with_dashes( $package['kind_slug'] . '-' . $package['name'] );
|
||||
}
|
||||
|
||||
final function get_package_id( $package, $from_cache = true ) {
|
||||
global $wpdb;
|
||||
static $cache = array();
|
||||
|
||||
if ( $this->is_a_package( $package ) ) {
|
||||
$package = object_to_array( $package );
|
||||
}
|
||||
|
||||
$key = $this->get_string_context( $package );
|
||||
if ( ! $from_cache || ! array_key_exists( $key, $cache ) ) {
|
||||
$package_id_query = "SELECT ID FROM {$wpdb->prefix}icl_string_packages WHERE kind_slug = %s AND name = %s";
|
||||
$package_id_prepare = $wpdb->prepare( $package_id_query, array( $package['kind_slug'], $package['name'] ) );
|
||||
$package_id = $wpdb->get_var( $package_id_prepare );
|
||||
if ( ! $package_id ) {
|
||||
return false;
|
||||
}
|
||||
$cache[ $key ] = $package_id;
|
||||
}
|
||||
|
||||
return $cache[ $key ];
|
||||
}
|
||||
|
||||
final public function get_all_packages() {
|
||||
global $wpdb;
|
||||
$cache_key = 'get_all_packages';
|
||||
$cache_found = false;
|
||||
|
||||
$all_packages = wp_cache_get( $cache_key, $this->cache_group, false, $cache_found );
|
||||
|
||||
if ( ! $cache_found ) {
|
||||
$all_packages = array();
|
||||
$all_packages_data_query = "SELECT * FROM {$wpdb->prefix}icl_string_packages";
|
||||
$all_packages_data = $wpdb->get_results( $all_packages_data_query );
|
||||
foreach ( $all_packages_data as $package_data ) {
|
||||
$package = $this->package_factory->create( $package_data );
|
||||
$all_packages[ $package->ID ] = $package;
|
||||
}
|
||||
if ( $all_packages ) {
|
||||
wp_cache_set( $cache_key, $all_packages, $this->cache_group );
|
||||
}
|
||||
}
|
||||
|
||||
return $all_packages;
|
||||
}
|
||||
|
||||
final protected function is_a_package( $element ) {
|
||||
return is_a( $element, 'WPML_Package' );
|
||||
}
|
||||
|
||||
protected function verify_ajax_call( $ajax_action ) {
|
||||
return isset( $_POST['wpnonce'] ) && wp_verify_nonce( $_POST['wpnonce'], $ajax_action );
|
||||
}
|
||||
|
||||
protected function sanitize_string_name( $string_name ) {
|
||||
$string_name = preg_replace( '/[ \[\]]+/', '-', $string_name );
|
||||
|
||||
return $string_name;
|
||||
}
|
||||
|
||||
public function refresh_packages() {
|
||||
|
||||
// TODO: deprecated.
|
||||
// This is required to support Layouts 1.0
|
||||
do_action( 'WPML_register_string_packages', 'layout', array() );
|
||||
// TODO: END deprecated.
|
||||
|
||||
do_action( 'wpml_register_string_packages' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Package $package
|
||||
*/
|
||||
private function maybe_update_package( $package ) {
|
||||
if ( $package->new_title ) {
|
||||
$package->title = $package->new_title;
|
||||
$package->update_package_record();
|
||||
}
|
||||
}
|
||||
|
||||
public function change_language_of_strings( $strings, $lang ) {
|
||||
global $wpdb;
|
||||
|
||||
$all_ok = true;
|
||||
|
||||
$strings_in = implode( ',', $strings );
|
||||
|
||||
$string_packages_query = "SELECT DISTINCT string_package_id FROM {$wpdb->prefix}icl_strings WHERE id IN ($strings_in)";
|
||||
$package_ids = $wpdb->get_col( $string_packages_query );
|
||||
|
||||
foreach ( $package_ids as $package_id ) {
|
||||
if ( $package_id ) {
|
||||
$package = $this->package_factory->create( $package_id );
|
||||
if ( ! $package->are_all_strings_included( $strings ) ) {
|
||||
$all_ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $all_ok ) {
|
||||
$this->set_packages_language( $package_ids, $lang );
|
||||
}
|
||||
|
||||
$response = array();
|
||||
$response['success'] = $all_ok;
|
||||
if ( ! $all_ok ) {
|
||||
$response['error'] = __( 'Some of the strings selected belong to packages. You can only change the language of these strings if all strings in the packages are selected.', 'wpml-string-translation' );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function change_language_of_strings_in_domain( $domain, $langs, $to_lang ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! empty( $langs ) ) {
|
||||
foreach ( $langs as &$lang ) {
|
||||
$lang = "'" . $lang . "'";
|
||||
}
|
||||
$langs = implode( ',', $langs );
|
||||
|
||||
$string_packages_query = "SELECT DISTINCT string_package_id FROM {$wpdb->prefix}icl_strings WHERE context='%s' AND language IN ($langs)";
|
||||
$string_packages_query = $wpdb->prepare( $string_packages_query, $domain );
|
||||
$package_ids = $wpdb->get_col( $string_packages_query );
|
||||
|
||||
$this->set_packages_language( $package_ids, $to_lang );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function set_packages_language( $package_ids, $lang ) {
|
||||
foreach ( $package_ids as $package_id ) {
|
||||
if ( $package_id ) {
|
||||
$package = $this->package_factory->create( $package_id );
|
||||
$package->set_strings_language( $lang );
|
||||
|
||||
$package_job = new WPML_Package_TM( $package );
|
||||
$package_job->set_language_details( $lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|array $packages
|
||||
* @param int $post_id
|
||||
*
|
||||
* @return WPML_Package[]
|
||||
*/
|
||||
public function get_post_string_packages( $packages, $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$query = $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}icl_string_packages WHERE post_id = %d", $post_id );
|
||||
$package_ids = $wpdb->get_col( $query );
|
||||
|
||||
$packages = $packages ? $packages : array();
|
||||
|
||||
foreach ( $package_ids as $package_id ) {
|
||||
$packages[ $package_id ] = $this->package_factory->create( $package_id );
|
||||
}
|
||||
|
||||
return $packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $string_id
|
||||
* @param string $language
|
||||
* @param string|null $value
|
||||
* @param int|bool $status
|
||||
* @param int|null $translator_id
|
||||
* @param int|null $translation_service
|
||||
* @param int|null $batch_id
|
||||
*/
|
||||
public function add_string_translation_action( $string_id, $language, $value = null, $status = false, $translator_id = null, $translation_service = null, $batch_id = null ) {
|
||||
icl_add_string_translation( $string_id, $language, $value, $status, $translator_id, $translation_service, $batch_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $package
|
||||
* @param int $package_id
|
||||
*
|
||||
* @return WPML_Package
|
||||
*/
|
||||
public function get_string_package( $package, $package_id ) {
|
||||
return $this->package_factory->create( $package_id );
|
||||
}
|
||||
|
||||
public function start_string_package_registration_action( $package ) {
|
||||
$this->package_cleanup->record_existing_strings( $this->package_factory->create( $package ) );
|
||||
}
|
||||
|
||||
public function delete_unused_package_strings_action( $package ) {
|
||||
$this->package_cleanup->delete_unused_strings( $this->package_factory->create( $package ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
class WPML_Package_Translation_HTML_Packages {
|
||||
var $load_priority = 101;
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'WPML_PT_HTML', array( $this, 'loaded' ), $this->load_priority );
|
||||
}
|
||||
|
||||
public function loaded() {
|
||||
$this->set_admin_hooks();
|
||||
}
|
||||
|
||||
private function set_admin_hooks() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'wpml_pt_package_table_columns', array( $this, 'render_package_table_columns' ), 10, 1 );
|
||||
add_action( 'wpml_pt_package_table_options', array( $this, 'package_translation_menu_options' ), 10, 1 );
|
||||
add_action( 'wpml_pt_package_table_body', array( $this, 'package_translation_menu_body' ), 10, 1 );
|
||||
add_action( 'wpml_pt_package_status', array( $this, 'render_string_package_status' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
public static function package_translation_menu() {
|
||||
$packages = apply_filters( 'wpml_pt_all_packages', array() );
|
||||
$package_kinds = array();
|
||||
|
||||
if ( $packages ) {
|
||||
foreach ( $packages as $package ) {
|
||||
$kind_slugs = array_keys( $package_kinds );
|
||||
if ( ! in_array( $package->kind_slug, $kind_slugs ) ) {
|
||||
$package_kinds[ $package->kind_slug ] = $package->kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table_title = __( 'Package Management', 'wpml-string-translation' );
|
||||
$package_kind_label = __( 'Display packages for this kind:', 'wpml-string-translation' );
|
||||
$package_kind_options[- 1] = __( 'Display packages for this kind:', 'wpml-string-translation' );
|
||||
foreach ( $package_kinds as $kind_slug => $kind ) {
|
||||
$package_kind_options[ $kind_slug ] = $kind;
|
||||
}
|
||||
?>
|
||||
<h2><?php echo $table_title; ?></h2>
|
||||
|
||||
<p>
|
||||
<label for="package_kind_filter"><?php echo $package_kind_label; ?></label>
|
||||
<select id="package_kind_filter">
|
||||
<?php do_action( 'wpml_pt_package_table_options', $package_kind_options ); ?>
|
||||
</select>
|
||||
</p>
|
||||
|
||||
<table id="icl_package_translations" class="widefat" cellspacing="0">
|
||||
<thead>
|
||||
<?php do_action( 'wpml_pt_package_table_columns', 'thead' ); ?>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<?php do_action( 'wpml_pt_package_table_columns', 'tfoot' ); ?>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<?php do_action( 'wpml_pt_package_table_body', $packages ); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
|
||||
<input id="delete_packages" type="button" class="button-primary" value="<?php echo __( 'Delete Selected Packages', 'wpml-string-translation' ); ?>" disabled="disabled"/>
|
||||
|
||||
<span class="spinner"></span>
|
||||
<span style="display:none" class="js-delete-confirm-message"><?php echo __( "Are you sure you want to delete these packages?\nTheir strings and translations will be deleted too.", 'wpml-string-translation' ); ?></span>
|
||||
|
||||
<?php
|
||||
wp_nonce_field( 'wpml_package_nonce', 'wpml_package_nonce' );
|
||||
}
|
||||
|
||||
public function package_translation_menu_options( $package_kind_options ) {
|
||||
foreach ( $package_kind_options as $option_value => $option_label ) {
|
||||
?>
|
||||
<option value="<?php echo esc_attr( $option_value ); ?>"><?php echo $option_label; ?></option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<\WPML_Package> $packages
|
||||
*/
|
||||
public function package_translation_menu_body( $packages ) {
|
||||
if ( ! $packages ) {
|
||||
$this->package_translation_menu_no_packages();
|
||||
} else {
|
||||
$this->package_translation_menu_items( $packages );
|
||||
}
|
||||
}
|
||||
|
||||
public function render_package_table_columns( $position ) {
|
||||
?>
|
||||
<tr>
|
||||
<th scope="col" class="manage-column column-cb check-column">
|
||||
<label for="select_all_package_<?php echo $position; ?>" style="display: none;">
|
||||
<?php _e( 'Select All', 'wpml-string-translation' ); ?>
|
||||
</label>
|
||||
<input id="select_all_package_<?php echo $position; ?>" class="js_package_all_cb" type="checkbox"/>
|
||||
</th>
|
||||
<th scope="col"><?php echo __( 'Kind', 'wpml-string-translation' ); ?></th>
|
||||
<th scope="col"><?php echo __( 'Name', 'wpml-string-translation' ); ?></th>
|
||||
<th scope="col"><?php echo __( 'Info', 'wpml-string-translation' ); ?></th>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function render_string_package_status( $string_count, $translation_in_progress, $default_package_language ) {
|
||||
$package_statuses[] = sprintf( __( 'Contains %s strings', 'wpml-string-translation' ), $string_count );
|
||||
if ( $translation_in_progress ) {
|
||||
$package_statuses[] = '(' . __( 'Translation is in progress', 'wpml-string-translation' ) . ')';
|
||||
}
|
||||
$package_statuses[] = __( 'Default package language', 'wpml-string-translation' ) . ': ' . $default_package_language;
|
||||
|
||||
echo implode( ' - ', $package_statuses );
|
||||
}
|
||||
|
||||
private function package_translation_menu_no_packages() {
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="6" align="center">
|
||||
<strong><?php echo __( 'No packages found', 'wpml-string-translation' ); ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<\WPML_Package> $packages
|
||||
*/
|
||||
private function package_translation_menu_items( $packages ) {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
foreach ( $packages as $package ) {
|
||||
|
||||
$package_language_code = $package->get_package_language();
|
||||
$package_language = $sitepress->get_display_language_name( $package_language_code );
|
||||
|
||||
$tm = new WPML_Package_TM( $package );
|
||||
|
||||
$translation_in_progress = $tm->is_translation_in_progress();
|
||||
$package_id = $package->ID;
|
||||
$string_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}icl_strings WHERE string_package_id=%d", $package_id ) );
|
||||
|
||||
$disabled = disabled( $translation_in_progress, true, false );
|
||||
?>
|
||||
<tr id="row_<?php echo $package_id; ?>" class="js_package js_package_<?php echo esc_attr( $package->kind_slug ); ?>">
|
||||
<td>
|
||||
<input id="package_<?php echo $package_id; ?>" class="js_package_row_cb" type="checkbox" value="<?php echo $package_id; ?>" <?php echo $disabled; ?>/>
|
||||
</td>
|
||||
<td class="js-package-kind">
|
||||
<?php echo $package->kind; ?>
|
||||
</td>
|
||||
<td>
|
||||
<label for="package_<?php echo $package_id; ?>"><?php echo esc_html( $package->title ); ?></label>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php
|
||||
do_action( 'wpml_pt_package_status', $string_count, $translation_in_progress, $package_language );
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Translation_Metabox {
|
||||
private $args;
|
||||
private $active_languages;
|
||||
private $container_attributes_html;
|
||||
private $dashboard_link;
|
||||
private $strings_link;
|
||||
private $default_language;
|
||||
private $main_container_attributes;
|
||||
private $show_description;
|
||||
private $show_link;
|
||||
private $show_status;
|
||||
private $show_title;
|
||||
private $status_container_attributes;
|
||||
private $status_container_attributes_html;
|
||||
private $status_container_tag;
|
||||
private $status_element_tag;
|
||||
private $title_tag;
|
||||
|
||||
public $metabox_data;
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
private $translation_statuses;
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
/**
|
||||
* @var \WPML_Package
|
||||
*/
|
||||
private $package;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $package_language;
|
||||
|
||||
/**
|
||||
* WPML_Package_Translation_Metabox constructor.
|
||||
*
|
||||
* @param stdClass|WPML_Package|array|int $package
|
||||
* @param \wpdb $wpdb
|
||||
* @param \SitePress $sitepress
|
||||
* @param array<string,mixed> $args
|
||||
*/
|
||||
public function __construct( $package, $wpdb, $sitepress, $args = array() ) {
|
||||
|
||||
$this->wpdb = $wpdb;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->package = new WPML_Package( $package );
|
||||
$this->args = $args;
|
||||
|
||||
if ( $this->got_package() ) {
|
||||
$this->dashboard_link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=dashboard&type=' . $this->package->kind_slug . '&lang=' . $this->package->get_package_language() );
|
||||
$this->strings_link = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=' . $this->package->get_string_context_from_package() );
|
||||
}
|
||||
|
||||
$this->parse_arguments( $args );
|
||||
$this->init_metabox_data();
|
||||
}
|
||||
|
||||
private function init_metabox_data() {
|
||||
$this->metabox_data = array();
|
||||
$this->active_languages = $this->sitepress->get_active_languages();
|
||||
$this->default_language = $this->sitepress->get_default_language();
|
||||
$this->package_language = $this->package->get_package_language();
|
||||
$this->package_language = $this->package_language ? $this->package_language : $this->default_language;
|
||||
|
||||
$this->metabox_data['title'] = __( 'WPML Translation', 'wpml-string-translation' );
|
||||
if ( $this->is_package_language_active() ) {
|
||||
$this->metabox_data['translate_title'] = __( 'Send to translation', 'wpml-string-translation' );
|
||||
} else {
|
||||
$this->metabox_data['translate_title'] = __( 'Translate strings', 'wpml-string-translation' );
|
||||
}
|
||||
|
||||
if ( $this->got_package() ) {
|
||||
$this->metabox_data['statuses_title'] = __( 'Translation status:', 'wpml-string-translation' );
|
||||
$this->init_translation_statuses();
|
||||
$this->metabox_data['package_language_title'] = sprintf( __( 'Language of this %1$s is %2$s', 'wpml-string-translation' ), $this->package->kind, $this->get_lang_selector() );
|
||||
} else {
|
||||
$this->metabox_data['package_language_title'] = '';
|
||||
$this->metabox_data['statuses_title'] = __( 'There is nothing to translate.', 'wpml-string-translation' );
|
||||
}
|
||||
}
|
||||
|
||||
private function get_lang_selector() {
|
||||
|
||||
$disable = $this->check_if_language_change_is_ok() ? '' : 'disabled="disabled" ';
|
||||
|
||||
ob_start();
|
||||
|
||||
$languages = $this->active_languages;
|
||||
if ( ! $this->is_package_language_active() ) {
|
||||
$languages = array_merge( array( $this->sitepress->get_language_details( $this->package_language ) ), $languages );
|
||||
} else {
|
||||
$languages = $this->active_languages;
|
||||
}
|
||||
|
||||
$selector = new WPML_Simple_Language_Selector( $this->sitepress );
|
||||
$selector->render(
|
||||
array(
|
||||
'id' => 'icl_package_language',
|
||||
'name' => 'icl_package_language',
|
||||
'show_please_select' => false,
|
||||
'languages' => $languages,
|
||||
'selected' => $this->package_language,
|
||||
'disabled' => ! $this->check_if_language_change_is_ok(),
|
||||
'echo' => true,
|
||||
)
|
||||
);
|
||||
?>
|
||||
<span class="spinner"></span>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public function get_package_language_name() {
|
||||
if ( $this->is_package_language_active() ) {
|
||||
return $this->active_languages[ $this->package_language ]['display_name'];
|
||||
} else {
|
||||
$all_languages = $this->sitepress->get_languages();
|
||||
return $all_languages[ $this->package_language ]['display_name'];
|
||||
}
|
||||
}
|
||||
|
||||
private function get_lang_switcher_js() {
|
||||
ob_start();
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
|
||||
var WPML_Package_Translation = WPML_Package_Translation || {};
|
||||
|
||||
WPML_Package_Translation.MetaBox = function () {
|
||||
var self = this;
|
||||
|
||||
self.init = function () {
|
||||
jQuery('#icl_package_language').off('change');
|
||||
jQuery('#icl_package_language').on('change', self.switch_lang);
|
||||
};
|
||||
|
||||
self.switch_lang = function() {
|
||||
self.disable_controls(true);
|
||||
var data = {
|
||||
action: 'wpml_change_package_lang',
|
||||
wpnonce: jQuery('#wpml_package_nonce').val(),
|
||||
package_id: jQuery('#wpml_package_id').val(),
|
||||
args: jQuery('#wpml_package_args').val(),
|
||||
package_lang: jQuery(this).val()
|
||||
};
|
||||
|
||||
jQuery.ajax(
|
||||
{
|
||||
url: ajaxurl,
|
||||
type: 'post',
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
success: function (response) {
|
||||
var position = jQuery('#wpml_package_status').prev();
|
||||
jQuery('#wpml_package_status').remove();
|
||||
jQuery(response.metabox).insertAfter(position);
|
||||
|
||||
jQuery('#icl_package_language').trigger('wpml-package-language-changed', [response.lang]);
|
||||
|
||||
self.disable_controls(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
self.disable_controls = function(state) {
|
||||
var lang_switcher = jQuery('#icl_package_language');
|
||||
if (state) {
|
||||
lang_switcher.next('.spinner').show();
|
||||
lang_switcher.prop('disabled', true);
|
||||
lang_switcher.closest('div').find('a').prop('disabled', true);
|
||||
} else {
|
||||
lang_switcher.next('.spinner').hide();
|
||||
lang_switcher.prop('disabled', false);
|
||||
lang_switcher.closest('div').find('a').prop('disabled', false);
|
||||
}
|
||||
};
|
||||
|
||||
self.init();
|
||||
};
|
||||
|
||||
jQuery(document).ready(
|
||||
function () {
|
||||
WPML_Package_Translation.meta_box = new WPML_Package_Translation.MetaBox();
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function get_metabox() {
|
||||
$result = '';
|
||||
$result .= '<div ' . $this->container_attributes_html . '>';
|
||||
if ( $this->show_title ) {
|
||||
if ( $this->title_tag ) {
|
||||
$result .= $this->get_tag( $this->title_tag );
|
||||
}
|
||||
$result .= $this->metabox_data['title'];
|
||||
if ( $this->title_tag ) {
|
||||
$result .= $this->get_tag( $this->title_tag, 'closed' );
|
||||
}
|
||||
}
|
||||
if ( $this->show_description ) {
|
||||
$result .= '<div>' . $this->metabox_data['package_language_title'] . '</div>';
|
||||
}
|
||||
if ( $this->show_status ) {
|
||||
$result .= '<p>' . $this->metabox_data['statuses_title'] . '</p>';
|
||||
}
|
||||
|
||||
$result .= $this->get_metabox_status();
|
||||
|
||||
$result .= '</div>';
|
||||
$result .= wp_nonce_field( 'wpml_package_nonce', 'wpml_package_nonce', true, false );
|
||||
$result .= '<input type="hidden" id="wpml_package_id" value="' . $this->package->ID . '" />';
|
||||
$result .= '<input type="hidden" id="wpml_package_args" value="' . base64_encode( wp_json_encode( $this->args ) ) . '" />';
|
||||
|
||||
if ( ! defined( 'DOING_AJAX' ) ) {
|
||||
$result .= $this->get_lang_switcher_js();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_metabox_status() {
|
||||
$result = '';
|
||||
if ( $this->got_package() ) {
|
||||
$result .= '<div id="wpml_package_status">';
|
||||
if ( $this->show_status && $this->metabox_data['statuses'] ) {
|
||||
if ( $this->status_container_tag ) {
|
||||
$result .= $this->get_tag( $this->status_container_tag . ' ' . $this->status_container_attributes_html );
|
||||
}
|
||||
foreach ( $this->metabox_data['statuses'] as $code => $status ) {
|
||||
$result .= $this->get_tag( $this->status_element_tag );
|
||||
$result .= '<img width="18" height="12" src="' . $this->sitepress->get_flag_url( $code ) . '"> ' . $status['name'] . ' : ' . $status['status'];
|
||||
$result .= $this->get_tag( $this->status_element_tag, 'closed' );
|
||||
}
|
||||
if ( $this->status_container_tag ) {
|
||||
$result .= $this->get_tag( $this->status_container_tag, 'closed' );
|
||||
}
|
||||
}
|
||||
if ( $this->show_link ) {
|
||||
if ( $this->is_package_language_active() ) {
|
||||
$result .= '<p><a style="float:right" class="button-secondary" href="' . $this->dashboard_link . '" target="_blank">' . $this->metabox_data['translate_title'] . '</a></p>';
|
||||
} else {
|
||||
$result .= '<p><a style="float:right" class="button-secondary" href="' . $this->strings_link . '" target="_blank">' . $this->metabox_data['translate_title'] . '</a></p>';
|
||||
}
|
||||
}
|
||||
$result .= '<br /><br /></div>';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function check_if_language_change_is_ok() {
|
||||
|
||||
$ok = true;
|
||||
|
||||
foreach ( $this->translation_statuses as $status ) {
|
||||
if ( isset( $status->status_code ) && $status->status_code != 0 ) {
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $ok ) {
|
||||
$translations = $this->package->get_translated_strings( array() );
|
||||
foreach ( $translations as $string ) {
|
||||
foreach ( $string as $lang => $data ) {
|
||||
if ( $data['status'] == ICL_STRING_TRANSLATION_COMPLETE ) {
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $ok ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function attributes_to_string( $attributes ) {
|
||||
$result = '';
|
||||
foreach ( $attributes as $key => $value ) {
|
||||
if ( $result ) {
|
||||
$result .= ' ';
|
||||
}
|
||||
$result .= esc_html( $key ) . '="' . esc_attr( $value ) . '"';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function get_post_translations() {
|
||||
|
||||
$element_type = $this->package->get_package_element_type();
|
||||
$trid = $this->sitepress->get_element_trid( $this->package->ID, $element_type );
|
||||
|
||||
return $this->sitepress->get_element_translations( $trid, $element_type );
|
||||
}
|
||||
|
||||
private function get_tag( $tag, $closed = false ) {
|
||||
$result = '<';
|
||||
if ( $closed ) {
|
||||
$result .= '/';
|
||||
}
|
||||
$result .= $tag . '>';
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string|array<string,mixed> > $args
|
||||
*/
|
||||
private function parse_arguments( $args ) {
|
||||
$default_args = array(
|
||||
'show_title' => true,
|
||||
'show_description' => true,
|
||||
'show_status' => true,
|
||||
'show_link' => true,
|
||||
'title_tag' => 'h2',
|
||||
'status_container_tag' => 'ul',
|
||||
'status_element_tag' => 'li',
|
||||
'main_container_attributes' => array(),
|
||||
'status_container_attributes' => array( 'style' => 'padding-left: 10px' ),
|
||||
);
|
||||
|
||||
$args = array_merge( $default_args, $args );
|
||||
|
||||
$this->show_title = $args['show_title'];
|
||||
$this->show_description = $args['show_description'];
|
||||
$this->show_status = $args['show_status'];
|
||||
$this->show_link = $args['show_link'];
|
||||
$this->title_tag = $args['title_tag'];
|
||||
$this->status_container_tag = $args['status_container_tag'];
|
||||
$this->status_element_tag = $args['status_element_tag'];
|
||||
$this->main_container_attributes = $args['main_container_attributes'];
|
||||
$this->status_container_attributes = $args['status_container_attributes'];
|
||||
|
||||
$this->container_attributes_html = $this->attributes_to_string( $this->main_container_attributes );
|
||||
$this->status_container_attributes_html = $this->attributes_to_string( $this->status_container_attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function got_package() {
|
||||
return $this->package && $this->package->ID;
|
||||
}
|
||||
|
||||
private function get_translation_statuses() {
|
||||
$post_translations = $this->get_post_translations();
|
||||
$status = array();
|
||||
foreach ( $post_translations as $language => $translation ) {
|
||||
$res_query = "SELECT status as status_code, needs_update FROM {$this->wpdb->prefix}icl_translation_status WHERE translation_id=%d";
|
||||
$res_args = array( $translation->translation_id );
|
||||
$res_prepare = $this->wpdb->prepare( $res_query, $res_args );
|
||||
/** @var \stdClass $res */
|
||||
$res = $this->wpdb->get_row( $res_prepare );
|
||||
if ( $res ) {
|
||||
$res->status = $res->status_code;
|
||||
switch ( $res->status ) {
|
||||
case ICL_TM_WAITING_FOR_TRANSLATOR:
|
||||
$res->status = __( 'Waiting for translator', 'wpml-string-translation' );
|
||||
break;
|
||||
case ICL_TM_IN_PROGRESS:
|
||||
$res->status = __( 'In progress', 'wpml-string-translation' );
|
||||
break;
|
||||
case ICL_TM_NEEDS_UPDATE:
|
||||
$res->status = '';
|
||||
break;
|
||||
case ICL_TM_COMPLETE:
|
||||
$res->status = __( 'Complete', 'wpml-string-translation' );
|
||||
break;
|
||||
default:
|
||||
$res->status = __( 'Not translated', 'wpml-string-translation' );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $res->needs_update ) {
|
||||
if ( $res->status ) {
|
||||
$res->status .= ' - ';
|
||||
}
|
||||
$res->status .= __( 'Needs update', 'wpml-string-translation' );
|
||||
}
|
||||
$status[ $language ] = $res;
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
private function init_translation_statuses() {
|
||||
$this->metabox_data['statuses'] = array();
|
||||
$this->translation_statuses = $this->get_translation_statuses();
|
||||
foreach ( $this->active_languages as $language_data ) {
|
||||
if ( $language_data['code'] != $this->package_language ) {
|
||||
$display_name = $language_data['display_name'];
|
||||
|
||||
$this->metabox_data['statuses'][ $language_data['code'] ] = array(
|
||||
'name' => $display_name,
|
||||
'status' => $this->get_status_value( $language_data ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get_status_value( $language_data ) {
|
||||
if ( isset( $this->translation_statuses[ $language_data['code'] ] ) ) {
|
||||
$status_value = $this->translation_statuses[ $language_data['code'] ]->status;
|
||||
} else {
|
||||
$tm = new WPML_Package_TM( $this->package );
|
||||
if ( $tm->is_in_basket( $language_data['code'] ) ) {
|
||||
$status_value = __( 'In translation basket', 'wpml-string-translation' );
|
||||
} else {
|
||||
$status_value = __( 'Not translated', 'wpml-string-translation' );
|
||||
}
|
||||
}
|
||||
|
||||
return $status_value;
|
||||
}
|
||||
|
||||
private function is_package_language_active() {
|
||||
return in_array( $this->package_language, array_keys( $this->active_languages ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Translation_Schema {
|
||||
|
||||
const OPTION_NAME = 'wpml-package-translation-db-updates-run';
|
||||
const REQUIRED_VERSION = '0.0.2';
|
||||
|
||||
private static $table_name;
|
||||
|
||||
static function run_update() {
|
||||
$updates_run = get_option( self::OPTION_NAME, array() );
|
||||
|
||||
if ( defined( 'WPML_PT_VERSION_DEV' ) ) {
|
||||
delete_option( 'wpml-package-translation-string-packages-table-updated' );
|
||||
if ( ( $key = array_search( WPML_PT_VERSION_DEV, $updates_run ) ) !== false ) {
|
||||
unset( $updates_run[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! in_array( self::REQUIRED_VERSION, $updates_run ) ) {
|
||||
// We need to make sure we build everything for 0.0.2 because users may
|
||||
// only be updating the string translation plugin and may not do an
|
||||
// activation.
|
||||
self::build_icl_string_packages_table();
|
||||
self::build_icl_string_packages_columns_if_required();
|
||||
self::fix_icl_string_packages_ID_column();
|
||||
self::build_icl_strings_columns_if_required();
|
||||
|
||||
$updates_run[] = self::REQUIRED_VERSION;
|
||||
|
||||
update_option( self::OPTION_NAME, $updates_run );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function current_table_has_column( $column ) {
|
||||
global $wpdb;
|
||||
|
||||
$cols = $wpdb->get_results( 'SHOW COLUMNS FROM `' . self::$table_name . '`' );
|
||||
$found = false;
|
||||
foreach ( $cols as $col ) {
|
||||
if ( $col->Field == $column ) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
private static function add_string_package_id_to_icl_strings() {
|
||||
global $wpdb;
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . '`
|
||||
ADD `string_package_id` BIGINT unsigned NULL AFTER value,
|
||||
ADD INDEX (`string_package_id`)';
|
||||
|
||||
return $wpdb->query( $sql );
|
||||
}
|
||||
|
||||
private static function add_type_to_icl_strings() {
|
||||
global $wpdb;
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . "` ADD `type` VARCHAR(40) NOT NULL DEFAULT 'LINE' AFTER string_package_id";
|
||||
|
||||
return $wpdb->query( $sql );
|
||||
}
|
||||
|
||||
private static function add_title_to_icl_strings() {
|
||||
global $wpdb;
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . '` ADD `title` VARCHAR(160) NULL AFTER type';
|
||||
|
||||
return $wpdb->query( $sql );
|
||||
}
|
||||
|
||||
public static function build_icl_strings_columns_if_required() {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! get_option( 'wpml-package-translation-string-table-updated' ) ) {
|
||||
|
||||
self::$table_name = $wpdb->prefix . 'icl_strings';
|
||||
|
||||
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . self::$table_name . "'" ) == self::$table_name ) {
|
||||
if ( ! self::current_table_has_column( 'string_package_id' ) ) {
|
||||
self::add_string_package_id_to_icl_strings();
|
||||
}
|
||||
|
||||
if ( ! self::current_table_has_column( 'type' ) ) {
|
||||
self::add_type_to_icl_strings();
|
||||
}
|
||||
|
||||
if ( ! self::current_table_has_column( 'title' ) ) {
|
||||
self::add_title_to_icl_strings();
|
||||
}
|
||||
update_option( 'wpml-package-translation-string-table-updated', true, 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function build_icl_string_packages_columns_if_required() {
|
||||
global $wpdb;
|
||||
|
||||
if ( get_option( 'wpml-package-translation-string-packages-table-updated' ) != '0.0.2' ) {
|
||||
|
||||
self::$table_name = $wpdb->prefix . 'icl_string_packages';
|
||||
|
||||
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . self::$table_name . "'" ) == self::$table_name ) {
|
||||
if ( ! self::current_table_has_column( 'kind_slug' ) ) {
|
||||
self::add_kind_slug_to_icl_string_packages();
|
||||
}
|
||||
self::update_kind_slug();
|
||||
|
||||
if ( ! self::current_table_has_column( 'view_link' ) ) {
|
||||
self::add_view_link_to_icl_string_packages();
|
||||
}
|
||||
update_option( 'wpml-package-translation-string-packages-table-updated', '0.0.2', 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function add_kind_slug_to_icl_string_packages() {
|
||||
global $wpdb;
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . "` ADD `kind_slug` varchar(160) DEFAULT '' NOT NULL AFTER `ID`";
|
||||
$result = $wpdb->query( $sql );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function add_view_link_to_icl_string_packages() {
|
||||
global $wpdb;
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . '` ADD `view_link` TEXT NOT NULL AFTER `edit_link`';
|
||||
|
||||
return $wpdb->query( $sql );
|
||||
}
|
||||
|
||||
private static function fix_icl_string_packages_ID_column() {
|
||||
global $wpdb;
|
||||
self::$table_name = $wpdb->prefix . 'icl_string_packages';
|
||||
if ( self::current_table_has_column( 'id' ) ) {
|
||||
$sql = 'ALTER TABLE `' . self::$table_name . '` CHANGE id ID BIGINT UNSIGNED NOT NULL auto_increment;';
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
}
|
||||
|
||||
private static function build_icl_string_packages_table() {
|
||||
global $wpdb;
|
||||
|
||||
$charset_collate = SitePress_Setup::get_charset_collate();
|
||||
|
||||
self::$table_name = $wpdb->prefix . 'icl_string_packages';
|
||||
$sql = '
|
||||
CREATE TABLE IF NOT EXISTS `' . self::$table_name . '` (
|
||||
`ID` bigint(20) unsigned NOT NULL auto_increment,
|
||||
`kind_slug` varchar(160) NOT NULL,
|
||||
`kind` varchar(160) NOT NULL,
|
||||
`name` varchar(160) NOT NULL,
|
||||
`title` varchar(160) NOT NULL,
|
||||
`edit_link` TEXT NOT NULL,
|
||||
`view_link` TEXT NOT NULL,
|
||||
`post_id` INTEGER DEFAULT NULL,
|
||||
`word_count` VARCHAR(2000) DEFAULT NULL,
|
||||
PRIMARY KEY (`ID`)
|
||||
) ' . $charset_collate . '';
|
||||
if ( $wpdb->query( $sql ) === false ) {
|
||||
throw new Exception( $wpdb->last_error );
|
||||
}
|
||||
}
|
||||
|
||||
private static function update_kind_slug() {
|
||||
global $wpdb;
|
||||
$sql = 'SELECT kind FROM ' . self::$table_name . " WHERE IFNULL(kind_slug,'')='' GROUP BY kind";
|
||||
$kinds = $wpdb->get_col( $sql );
|
||||
$result = ( count( $kinds ) == 0 );
|
||||
foreach ( $kinds as $kind ) {
|
||||
$kind_slug = sanitize_title_with_dashes( $kind );
|
||||
$result = $wpdb->update( self::$table_name, array( 'kind_slug' => $kind_slug ), array( 'kind' => $kind ) );
|
||||
if ( ! $result ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_ST {
|
||||
|
||||
public function get_string_element( $string_id, $column = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$package_query = "SELECT * FROM {$wpdb->prefix}icl_strings WHERE id=%d";
|
||||
$package_prepare = $wpdb->prepare( $package_query, array( $string_id ) );
|
||||
$result = $wpdb->get_row( $package_prepare );
|
||||
|
||||
if ( $result && $column && isset( $result[ $column ] ) ) {
|
||||
$result = $result[ $column ];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function get_string_title( $title, $string_details ) {
|
||||
$string_title = $this->get_string_element( $string_details['string_id'], 'title' );
|
||||
if ( $string_title ) {
|
||||
return $string_title;
|
||||
} else {
|
||||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_TM_Jobs {
|
||||
/**
|
||||
* @var WPML_Package
|
||||
*/
|
||||
protected $package;
|
||||
|
||||
protected function __construct( $package ) {
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
final public function validate_translations( $create_if_missing = true ) {
|
||||
$trid = $this->get_trid( $create_if_missing );
|
||||
|
||||
return $trid != false;
|
||||
}
|
||||
|
||||
final protected function get_trid( $create_if_missing = true ) {
|
||||
global $sitepress;
|
||||
$package = $this->package;
|
||||
$post_trid = $sitepress->get_element_trid( $package->ID, $package->get_translation_element_type() );
|
||||
if ( ! $post_trid && $create_if_missing ) {
|
||||
$this->set_language_details();
|
||||
$post_trid = $sitepress->get_element_trid( $package->ID, $package->get_translation_element_type() );
|
||||
}
|
||||
|
||||
return $post_trid;
|
||||
}
|
||||
|
||||
final public function set_language_details( $language_code = null ) {
|
||||
global $sitepress;
|
||||
$package = $this->package;
|
||||
$post_id = $package->ID;
|
||||
$post = $this->get_translatable_item( $post_id );
|
||||
$post_id = $post->ID;
|
||||
$element_type = $package->get_translation_element_type();
|
||||
if ( ! $language_code ) {
|
||||
$language_code = icl_get_default_language();
|
||||
}
|
||||
$sitepress->set_element_language_details( $post_id, $element_type, false, $language_code, null, false );
|
||||
}
|
||||
|
||||
final public function get_translatable_item( $package ) {
|
||||
// for TranslationManagement::send_jobs
|
||||
if ( ! is_a( $package, 'WPML_Package' ) ) {
|
||||
$package = new WPML_Package( $package );
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
final public function delete_translation_jobs() {
|
||||
global $wpdb;
|
||||
|
||||
$post_translations = $this->get_post_translations();
|
||||
foreach ( $post_translations as $lang => $translation ) {
|
||||
$rid_query = "SELECT rid FROM {$wpdb->prefix}icl_translation_status WHERE translation_id=%d";
|
||||
$rid_prepare = $wpdb->prepare( $rid_query, array( $translation->translation_id ) );
|
||||
$rid = $wpdb->get_var( $rid_prepare );
|
||||
if ( $rid ) {
|
||||
$job_id_query = "SELECT job_id FROM {$wpdb->prefix}icl_translate_job WHERE rid=%d";
|
||||
$job_id_prepare = $wpdb->prepare( $job_id_query, array( $rid ) );
|
||||
$job_id = $wpdb->get_var( $job_id_prepare );
|
||||
|
||||
if ( $job_id ) {
|
||||
$wpdb->delete( $wpdb->prefix . 'icl_translate_job', array( 'job_id' => $job_id ) );
|
||||
$wpdb->delete( $wpdb->prefix . 'icl_translate', array( 'job_id' => $job_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final public function delete_translations() {
|
||||
global $sitepress;
|
||||
|
||||
$sitepress->delete_element_translation(
|
||||
$this->get_trid(),
|
||||
$this->package->get_translation_element_type()
|
||||
);
|
||||
}
|
||||
|
||||
final public function get_post_translations() {
|
||||
global $sitepress;
|
||||
$package = $this->package;
|
||||
|
||||
$translation_element_type = $package->get_translation_element_type();
|
||||
$trid = $this->get_trid();
|
||||
|
||||
return $sitepress->get_element_translations( $trid, $translation_element_type );
|
||||
}
|
||||
|
||||
final protected function update_translation_job_needs_update( $job_id ) {
|
||||
global $wpdb;
|
||||
$update_data = array( 'translated' => 0 );
|
||||
$update_where = array( 'job_id' => $job_id );
|
||||
$wpdb->update( "{$wpdb->prefix}icl_translate_job", $update_data, $update_where );
|
||||
}
|
||||
|
||||
final function update_translation_job( $rid, $post ) {
|
||||
|
||||
$updated = $this->update_translation_job_fields( $rid, $post );
|
||||
$deleted = $this->delete_translation_job_fields( $rid, $post );
|
||||
|
||||
return ( $updated || $deleted );
|
||||
}
|
||||
|
||||
private function delete_translation_job_fields( $rid, $post ) {
|
||||
$deleted = false;
|
||||
$job_id = $this->get_translation_job_id( $rid );
|
||||
$translation_fields = $this->get_translations_job_fields( $job_id );
|
||||
foreach ( $translation_fields as $field_type => $el ) {
|
||||
// delete fields that are no longer present
|
||||
if ( $el->field_translate && ! isset( $post->string_data[ $field_type ] ) ) {
|
||||
$this->delete_translation_field( $el->tid );
|
||||
if ( ! $deleted ) {
|
||||
$deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $rid
|
||||
* @param WPML_Package $post
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function update_translation_job_fields( $rid, $post ) {
|
||||
$updated_any = false;
|
||||
|
||||
$job_id = $this->get_translation_job_id( $rid );
|
||||
$translation_fields = $this->get_translations_job_fields( $job_id );
|
||||
|
||||
if ( isset( $post->string_data ) && is_array( $post->string_data ) ) {
|
||||
foreach ( $post->string_data as $field_type => $field_value ) {
|
||||
$updated = $this->insert_update_translation_job_field( $field_value, $translation_fields, $field_type, $job_id );
|
||||
if ( ! $updated_any && $updated ) {
|
||||
$updated_any = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $updated_any;
|
||||
}
|
||||
|
||||
protected function get_translation_job_id( $rid ) {
|
||||
global $wpdb;
|
||||
$job_id_query = "SELECT MAX(job_id) FROM {$wpdb->prefix}icl_translate_job WHERE rid=%d GROUP BY rid";
|
||||
$job_id_prepare = $wpdb->prepare( $job_id_query, $rid );
|
||||
$job_id = $wpdb->get_var( $job_id_prepare );
|
||||
|
||||
return $job_id;
|
||||
}
|
||||
|
||||
private function get_translations_job_fields( $job_id ) {
|
||||
global $wpdb;
|
||||
$translation_fields_query = "SELECT field_type, field_data, tid, field_translate
|
||||
FROM {$wpdb->prefix}icl_translate
|
||||
WHERE job_id=%d";
|
||||
$translation_fields_query = $wpdb->prepare( $translation_fields_query, $job_id );
|
||||
$translation_fields = $wpdb->get_results( $translation_fields_query, OBJECT_K );
|
||||
|
||||
return $translation_fields;
|
||||
}
|
||||
|
||||
private function delete_translation_field( $tid ) {
|
||||
global $wpdb;
|
||||
$wpdb->delete( $wpdb->prefix . 'icl_translate', array( 'tid' => $tid ), array( '%d' ) );
|
||||
}
|
||||
|
||||
private function insert_update_translation_job_field( $field_value, $translation_fields, $field_type, $job_id ) {
|
||||
$updated = false;
|
||||
$field_data = base64_encode( $field_value );
|
||||
if ( ! isset( $translation_fields[ $field_type ] ) ) {
|
||||
$this->insert_translation_field( $job_id, $field_type, $field_data );
|
||||
$updated = true;
|
||||
} elseif ( $translation_fields[ $field_type ]->field_data != $field_data ) {
|
||||
$this->update_translation_field( $field_data, $translation_fields, $field_type );
|
||||
$updated = true;
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
private function update_translation_field( $field_data, $translation_fields, $field_type ) {
|
||||
global $wpdb;
|
||||
$wpdb->update(
|
||||
$wpdb->prefix . 'icl_translate',
|
||||
array(
|
||||
'field_data' => $field_data,
|
||||
'field_finished' => 0,
|
||||
),
|
||||
array( 'tid' => $translation_fields[ $field_type ]->tid )
|
||||
);
|
||||
}
|
||||
|
||||
private function insert_translation_field( $job_id, $field_type, $field_data ) {
|
||||
global $wpdb;
|
||||
$data = array(
|
||||
'job_id' => $job_id,
|
||||
'content_id' => 0,
|
||||
'field_type' => $field_type,
|
||||
'field_format' => 'base64',
|
||||
'field_translate' => 1,
|
||||
'field_data' => $field_data,
|
||||
'field_data_translated' => 0,
|
||||
'field_finished' => 0,
|
||||
);
|
||||
|
||||
$wpdb->insert( $wpdb->prefix . 'icl_translate', $data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_TM extends WPML_Package_TM_Jobs {
|
||||
public function __construct( $package ) {
|
||||
parent::__construct( $package );
|
||||
}
|
||||
|
||||
public function get_translation_statuses() {
|
||||
global $sitepress;
|
||||
$package = $this->package;
|
||||
|
||||
$post_trid = $this->get_trid();
|
||||
$items = array();
|
||||
if ( $post_trid ) {
|
||||
$translation_element_type = $package->get_translation_element_type();
|
||||
$post_translations = $sitepress->get_element_translations( $post_trid, $translation_element_type );
|
||||
foreach ( $post_translations as $lang => $translation ) {
|
||||
$translation->trid = $post_trid;
|
||||
$item[] = $this->set_translation_status( $package, $translation, $lang );
|
||||
}
|
||||
} else {
|
||||
$items[] = $package;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WPML_Package $package
|
||||
* @param \stdClass $translation
|
||||
* @param string $lang
|
||||
*
|
||||
* @return \WPML_Package
|
||||
*/
|
||||
private function set_translation_status( $package, $translation, $lang ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! $package->trid ) {
|
||||
$package->trid = $translation->trid;
|
||||
}
|
||||
|
||||
$res_query = "SELECT status, needs_update, md5 FROM {$wpdb->prefix}icl_translation_status WHERE translation_id=%d";
|
||||
$res_args = array( $translation->translation_id );
|
||||
$res_prepare = $wpdb->prepare( $res_query, $res_args );
|
||||
$res = $wpdb->get_row( $res_prepare );
|
||||
$_suffix = str_replace( '-', '_', $lang );
|
||||
$status = ICL_TM_NOT_TRANSLATED;
|
||||
if ( $res ) {
|
||||
$status = $res->status;
|
||||
$index = 'needs_update_' . $_suffix;
|
||||
$package->$index = $res->needs_update;
|
||||
}
|
||||
$index = 'status_' . $_suffix;
|
||||
$package->$index = apply_filters( 'wpml_translation_status', $status, $translation->trid, $lang, 'package' );
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
public function is_translation_in_progress() {
|
||||
global $wpdb;
|
||||
|
||||
$post_translations = $this->get_post_translations();
|
||||
|
||||
foreach ( $post_translations as $lang => $translation ) {
|
||||
$res_query = "SELECT status, needs_update, md5
|
||||
FROM {$wpdb->prefix}icl_translation_status
|
||||
WHERE translation_id=%d";
|
||||
$res_prepared = $wpdb->prepare( $res_query, array( $translation->translation_id ) );
|
||||
$res = $wpdb->get_row( $res_prepared );
|
||||
if ( $res && $res->status == ICL_TM_IN_PROGRESS ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update translations
|
||||
*
|
||||
* @param bool $is_new_package
|
||||
* @param bool $needs_update - when deleting single field we do not need to change the translation status of the form
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update_package_translations( $is_new_package, $needs_update = true ) {
|
||||
|
||||
global $iclTranslationManagement;
|
||||
|
||||
$updated = false;
|
||||
|
||||
$package = $this->package;
|
||||
$trid = $this->get_trid();
|
||||
|
||||
if ( $is_new_package ) {
|
||||
$this->set_language_details();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$item_md5_translations = $this->get_item_md5_translations( $trid );
|
||||
|
||||
if ( $item_md5_translations ) {
|
||||
$md5 = $iclTranslationManagement->post_md5( $this->package );
|
||||
|
||||
if ( $md5 != $item_md5_translations[0]->md5 ) { // all translations need update
|
||||
|
||||
$translation_package = $iclTranslationManagement->create_translation_package( $this->package );
|
||||
|
||||
foreach ( $item_md5_translations as $translation ) {
|
||||
$translation_id = $translation->translation_id;
|
||||
$previous_state = $this->get_translation_state( $translation );
|
||||
|
||||
$data = array();
|
||||
if ( ! empty( $previous_state ) ) {
|
||||
$data['previous_state'] = serialize( $previous_state );
|
||||
}
|
||||
$data = array(
|
||||
'translation_id' => $translation_id,
|
||||
'translation_package' => serialize( $translation_package ),
|
||||
'md5' => $md5,
|
||||
);
|
||||
|
||||
if ( $needs_update ) {
|
||||
$data['needs_update'] = 1;
|
||||
}
|
||||
|
||||
$update_result = $iclTranslationManagement->update_translation_status( $data );
|
||||
|
||||
$rid = $update_result[0];
|
||||
|
||||
$this->update_translation_job( $rid, $this->package );
|
||||
|
||||
// change job status only when needs update
|
||||
if ( $needs_update ) {
|
||||
$job_id = $this->get_translation_job_id( $rid );
|
||||
if ( $job_id ) {
|
||||
$this->update_translation_job_needs_update( $job_id );
|
||||
$updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
private function get_item_md5_translations( $trid ) {
|
||||
global $wpdb;
|
||||
|
||||
$item_md5_translations_query = "
|
||||
SELECT t.translation_id, s.md5
|
||||
FROM {$wpdb->prefix}icl_translations t
|
||||
NATURAL JOIN {$wpdb->prefix}icl_translation_status s
|
||||
WHERE t.trid=%d
|
||||
AND t.source_language_code IS NOT NULL";
|
||||
$item_md5_translations_prepare = $wpdb->prepare( $item_md5_translations_query, $trid );
|
||||
$item_md5_translations = $wpdb->get_results( $item_md5_translations_prepare );
|
||||
|
||||
return $item_md5_translations;
|
||||
}
|
||||
|
||||
private function get_translation_state( $translation ) {
|
||||
global $wpdb;
|
||||
|
||||
$previous_state_query = "
|
||||
SELECT status, translator_id, needs_update, md5, translation_service, translation_package, timestamp, links_fixed
|
||||
FROM {$wpdb->prefix}icl_translation_status
|
||||
WHERE translation_id = %d
|
||||
";
|
||||
$previous_state_prepare = $wpdb->prepare( $previous_state_query, $translation->translation_id );
|
||||
$previous_state = $wpdb->get_row( $previous_state_prepare, ARRAY_A );
|
||||
|
||||
return $previous_state;
|
||||
}
|
||||
|
||||
public function add_package_to_basket( $translation_action, $source_language, $target_language ) {
|
||||
if ( ! $this->validate_basket_package_item( $translation_action, $source_language ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->is_duplicate_or_do_nothing( $translation_action ) ) {
|
||||
$this->duplicate_or_do_nothing( $translation_action, $target_language );
|
||||
} elseif ( $translation_action == 1 ) {
|
||||
$this->send_package_to_basket( $source_language, $target_language );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function duplicate_package( $package_id ) {
|
||||
// TODO: [WPML 3.3] duplication to be done
|
||||
// $this->make_duplicate( $package_id, $language_code );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $translation_action
|
||||
* @param string $source_language
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validate_basket_package_item( $translation_action, $source_language ) {
|
||||
ICL_AdminNotifier::remove_message( 'the_basket_items_notification' );
|
||||
|
||||
$package = $this->package;
|
||||
$package_id = $package->ID;
|
||||
$basket = TranslationProxy_Basket::get_basket();
|
||||
$package_is_valid = true;
|
||||
$basket_source_language = TranslationProxy_Basket::get_source_language();
|
||||
if ( $basket && $basket_source_language ) {
|
||||
if ( $source_language != $basket_source_language ) {
|
||||
TranslationProxy_Basket::add_message(
|
||||
array(
|
||||
'type' => 'update',
|
||||
'text' => __(
|
||||
'You cannot add packages in this language to the basket since it already contains posts, packages or strings of another source language!
|
||||
Either submit the current basket and then add the post or delete the posts of differing language in the current basket',
|
||||
'wpml-string-translation'
|
||||
),
|
||||
)
|
||||
);
|
||||
TranslationProxy_Basket::update_basket();
|
||||
|
||||
$package_is_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
$select_one_lang_message = __( 'Please select at least one language to translate into.', 'wpml-string-translation' );
|
||||
|
||||
if ( ! $translation_action ) {
|
||||
TranslationProxy_Basket::add_message(
|
||||
array(
|
||||
'type' => 'error',
|
||||
'text' => $select_one_lang_message,
|
||||
)
|
||||
);
|
||||
|
||||
$package_is_valid = false;
|
||||
} else {
|
||||
TranslationProxy_Basket::remove_message( $select_one_lang_message );
|
||||
}
|
||||
|
||||
if ( ! $package_id ) {
|
||||
TranslationProxy_Basket::add_message(
|
||||
array(
|
||||
'type' => 'error',
|
||||
'text' => __( 'Please select at least one document to translate.', 'wpml-string-translation' ),
|
||||
)
|
||||
);
|
||||
|
||||
$package_is_valid = false;
|
||||
|
||||
return $package_is_valid;
|
||||
}
|
||||
|
||||
return $package_is_valid;
|
||||
}
|
||||
|
||||
private function is_duplicate_or_do_nothing( $translation_action ) {
|
||||
return $translation_action == 0 || $translation_action == 2;
|
||||
}
|
||||
|
||||
private function duplicate_or_do_nothing( $translation_action, $target_language ) {
|
||||
$basket = TranslationProxy_Basket::get_basket();
|
||||
|
||||
$package = $this->package;
|
||||
$package_id = $package->ID;
|
||||
|
||||
// iterate posts ids, check if they are in wp_options
|
||||
// if they are set to translate for this particular language
|
||||
// end then remove it
|
||||
// check if we have this post in wp_options
|
||||
// end remove
|
||||
if ( isset( $basket['package'][ $package_id ]['to_langs'][ $target_language ] ) ) {
|
||||
unset( $basket['package'][ $package_id ]['to_langs'][ $target_language ] );
|
||||
TranslationProxy_Basket::update_basket( $basket );
|
||||
}
|
||||
// if user want to duplicate this post, lets do this
|
||||
if ( $translation_action == 2 ) {
|
||||
$this->duplicate_package( $package_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source_language
|
||||
* @param string $target_language
|
||||
*
|
||||
* @throws WPML_Package_Exception
|
||||
*/
|
||||
public function send_package_to_basket( $source_language, $target_language ) {
|
||||
global $sitepress, $iclTranslationManagement;
|
||||
|
||||
$package = $this->package;
|
||||
$package_id = $package->ID;
|
||||
$basket = TranslationProxy_Basket::get_basket();
|
||||
$language_name = $sitepress->get_display_language_name( $target_language );
|
||||
|
||||
$send_to_basket = true;
|
||||
$package_helper = new WPML_Package_Helper();
|
||||
$post = $package_helper->get_translatable_item( null, $package_id );
|
||||
|
||||
$post_title = esc_html( $post->title );
|
||||
$element_type = $package->get_element_type_prefix() . '_' . $post->kind_slug;
|
||||
$trid = $sitepress->get_element_trid( $package_id, $element_type );
|
||||
$job_id = $iclTranslationManagement->get_translation_job_id( $trid, $target_language );
|
||||
if ( $job_id ) {
|
||||
$job_details = $iclTranslationManagement->get_translation_job( $job_id );
|
||||
$send_to_basket = $this->validate_package_status( $job_details, $post_title, $language_name );
|
||||
}
|
||||
|
||||
if ( $send_to_basket ) {
|
||||
$basket['package'][ $package_id ]['from_lang'] = $source_language;
|
||||
$basket['package'][ $package_id ]['to_langs'][ $target_language ] = 1;
|
||||
// set basket language if not already set
|
||||
if ( ! isset( $basket['source_language'] ) ) {
|
||||
$basket['source_language'] = $source_language;
|
||||
}
|
||||
}
|
||||
TranslationProxy_Basket::update_basket( $basket );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $job_details
|
||||
* @param string $post_title
|
||||
* @param string $language_name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validate_package_status( $job_details, $post_title, $language_name ) {
|
||||
$send_to_basket = true;
|
||||
$message_args = array();
|
||||
|
||||
if ( ! $job_details->needs_update ) {
|
||||
if ( $job_details->status == ICL_TM_IN_PROGRESS ) {
|
||||
$message_args = array(
|
||||
'type' => 'update',
|
||||
'text' => sprintf(
|
||||
__(
|
||||
'Post "%1$s" will be ignored for %2$s, because translation is already in progress.',
|
||||
'wpml-string-translation'
|
||||
),
|
||||
$post_title,
|
||||
$language_name
|
||||
),
|
||||
);
|
||||
$send_to_basket = false;
|
||||
} elseif ( $job_details->status == ICL_TM_WAITING_FOR_TRANSLATOR ) {
|
||||
$message_args = array(
|
||||
'type' => 'update',
|
||||
'text' => sprintf(
|
||||
__(
|
||||
'Post "%1$s" will be ignored for %2$s, because translation is already waiting for translator.',
|
||||
'wpml-string-translation'
|
||||
),
|
||||
$post_title,
|
||||
$language_name
|
||||
),
|
||||
);
|
||||
$send_to_basket = false;
|
||||
}
|
||||
}
|
||||
if ( ! $send_to_basket ) {
|
||||
TranslationProxy_Basket::add_message( $message_args );
|
||||
TranslationProxy_Basket::update_basket();
|
||||
}
|
||||
|
||||
return $send_to_basket;
|
||||
}
|
||||
|
||||
public function is_in_basket( $target_lang ) {
|
||||
if ( class_exists( 'TranslationProxy_Basket' ) ) {
|
||||
$basket = TranslationProxy_Basket::get_basket();
|
||||
return isset( $basket['package'][ $this->package->ID ]['to_langs'][ $target_lang ] );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Translation_UI {
|
||||
var $load_priority = 101;
|
||||
private $menu_root = '';
|
||||
|
||||
const MENU_SLUG = 'wpml-package-management';
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'wpml_loaded', array( $this, 'loaded' ), $this->load_priority );
|
||||
}
|
||||
|
||||
public function loaded() {
|
||||
|
||||
if ( $this->passed_dependencies() ) {
|
||||
$this->set_admin_hooks();
|
||||
do_action( 'WPML_PT_HTML' );
|
||||
}
|
||||
}
|
||||
|
||||
private function passed_dependencies() {
|
||||
return defined( 'ICL_SITEPRESS_VERSION' )
|
||||
&& defined( 'WPML_ST_VERSION' )
|
||||
&& defined( 'WPML_TM_VERSION' );
|
||||
}
|
||||
|
||||
private function set_admin_hooks() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'wpml_admin_menu_configure', array( $this, 'menu' ) );
|
||||
add_action( 'wpml_admin_menu_root_configured', array( $this, 'main_menu_configured' ), 10, 2 );
|
||||
|
||||
add_action( 'admin_register_scripts', array( $this, 'admin_register_scripts' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function main_menu_configured( $menu_id, $root_slug ) {
|
||||
if ( 'WPML' === $menu_id ) {
|
||||
$this->menu_root = $root_slug;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $menu_id
|
||||
*/
|
||||
public function menu( $menu_id ) {
|
||||
if ( 'WPML' !== $menu_id || ! defined( 'ICL_PLUGIN_PATH' ) ) {
|
||||
return;
|
||||
}
|
||||
global $sitepress;
|
||||
if ( ! isset( $sitepress ) || ( method_exists( $sitepress, 'get_setting' ) && ! $sitepress->get_setting( 'setup_complete' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $sitepress_settings;
|
||||
|
||||
if ( ! isset( $sitepress_settings['existing_content_language_verified'] ) || ! $sitepress_settings['existing_content_language_verified'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( current_user_can( 'wpml_manage_string_translation' ) ) {
|
||||
$menu = array();
|
||||
$menu['order'] = 1300;
|
||||
$menu['page_title'] = __( 'Packages', 'wpml-string-translation' );
|
||||
$menu['menu_title'] = __( 'Packages', 'wpml-string-translation' );
|
||||
$menu['capability'] = 'wpml_manage_string_translation';
|
||||
$menu['menu_slug'] = self::MENU_SLUG;
|
||||
$menu['function'] = array(
|
||||
'WPML_Package_Translation_HTML_Packages',
|
||||
'package_translation_menu',
|
||||
);
|
||||
|
||||
do_action( 'wpml_admin_menu_register_item', $menu );
|
||||
$this->admin_register_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
function admin_register_scripts() {
|
||||
wp_register_script( 'wpml-package-trans-man-script', WPML_PACKAGE_TRANSLATION_URL . '/resources/js/wpml_package_management.js', array( 'jquery' ) );
|
||||
}
|
||||
|
||||
function admin_enqueue_scripts( $hook ) {
|
||||
if ( get_plugin_page_hookname( self::MENU_SLUG, $this->menu_root ) === $hook ) {
|
||||
wp_enqueue_script( 'wpml-package-trans-man-script' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,806 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package_Translation extends WPML_Package_Helper {
|
||||
var $load_priority = 100;
|
||||
var $package_translation_active;
|
||||
var $admin_lang_switcher = null;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
add_action( 'wpml_loaded', array( $this, 'loaded' ), $this->load_priority, 1 );
|
||||
}
|
||||
|
||||
function loaded( SitePress $sitepress = null ) {
|
||||
parent::loaded();
|
||||
|
||||
if ( null === $sitepress ) {
|
||||
global $sitepress;
|
||||
}
|
||||
|
||||
$is_setup_complete = (bool) $sitepress->get_setting( 'setup_complete', false );
|
||||
|
||||
if ( $is_setup_complete ) {
|
||||
$this->run_db_update();
|
||||
}
|
||||
|
||||
if ( $this->passed_dependencies() && $is_setup_complete ) {
|
||||
$this->add_admin_hooks();
|
||||
$this->add_global_hooks();
|
||||
|
||||
if ( is_admin() ) {
|
||||
|
||||
if ( $this->is_refresh_required() ) {
|
||||
add_action( 'init', array( $this, 'refresh_packages' ), 999, 0 );
|
||||
$this->set_refresh_not_required();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function add_admin_hooks() {
|
||||
if ( is_admin() || $this->is_doing_xmlrpc() || wpml_is_rest_request() ) {
|
||||
add_action( 'wp_ajax_wpml_delete_packages', array( $this, 'delete_packages_ajax' ) );
|
||||
add_action( 'wp_ajax_wpml_change_package_lang', array( $this, 'change_package_lang_ajax' ) );
|
||||
|
||||
/* Core hooks */
|
||||
add_filter( 'wpml_pt_all_packages', array( $this, 'get_all_packages' ) );
|
||||
|
||||
/* Translation hooks for other plugins to use */
|
||||
add_filter( 'wpml_tm_element_type', array( $this, 'get_element_type' ), 10, 2 );
|
||||
add_filter( 'wpml_tm_dashboard_title_locations', array( $this, 'add_title_db_location' ), 10, 2 );
|
||||
|
||||
add_filter( 'wpml_string_title_from_id', array( $this, 'string_title_from_id_filter' ), 10, 2 );
|
||||
// TODO: deprecated, use the 'wpml_register_string' action
|
||||
add_filter( 'WPML_register_string', array( $this, 'register_string_for_translation' ), 10, 5 );
|
||||
|
||||
add_action( 'wpml_add_string_translation', array( $this, 'add_string_translation_action' ), 10, 7 );
|
||||
|
||||
// TODO: These 3 hooks are deprecated. They are needed for Layouts 1.0. Consider removing them after Layouts 1.2 is released
|
||||
add_filter( 'WPML_get_translated_strings', array( $this, 'get_translated_strings' ), 10, 2 );
|
||||
add_action( 'WPML_set_translated_strings', array( $this, 'set_translated_strings' ), 10, 2 );
|
||||
add_action( 'WPML_show_package_language_ui', array( $this, 'show_language_selector' ), 10, 2 );
|
||||
|
||||
add_filter( 'wpml_get_translated_strings', array( $this, 'get_translated_strings' ), 10, 2 );
|
||||
add_action( 'wpml_set_translated_strings', array( $this, 'set_translated_strings' ), 10, 2 );
|
||||
add_action( 'wpml_show_package_language_ui', array( $this, 'show_language_selector' ), 10, 2 );
|
||||
add_action( 'wpml_show_package_language_admin_bar', array( $this, 'show_admin_bar_language_selector' ), 10, 2 );
|
||||
|
||||
/* WPML hooks */
|
||||
add_filter( 'wpml_get_translatable_types', array( $this, 'get_translatable_types' ), 10, 1 );
|
||||
add_filter( 'wpml_get_translatable_item', array( $this, 'get_translatable_item' ), 10, 3 );
|
||||
add_filter( 'wpml_external_item_url', array( $this, 'get_package_edit_url' ), 10, 2 );
|
||||
add_filter( 'wpml_external_item_link', array( $this, 'get_package_edit_link' ), 10, 3 );
|
||||
add_filter( 'wpml_get_external_item_title', array( $this, 'get_package_title' ), 10, 3 );
|
||||
add_filter( 'wpml_element_id_from_package', array( $this, 'get_element_id_from_package_filter' ), 10, 2 );
|
||||
add_filter( 'wpml_get_package_type', array( $this, 'get_package_type' ), 10, 2 );
|
||||
add_filter( 'wpml_get_package_type_prefix', array( $this, 'get_package_type_prefix' ), 10, 2 );
|
||||
add_filter( 'wpml_language_for_element', array( $this, 'get_language_for_element' ), 10, 2 );
|
||||
add_filter( 'wpml_st_get_string_package', array( $this, 'get_string_package' ), 10, 2 );
|
||||
add_action( 'wpml_save_external', [ $this, 'save_package_translations' ], 10, 3 );
|
||||
|
||||
/* Translation queue hooks */
|
||||
add_filter( 'wpml_tm_external_translation_job_title', array( $this, 'get_post_title' ), 10, 2 );
|
||||
add_filter( 'wpml_tm_add_to_basket', array( $this, 'add_to_basket' ), 10, 2 );
|
||||
add_filter( 'wpml_tm_translation_jobs_basket', array( $this, 'update_translation_jobs_basket' ), 10, 3 );
|
||||
add_filter( 'wpml_tm_basket_items_types', array( $this, 'basket_items_types' ), 10, 2 );
|
||||
|
||||
/*
|
||||
TM Hooks */
|
||||
// This is called by \TranslationManagement::send_all_jobs - The hook is dynamically built.
|
||||
add_filter( 'wpml_tm_dashboard_sql', array( $this, 'tm_dashboard_sql_filter' ), 10, 1 );
|
||||
|
||||
/* Translation editor hooks */
|
||||
add_filter( 'wpml_tm_editor_string_name', array( $this, 'get_editor_string_name' ), 10, 2 );
|
||||
add_filter( 'wpml_tm_editor_string_style', array( $this, 'get_editor_string_style' ), 10, 3 );
|
||||
|
||||
/*
|
||||
API Hooks */
|
||||
// @deprecated @since 3.2 Use 'wpml_delete_package'
|
||||
add_action( 'wpml_delete_package_action', array( $this, 'delete_package_action' ), 10, 2 );
|
||||
|
||||
add_action( 'deleted_post', array( $this, 'remove_post_packages' ) );
|
||||
}
|
||||
}
|
||||
|
||||
private function is_doing_xmlrpc() {
|
||||
return ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST );
|
||||
}
|
||||
|
||||
private function add_global_hooks() {
|
||||
|
||||
// TODO: deprecated, use the 'wpml_translate_string' filter
|
||||
add_filter( 'WPML_translate_string', array( $this, 'translate_string' ), 10, 3 );
|
||||
add_filter( 'wpml_translate_string', array( $this, 'translate_string' ), 10, 3 );
|
||||
|
||||
add_action( 'wpml_register_string', array( $this, 'register_string_action' ), 10, 5 );
|
||||
add_action( 'wpml_start_string_package_registration', array( $this, 'start_string_package_registration_action' ), 10, 1 );
|
||||
add_action( 'wpml_delete_unused_package_strings', array( $this, 'delete_unused_package_strings_action' ), 10, 1 );
|
||||
add_action( 'wpml_delete_package', array( $this, 'delete_package_action' ), 10, 2 );
|
||||
add_filter( 'wpml_st_get_post_string_packages', array( $this, 'get_post_string_packages' ), 10, 2 );
|
||||
|
||||
add_filter( 'wpml_string_id_from_package', array( $this, 'string_id_from_package_filter' ), 10, 4 );
|
||||
|
||||
/* API Hooks */
|
||||
add_filter( 'wpml_is_external', array( $this, 'is_external' ), 10, 2 );
|
||||
}
|
||||
|
||||
private function run_db_update() {
|
||||
if ( is_admin() ) {
|
||||
WPML_Package_Translation_Schema::run_update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function passed_dependencies() {
|
||||
return defined( 'ICL_SITEPRESS_VERSION' )
|
||||
&& defined( 'WPML_ST_VERSION' )
|
||||
&& defined( 'WPML_TM_VERSION' );
|
||||
}
|
||||
|
||||
public function add_title_db_location( $locations ) {
|
||||
global $wpdb;
|
||||
|
||||
$locations[ $wpdb->prefix . 'icl_string_packages' ] = array(
|
||||
'id_column' => 'ID',
|
||||
'title_column' => 'title',
|
||||
'element_type_prefix' => 'package',
|
||||
'date_column' => false,
|
||||
);
|
||||
|
||||
return $locations;
|
||||
}
|
||||
|
||||
function get_package_edit_url( $url, $post_id ) {
|
||||
$package = new WPML_Package( $post_id );
|
||||
if ( ! $package ) {
|
||||
return false;
|
||||
} //not ours
|
||||
if ( isset( $package->edit_link ) ) {
|
||||
$url = $package->edit_link;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function get_package_title( $title, $kind, $id ) {
|
||||
$package = new WPML_Package( $id );
|
||||
if ( ! $package ) {
|
||||
return $title;
|
||||
} //not ours
|
||||
if ( isset( $package->title ) ) {
|
||||
$title = $package->title;
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
function get_package_view_link( $link, $post_id, $hide_if_missing_link = false ) {
|
||||
$package = new WPML_Package( $post_id );
|
||||
if ( ! $package ) {
|
||||
return $link;
|
||||
} //not ours
|
||||
return $this->build_package_link( $package->view_link, $package->title, $hide_if_missing_link );
|
||||
}
|
||||
|
||||
function get_package_edit_link( $link, $post_id, $hide_if_missing_link = false ) {
|
||||
$package = new WPML_Package( $post_id );
|
||||
if ( ! $package ) {
|
||||
return $link;
|
||||
} //not ours
|
||||
return $this->build_package_link( $package->edit_link, esc_html( $package->title ), $hide_if_missing_link );
|
||||
}
|
||||
|
||||
private function build_package_link( $url, $title, $hide_if_missing_link = false ) {
|
||||
$link = '<a href="' . $url . '">' . $title . '</a>';
|
||||
if ( false === $hide_if_missing_link ) {
|
||||
if ( ! $url ) {
|
||||
$link = $title;
|
||||
}
|
||||
} elseif ( ! $url ) {
|
||||
$link = '';
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass|WPML_Package|array|int $package
|
||||
* @param array<string,mixed> $args
|
||||
*/
|
||||
function show_language_selector( $package, $args = array() ) {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
$wpml_pt_meta = new WPML_Package_Translation_Metabox( $package, $wpdb, $sitepress, $args );
|
||||
echo $wpml_pt_meta->get_metabox();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass|WPML_Package|array|int $package
|
||||
* @param array<string,mixed> $args
|
||||
*/
|
||||
function show_admin_bar_language_selector( $package, $args = array() ) {
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-admin-lang-switcher.class.php';
|
||||
$this->admin_lang_switcher = new WPML_Package_Admin_Lang_Switcher( $package, $args );
|
||||
}
|
||||
|
||||
function cleanup_translation_jobs_basket_packages( $translation_jobs_basket ) {
|
||||
if ( empty( $translation_jobs_basket['packages'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $translation_jobs_basket['packages'] as $id => $data ) {
|
||||
if ( ! new WPML_Package( $id ) ) {
|
||||
TranslationProxy_Basket::delete_item_from_basket( $id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function update_translation_jobs_basket( $translation_jobs_cart, $translation_jobs_basket, $item_type ) {
|
||||
if ( $item_type == 'package' ) {
|
||||
if ( ! isset( $translation_jobs_basket[ $item_type ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$packages = $translation_jobs_basket[ $item_type ];
|
||||
if ( empty( $packages ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->cleanup_translation_jobs_basket_packages( $translation_jobs_basket );
|
||||
|
||||
global $sitepress;
|
||||
|
||||
$packages_ids = array_keys( $packages );
|
||||
|
||||
foreach ( $packages_ids as $package_id ) {
|
||||
$package = new WPML_Package( $package_id );
|
||||
if ( $package ) {
|
||||
if ( ! isset( $package->ID ) || ! $package->ID ) {
|
||||
TranslationProxy_Basket::delete_item_from_basket( $package_id, 'package' );
|
||||
continue;
|
||||
}
|
||||
|
||||
$package_source_language = $packages[ $package_id ]['from_lang'];
|
||||
$package_target_languages = $packages[ $package_id ]['to_langs'];
|
||||
$language_names = $this->languages_to_csv( $package_target_languages );
|
||||
|
||||
$final_post = array();
|
||||
|
||||
$final_post['post_title'] = $package->title;
|
||||
$final_post['post_notes'] = get_post_meta( $package->ID, '_icl_translator_note', true );
|
||||
$final_post['post_type'] = $package->kind;
|
||||
if ( isset( $package->post_status ) ) {
|
||||
$final_post['post_status'] = $package->post_status;
|
||||
}
|
||||
if ( isset( $package->post_date ) ) {
|
||||
$final_post['post_date'] = $package->post_date;
|
||||
}
|
||||
$final_post['from_lang'] = $package_source_language;
|
||||
$final_post['from_lang_string'] = ucfirst( $sitepress->get_display_language_name( $package_source_language, $sitepress->get_admin_language() ) );
|
||||
$final_post['to_langs'] = $package_target_languages;
|
||||
$final_post['to_langs_string'] = implode( ', ', $language_names );
|
||||
|
||||
$translation_jobs_cart[ $package_id ] = $final_post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $translation_jobs_cart;
|
||||
}
|
||||
|
||||
public function basket_items_types( $item_types ) {
|
||||
$item_types['package'] = 'custom';
|
||||
|
||||
return $item_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $package_target_languages
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
private function languages_to_csv( $package_target_languages ) {
|
||||
global $sitepress;
|
||||
|
||||
$language_names = array();
|
||||
foreach ( $package_target_languages as $language_code => $value ) {
|
||||
$language_names[] = ucfirst( $sitepress->get_display_language_name( $language_code, $sitepress->get_admin_language() ) );
|
||||
}
|
||||
|
||||
return $language_names;
|
||||
}
|
||||
|
||||
function is_external( $result, $type ) {
|
||||
return $result || is_a( $type, 'WPML_Package' ) || $type == 'package';
|
||||
}
|
||||
|
||||
public function get_element_type( $type, $element ) {
|
||||
if ( $this->is_a_package( $element ) ) {
|
||||
$type = 'package';
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function attributes_to_string( $attributes ) {
|
||||
$result = '';
|
||||
foreach ( $attributes as $key => $value ) {
|
||||
if ( $result ) {
|
||||
$result .= ' ';
|
||||
}
|
||||
$result .= esc_html( $key ) . '="' . esc_attr( $value ) . '"';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $kind_slug
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_package_element_type( $kind_slug ) {
|
||||
if ( is_object( $kind_slug ) ) {
|
||||
$kind_slug = $kind_slug->kind_slug;
|
||||
}
|
||||
if ( is_array( $kind_slug ) ) {
|
||||
$kind_slug = $kind_slug['kind_slug'];
|
||||
}
|
||||
|
||||
return 'package_' . $kind_slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $package
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function package_has_kind( $package ) {
|
||||
return isset( $package['kind'] ) && $package['kind'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $package
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function package_has_name( $package ) {
|
||||
return isset( $package['name'] ) && $package['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $package
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function package_has_title( $package ) {
|
||||
return isset( $package['title'] ) && $package['title'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,string> $package
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function package_has_kind_and_name( $package ) {
|
||||
return $this->package_has_kind( $package ) && $this->package_has_name( $package );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string_name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function sanitize_string_with_underscores( $string_name ) {
|
||||
return preg_replace( '/[ \[\]]+/', '_', $string_name );
|
||||
}
|
||||
|
||||
function new_external_item( $type, $package_item, $get_string_data = false ) {
|
||||
// create a new external item for the Translation Dashboard or for translation jobs
|
||||
|
||||
$package_id = $package_item['ID'];
|
||||
|
||||
$item = new stdClass();
|
||||
$item->external_type = true;
|
||||
$item->type = $type;
|
||||
$item->ID = $package_id;
|
||||
$item->post_type = $type;
|
||||
$item->post_id = 'external_' . $item->post_type . '_' . $package_item['ID'];
|
||||
$item->post_date = '';
|
||||
$item->post_status = __( 'Active', 'wpml-string-translation' );
|
||||
$item->post_title = $package_item['title'];
|
||||
$item->is_translation = false;
|
||||
|
||||
if ( $get_string_data ) {
|
||||
$item->string_data = $this->_get_package_strings( $package_item );
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
function get_package_from_external_id( $post_id ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$packages = $wpdb->get_col( "SELECT ID FROM {$wpdb->prefix}icl_string_packages WHERE ID>0" );
|
||||
|
||||
foreach ( $packages as $package_id ) {
|
||||
|
||||
$package = new WPML_Package( $package_id );
|
||||
|
||||
$test = $this->get_external_id_from_package( $package );
|
||||
if ( is_string( $post_id ) && $post_id == $test ) {
|
||||
return $package;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // not a package type
|
||||
}
|
||||
|
||||
function _get_package_strings( $package_item ) {
|
||||
global $wpdb;
|
||||
$strings = array();
|
||||
|
||||
$package_item_id = $package_item['ID'];
|
||||
$results = $wpdb->get_results( $wpdb->prepare( "SELECT name, value FROM {$wpdb->prefix}icl_strings WHERE string_package_id=%d", $package_item_id ) );
|
||||
|
||||
foreach ( $results as $result ) {
|
||||
$string_name = (bool) $package_item_id === true && strpos(
|
||||
$result->name,
|
||||
(string) $package_item_id
|
||||
) === 0
|
||||
? substr( $result->name, strlen( $package_item_id ) + 1 ) : $result->name;
|
||||
$strings[ $string_name ] = $result->value;
|
||||
}
|
||||
|
||||
// Add/update any registered strings
|
||||
if ( isset( $this->registered_strings[ $package_item_id ]['strings'] ) ) {
|
||||
foreach ( $this->registered_strings[ $package_item_id ]['strings'] as $id => $string_data ) {
|
||||
$strings[ $id ] = $string_data['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
function get_link( $item, $package_item, $anchor, $hide_empty ) {
|
||||
if ( $item == '' ) {
|
||||
$package_item = $this->get_package_from_external_id( $package_item );
|
||||
if ( ! $package_item ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$has_link = isset( $package_item->edit_link ) && $package_item->edit_link;
|
||||
if ( false === $anchor ) {
|
||||
if ( $has_link ) {
|
||||
$anchor = '<a href="' . $package_item->edit_link . '">' . $package_item['title'] . '</a>';
|
||||
} elseif ( ! $hide_empty ) {
|
||||
$anchor = $package_item['title'];
|
||||
}
|
||||
} else {
|
||||
if ( $has_link ) {
|
||||
$anchor = '<a href="' . $package_item['edit_link'] . '">' . $anchor . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$item = $anchor;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update translations
|
||||
*
|
||||
* @param int $package_id
|
||||
* @param bool $is_new - set to true for newly created form (first save without fields)
|
||||
* @param bool $needs_update - when deleting single field we do not need to change the translation status of the form
|
||||
*
|
||||
* @internal param array $item - package information
|
||||
*/
|
||||
function update_package_translations( $package_id, $is_new, $needs_update = true ) {
|
||||
|
||||
global $sitepress, $wpdb, $iclTranslationManagement;
|
||||
|
||||
$item = $this->get_package_details( $package_id );
|
||||
|
||||
$post_id = $this->get_external_id_from_package( new WPML_Package( $package_id ) );
|
||||
$post = $this->get_translatable_item( null, $post_id );
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
$default_lang = $sitepress->get_default_language();
|
||||
$icl_el_type = $this->get_package_element_type( $item );
|
||||
$trid = $sitepress->get_element_trid( $item['ID'], $icl_el_type );
|
||||
|
||||
if ( $is_new ) {
|
||||
$sitepress->set_element_language_details( $post->ID, $icl_el_type, false, $default_lang, null, false );
|
||||
|
||||
// for new package nothing more to do
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT t.translation_id, s.md5
|
||||
FROM {$wpdb->prefix}icl_translations t
|
||||
NATURAL JOIN {$wpdb->prefix}icl_translation_status s
|
||||
WHERE t.trid=%d
|
||||
AND t.source_language_code IS NOT NULL
|
||||
";
|
||||
$element_translations = $wpdb->get_results( $wpdb->prepare( $sql, $trid ) );
|
||||
|
||||
if ( ! empty( $element_translations ) ) {
|
||||
|
||||
$md5 = $iclTranslationManagement->post_md5( $post );
|
||||
|
||||
if ( $md5 != $element_translations[0]->md5 ) { // all translations need update
|
||||
|
||||
$translation_package = $iclTranslationManagement->create_translation_package( $post );
|
||||
|
||||
foreach ( $element_translations as $trans ) {
|
||||
$_prevstate = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT status, translator_id, needs_update, md5, translation_service, translation_package, timestamp, links_fixed
|
||||
FROM {$wpdb->prefix}icl_translation_status
|
||||
WHERE translation_id = %d
|
||||
",
|
||||
$trans->translation_id
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
if ( ! empty( $_prevstate ) ) {
|
||||
$data['_prevstate'] = serialize( $_prevstate );
|
||||
}
|
||||
$data = array(
|
||||
'translation_id' => $trans->translation_id,
|
||||
'translation_package' => serialize( $translation_package ),
|
||||
'md5' => $md5,
|
||||
);
|
||||
|
||||
// update only when something changed (we do not need to change status when deleting a field)
|
||||
if ( $needs_update ) {
|
||||
$data['needs_update'] = 1;
|
||||
}
|
||||
|
||||
$update_result = $iclTranslationManagement->update_translation_status( $data );
|
||||
$rid = $update_result[0];
|
||||
$this->update_icl_translate( $rid, $post );
|
||||
|
||||
// change job status only when needs update
|
||||
if ( $needs_update ) {
|
||||
$job_id = $wpdb->get_var( $wpdb->prepare( "SELECT MAX(job_id) FROM {$wpdb->prefix}icl_translate_job WHERE rid=%d GROUP BY rid", $rid ) );
|
||||
if ( $job_id ) {
|
||||
$wpdb->update( "{$wpdb->prefix}icl_translate_job", array( 'translated' => 0 ), array( 'job_id' => $job_id ), array( '%d' ), array( '%d' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions to update translations when packages are modified in admin
|
||||
*
|
||||
* @param int $rid
|
||||
* @param \stdClass $post
|
||||
*/
|
||||
|
||||
function update_icl_translate( $rid, $post ) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$job_id = $wpdb->get_var( $wpdb->prepare( "SELECT MAX(job_id) FROM {$wpdb->prefix}icl_translate_job WHERE rid=%d GROUP BY rid", $rid ) );
|
||||
$elements = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT field_type, field_data, tid, field_translate FROM {$wpdb->prefix}icl_translate
|
||||
WHERE job_id=%d",
|
||||
$job_id
|
||||
),
|
||||
OBJECT_K
|
||||
);
|
||||
|
||||
foreach ( $post->string_data as $field_type => $field_value ) {
|
||||
$field_data = base64_encode( $field_value );
|
||||
if ( ! isset( $elements[ $field_type ] ) ) {
|
||||
// insert new field
|
||||
|
||||
$data = array(
|
||||
'job_id' => $job_id,
|
||||
'content_id' => 0,
|
||||
'field_type' => $field_type,
|
||||
'field_format' => 'base64',
|
||||
'field_translate' => 1,
|
||||
'field_data' => $field_data,
|
||||
'field_data_translated' => 0,
|
||||
'field_finished' => 0,
|
||||
);
|
||||
|
||||
$wpdb->insert( $wpdb->prefix . 'icl_translate', $data );
|
||||
} elseif ( $elements[ $field_type ]->field_data != $field_data ) {
|
||||
// update field value
|
||||
$wpdb->update(
|
||||
$wpdb->prefix . 'icl_translate',
|
||||
array(
|
||||
'field_data' => $field_data,
|
||||
'field_finished' => 0,
|
||||
),
|
||||
array( 'tid' => $elements[ $field_type ]->tid )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $elements as $field_type => $el ) {
|
||||
// delete fields that are no longer present
|
||||
if ( $el->field_translate && ! isset( $post->string_data[ $field_type ] ) ) {
|
||||
$wpdb->delete( $wpdb->prefix . 'icl_translate', array( 'tid' => $el->tid ), array( '%d' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function get_package_details( $package_id ) {
|
||||
global $wpdb;
|
||||
static $cache = array();
|
||||
|
||||
if ( ! isset( $cache[ $package_id ] ) ) {
|
||||
$item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}icl_string_packages WHERE ID=%d", $package_id ), ARRAY_A );
|
||||
$cache[ $package_id ] = $item;
|
||||
}
|
||||
|
||||
return $cache[ $package_id ];
|
||||
}
|
||||
|
||||
function get_string_context_title( $context, $string_details ) {
|
||||
global $wpdb;
|
||||
|
||||
static $cache = array();
|
||||
|
||||
if ( ! isset( $cache[ $context ] ) ) {
|
||||
$package_id = $wpdb->get_var( $wpdb->prepare( "SELECT string_package_id FROM {$wpdb->prefix}icl_strings WHERE id=%d", $string_details['string_id'] ) );
|
||||
if ( $package_id ) {
|
||||
$package_details = $this->get_package_details( $package_id );
|
||||
if ( $package_details ) {
|
||||
$cache[ $context ] = $package_details->kind . ' - ' . $package_details->title;
|
||||
} else {
|
||||
$cache[ $context ] = $context;
|
||||
}
|
||||
} else {
|
||||
$cache[ $context ] = $context;
|
||||
}
|
||||
}
|
||||
|
||||
return $cache[ $context ];
|
||||
}
|
||||
|
||||
function get_string_title( $title, $string_details ) {
|
||||
global $wpdb;
|
||||
|
||||
$string_title = $wpdb->get_var( $wpdb->prepare( "SELECT title FROM {$wpdb->prefix}icl_strings WHERE id=%d", $string_details['string_id'] ) );
|
||||
if ( $string_title ) {
|
||||
return $string_title;
|
||||
} else {
|
||||
return $title;
|
||||
}
|
||||
}
|
||||
|
||||
function _get_post_translations( $package ) {
|
||||
global $sitepress;
|
||||
|
||||
if ( is_object( $package ) ) {
|
||||
$package = get_object_vars( $package );
|
||||
}
|
||||
|
||||
$element_type = $this->get_package_element_type( $package['kind_slug'] );
|
||||
$trid = $sitepress->get_element_trid( $package['ID'], $element_type );
|
||||
|
||||
return $sitepress->get_element_translations( $trid, $element_type );
|
||||
}
|
||||
|
||||
function _is_translation_in_progress( $package ) {
|
||||
global $wpdb;
|
||||
|
||||
$post_translations = self::_get_post_translations( $package );
|
||||
|
||||
foreach ( $post_translations as $lang => $translation ) {
|
||||
$res = $wpdb->get_row( $wpdb->prepare( "SELECT status, needs_update, md5 FROM {$wpdb->prefix}icl_translation_status WHERE translation_id=%d", $translation->translation_id ) );
|
||||
if ( $res && $res->status == ICL_TM_IN_PROGRESS ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function _delete_translation_job( $package_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$package = $this->get_package_details( $package_id );
|
||||
|
||||
$post_translations = $this->_get_post_translations( $package );
|
||||
foreach ( $post_translations as $lang => $translation ) {
|
||||
$rid = $wpdb->get_var( $wpdb->prepare( "SELECT rid FROM {$wpdb->prefix}icl_translation_status WHERE translation_id=%d", $translation->translation_id ) );
|
||||
if ( $rid ) {
|
||||
$job_id = $wpdb->get_var( $wpdb->prepare( "SELECT job_id FROM {$wpdb->prefix}icl_translate_job WHERE rid=%d", $rid ) );
|
||||
|
||||
if ( $job_id ) {
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}icl_translate_job WHERE job_id=%d", $job_id ) );
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}icl_translate WHERE job_id=%d", $job_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function add_to_basket( $data ) {
|
||||
if ( isset( $data['tr_action'] ) ) {
|
||||
$posts_ids = TranslationProxy_Basket::get_elements_ids( $data, 'package' );
|
||||
|
||||
foreach ( $posts_ids as $id ) {
|
||||
$post_id = $id;
|
||||
$source_language = $data['translate_from'];
|
||||
$target_languages = $data['tr_action'];
|
||||
foreach ( $target_languages as $translate_to => $translation_action ) {
|
||||
$package = new WPML_Package( $post_id );
|
||||
$tm = new WPML_Package_TM( $package );
|
||||
$tm->add_package_to_basket( $translation_action, $source_language, $translate_to );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _no_wpml_warning() {
|
||||
?>
|
||||
<div class="message error">
|
||||
<p>
|
||||
<?php printf( __( 'WPML Package Translation is enabled but not effective. It requires <a href="%s">WPML</a>, String Translation and Translation Management in order to work.', 'wpml-string-translation' ), 'http://wpml.org/' ); ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function tm_dashboard_sql_filter( $sql ) {
|
||||
global $wpdb;
|
||||
|
||||
$sql .= " AND i.element_id NOT IN ( SELECT ID FROM {$wpdb->prefix}icl_string_packages WHERE post_id IS NOT NULL AND element_type = 'package_layout' )";
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_refresh_required() {
|
||||
$refresh_required = get_option( 'wpml-package-translation-refresh-required', 'yes' );
|
||||
return 'yes' === $refresh_required || '1' === $refresh_required;
|
||||
}
|
||||
|
||||
private function set_refresh_not_required() {
|
||||
update_option( 'wpml-package-translation-refresh-required', 'no', false );
|
||||
}
|
||||
|
||||
public function save_package_translations( $element_type_prefix, $job, $decoder ) {
|
||||
if ( $element_type_prefix === 'package' ) {
|
||||
$element_type_prefix = $this->get_package_type_prefix( $element_type_prefix, $job->original_doc_id );
|
||||
|
||||
foreach ( $job->elements as $field ) {
|
||||
if ( $field->field_translate ) {
|
||||
$string_id = icl_st_is_registered_string( $element_type_prefix, $field->field_type );
|
||||
if ( ! $string_id ) {
|
||||
icl_register_string( $element_type_prefix, $field->field_type, $decoder( $field->field_data, $field->field_format ) );
|
||||
$string_id = icl_st_is_registered_string( $element_type_prefix, $field->field_type );
|
||||
}
|
||||
if ( $string_id ) {
|
||||
icl_add_string_translation( $string_id, $job->language_code, $decoder( $field->field_data_translated, $field->field_format ), ICL_TM_COMPLETE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,537 @@
|
||||
<?php
|
||||
|
||||
class WPML_Package {
|
||||
|
||||
const CACHE_GROUP = 'WPML_Package';
|
||||
|
||||
public $ID;
|
||||
public $view_link;
|
||||
public $edit_link;
|
||||
public $is_translation;
|
||||
public $string_data;
|
||||
public $title;
|
||||
public $new_title;
|
||||
public $kind_slug;
|
||||
public $kind;
|
||||
public $trid;
|
||||
public $name;
|
||||
public $translation_element_type;
|
||||
public $post_id;
|
||||
|
||||
private $element_type_prefix;
|
||||
|
||||
/**
|
||||
* @param stdClass|WPML_Package|array|int $data_item
|
||||
*/
|
||||
function __construct( $data_item ) {
|
||||
$this->element_type_prefix = 'package';
|
||||
$this->view_link = '';
|
||||
$this->edit_link = '';
|
||||
$this->post_id = null;
|
||||
if ( $data_item ) {
|
||||
if ( is_object( $data_item ) ) {
|
||||
$data_item = get_object_vars( $data_item );
|
||||
}
|
||||
if ( is_numeric( $data_item ) ) {
|
||||
$data_item = $this->init_from_id( $data_item, ARRAY_A );
|
||||
}
|
||||
if ( isset( $data_item['title'] ) ) {
|
||||
$this->new_title = $data_item['title'];
|
||||
}
|
||||
if ( $data_item && is_array( $data_item ) ) {
|
||||
$this->init_from_array( $data_item );
|
||||
}
|
||||
$this->new_title = $this->new_title != $this->title ? $this->new_title : null;
|
||||
}
|
||||
}
|
||||
|
||||
private function init_from_id( $id, $output = OBJECT ) {
|
||||
global $wpdb;
|
||||
|
||||
$packages_query = "SELECT * FROM {$wpdb->prefix}icl_string_packages WHERE id=%s";
|
||||
$packages_prepared = $wpdb->prepare( $packages_query, $id );
|
||||
$package = $wpdb->get_row( $packages_prepared, $output );
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
public function __get( $property ) {
|
||||
if ( $property == 'id' ) {
|
||||
_deprecated_argument( 'id', '0.0.2', "Property 'id' is deprecated. Please use 'ID'." );
|
||||
|
||||
return $this->ID;
|
||||
}
|
||||
if ( $property == 'post_id' ) {
|
||||
return $this->ID;
|
||||
}
|
||||
if ( $property == 'post_title' ) {
|
||||
return $this->title;
|
||||
}
|
||||
if ( $property == 'post_type' ) {
|
||||
return $this->kind_slug;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function __set( $property, $value ) {
|
||||
if ( $property == 'id' ) {
|
||||
_deprecated_argument( 'id', '0.0.2', "Property 'id' is deprecated. Please use 'ID'." );
|
||||
$this->ID = $value;
|
||||
} else {
|
||||
$this->$property = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function __isset( $property ) {
|
||||
if ( $property == 'id' ) {
|
||||
return isset( $this->ID );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __unset( $property ) {
|
||||
if ( $property == 'id' ) {
|
||||
unset( $this->$property );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_translation_element_type() {
|
||||
return $this->translation_element_type;
|
||||
}
|
||||
|
||||
public function get_package_post_id() {
|
||||
return $this->get_element_type_prefix() . '_' . $this->kind_slug . '_' . $this->ID;
|
||||
}
|
||||
|
||||
public function get_element_type_prefix() {
|
||||
return $this->element_type_prefix;
|
||||
}
|
||||
|
||||
public function set_package_post_data() {
|
||||
$this->translation_element_type = $this->element_type_prefix . '_' . $this->kind_slug;
|
||||
$this->update_strings_data();
|
||||
}
|
||||
|
||||
public function update_strings_data() {
|
||||
$strings = [];
|
||||
$package_id = $this->ID;
|
||||
if ( $package_id ) {
|
||||
$results = $this->get_package_strings();
|
||||
foreach ( $results as $result ) {
|
||||
$string_name = $this->get_package_string_name_from_st_name( $result );
|
||||
$strings[ $string_name ] = $result->value;
|
||||
}
|
||||
|
||||
$this->string_data = $strings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $refresh
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_package_strings( $refresh = false ) {
|
||||
global $wpdb;
|
||||
$package_id = $this->ID;
|
||||
$results = false;
|
||||
if ( $package_id ) {
|
||||
|
||||
$cache = new WPML_WP_Cache( self::CACHE_GROUP );
|
||||
$cache_key = 'strings:' . $package_id;
|
||||
$found = false;
|
||||
|
||||
$results = $cache->get( $cache_key, $found );
|
||||
if ( ! $found || $refresh ) {
|
||||
$results_query = "
|
||||
SELECT id, name, value, wrap_tag, type, title
|
||||
FROM {$wpdb->prefix}icl_strings
|
||||
WHERE string_package_id=%d
|
||||
ORDER BY location, id ASC";
|
||||
$results_prepare = $wpdb->prepare( $results_query, $package_id );
|
||||
$results = $wpdb->get_results( $results_prepare );
|
||||
|
||||
$cache->set( $cache_key, $results );
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function set_strings_language( $language_code ) {
|
||||
global $wpdb;
|
||||
$package_id = $this->ID;
|
||||
if ( $package_id ) {
|
||||
$update_query = "UPDATE {$wpdb->prefix}icl_strings SET language=%s WHERE string_package_id=%d";
|
||||
$update_prepare = $wpdb->prepare( $update_query, $language_code, $package_id );
|
||||
$wpdb->query( $update_prepare );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $result
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_package_string_name_from_st_name( $result ) {
|
||||
|
||||
// package string name is the same as the string name.
|
||||
return $result->name;
|
||||
}
|
||||
|
||||
private function sanitize_attributes() {
|
||||
if ( isset( $this->name ) ) {
|
||||
$this->name = $this->sanitize_string_name( $this->name );
|
||||
}
|
||||
if ( ( ! isset( $this->title ) || $this->title === '' ) && isset( $this->name ) ) {
|
||||
$this->title = $this->name;
|
||||
}
|
||||
if ( ! isset( $this->edit_link ) ) {
|
||||
$this->edit_link = '';
|
||||
}
|
||||
|
||||
$this->sanitize_kind();
|
||||
}
|
||||
|
||||
public function create_new_package_record() {
|
||||
$this->sanitize_attributes();
|
||||
|
||||
$package_id = $this->package_exists();
|
||||
if ( ! $package_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$data = array(
|
||||
'kind_slug' => $this->kind_slug,
|
||||
'kind' => $this->kind,
|
||||
'name' => $this->name,
|
||||
'title' => $this->title,
|
||||
'edit_link' => $this->edit_link,
|
||||
'view_link' => $this->view_link,
|
||||
'post_id' => $this->post_id,
|
||||
);
|
||||
$wpdb->insert( $wpdb->prefix . 'icl_string_packages', $data );
|
||||
$package_id = $wpdb->insert_id;
|
||||
|
||||
$this->ID = $package_id;
|
||||
}
|
||||
|
||||
return $package_id;
|
||||
}
|
||||
|
||||
public function update_package_record() {
|
||||
$result = false;
|
||||
|
||||
if ( $this->ID ) {
|
||||
global $wpdb;
|
||||
|
||||
$update_data = array(
|
||||
'kind_slug' => $this->kind_slug,
|
||||
'kind' => $this->kind,
|
||||
'name' => $this->name,
|
||||
'title' => $this->title,
|
||||
'edit_link' => $this->edit_link,
|
||||
'view_link' => $this->view_link,
|
||||
);
|
||||
$update_where = array(
|
||||
'ID' => $this->ID,
|
||||
);
|
||||
$result = $wpdb->update( $wpdb->prefix . 'icl_string_packages', $update_data, $update_where );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function get_package_id() {
|
||||
return $this->ID;
|
||||
}
|
||||
|
||||
public function sanitize_string_name( $string_name ) {
|
||||
$string_name = preg_replace( '/[ \[\]]+/', '-', $string_name );
|
||||
|
||||
return $string_name;
|
||||
}
|
||||
|
||||
function translate_string( $string_value, $sanitized_string_name ) {
|
||||
$package_id = $this->get_package_id();
|
||||
|
||||
if ( $package_id ) {
|
||||
$sanitized_string_name = $this->sanitize_string_name( $sanitized_string_name );
|
||||
|
||||
$string_context = $this->get_string_context_from_package();
|
||||
|
||||
$string_name = $sanitized_string_name;
|
||||
|
||||
return icl_translate( $string_context, $string_name, $string_value );
|
||||
} else {
|
||||
return $string_value;
|
||||
}
|
||||
}
|
||||
|
||||
function get_string_context_from_package() {
|
||||
return $this->kind_slug . '-' . $this->name;
|
||||
}
|
||||
|
||||
public function get_string_id_from_package( $string_name, $string_value ) {
|
||||
$package_id = $this->get_package_id();
|
||||
$string_context = $this->get_string_context_from_package();
|
||||
|
||||
$string_data = array(
|
||||
'context' => $string_context,
|
||||
'name' => $string_name,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param int|null $default
|
||||
* @param array $string_data {
|
||||
*
|
||||
* @type string $context
|
||||
* @type string $name Optional
|
||||
* }
|
||||
*/
|
||||
$string_id = apply_filters( 'wpml_string_id', null, $string_data );
|
||||
|
||||
if ( ! $string_id ) {
|
||||
$string_id = icl_register_string( $string_context, $string_name, $string_value, null, $this->get_package_language() );
|
||||
}
|
||||
|
||||
return $string_id;
|
||||
}
|
||||
|
||||
function get_translated_strings( $strings ) {
|
||||
$package_id = $this->get_package_id();
|
||||
|
||||
if ( $package_id ) {
|
||||
$results = $this->get_package_strings();
|
||||
|
||||
foreach ( $results as $result ) {
|
||||
$translations = icl_get_string_translations_by_id( $result->id );
|
||||
if ( ! empty( $translations ) ) {
|
||||
$string_name = $this->get_package_string_name_from_st_name( $result );
|
||||
$strings[ $string_name ] = $translations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
function set_translated_strings( $translations ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->sanitize_attributes();
|
||||
$package_id = $this->get_package_id();
|
||||
|
||||
if ( $package_id ) {
|
||||
foreach ( $translations as $string_name => $languages ) {
|
||||
$string_id_query = "SELECT id FROM {$wpdb->prefix}icl_strings WHERE name='%s'";
|
||||
$string_id_prepare = $wpdb->prepare( $string_id_query, $string_name );
|
||||
$string_id = $wpdb->get_var( $string_id_prepare );
|
||||
foreach ( $languages as $language_code => $language_data ) {
|
||||
icl_add_string_translation( $string_id, $language_code, $language_data['value'], $language_data['status'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function init_from_array( $args ) {
|
||||
foreach ( $args as $key => $value ) {
|
||||
if ( 'id' == $key ) {
|
||||
$key = 'ID';
|
||||
}
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
$this->sanitize_attributes();
|
||||
|
||||
if ( $this->package_id_exists() || $this->package_name_and_kind_exists() ) {
|
||||
$this->set_package_from_db();
|
||||
}
|
||||
$this->set_package_post_data();
|
||||
}
|
||||
|
||||
public function has_kind_and_name() {
|
||||
return ( isset( $this->kind ) && isset( $this->name ) && $this->kind && $this->name );
|
||||
}
|
||||
|
||||
private function set_package_from_db() {
|
||||
$package = false;
|
||||
if ( $this->package_id_exists() ) {
|
||||
$package = $this->get_package_from_id();
|
||||
} elseif ( $this->package_name_and_kind_exists() ) {
|
||||
$package = $this->get_package_from_name_and_kind();
|
||||
}
|
||||
if ( $package ) {
|
||||
$this->object_to_package( $package );
|
||||
}
|
||||
$this->sanitize_kind();
|
||||
}
|
||||
|
||||
private function get_package_from_id() {
|
||||
$result = false;
|
||||
if ( $this->has_id() ) {
|
||||
global $wpdb;
|
||||
|
||||
$package_query = "SELECT * FROM {$wpdb->prefix}icl_string_packages WHERE ID=%d";
|
||||
$package_prepared = $wpdb->prepare( $package_query, array( $this->ID ) );
|
||||
|
||||
$result = $wpdb->get_row( $package_prepared );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function get_package_from_name_and_kind() {
|
||||
global $wpdb;
|
||||
|
||||
$cache = new WPML_WP_Cache( self::CACHE_GROUP );
|
||||
$cache_key = 'name-kind:' . $this->kind_slug . $this->name;
|
||||
$found = false;
|
||||
|
||||
$result = $cache->get( $cache_key, $found );
|
||||
if ( ! $found ) {
|
||||
|
||||
$package_query = "SELECT * FROM {$wpdb->prefix}icl_string_packages WHERE kind_slug=%s AND name=%s";
|
||||
$package_prepared = $wpdb->prepare( $package_query, array( $this->kind_slug, $this->name ) );
|
||||
|
||||
$result = $wpdb->get_row( $package_prepared );
|
||||
|
||||
if ( $result ) {
|
||||
$cache->set( $cache_key, $result );
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function package_name_and_kind_exists() {
|
||||
$result = false;
|
||||
if ( $this->has_kind_and_name() ) {
|
||||
$result = (bool) $this->get_package_from_name_and_kind();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function package_id_exists() {
|
||||
$result = false;
|
||||
if ( $this->has_id() ) {
|
||||
global $wpdb;
|
||||
|
||||
$package_query = "SELECT ID FROM {$wpdb->prefix}icl_string_packages WHERE ID=%d";
|
||||
$package_prepared = $wpdb->prepare( $package_query, array( $this->ID ) );
|
||||
|
||||
$result = $wpdb->get_var( $package_prepared );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function package_exists() {
|
||||
$existing_package = false;
|
||||
if ( $this->has_id() ) {
|
||||
$existing_package = $this->package_id_exists();
|
||||
} elseif ( $this->has_kind_and_name() ) {
|
||||
$existing_package = $this->package_name_and_kind_exists();
|
||||
}
|
||||
|
||||
return $existing_package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function has_id() {
|
||||
return isset( $this->ID ) && $this->ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $package
|
||||
*/
|
||||
private function object_to_package( $package ) {
|
||||
$this->ID = $package->ID;
|
||||
$this->kind_slug = $package->kind_slug;
|
||||
$this->kind = $package->kind;
|
||||
$this->name = $package->name;
|
||||
$this->title = $package->title;
|
||||
$this->edit_link = $package->edit_link;
|
||||
$this->view_link = $package->view_link;
|
||||
}
|
||||
|
||||
private function get_kind_from_slug() {
|
||||
global $wpdb;
|
||||
if ( $this->kind_slug ) {
|
||||
$kinds_query = "SELECT kind FROM {$wpdb->prefix}icl_string_packages WHERE kind_slug=%s GROUP BY kind";
|
||||
$kinds_prepared = $wpdb->prepare( $kinds_query, $this->kind_slug );
|
||||
$kinds = $wpdb->get_col( $kinds_prepared );
|
||||
if ( count( $kinds ) > 1 ) {
|
||||
throw new WPML_Package_Exception( 'error', 'Package contains multiple kinds' );
|
||||
}
|
||||
if ( $kinds ) {
|
||||
return $kinds[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function sanitize_kind() {
|
||||
if ( isset( $this->kind ) && ( ! isset( $this->kind_slug ) || trim( $this->kind_slug ) === '' ) ) {
|
||||
$this->kind_slug = sanitize_title_with_dashes( $this->kind );
|
||||
}
|
||||
if ( $this->kind == $this->kind_slug ) {
|
||||
$this->kind = $this->get_kind_from_slug();
|
||||
}
|
||||
}
|
||||
|
||||
public function get_package_element_type() {
|
||||
return 'package_' . $this->kind_slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_package_language() {
|
||||
global $sitepress;
|
||||
|
||||
if ( $this->post_id ) {
|
||||
$details = null;
|
||||
$post = get_post( $this->post_id );
|
||||
|
||||
if ( $post ) {
|
||||
$details = $sitepress->get_element_language_details( $this->post_id, 'post_' . $post->post_type );
|
||||
}
|
||||
} else {
|
||||
$element_type = $this->get_package_element_type();
|
||||
$details = $sitepress->get_element_language_details( $this->ID, $element_type );
|
||||
}
|
||||
|
||||
if ( $details ) {
|
||||
return $details->language_code;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function are_all_strings_included( $strings ) {
|
||||
// check to see if all the strings in this package are present in $strings
|
||||
$package_strings = $this->get_package_strings();
|
||||
if ( is_array( $package_strings ) ) {
|
||||
foreach ( $package_strings as $string ) {
|
||||
if ( ! in_array( $string->id, $strings ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function flush_cache() {
|
||||
$cache = new WPML_WP_Cache( self::CACHE_GROUP );
|
||||
$cache->flush_group_cache();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*globals jQuery, ajaxurl*/
|
||||
/*jshint browser:true, devel:true*/
|
||||
|
||||
var WPML_Package_Translation = WPML_Package_Translation || {};
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
WPML_Package_Translation.ManagementPage = function () {
|
||||
var self = this;
|
||||
|
||||
self.init = function () {
|
||||
jQuery('.js_package_all_cb').on('change', self.check_uncheck_all);
|
||||
jQuery('.js_package_row_cb').on('change', self.enable_disable_delete);
|
||||
jQuery('#delete_packages').on('click', self.delete_selected_packages);
|
||||
jQuery('#package_kind_filter').on('change', self.filter_by_kind);
|
||||
};
|
||||
|
||||
self.check_uncheck_all = function () {
|
||||
var package_all_cb = jQuery('.js_package_all_cb').first();
|
||||
|
||||
var checked = package_all_cb.prop('checked');
|
||||
jQuery('.js_package_row_cb').each(
|
||||
function () {
|
||||
if (!jQuery(this).is(':disabled')) {
|
||||
jQuery(this).prop('checked', checked);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
self.enable_disable_delete();
|
||||
};
|
||||
|
||||
self.enable_disable_delete = function () {
|
||||
var enable = jQuery('.js_package_row_cb:checked:visible').length !== 0;
|
||||
|
||||
jQuery('#delete_packages').prop('disabled', !enable);
|
||||
};
|
||||
|
||||
self.delete_selected_packages = function () {
|
||||
|
||||
if (confirm(jQuery('.js-delete-confirm-message').html())) {
|
||||
jQuery('#delete_packages').prop('disabled', true);
|
||||
jQuery('.spinner').css( 'float', 'none' ).addClass( 'is-active' );
|
||||
|
||||
var selected = jQuery('.js_package_row_cb:checked:visible');
|
||||
|
||||
var packages = [];
|
||||
|
||||
selected.each(
|
||||
function () {
|
||||
packages.push(jQuery(this).val());
|
||||
}
|
||||
);
|
||||
|
||||
var data = {
|
||||
action: 'wpml_delete_packages',
|
||||
wpnonce: jQuery('#wpml_package_nonce').attr('value'),
|
||||
packages: packages
|
||||
};
|
||||
|
||||
jQuery.ajax(
|
||||
{
|
||||
url: ajaxurl,
|
||||
type: 'post',
|
||||
data: data,
|
||||
success: function () {
|
||||
selected.each(
|
||||
function () {
|
||||
var package_row = jQuery(this).closest('.js_package');
|
||||
package_row.fadeOut(
|
||||
1000, function () {
|
||||
jQuery(this).remove();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
jQuery('.spinner').removeClass( 'is-active' );
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
self.all_selected = function () {
|
||||
var kind_slug = jQuery('#package_kind_filter').val();
|
||||
return kind_slug === '-1';
|
||||
};
|
||||
|
||||
self.filter_by_kind = function () {
|
||||
var kind_slug = jQuery('#package_kind_filter').val();
|
||||
var icl_package_translations = jQuery('#icl_package_translations');
|
||||
var icl_package_translations_body = icl_package_translations.find('tbody');
|
||||
if (self.all_selected()) {
|
||||
icl_package_translations_body.find('tr').show();
|
||||
} else {
|
||||
icl_package_translations_body.find('tr').hide();
|
||||
icl_package_translations_body.find('tr.js_package.js_package_' + kind_slug).show();
|
||||
}
|
||||
self.enable_disable_delete();
|
||||
};
|
||||
|
||||
self.init();
|
||||
};
|
||||
|
||||
jQuery(
|
||||
function () {
|
||||
WPML_Package_Translation.management_page = new WPML_Package_Translation.ManagementPage();
|
||||
}
|
||||
);
|
||||
|
||||
}());
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*
|
||||
WPML Package Translation
|
||||
This is now part of String Translation.
|
||||
*/
|
||||
|
||||
if ( defined( 'WPML_PACKAGE_TRANSLATION' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
define( 'WPML_PACKAGE_TRANSLATION', '0.0.2' );
|
||||
define( 'WPML_PACKAGE_TRANSLATION_PATH', dirname( __FILE__ ) );
|
||||
define( 'WPML_PACKAGE_TRANSLATION_URL', WPML_ST_URL . '/inc/' . basename( WPML_PACKAGE_TRANSLATION_PATH ) );
|
||||
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-constants.php';
|
||||
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-exception.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-helper.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-ui.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-html-packages.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-metabox.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-st.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-tm-jobs.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation-tm.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package.class.php';
|
||||
require WPML_PACKAGE_TRANSLATION_PATH . '/inc/wpml-package-translation.class.php';
|
||||
|
||||
$WPML_package_translation = new WPML_Package_Translation();
|
||||
$WPML_Package_Translation_UI = new WPML_Package_Translation_UI();
|
||||
$WPML_Package_Translation_HTML_Packages = new WPML_Package_Translation_HTML_Packages();
|
||||
Reference in New Issue
Block a user