first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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 );
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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' );
}
}

View File

@@ -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'
),
'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/">' . __( "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;
}
}