3 use function WPML\Container\make;
4 use WPML\TM\Menu\TranslationQueue\CloneJobs;
6 class WPML_Translations_Queue {
8 /** @var SitePress $sitepress */
11 /* @var WPML_UI_Screen_Options_Pagination */
12 private $screen_options;
14 /** @var WPML_Admin_Table_Sort $table_sort */
17 private $must_render_the_editor = false;
19 /** @var WPML_Translation_Editor_UI */
20 private $translation_editor;
28 * @param SitePress $sitepress
29 * @param WPML_UI_Screen_Options_Factory $screen_options_factory
30 * @param CloneJobs $clone_jobs
32 public function __construct(
34 $screen_options_factory,
37 $this->sitepress = $sitepress;
38 $this->screen_options = $screen_options_factory->create_pagination(
39 'tm_translations_queue_per_page',
42 $this->table_sort = $screen_options_factory->create_admin_table_sort();
43 $this->clone_jobs = $clone_jobs;
46 public function init_hooks() {
47 add_action( 'current_screen', array( $this, 'load' ) );
50 public function load() {
51 if ( $this->must_open_the_editor() ) {
52 $job_id = $this->get_job_id_from_request();
53 $job_object = wpml_tm_load_job_factory()->get_translation_job( $job_id, false, 0, true );
55 if ( $job_object->get_translator_id() <= 0 ) {
56 $job_object->assign_to( $this->sitepress->get_wp_api()->get_current_user_id() );
59 if ( (int) $job_object->get_status_value() !== ICL_TM_COMPLETE ) {
60 $this->mark_job_as_in_progress( $job_object );
63 if ( $job_object->user_can_translate( wp_get_current_user() ) ) {
64 $this->clone_jobs->cloneCompletedJob( $job_id, $job_object );
65 $this->clone_jobs->maybeCloneWPMLJob( $job_id );
67 $this->attempt_opening_ATE( $job_id );
69 wpml_tm_load_old_jobs_editor()->set( $job_id, WPML_TM_Editors::WPML );
72 $this->must_render_the_editor = true;
73 $this->translation_editor = new WPML_Translation_Editor_UI(
78 new WPML_TM_Job_Action_Factory( wpml_tm_load_job_factory() ),
79 new WPML_TM_Job_Layout( $wpdb, $this->sitepress->get_wp_api() )
87 * @param array $icl_translation_filter
89 * @throws \InvalidArgumentException
91 public function display( array $icl_translation_filter = array() ) {
92 if ( $this->must_render_the_editor ) {
93 $this->translation_editor->render();
99 * @var TranslationManagement $iclTranslationManagement
100 * @var WPML_Translation_Job_Factory $wpml_translation_job_factory
102 global $iclTranslationManagement, $wpml_translation_job_factory;
104 $translation_jobs = array();
105 $job_types = array();
106 $langs_from = array();
107 $lang_from = array();
112 if ( ! empty( $_GET['resigned'] ) ) {
113 $iclTranslationManagement->add_message(
117 "You've resigned from this job.",
118 'wpml-translation-management'
124 $cookie_filters = self::get_cookie_filters();
126 if ( $cookie_filters ) {
127 $icl_translation_filter = $cookie_filters;
130 $current_translator = $iclTranslationManagement->get_current_translator();
131 $can_translate = $current_translator && $current_translator->ID > 0 && $current_translator->language_pairs;
132 $post_link_factory = new WPML_TM_Post_Link_Factory( $this->sitepress );
133 if ( $can_translate ) {
134 $icl_translation_filter['translator_id'] = $current_translator->ID;
135 $icl_translation_filter['include_unassigned'] = true;
137 $element_type_prefix = isset( $_GET['element_type'] ) ? $_GET['element_type'] : 'post';
138 if ( isset( $_GET['updated'] ) && $_GET['updated'] ) {
139 $tm_post_link_updated = $post_link_factory->view_link( $_GET['updated'] );
140 if ( $iclTranslationManagement->is_external_type( $element_type_prefix ) ) {
141 $tm_post_link_updated = apply_filters(
142 'wpml_external_item_link',
143 $tm_post_link_updated,
148 $user_message = __( 'Translation updated: ', 'wpml-translation-management' ) . $tm_post_link_updated;
149 $iclTranslationManagement->add_message(
152 'text' => $user_message,
155 } elseif ( isset( $_GET['added'] ) && $_GET['added'] ) {
156 $tm_post_link_added = $post_link_factory->view_link( $_GET['added'] );
157 if ( $iclTranslationManagement->is_external_type( $element_type_prefix ) ) {
158 $tm_post_link_added = apply_filters(
159 'wpml_external_item_link',
165 $user_message = __( 'Translation added: ', 'wpml-translation-management' ) . $tm_post_link_added;
166 $iclTranslationManagement->add_message(
169 'text' => $user_message,
172 } elseif ( isset( $_GET['job-cancelled'] ) ) {
173 $user_message = __( 'Translation has been removed by admin', 'wpml-translation-management' );
174 $iclTranslationManagement->add_message(
177 'text' => $user_message,
182 if ( isset( $_GET['title'] ) && $_GET['title'] ) {
183 $icl_translation_filter['title'] = filter_var( $_GET['title'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
186 if ( ! empty( $current_translator->language_pairs ) ) {
187 $_langs_to = array();
188 if ( 1 < count( $current_translator->language_pairs ) ) {
189 foreach ( $current_translator->language_pairs as $lang => $to ) {
190 $langs_from[] = $this->sitepress->get_language_details( $lang );
191 $_langs_to = array_merge( (array) $_langs_to, array_keys( $to ) );
193 $_langs_to = array_unique( $_langs_to );
195 $_langs_to = array_keys( current( $current_translator->language_pairs ) );
196 $lang_from = $this->sitepress->get_language_details( key( $current_translator->language_pairs ) );
197 $icl_translation_filter['from'] = $lang_from['code'];
200 if ( 1 < count( $_langs_to ) ) {
201 foreach ( $_langs_to as $lang ) {
202 $langs_to[] = $this->sitepress->get_language_details( $lang );
205 $lang_to = $this->sitepress->get_language_details( current( $_langs_to ) );
206 $icl_translation_filter['to'] = $lang_to['code'];
208 $job_types = $wpml_translation_job_factory->get_translation_job_types_filter(
211 'translator_id' => $current_translator->ID,
212 'include_unassigned' => true,
216 if ( isset( $_GET['orderby'] ) ) {
217 $icl_translation_filter['order_by'] = filter_var( $_GET['orderby'], FILTER_SANITIZE_STRING );
220 if ( isset( $_GET['order'] ) ) {
221 $icl_translation_filter['order'] = filter_var( $_GET['order'], FILTER_SANITIZE_STRING );
224 $translation_jobs = $wpml_translation_job_factory->get_translation_jobs( (array) $icl_translation_filter );
229 <h2><?php echo __( 'Translations queue', 'wpml-translation-management' ); ?></h2>
231 <?php if ( empty( $current_translator->language_pairs ) ) : ?>
232 <div class="error below-h2"><p><?php _e( 'No translation languages configured for this user.', 'wpml-translation-management' ); ?></p></div>
234 <?php do_action( 'icl_tm_messages' ); ?>
236 <?php if ( ! empty( $current_translator->language_pairs ) ) : ?>
238 <div class="alignright">
240 name="translation-jobs-filter"
242 action="admin.php?page=<?php echo WPML_TM_FOLDER; ?>/menu/translations-queue.php">
243 <input type="hidden" name="icl_tm_action" value="ujobs_filter"/>
248 <select name="filter[type]">
249 <option value=""><?php _e( 'All types', 'wpml-translation-management' ); ?></option>
250 <?php foreach ( $job_types as $job_type => $job_type_name ) : ?>
251 <option value="<?php echo $job_type; ?>"
253 if ( ! empty( $icl_translation_filter['type'] )
254 && $icl_translation_filter['type']
258 selected="selected"<?php endif; ?>><?php echo $job_type_name; ?></option>
262 <strong><?php _e( 'From', 'wpml-translation-management' ); ?></strong>
264 if ( 1 < count( $current_translator->language_pairs ) ) {
266 $from_select = new WPML_Simple_Language_Selector( $this->sitepress );
267 echo $from_select->render(
269 'name' => 'filter[from]',
270 'please_select_text' => __(
272 'wpml-translation-management'
275 'languages' => $langs_from,
276 'selected' => isset( $icl_translation_filter['from'] )
277 ? $icl_translation_filter['from'] : '',
284 value="<?php echo esc_attr( $lang_from['code'] ); ?>"/>
286 echo $this->sitepress->get_flag_img( $lang_from['code'] )
288 . $lang_from['display_name'];
293 <strong><?php _e( 'To', 'wpml-translation-management' ); ?></strong>
295 if ( 1 < @count( $langs_to ) ) {
296 $to_select = new WPML_Simple_Language_Selector( $this->sitepress );
297 echo $to_select->render(
299 'name' => 'filter[to]',
300 'please_select_text' => __(
302 'wpml-translation-management'
305 'languages' => $langs_to,
306 'selected' => isset( $icl_translation_filter['to'] )
307 ? $icl_translation_filter['to'] : '',
312 <input type="hidden" name="filter[to]"
313 value="<?php echo esc_attr( $lang_to['code'] ); ?>"/>
315 echo $this->sitepress->get_flag_img( $lang_to['code'] ) . ' ' . $lang_to['display_name'];
318 $translation_filter_status = null;
319 if ( array_key_exists( 'status', $icl_translation_filter ) ) {
320 $translation_filter_status = (int) $icl_translation_filter['status'];
326 <select name="filter[status]">
327 <option value=""><?php _e( 'All statuses', 'wpml-translation-management' ) ?></option>
328 <option value="<?php echo ICL_TM_COMPLETE; ?>"
330 if ( $translation_filter_status === ICL_TM_COMPLETE ) :
333 selected="selected"<?php endif; ?>><?php echo TranslationManagement::status2text( ICL_TM_COMPLETE ); ?></option>
334 <option value="<?php echo ICL_TM_IN_PROGRESS; ?>"
336 if ( $translation_filter_status
337 === ICL_TM_IN_PROGRESS ) :
340 selected="selected"<?php endif; ?>><?php echo TranslationManagement::status2text( ICL_TM_IN_PROGRESS ); ?></option>
341 <option value="<?php echo ICL_TM_WAITING_FOR_TRANSLATOR; ?>"
343 if ( $translation_filter_status === ICL_TM_WAITING_FOR_TRANSLATOR ) :
346 selected="selected"<?php endif; ?>><?php _e( 'Available to translate', 'wpml-translation-management' ) ?></option>
349 <input class="button-secondary"
351 value="<?php _e( 'Filter', 'wpml-translation-management' ); ?>"/>
359 $actions = apply_filters( 'wpml_translation_queue_actions', array() );
362 * @deprecated Use 'wpml_translation_queue_actions' instead
364 $actions = apply_filters( 'WPML_translation_queue_actions', $actions );
366 <?php if ( count( $actions ) > 0 ) : ?>
367 <form method="post" name="translation-jobs-action" action="admin.php?page=<?php echo WPML_TM_FOLDER; ?>/menu/translations-queue.php">
371 do_action( 'wpml_xliff_select_actions', $actions, 'action', $translation_jobs );
374 * @deprecated Use 'wpml_xliff_select_actions' instead
376 do_action( 'WPML_xliff_select_actions', $actions, 'action', $translation_jobs );
381 $translation_queue_pagination = new WPML_Translations_Queue_Pagination_UI(
383 $this->screen_options->get_items_per_page()
385 $translation_jobs = $translation_queue_pagination->get_paged_jobs();
388 <?php // pagination - end ?>
391 $blog_translators = wpml_tm_load_blog_translators();
392 $tm_api = new WPML_TM_API( $blog_translators, $iclTranslationManagement );
394 $translation_queue_jobs_model = new WPML_Translations_Queue_Jobs_Model(
396 $iclTranslationManagement,
398 \WPML\TM\Jobs\Utils\ElementLinkFactory::create(),
401 $translation_jobs = $translation_queue_jobs_model->get();
403 $this->show_table( $translation_jobs, count( $actions ) > 0, $job_id );
406 <div id="tm-queue-pagination" class="tablenav">
407 <?php $translation_queue_pagination->show(); ?>
410 do_action( 'wpml_xliff_select_actions', $actions, 'action2', $translation_jobs );
413 * @deprecated Use 'wpml_xliff_select_actions' instead
415 do_action( 'WPML_xliff_select_actions', $actions, 'action2', $translation_jobs );
418 <?php // pagination - end ?>
420 <?php if ( count( $actions ) > 0 ) : ?>
424 <?php do_action( 'wpml_translation_queue_after_display', $translation_jobs ); ?>
430 // Check for any bulk actions
431 if ( isset( $_POST['action'] ) || isset( $_POST['action2'] ) ) {
432 $xliff_version = isset( $_POST['doaction'] ) ? $_POST['action'] : $_POST['action2'];
433 do_action( 'wpml_translation_queue_do_actions_export_xliff', $_POST, $xliff_version );
436 * @deprecated Use 'wpml_translation_queue_do_actions_export_xliff' instead
438 do_action( 'WPML_translation_queue_do_actions_export_xliff', $_POST, $xliff_version );
443 * @param $translation_jobs
444 * @param $has_actions
447 public function show_table( $translation_jobs, $has_actions, $open_job ) {
449 <table class="widefat striped icl-translation-jobs" id="icl-translation-jobs" cellspacing="0"
450 data-string-complete="<?php esc_attr_e( 'Complete', 'wpml-translation-management' ); ?>"
451 data-string-edit="<?php esc_attr_e( 'Edit', 'wpml-translation-management' ); ?>"
453 <?php foreach ( array( 'thead', 'tfoot' ) as $element_type ) { ?>
454 <<?php echo $element_type; ?>>
456 <?php if ( $has_actions ) { ?>
457 <td class="manage-column column-cb check-column js-check-all" scope="col">
458 <input title="<?php echo esc_attr( $translation_jobs['strings']['check_all'] ); ?>"
462 <th scope="col" class="cloumn-job_id <?php echo $this->table_sort->get_column_classes( 'job_id' ); ?>">
463 <a href="<?php echo $this->table_sort->get_column_url( 'job_id' ); ?>">
464 <span><?php echo esc_html( $translation_jobs['strings']['job_id'] ); ?></span>
465 <span class="sorting-indicator"></span>
469 class="column-title"><?php echo esc_html( $translation_jobs['strings']['title'] ); ?></th>
471 class="column-type"><?php echo esc_html( $translation_jobs['strings']['type'] ); ?></th>
473 class="column-language"><?php echo esc_html( $translation_jobs['strings']['language'] ); ?></th>
475 class="column-status"><?php echo esc_html( $translation_jobs['strings']['status'] ); ?></th>
477 class="column-deadline <?php echo $this->table_sort->get_column_classes( 'deadline' ); ?>">
478 <a href="<?php echo $this->table_sort->get_column_url( 'deadline' ); ?>">
479 <span><?php echo esc_html( $translation_jobs['strings']['deadline'] ); ?></span>
480 <span class="sorting-indicator"></span>
484 class="column-actions"></th>
486 </<?php echo $element_type; ?>>
490 <?php if ( empty( $translation_jobs['jobs'] ) ) { ?>
493 align="center"><?php _e( 'No translation jobs found', 'wpml-translation-management' ); ?></td>
498 $ate_jobs = apply_filters( 'wpml_tm_ate_jobs_data', array(), $translation_jobs['jobs'] );
500 foreach ( $translation_jobs['jobs'] as $index => $job ) {
502 <tr<?php echo $this->get_row_css_attribute( $job ); ?>>
503 <?php if ( $has_actions ) { ?>
505 <input type="checkbox" name="job[<?php echo $job->job_id; ?>]" value="1"/>
508 <td class="column-job_id"><?php echo $job->job_id; ?></td>
509 <td class="column-title">
510 <?php echo esc_html( $job->post_title ); ?>
511 <div class="row-actions">
512 <span class="view"><?php echo $job->tm_post_link; ?></span>
515 <td class="column-type" data-colname=""><?php echo esc_html( $job->post_type ); ?></td>
516 <td class="column-languages"><?php echo $job->lang_text_with_flags; ?></td>
517 <td class="column-status"><span><i class="<?php echo esc_attr( $job->icon ); ?>"></i><?php echo esc_html( $job->status_text ); ?></span></td>
518 <td class="column-deadline">
520 if ( $job->deadline_date ) {
521 if ( '0000-00-00 00:00:00' === $job->deadline_date ) {
522 $deadline_day = __( 'Not set', 'wpml-translation-management' );
524 $deadline_day = date( 'Y-m-d', strtotime( $job->deadline_date ) );
526 echo esc_html( $deadline_day );
530 <td class="column-actions">
532 if ( $job->original_doc_id ) {
534 if ( array_key_exists( $job->job_id, $ate_jobs ) ) {
535 if ( array_key_exists( 'ate_job_id', $ate_jobs[ $job->job_id ] ) ) {
536 $ate_job_id = $ate_jobs[ $job->job_id ]['ate_job_id'];
540 <a class="button-secondary js-translation-queue-edit"
541 href="<?php echo esc_attr( $job->edit_url ); ?>"
542 data-job-id="<?php echo $job->job_id; ?>"
543 data-ate-job-id="<?php echo esc_attr( $ate_job_id ); ?>"
544 data-ate-job-url="<?php echo $job->edit_url; ?>"
545 data-ate-auto-open="<?php echo $job->job_id === $open_job; ?>"
547 <?php echo $job->button_text; ?>
552 <?php if ( $job->is_doing_job ) { ?>
554 <a class="link-resign"
555 href="<?php echo esc_attr( $job->resign_url ); ?>"
556 onclick="if ( !confirm( '<?php echo esc_js( $translation_jobs['strings']['confirm'] ); ?>' ) ) { return false; }">
557 <?php echo $job->resign_text; ?>
561 if ( $job->view_link ) {
563 echo $job->view_link;
577 private function get_job_id_from_request() {
579 * @var TranslationManagement $iclTranslationManagement
580 * @var WPML_Post_Translation $wpml_post_translations
581 * @var WPML_Translation_Job_Factory $wpml_translation_job_factory
583 global $iclTranslationManagement, $wpml_post_translations, $wpml_translation_job_factory, $sitepress;
585 $job_id = filter_var( isset( $_GET['job_id'] ) ? $_GET['job_id'] : '', FILTER_SANITIZE_NUMBER_INT );
587 list( $trid, $update_needed, $language_code, $element_type ) = $this->get_job_data_for_restore( $job_id );
588 $source_language_code = filter_var( isset( $_GET['source_language_code'] ) ? $_GET['source_language_code'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
590 if ( $trid && $language_code ) {
592 $job_id = $iclTranslationManagement->get_translation_job_id(
597 if ( ! $source_language_code ) {
598 $post_id = SitePress::get_original_element_id_by_trid( $trid );
600 $posts_in_trid = $wpml_post_translations->get_element_translations(
604 $post_id = isset( $posts_in_trid[ $source_language_code ] ) ? $posts_in_trid[ $source_language_code ] : false;
606 $blog_translators = wpml_tm_load_blog_translators();
608 'lang_from' => $source_language_code,
609 'lang_to' => $language_code,
612 if ( $post_id && $blog_translators->is_translator(
613 $sitepress->get_current_user()->ID,
617 $job_id = $wpml_translation_job_factory->create_local_post_job(
623 } elseif ( $update_needed ) {
624 $element_id = SitePress::get_original_element_id_by_trid( $trid );
625 $job_id = $wpml_translation_job_factory->create_local_job( $element_id, $language_code, null, $element_type );
635 * @return array ( trid, updated_needed, language_code )
637 private function get_job_data_for_restore( $job_id ) {
638 $fields = array( 'trid', 'update_needed', 'language_code', 'element_type' );
639 $result = array_fill_keys( $fields, false );
641 if ( isset( $_GET['trid'] ) ) {
642 $result['trid'] = filter_var( $_GET['trid'], FILTER_SANITIZE_NUMBER_INT );
644 if ( isset( $_GET['update_needed'] ) ) {
645 $result['update_needed'] = filter_var( $_GET['update_needed'], FILTER_SANITIZE_NUMBER_INT );
647 if ( isset( $_GET['language_code'] ) ) {
648 $result['language_code'] = filter_var( $_GET['language_code'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
651 $wpdb = $this->sitepress->get_wpdb();
653 if ( isset( $result['trid'] ) ) {
654 $element_type_query = $wpdb->prepare(
655 "SELECT element_type FROM {$wpdb->prefix}icl_translations WHERE trid = %d LIMIT 1",
659 $result['element_type'] = $wpdb->get_var( $element_type_query );
662 if ( ! $job_id || isset( $_GET['trid'], $_GET['update_needed'], $_GET['language_code'], $result['element_type'] ) ) {
665 $result['update_needed'],
666 $result['language_code'],
667 $result['element_type'],
672 SELECT t.trid, ts.needs_update as update_needed, t.language_code, t.element_type
673 FROM {$wpdb->prefix}icl_translations t
674 INNER JOIN {$wpdb->prefix}icl_translation_status ts on ts.translation_id = t.translation_id
675 INNER JOIN {$wpdb->prefix}icl_translate_job j ON j.rid = ts.rid
679 $db_result = $wpdb->get_row( $wpdb->prepare( $sql, $job_id ), ARRAY_A );
681 foreach ( $fields as $field ) {
682 if ( ! isset( $_GET[ $field ] ) ) {
683 $result[ $field ] = $db_result[ $field ];
687 return array( $result['trid'], $result['update_needed'], $result['language_code'], $result['element_type'] );
691 * @param stdClass $job
695 private function get_row_css_attribute( $job ) {
696 $classes = [ 'js-wpml-job-row' ];
698 if ( isset( $job->deadline_date ) && ICL_TM_COMPLETE !== (int) $job->status ) {
699 $deadline_day = date( 'Y-m-d', strtotime( $job->deadline_date ) );
700 $today = date( 'Y-m-d' );
702 if ( $deadline_day < $today ) {
703 $classes[] = 'overdue';
707 return ' class="' . esc_attr( implode( ' ', $classes ) ) . '" data-job-id="' . $job->job_id . '"';
713 private function must_open_the_editor() {
714 return ( isset( $_GET['job_id'] ) && $_GET['job_id'] > 0 )
715 || ( isset( $_GET['trid'] ) && $_GET['trid'] > 0 );
721 private function attempt_opening_ATE( $job_id ) {
722 if ( ! WPML_TM_ATE_Status::is_enabled_and_activated() ) {
726 // a job already exists
727 if ( isset( $_GET['job_id'] ) && $_GET['job_id'] > 0 ) {
728 $current_editor = wpml_tm_load_old_jobs_editor()->get( $job_id );
729 if ( WPML_TM_Editors::ATE !== $current_editor && WPML_TM_Editors::NONE !== $current_editor ) {
734 $editor_url = apply_filters( 'wpml_tm_ate_jobs_editor_url', null, $job_id, $this->get_return_url() );
737 make( \WPML\TM\ATE\Sync\Trigger::class )->setSyncRequiredForCurrentUser();
738 wpml_tm_load_old_jobs_editor()->set( $job_id, WPML_TM_Editors::ATE );
740 if ( wp_safe_redirect( $editor_url, 302, 'WPML' ) ) {
747 * @return mixed|null|string
749 private function get_return_url() {
752 if ( array_key_exists( 'return_url', $_GET ) ) {
753 $return_url = filter_var( $_GET['return_url'], FILTER_SANITIZE_URL );
755 $return_url_parts = wp_parse_url( $return_url );
757 $admin_url = get_admin_url();
758 $admin_url_parts = wp_parse_url( $admin_url );
760 if ( strpos( $return_url_parts['path'], $admin_url_parts['path'] ) === 0 ) {
761 $admin_url_parts['path'] = $return_url_parts['path'];
763 $admin_url_parts = $return_url_parts;
766 if ( array_key_exists( 'query', $return_url_parts ) ) {
767 $admin_url_parts['query'] = $this->filterQueryParameters( $return_url_parts['query'] );
770 $return_url = http_build_url( $admin_url_parts );
776 private function filterQueryParameters( $query ) {
778 parse_str( $query, $parameters );
780 unset( $parameters['ate_original_id'] );
781 unset( $parameters['back'] );
782 unset( $parameters['complete'] );
784 return http_build_query( $parameters );
790 public static function get_cookie_filters() {
793 if ( isset( $_COOKIE['wp-translation_ujobs_filter'] ) ) {
794 parse_str( $_COOKIE['wp-translation_ujobs_filter'], $filters );
796 $filters = filter_var_array(
799 'type' => FILTER_SANITIZE_STRING,
800 'from' => FILTER_SANITIZE_STRING,
801 'to' => FILTER_SANITIZE_STRING,
802 'status' => FILTER_SANITIZE_NUMBER_INT,
811 * @param \WPML_Translation_Job $job_object
813 private function mark_job_as_in_progress( \WPML_Translation_Job $job_object ) {
814 wpml_load_core_tm()->update_translation_status(
816 'translation_id' => $job_object->get_translation_id(),
817 'status' => ICL_TM_IN_PROGRESS,