first commit
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\Notices;
|
||||
|
||||
use WPML\TM\ATE\ClonedSites\Lock;
|
||||
use WPML\TM\Templates\Notices\AteLocked;
|
||||
|
||||
class AteLockNotice implements \IWPML_Backend_Action, \IWPML_DIC_Action {
|
||||
|
||||
/**
|
||||
* @var AteLocked
|
||||
*/
|
||||
private $templateRenderer;
|
||||
|
||||
public function __construct( AteLocked $templateRenderer ) {
|
||||
$this->templateRenderer = $templateRenderer;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'admin_notices', [ $this, 'ateLockNotice' ] );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueueScripts' ] );
|
||||
}
|
||||
|
||||
public function enqueueScripts() {
|
||||
if ( $this->shouldRender() ) {
|
||||
wp_enqueue_script(
|
||||
'wpml-tm-ate-lock',
|
||||
WPML_TM_URL . '/res/js/ate-api-lock-notification.js',
|
||||
[],
|
||||
WPML_TM_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function ateLockNotice() {
|
||||
if ( $this->shouldRender() ) {
|
||||
$this->renderNotice();
|
||||
}
|
||||
}
|
||||
|
||||
private function shouldRender() {
|
||||
return Lock::isLocked() && $this->shouldDisplayOnCurrentPage();
|
||||
}
|
||||
|
||||
private function renderNotice() {
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$this->renderAdminNotice();
|
||||
} else {
|
||||
$this->renderUserNotice();
|
||||
}
|
||||
}
|
||||
|
||||
private function renderAdminNotice() {
|
||||
$model = (object) [
|
||||
'title' => __( 'Site Moved or Copied - Action Required', 'wpml-translation-management' ),
|
||||
'intro' => __( 'Looks like this site is a copy of a different site, or moved to a different URL.', 'wpml-translation-management' ),
|
||||
'radio_option_1' => __( 'I moved the site to this new URL', 'wpml-translation-management' ),
|
||||
'radio_option_2' => __( 'This is a copy of my original site', 'wpml-translation-management' ),
|
||||
'btn_text' => __( 'Save', 'wpml-translation-management' ),
|
||||
'link_text' => __( 'More details', 'wpml-translation-management' ),
|
||||
];
|
||||
|
||||
$this->templateRenderer->renderAdmin( $model );
|
||||
}
|
||||
|
||||
private function renderUserNotice() {
|
||||
$model = (object) [
|
||||
'title' => __( 'Site Moved or Copied - Action Required', 'wpml-translation-management' ),
|
||||
'intro' => __( 'Looks like this site is a copy of a different site, or moved to a different URL. Please contact your translation manager to update Translation Management plugin configuration.', 'wpml-translation-management' ),
|
||||
];
|
||||
|
||||
$this->templateRenderer->renderUser( $model );
|
||||
}
|
||||
|
||||
private function shouldDisplayOnCurrentPage() {
|
||||
return $this->shouldDisplayOnScreen( [ 'dashboard' ] ) || $this->shouldDisplayOnPage( $this->getPages() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $screens
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldDisplayOnScreen( array $screens ) {
|
||||
$currentScreen = get_current_screen();
|
||||
return $currentScreen instanceof \WP_Screen
|
||||
&& in_array( $currentScreen->id, $screens );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $pages
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldDisplayOnPage( array $pages ) {
|
||||
return isset( $_GET['page'] ) && in_array( $_GET['page'], $pages );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string[]
|
||||
*/
|
||||
private function getPages() {
|
||||
$pages = [
|
||||
WPML_PLUGIN_FOLDER . '/menu/languages.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/theme-localization.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/settings.php',
|
||||
WPML_PLUGIN_FOLDER . '/menu/support.php',
|
||||
WPML_TM_FOLDER . '/menu/settings',
|
||||
WPML_TM_FOLDER . '/menu/main.php',
|
||||
WPML_TM_FOLDER . '/menu/translations-queue.php',
|
||||
WPML_TM_FOLDER . '/menu/string-translation.php',
|
||||
WPML_TM_FOLDER . '/menu/settings.php',
|
||||
];
|
||||
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Disable_Notices_In_Wizard_Factory implements IWPML_Backend_Action_Loader, IWPML_Deferred_Action_Loader {
|
||||
|
||||
const AFTER_INSTALLER_READY_ACTION = 'otgs_installer_initialized';
|
||||
|
||||
/**
|
||||
* Creates the instance.
|
||||
*
|
||||
* @return \IWPML_Action|\IWPML_Action[]|\WPML_TM_Disable_Notices_In_Wizard|null
|
||||
*/
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
return new WPML_TM_Disable_Notices_In_Wizard( $sitepress->get_wp_api(), wpml_translation_management() );
|
||||
}
|
||||
|
||||
/**
|
||||
* It returns the action hook to use to defer the loading of the class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_load_action() {
|
||||
return self::AFTER_INSTALLER_READY_ACTION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Disable_Notices_In_Wizard {
|
||||
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
|
||||
/** @var WPML_Translation_Management $wpml_translation_management */
|
||||
private $wpml_translation_management;
|
||||
|
||||
public function __construct( WPML_WP_API $wp_api, WPML_Translation_Management $wpml_translation_management ) {
|
||||
$this->wp_api = $wp_api;
|
||||
$this->wpml_translation_management = $wpml_translation_management;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( $this->wp_api->is_tm_page() && $this->wpml_translation_management->should_show_wizard() ) {
|
||||
add_action( 'admin_print_scripts', array( $this, 'disable_notices' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function disable_notices() {
|
||||
global $wp_filter;
|
||||
|
||||
unset( $wp_filter['user_admin_notices'], $wp_filter['admin_notices'], $wp_filter['all_admin_notices'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
class WPML_All_Translation_Jobs_Migration_Notice extends WPML_Translation_Jobs_Migration_Notice {
|
||||
|
||||
/**
|
||||
* It gets the definition of the notice's content.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_model() {
|
||||
return array(
|
||||
'strings' => array(
|
||||
'title' => __( 'Problem receiving translation jobs?', 'wpml-translation-management' ),
|
||||
'description' => __( 'WPML needs to update its table of translation jobs, so that your site can continue receiving completed translations. This process will take a few minutes and does not modify content or translations in your site.', 'wpml-translation-management' ),
|
||||
'button' => __( 'Start update', 'wpml-translation-management' ),
|
||||
/* translators: this is shown between two number: processed items and total number of items to process */
|
||||
'of' => __( 'of', 'wpml-translation-management' ),
|
||||
'jobs_migrated' => __( 'jobs fixed', 'wpml-translation-management' ),
|
||||
'communicationError' => __(
|
||||
'The communication error with Translation Proxy has appeared. Please try later.',
|
||||
'wpml-translation-management'
|
||||
),
|
||||
),
|
||||
'nonce' => wp_nonce_field(
|
||||
WPML_Translation_Jobs_Migration_Ajax::ACTION,
|
||||
WPML_Translation_Jobs_Migration_Ajax::ACTION,
|
||||
false,
|
||||
false
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the ID of the notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_notice_id() {
|
||||
return 'all-translation-jobs-migration';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Migration_State {
|
||||
const MIGRATION_DONE_KEY = 'wpml-tm-translation-jobs-migration';
|
||||
const FIXING_MIGRATION_STATE_KEY = 'wpml-tm-all-translation-jobs-migration';
|
||||
const MIGRATION_SKIPPED = 'wpml-tm-translation-jobs-migration-skipped';
|
||||
|
||||
/**
|
||||
* The fixing migration has already been run but it contained errors
|
||||
*/
|
||||
const FIRST_MIGRATION_FIX_HAS_RUN = 1;
|
||||
/**
|
||||
* We've already cleaned logs of the first fixing migration and are ready to run another this time flawless version
|
||||
*/
|
||||
const READY_TO_RUN_SECOND_MIGRATION_FIX = 2;
|
||||
/**
|
||||
* The final flawless fixing migration has been run
|
||||
*/
|
||||
const SECOND_MIGRATION_FIX_HAS_RUN = 3;
|
||||
|
||||
/**
|
||||
* Checks if the original migration has been finished
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_migrated() {
|
||||
return (bool) get_option( self::MIGRATION_DONE_KEY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the fixing migration ( migration which fixes the flaws of the original migration ) has been run
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_fixing_migration_done() {
|
||||
$option = (int) get_option( self::FIXING_MIGRATION_STATE_KEY );
|
||||
if ( $option === self::FIRST_MIGRATION_FIX_HAS_RUN ) { // clear previous log
|
||||
update_option( WPML_Translation_Jobs_Migration::MIGRATION_FIX_LOG_KEY, array(), false );
|
||||
update_option( self::FIXING_MIGRATION_STATE_KEY, self::READY_TO_RUN_SECOND_MIGRATION_FIX, true );
|
||||
}
|
||||
|
||||
return (int) get_option( self::FIXING_MIGRATION_STATE_KEY ) === self::SECOND_MIGRATION_FIX_HAS_RUN;
|
||||
}
|
||||
|
||||
public function mark_migration_as_done() {
|
||||
update_option( self::MIGRATION_DONE_KEY, 1, true );
|
||||
|
||||
// a user has never run the original migration so it does not need the fixing migration
|
||||
$this->mark_fixing_migration_as_done();
|
||||
}
|
||||
|
||||
public function mark_fixing_migration_as_done() {
|
||||
update_option( self::FIXING_MIGRATION_STATE_KEY, self::SECOND_MIGRATION_FIX_HAS_RUN, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $flag
|
||||
*/
|
||||
public function skip_migration( $flag = true ) {
|
||||
update_option( self::MIGRATION_SKIPPED, $flag, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_skipped() {
|
||||
return (bool) get_option( self::MIGRATION_SKIPPED );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The class adds the hook which is triggered in the moment of Translation Service authorization.
|
||||
* It checks if the migration has been skipped due to lack of activated service and if so, it turns on the migration.
|
||||
*/
|
||||
class WPML_TM_Restore_Skipped_Migration implements IWPML_Action {
|
||||
/** @var WPML_TM_Jobs_Migration_State */
|
||||
private $migration_state;
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Jobs_Migration_State $migration_state
|
||||
*/
|
||||
public function __construct( WPML_TM_Jobs_Migration_State $migration_state ) {
|
||||
$this->migration_state = $migration_state;
|
||||
}
|
||||
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_tm_translation_service_authorized', array( $this, 'restore' ) );
|
||||
}
|
||||
|
||||
public function restore() {
|
||||
if ( $this->migration_state->is_skipped() ) {
|
||||
$this->migration_state->skip_migration( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Translation_Jobs_Fix_Summary_Factory implements IWPML_Backend_Action_Loader {
|
||||
/**
|
||||
* @return WPML_TM_Translation_Jobs_Fix_Summary
|
||||
*/
|
||||
public function create() {
|
||||
$template_service = new WPML_Twig_Template_Loader( array( WPML_TM_PATH . '/templates/translation-jobs-migration/' ) );
|
||||
|
||||
return new WPML_TM_Translation_Jobs_Fix_Summary(
|
||||
new WPML_TM_Translation_Jobs_Fix_Summary_Notice( wpml_get_admin_notices(), $template_service->get_template() ),
|
||||
new WPML_TM_Jobs_Migration_State()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Translation_Jobs_Fix_Summary_Notice extends WPML_Translation_Jobs_Migration_Notice {
|
||||
|
||||
protected function get_model() {
|
||||
$tm_url = '<a href="' . admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php' ) . '">' . __( 'Translation Dashboard', 'sitepress' ) . '</a>';
|
||||
$description = sprintf( __( 'WPML completed updating the translations history. Next, please visit the %s and click on the button to "Check status and get translations".', 'wpml-translation-management' ), $tm_url );
|
||||
|
||||
return array(
|
||||
'strings' => array(
|
||||
'title' => __( 'Problem receiving translation jobs?', 'sitepress' ),
|
||||
'description' => $description,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_notice_id() {
|
||||
return 'translation-jobs-migration-fix-summary';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Translation_Jobs_Fix_Summary {
|
||||
|
||||
const INVALID_JOBS_SYNCED_KEY = 'wpml_tm_migration_invalid_jobs_already_synced';
|
||||
|
||||
/** @var WPML_TM_Translation_Jobs_Fix_Summary_Notice */
|
||||
private $notice;
|
||||
|
||||
/** @var WPML_TM_Jobs_Migration_State */
|
||||
private $migration_state;
|
||||
|
||||
public function __construct(
|
||||
WPML_TM_Translation_Jobs_Fix_Summary_Notice $notice,
|
||||
WPML_TM_Jobs_Migration_State $migration_state
|
||||
) {
|
||||
$this->notice = $notice;
|
||||
$this->migration_state = $migration_state;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'init', array( $this, 'display_summary' ) );
|
||||
add_action(
|
||||
'wp_ajax_' . WPML_TP_Sync_Ajax_Handler::AJAX_ACTION,
|
||||
array(
|
||||
$this,
|
||||
'mark_invalid_jobs_as_synced',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function display_summary() {
|
||||
if ( $this->should_display_summary_notice() ) {
|
||||
$this->notice->add_notice();
|
||||
} elseif ( $this->notice->exists() ) {
|
||||
$this->notice->remove_notice();
|
||||
}
|
||||
}
|
||||
|
||||
private function should_display_summary_notice() {
|
||||
if ( ! $this->migration_state->is_fixing_migration_done() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$jobs_with_new_status = get_option( WPML_Translation_Jobs_Migration::MIGRATION_FIX_LOG_KEY );
|
||||
$jobs_with_new_status = isset( $jobs_with_new_status['status_changed'] ) ? $jobs_with_new_status['status_changed'] : null;
|
||||
$jobs_already_synced = (int) get_option( self::INVALID_JOBS_SYNCED_KEY ) > 1;
|
||||
|
||||
return $jobs_with_new_status && ! $jobs_already_synced;
|
||||
}
|
||||
|
||||
public function mark_invalid_jobs_as_synced() {
|
||||
update_option( self::INVALID_JOBS_SYNCED_KEY, 2 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Troubleshooting_Fix_Translation_Jobs_TP_ID_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $wpml_post_translations, $wpml_term_translations, $wpdb;
|
||||
|
||||
$jobs_migration_repository = new WPML_Translation_Jobs_Migration_Repository( wpml_tm_get_jobs_repository(), true );
|
||||
$job_factory = wpml_tm_load_job_factory();
|
||||
$wpml_tm_records = new WPML_TM_Records( $wpdb, $wpml_post_translations, $wpml_term_translations );
|
||||
$cms_id_helper = new WPML_TM_CMS_ID( $wpml_tm_records, $job_factory );
|
||||
$jobs_migration = new WPML_Translation_Jobs_Migration( $jobs_migration_repository, $cms_id_helper, $wpdb, wpml_tm_get_tp_jobs_api() );
|
||||
|
||||
return new WPML_TM_Troubleshooting_Fix_Translation_Jobs_TP_ID( $jobs_migration, wpml_tm_get_jobs_repository() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Troubleshooting_Fix_Translation_Jobs_TP_ID {
|
||||
|
||||
const AJAX_ACTION = 'wpml-fix-translation-jobs-tp-id';
|
||||
|
||||
private $jobs_migration;
|
||||
private $jobs_repository;
|
||||
|
||||
public function __construct( WPML_Translation_Jobs_Migration $jobs_migration, WPML_TM_Jobs_Repository $jobs_repository ) {
|
||||
$this->jobs_migration = $jobs_migration;
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action(
|
||||
'wpml_troubleshooting_after_fix_element_type_collation',
|
||||
array(
|
||||
$this,
|
||||
'render_troubleshooting_section',
|
||||
)
|
||||
);
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'fix_tp_id_ajax' ) );
|
||||
|
||||
}
|
||||
|
||||
public function fix_tp_id_ajax() {
|
||||
if ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], self::AJAX_ACTION ) ) {
|
||||
$job_ids = isset( $_POST['job_ids'] ) ? array_map( 'intval', explode( ',', filter_var( $_POST['job_ids'], FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) ) : array();
|
||||
$jobs = array();
|
||||
|
||||
foreach ( $job_ids as $job_id ) {
|
||||
if ( ! $job_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = new WPML_TM_Jobs_Search_Params();
|
||||
$params->set_scope( WPML_TM_Jobs_Search_Params::SCOPE_REMOTE );
|
||||
$params->set_job_types( array( WPML_TM_Job_Entity::POST_TYPE, WPML_TM_Job_Entity::PACKAGE_TYPE ) );
|
||||
$params->set_local_job_id( $job_id );
|
||||
|
||||
$jobs[] = current( $this->jobs_repository->get( $params )->getIterator()->getArrayCopy() );
|
||||
}
|
||||
|
||||
if ( $jobs ) {
|
||||
$this->jobs_migration->migrate_jobs( $jobs, true );
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
wp_send_json_error();
|
||||
}
|
||||
}
|
||||
|
||||
public function enqueue_scripts( $hook ) {
|
||||
if ( WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' === $hook ) {
|
||||
wp_enqueue_script( 'wpml-fix-tp-id', WPML_TM_URL . '/res/js/fix-tp-id.js', array( 'jquery' ), WPML_TM_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function render_troubleshooting_section() {
|
||||
?>
|
||||
<p>
|
||||
<input id="wpml_fix_tp_id_text" type="text" value=""/><input id="wpml_fix_tp_id_btn" type="button" class="button-secondary" value="<?php esc_attr_e( 'Fix WPML Translation Jobs "tp_id" field', 'sitepress' ); ?>"/><br/>
|
||||
<?php wp_nonce_field( self::AJAX_ACTION, 'wpml-fix-tp-id-nonce' ); ?>
|
||||
<small style="margin-left:10px;"><?php esc_attr_e( 'Fixes the "tp_id" field of WPML ranslation jobs and set the status to "in progress" (it requires manual action to re-sync translation status + download translations). It accepts comma separated values of translation job IDs (rid).', 'sitepress' ); ?></small>
|
||||
</p>
|
||||
<?php
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Fixing_Migration_Ajax {
|
||||
|
||||
const ACTION = 'wpml_translation_jobs_migration';
|
||||
const JOBS_MIGRATED_PER_REQUEST = 100;
|
||||
const PAGINATION_OPTION = 'wpml_translation_jobs_migration_processed';
|
||||
|
||||
/** @var WPML_Translation_Jobs_Migration */
|
||||
private $jobs_migration;
|
||||
|
||||
/** @var WPML_Translation_Jobs_Migration_Repository */
|
||||
private $jobs_repository;
|
||||
|
||||
/** @var WPML_TM_Jobs_Migration_State */
|
||||
private $migration_state;
|
||||
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Migration $jobs_migration,
|
||||
WPML_Translation_Jobs_Migration_Repository $jobs_repository,
|
||||
WPML_TM_Jobs_Migration_State $migration_state
|
||||
) {
|
||||
$this->jobs_migration = $jobs_migration;
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
$this->migration_state = $migration_state;
|
||||
}
|
||||
|
||||
public function run_migration() {
|
||||
if ( ! $this->is_valid_request() ) {
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
$jobs = $this->jobs_repository->get();
|
||||
$total_jobs = count( $jobs );
|
||||
|
||||
$offset = $this->get_already_processed();
|
||||
|
||||
if ( $offset < $total_jobs ) {
|
||||
$jobs_chunk = array_slice( $jobs, $offset, self::JOBS_MIGRATED_PER_REQUEST );
|
||||
|
||||
try {
|
||||
$this->jobs_migration->migrate_jobs( $jobs_chunk, true );
|
||||
} catch ( Exception $e ) {
|
||||
wp_send_json_error( $e->getMessage(), 500 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$done = $total_jobs <= $offset + self::JOBS_MIGRATED_PER_REQUEST;
|
||||
$jobs_chunk_total = count( $jobs_chunk );
|
||||
|
||||
update_option( self::PAGINATION_OPTION, $offset + self::JOBS_MIGRATED_PER_REQUEST );
|
||||
} else {
|
||||
$done = true;
|
||||
$jobs_chunk_total = 0;
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'totalJobs' => $total_jobs,
|
||||
'jobsMigrated' => $jobs_chunk_total,
|
||||
'done' => $done,
|
||||
);
|
||||
|
||||
if ( $done ) {
|
||||
$this->migration_state->mark_fixing_migration_as_done();
|
||||
delete_option( self::PAGINATION_OPTION );
|
||||
}
|
||||
|
||||
wp_send_json_success( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request() {
|
||||
return wp_verify_nonce( $_POST['nonce'], self::ACTION );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function get_already_processed() {
|
||||
return (int) get_option( self::PAGINATION_OPTION, 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Migration_Ajax {
|
||||
|
||||
const ACTION = 'wpml_translation_jobs_migration';
|
||||
|
||||
const JOBS_MIGRATED_PER_REQUEST = 100;
|
||||
|
||||
/** @var WPML_Translation_Jobs_Migration */
|
||||
private $jobs_migration;
|
||||
|
||||
/** @var WPML_Translation_Jobs_Migration_Repository */
|
||||
private $jobs_repository;
|
||||
|
||||
/** @var WPML_TM_Jobs_Migration_State */
|
||||
private $migration_state;
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Migration $jobs_migration,
|
||||
WPML_Translation_Jobs_Migration_Repository $jobs_repository,
|
||||
WPML_TM_Jobs_Migration_State $migration_state
|
||||
) {
|
||||
$this->jobs_migration = $jobs_migration;
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
$this->migration_state = $migration_state;
|
||||
}
|
||||
|
||||
public function run_migration() {
|
||||
if ( ! $this->is_valid_request() ) {
|
||||
wp_send_json_error();
|
||||
return;
|
||||
}
|
||||
|
||||
$jobs = $this->jobs_repository->get();
|
||||
|
||||
$jobs_chunk = array_slice( $jobs, 0, self::JOBS_MIGRATED_PER_REQUEST );
|
||||
try {
|
||||
$this->jobs_migration->migrate_jobs( $jobs_chunk );
|
||||
} catch ( Exception $e ) {
|
||||
wp_send_json_error( $e->getMessage(), 500 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$done = count( $jobs ) === count( $jobs_chunk );
|
||||
$total_jobs = count( $jobs );
|
||||
$jobs_chunk_total = count( $jobs_chunk );
|
||||
|
||||
$result = array(
|
||||
'totalJobs' => $total_jobs,
|
||||
'jobsMigrated' => $jobs_chunk_total,
|
||||
'done' => $done,
|
||||
);
|
||||
|
||||
if ( $jobs_chunk_total === $total_jobs ) {
|
||||
$this->migration_state->mark_migration_as_done();
|
||||
}
|
||||
|
||||
wp_send_json_success( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request() {
|
||||
return wp_verify_nonce( $_POST['nonce'], self::ACTION );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Migration_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_AJAX_Action_Loader {
|
||||
|
||||
/**
|
||||
* It creates an instance of WPML_Translation_Jobs_Migration_Notice.
|
||||
*
|
||||
* @return null|WPML_Translation_Jobs_Migration_Hooks|WPML_TM_Restore_Skipped_Migration
|
||||
*/
|
||||
public function create() {
|
||||
$fixing_migration = false;
|
||||
|
||||
$wpml_notices = wpml_get_admin_notices();
|
||||
$wpml_notices->remove_notice( WPML_Translation_Jobs_Migration_Notice::NOTICE_GROUP_ID, 'all-translation-jobs-migration' );
|
||||
$wpml_notices->remove_notice( WPML_Translation_Jobs_Migration_Notice::NOTICE_GROUP_ID, 'translation-jobs-migration' );
|
||||
|
||||
if ( ! $this->should_add_migration_hooks() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$migration_state = new WPML_TM_Jobs_Migration_State();
|
||||
if ( $migration_state->is_skipped() ) {
|
||||
return new WPML_TM_Restore_Skipped_Migration( $migration_state );
|
||||
}
|
||||
|
||||
if ( $migration_state->is_migrated() ) {
|
||||
if ( $migration_state->is_fixing_migration_done() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$fixing_migration = true;
|
||||
}
|
||||
|
||||
$template_service = new WPML_Twig_Template_Loader( array( WPML_TM_PATH . '/templates/translation-jobs-migration/' ) );
|
||||
|
||||
if ( $fixing_migration ) {
|
||||
$notice = new WPML_All_Translation_Jobs_Migration_Notice( $wpml_notices, $template_service->get_template() );
|
||||
} else {
|
||||
$notice = new WPML_Translation_Jobs_Missing_TP_ID_Migration_Notice( $wpml_notices, $template_service->get_template() );
|
||||
}
|
||||
|
||||
$jobs_migration_repository = new WPML_Translation_Jobs_Migration_Repository( wpml_tm_get_jobs_repository(), $fixing_migration );
|
||||
|
||||
global $wpml_post_translations, $wpml_term_translations, $wpdb;
|
||||
|
||||
$job_factory = wpml_tm_load_job_factory();
|
||||
$wpml_tm_records = new WPML_TM_Records( $wpdb, $wpml_post_translations, $wpml_term_translations );
|
||||
$cms_id_helper = new WPML_TM_CMS_ID( $wpml_tm_records, $job_factory );
|
||||
$jobs_migration = new WPML_Translation_Jobs_Migration( $jobs_migration_repository, $cms_id_helper, $wpdb, wpml_tm_get_tp_jobs_api() );
|
||||
if ( $fixing_migration ) {
|
||||
$ajax_handler = new WPML_Translation_Jobs_Fixing_Migration_Ajax(
|
||||
$jobs_migration,
|
||||
$jobs_migration_repository,
|
||||
$migration_state
|
||||
);
|
||||
} else {
|
||||
$ajax_handler = new WPML_Translation_Jobs_Migration_Ajax(
|
||||
$jobs_migration,
|
||||
$jobs_migration_repository,
|
||||
$migration_state
|
||||
);
|
||||
}
|
||||
|
||||
return new WPML_Translation_Jobs_Migration_Hooks(
|
||||
$notice,
|
||||
$ajax_handler,
|
||||
$jobs_migration_repository,
|
||||
wpml_get_upgrade_schema(),
|
||||
$migration_state
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if location is allowed to add migration hooks.
|
||||
*/
|
||||
private function should_add_migration_hooks() {
|
||||
$allowed_uris = array(
|
||||
'/.*page=sitepress-multilingual-cms.*/',
|
||||
'/.*page=wpml-string-translation.*/',
|
||||
'/.*page=wpml-translation-management.*/',
|
||||
);
|
||||
|
||||
if ( wp_doing_ajax() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$uri = $this->get_request_uri();
|
||||
|
||||
foreach ( $allowed_uris as $pattern ) {
|
||||
if ( preg_match( $pattern, $uri ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request uri.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_request_uri() {
|
||||
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
return filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_STRING );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Migration_Hooks {
|
||||
|
||||
private $notice;
|
||||
private $ajax_handler;
|
||||
|
||||
/** @var WPML_Translation_Jobs_Migration_Repository */
|
||||
private $jobs_migration_repository;
|
||||
|
||||
/** @var WPML_Upgrade_Schema $schema */
|
||||
private $schema;
|
||||
|
||||
/** @var WPML_TM_Jobs_Migration_State */
|
||||
private $migration_state;
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Migration_Notice $notice,
|
||||
$ajax_handler,
|
||||
WPML_Translation_Jobs_Migration_Repository $jobs_migration_repository,
|
||||
WPML_Upgrade_Schema $schema,
|
||||
WPML_TM_Jobs_Migration_State $migration_state
|
||||
) {
|
||||
$this->notice = $notice;
|
||||
$this->ajax_handler = $ajax_handler;
|
||||
$this->jobs_migration_repository = $jobs_migration_repository;
|
||||
$this->schema = $schema;
|
||||
$this->migration_state = $migration_state;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'init', array( $this, 'add_hooks_on_init' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
public function add_hooks_on_init() {
|
||||
if ( $this->new_columns_are_not_added_yet() ) {
|
||||
add_action( 'wpml_tm_lock_ui', array( $this, 'lock_tm_ui' ) );
|
||||
} elseif ( $this->needs_migration() ) {
|
||||
$this->notice->add_notice();
|
||||
|
||||
add_action( 'wpml_tm_lock_ui', array( $this, 'lock_tm_ui' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_action(
|
||||
'wp_ajax_' . WPML_Translation_Jobs_Migration_Ajax::ACTION,
|
||||
array( $this->ajax_handler, 'run_migration' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see
|
||||
* `WPML_TM_Add_TP_Revision_And_TS_Status_Columns_To_Core_Status`
|
||||
* `WPML_TM_Add_TP_Revision_And_TS_Status_Columns_To_Translation_Status`
|
||||
* `WPML_TM_Add_TP_ID_Column_To_Translation_Status`
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function new_columns_are_not_added_yet() {
|
||||
$has_columns = $this->schema->does_column_exist( 'icl_core_status', 'tp_revision' )
|
||||
&& $this->schema->does_column_exist( 'icl_core_status', 'ts_status' )
|
||||
&& $this->schema->does_column_exist( 'icl_translation_status', 'tp_revision' )
|
||||
&& $this->schema->does_column_exist( 'icl_translation_status', 'ts_status' )
|
||||
&& $this->schema->does_column_exist( 'icl_translation_status', 'tp_id' );
|
||||
|
||||
return ! $has_columns;
|
||||
}
|
||||
|
||||
public function enqueue_scripts() {
|
||||
wp_enqueue_script(
|
||||
'wpml-tm-translation-jobs-migration',
|
||||
WPML_TM_URL . '/dist/js/translationJobsMigration/app.js',
|
||||
array(),
|
||||
WPML_TM_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function needs_migration() {
|
||||
if ( $this->jobs_migration_repository->get_count() ) {
|
||||
return ! $this->skip_migration_if_service_is_not_active();
|
||||
}
|
||||
|
||||
$this->migration_state->mark_migration_as_done();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function skip_migration_if_service_is_not_active() {
|
||||
if ( ! TranslationProxy::is_current_service_active_and_authenticated() ) {
|
||||
$this->migration_state->skip_migration( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function lock_tm_ui() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
abstract class WPML_Translation_Jobs_Migration_Notice {
|
||||
|
||||
const NOTICE_GROUP_ID = 'translation-jobs';
|
||||
const TEMPLATE = 'translation-jobs-migration.twig';
|
||||
|
||||
/**
|
||||
* The instance of \WPML_Notices.
|
||||
*
|
||||
* @var \WPML_Notices
|
||||
*/
|
||||
private $admin_notices;
|
||||
|
||||
/**
|
||||
* The instance of \IWPML_Template_Service.
|
||||
*
|
||||
* @var \IWPML_Template_Service
|
||||
*/
|
||||
private $template_service;
|
||||
|
||||
/**
|
||||
* WPML_Translation_Jobs_Migration_Notice constructor.
|
||||
*
|
||||
* @param \WPML_Notices $admin_notices An instance of \WPML_Notices.
|
||||
* @param \IWPML_Template_Service $template_service A class implementing \IWPML_Template_Service.
|
||||
*/
|
||||
public function __construct( WPML_Notices $admin_notices, IWPML_Template_Service $template_service ) {
|
||||
$this->admin_notices = $admin_notices;
|
||||
$this->template_service = $template_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* It adds the notice to be shown when conditions meet.
|
||||
*/
|
||||
public function add_notice() {
|
||||
$notice = $this->admin_notices->create_notice( $this->get_notice_id(), $this->get_notice_content(), self::NOTICE_GROUP_ID );
|
||||
$notice->set_css_class_types( 'notice-error' );
|
||||
$this->admin_notices->add_notice( $notice );
|
||||
}
|
||||
|
||||
/**
|
||||
* It removes the notice.
|
||||
*/
|
||||
public function remove_notice() {
|
||||
$this->admin_notices->remove_notice( self::NOTICE_GROUP_ID, $this->get_notice_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
* It checks is the notice exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists() {
|
||||
return (bool) $this->admin_notices->get_notice( $this->get_notice_id(), self::NOTICE_GROUP_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the notice content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_notice_content() {
|
||||
return $this->template_service->show( $this->get_model(), self::TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the definition of the notice's content.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function get_model();
|
||||
|
||||
/**
|
||||
* It gets the ID of the notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_notice_id();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Migration_Repository {
|
||||
|
||||
private $jobs_repository;
|
||||
private $all_jobs = false;
|
||||
|
||||
public function __construct( WPML_TM_Jobs_Repository $jobs_repository, $all_jobs = false ) {
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
$this->all_jobs = $all_jobs;
|
||||
}
|
||||
|
||||
public function get() {
|
||||
return $this->jobs_repository->get( $this->get_params() )->getIterator()->getArrayCopy();
|
||||
}
|
||||
|
||||
public function get_count() {
|
||||
return $this->jobs_repository->get_count( $this->get_params() );
|
||||
}
|
||||
|
||||
private function get_params() {
|
||||
$params = new WPML_TM_Jobs_Search_Params();
|
||||
$params->set_scope( WPML_TM_Jobs_Search_Params::SCOPE_REMOTE );
|
||||
$params->set_job_types( array( WPML_TM_Job_Entity::POST_TYPE, WPML_TM_Job_Entity::PACKAGE_TYPE ) );
|
||||
|
||||
if ( ! $this->all_jobs ) {
|
||||
$params->set_tp_id( null );
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Migration {
|
||||
|
||||
const MIGRATION_FIX_LOG_KEY = 'wpml_fixing_migration_log';
|
||||
|
||||
private $jobs_repository;
|
||||
private $cms_id_builder;
|
||||
private $wpdb;
|
||||
private $jobs_api;
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Migration_Repository $jobs_repository,
|
||||
WPML_TM_CMS_ID $cms_id_builder,
|
||||
wpdb $wpdb,
|
||||
WPML_TP_Jobs_API $jobs_api
|
||||
) {
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
$this->cms_id_builder = $cms_id_builder;
|
||||
$this->wpdb = $wpdb;
|
||||
$this->jobs_api = $jobs_api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity[] $jobs
|
||||
* @param bool $recover_status
|
||||
*
|
||||
* @throws WPML_TP_API_Exception
|
||||
*/
|
||||
public function migrate_jobs( array $jobs, $recover_status = false ) {
|
||||
$mapped_jobs = $this->map_cms_id_job_id( $jobs );
|
||||
|
||||
if ( $mapped_jobs ) {
|
||||
$tp_jobs = $this->get_tp_jobs( $mapped_jobs );
|
||||
|
||||
foreach ( $jobs as $job ) {
|
||||
$cms_id = array_key_exists( $job->get_id(), $mapped_jobs ) ? $mapped_jobs[ $job->get_id() ] : '';
|
||||
list( $tp_id, $revision_id ) = $this->get_tp_id_revision_id( $cms_id, $tp_jobs );
|
||||
|
||||
if ( $recover_status ) {
|
||||
$this->recovery_mode( $job, $tp_id, $revision_id );
|
||||
} else {
|
||||
$this->first_migration_mode( $job, $tp_id, $revision_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $mapped_jobs
|
||||
*
|
||||
* @throws WPML_TP_API_Exception
|
||||
* @return array
|
||||
*/
|
||||
private function get_tp_jobs( array $mapped_jobs ) {
|
||||
return $this->get_latest_jobs_grouped_by_cms_id(
|
||||
$this->jobs_api->get_jobs_per_cms_ids( array_values( $mapped_jobs ), true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
* @param int $tp_id
|
||||
* @param int $revision_id
|
||||
*/
|
||||
private function recovery_mode( WPML_TM_Post_Job_Entity $job, $tp_id, $revision_id ) {
|
||||
if ( $tp_id !== $job->get_tp_id() ) {
|
||||
$new_status = $this->get_new_status( $job, $tp_id );
|
||||
$this->log( $job->get_id(), $job->get_tp_id(), $tp_id, $job->get_status(), $new_status );
|
||||
|
||||
$this->fix_job_fields( $tp_id, $revision_id, $new_status, $job->get_id() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
* @param int $tp_id
|
||||
* @param int $revision_id
|
||||
*/
|
||||
private function first_migration_mode( WPML_TM_Post_Job_Entity $job, $tp_id, $revision_id ) {
|
||||
$this->fix_job_fields( $tp_id, $revision_id, false, $job->get_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tp_jobs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_latest_jobs_grouped_by_cms_id( $tp_jobs ) {
|
||||
$result = array();
|
||||
|
||||
foreach ( $tp_jobs as $tp_job ) {
|
||||
if ( ! isset( $result[ $tp_job->cms_id ] ) ) {
|
||||
$result[ $tp_job->cms_id ] = $tp_job;
|
||||
} elseif ( $tp_job->id > $result[ $tp_job->cms_id ]->id ) {
|
||||
$result[ $tp_job->cms_id ] = $tp_job;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
* @param int $new_tp_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function get_new_status( WPML_TM_Post_Job_Entity $job, $new_tp_id ) {
|
||||
$new_status = false;
|
||||
if ( $job->get_tp_id() !== null && $new_tp_id ) {
|
||||
if ( $job->get_status() === ICL_TM_NOT_TRANSLATED || $this->has_been_completed_after_release( $job ) ) {
|
||||
$new_status = ICL_TM_IN_PROGRESS;
|
||||
}
|
||||
}
|
||||
|
||||
return $new_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
private function has_been_completed_after_release( WPML_TM_Post_Job_Entity $job ) {
|
||||
return $job->get_status() === ICL_TM_COMPLETE && $job->get_completed_date() && $job->get_completed_date() > $this->get_4_2_0_release_date();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $cms_id
|
||||
* @param array $tp_jobs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_tp_id_revision_id( $cms_id, $tp_jobs ) {
|
||||
$result = array( 0, 0 );
|
||||
if ( isset( $tp_jobs[ $cms_id ] ) ) {
|
||||
$result = array(
|
||||
$tp_jobs[ $cms_id ]->id,
|
||||
$tp_jobs[ $cms_id ]->translation_revision,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $tp_id
|
||||
* @param int $revision_id
|
||||
* @param int|false $status
|
||||
* @param int $job_id
|
||||
*/
|
||||
private function fix_job_fields( $tp_id, $revision_id, $status, $job_id ) {
|
||||
$new_data = array(
|
||||
'tp_id' => $tp_id,
|
||||
'tp_revision' => $revision_id,
|
||||
);
|
||||
|
||||
if ( $status ) {
|
||||
$new_data['status'] = $status;
|
||||
}
|
||||
|
||||
$this->wpdb->update(
|
||||
$this->wpdb->prefix . 'icl_translation_status',
|
||||
$new_data,
|
||||
array( 'rid' => $job_id )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity[] $jobs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function map_cms_id_job_id( $jobs ) {
|
||||
$mapped_jobs = array();
|
||||
|
||||
foreach ( $jobs as $job ) {
|
||||
$cms_id = $this->cms_id_builder->cms_id_from_job_id( $job->get_translate_job_id() );
|
||||
$mapped_jobs[ $job->get_id() ] = $cms_id;
|
||||
}
|
||||
|
||||
return $mapped_jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @throws Exception
|
||||
*/
|
||||
private function get_4_2_0_release_date() {
|
||||
return new DateTime(
|
||||
defined( 'WPML_4_2_0_RELEASE_DATE' ) ? WPML_4_2_0_RELEASE_DATE : '2019-01-20'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $rid
|
||||
* @param int $old_tp_id
|
||||
* @param int $new_tp_id
|
||||
* @param int $old_status
|
||||
* @param int $new_status
|
||||
*/
|
||||
private function log( $rid, $old_tp_id, $new_tp_id, $old_status, $new_status ) {
|
||||
$log = get_option( self::MIGRATION_FIX_LOG_KEY, array() );
|
||||
$key = $new_status ? 'status_changed' : 'status_not_changed';
|
||||
|
||||
$log[ $key ][ $rid ] = array(
|
||||
'rid' => $rid,
|
||||
'old_tp_id' => $old_tp_id,
|
||||
'new_tp_id' => $new_tp_id,
|
||||
'old_status' => $old_status,
|
||||
'new_status' => $new_status,
|
||||
);
|
||||
|
||||
update_option( self::MIGRATION_FIX_LOG_KEY, $log, false );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translation_Jobs_Missing_TP_ID_Migration_Notice extends WPML_Translation_Jobs_Migration_Notice {
|
||||
|
||||
/**
|
||||
* It gets the definition of the notice's content.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_model() {
|
||||
return array(
|
||||
'strings' => array(
|
||||
'title' => __( 'WPML Translation Jobs Migration', 'wpml-translation-management' ),
|
||||
/* translators: the placeholder is replaced with the current version of WPML */
|
||||
'description' => sprintf( __( 'WPML found some remote jobs on your site that must be migrated in order to work with WPML %s. You might not be able to access some of the WPML administration pages until this migration is fully completed.', 'wpml-translation-management' ), ICL_SITEPRESS_VERSION ),
|
||||
'button' => __( 'Run now', 'wpml-translation-management' ),
|
||||
/* translators: this is shown between two number: processed items and total number of items to process */
|
||||
'of' => __( 'of', 'wpml-translation-management' ),
|
||||
'jobs_migrated' => __( 'jobs migrated', 'wpml-translation-management' ),
|
||||
'communicationError' => __(
|
||||
'The communication error with Translation Proxy has appeared. Please try later.',
|
||||
'wpml-translation-management'
|
||||
),
|
||||
),
|
||||
'nonce' => wp_nonce_field( WPML_Translation_Jobs_Migration_Ajax::ACTION, WPML_Translation_Jobs_Migration_Ajax::ACTION, false, false ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* It gets the ID of the notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_notice_id() {
|
||||
return 'translation-jobs-migration';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_TS_Instructions_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_AJAX_Action_Loader {
|
||||
/**
|
||||
* @return WPML_TM_TS_Instructions_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
return new WPML_TM_TS_Instructions_Hooks( $this->create_notice() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TM_TS_Instructions_Notice
|
||||
*/
|
||||
private function create_notice() {
|
||||
$template_service = new WPML_Twig_Template_Loader( array( WPML_TM_PATH . '/templates/notices/translation-service-instruction/' ) );
|
||||
|
||||
return new WPML_TM_TS_Instructions_Notice( wpml_get_admin_notices(), $template_service->get_template() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_TS_Instructions_Hooks implements IWPML_Action {
|
||||
/** @var WPML_TM_TS_Instructions_Notice */
|
||||
private $notice;
|
||||
|
||||
/**
|
||||
* WPML_TM_TS_Instructions_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TM_TS_Instructions_Notice $notice
|
||||
*/
|
||||
public function __construct( WPML_TM_TS_Instructions_Notice $notice ) {
|
||||
$this->notice = $notice;
|
||||
}
|
||||
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_tp_project_created', array( $this, 'display_message' ), 10, 3 );
|
||||
add_action( 'init', array( $this, 'add_hooks_on_init' ), 10, 0 );
|
||||
|
||||
add_action( 'wpml_tp_service_de_authorized', array( $this, 'dismiss' ), 10, 0 );
|
||||
add_action( 'wpml_tp_service_dectivated', array( $this, 'dismiss' ), 10, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $service
|
||||
* @param stdClass $project
|
||||
* @param array $icl_translation_projects
|
||||
*/
|
||||
public function display_message( $service, $project, array $icl_translation_projects ) {
|
||||
$is_first_project_ever = empty( $icl_translation_projects );
|
||||
|
||||
if ( $is_first_project_ever || ! $this->has_completed_remote_jobs() ) {
|
||||
$this->notice->add_notice( $service );
|
||||
}
|
||||
}
|
||||
|
||||
public function add_hooks_on_init() {
|
||||
if ( $this->notice->exists() ) {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 10, 0 );
|
||||
add_action( 'wp_ajax_translation_service_instruction_dismiss', array( $this, 'dismiss' ), 10, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public function enqueue_scripts() {
|
||||
$handle = 'wpml-tm-translation-service-instruction';
|
||||
|
||||
wp_register_script(
|
||||
$handle,
|
||||
WPML_TM_URL . '/dist/js/translationServiceInstruction/app.js',
|
||||
array(),
|
||||
WPML_TM_VERSION
|
||||
);
|
||||
|
||||
$data = array(
|
||||
'restUrl' => untrailingslashit( rest_url() ),
|
||||
'restNonce' => wp_create_nonce( 'wp_rest' ),
|
||||
'ate' => null,
|
||||
'currentUser' => wp_get_current_user(),
|
||||
);
|
||||
|
||||
wp_localize_script( $handle, 'WPML_TM_SETTINGS', $data );
|
||||
|
||||
wp_enqueue_script( $handle );
|
||||
}
|
||||
|
||||
public function dismiss() {
|
||||
$this->notice->remove_notice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function has_completed_remote_jobs() {
|
||||
$search_params = new WPML_TM_Jobs_Search_Params();
|
||||
$search_params->set_status( array( ICL_TM_COMPLETE ) );
|
||||
$search_params->set_scope( WPML_TM_Jobs_Search_Params::SCOPE_REMOTE );
|
||||
|
||||
return wpml_tm_get_jobs_repository()->get_count( $search_params ) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_TS_Instructions_Notice {
|
||||
const NOTICE_ID = 'translation-service-instructions';
|
||||
const NOTICE_GROUP_ID = 'translation-service-instructions';
|
||||
const TEMPLATE = 'translation-service-instructions.twig';
|
||||
|
||||
/** @var WPML_Notices */
|
||||
private $admin_notices;
|
||||
|
||||
/** @var IWPML_Template_Service */
|
||||
private $template_service;
|
||||
|
||||
public function __construct( WPML_Notices $admin_notices, IWPML_Template_Service $template_service ) {
|
||||
$this->admin_notices = $admin_notices;
|
||||
$this->template_service = $template_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $service
|
||||
*/
|
||||
public function add_notice( $service ) {
|
||||
$notice = $this->admin_notices->create_notice(
|
||||
self::NOTICE_ID,
|
||||
$this->get_notice_content( $service ),
|
||||
self::NOTICE_GROUP_ID
|
||||
);
|
||||
$notice->add_display_callback( array( 'WPML_TM_Page', 'is_tm_dashboard' ) );
|
||||
$notice->set_text_only( true );
|
||||
$this->admin_notices->add_notice( $notice );
|
||||
}
|
||||
|
||||
public function remove_notice() {
|
||||
$this->admin_notices->remove_notice( self::NOTICE_GROUP_ID, self::NOTICE_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function exists() {
|
||||
return ( WPML_TM_Page::is_dashboard() || wpml_is_ajax() ) &&
|
||||
(bool) $this->admin_notices->get_notice( self::NOTICE_ID, self::NOTICE_GROUP_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_notice_content( $service ) {
|
||||
$model = $this->get_model( $service );
|
||||
|
||||
return $this->template_service->show( $model, self::TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass $service
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_model( $service ) {
|
||||
return array(
|
||||
'strings' => array(
|
||||
'title' => sprintf(
|
||||
__( 'How to work correctly with %s', 'wpml-translation-management' ),
|
||||
$service->name
|
||||
),
|
||||
'description' => sprintf(
|
||||
__(
|
||||
"Congratulations for choosing %s to translate your site's content. To avoid high costs and wasted time, please watch our short video.",
|
||||
'wpml-translation-management'
|
||||
),
|
||||
$service->name
|
||||
),
|
||||
'need_help' => __( 'Need help? See ', 'wpml-translation-management' ),
|
||||
'help_caption' => __(
|
||||
'how to translate different parts of the site.',
|
||||
'wpml-translation-management'
|
||||
),
|
||||
'this_stuff_is_important' => __( 'This stuff is actually important. Please follow the video to send a test translation. Then, you can dismiss this message. Thank you!', 'wpml-translation-management' ),
|
||||
'my_test_translation_went_fine' => __( 'My test translation went fine.', 'wpml-translation-management' ),
|
||||
'dismiss' => __( 'Dismiss this message.', 'wpml-translation-management' ),
|
||||
),
|
||||
'image_url' => WPML_TM_URL . '/res/img/ts-instruction-video.png',
|
||||
'help_link' => 'https://wpml.org/documentation/translating-your-contents/professional-translation-via-wpml/doing-test-translation/?utm_source=wpmlplugin&utm_campaign=translation-services&utm_medium=translation-dashboard-message&utm_term=doing-test-translation',
|
||||
'video_link' => 'https://wpml.org/documentation/translating-your-contents/professional-translation-via-wpml/doing-test-translation/?utm_source=wpmlplugin&utm_medium=translation-dashboard-message-video&utm_campaign=translation-services&utm_term=doing-test-translation',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Post_Edit_Notices_Factory {
|
||||
|
||||
const TEMPLATES_PATH = '/templates/notices/post-edit/';
|
||||
|
||||
public function create() {
|
||||
/**
|
||||
* @var SitePress $sitepress
|
||||
* @var WPML_TM_Translation_Status_Display $wpml_tm_status_display_filter
|
||||
*/
|
||||
global $sitepress, $wpml_tm_status_display_filter;
|
||||
|
||||
$status_helper = wpml_get_post_status_helper();
|
||||
|
||||
$paths = array( WPML_TM_PATH . self::TEMPLATES_PATH );
|
||||
$template_service_loader = new WPML_Twig_Template_Loader( $paths );
|
||||
$template_service = $template_service_loader->get_template();
|
||||
|
||||
$super_globals = new WPML_Super_Globals_Validation();
|
||||
|
||||
if ( ! $wpml_tm_status_display_filter ) {
|
||||
wpml_tm_load_status_display_filter();
|
||||
}
|
||||
|
||||
return new WPML_TM_Post_Edit_Notices(
|
||||
$status_helper,
|
||||
$sitepress,
|
||||
$template_service,
|
||||
$super_globals,
|
||||
$wpml_tm_status_display_filter,
|
||||
new WPML_Translation_Element_Factory( $sitepress, new WPML_WP_Cache() ),
|
||||
new WPML_TM_ATE()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Post_Edit_Notices {
|
||||
|
||||
const TEMPLATE_TRANSLATION_IN_PROGRESS = 'translation-in-progress.twig';
|
||||
const TEMPLATE_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS = 'edit-original-translation-in-progress.twig';
|
||||
const TEMPLATE_USE_PREFERABLY_TM_DASHBOARD = 'use-preferably-tm-dashboard.twig';
|
||||
const TEMPLATE_USE_PREFERABLY_TE = 'use-preferably-translation-editor.twig';
|
||||
const DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION = 'wpml_dismiss_post_edit_original_te_notice';
|
||||
const DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION = 'wpml_dismiss_post_edit_te_notice';
|
||||
|
||||
/** @var WPML_Post_Status $post_status */
|
||||
private $post_status;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var IWPML_Template_Service $template_render */
|
||||
private $template_render;
|
||||
|
||||
/** @var WPML_Super_Globals_Validation $super_globals */
|
||||
private $super_globals;
|
||||
|
||||
/** @var WPML_TM_Translation_Status_Display $status_display */
|
||||
private $status_display;
|
||||
|
||||
/** @var WPML_Translation_Element_Factory $element_factory */
|
||||
private $element_factory;
|
||||
|
||||
/** @var WPML_TM_ATE $tm_ate */
|
||||
private $tm_ate;
|
||||
|
||||
/**
|
||||
* @param WPML_Post_Status $post_status
|
||||
* @param SitePress $sitepress
|
||||
* @param IWPML_Template_Service $template_render
|
||||
* @param WPML_Super_Globals_Validation $super_globals
|
||||
* @param WPML_TM_Translation_Status_Display $status_display
|
||||
* @param WPML_Translation_Element_Factory $element_factory
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_Post_Status $post_status,
|
||||
SitePress $sitepress,
|
||||
IWPML_Template_Service $template_render,
|
||||
WPML_Super_Globals_Validation $super_globals,
|
||||
WPML_TM_Translation_Status_Display $status_display,
|
||||
WPML_Translation_Element_Factory $element_factory,
|
||||
WPML_TM_ATE $tm_ate
|
||||
) {
|
||||
$this->post_status = $post_status;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->template_render = $template_render;
|
||||
$this->super_globals = $super_globals;
|
||||
$this->status_display = $status_display;
|
||||
$this->element_factory = $element_factory;
|
||||
$this->tm_ate = $tm_ate;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$request_get_trid = isset( $_GET['trid'] ) ?
|
||||
filter_var( $_GET['trid'], FILTER_SANITIZE_NUMBER_INT ) :
|
||||
'';
|
||||
|
||||
$request_get_post = isset( $_GET['post'] ) ?
|
||||
filter_var( $_GET['post'], FILTER_SANITIZE_NUMBER_INT ) :
|
||||
'';
|
||||
|
||||
if ( $request_get_trid || $request_get_post ) {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
||||
add_action( 'admin_notices', array( $this, 'display_notices' ) );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_' . self::DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION, array( $this, 'do_not_display_it_again_to_user' ) );
|
||||
add_action( 'wp_ajax_' . self::DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION, array( $this, 'do_not_display_it_again' ) );
|
||||
}
|
||||
|
||||
public function enqueue_assets() {
|
||||
wp_enqueue_script(
|
||||
'wpml-tm-post-edit-alert',
|
||||
WPML_TM_URL . '/res/js/post-edit-alert.js',
|
||||
array( 'jquery', 'jquery-ui-dialog' ),
|
||||
WPML_TM_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
public function display_notices() {
|
||||
$trid = $this->super_globals->get( 'trid', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE );
|
||||
$post_id = $this->super_globals->get( 'post', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE );
|
||||
$lang = $this->super_globals->get( 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
|
||||
|
||||
if ( ! $post_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_element = $this->element_factory->create( $post_id, 'post' );
|
||||
$is_original = ! $post_element->get_source_language_code();
|
||||
|
||||
if ( ! $trid ) {
|
||||
$trid = $post_element->get_trid();
|
||||
}
|
||||
|
||||
if ( $trid ) {
|
||||
|
||||
if(
|
||||
$is_original &&
|
||||
$this->is_waiting_for_a_translations( $post_element ) &&
|
||||
$this->should_display_it_to_user( self::DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION )
|
||||
) {
|
||||
$model = array(
|
||||
'warning' => sprintf(
|
||||
__( '%sTranslation in progress - wait before editing%s', 'wpml-translation-management' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
'message' => __( 'This page that you are editing is being translated right now. If you edit now, some or all of the translation for this page may be missing. It\'s best to wait until translation completes, then edit and update the translation.', 'wpml-translation-management' ),
|
||||
'go_back_button' => __( 'Take me back', 'wpml-translation-management' ),
|
||||
'edit_anyway_button' => __( 'I understand - continue editing', 'wpml-translation-management' ),
|
||||
'do_not_show_again' => __( "Don't show this warning again", 'wpml-translation-management' ),
|
||||
'do_not_show_again_action' => self::DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION,
|
||||
'nonce' => wp_nonce_field(
|
||||
self::DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION,
|
||||
self::DO_NOT_SHOW_AGAIN_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS_ACTION,
|
||||
true,
|
||||
false
|
||||
),
|
||||
);
|
||||
|
||||
echo $this->template_render->show( $model, self::TEMPLATE_EDIT_ORIGINAL_TRANSLATION_IN_PROGRESS );
|
||||
}elseif ( $this->is_waiting_for_a_translation( (int) $this->post_status->get_status( $post_id, $trid, $lang ) ) ) {
|
||||
$model = array(
|
||||
'warning' => sprintf(
|
||||
__( '%sWarning:%s You are trying to edit a translation that is currently in the process of being added using WPML.', 'wpml-translation-management' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
'check_dashboard' => sprintf(
|
||||
__( 'Please refer to the <a href="%s">Translation Management dashboard</a> for the exact status of this translation.', 'wpml-translation-management' ),
|
||||
admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&' )
|
||||
),
|
||||
);
|
||||
|
||||
echo $this->template_render->show( $model, self::TEMPLATE_TRANSLATION_IN_PROGRESS );
|
||||
|
||||
} elseif (
|
||||
! $is_original &&
|
||||
WPML_TM_Post_Edit_TM_Editor_Mode::is_using_tm_editor( $this->sitepress, $post_id ) &&
|
||||
apply_filters( 'wpml_tm_show_page_builders_translation_editor_warning', true, $post_id ) &&
|
||||
$this->should_display_it( self::DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION )
|
||||
) {
|
||||
|
||||
$model = array(
|
||||
'warning' => sprintf(
|
||||
__( '%sWarning:%s You are trying to edit a translation using the standard WordPress editor but your site is configured to use the WPML Translation Editor.', 'wpml-translation-management' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
'go_back_button' => __( 'Go back', 'wpml-translation-management' ),
|
||||
'edit_anyway_button' => __( 'Edit anyway', 'wpml-translation-management' ),
|
||||
'open_in_te_button' => __( 'Open in Translation Editor', 'wpml-translation-management' ),
|
||||
'translation_editor_url' => $this->get_translation_editor_link( $post_element ),
|
||||
'do_not_show_again' => __( "Don't show this warning again", 'wpml-translation-management' ),
|
||||
'do_not_show_again_action' => self::DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION,
|
||||
'nonce' => wp_nonce_field(
|
||||
self::DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION,
|
||||
self::DO_NOT_SHOW_AGAIN_USE_PREFERABLY_TE_ACTION,
|
||||
true,
|
||||
false
|
||||
),
|
||||
);
|
||||
|
||||
echo $this->template_render->show( $model, self::TEMPLATE_USE_PREFERABLY_TE );
|
||||
}
|
||||
|
||||
} elseif ( $post_element->is_translatable()
|
||||
&& WPML_TM_Post_Edit_TM_Editor_Mode::is_using_tm_editor( $this->sitepress, $post_id )
|
||||
){
|
||||
$model = array(
|
||||
'warning' => sprintf(
|
||||
__('%sWarning:%s You are trying to add a translation using the standard WordPress editor but your site is configured to use the WPML Translation Editor.' , 'wpml-translation-management'),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
'use_tm_dashboard' => sprintf(
|
||||
__( 'You should use <a href="%s">Translation management dashboard</a> to send the original document to translation.' , 'wpml-translation-management' ),
|
||||
admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php' )
|
||||
),
|
||||
);
|
||||
|
||||
echo $this->template_render->show( $model, self::TEMPLATE_USE_PREFERABLY_TM_DASHBOARD );
|
||||
}
|
||||
}
|
||||
|
||||
public function do_not_display_it_again_to_user() {
|
||||
$action = isset( $_POST['action'] ) ? filter_var( $_POST['action'], FILTER_SANITIZE_STRING ) : false;
|
||||
if( $this->is_valid_request( $action ) ){
|
||||
update_user_option( get_current_user_id(), $action, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
public function do_not_display_it_again() {
|
||||
$action = isset( $_POST['action'] ) ? filter_var( $_POST['action'], FILTER_SANITIZE_STRING ) : false;
|
||||
if( $this->is_valid_request( $action ) ){
|
||||
update_option( $action, 1, false );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request( $action ) {
|
||||
return isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function should_display_it_to_user( $action ) {
|
||||
return false === get_user_option( $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function should_display_it( $action ) {
|
||||
return false === get_option( $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Translation_Element $post_element
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_waiting_for_a_translations( $post_element ){
|
||||
|
||||
$in_progress = false;
|
||||
|
||||
$translations = $this->sitepress->get_element_translations( $post_element->get_trid(), $post_element->get_wpml_element_type() );
|
||||
|
||||
if( $translations ){
|
||||
|
||||
$wpml_element_translations = wpml_tm_load_element_translations();
|
||||
|
||||
foreach( $translations as $translation ){
|
||||
|
||||
if( !$translation->original ){
|
||||
|
||||
//ATE status needs to be checked directly because it can be not updated in DB yet
|
||||
if(
|
||||
$this->tm_ate->is_translation_method_ate_enabled() &&
|
||||
$this->tm_ate->is_translation_ready_for_post( $post_element->get_trid(), $translation->language_code )
|
||||
){
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $this->is_waiting_for_a_translation( $wpml_element_translations->get_translation_status( $post_element->get_trid(), $translation->language_code ) ) ) {
|
||||
$in_progress = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $in_progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|null $translation_status
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_waiting_for_a_translation( $translation_status ) {
|
||||
return ! is_null( $translation_status )
|
||||
&& $translation_status > 0
|
||||
&& $translation_status != ICL_TM_DUPLICATE
|
||||
&& $translation_status < ICL_TM_COMPLETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Post_Element $post_element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_translation_editor_link( WPML_Post_Element $post_element ) {
|
||||
$post_id = $post_element->get_id();
|
||||
$source_post_element = $post_element->get_source_element();
|
||||
|
||||
if ( $source_post_element ) {
|
||||
$post_id = $source_post_element->get_id();
|
||||
}
|
||||
|
||||
$url = $this->status_display->filter_status_link(
|
||||
'#', $post_id, $post_element->get_language_code(), $post_element->get_trid()
|
||||
);
|
||||
|
||||
return remove_query_arg( 'return_url', $url );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user