first commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Troubleshooting;
|
||||
|
||||
class AssignTranslationStatusToDuplicates {
|
||||
|
||||
public static function run() {
|
||||
global $sitepress, $iclTranslationManagement;
|
||||
|
||||
$active_language_codes = array_keys( $sitepress->get_active_languages() );
|
||||
$duplicated_posts = self::get_duplicates();
|
||||
$updated_items = 0;
|
||||
foreach ( $duplicated_posts as $original_post_id ) {
|
||||
$element_type = 'post_' . get_post_type( $original_post_id );
|
||||
$trid = $sitepress->get_element_trid( $original_post_id, $element_type );
|
||||
$element_language_details = $sitepress->get_element_translations( $trid, $element_type );
|
||||
$item_updated = false;
|
||||
foreach ( $active_language_codes as $code ) {
|
||||
if ( ! isset( $element_language_details[ $code ] ) ) {
|
||||
continue;
|
||||
}
|
||||
/** @var \stdClass $element_translation */
|
||||
$element_translation = $element_language_details[ $code ];
|
||||
if ( ! isset( $element_translation->element_id ) || $element_translation->original ) {
|
||||
continue;
|
||||
}
|
||||
$translation = $iclTranslationManagement->get_element_translation(
|
||||
$element_translation->element_id,
|
||||
$code,
|
||||
$element_type
|
||||
);
|
||||
if ( ! $translation ) {
|
||||
$status_helper = wpml_get_post_status_helper();
|
||||
$status_helper->set_status( $element_translation->element_id, ICL_TM_DUPLICATE );
|
||||
$item_updated = true;
|
||||
}
|
||||
}
|
||||
if ( $item_updated ) {
|
||||
$updated_items ++;
|
||||
}
|
||||
if ( $updated_items >= 20 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $updated_items;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private static function get_duplicates() {
|
||||
global $wpdb;
|
||||
|
||||
$duplicated_posts_sql = "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key='_icl_lang_duplicate_of' AND meta_value<>'' GROUP BY meta_value;";
|
||||
return $wpdb->get_col( $duplicated_posts_sql );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\Troubleshooting;
|
||||
|
||||
use WPML\LIB\WP\Nonce;
|
||||
use WPML\Core\WP\App\Resources;
|
||||
use WPML\TM\ATE\AutoTranslate\Endpoint\CancelJobs;
|
||||
use WPML\TM\ATE\Hooks\JobActionsFactory;
|
||||
|
||||
class Loader implements \IWPML_Backend_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
|
||||
add_action( 'after_setup_complete_troubleshooting_functions', [ $this, 'render' ], 7 );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueueScripts' ] );
|
||||
}
|
||||
|
||||
public function render() {
|
||||
echo '<div id="wpml-troubleshooting-container" style="margin: 5px 0; width: 350px;"></div>';
|
||||
}
|
||||
|
||||
public function enqueueScripts( $hook ) {
|
||||
if ( WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' === $hook ) {
|
||||
$enqueue = Resources::enqueueApp( 'troubleshooting' );
|
||||
$enqueue(
|
||||
[
|
||||
'name' => 'troubleshooting',
|
||||
'data' => [
|
||||
'refreshLicense' => [
|
||||
'nonce' => Nonce::create( 'update_site_key_wpml' ),
|
||||
],
|
||||
'endpoints' => [
|
||||
'cancelJobs' => CancelJobs::class,
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
class WPML_Debug_Information {
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
public $wpdb;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
protected $sitepress;
|
||||
|
||||
/**
|
||||
* @param wpdb $wpdb
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( $wpdb, $sitepress ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
$info = array( 'core', 'plugins', 'theme', 'extra-debug' );
|
||||
|
||||
$output = array();
|
||||
foreach ( $info as $type ) {
|
||||
switch ( $type ) {
|
||||
case 'core':
|
||||
$output['core'] = $this->get_core_info();
|
||||
break;
|
||||
case 'plugins':
|
||||
$output['plugins'] = $this->get_plugins_info();
|
||||
break;
|
||||
case 'theme':
|
||||
$output['theme'] = $this->get_theme_info();
|
||||
break;
|
||||
case 'extra-debug':
|
||||
$output['extra-debug'] = apply_filters( 'icl_get_extra_debug_info', array() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function get_core_info() {
|
||||
|
||||
$core = array(
|
||||
'Wordpress' => array(
|
||||
'Multisite' => is_multisite() ? 'Yes' : 'No',
|
||||
'SiteURL' => site_url(),
|
||||
'HomeURL' => home_url(),
|
||||
'Version' => get_bloginfo( 'version' ),
|
||||
'PermalinkStructure' => get_option( 'permalink_structure' ),
|
||||
'PostTypes' => implode( ', ', get_post_types( '', 'names' ) ),
|
||||
'PostStatus' => implode( ', ', get_post_stati() ),
|
||||
'RestEnabled' => wpml_is_rest_enabled() ? 'Yes' : 'No',
|
||||
),
|
||||
'Server' => array(
|
||||
'jQueryVersion' => wp_script_is( 'jquery', 'registered' ) ? $GLOBALS['wp_scripts']->registered['jquery']->ver : __( 'n/a', 'bbpress' ),
|
||||
'PHPVersion' => $this->sitepress->get_wp_api()->phpversion(),
|
||||
'MySQLVersion' => $this->wpdb->db_version(),
|
||||
'ServerSoftware' => $_SERVER['SERVER_SOFTWARE'],
|
||||
),
|
||||
'PHP' => array(
|
||||
'MemoryLimit' => ini_get( 'memory_limit' ),
|
||||
'WP Memory Limit' => WP_MEMORY_LIMIT,
|
||||
'UploadMax' => ini_get( 'upload_max_filesize' ),
|
||||
'PostMax' => ini_get( 'post_max_size' ),
|
||||
'TimeLimit' => ini_get( 'max_execution_time' ),
|
||||
'MaxInputVars' => ini_get( 'max_input_vars' ),
|
||||
'MBString' => $this->sitepress->get_wp_api()->extension_loaded( 'mbstring' ),
|
||||
'libxml' => $this->sitepress->get_wp_api()->extension_loaded( 'libxml' ),
|
||||
),
|
||||
);
|
||||
|
||||
return $core;
|
||||
}
|
||||
|
||||
function get_plugins_info() {
|
||||
|
||||
$plugins = $this->sitepress->get_wp_api()->get_plugins();
|
||||
$active_plugins = $this->sitepress->get_wp_api()->get_option( 'active_plugins' );
|
||||
$active_plugins_info = array();
|
||||
|
||||
foreach ( $active_plugins as $plugin ) {
|
||||
if ( isset( $plugins[ $plugin ] ) ) {
|
||||
unset( $plugins[ $plugin ]['Description'] );
|
||||
$active_plugins_info[ $plugin ] = $plugins[ $plugin ];
|
||||
}
|
||||
}
|
||||
|
||||
$mu_plugins = get_mu_plugins();
|
||||
|
||||
$dropins = get_dropins();
|
||||
|
||||
$output = array(
|
||||
'active_plugins' => $active_plugins_info,
|
||||
'mu_plugins' => $mu_plugins,
|
||||
'dropins' => $dropins,
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function get_theme_info() {
|
||||
|
||||
if ( $this->sitepress->get_wp_api()->get_bloginfo( 'version' ) < '3.4' ) {
|
||||
/** @var \WP_Theme $current_theme */
|
||||
$current_theme = get_theme_data( get_stylesheet_directory() . '/style.css' );
|
||||
$theme = $current_theme;
|
||||
unset( $theme['Description'] );
|
||||
unset( $theme['Status'] );
|
||||
unset( $theme['Tags'] );
|
||||
} else {
|
||||
$theme = array(
|
||||
'Name' => $this->sitepress->get_wp_api()->get_theme_name(),
|
||||
'ThemeURI' => $this->sitepress->get_wp_api()->get_theme_URI(),
|
||||
'Author' => $this->sitepress->get_wp_api()->get_theme_author(),
|
||||
'AuthorURI' => $this->sitepress->get_wp_api()->get_theme_authorURI(),
|
||||
'Template' => $this->sitepress->get_wp_api()->get_theme_template(),
|
||||
'Version' => $this->sitepress->get_wp_api()->get_theme_version(),
|
||||
'TextDomain' => $this->sitepress->get_wp_api()->get_theme_textdomain(),
|
||||
'DomainPath' => $this->sitepress->get_wp_api()->get_theme_domainpath(),
|
||||
'ParentName' => $this->sitepress->get_wp_api()->get_theme_parent_name(),
|
||||
);
|
||||
}
|
||||
|
||||
return $theme;
|
||||
}
|
||||
|
||||
function do_json_encode( $data ) {
|
||||
$json_options = 0;
|
||||
if ( defined( 'JSON_HEX_TAG' ) ) {
|
||||
$json_options += JSON_HEX_TAG;
|
||||
}
|
||||
if ( defined( 'JSON_HEX_APOS' ) ) {
|
||||
$json_options += JSON_HEX_APOS;
|
||||
}
|
||||
if ( defined( 'JSON_HEX_QUOT' ) ) {
|
||||
$json_options += JSON_HEX_QUOT;
|
||||
}
|
||||
if ( defined( 'JSON_HEX_AMP' ) ) {
|
||||
$json_options += JSON_HEX_AMP;
|
||||
}
|
||||
if ( defined( 'JSON_UNESCAPED_UNICODE' ) ) {
|
||||
$json_options += JSON_UNESCAPED_UNICODE;
|
||||
}
|
||||
|
||||
if ( version_compare( $this->sitepress->get_wp_api()->phpversion(), '5.3.0', '<' ) ) {
|
||||
$json_data = wp_json_encode( $data );
|
||||
} else {
|
||||
$json_data = wp_json_encode( $data, $json_options );
|
||||
}
|
||||
|
||||
return $json_data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
class WPML_Fix_Type_Assignments extends WPML_WPDB_And_SP_User {
|
||||
|
||||
/**
|
||||
* WPML_Fix_Type_Assignments constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( $sitepress ) {
|
||||
$wpdb = $sitepress->wpdb();
|
||||
parent::__construct( $wpdb, $sitepress );
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs various database repair and cleanup actions on icl_translations.
|
||||
*
|
||||
* @return int Number of rows in icl_translations that were fixed
|
||||
*/
|
||||
public function run() {
|
||||
$rows_fixed = $this->fix_broken_duplicate_rows();
|
||||
$rows_fixed += $this->fix_missing_original();
|
||||
$rows_fixed += $this->fix_wrong_source_language();
|
||||
$rows_fixed += $this->fix_broken_taxonomy_assignments();
|
||||
$rows_fixed += $this->fix_broken_post_assignments();
|
||||
$rows_fixed += $this->fix_broken_type_assignments();
|
||||
icl_cache_clear();
|
||||
wp_cache_init();
|
||||
|
||||
return $rows_fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes rows from icl_translations that are duplicated in terms of their
|
||||
* element id and within their meta type ( post,taxonomy,package ...),
|
||||
* with the duplicate actually being of the correct type.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_broken_duplicate_rows() {
|
||||
|
||||
$rows_fixed = $this->wpdb->query(
|
||||
"
|
||||
DELETE t
|
||||
FROM {$this->wpdb->prefix}icl_translations i
|
||||
JOIN {$this->wpdb->prefix}icl_translations t
|
||||
ON i.element_id = t.element_id
|
||||
AND SUBSTRING_INDEX(i.element_type, '_', 1) =
|
||||
SUBSTRING_INDEX(t.element_type, '_', 1)
|
||||
AND i.element_type != t.element_type
|
||||
AND i.translation_id != t.translation_id
|
||||
JOIN (SELECT
|
||||
CONCAT('post_', p.post_type) AS element_type,
|
||||
p.ID AS element_id
|
||||
FROM {$this->wpdb->posts} p
|
||||
UNION ALL
|
||||
SELECT
|
||||
CONCAT('tax_', tt.taxonomy) AS element_type,
|
||||
tt.term_taxonomy_id AS element_id
|
||||
FROM {$this->wpdb->term_taxonomy} tt) AS data
|
||||
ON data.element_id = i.element_id
|
||||
AND data.element_type = i.element_type"
|
||||
);
|
||||
|
||||
if ( 0 < $rows_fixed ) {
|
||||
do_action(
|
||||
'wpml_translation_update',
|
||||
array(
|
||||
'type' => 'delete',
|
||||
'rows_affected' => $rows_fixed,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rows_fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes all taxonomy term rows in icl_translations, which have a corrupted
|
||||
* element_type set, different from the one actually set in the term_taxonomy
|
||||
* table.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_broken_taxonomy_assignments() {
|
||||
|
||||
$rows_fixed = $this->wpdb->query(
|
||||
"UPDATE {$this->wpdb->prefix}icl_translations t
|
||||
JOIN {$this->wpdb->term_taxonomy} tt
|
||||
ON tt.term_taxonomy_id = t.element_id
|
||||
AND t.element_type LIKE 'tax%'
|
||||
AND t.element_type <> CONCAT('tax_', tt.taxonomy)
|
||||
SET t.element_type = CONCAT('tax_', tt.taxonomy)"
|
||||
);
|
||||
|
||||
if ( 0 < $rows_fixed ) {
|
||||
do_action(
|
||||
'wpml_translation_update',
|
||||
array(
|
||||
'context' => 'tax',
|
||||
'type' => 'element_type_update',
|
||||
'rows_affected' => $rows_fixed,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rows_fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes all post rows in icl_translations, which have a corrupted
|
||||
* element_type set, different from the one actually set in the wp_posts
|
||||
* table.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_broken_post_assignments() {
|
||||
|
||||
$rows_fixed = $this->wpdb->query(
|
||||
"UPDATE {$this->wpdb->prefix}icl_translations t
|
||||
JOIN {$this->wpdb->posts} p
|
||||
ON p.ID = t.element_id
|
||||
AND t.element_type LIKE 'post%'
|
||||
AND t.element_type <> CONCAT('post_', p.post_type)
|
||||
SET t.element_type = CONCAT('post_', p.post_type)"
|
||||
);
|
||||
|
||||
if ( 0 < $rows_fixed ) {
|
||||
do_action(
|
||||
'wpml_translation_update',
|
||||
array(
|
||||
'context' => 'tax',
|
||||
'type' => 'element_type_update',
|
||||
'rows_affected' => $rows_fixed,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rows_fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes all instances of a different element_type having been set for
|
||||
* an original element and it's translation, by setting the original's type
|
||||
* on the corrupted translation rows.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_broken_type_assignments() {
|
||||
|
||||
$rows_fixed = $this->wpdb->query(
|
||||
"UPDATE {$this->wpdb->prefix}icl_translations t
|
||||
JOIN {$this->wpdb->prefix}icl_translations c
|
||||
ON c.trid = t.trid
|
||||
AND c.language_code != t.language_code
|
||||
SET t.element_type = c.element_type
|
||||
WHERE c.source_language_code IS NULL
|
||||
AND t.source_language_code IS NOT NULL"
|
||||
);
|
||||
|
||||
if ( 0 < $rows_fixed ) {
|
||||
do_action(
|
||||
'wpml_translation_update',
|
||||
array(
|
||||
'type' => 'element_type_update',
|
||||
'rows_affected' => $rows_fixed,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $rows_fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes all rows that have an empty string instead of NULL or a source language
|
||||
* equal to its actual language set by setting the source language to NULL.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_wrong_source_language() {
|
||||
|
||||
return $this->wpdb->query(
|
||||
"UPDATE {$this->wpdb->prefix}icl_translations
|
||||
SET source_language_code = NULL
|
||||
WHERE source_language_code = ''
|
||||
OR source_language_code = language_code"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes instances of the source element of a trid being missing, by assigning
|
||||
* the oldest element ( determined by the lowest element_id ) as the original
|
||||
* element in a trid.
|
||||
*
|
||||
* @return int number of rows fixed
|
||||
*/
|
||||
private function fix_missing_original() {
|
||||
$broken_elements = $this->wpdb->get_results(
|
||||
" SELECT MIN(iclt.element_id) AS element_id, iclt.trid
|
||||
FROM {$this->wpdb->prefix}icl_translations iclt
|
||||
LEFT JOIN {$this->wpdb->prefix}icl_translations iclo
|
||||
ON iclt.trid = iclo.trid
|
||||
AND iclo.source_language_code IS NULL
|
||||
WHERE iclo.translation_id IS NULL
|
||||
GROUP BY iclt.trid"
|
||||
);
|
||||
$rows_affected = 0;
|
||||
foreach ( $broken_elements as $element ) {
|
||||
$rows_affected_per_element = $this->wpdb->query(
|
||||
$this->wpdb->prepare(
|
||||
"UPDATE {$this->wpdb->prefix}icl_translations
|
||||
SET source_language_code = NULL
|
||||
WHERE trid = %d AND element_id = %d",
|
||||
$element->trid,
|
||||
$element->element_id
|
||||
)
|
||||
);
|
||||
|
||||
if ( 0 < $rows_affected_per_element ) {
|
||||
do_action(
|
||||
'wpml_translation_update',
|
||||
array( 'trid' => $element->trid )
|
||||
);
|
||||
}
|
||||
|
||||
$rows_affected += $rows_affected_per_element;
|
||||
}
|
||||
|
||||
return $rows_affected;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
class WPML_Table_Collate_Fix implements IWPML_AJAX_Action, IWPML_Backend_Action, IWPML_DIC_Action {
|
||||
|
||||
const AJAX_ACTION = 'fix_tables_collation';
|
||||
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
|
||||
/** @var WPML_Upgrade_Schema $schema */
|
||||
private $schema;
|
||||
|
||||
public function __construct( wpdb $wpdb, WPML_Upgrade_Schema $schema ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->schema = $schema;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action(
|
||||
'wpml_troubleshooting_after_fix_element_type_collation',
|
||||
array(
|
||||
$this,
|
||||
'render_troubleshooting_button',
|
||||
)
|
||||
);
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'fix_collate_ajax' ) );
|
||||
add_action( 'upgrader_process_complete', array( $this, 'fix_collate' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
public function fix_collate_ajax() {
|
||||
if ( isset( $_POST['nonce'] )
|
||||
&& wp_verify_nonce( $_POST['nonce'], self::AJAX_ACTION )
|
||||
) {
|
||||
$this->fix_collate();
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
||||
|
||||
public function render_troubleshooting_button() {
|
||||
?>
|
||||
<p>
|
||||
<input id="wpml_fix_tables_collation" type="button" class="button-secondary"
|
||||
value="<?php _e( 'Fix WPML tables collation', 'sitepress' ); ?>"/><br/>
|
||||
<?php wp_nonce_field( self::AJAX_ACTION, 'wpml-fix-tables-collation-nonce' ); ?>
|
||||
<small style="margin-left:10px;"><?php esc_attr_e( 'Fixes the collation of WPML tables in order to match the collation of default WP tables.', 'sitepress' ); ?></small>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function enqueue_scripts( $hook ) {
|
||||
if ( WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' === $hook ) {
|
||||
wp_enqueue_script( 'wpml-fix-tables-collation', ICL_PLUGIN_URL . '/res/js/fix-tables-collation.js', array( 'jquery' ), ICL_SITEPRESS_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
public function fix_collate() {
|
||||
if ( did_action( 'upgrader_process_complete' ) > 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wp_default_table_data = $this->wpdb->get_row(
|
||||
$this->wpdb->prepare( 'SHOW TABLE status LIKE %s', $this->wpdb->posts )
|
||||
);
|
||||
|
||||
if ( isset( $wp_default_table_data->Collation ) ) {
|
||||
$charset = $this->schema->get_default_charset();
|
||||
|
||||
foreach ( $this->get_all_wpml_tables() as $table ) {
|
||||
$table = reset( $table );
|
||||
|
||||
$table_data = $this->wpdb->get_row(
|
||||
$this->wpdb->prepare( 'SHOW TABLE status LIKE %s', $table )
|
||||
);
|
||||
|
||||
if ( isset( $table_data->Collation ) && $table_data->Collation !== $wp_default_table_data->Collation ) {
|
||||
$this->wpdb->query(
|
||||
$this->wpdb->prepare(
|
||||
'ALTER TABLE ' . $table . ' CONVERT TO CHARACTER SET %s COLLATE %s',
|
||||
$charset,
|
||||
$wp_default_table_data->Collation
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_all_wpml_tables() {
|
||||
return $this->wpdb->get_results(
|
||||
$this->wpdb->prepare(
|
||||
'SHOW TABLES LIKE %s',
|
||||
$this->wpdb->prefix . 'icl_%'
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Troubleshoot_Action
|
||||
*
|
||||
* @author onTheGoSystems
|
||||
*/
|
||||
class WPML_Troubleshoot_Action {
|
||||
|
||||
const SYNC_POSTS_TAXONOMIES_SLUG = 'synchronize_posts_taxonomies';
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid_request() {
|
||||
$response = false;
|
||||
|
||||
if ( array_key_exists( 'nonce', $_POST ) && array_key_exists( 'debug_action', $_POST )
|
||||
&& self::SYNC_POSTS_TAXONOMIES_SLUG === $_POST['debug_action']
|
||||
) {
|
||||
$response = wp_verify_nonce( $_POST['nonce'], $_POST['debug_action'] );
|
||||
|
||||
if ( ! $response ) {
|
||||
wp_send_json_error( array( 'message' => esc_html__( 'Invalid nonce.', 'sitepress' ) ) );
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_Troubleshoot_Sync_Posts_Taxonomies
|
||||
*/
|
||||
class WPML_Troubleshoot_Sync_Posts_Taxonomies {
|
||||
|
||||
const BATCH_SIZE = 5;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var WPML_Term_Translation_Utils $term_translation_utils */
|
||||
private $term_translation_utils;
|
||||
|
||||
public function __construct( SitePress $sitePress, WPML_Term_Translation_Utils $term_translation_utils ) {
|
||||
$this->sitepress = $sitePress;
|
||||
$this->term_translation_utils = $term_translation_utils;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
if ( ! array_key_exists( 'post_type', $_POST ) || ! array_key_exists( 'batch_number', $_POST ) ) {
|
||||
wp_send_json_error( array( 'message' => esc_html__( 'Some parameters are missing for this request.', 'sitepress' ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type = Sanitize::stringProp( 'post_type', $_POST );
|
||||
$batch_number = (int) filter_var( $_POST['batch_number'], FILTER_SANITIZE_NUMBER_INT );
|
||||
|
||||
$posts = $this->get_posts_batch( $post_type, $batch_number );
|
||||
$this->synchronize_batch( $posts );
|
||||
|
||||
$new_batch_number = $batch_number + 1;
|
||||
|
||||
$response_data = array(
|
||||
'post_type' => $post_type,
|
||||
'batch_number' => $new_batch_number,
|
||||
'message' => sprintf( esc_html__( 'Running now batch #%d', 'sitepress' ), $new_batch_number ),
|
||||
);
|
||||
|
||||
if ( count( $posts ) < self::BATCH_SIZE ) {
|
||||
$total_posts_processed = ( $batch_number * self::BATCH_SIZE ) + count( $posts );
|
||||
|
||||
$response_data['completed'] = true;
|
||||
$response_data['message'] = sprintf( esc_html__( 'Completed: %1$d posts were processed for "%2$s".', 'sitepress' ), $total_posts_processed, $post_type );
|
||||
}
|
||||
|
||||
wp_send_json_success( $response_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param int $batch_number
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_posts_batch( $type, $batch_number ) {
|
||||
$this->sitepress->switch_lang( $this->sitepress->get_default_language() );
|
||||
|
||||
$args = array(
|
||||
'post_type' => $type,
|
||||
'offset' => $batch_number * self::BATCH_SIZE,
|
||||
'order_by' => 'ID',
|
||||
'order' => 'ASC',
|
||||
'posts_per_page' => self::BATCH_SIZE,
|
||||
'suppress_filters' => false,
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
|
||||
$this->sitepress->switch_lang();
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $posts
|
||||
*/
|
||||
private function synchronize_batch( $posts ) {
|
||||
$active_languages = $this->sitepress->get_active_languages();
|
||||
|
||||
foreach ( $active_languages as $language_code => $active_language ) {
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$this->term_translation_utils->sync_terms( $post->ID, $language_code );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user