first commit
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_ATE_Request_Activation_Email {
|
||||
|
||||
const REQUEST_ACTIVATION_TEMPLATE = 'notification/request-ate-activation.twig';
|
||||
|
||||
/** @var WPML_TM_Email_Notification_View */
|
||||
private $email_view;
|
||||
|
||||
public function __construct( WPML_TM_Email_Notification_View $email_view ) {
|
||||
$this->email_view = $email_view;
|
||||
}
|
||||
|
||||
public function send_email( $to_manager, $from_user ) {
|
||||
$site_name = get_option( 'blogname' );
|
||||
$translators_tab_url = WPML_TM_Page::get_translators_url();
|
||||
|
||||
$model = array(
|
||||
'setup_url' => esc_url( $translators_tab_url ),
|
||||
'casual_name' => $to_manager->user_firstname,
|
||||
'username' => $to_manager->display_name,
|
||||
'intro_message_1' => sprintf( __( 'The translator %1$s is requesting to use the Advanced Translation Editor on site %2$s.', 'wpml-translation-management' ), $from_user->display_name, $site_name ),
|
||||
'setup' => __( 'Advanced Translation Editor settings', 'wpml-translation-management' ),
|
||||
'reminder' => sprintf( __( '* Remember, your login name for %1$s is %2$s. If you need help with your password, use the password reset in the login page.', 'wpml-translation-management' ), $site_name, $to_manager->user_login ),
|
||||
);
|
||||
|
||||
$to = $to_manager->display_name . ' <' . $to_manager->user_email . '>';
|
||||
$message = $this->email_view->render_model( $model, self::REQUEST_ACTIVATION_TEMPLATE );
|
||||
$subject = sprintf( __( "Request to use WPML's Advanced Translation Editor by %s", 'wpml-translation-management' ), $site_name );
|
||||
|
||||
$headers = array(
|
||||
'MIME-Version: 1.0',
|
||||
'Content-type: text/html; charset=UTF-8',
|
||||
);
|
||||
|
||||
return wp_mail( $to, $subject, $message, $headers );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Daily_Summary_Report_Model implements WPML_TM_Jobs_Summary_Report_Model {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_subject() {
|
||||
return __( 'Translation updates for %1$s for %2$s', 'wpml-translation-management' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_summary_text() {
|
||||
return __( 'Today %1$s had the following %2$s translation updates', 'wpml-translation-management' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report_Process_Factory {
|
||||
|
||||
/** @var WPML_TM_Jobs_Summary_Report_View $template */
|
||||
private $template;
|
||||
|
||||
/** @var WPML_TM_Jobs_Summary_Report_Process $weekly_report */
|
||||
private $weekly_report;
|
||||
|
||||
/** @var WPML_TM_Jobs_Summary_Report_Process $daily_report */
|
||||
private $daily_report;
|
||||
|
||||
/**
|
||||
* @return WPML_TM_Jobs_Summary_Report_Process
|
||||
*/
|
||||
public function create_weekly_report() {
|
||||
if ( ! $this->weekly_report ) {
|
||||
$summary_report = $this->get_summary_report( WPML_TM_Jobs_Summary::WEEKLY_REPORT );
|
||||
|
||||
$this->weekly_report = new WPML_TM_Jobs_Summary_Report_Process(
|
||||
$this->get_template(),
|
||||
new WPML_TM_Jobs_Weekly_Summary_Report_Model(),
|
||||
$summary_report->get_jobs()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->weekly_report;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TM_Jobs_Summary_Report_Process
|
||||
*/
|
||||
public function create_daily_report() {
|
||||
if ( ! $this->daily_report ) {
|
||||
$summary_report = $this->get_summary_report( WPML_TM_Jobs_Summary::DAILY_REPORT );
|
||||
|
||||
$this->daily_report = new WPML_TM_Jobs_Summary_Report_Process(
|
||||
$this->get_template(),
|
||||
new WPML_TM_Jobs_Daily_Summary_Report_Model(),
|
||||
$summary_report->get_jobs()
|
||||
);
|
||||
}
|
||||
|
||||
return $this->daily_report;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $frequency
|
||||
*
|
||||
* @return WPML_TM_Jobs_Summary_Report
|
||||
*/
|
||||
private function get_summary_report( $frequency ) {
|
||||
global $sitepress, $wpdb;
|
||||
|
||||
$word_count_records_factory = new WPML_TM_Word_Count_Records_Factory();
|
||||
$word_count_records = $word_count_records_factory->create();
|
||||
$single_process_factory = new WPML_TM_Word_Count_Single_Process_Factory();
|
||||
$single_process = $single_process_factory->create();
|
||||
|
||||
return new WPML_TM_Jobs_Summary_Report(
|
||||
new WPML_Translation_Jobs_Collection( $wpdb, array() ),
|
||||
new WPML_TM_String( false, $word_count_records, $single_process ),
|
||||
new WPML_TM_Post( false, $word_count_records, $single_process ),
|
||||
$frequency,
|
||||
new WPML_Translation_Element_Factory( $sitepress )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TM_Jobs_Summary_Report_View
|
||||
*/
|
||||
private function get_template() {
|
||||
if ( ! $this->template ) {
|
||||
$template_service_factory = new WPML_TM_Email_Twig_Template_Factory();
|
||||
$this->template = new WPML_TM_Jobs_Summary_Report_View( $template_service_factory->create() );
|
||||
}
|
||||
|
||||
return $this->template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report_Process {
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Jobs_Summary_Report_View
|
||||
*/
|
||||
private $view;
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Jobs_Summary_Report_Model
|
||||
*/
|
||||
private $report_model;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $jobs;
|
||||
|
||||
public function __construct(
|
||||
WPML_TM_Jobs_Summary_Report_View $view,
|
||||
WPML_TM_Jobs_Summary_Report_Model $report_model,
|
||||
array $jobs
|
||||
) {
|
||||
$this->view = $view;
|
||||
$this->report_model = $report_model;
|
||||
$this->jobs = $jobs;
|
||||
}
|
||||
|
||||
public function send() {
|
||||
foreach ( $this->jobs as $manager_id => $jobs ) {
|
||||
if ( array_key_exists( WPML_TM_Jobs_Summary::JOBS_COMPLETED_KEY, $jobs ) ) {
|
||||
$this->view
|
||||
->set_jobs( $jobs )
|
||||
->set_manager_id( $manager_id )
|
||||
->set_summary_text( $this->report_model->get_summary_text() );
|
||||
|
||||
$this->send_email( $manager_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $manager_id
|
||||
*/
|
||||
private function send_email( $manager_id ) {
|
||||
wp_mail(
|
||||
get_userdata( $manager_id )->user_email,
|
||||
sprintf( $this->report_model->get_subject(), get_bloginfo( 'name' ), date( 'd/F/Y', time() ) ),
|
||||
$this->view->get_report_content(),
|
||||
array(
|
||||
'MIME-Version: 1.0',
|
||||
'Content-type: text/html; charset=UTF-8',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report_View extends WPML_TM_Email_View {
|
||||
|
||||
const WEEKLY_SUMMARY_TEMPLATE = 'notification/summary/summary.twig';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $jobs;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $manager_id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $summary_text;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_report_content() {
|
||||
$model = $this->get_model();
|
||||
$content = $this->render_header( $model['username'] );
|
||||
$content .= $this->template_service->show( $model, self::WEEKLY_SUMMARY_TEMPLATE );
|
||||
$content .= $this->render_email_footer();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_model() {
|
||||
return array(
|
||||
'username' => get_userdata( $this->manager_id )->display_name,
|
||||
'jobs' => $this->jobs,
|
||||
'text' => $this->summary_text,
|
||||
'site_name' => get_bloginfo( 'name' ),
|
||||
'number_of_updates' => isset( $this->jobs['completed'] ) ? count( $this->jobs['completed'] ) : 0,
|
||||
'strings' => array(
|
||||
'jobs_waiting' => __( 'Jobs that are waiting for translation', 'wpml-translation-management' ),
|
||||
'original_page' => __( 'Original Page', 'wpml-translation-management' ),
|
||||
'translation' => __( 'Translation', 'wpml-translation-management' ),
|
||||
'translator' => __( 'Translator', 'wpml-translation-management' ),
|
||||
'updated' => __( 'Updated / Translated', 'wpml-translation-management' ),
|
||||
'date' => __( 'Date', 'wpml-translation-management' ),
|
||||
'your_deadline' => __( 'Your deadline', 'wpml-translation-management' ),
|
||||
'translation_languages' => __( 'Translation languages', 'wpml-translation-management' ),
|
||||
'number_of_pages' => __( 'Number of pages', 'wpml-translation-management' ),
|
||||
'number_of_strings' => __( 'Number of strings', 'wpml-translation-management' ),
|
||||
'number_of_words' => __( 'Number of words', 'wpml-translation-management' ),
|
||||
'undefined' => __( 'Undefined', 'wpml-translation-management' ),
|
||||
),
|
||||
'improve_quality' => array(
|
||||
'title' => __( 'Want to improve the quality of your site’s translation?', 'wpml-translation-management' ),
|
||||
'options' => array(
|
||||
array(
|
||||
'link_url' => admin_url( 'admin.php?page=' . WPML_PLUGIN_FOLDER . '/menu/languages.php#wpml-translation-feedback-options' ),
|
||||
'link_text' => __( 'Translation Feedback', 'wpml-translation-management' ),
|
||||
'text' => __( 'Allow visitors to tell you about translation issues by enabling %s', 'wpml-translation-management' ),
|
||||
),
|
||||
array(
|
||||
'link_url' => admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=translators' ),
|
||||
'link_text' => __( 'translation services that are integrated with WPML', 'wpml-translation-management' ),
|
||||
'text' => __( 'Try one of the %s', 'wpml-translation-management' ),
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $jobs
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_jobs( $jobs ) {
|
||||
$this->jobs = $jobs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $manager_id
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_manager_id( $manager_id ) {
|
||||
$this->manager_id = $manager_id;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $summary_text
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function set_summary_text( $summary_text ) {
|
||||
$this->summary_text = $summary_text;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report {
|
||||
|
||||
/**
|
||||
* @var WPML_Translation_Jobs_Collection
|
||||
*/
|
||||
private $jobs_collection;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $jobs = array();
|
||||
|
||||
/**
|
||||
* @var WPML_TM_String
|
||||
*/
|
||||
private $string_counter;
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Post
|
||||
*/
|
||||
private $post_counter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var WPML_Translation_Element_Factory
|
||||
*/
|
||||
private $element_factory;
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Collection $jobs_collection,
|
||||
WPML_TM_String $string_counter,
|
||||
WPML_TM_Post $post_counter,
|
||||
$type,
|
||||
WPML_Translation_Element_Factory $element_factory
|
||||
) {
|
||||
$this->jobs_collection = $jobs_collection;
|
||||
$this->string_counter = $string_counter;
|
||||
$this->post_counter = $post_counter;
|
||||
$this->type = $type;
|
||||
$this->element_factory = $element_factory;
|
||||
$this->build_completed_jobs();
|
||||
$this->build_waiting_jobs();
|
||||
}
|
||||
|
||||
private function build_completed_jobs() {
|
||||
$jobs = $this->jobs_collection->get_jobs( array(
|
||||
'any_translation_service' => true,
|
||||
'status' => ICL_TM_COMPLETE
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $jobs as $job ) {
|
||||
$completed_date = $job instanceof WPML_Post_Translation_Job || $job instanceof WPML_Element_Translation_Job ? $job->get_completed_date() : '';
|
||||
$out_of_period = strtotime( $completed_date ) < strtotime( '-' . WPML_TM_Jobs_Summary::WEEKLY_SCHEDULE );
|
||||
|
||||
if ( WPML_TM_Jobs_Summary::DAILY_REPORT === $this->type ) {
|
||||
$out_of_period = strtotime( $completed_date ) < strtotime( '-' . WPML_TM_Jobs_Summary::DAILY_SCHEDULE );
|
||||
}
|
||||
|
||||
if ( ! $completed_date || $out_of_period ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$original_element = $this->element_factory->create( $job->get_original_element_id(), $job->get_type() );
|
||||
$translation_element = $original_element->get_translation( $job->get_language_code() );
|
||||
|
||||
|
||||
$this->jobs[ $job->get_basic_data()->manager_id ][ WPML_TM_Jobs_Summary::JOBS_COMPLETED_KEY ][] = array(
|
||||
'completed_date' => date_i18n( get_option( 'date_format', 'F d, Y' ), strtotime( $job->get_completed_date() ) ),
|
||||
'original_page' => array(
|
||||
'title' => $job->get_title(),
|
||||
'url' => $job->get_url( true ),
|
||||
),
|
||||
'translated_page' => array(
|
||||
'title' => get_the_title( $translation_element->get_element_id() ) . ' (' . $job->get_language_code() . ')',
|
||||
'url' => get_the_permalink( $translation_element->get_element_id() ),
|
||||
),
|
||||
'translator' => $this->get_translator_name( $job ),
|
||||
'deadline' => $job->get_deadline_date() ?
|
||||
date_i18n( get_option( 'date_format', 'F d, Y' ), strtotime( $job->get_deadline_date() ) ) :
|
||||
'',
|
||||
'status' => $job->get_status(),
|
||||
'overdue' => $job->get_deadline_date() &&
|
||||
strtotime( $job->get_deadline_date() ) < strtotime( $job->get_completed_date() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function build_waiting_jobs() {
|
||||
$jobs = $this->jobs_collection->get_jobs( array(
|
||||
'any_translation_service' => true,
|
||||
'status' => ICL_TM_WAITING_FOR_TRANSLATOR
|
||||
)
|
||||
);
|
||||
$counters = array();
|
||||
$number_of_strings = 0;
|
||||
$number_of_words_in_strings = 0;
|
||||
|
||||
foreach ( $jobs as $job ) {
|
||||
$manager_id = isset( $job->get_basic_data()->manager_id ) ? $job->get_basic_data()->manager_id : 0;
|
||||
$lang_pair = $job->get_source_language_code() . '|' . $job->get_language_code();
|
||||
|
||||
if ( ! isset( $counters[ $manager_id ][ $lang_pair ]['number_of_strings'], $counters[ $manager_id ][ $lang_pair ]['number_of_words'], $counters[ $manager_id ][ $lang_pair ]['number_of_pages'] ) ) {
|
||||
$counters[ $manager_id ][ $lang_pair ]['number_of_strings'] = 0;
|
||||
$counters[ $manager_id ][ $lang_pair ]['number_of_words'] = 0;
|
||||
$counters[ $manager_id ][ $lang_pair ]['number_of_pages'] = 0;
|
||||
}
|
||||
|
||||
if ( 'String' === $job->get_type() ) {
|
||||
$this->string_counter->set_id( $job->get_original_element_id() );
|
||||
$number_of_strings ++;
|
||||
$number_of_words_in_strings += $this->string_counter->get_words_count();
|
||||
} else {
|
||||
$this->post_counter->set_id( $job->get_original_element_id() );
|
||||
$counters[ $manager_id ][ $lang_pair ]['number_of_pages'] += 1;
|
||||
$counters[ $manager_id ][ $lang_pair ]['number_of_words'] += $this->post_counter->get_words_count();
|
||||
|
||||
$this->jobs[ $manager_id ][ WPML_TM_Jobs_Summary::JOBS_WAITING_KEY ][ $lang_pair ] = array(
|
||||
'lang_pair' => $job->get_source_language_code( true ) . ' ' . __( 'to', 'wpml-translation-management' ) . ' ' . $job->get_language_code( true ),
|
||||
'number_of_strings' => $number_of_strings,
|
||||
'number_of_words' => $counters[ $manager_id ][ $lang_pair ]['number_of_words'] + $number_of_words_in_strings,
|
||||
'number_of_pages' => $counters[ $manager_id ][ $lang_pair ]['number_of_pages'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Element_Translation_Job $job
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_translator_name( WPML_Element_Translation_Job $job ) {
|
||||
$translator_name = $job->get_translation_service() ?
|
||||
TranslationProxy::get_service_name( $job->get_translation_service() ) :
|
||||
$job->get_translator_name();
|
||||
|
||||
if ( 'local' === $job->get_translation_service() ) {
|
||||
$user = get_userdata( $job->get_translator_id() );
|
||||
$translator_name = $user->display_name . ' (' . $user->user_login . ')';
|
||||
}
|
||||
|
||||
return $translator_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_jobs() {
|
||||
return $this->jobs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary {
|
||||
|
||||
const WEEKLY_REPORT = 'weekly';
|
||||
const DAILY_REPORT = 'daily';
|
||||
const DAILY_SCHEDULE = '1 day';
|
||||
const WEEKLY_SCHEDULE = '1 week';
|
||||
const JOBS_COMPLETED_KEY = 'completed';
|
||||
const JOBS_WAITING_KEY = 'waiting';
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Weekly_Summary_Report_Model implements WPML_TM_Jobs_Summary_Report_Model {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_subject() {
|
||||
return __( 'Translation updates for %1$s until %2$s', 'wpml-translation-management' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_summary_text() {
|
||||
return __( 'This week %1$s had the following %2$s translation updates', 'wpml-translation-management' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
interface WPML_TM_Jobs_Summary_Report_Model {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_subject();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_summary_text();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report_Hooks_Factory implements IWPML_Frontend_Action_Loader, IWPML_Backend_Action_Loader {
|
||||
|
||||
/**
|
||||
* @return WPML_TM_Jobs_Summary_Report_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
global $iclTranslationManagement;
|
||||
|
||||
return new WPML_TM_Jobs_Summary_Report_Hooks(
|
||||
new WPML_TM_Jobs_Summary_Report_Process_Factory(),
|
||||
$iclTranslationManagement
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Jobs_Summary_Report_Hooks {
|
||||
|
||||
const EVENT_HOOK = 'wpml_tm_send_summary_report';
|
||||
const EVENT_CALLBACK = 'send_summary_report';
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Jobs_Summary_Report_Process_Factory
|
||||
*/
|
||||
private $process_factory;
|
||||
|
||||
/**
|
||||
* @var TranslationManagement
|
||||
*/
|
||||
private $tm;
|
||||
|
||||
public function __construct( WPML_TM_Jobs_Summary_Report_Process_Factory $process_factory, TranslationManagement $tm ) {
|
||||
$this->process_factory = $process_factory;
|
||||
$this->tm = $tm;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( $this->notification_setting_allow_scheduling() ) {
|
||||
add_action( self::EVENT_HOOK, array( $this, self::EVENT_CALLBACK ) );
|
||||
add_action( 'init', array( $this, 'schedule_email' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function notification_setting_allow_scheduling() {
|
||||
$schedulable_settings = array(
|
||||
WPML_TM_Emails_Settings::NOTIFY_DAILY,
|
||||
WPML_TM_Emails_Settings::NOTIFY_WEEKLY
|
||||
);
|
||||
|
||||
return isset( $this->tm->settings['notification'][ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] ) &&
|
||||
in_array(
|
||||
(int) $this->tm->settings['notification'][ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ],
|
||||
$schedulable_settings,
|
||||
true
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function send_summary_report() {
|
||||
if ( WPML_TM_Emails_Settings::NOTIFY_DAILY === (int) $this->tm->settings['notification'][ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] ) {
|
||||
$summary_report_process = $this->process_factory->create_daily_report();
|
||||
} else {
|
||||
$summary_report_process = $this->process_factory->create_weekly_report();
|
||||
}
|
||||
|
||||
if ( $summary_report_process ) {
|
||||
$summary_report_process->send();
|
||||
}
|
||||
}
|
||||
|
||||
public function schedule_email() {
|
||||
if ( ! wp_next_scheduled( self::EVENT_HOOK ) ) {
|
||||
wp_schedule_single_event( $this->get_schedule_time(), self::EVENT_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function get_schedule_time() {
|
||||
$schedule_time = strtotime( '+ ' . WPML_TM_Jobs_Summary::DAILY_SCHEDULE );
|
||||
|
||||
if ( WPML_TM_Emails_Settings::NOTIFY_WEEKLY === (int) $this->tm->settings['notification'][ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] ) {
|
||||
$schedule_time = strtotime( '+ ' . WPML_TM_Jobs_Summary::WEEKLY_SCHEDULE );
|
||||
}
|
||||
|
||||
return $schedule_time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Email_Notification_View extends WPML_TM_Email_View {
|
||||
|
||||
const PROMOTE_TRANSLATION_SERVICES_TEMPLATE = 'notification/promote-translation-services.twig';
|
||||
|
||||
/**
|
||||
* @param array $model
|
||||
* @param string $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_model( array $model, $template ) {
|
||||
if ( isset( $model['casual_name'] ) && $model['casual_name'] ) {
|
||||
$content = $this->render_casual_header( $model['casual_name'] );
|
||||
} else {
|
||||
$content = $this->render_header( $model['username'] );
|
||||
}
|
||||
$content .= $this->template_service->show( $model, $template );
|
||||
$content .= $this->render_promote_translation_services( $model );
|
||||
$content .= $this->render_footer();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $model
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_promote_translation_services( array $model ) {
|
||||
$content = '';
|
||||
|
||||
if ( isset( $model['promote_translation_services'] ) && $model['promote_translation_services'] ) {
|
||||
$translation_services_url = esc_url( admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=translators' ) );
|
||||
|
||||
/* translators: Promote translation services: %s replaced by "professional translation services integrated with WPML" */
|
||||
$promoteA = esc_html_x( 'Need faster translation work? Try one of the %s.', 'Promote translation services: %s replaced by "professional translation services integrated with WPML"', 'wpml-translation-management' );
|
||||
/* translators: Promote translation services: Promote translation services: used to build a link to the translation services page */
|
||||
$promoteB = esc_html_x( 'professional translation services integrated with WPML', 'Promote translation services: used to build a link to the translation services page', 'wpml-translation-management' );
|
||||
|
||||
$promote_model['message'] = sprintf( $promoteA, '<a href="' . $translation_services_url . '">' . $promoteB . '</a>' );
|
||||
|
||||
$content = $this->template_service->show( $promote_model, self::PROMOTE_TRANSLATION_SERVICES_TEMPLATE );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function render_footer() {
|
||||
$notifications_url = esc_url( admin_url( 'admin.php?page=' . WPML_TM_FOLDER . WPML_Translation_Management::PAGE_SLUG_SETTINGS . '&sm=notifications' ) );
|
||||
$notifications_text = esc_html__( 'WPML Notification Settings', 'wpml-translation-management' );
|
||||
$notifications_link = '<a href="' . $notifications_url . '" style="color: #ffffff;">' . $notifications_text . '</a>';
|
||||
|
||||
$bottom_text = sprintf(
|
||||
esc_html__(
|
||||
'To stop receiving notifications, log-in to %s and change your preferences.',
|
||||
'wpml-translation-management'
|
||||
),
|
||||
$notifications_link
|
||||
);
|
||||
|
||||
return $this->render_email_footer( $bottom_text );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Overdue_Jobs_Report_Factory {
|
||||
|
||||
public function create() {
|
||||
global $wpdb, $iclTranslationManagement, $sitepress;
|
||||
|
||||
$jobs_collection = new WPML_Translation_Jobs_Collection( $wpdb, array() );
|
||||
$email_template_service_factory = wpml_tm_get_email_twig_template_factory();
|
||||
$report_email_view = new WPML_TM_Email_Notification_View( $email_template_service_factory->create() );
|
||||
$has_active_remote_service = TranslationProxy::is_current_service_active_and_authenticated();
|
||||
$notification_settings = $iclTranslationManagement->settings['notification'];
|
||||
$tp_jobs_factory = new WPML_TP_Jobs_Collection_Factory();
|
||||
$tp_jobs = $tp_jobs_factory->create();
|
||||
|
||||
return new WPML_TM_Overdue_Jobs_Report(
|
||||
$jobs_collection,
|
||||
$report_email_view,
|
||||
$has_active_remote_service,
|
||||
$notification_settings,
|
||||
$sitepress,
|
||||
$tp_jobs
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Overdue_Jobs_Report {
|
||||
|
||||
const OVERDUE_JOBS_REPORT_TEMPLATE = 'notification/overdue-jobs-report.twig';
|
||||
|
||||
/** @var WPML_Translation_Jobs_Collection $jobs_collection */
|
||||
private $jobs_collection;
|
||||
|
||||
/** @var WPML_TM_Email_Notification_View $email_view */
|
||||
private $email_view;
|
||||
|
||||
/** @var bool $has_active_remote_service */
|
||||
private $has_active_remote_service;
|
||||
|
||||
/** @var array $notification_settings */
|
||||
private $notification_settings;
|
||||
|
||||
private $sitepress;
|
||||
|
||||
private $tp_jobs;
|
||||
|
||||
/**
|
||||
* @param WPML_Translation_Jobs_Collection $jobs_collection
|
||||
* @param WPML_TM_Email_Notification_View $email_view
|
||||
* @param bool $has_active_remote_service
|
||||
* @param array $notification_settings
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_TP_Jobs_Collection|null $tp_jobs
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_Translation_Jobs_Collection $jobs_collection,
|
||||
WPML_TM_Email_Notification_View $email_view,
|
||||
$has_active_remote_service,
|
||||
array $notification_settings,
|
||||
SitePress $sitepress,
|
||||
WPML_TP_Jobs_Collection $tp_jobs = null
|
||||
) {
|
||||
$this->jobs_collection = $jobs_collection;
|
||||
$this->email_view = $email_view;
|
||||
$this->has_active_remote_service = $has_active_remote_service;
|
||||
$this->notification_settings = $notification_settings;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->tp_jobs = $tp_jobs;
|
||||
}
|
||||
|
||||
public function send() {
|
||||
$jobs_by_manager_id = $this->get_overdue_jobs_by_manager_id();
|
||||
|
||||
if ( $jobs_by_manager_id ) {
|
||||
$current_language = $this->sitepress->get_current_language();
|
||||
$this->sitepress->switch_lang( $this->sitepress->get_default_language() );
|
||||
foreach ( $jobs_by_manager_id as $manager_id => $jobs ) {
|
||||
$this->send_email( $manager_id, $jobs );
|
||||
}
|
||||
$this->sitepress->switch_lang( $current_language );
|
||||
}
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_overdue_jobs_by_manager_id() {
|
||||
$args = array(
|
||||
'overdue' => true,
|
||||
'translator_id' => '',
|
||||
);
|
||||
|
||||
$jobs = $this->jobs_collection->get_jobs( $args );
|
||||
$jobs_by_manager_id = array();
|
||||
|
||||
foreach ( $jobs as $key => $job ) {
|
||||
|
||||
if ( $this->tp_jobs && $this->tp_jobs->is_job_canceled( $job ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $job instanceof WPML_Element_Translation_Job ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $job->get_number_of_days_overdue() < $this->notification_settings['overdue_offset'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$job->get_basic_data();
|
||||
$jobs_by_manager_id[ $job->get_manager_id() ][] = $job;
|
||||
}
|
||||
|
||||
return $jobs_by_manager_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $manager_id
|
||||
* @param array $jobs
|
||||
*/
|
||||
private function send_email( $manager_id, array $jobs ) {
|
||||
$manager = get_user_by( 'id', $manager_id );
|
||||
|
||||
$translation_jobs_url = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=jobs' );
|
||||
|
||||
/* translators: List of translation jobs: %s replaced by "list of translation jobs" */
|
||||
$message_to_translation_jobsA = esc_html_x( 'You can see all the jobs that you sent and their deadlines in the %s.', 'List of translation jobs: %s replaced by "list of translation jobs"', 'wpml-translation-management' );
|
||||
/* translators: List of translation jobs: used to build a link to the translation jobs page */
|
||||
$message_to_translation_jobsB = esc_html_x( 'list of translation jobs', 'List of translation jobs: used to build a link to the translation jobs page', 'wpml-translation-management' );
|
||||
|
||||
$message_to_translation_jobs = sprintf(
|
||||
$message_to_translation_jobsA,
|
||||
'<a href="' . esc_url( $translation_jobs_url ) . '">' . $message_to_translation_jobsB . '</a>'
|
||||
);
|
||||
|
||||
$model = array(
|
||||
'username' => $manager->display_name,
|
||||
'intro_message_1' => __( 'This is a quick reminder about translation jobs that you sent and are behind schedule.', 'wpml-translation-management' ),
|
||||
'intro_message_2' => __( 'The deadline that you set for the following jobs has passed:', 'wpml-translation-management' ),
|
||||
'jobs' => $jobs,
|
||||
'job_deadline_details' => __( 'deadline: %1$s, late by %2$d days', 'wpml-translation-management' ),
|
||||
'message_to_translation_jobs' => $message_to_translation_jobs,
|
||||
'promote_translation_services' => ! $this->has_active_remote_service,
|
||||
);
|
||||
|
||||
$to = $manager->display_name . ' <' . $manager->user_email . '>';
|
||||
$subject = esc_html__( 'Overdue translation jobs report', 'wpml-translation-management' );
|
||||
$message = $this->email_view->render_model( $model, self::OVERDUE_JOBS_REPORT_TEMPLATE );
|
||||
|
||||
$headers = array(
|
||||
'MIME-Version: 1.0',
|
||||
'Content-type: text/html; charset=UTF-8',
|
||||
);
|
||||
|
||||
wp_mail( $to, $subject, $message, $headers );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Batch_Report_Email
|
||||
*/
|
||||
class WPML_TM_Batch_Report_Email_Builder {
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Batch_Report
|
||||
*/
|
||||
private $batch_report;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $emails;
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Email_Jobs_Summary_View
|
||||
*/
|
||||
private $email_template;
|
||||
|
||||
/**
|
||||
* WPML_TM_Notification_Batch_Email constructor.
|
||||
*
|
||||
* @param WPML_TM_Batch_Report $batch_report
|
||||
* @param WPML_TM_Email_Jobs_Summary_View $email_template
|
||||
*/
|
||||
public function __construct( WPML_TM_Batch_Report $batch_report, WPML_TM_Email_Jobs_Summary_View $email_template ) {
|
||||
$this->batch_report = $batch_report;
|
||||
$this->email_template = $email_template;
|
||||
$this->emails = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $batch_jobs
|
||||
*/
|
||||
public function prepare_assigned_jobs_emails( $batch_jobs ) {
|
||||
foreach ( $batch_jobs as $translator_id => $language_pairs ) {
|
||||
|
||||
if ( 0 !== $translator_id ) {
|
||||
|
||||
$translator = get_userdata( $translator_id );
|
||||
$title = __( 'You have been assigned to new translation job(s):', 'wpml-translation-management' );
|
||||
$render_jobs_list = $this->email_template->render_jobs_list( $language_pairs, $translator_id, $title );
|
||||
|
||||
if ( null === $render_jobs_list ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$body = $this->email_template->render_header( $translator->display_name );
|
||||
$body .= $render_jobs_list;
|
||||
|
||||
$assigned_jobs = $this->email_template->get_assigned_jobs();
|
||||
$title_singular = __( 'There is 1 job, which you can take (not specifically assigned to you):', 'wpml-translation-management' );
|
||||
$title_plural = __( 'There are %s jobs, which you can take (not specifically assigned to you):', 'wpml-translation-management' );
|
||||
$unassigned_jobs_body = $this->email_template->render_jobs_list(
|
||||
$this->batch_report->get_unassigned_jobs(),
|
||||
$translator_id,
|
||||
$title_singular,
|
||||
$title_plural
|
||||
);
|
||||
|
||||
if ( null !== $unassigned_jobs_body ) {
|
||||
$body .= $unassigned_jobs_body;
|
||||
}
|
||||
|
||||
$body .= $this->email_template->render_footer();
|
||||
$email['body'] = $body;
|
||||
$email = $this->add_attachments( $email, $assigned_jobs );
|
||||
$this->emails[] = array(
|
||||
'translator_id' => $translator->ID,
|
||||
'email' => $translator->user_email,
|
||||
'subject' => $this->get_subject_assigned_job(),
|
||||
'body' => $body,
|
||||
'attachment' => array_key_exists( 'attachment', $email ) ? $email['attachment'] : array(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $batch_jobs
|
||||
*/
|
||||
public function prepare_unassigned_jobs_emails( $batch_jobs ) {
|
||||
if ( array_key_exists( 0, $batch_jobs ) ) {
|
||||
|
||||
$unassigned_jobs = $batch_jobs[0];
|
||||
$translators = $this->batch_report->get_unassigned_translators();
|
||||
$title_singular = __( 'There is 1 job waiting for a translator:', 'wpml-translation-management' );
|
||||
$title_plural = __( 'There are %s jobs waiting for a translator:', 'wpml-translation-management' );
|
||||
|
||||
foreach ( $translators as $translator ) {
|
||||
|
||||
$translator_user = get_userdata( $translator );
|
||||
$render_jobs_list = $this->email_template->render_jobs_list( $unassigned_jobs, $translator_user->ID, $title_singular, $title_plural );
|
||||
|
||||
if ( null !== $render_jobs_list ) {
|
||||
$body = $this->email_template->render_header( $translator_user->display_name );
|
||||
$body .= $render_jobs_list;
|
||||
$body .= $this->email_template->render_footer();
|
||||
|
||||
$this->emails[] = array(
|
||||
'translator_id' => $translator_user->ID,
|
||||
'email' => $translator_user->user_email,
|
||||
'subject' => $this->get_subject_unassigned_job(),
|
||||
'body' => $body,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $email
|
||||
* @param array $jobs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function add_attachments( $email, $jobs ) {
|
||||
$attachments = array();
|
||||
foreach ( $jobs as $job ) {
|
||||
if ( 'post' === $job['type'] ) {
|
||||
$email = apply_filters( 'wpml_new_job_notification', $email, $job['job_id'] );
|
||||
if ( array_key_exists( 'attachment', $email ) ) {
|
||||
$attachments[] = $email['attachment'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $attachments ) {
|
||||
$attachments = apply_filters( 'wpml_new_job_notification_attachments', $attachments );
|
||||
if ( count( $attachments ) > 0 ) {
|
||||
$attachment_values = array_values( $attachments );
|
||||
$email['attachment'] = $attachment_values[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_subject_assigned_job() {
|
||||
return sprintf( __( 'New translation job from %s', 'wpml-translation-management' ), get_bloginfo( 'name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_subject_unassigned_job() {
|
||||
return sprintf( __( 'Job waiting for a translator in %s', 'wpml-translation-management' ), get_bloginfo( 'name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_emails() {
|
||||
return $this->emails;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Batch_Report_Email_Process
|
||||
*/
|
||||
class WPML_TM_Batch_Report_Email_Process {
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Batch_Report
|
||||
*/
|
||||
private $batch_report;
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Batch_Report_Email_Builder
|
||||
*/
|
||||
private $email_builder;
|
||||
|
||||
/**
|
||||
* WPML_TM_Batch_Report_Email_Process constructor.
|
||||
*
|
||||
* @param WPML_TM_Batch_Report $batch_report
|
||||
* @param WPML_TM_Batch_Report_Email_Builder $email_builder
|
||||
*/
|
||||
public function __construct( WPML_TM_Batch_Report $batch_report, WPML_TM_Batch_Report_Email_Builder $email_builder ) {
|
||||
$this->batch_report = $batch_report;
|
||||
$this->email_builder = $email_builder;
|
||||
}
|
||||
|
||||
public function process_emails() {
|
||||
$batch_jobs = $this->batch_report->get_jobs();
|
||||
|
||||
$this->email_builder->prepare_assigned_jobs_emails( $batch_jobs );
|
||||
$this->email_builder->prepare_unassigned_jobs_emails( $batch_jobs );
|
||||
|
||||
$this->send_emails();
|
||||
}
|
||||
|
||||
private function send_emails() {
|
||||
$headers = array();
|
||||
$headers[] = 'Content-type: text/html; charset=UTF-8';
|
||||
|
||||
foreach ( $this->email_builder->get_emails() as $email ) {
|
||||
$email['attachment'] = isset( $email['attachment'] ) ? $email['attachment'] : array();
|
||||
$email_sent = wp_mail( $email['email'], $email['subject'], $email['body'], $headers, $email['attachment'] );
|
||||
|
||||
if ( $email_sent ) {
|
||||
$this->batch_report->reset_batch_report( $email['translator_id'] );
|
||||
}
|
||||
}
|
||||
|
||||
$this->batch_report->reset_batch_report( 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Notification_Batch_Hooks
|
||||
*/
|
||||
class WPML_TM_Batch_Report_Hooks {
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Batch_Report
|
||||
*/
|
||||
private $batch_report;
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Batch_Report_Email_Process
|
||||
*/
|
||||
private $email_process;
|
||||
|
||||
/**
|
||||
* WPML_TM_Batch_Report_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TM_Batch_Report $batch_report
|
||||
* @param WPML_TM_Batch_Report_Email_Process $email_process
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TM_Batch_Report $batch_report,
|
||||
WPML_TM_Batch_Report_Email_Process $email_process
|
||||
) {
|
||||
$this->batch_report = $batch_report;
|
||||
$this->email_process = $email_process;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_tm_assign_job_notification', array( $this, 'set_job' ) );
|
||||
add_action( 'wpml_tm_new_job_notification', array( $this, 'set_job' ), 10, 2 );
|
||||
add_action( 'wpml_tm_local_string_sent', array( $this, 'set_job' ) );
|
||||
add_action( 'wpml_tm_basket_committed', array( $this->email_process, 'process_emails' ) );
|
||||
}
|
||||
|
||||
public function set_job( $job ) {
|
||||
if ( $job instanceof WPML_Translation_Job ) {
|
||||
$this->batch_report->set_job( $job );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Batch_Report
|
||||
*/
|
||||
class WPML_TM_Batch_Report {
|
||||
|
||||
const BATCH_REPORT_OPTION = '_wpml_batch_report';
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Blog_Translators
|
||||
*/
|
||||
private $blog_translators;
|
||||
|
||||
/**
|
||||
* WPML_TM_Batch_Report constructor.
|
||||
*
|
||||
* @param WPML_TM_Blog_Translators $blog_translators
|
||||
*/
|
||||
public function __construct( WPML_TM_Blog_Translators $blog_translators) {
|
||||
$this->blog_translators = $blog_translators;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Translation_Job $job
|
||||
*/
|
||||
public function set_job( WPML_Translation_Job $job ) {
|
||||
$batch_jobs = $batch_jobs_raw = $this->get_jobs();
|
||||
$job_fields = $job->get_basic_data();
|
||||
|
||||
if ( WPML_User_Jobs_Notification_Settings::is_new_job_notification_enabled( $job_fields->translator_id ) ) {
|
||||
$lang_pair = $job_fields->source_language_code . '|' . $job_fields->language_code;
|
||||
$batch_jobs[ (int) $job_fields->translator_id ][$lang_pair][] = array(
|
||||
'element_id' => isset( $job_fields->original_doc_id ) ? $job_fields->original_doc_id : null,
|
||||
'type' => strtolower( $job->get_type() ),
|
||||
'job_id' => $job->get_id(),
|
||||
);
|
||||
}
|
||||
|
||||
if ( $batch_jobs_raw !== $batch_jobs ) {
|
||||
update_option( self::BATCH_REPORT_OPTION, $batch_jobs, 'no' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_unassigned_jobs() {
|
||||
$batch_jobs = $this->get_jobs();
|
||||
$unassigned_jobs = array();
|
||||
|
||||
if( array_key_exists( 0, $batch_jobs ) ) {
|
||||
$unassigned_jobs = $batch_jobs[0];
|
||||
}
|
||||
|
||||
return $unassigned_jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_unassigned_translators() {
|
||||
$assigned_translators = array_keys( $this->get_jobs() );
|
||||
$blog_translators = wp_list_pluck( $this->blog_translators->get_blog_translators() , 'ID');
|
||||
|
||||
return array_diff( $blog_translators, $assigned_translators );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_jobs() {
|
||||
return get_option( self::BATCH_REPORT_OPTION ) ? get_option( self::BATCH_REPORT_OPTION ) : array();
|
||||
}
|
||||
|
||||
public function reset_batch_report( $translator_id ) {
|
||||
$batch_jobs = $this->get_jobs();
|
||||
if ( array_key_exists( $translator_id, $batch_jobs ) ) {
|
||||
unset( $batch_jobs[$translator_id] );
|
||||
}
|
||||
|
||||
update_option( self::BATCH_REPORT_OPTION, $batch_jobs, 'no' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Email_Jobs_Summary_View
|
||||
*/
|
||||
class WPML_TM_Email_Jobs_Summary_View extends WPML_TM_Email_View {
|
||||
|
||||
const JOBS_TEMPLATE = 'batch-report/email-job-pairs.twig';
|
||||
|
||||
/**
|
||||
* @var WPML_TM_Blog_Translators
|
||||
*/
|
||||
private $blog_translators;
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $assigned_jobs;
|
||||
|
||||
/**
|
||||
* WPML_TM_Batch_Report_Email_Template constructor.
|
||||
*
|
||||
* @param WPML_Twig_Template $template_service
|
||||
* @param WPML_TM_Blog_Translators $blog_translators
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_Twig_Template $template_service,
|
||||
WPML_TM_Blog_Translators $blog_translators,
|
||||
SitePress $sitepress
|
||||
) {
|
||||
parent::__construct( $template_service );
|
||||
$this->blog_translators = $blog_translators;
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $language_pairs
|
||||
* @param int $translator_id
|
||||
* @param string $title_singular
|
||||
* @param string $title_plural
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function render_jobs_list( $language_pairs, $translator_id, $title_singular, $title_plural = '' ) {
|
||||
$this->empty_assigned_jobs();
|
||||
|
||||
$model = array(
|
||||
'strings' => array(
|
||||
'strings_text' => __( 'Strings', 'wpml-translation-management' ),
|
||||
'start_translating_text' => __( 'start translating', 'wpml-translation-management' ),
|
||||
'take' => _x( 'take it', 'Take a translation job waiting for a translator', 'wpml-translation-management' ),
|
||||
'strings_link' => admin_url(
|
||||
'admin.php?page=wpml-string-translation%2Fmenu%2Fstring-translation.php'
|
||||
),
|
||||
'closing_sentence' => $this->get_closing_sentence(),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $language_pairs as $lang_pair => $elements ) {
|
||||
|
||||
$languages = explode( '|', $lang_pair );
|
||||
$args = array(
|
||||
'lang_from' => $languages[0],
|
||||
'lang_to' => $languages[1]
|
||||
);
|
||||
|
||||
if ( $this->blog_translators->is_translator( $translator_id, $args ) &&
|
||||
WPML_User_Jobs_Notification_Settings::is_new_job_notification_enabled( $translator_id ) ) {
|
||||
|
||||
$model_elements = array();
|
||||
$string_added = false;
|
||||
|
||||
foreach ( $elements as $element ) {
|
||||
|
||||
if ( ! $string_added || 'string' !== $element['type'] ) {
|
||||
$model_elements[] = array(
|
||||
'original_link' => get_permalink( $element['element_id'] ),
|
||||
'original_text' => sprintf( __( 'Link to original document %d', 'wpml-translation-management' ), $element['element_id'] ),
|
||||
'start_translating_link' => admin_url(
|
||||
'admin.php?page=' . WPML_TM_FOLDER . '%2Fmenu%2Ftranslations-queue.php&job_id=' . $element['job_id']
|
||||
),
|
||||
'type' => $element['type'],
|
||||
);
|
||||
|
||||
if ( 'string' === $element['type'] ) {
|
||||
$string_added = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->add_assigned_job( $element['job_id'], $element['type'] );
|
||||
}
|
||||
|
||||
$source_lang = $this->sitepress->get_language_details( $languages[0] );
|
||||
$target_lang = $this->sitepress->get_language_details( $languages[1] );
|
||||
$model['lang_pairs'][$lang_pair] = array(
|
||||
'title' => sprintf( __( 'From %1$s to %2$s:', 'wpml-translation-management' ), $source_lang['english_name'], $target_lang['english_name'] ),
|
||||
'elements' => $model_elements,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$model['strings']['title'] = $title_singular;
|
||||
if ( 1 < count( $this->get_assigned_jobs() ) ) {
|
||||
$model['strings']['title'] = sprintf( $title_plural, count( $this->get_assigned_jobs() ) );
|
||||
}
|
||||
|
||||
return count( $this->get_assigned_jobs() ) ? $this->template_service->show( $model, self::JOBS_TEMPLATE ) : null;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function render_footer() {
|
||||
$site_url = get_bloginfo( 'url' );
|
||||
$profile_link = '<a href="' . admin_url( 'profile.php' ) . '" style="color: #ffffff;">' . esc_html__( 'Your Profile', '' ) .'</a>';
|
||||
|
||||
$bottom_text = sprintf(
|
||||
__(
|
||||
'You are receiving this email because you have a translator
|
||||
account in %1$s. To stop receiving notifications,
|
||||
log-in to %2$s and unselect "Send me a notification email
|
||||
when there is something new to translate". Please note that
|
||||
this will take you out of the translators pool.', 'wpml-translation-management'
|
||||
),
|
||||
$site_url,
|
||||
$profile_link
|
||||
);
|
||||
|
||||
return $this->render_email_footer( $bottom_text );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_id
|
||||
* @param string $type
|
||||
*/
|
||||
private function add_assigned_job( $job_id, $type ) {
|
||||
$this->assigned_jobs[] = array(
|
||||
'job_id' => $job_id,
|
||||
'type' => $type,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_assigned_jobs() {
|
||||
$string_counted = false;
|
||||
foreach ( $this->assigned_jobs as $key => $assigned_job ) {
|
||||
if ( 'string' === $assigned_job['type'] ) {
|
||||
if ( $string_counted ) {
|
||||
unset( $this->assigned_jobs[$key] );
|
||||
}
|
||||
$string_counted = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->assigned_jobs;
|
||||
}
|
||||
|
||||
private function empty_assigned_jobs() {
|
||||
$this->assigned_jobs = array();
|
||||
}
|
||||
|
||||
private function get_closing_sentence() {
|
||||
$sentence = null;
|
||||
|
||||
if ( WPML_TM_ATE_Status::is_enabled_and_activated() ) {
|
||||
$link = '<a href="https://wpml.org/documentation/translating-your-contents/advanced-translation-editor/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmltm">' . __( "WPML's Advanced Translation Editor", 'wpml-translation-management' ) . '</a>';
|
||||
|
||||
$sentence = sprintf( __( "Need help translating? Read how to use %s.", 'wpml-translation-management' ), $link );
|
||||
}
|
||||
|
||||
return $sentence;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Email_Twig_Template_Factory {
|
||||
|
||||
/** @return WPML_Twig_Template */
|
||||
public function create() {
|
||||
$loader = new WPML_Twig_Template_Loader( array( WPML_TM_PATH . '/templates/emails/' ) );
|
||||
return $loader->get_template();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
abstract class WPML_TM_Email_View {
|
||||
|
||||
const FOOTER_TEMPLATE = 'email-footer.twig';
|
||||
const HEADER_TEMPLATE = 'email-header.twig';
|
||||
|
||||
/** @var WPML_Twig_Template $template_service */
|
||||
protected $template_service;
|
||||
|
||||
public function __construct( WPML_Twig_Template $template_service ) {
|
||||
$this->template_service = $template_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_header( $username = '' ) {
|
||||
$model = array(
|
||||
'greetings' => sprintf( __( 'Dear %s,', 'wpml-translation-management' ), $username ),
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::HEADER_TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_casual_header( $first_name = '' ) {
|
||||
$model = array(
|
||||
'greetings' => sprintf( __( 'Hi %s,', 'wpml-translation-management' ), $first_name ),
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::HEADER_TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $bottom_text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function render_email_footer( $bottom_text = '' ) {
|
||||
$site_url = get_bloginfo( 'url' );
|
||||
|
||||
$model = array(
|
||||
'bottom_text' => $bottom_text,
|
||||
'wpml_footer' => sprintf(
|
||||
esc_html__( 'Generated by WPML plugin, running on %s.', 'wpml-translation-management' ),
|
||||
'<a href="' . $site_url . '" style="color: #ffffff;">' . $site_url . '</a>'
|
||||
),
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::FOOTER_TEMPLATE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,507 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_Mail_Notification
|
||||
*/
|
||||
class WPML_TM_Mail_Notification {
|
||||
|
||||
const JOB_COMPLETE_TEMPLATE = 'notification/job-completed.twig';
|
||||
const JOB_REVISED_TEMPLATE = 'notification/job-revised.twig';
|
||||
const JOB_CANCELED_TEMPLATE = 'notification/job-canceled.twig';
|
||||
|
||||
private $mail_cache = array();
|
||||
private $process_mail_queue;
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var WPML_Translation_Job_Factory $job_factory */
|
||||
private $job_factory;
|
||||
|
||||
/** @var WPML_TM_Email_Notification_View $email_view */
|
||||
private $email_view;
|
||||
|
||||
/** @var array $notification_settings */
|
||||
private $notification_settings;
|
||||
|
||||
/** @var bool $has_active_remote_service */
|
||||
private $has_active_remote_service;
|
||||
|
||||
public function __construct(
|
||||
SitePress $sitepress,
|
||||
wpdb $wpdb,
|
||||
WPML_Translation_Job_Factory $job_factory,
|
||||
WPML_TM_Email_Notification_View $email_view,
|
||||
array $notification_settings,
|
||||
$has_active_remote_service
|
||||
) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->job_factory = $job_factory;
|
||||
$this->email_view = $email_view;
|
||||
$this->notification_settings = array_merge(
|
||||
array(
|
||||
'resigned' => 0,
|
||||
'completed' => 0,
|
||||
),
|
||||
$notification_settings
|
||||
);
|
||||
$this->has_active_remote_service = $has_active_remote_service;
|
||||
}
|
||||
|
||||
public function init() {
|
||||
add_action( 'wpml_tm_empty_mail_queue', array( $this, 'send_queued_mails' ), 10, 0 );
|
||||
|
||||
if ( $this->should_send_email_on_update() ) {
|
||||
add_action( 'wpml_tm_complete_job_notification', array( $this, 'wpml_tm_job_complete_mail' ), 10, 2 );
|
||||
add_action( 'wpml_tm_revised_job_notification', array( $this, 'revised_job_email' ), 10 );
|
||||
add_action( 'wpml_tm_canceled_job_notification', array( $this, 'canceled_job_email' ), 10 );
|
||||
}
|
||||
|
||||
add_action( 'wpml_tm_remove_job_notification', array( $this, 'translator_removed_mail' ), 10, 2 );
|
||||
add_action( 'wpml_tm_resign_job_notification', array( $this, 'translator_resign_mail' ), 10, 2 );
|
||||
add_action( 'icl_ajx_custom_call', array( $this, 'send_queued_mails' ), 10, 0 );
|
||||
add_action( 'icl_pro_translation_completed', array( $this, 'send_queued_mails' ), 10, 0 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function should_send_email_on_update() {
|
||||
return ! isset( $this->notification_settings[ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] ) ||
|
||||
( isset( $this->notification_settings[ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] ) &&
|
||||
WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY === (int) $this->notification_settings[ WPML_TM_Emails_Settings::COMPLETED_JOB_FREQUENCY ] );
|
||||
}
|
||||
|
||||
public function send_queued_mails() {
|
||||
$tj_url = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php' );
|
||||
|
||||
foreach ( $this->mail_cache as $type => $mail_to_send ) {
|
||||
foreach ( $mail_to_send as $to => $subjects ) {
|
||||
$headers = '';
|
||||
$body_to_send = '';
|
||||
|
||||
foreach ( $subjects as $subject => $content ) {
|
||||
$body = $content['body'];
|
||||
$home_url = get_home_url();
|
||||
|
||||
if ( 'completed' === $type ) {
|
||||
$headers = array(
|
||||
'Content-type: text/html; charset=UTF-8',
|
||||
);
|
||||
|
||||
$body_to_send .= $body[0];
|
||||
|
||||
} else {
|
||||
$body_to_send .= $body_to_send . "\n\n" . implode( "\n\n\n\n", $body ) . "\n\n\n\n";
|
||||
|
||||
if ( $type === 'translator' ) {
|
||||
$footer = sprintf(
|
||||
__( 'You can view your other translation jobs here: %s', 'wpml-translation-management' ),
|
||||
$tj_url
|
||||
) . "\n\n--\n";
|
||||
$footer .= sprintf(
|
||||
__(
|
||||
"This message was automatically sent by Translation Management running on %1\$s. To stop receiving these notifications contact the system administrator at %2\$s.\n\nThis email is not monitored for replies.",
|
||||
'wpml-translation-management'
|
||||
),
|
||||
get_bloginfo( 'name' ),
|
||||
$home_url
|
||||
);
|
||||
} else {
|
||||
$footer = "\n--\n" . sprintf(
|
||||
__(
|
||||
"This message was automatically sent by Translation Management running on %1\$s. To stop receiving these notifications, go to Notification Settings, or contact the system administrator at %2\$s.\n\nThis email is not monitored for replies.",
|
||||
'wpml-translation-management'
|
||||
),
|
||||
get_bloginfo( 'name' ),
|
||||
$home_url
|
||||
);
|
||||
}
|
||||
|
||||
$body_to_send .= $footer;
|
||||
}
|
||||
|
||||
$attachments = isset( $content['attachment'] ) ? $content['attachment'] : array();
|
||||
$attachments = apply_filters( 'wpml_new_job_notification_attachments', $attachments );
|
||||
|
||||
/**
|
||||
* @deprecated Use 'wpml_new_job_notification_attachments' instead
|
||||
*/
|
||||
$attachments = apply_filters( 'WPML_new_job_notification_attachments', $attachments );
|
||||
$this->sitepress->get_wp_api()->wp_mail( $to, $subject, $body_to_send, $headers, $attachments );
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->mail_cache = array();
|
||||
$this->process_mail_queue = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_id
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function get_basic_mail_data( $job_id ) {
|
||||
$manager_id = false;
|
||||
|
||||
/** @var WPML_Translation_Job|false $job */
|
||||
if ( is_object( $job_id ) ) {
|
||||
$job = $job_id;
|
||||
} else {
|
||||
$job = $this->job_factory->get_translation_job( $job_id, false, 0, true );
|
||||
}
|
||||
|
||||
if ( is_object( $job ) ) {
|
||||
$data = $job->get_basic_data();
|
||||
$manager_id = isset( $data->manager_id ) ? $data->manager_id : -1;
|
||||
}
|
||||
|
||||
if ( ! $job || ( $manager_id && (int) $manager_id === (int) $job->get_translator_id() ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$manager = new WP_User( $manager_id );
|
||||
$translator = new WP_User( $job->get_translator_id() );
|
||||
$user_language = $this->sitepress->get_user_admin_language( $manager->ID );
|
||||
|
||||
$mail = array(
|
||||
'to' => $manager->display_name . ' <' . $manager->user_email . '>',
|
||||
);
|
||||
|
||||
$this->sitepress->switch_locale( $user_language );
|
||||
|
||||
list( $lang_from, $lang_to ) = $this->get_lang_to_from( $job, $user_language );
|
||||
|
||||
$model = array(
|
||||
'view_jobs_text' => __( 'View translation jobs', 'wpml-translation-management' ),
|
||||
'username' => $manager->display_name,
|
||||
'lang_from' => $lang_from,
|
||||
'lang_to' => $lang_to,
|
||||
);
|
||||
|
||||
$document_title = $job->get_title();
|
||||
|
||||
if ( 'string' !== strtolower( $job->get_type() ) ) {
|
||||
/** @var WPML_Post_Translation_Job $job */
|
||||
$model['translation_jobs_url'] = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=jobs' );
|
||||
$document_title = '<a href="' . $job->get_url( true ) . '">' . $document_title . '</a>';
|
||||
$model = $this->update_model_for_deadline( $model, $job );
|
||||
}
|
||||
|
||||
return array(
|
||||
'mail' => $mail,
|
||||
'document_title' => $document_title,
|
||||
'job' => $job,
|
||||
'manager' => $manager,
|
||||
'translator' => $translator,
|
||||
'model' => $model,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Translation_Job|int $job_id
|
||||
* @param bool|false $update
|
||||
*
|
||||
* @return false|array representation of the email to be sent
|
||||
*/
|
||||
public function wpml_tm_job_complete_mail( $job_id, $update = false ) {
|
||||
$basic_mail_data = $this->get_basic_mail_data( $job_id );
|
||||
if ( null === $basic_mail_data ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$mail = $basic_mail_data['mail'];
|
||||
$document_title = $basic_mail_data['document_title'];
|
||||
$translator = $basic_mail_data['translator'];
|
||||
$job = $basic_mail_data['job'];
|
||||
$model = $basic_mail_data['model'];
|
||||
$lang_from = $model['lang_from'];
|
||||
$lang_to = $model['lang_to'];
|
||||
|
||||
if ( $update ) {
|
||||
$mail['subject'] = sprintf(
|
||||
__( 'Translator has updated translation job for %s', 'wpml-translation-management' ),
|
||||
get_bloginfo( 'name' )
|
||||
);
|
||||
$body_placeholder = esc_html__(
|
||||
'The translator %1$shas updated the translation job for "%2$s" from %3$s to %4$s.',
|
||||
'wpml-translation-management'
|
||||
);
|
||||
} else {
|
||||
$mail['subject'] = sprintf(
|
||||
__( 'Translator has completed translation job for %s', 'wpml-translation-management' ),
|
||||
get_bloginfo( 'name' )
|
||||
);
|
||||
$body_placeholder = esc_html__(
|
||||
'The translator %1$shas completed the translation job for "%2$s" from %3$s to %4$s.',
|
||||
'wpml-translation-management'
|
||||
);
|
||||
}
|
||||
$translator_name = ! empty( $translator->display_name ) ? '(' . $translator->display_name . ') ' : '';
|
||||
$model['message'] = sprintf( $body_placeholder, $translator_name, $document_title, $lang_from, $lang_to );
|
||||
$model['needs_help'] = array(
|
||||
'title' => __( 'Need help with translation?', 'wpml-translation-management' ),
|
||||
'options_or' => __( 'or', 'wpml-translation-management' ),
|
||||
'translators_link' => admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=translators' ),
|
||||
'translators_text' => __( 'Manage your translators', 'wpml-translation-management' ),
|
||||
'translation_services_link' => admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=translators' ),
|
||||
'translation_services_text' => __( 'try a translation service', 'wpml-translation-management' ),
|
||||
);
|
||||
$model['overdue_job'] = ! $job->is_completed_on_time();
|
||||
|
||||
$mail['body'] = $this->email_view->render_model( $model, self::JOB_COMPLETE_TEMPLATE );
|
||||
$mail['type'] = 'completed';
|
||||
$this->enqueue_mail( $mail );
|
||||
|
||||
$this->sitepress->switch_locale();
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $job_id
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function revised_job_email( $job_id ) {
|
||||
|
||||
if ( ! $this->should_send_immediate_notification( 'completed' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subject = sprintf( __( 'Translator job updated for %s', 'wpml-translation-management' ), get_bloginfo( 'name' ) );
|
||||
$placeholder = esc_html__(
|
||||
'A new translation for %1$s from %2$s to %3$s was created on the Translation Service. It’s ready to download and will be applied next time the Translation Service delivers completed translations to your site or when you manually fetch them.',
|
||||
'wpml-translation-management'
|
||||
);
|
||||
|
||||
return $this->generic_update_notification_email( $job_id, $subject, $placeholder, self::JOB_REVISED_TEMPLATE );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Job_Entity $job
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function canceled_job_email( WPML_TM_Job_Entity $job ) {
|
||||
if ( ! $job instanceof WPML_TM_Post_Job_Entity ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->should_send_immediate_notification( 'completed' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subject = sprintf( __( 'Translator job canceled for %s', 'wpml-translation-management' ), get_bloginfo( 'name' ) );
|
||||
$placeholder = esc_html__(
|
||||
'The translation for %1$s from %2$s to %3$s was canceled on the Translation Service. You can send this document to translation again from the Translation Dashboard.',
|
||||
'wpml-translation-management'
|
||||
);
|
||||
|
||||
return $this->generic_update_notification_email(
|
||||
$job->get_translate_job_id(),
|
||||
$subject,
|
||||
$placeholder,
|
||||
self::JOB_CANCELED_TEMPLATE
|
||||
);
|
||||
}
|
||||
|
||||
private function generic_update_notification_email( $job_id, $mail_subject, $body_placeholder, $template ) {
|
||||
$basic_mail_data = $this->get_basic_mail_data( $job_id );
|
||||
if ( null === $basic_mail_data ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$mail = $basic_mail_data['mail'];
|
||||
$document_title = $basic_mail_data['document_title'];
|
||||
|
||||
$model = $basic_mail_data['model'];
|
||||
$lang_from = $model['lang_from'];
|
||||
$lang_to = $model['lang_to'];
|
||||
|
||||
$mail['subject'] = $mail_subject;
|
||||
$model['message'] = sprintf( $body_placeholder, $document_title, $lang_from, $lang_to );
|
||||
$mail['body'] = $this->email_view->render_model( $model, $template );
|
||||
$mail['type'] = 'completed';
|
||||
$this->enqueue_mail( $mail );
|
||||
|
||||
$this->sitepress->switch_locale();
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
private function should_send_immediate_notification( $type ) {
|
||||
return isset( $this->notification_settings[ $type ] ) &&
|
||||
(int) $this->notification_settings[ $type ] === WPML_TM_Emails_Settings::NOTIFY_IMMEDIATELY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $model
|
||||
* @param WPML_Element_Translation_Job $job
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function update_model_for_deadline( array $model, WPML_Element_Translation_Job $job ) {
|
||||
if ( $job->is_completed_on_time() ) {
|
||||
$model['deadline_status'] = __( 'The translation job was completed on time.', 'wpml-translation-management' );
|
||||
} else {
|
||||
$overdue_days = $job->get_number_of_days_overdue();
|
||||
|
||||
$model['deadline_status'] = sprintf(
|
||||
_n(
|
||||
'This translation job is overdue by %s day.',
|
||||
'This translation job is overdue by %s days.',
|
||||
$overdue_days,
|
||||
'wpml-translation-management'
|
||||
),
|
||||
$overdue_days
|
||||
);
|
||||
|
||||
if ( $overdue_days >= 7 ) {
|
||||
$model['promote_translation_services'] = ! $this->has_active_remote_service;
|
||||
}
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $translator_id
|
||||
* @param WPML_Translation_Job|int $job
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function translator_removed_mail( $translator_id, $job ) {
|
||||
/** @var WPML_Translation_Job $job */
|
||||
list( $manager_id, $job ) = $this->get_mail_elements( $job );
|
||||
if ( ! $job || $manager_id == $translator_id ) {
|
||||
return false;
|
||||
}
|
||||
$translator = new WP_User( $translator_id );
|
||||
$manager = new WP_User( $manager_id );
|
||||
$user_language = $this->sitepress->get_user_admin_language( $manager->ID );
|
||||
$doc_title = $job->get_title();
|
||||
$this->sitepress->switch_locale( $user_language );
|
||||
list( $lang_from, $lang_to ) = $this->get_lang_to_from( $job, $user_language );
|
||||
$mail['to'] = $translator->display_name . ' <' . $translator->user_email . '>';
|
||||
$mail['subject'] = sprintf( __( 'Removed from translation job on %s', 'wpml-translation-management' ), get_bloginfo( 'name' ) );
|
||||
$mail['body'] = sprintf(
|
||||
__( 'You have been removed from the translation job "%1$s" for %2$s to %3$s.', 'wpml-translation-management' ),
|
||||
$doc_title,
|
||||
$lang_from,
|
||||
$lang_to
|
||||
);
|
||||
$mail['type'] = 'translator';
|
||||
$this->enqueue_mail( $mail );
|
||||
$this->sitepress->switch_locale();
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $translator_id
|
||||
* @param int|WPML_Translation_Job $job_id
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function translator_resign_mail( $translator_id, $job_id ) {
|
||||
/** @var WPML_Translation_Job $job */
|
||||
list( $manager_id, $job ) = $this->get_mail_elements( $job_id );
|
||||
if ( ! $job || $manager_id == $translator_id ) {
|
||||
return false;
|
||||
}
|
||||
$translator = new WP_User( $translator_id );
|
||||
$manager = new WP_User( $manager_id );
|
||||
$tj_url = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=jobs' );
|
||||
$doc_title = $job->get_title();
|
||||
$user_language = $this->sitepress->get_user_admin_language( $manager->ID );
|
||||
$this->sitepress->switch_locale( $user_language );
|
||||
list( $lang_from, $lang_to ) = $this->get_lang_to_from( $job, $user_language );
|
||||
$mail = array();
|
||||
if ( $this->notification_settings['resigned'] == ICL_TM_NOTIFICATION_IMMEDIATELY ) {
|
||||
$mail['to'] = $manager->display_name . ' <' . $manager->user_email . '>';
|
||||
$mail['subject'] = sprintf(
|
||||
__( 'Translator has resigned from job on %s', 'wpml-translation-management' ),
|
||||
get_bloginfo( 'name' )
|
||||
);
|
||||
$original_doc_title = $doc_title ? $doc_title : __( 'Deleted', 'wpml-translation-management' );
|
||||
$mail['body'] = sprintf(
|
||||
__(
|
||||
'Translator %1$s has resigned from the translation job "%2$s" for %3$s to %4$s.%5$sView translation jobs: %6$s',
|
||||
'wpml-translation-management'
|
||||
),
|
||||
$translator->display_name,
|
||||
$original_doc_title,
|
||||
$lang_from,
|
||||
$lang_to,
|
||||
"\n",
|
||||
$tj_url
|
||||
);
|
||||
$mail['type'] = 'admin';
|
||||
$this->enqueue_mail( $mail );
|
||||
}
|
||||
// restore locale
|
||||
$this->sitepress->switch_locale();
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
private function enqueue_mail( $mail ) {
|
||||
if ( $mail !== 'empty_queue' ) {
|
||||
$this->mail_cache[ $mail['type'] ][ $mail['to'] ][ $mail['subject'] ]['body'][] = $mail['body'];
|
||||
if ( isset( $mail['attachment'] ) ) {
|
||||
$this->mail_cache[ $mail['type'] ][ $mail['to'] ][ $mail['subject'] ]['attachment'][] = $mail['attachment'];
|
||||
}
|
||||
$this->process_mail_queue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|WPML_Translation_Job $job_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_mail_elements( $job_id ) {
|
||||
$job = is_object( $job_id ) ? $job_id : $this->job_factory->get_translation_job(
|
||||
$job_id,
|
||||
false,
|
||||
0,
|
||||
true
|
||||
);
|
||||
if ( is_object( $job ) ) {
|
||||
$data = $job->get_basic_data();
|
||||
$manager_id = isset( $data->manager_id ) ? $data->manager_id : - 1;
|
||||
} else {
|
||||
$job = false;
|
||||
$manager_id = false;
|
||||
}
|
||||
|
||||
return array( $manager_id, $job );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Translation_Job $job
|
||||
* @param string $user_language
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_lang_to_from( $job, $user_language ) {
|
||||
$sql = "SELECT name FROM {$this->wpdb->prefix}icl_languages_translations WHERE language_code=%s AND display_language_code=%s LIMIT 1";
|
||||
$lang_from = $this->wpdb->get_var(
|
||||
$this->wpdb->prepare(
|
||||
$sql,
|
||||
$job->get_source_language_code(),
|
||||
$user_language
|
||||
)
|
||||
);
|
||||
$lang_to = $this->wpdb->get_var( $this->wpdb->prepare( $sql, $job->get_language_code(), $user_language ) );
|
||||
|
||||
return array( $lang_from, $lang_to );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user