File: /var/www/delta/wp-content/plugins/sitepress-multilingual-cms/inc/utilities/wpml-languages.class.php
<?php
use WPML\FP\Obj;
use WPML\TM\ATE\Review\PreviewLink;
/**
* Class WPML_Languages
*
* @package wpml-core
*/
class WPML_Languages extends WPML_SP_And_PT_User {
/** @var WPML_Term_Translation $term_translation */
private $term_translation;
/** @var WPML_Query_Utils $query_utils */
private $query_utils;
/**
* @param WPML_Term_Translation $term_translation
* @param SitePress $sitepress
* @param WPML_Post_Translation $post_translation
*/
public function __construct( &$term_translation, &$sitepress, &$post_translation ) {
parent::__construct( $post_translation, $sitepress );
$this->term_translation = &$term_translation;
$this->query_utils = $sitepress->get_query_utils();
}
/**
* @param WP_Query $wp_query
* @param WP_Query $_wp_query_back
* @param WP_Query $saved_query
*
* @return array<array<string,\stdClass>, \WP_Query>
*/
public function get_ls_translations( $wp_query, $_wp_query_back, $saved_query ) {
list( $taxonomy, $term_id ) = $this->extract_tax_archive_data( $wp_query );
if ( $taxonomy && $term_id ) {
if ( $this->sitepress->is_translated_taxonomy( $taxonomy ) ) {
$icl_taxonomy = 'tax_' . $taxonomy;
$trid = $this->term_translation->trid_from_tax_and_id( $term_id, $taxonomy );
$translations = $this->sitepress->get_element_translations( $trid, $icl_taxonomy, false );
} elseif ( 'post_format' === $taxonomy ) {
$translations = $this->get_post_format_translations( $taxonomy, $term_id );
} else {
$translations[ $this->sitepress->get_current_language() ] = (object) array(
'translation_id' => 0,
'language_code' => $this->sitepress->get_default_language(),
'original' => 1,
'name' => $taxonomy,
'term_id' => $term_id,
);
}
} elseif ( $wp_query->is_archive() && ! empty( $wp_query->posts ) ) {
$translations = array();
} elseif ( $wp_query->is_attachment() ) {
$trid = $this->post_translation->get_element_trid( $wp_query->get_queried_object_id() );
$translations = $this->sitepress->get_element_translations( $trid, 'post_attachment' );
} elseif ( $wp_query->is_page()
|| ( 'page' === $this->sitepress->get_wp_api()->get_option( 'show_on_front' )
&& ( isset( $saved_query->queried_object_id )
&& $saved_query->queried_object_id == $this->sitepress->get_wp_api()->get_option( 'page_on_front' )
|| ( isset( $saved_query->queried_object_id )
&& $saved_query->queried_object_id == $this->sitepress->get_wp_api()->get_option( 'page_for_posts' ) ) ) )
) {
$trid = $this->sitepress->get_element_trid( $wp_query->get_queried_object_id(), 'post_page' );
$translations = $this->sitepress->get_element_translations( $trid, 'post_page' );
} elseif ( $wp_query->is_singular() && ! empty( $wp_query->posts )
|| ( isset( $_wp_query_back->query['name'] ) && isset( $_wp_query_back->query['post_type'] ) )
|| isset( $_wp_query_back->query['p'] )
) {
$pid = ! empty( $saved_query->post->ID ) ? $saved_query->post->ID : ( ! empty( $saved_query->query['p'] ) ? $saved_query->query['p'] : 0 );
$trid = $this->post_translation->get_element_trid( $pid );
$post_type = get_post_type( $pid );
// Check for preview_nonce - it's added to the url of a "Translation Review" page.
// When the nonce passes we want to skip privilege check for the translations, because also a
// Subscriber Translator does currently preview a draft post (translation preview) and the related language
// should appear in the Language Switcher. See wpmlcore-8602 for more details.
$previewNonce = Obj::propOr( '', 'preview_nonce', $_GET );
$previewNonceName = PreviewLink::getNonceName( (int) Obj::propOr( 0, 'preview_id', $_GET ) );
$skipPrivilegeChecking = \wp_verify_nonce( $previewNonce, $previewNonceName );
$translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type, false, false, false, false, $skipPrivilegeChecking );
} else {
$wp_query->is_singular = false;
$wp_query->is_archive = false;
$wp_query->is_category = false;
$wp_query->is_404 = true;
$translations = null;
}
$translations = apply_filters( 'wpml_get_ls_translations', $translations, $wp_query );
return array( $translations, $wp_query );
}
/**
* @param array $lang
* @param array $translations
* @param bool $icl_lso_link_empty
* @param bool $skip_lang
* @param string $link_empty_to
* @param WPML_LS_Display_As_Translated_Link $display_as_translated_ls_link
*
* @return array
*/
public function add_tax_url_to_ls_lang( $lang, $translations, $icl_lso_link_empty, $skip_lang, $link_empty_to, WPML_LS_Display_As_Translated_Link $display_as_translated_ls_link ) {
if ( isset( $translations[ $lang['code'] ] ) ) {
// force the taxonomy id adjustment to not modify this
$queried_object = $this->sitepress->get_wp_api()->get_queried_object();
$taxonomy = isset( $queried_object->taxonomy ) ? $queried_object->taxonomy : null;
if ( $taxonomy ) {
$translated_url = get_term_link( (int) $translations[ $lang['code'] ]->term_id, $taxonomy );
if ( ! $translated_url instanceof WP_Error ) {
$lang['translated_url'] = $translated_url;
$lang['missing'] = 0;
if ( 'post_format' === $taxonomy ) {
$lang['translated_url'] = $this->sitepress->convert_url( $lang['translated_url'], $lang['code'] );
}
} else {
$skip_lang = true;
}
}
}
if ( ! isset( $translations[ $lang['code'] ] ) || ! isset( $taxonomy ) ) {
$translated_url = $display_as_translated_ls_link->get_url( $translations, $lang['code'] );
if ( $translated_url ) {
$lang['translated_url'] = $translated_url;
$lang['missing'] = 0;
} else {
$args = array(
'skip_lang' => $skip_lang,
'link_empty' => $icl_lso_link_empty,
'override_missing' => false,
'link_empty_to' => $link_empty_to,
);
list( $lang, $skip_lang ) = $this->maybe_mark_lang_missing( $lang, $args );
}
}
return array( $lang, $skip_lang );
}
/**
* @param array $lang
* @param object|WP_User $author_data
* @param bool $icl_lso_link_empty
* @param bool $skip_lang
* @param bool $link_empty_to
*
* @return array
*/
public function add_author_url_to_ls_lang( $lang, $fallback_lang, $author_data, $icl_lso_link_empty, $skip_lang, $link_empty_to ) {
$post_type = get_query_var( 'post_type' ) ? get_query_var( 'post_type' ) : 'post';
if ( $this->query_utils->author_query_has_posts( $post_type, $author_data, $lang['code'], $fallback_lang ) ) {
$lang['translated_url'] = $this->sitepress->convert_url( $this->sitepress->get_wp_api()->get_author_posts_url( $author_data->ID ), $lang['code'] );
$lang['missing'] = 0;
} else {
$args = array(
'skip_lang' => $skip_lang,
'link_empty' => $icl_lso_link_empty,
'override_missing' => false,
'link_empty_to' => $link_empty_to,
);
list( $lang, $skip_lang ) = $this->maybe_mark_lang_missing( $lang, $args );
}
return array( $lang, $skip_lang );
}
/**
* @param array $lang
* @param string $fallback_lang
* @param WP_Query $current_query
* @param bool $icl_lso_link_empty
* @param bool $skip_lang
* @param string $link_empty_to
*
* @return array
*/
public function add_date_or_cpt_url_to_ls_lang( $lang, $fallback_lang, $current_query, $icl_lso_link_empty, $skip_lang, $link_empty_to ) {
list( $year, $month, $day ) = $this->extract_date_data_from_query( $current_query );
$query_helper = new WPML_WP_Query_API( $current_query );
$post_type = ( $_type = $query_helper->get_first_post_type() ) ? $_type : 'post';
$lang_code = $lang['code'];
$mark_missing = false;
$override = false;
if ( $current_query->is_year() && $this->query_utils->archive_query_has_posts(
$lang_code,
$fallback_lang,
$year,
null,
null,
$post_type
)
) {
$date_archive_url = $this->sitepress->get_wp_api()->get_year_link( $year );
} elseif ( $current_query->is_month() && $this->query_utils->archive_query_has_posts(
$lang_code,
$fallback_lang,
$year,
$month,
null,
$post_type
)
) {
$date_archive_url = $this->sitepress->get_wp_api()->get_month_link( $year, $month );
} elseif ( $current_query->is_day() && $this->query_utils->archive_query_has_posts( $lang_code, $fallback_lang, $year, $month, $day, $post_type ) ) {
$date_archive_url = $this->sitepress->get_wp_api()->get_day_link( $year, $month, $day );
} elseif ( ! empty( $current_query->query_vars['post_type'] ) ) {
$override = ! $this->sitepress->is_translated_post_type( $post_type );
$mark_missing = true;
if ( ! $override && $this->query_utils->archive_query_has_posts( $lang_code, $fallback_lang, null, null, null, $post_type ) ) {
$getArchiveLinkWithLanguage = function( $post_type, $lang_code ) {
$current_language = $this->sitepress->get_current_language();
$this->sitepress->switch_lang( $lang_code );
$url = $this->sitepress->convert_url( $this->sitepress->get_wp_api()->get_post_type_archive_link( $post_type ), $lang_code );
$this->sitepress->switch_lang( $current_language );
return $url;
};
$url = $getArchiveLinkWithLanguage( $post_type, $lang_code );
$lang['translated_url'] = $this->sitepress->adjust_cpt_in_url( $url, $post_type, $lang_code );
$mark_missing = false;
}
} else {
$mark_missing = true;
}
if ( $mark_missing ) {
$args = array(
'skip_lang' => $skip_lang,
'link_empty' => $icl_lso_link_empty,
'override_missing' => $override,
'link_empty_to' => $link_empty_to,
);
list( $lang, $skip_lang ) = $this->maybe_mark_lang_missing( $lang, $args );
} elseif ( isset( $date_archive_url ) ) {
$lang['translated_url'] = $this->sitepress->convert_url( $date_archive_url, $lang_code );
}
return array( $lang, $skip_lang );
}
public function get_ls_language( $lang_code, $current_language, $language_array = false ) {
$ls_language = $language_array
? $language_array : $this->sitepress->get_language_details( $lang_code );
$native_name = $this->sitepress->get_display_language_name( $lang_code, $lang_code );
if ( ! $native_name ) {
$native_name = $ls_language['english_name'];
}
$ls_language['native_name'] = $native_name;
$translated_name = $this->sitepress->get_display_language_name( $lang_code, $current_language );
if ( ! $translated_name ) {
$translated_name = $ls_language['english_name'];
}
$ls_language['translated_name'] = $translated_name;
if ( isset( $ls_language['translated_url'] ) ) {
$ls_language['url'] = $ls_language['translated_url'];
unset( $ls_language['translated_url'] );
} else {
$ls_language['url'] = $this->sitepress->language_url( $lang_code, true );
}
$flag_url = $this->sitepress->get_flag_url( $lang_code );
$ls_language['country_flag_url'] = $flag_url;
$ls_language['active'] = $current_language === $lang_code ? '1' : 0;
$ls_language['language_code'] = $lang_code;
unset( $ls_language['display_name'], $ls_language['english_name'] );
return $ls_language;
}
public function sort_ls_languages( $w_active_languages, $template_args ) {
// sort languages according to parameters
$order_by = isset( $template_args['orderby'] ) ? $template_args['orderby'] : 'custom';
$order = isset( $template_args['order'] ) ? $template_args['order'] : 'asc';
switch ( $order_by ) {
case 'id':
uasort( $w_active_languages, array( $this, 'sort_by_id' ) );
break;
case 'code':
krsort( $w_active_languages );
break;
case 'name':
uasort( $w_active_languages, array( $this, 'sort_by_name' ) );
break;
case 'custom':
default:
$w_active_languages = $this->sitepress->order_languages( $w_active_languages );
}
return $order !== 'asc' ? array_reverse( $w_active_languages, true ) : $w_active_languages;
}
/**
* @param array $lang
* @param array $args with keys below
* - `skip_lang` bool|int
* - `link_empty` bool|int
* - `link_empty_to` string a URL possibly with a {%lang} placeholder (e.g. http://example.tld/{%lang}/notify-no-translation/)
* - `override_missing` bool if true language will always be shown ( Example: untranslated CPT archives)
*
* @return array
*/
private function maybe_mark_lang_missing( $lang, $args ) {
$args = array_merge(
array(
'skip_lang' => 0,
'link_empty' => 0,
'link_empty_to' => '',
'override_missing' => false,
),
$args
);
if ( $args['link_empty'] ) {
if ( ! empty( $args['link_empty_to'] ) ) {
$lang['translated_url'] = str_replace(
'{%lang}',
$lang['code'],
$args['link_empty_to']
);
} else {
$lang['translated_url'] = $this->sitepress->language_url( $lang['code'], true );
}
} else {
if ( $this->sitepress->get_current_language() != $lang['code'] ) {
$args['skip_lang'] = true;
}
}
$lang['missing'] = $args['override_missing'] ? 0 : 1;
return array( $lang, $args['skip_lang'] );
}
/**
* @param WP_Query $query
*
* @return array()
*/
private function extract_date_data_from_query( $query ) {
$year = ! empty( $query->query_vars['year'] )
? $query->query_vars['year']
: ( ! empty( $query->query_vars['m'] )
? substr( $query->query_vars['m'], 0, 4 ) : null );
$month = ! empty( $query->query_vars['monthnum'] )
? $query->query_vars['monthnum']
: ( ! empty( $query->query_vars['m'] )
? substr( $query->query_vars['m'], 4, 2 ) : null );
$day = ! empty( $query->query_vars['day'] )
? $query->query_vars['day']
: ( ! empty( $query->query_vars['m'] )
? substr( $query->query_vars['m'], 6, 2 ) : null );
return array( $year, $month, $day );
}
/**
* @param WP_Query $wp_query
*
* @return array()
*/
private function extract_tax_archive_data( $wp_query ) {
$taxonomy = false;
$term_id = false;
if ( $wp_query->is_category() ) {
$taxonomy = 'category';
$term_id = $wp_query->get( 'cat' );
} elseif ( $wp_query->is_tag() ) {
$taxonomy = 'post_tag';
$term_id = $wp_query->get( 'tag_id' );
} elseif ( $wp_query->is_tax() ) {
$term = $wp_query->get_queried_object();
$taxonomy = $term->taxonomy;
$term_id = $term->term_id;
}
return array( $taxonomy, $term_id );
}
/**
* @param string $taxonomy
* @param int $term_id
*
* @return array
*/
private function get_post_format_translations( $taxonomy, $term_id ) {
$translations = array();
foreach ( $this->sitepress->get_active_languages() as $code => $active_language ) {
$translations[ $code ] = (object) array(
'translation_id' => 0,
'language_code' => $code,
'original' => 1,
'name' => $taxonomy,
'term_id' => $term_id,
);
}
return $translations;
}
private function sort_by_id( $array_a, $array_b ) {
return (int) $array_a['id'] > (int) $array_b['id'] ? - 1 : 1;
}
private function sort_by_name( $array_a, $array_b ) {
return $array_a['translated_name'] > $array_b['translated_name'] ? 1 : - 1;
}
}