options['force_lang'] ) { add_filter( 'fue_email_preview_url', array( $this, 'preview_url' ) ); } // Email language. add_action( 'fue_before_email_send', array( $this, 'before_email_send' ), 10, 4 ); add_action( 'fue_after_email_sent', array( PLLWC()->emails, 'after_email' ) ); } /** * Adds the language and translation management for the 'follow_up_email' custom post type. * Hooked to the filter 'pll_get_post_types'. * * @since 0.9 * * @param string[] $types List of post type names for which Polylang manages language and translations. * @param bool $hide True when displaying the list in Polylang settings. * @return string[] List of post type names for which Polylang manages language and translations. */ public function translate_types( $types, $hide ) { $fue_types = array( 'follow_up_email' ); return $hide ? array_diff( $types, $fue_types ) : array_merge( $types, $fue_types ); } /** * Synchronizes the Follow-Up emails taxonomies. * Hooked to the filter 'pll_copy_taxonomies'. * * @since 0.9 * * @param string[] $taxonomies List of taxonomies to Synchronize. * @return string[] Modified list of taxonomies. */ public function copy_taxonomies( $taxonomies ) { return array_merge( $taxonomies, array( 'follow_up_email_type', 'follow_up_email_campaign' ) ); } /** * Synchronizes the custom fields. * Hooked to the filter 'pll_copy_post_metas'. * * @since 0.9 * * @param string[] $keys List of custom fields names. * @param bool $sync True if it is synchronization, false if it is a copy. * @param int $from Id of the post from which we copy information. * @return string[] */ public function copy_post_metas( $keys, $sync, $from ) { if ( 'follow_up_email' === get_post_type( $from ) ) { $to_sync = array( '_template', '_interval_type', '_interval_num', '_interval_duration', '_send_date', '_send_date_hour', '_send_date_minute', '_always_send', '_conditions', '_send_coupon', '_coupon_id', '_category_id', '_product_id', '_meta', ); $to_copy = array( '_tracking_on', '_tracking', '_tracking_code', ); if ( $sync ) { $keys = array_merge( $keys, $to_sync ); } else { $keys = array_merge( $keys, $to_copy, $to_sync ); } } return $keys; } /** * Translates some custom fields when synchronizing follow-up emails. * Hooked to the filter 'pll_translate_post_meta'. * * @since 1.0 * @param mixed $value Meta value. * @param string $key Meta key. * @param string $lang Language of target. * @param int $from Id of the follow-up email from which we copy information. * @return mixed */ public function translate_post_meta( $value, $key, $lang, $from ) { if ( 'follow_up_email' === get_post_type( $from ) && ! empty( $value ) ) { switch ( $key ) { case '_category_id': // Translate a product category id. $tr_value = pll_get_term( $value, $lang ); $value = $tr_value ? $tr_value : $value; break; case '_product_id': // Translate a product id. $data_store = PLLWC_Data_Store::load( 'product_language' ); $tr_value = $data_store->get( $value, $lang ); $value = $tr_value ? $tr_value : $value; break; case '_meta': foreach ( $value as $k => $v ) { switch ( $k ) { case 'excluded_customers_products': // Translate an array of product ids. if ( ! empty( $v ) ) { $value[ $k ] = array(); $data_store = PLLWC_Data_Store::load( 'product_language' ); foreach ( $v as $product_id ) { if ( $tr_id = $data_store->get( $product_id, $lang ) ) { $value[ $k ][] = $tr_id; } } } break; case 'excluded_categories': case 'excluded_customers_categories': // Translate an array of product category ids. if ( ! empty( $v ) ) { $value[ $k ] = array(); foreach ( $v as $term_id ) { if ( $tr_id = pll_get_term( $term_id, $lang ) ) { $value[ $k ][] = $tr_id; } } } break; } } break; case '_conditions': foreach ( $value as $k => $v ) { switch ( $v['condition'] ) { case 'bought_categories': // Translate an array of product category ids. if ( ! empty( $v['categories'] ) ) { $value[ $k ]['categories'] = array(); foreach ( $v['categories'] as $term_id ) { if ( $tr_id = pll_get_term( $term_id, $lang ) ) { $value[ $k ]['categories'][] = $tr_id; } } } break; } } break; } } return $value; } /** * Removes the language filter for Follow-Up Emails * as the language may not be the desired one on admin. * Hooked to the action 'parse_query'. * * @since 0.9 * * @param WP_Query $query WP_Query object. * @return void */ public function parse_query( $query ) { if ( isset( $query->query['post_type'] ) && 'follow_up_email' === $query->query['post_type'] ) { if ( function_exists( 'get_current_screen' ) ) { $screen = get_current_screen(); } // Keep the filter active on the Follow-Up Emails page. if ( empty( $screen ) || empty( $screen->base ) || 'toplevel_page_followup-emails' !== $screen->base ) { $query->set( 'lang', '' ); } } } /** * Get the email language from the email order data. * * @since 0.9 * * @param array $data Email order data. * @return string|bool */ protected function get_email_order_language( $data ) { if ( ! empty( $data['order_id'] ) ) { $data_store = PLLWC_Data_Store::load( 'order_language' ); return $data_store->get_language( $data['order_id'] ); } elseif ( ! empty( $data['user_id'] ) ) { return get_user_meta( $data['user_id'], 'locale', true ); } return false; } /** * Make sure that the emails are sent in the correct language. * Hooked to the filter 'fue_insert_email_order'. * * @since 0.9 * * @param array $data Email order data. * @return array */ public function insert_email_order( $data ) { $lang = $this->get_email_order_language( $data ); if ( ! empty( $lang ) && ! empty( $data['email_id'] ) ) { if ( doing_action( 'user_register' ) ) { // In this case Follow-Up Emails sends each email only once. if ( $tr_id = pll_get_post( $data['email_id'], $lang ) ) { $args = array( 'email_id' => $tr_id, 'user_id' => $data['user_id'], ); if ( count( Follow_Up_Emails::instance()->scheduler->get_items( $args ) ) === 0 ) { $data['email_id'] = $tr_id; } else { $data['email_id'] = 0; } } } elseif ( doing_action( 'woocommerce_cart_updated' ) ) { // In this case Follow-Up Emails sends only the email with the highest priority. if ( $tr_id = pll_get_post( $data['email_id'], $lang ) ) { $data['email_id'] = $tr_id; } } elseif ( pll_get_post_language( $data['email_id'] ) !== $lang ) { // Otherwise Follow-Up Emails sends all emails in all languages, so let's keep only the right one. $data['email_id'] = 0; } } return $data; } /** * Adds the language information in the preview url. * Hooked to the filter 'fue_email_preview_url'. * * @since 0.9 * * @param string $url Preview url. * @return string Modified url. */ public function preview_url( $url ) { $query = wp_parse_url( $url, PHP_URL_QUERY ); parse_str( $query, $args ); if ( ! empty( $args['email'] ) && $lang = pll_get_post_language( (int) $args['email'] ) ) { if ( ! PLL()->options['hide_default'] || PLL()->options['default_lang'] !== $lang ) { // Can't use switch_language_in_link() due to the lack of slash before the query. $url = str_replace( '?', "/{$lang}?", $url ); } } return $url; } /** * Sets the email language. * Hooked to the action 'fue_before_email_send'. * * @since 0.9 * * @param string $subject Email subject. * @param string $message Email message. * @param string $headers Email headers. * @param object $queue_item Email queue item. * @return void */ public function before_email_send( $subject, $message, $headers, $queue_item ) { if ( ! empty( $queue_item->email_id ) ) { $language = PLL()->model->post->get_language( $queue_item->email_id ); PLLWC()->emails->set_email_language( $language ); } } }