first commit
This commit is contained in:
112
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/accept-language.php
vendored
Normal file
112
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/accept-language.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Accept_Language.
|
||||
*
|
||||
* Represents an Accept-Language HTTP Header, as defined in RFC 2616 Section 14.4 {@see https://tools.ietf.org/html/rfc2616.html#section-14.4}.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class PLL_Accept_Language {
|
||||
const SUBTAG_PATTERNS = array(
|
||||
'language' => '(\b[a-z]{2,3}|[a-z]{4}|[a-z]{5-8}\b)',
|
||||
'language-extension' => '(?:-(\b[a-z]{3}){1,3}\b)?',
|
||||
'script' => '(?:-(\b[a-z]{4})\b)?',
|
||||
'region' => '(?:-(\b[a-z]{2}|[0-9]{3})\b)?',
|
||||
'variant' => '(?:-(\b[0-9][a-z]{1,3}|[a-z][a-z0-9]{4,7})\b)?',
|
||||
'extension' => '(?:-(\b[a-wy-z]-[a-z0-9]{2,8})\b)?',
|
||||
'private-use' => '(?:-(\bx-[a-z0-9]{1,8})\b)?',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string[] {
|
||||
* @type string $language Usually 2 or three letters (ISO 639).
|
||||
* @type string $language-extension Up to three groups of 3 letters.
|
||||
* @type string $script Four letters.
|
||||
* @type string $region Either two letters of three digits.
|
||||
* @type string $variant Either one digit followed by 1 to 3 letters, or a letter followed by 2 to 7 alphanumerical characters.
|
||||
* @type string $extension One letter that cannot be an 'x', followed by 2 to 8 alphanumerical characters.
|
||||
* @type string $private-use Starts by 'x-', followed by 1 to 8 alphanumerical characters.
|
||||
* }
|
||||
*/
|
||||
protected $subtags;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $quality;
|
||||
|
||||
/**
|
||||
* PLL_Accept_Language constructor.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string[] $subtags With subtag name as keys and subtag values as names.
|
||||
* @param mixed $quality Floating point value from 0.0 to 1.0. Higher values indicates a user's preference.
|
||||
*/
|
||||
public function __construct( $subtags, $quality = 1.0 ) {
|
||||
$this->subtags = $subtags;
|
||||
$this->quality = is_numeric( $quality ) ? floatval( $quality ) : 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from an array resulting of a PHP {@see preg_match()} or {@see preg_match_all()} call.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string[] $matches Expects first entry to be full match, following entries to be subtags and last entry to be quality factor.
|
||||
* @return PLL_Accept_Language
|
||||
*/
|
||||
public static function from_array( $matches ) {
|
||||
$subtags = array_combine(
|
||||
array_keys( array_slice( self::SUBTAG_PATTERNS, 0, count( $matches ) - 1 ) ),
|
||||
array_slice( $matches, 1, count( self::SUBTAG_PATTERNS ) )
|
||||
);
|
||||
$quality = count( $matches ) === 9 ? $matches[8] : 1.0;
|
||||
|
||||
return new PLL_Accept_Language( $subtags, $quality );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full language tag.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
$subtags = array_filter(
|
||||
$this->subtags,
|
||||
function ( $subtag ) {
|
||||
return ! empty( trim( $subtag ) );
|
||||
}
|
||||
);
|
||||
return implode( '-', $subtags );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quality factor as negotiated by the browser agent.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function get_quality() {
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a subtag from the language tag.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $name A valid subtag name, {@see PLL_Accept_Language::SUBTAG_PATTERNS} for available subtag names.
|
||||
* @return string
|
||||
*/
|
||||
public function get_subtag( $name ) {
|
||||
return isset( $this->subtags[ $name ] ) ? $this->subtags[ $name ] : '';
|
||||
}
|
||||
}
|
||||
143
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/accept-languages-collection.php
vendored
Normal file
143
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/accept-languages-collection.php
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class PLL_Accept_Languages_Collection.
|
||||
*
|
||||
* Represents a collection of values parsed from an Accept-Language HTTP header.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
class PLL_Accept_Languages_Collection {
|
||||
/**
|
||||
* @var PLL_Accept_Language[]
|
||||
*/
|
||||
protected $accept_languages = array();
|
||||
|
||||
/**
|
||||
* Parse Accept-Language HTTP header according to IETF BCP 47.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $http_header Value of the Accept-Language HTTP Header. Formatted as stated BCP 47 for language tags {@see https://tools.ietf.org/html/bcp47}.
|
||||
* @return PLL_Accept_Languages_Collection
|
||||
*/
|
||||
public static function from_accept_language_header( $http_header ) {
|
||||
$lang_parse = array();
|
||||
// Break up string into pieces ( languages and q factors ).
|
||||
$language_pattern = implode( '', PLL_Accept_Language::SUBTAG_PATTERNS );
|
||||
$quality_pattern = '\s*;\s*q\s*=\s*((?>1|0)(?>\.[0-9]+)?)';
|
||||
$full_pattern = "/{$language_pattern}(?:{$quality_pattern})?/i";
|
||||
|
||||
preg_match_all(
|
||||
$full_pattern,
|
||||
$http_header,
|
||||
$lang_parse,
|
||||
PREG_SET_ORDER
|
||||
);
|
||||
|
||||
return new PLL_Accept_Languages_Collection(
|
||||
array_map(
|
||||
array( PLL_Accept_Language::class, 'from_array' ),
|
||||
$lang_parse
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* PLL_Accept_Languages_Collection constructor.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param PLL_Accept_Language[] $accept_languages Objects representing Accept-Language HTTP headers.
|
||||
*/
|
||||
public function __construct( $accept_languages = array() ) {
|
||||
$this->accept_languages = $accept_languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bubble sort (need a stable sort for Android, so can't use a PHP sort function).
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bubble_sort() {
|
||||
$k = $this->accept_languages;
|
||||
$v = array_map(
|
||||
function ( $accept_lang ) {
|
||||
return $accept_lang->get_quality();
|
||||
},
|
||||
$this->accept_languages
|
||||
);
|
||||
|
||||
if ( $n = count( $k ) ) {
|
||||
|
||||
if ( $n > 1 ) {
|
||||
for ( $i = 2; $i <= $n; $i++ ) {
|
||||
for ( $j = 0; $j <= $n - 2; $j++ ) {
|
||||
if ( $v[ $j ] < $v[ $j + 1 ] ) {
|
||||
// Swap values.
|
||||
$temp = $v[ $j ];
|
||||
$v[ $j ] = $v[ $j + 1 ];
|
||||
$v[ $j + 1 ] = $temp;
|
||||
// Swap keys.
|
||||
$temp = $k[ $j ];
|
||||
$k[ $j ] = $k[ $j + 1 ];
|
||||
$k[ $j + 1 ] = $temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->accept_languages = array_filter(
|
||||
$k,
|
||||
function ( $accept_lang ) {
|
||||
return $accept_lang->get_quality() > 0;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks through sorted list and use first one that matches our language list.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param PLL_Language[] $languages The language list.
|
||||
* @return string|false A language slug if there's a match, false otherwise.
|
||||
*/
|
||||
public function find_best_match( $languages = array() ) {
|
||||
foreach ( $this->accept_languages as $accept_lang ) {
|
||||
// First loop to match the exact locale.
|
||||
foreach ( $languages as $language ) {
|
||||
if ( 0 === strcasecmp( $accept_lang, $language->get_locale( 'display' ) ) ) {
|
||||
return $language->slug;
|
||||
}
|
||||
}
|
||||
|
||||
// In order of priority.
|
||||
$subsets = array();
|
||||
if ( ! empty( $accept_lang->get_subtag( 'region' ) ) ) {
|
||||
$subsets[] = $accept_lang->get_subtag( 'language' ) . '-' . $accept_lang->get_subtag( 'region' );
|
||||
$subsets[] = $accept_lang->get_subtag( 'region' );
|
||||
}
|
||||
if ( ! empty( $accept_lang->get_subtag( 'variant' ) ) ) {
|
||||
$subsets[] = $accept_lang->get_subtag( 'language' ) . '-' . $accept_lang->get_subtag( 'variant' );
|
||||
}
|
||||
$subsets[] = $accept_lang->get_subtag( 'language' );
|
||||
|
||||
// More loops to match the subsets.
|
||||
foreach ( $languages as $language ) {
|
||||
foreach ( $subsets as $subset ) {
|
||||
|
||||
if ( 0 === stripos( $subset, $language->slug ) || 0 === stripos( $language->get_locale( 'display' ), $subset ) ) {
|
||||
return $language->slug;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
269
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/canonical.php
vendored
Normal file
269
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/canonical.php
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages canonical redirect on frontend.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
class PLL_Canonical {
|
||||
/**
|
||||
* Stores the plugin options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* Instance of a child class of PLL_Links_Model.
|
||||
*
|
||||
* @var PLL_Links_Model
|
||||
*/
|
||||
protected $links_model;
|
||||
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language
|
||||
*/
|
||||
protected $curlang;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @param object $polylang Main Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links_model = &$polylang->links_model;
|
||||
$this->model = &$polylang->model;
|
||||
$this->options = &$polylang->options;
|
||||
$this->curlang = &$polylang->curlang;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the language code is not in agreement with the language of the content,
|
||||
* redirects incoming links to the proper URL to avoid duplicate content.
|
||||
*
|
||||
* @since 0.9.6
|
||||
*
|
||||
* @global WP_Query $wp_query WordPress Query object.
|
||||
* @global bool $is_IIS
|
||||
*
|
||||
* @param string $requested_url Optional, defaults to requested url.
|
||||
* @param bool $do_redirect Optional, whether to perform the redirect or not.
|
||||
* @return string|void Returns if redirect is not performed.
|
||||
*/
|
||||
public function check_canonical_url( $requested_url = '', $do_redirect = true ) {
|
||||
global $wp_query;
|
||||
|
||||
// Don't redirect in same cases as WP.
|
||||
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $GLOBALS['is_IIS'] && ! iis7_supports_permalinks() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id=.
|
||||
if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the default language code is not hidden and the static front page url contains the page name,
|
||||
* the customizer lands here and the code below would redirect to the list of posts.
|
||||
*/
|
||||
if ( is_customize_preview() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $requested_url ) ) {
|
||||
$requested_url = pll_get_requested_url();
|
||||
}
|
||||
|
||||
if ( ( is_single() && ( ! is_attachment() || get_option( 'wp_attachment_pages_enabled' ) ) ) || ( is_page() && ! is_front_page() ) ) {
|
||||
$post = get_post();
|
||||
if ( $post instanceof WP_Post && $this->model->is_translated_post_type( $post->post_type ) ) {
|
||||
$language = $this->model->post->get_language( (int) $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $wp_query->tax_query ) ) {
|
||||
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $wp_query->tax_query ) ) ) {
|
||||
$term_id = $this->get_queried_term_id( $wp_query->tax_query );
|
||||
if ( $term_id ) {
|
||||
$language = $this->model->term->get_language( $term_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $wp_query->is_posts_page ) {
|
||||
$page_id = get_query_var( 'page_id' );
|
||||
if ( ! $page_id ) {
|
||||
$page_id = get_queried_object_id();
|
||||
}
|
||||
if ( $page_id && is_numeric( $page_id ) ) {
|
||||
$language = $this->model->post->get_language( (int) $page_id );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 3 === $this->options['force_lang'] ) {
|
||||
$requested_host = wp_parse_url( $requested_url, PHP_URL_HOST );
|
||||
foreach ( $this->options['domains'] as $lang => $domain ) {
|
||||
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
||||
if ( $requested_host && $host && ltrim( $requested_host, 'w.' ) === ltrim( $host, 'w.' ) ) {
|
||||
$language = $this->model->get_language( $lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $language ) ) {
|
||||
$language = $this->curlang;
|
||||
$redirect_url = $requested_url;
|
||||
} else {
|
||||
$redirect_url = $this->redirect_canonical( $requested_url, $language );
|
||||
$redirect_url = $this->options['force_lang'] ?
|
||||
$this->links_model->switch_language_in_link( $redirect_url, $language ) :
|
||||
$this->links_model->remove_language_from_link( $redirect_url ); // Works only for default permalinks.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filters the canonical url detected by Polylang.
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param string|false $redirect_url False or the url to redirect to.
|
||||
* @param PLL_Language $language The language detected.
|
||||
*/
|
||||
$redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language );
|
||||
|
||||
if ( ! $redirect_url || $requested_url === $redirect_url ) {
|
||||
return $requested_url;
|
||||
}
|
||||
|
||||
if ( ! $do_redirect ) {
|
||||
return $redirect_url;
|
||||
}
|
||||
|
||||
// Protect against chained redirects.
|
||||
if ( $redirect_url === $this->check_canonical_url( $redirect_url, false ) && wp_validate_redirect( $redirect_url ) ) {
|
||||
wp_safe_redirect( $redirect_url, 301, POLYLANG );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the term_id of the requested term.
|
||||
*
|
||||
* @since 2.9
|
||||
*
|
||||
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
||||
* @return int
|
||||
*/
|
||||
protected function get_queried_term_id( $tax_query ) {
|
||||
$queried_terms = $tax_query->queried_terms;
|
||||
$taxonomy = $this->get_queried_taxonomy( $tax_query );
|
||||
|
||||
if ( ! is_array( $queried_terms[ $taxonomy ]['terms'] ) ) {
|
||||
return 0;
|
||||
}
|
||||
$field = $queried_terms[ $taxonomy ]['field'];
|
||||
$term = reset( $queried_terms[ $taxonomy ]['terms'] );
|
||||
$lang = isset( $queried_terms['language']['terms'] ) ? reset( $queried_terms['language']['terms'] ) : '';
|
||||
|
||||
// We can get a term_id when requesting a plain permalink, eg /?cat=1.
|
||||
if ( 'term_id' === $field ) {
|
||||
return $term;
|
||||
}
|
||||
|
||||
// We get a slug when requesting a pretty permalink. Let's query all corresponding terms.
|
||||
$args = array(
|
||||
'lang' => '',
|
||||
'taxonomy' => $taxonomy,
|
||||
$field => $term,
|
||||
'hide_empty' => false,
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$term_ids = get_terms( $args );
|
||||
|
||||
if ( ! is_array( $term_ids ) || empty( $term_ids ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$term_ids = array_filter( $term_ids, 'is_numeric' );
|
||||
|
||||
$filtered_terms_by_lang = array_filter(
|
||||
$term_ids,
|
||||
function ( $term_id ) use ( $lang ) {
|
||||
$term_lang = $this->model->term->get_language( (int) $term_id );
|
||||
|
||||
return ! empty( $term_lang ) && $term_lang->slug === $lang;
|
||||
}
|
||||
);
|
||||
|
||||
$tr_term = (int) reset( $filtered_terms_by_lang );
|
||||
|
||||
if ( ! empty( $tr_term ) ) {
|
||||
// The queried term exists in the desired language.
|
||||
return $tr_term;
|
||||
}
|
||||
|
||||
// The queried term doesn't exist in the desired language, let's return the first one retrieved.
|
||||
return (int) reset( $term_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the taxonomy being queried.
|
||||
*
|
||||
* @since 2.9
|
||||
*
|
||||
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
||||
* @return string A taxonomy slug
|
||||
*/
|
||||
protected function get_queried_taxonomy( $tax_query ) {
|
||||
$queried_terms = $tax_query->queried_terms;
|
||||
unset( $queried_terms['language'] );
|
||||
|
||||
return (string) key( $queried_terms );
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the canonical redirect url through the deidcated WP function.
|
||||
*
|
||||
* @since 3.3
|
||||
*
|
||||
* @global WP_Query $wp_query WordPress Query object.
|
||||
*
|
||||
* @param string $url Requested url.
|
||||
* @param PLL_Language $language Language of the queried object.
|
||||
* @return string
|
||||
*/
|
||||
protected function redirect_canonical( $url, $language ) {
|
||||
/**
|
||||
* @var WP_Query
|
||||
*/
|
||||
global $wp_query;
|
||||
|
||||
$this->curlang = $language; // Hack to filter the `page_for_posts` option in the correct language.
|
||||
|
||||
$backup_wp_query = $wp_query;
|
||||
|
||||
if ( isset( $wp_query->tax_query ) ) {
|
||||
unset( $wp_query->tax_query->queried_terms['language'] );
|
||||
unset( $wp_query->query['lang'] );
|
||||
}
|
||||
|
||||
$redirect_url = redirect_canonical( $url, false );
|
||||
|
||||
$wp_query = $backup_wp_query;
|
||||
|
||||
return $redirect_url ? $redirect_url : $url;
|
||||
}
|
||||
}
|
||||
166
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-content.php
vendored
Normal file
166
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-content.php
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Choose the language when it is set from content
|
||||
* The language is set either in parse_query with priority 2 or in wp with priority 5
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Choose_Lang_Content extends PLL_Choose_Lang {
|
||||
|
||||
/**
|
||||
* Defers the language choice to the 'wp' action (when the content is known)
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
if ( ! did_action( 'pll_language_defined' ) ) {
|
||||
// Set the languages from content
|
||||
add_action( 'wp', array( $this, 'wp' ), 5 ); // Priority 5 for post types and taxonomies registered in wp hook with default priority
|
||||
|
||||
// If no language found, choose the preferred one
|
||||
add_filter( 'pll_get_current_language', array( $this, 'pll_get_current_language' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites parent::set_language to remove the 'wp' action if the language is set before.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param PLL_Language $curlang Current language.
|
||||
* @return void
|
||||
*/
|
||||
protected function set_language( $curlang ) {
|
||||
parent::set_language( $curlang );
|
||||
remove_action( 'wp', array( $this, 'wp' ), 5 ); // won't attempt to set the language a 2nd time
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language based on the queried content
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return PLL_Language|false detected language, false if none was found
|
||||
*/
|
||||
protected function get_language_from_content() {
|
||||
// No language set for 404
|
||||
if ( is_404() || ( is_attachment() && ! $this->options['media_support'] ) ) {
|
||||
return $this->get_preferred_language();
|
||||
}
|
||||
|
||||
if ( $var = get_query_var( 'lang' ) ) {
|
||||
$lang = explode( ',', $var );
|
||||
$lang = $this->model->get_language( reset( $lang ) ); // Choose the first queried language
|
||||
}
|
||||
|
||||
elseif ( ( is_single() || is_page() || ( is_attachment() && $this->options['media_support'] ) ) && ( ( $var = get_queried_object_id() ) || ( $var = get_query_var( 'p' ) ) || ( $var = get_query_var( 'page_id' ) ) || ( $var = get_query_var( 'attachment_id' ) ) ) && is_numeric( $var ) ) {
|
||||
$lang = $this->model->post->get_language( (int) $var );
|
||||
}
|
||||
|
||||
else {
|
||||
foreach ( $this->model->get_translated_taxonomies() as $taxonomy ) {
|
||||
$tax_object = get_taxonomy( $taxonomy );
|
||||
|
||||
if ( empty( $tax_object ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$var = get_query_var( $tax_object->query_var );
|
||||
|
||||
if ( ! is_string( $var ) || empty( $var ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$term = get_term_by( 'slug', $var, $taxonomy );
|
||||
|
||||
if ( ! $term instanceof WP_Term ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lang = $this->model->term->get_language( $term->term_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the language before it is set from the content.
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param PLL_Language|false $lang Language object or false if none was found.
|
||||
*/
|
||||
return apply_filters( 'pll_get_current_language', isset( $lang ) ? $lang : false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language for the home page.
|
||||
* Adds the lang query var when querying archives with no language code.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param WP_Query $query Instance of WP_Query.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_main_query( $query ) {
|
||||
if ( empty( $GLOBALS['wp_the_query'] ) || $query !== $GLOBALS['wp_the_query'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$qv = $query->query_vars;
|
||||
|
||||
// Homepage is requested, let's set the language
|
||||
// Take care to avoid posts page for which is_home = 1
|
||||
if ( empty( $query->query ) && ( is_home() || is_page() ) ) {
|
||||
$this->home_language();
|
||||
$this->home_requested();
|
||||
}
|
||||
|
||||
parent::parse_main_query( $query );
|
||||
|
||||
$is_archive = ( count( $query->query ) == 1 && ! empty( $qv['paged'] ) ) ||
|
||||
$query->is_date ||
|
||||
$query->is_author ||
|
||||
( ! empty( $qv['post_type'] ) && $query->is_post_type_archive && $this->model->is_translated_post_type( $qv['post_type'] ) );
|
||||
|
||||
// Sets the language in case we hide the default language
|
||||
// Use $query->query['s'] as is_search is not set when search is empty
|
||||
// http://wordpress.org/support/topic/search-for-empty-string-in-default-language
|
||||
if ( $this->options['hide_default'] && ! isset( $qv['lang'] ) && ( $is_archive || isset( $query->query['s'] ) || ( count( $query->query ) == 1 && ! empty( $qv['feed'] ) ) ) ) {
|
||||
$this->set_language( $this->model->get_default_language() );
|
||||
$this->set_curlang_in_query( $query );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language from content
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wp() {
|
||||
// Nothing to do if the language has already been set ( although normally the filter has been removed )
|
||||
if ( empty( $this->curlang ) && $curlang = $this->get_language_from_content() ) {
|
||||
parent::set_language( $curlang );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If no language is found by {@see PLL_Choose_Lang_Content::get_language_from_content()}, returns the preferred one.
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param PLL_Language|false $lang Language found by {@see PLL_Choose_Lang_Content::get_language_from_content()}.
|
||||
* @return PLL_Language|false
|
||||
*/
|
||||
public function pll_get_current_language( $lang ) {
|
||||
return ! $lang ? $this->get_preferred_language() : $lang;
|
||||
}
|
||||
}
|
||||
45
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-domain.php
vendored
Normal file
45
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-domain.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Choose the language when the language is managed by different domains
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
class PLL_Choose_Lang_Domain extends PLL_Choose_Lang_Url {
|
||||
|
||||
/**
|
||||
* Don't set any language cookie
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_setcookie() {}
|
||||
|
||||
/**
|
||||
* Don't redirect according to browser preferences
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return PLL_Language
|
||||
*/
|
||||
public function get_preferred_language() {
|
||||
return $this->model->get_language( $this->links_model->get_language_from_url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds query vars to query for home pages in all languages
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function home_requested() {
|
||||
$this->set_curlang_in_query( $GLOBALS['wp_query'] );
|
||||
/** This action is documented in include/choose-lang.php */
|
||||
do_action( 'pll_home_requested' );
|
||||
}
|
||||
}
|
||||
118
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-url.php
vendored
Normal file
118
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang-url.php
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Choose the language when the language code is added to all urls
|
||||
* The language is set in plugins_loaded with priority 1 as done by WPML
|
||||
* Some actions have to be delayed to wait for $wp_rewrite availability
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Choose_Lang_Url extends PLL_Choose_Lang {
|
||||
/**
|
||||
* The name of the index file which is the entry point to all requests.
|
||||
* We need this before the global $wp_rewrite is created.
|
||||
* Also hardcoded in WP_Rewrite.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $index = 'index.php';
|
||||
|
||||
/**
|
||||
* Sets the language
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
if ( ! did_action( 'pll_language_defined' ) ) {
|
||||
$this->set_language_from_url();
|
||||
}
|
||||
|
||||
add_filter( 'request', array( $this, 'request' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the language according to information found in the url
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set_language_from_url() {
|
||||
$host = str_replace( 'www.', '', (string) wp_parse_url( $this->links_model->home, PHP_URL_HOST ) ); // Remove www. for the comparison
|
||||
$home_path = (string) wp_parse_url( $this->links_model->home, PHP_URL_PATH );
|
||||
|
||||
$requested_url = pll_get_requested_url();
|
||||
$requested_host = str_replace( 'www.', '', (string) wp_parse_url( $requested_url, PHP_URL_HOST ) ); // Remove www. for the comparison
|
||||
$requested_path = rtrim( str_replace( $this->index, '', (string) wp_parse_url( $requested_url, PHP_URL_PATH ) ), '/' ); // Some PHP setups turn requests for / into /index.php in REQUEST_URI
|
||||
$requested_query = wp_parse_url( $requested_url, PHP_URL_QUERY );
|
||||
|
||||
// Home is requested
|
||||
if ( $requested_host === $host && $requested_path === $home_path && empty( $requested_query ) ) {
|
||||
$this->home_language();
|
||||
add_action( 'setup_theme', array( $this, 'home_requested' ) );
|
||||
}
|
||||
|
||||
// Take care to post & page preview http://wordpress.org/support/topic/static-frontpage-url-parameter-url-language-information
|
||||
elseif ( isset( $_GET['preview'] ) && ( ( isset( $_GET['p'] ) && $id = (int) $_GET['p'] ) || ( isset( $_GET['page_id'] ) && $id = (int) $_GET['page_id'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$curlang = ( $lg = $this->model->post->get_language( $id ) ) ? $lg : $this->model->get_default_language();
|
||||
}
|
||||
|
||||
// Take care to ( unattached ) attachments
|
||||
elseif ( isset( $_GET['attachment_id'] ) && $id = (int) $_GET['attachment_id'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$curlang = ( $lg = $this->model->post->get_language( $id ) ) ? $lg : $this->get_preferred_language();
|
||||
}
|
||||
|
||||
elseif ( $slug = $this->links_model->get_language_from_url() ) {
|
||||
$curlang = $this->model->get_language( $slug );
|
||||
}
|
||||
|
||||
elseif ( $this->options['hide_default'] ) {
|
||||
$curlang = $this->model->get_default_language();
|
||||
}
|
||||
|
||||
// If no language found, check_language_code_in_url() will attempt to find one and redirect to the correct url
|
||||
// Otherwise a 404 will be fired in the preferred language
|
||||
$this->set_language( empty( $curlang ) ? $this->get_preferred_language() : $curlang );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the current language in query vars
|
||||
* useful for subdomains and multiple domains
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param array $qv main request query vars
|
||||
* @return array modified query vars
|
||||
*/
|
||||
public function request( $qv ) {
|
||||
// FIXME take care not to break untranslated content
|
||||
// FIXME media ?
|
||||
|
||||
// Untranslated post types
|
||||
if ( isset( $qv['post_type'] ) && ! $this->model->is_translated_post_type( $qv['post_type'] ) ) {
|
||||
return $qv;
|
||||
}
|
||||
|
||||
// Untranslated taxonomies
|
||||
$tax_qv = array_filter( wp_list_pluck( get_taxonomies( array(), 'objects' ), 'query_var' ) ); // Get all taxonomies query vars
|
||||
$tax_qv = array_intersect( $tax_qv, array_keys( $qv ) ); // Get all queried taxonomies query vars
|
||||
|
||||
if ( ! $this->model->is_translated_taxonomy( array_keys( $tax_qv ) ) ) {
|
||||
return $qv;
|
||||
}
|
||||
|
||||
if ( isset( $this->curlang ) && empty( $qv['lang'] ) ) {
|
||||
$qv['lang'] = $this->curlang->slug;
|
||||
}
|
||||
|
||||
return $qv;
|
||||
}
|
||||
}
|
||||
351
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang.php
vendored
Normal file
351
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/choose-lang.php
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class to choose the language
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
abstract class PLL_Choose_Lang {
|
||||
/**
|
||||
* Stores the plugin options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options;
|
||||
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* Instance of a child class of PLL_Links_Model.
|
||||
*
|
||||
* @var PLL_Links_Model
|
||||
*/
|
||||
public $links_model;
|
||||
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links_model = &$polylang->links_model;
|
||||
$this->model = &$polylang->model;
|
||||
$this->options = &$polylang->options;
|
||||
|
||||
$this->curlang = &$polylang->curlang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language for ajax requests
|
||||
* and setup actions
|
||||
* Any child class must call this method if it overrides it
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
if ( Polylang::is_ajax_on_front() || ! wp_using_themes() ) {
|
||||
$this->set_language( empty( $_REQUEST['lang'] ) ? $this->get_preferred_language() : $this->model->get_language( sanitize_key( $_REQUEST['lang'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
add_action( 'pre_comment_on_post', array( $this, 'pre_comment_on_post' ) ); // sets the language of comment
|
||||
add_action( 'parse_query', array( $this, 'parse_main_query' ), 2 ); // sets the language in special cases
|
||||
add_action( 'wp', array( $this, 'maybe_setcookie' ), 7 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current language
|
||||
* and fires the action 'pll_language_defined'.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param PLL_Language|false $curlang Current language.
|
||||
* @return void
|
||||
*/
|
||||
protected function set_language( $curlang ) {
|
||||
// Don't set the language a second time
|
||||
if ( isset( $this->curlang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Final check in case $curlang has an unexpected value
|
||||
// See https://wordpress.org/support/topic/detect-browser-language-sometimes-setting-null-language
|
||||
if ( ! $curlang instanceof PLL_Language ) {
|
||||
$curlang = $this->model->get_default_language();
|
||||
|
||||
if ( ! $curlang instanceof PLL_Language ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->curlang = $curlang;
|
||||
|
||||
$GLOBALS['text_direction'] = $this->curlang->is_rtl ? 'rtl' : 'ltr';
|
||||
if ( did_action( 'wp_default_styles' ) ) {
|
||||
wp_styles()->text_direction = $GLOBALS['text_direction'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when the current language is defined.
|
||||
*
|
||||
* @since 0.9.5
|
||||
*
|
||||
* @param string $slug Current language code.
|
||||
* @param PLL_Language $curlang Current language object.
|
||||
*/
|
||||
do_action( 'pll_language_defined', $this->curlang->slug, $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cookie to remember the language.
|
||||
* Setting PLL_COOKIE to false will disable cookie although it will break some functionalities
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_setcookie() {
|
||||
// Don't set cookie in javascript when a cache plugin is active.
|
||||
if ( ! pll_is_cache_active() && ! empty( $this->curlang ) && ! is_404() ) {
|
||||
$args = array(
|
||||
'domain' => 2 === $this->options['force_lang'] ? wp_parse_url( $this->links_model->home, PHP_URL_HOST ) : COOKIE_DOMAIN,
|
||||
'samesite' => 3 === $this->options['force_lang'] ? 'None' : 'Lax',
|
||||
);
|
||||
PLL_Cookie::set( $this->curlang->slug, $args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred language according to the browser preferences.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return string|bool The preferred language slug or false.
|
||||
*/
|
||||
public function get_preferred_browser_language() {
|
||||
if ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
|
||||
$accept_langs = PLL_Accept_Languages_Collection::from_accept_language_header( sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) );
|
||||
|
||||
$accept_langs->bubble_sort();
|
||||
|
||||
$languages = $this->model->get_languages_list( array( 'hide_empty' => true ) ); // Hides languages with no post.
|
||||
|
||||
/**
|
||||
* Filters the list of languages to use to match the browser preferences.
|
||||
*
|
||||
* @since 1.9.3
|
||||
*
|
||||
* @param array $languages Array of PLL_Language objects.
|
||||
*/
|
||||
$languages = apply_filters( 'pll_languages_for_browser_preferences', $languages );
|
||||
|
||||
return $accept_langs->find_best_match( $languages );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred language
|
||||
* either from the cookie if it's a returning visit
|
||||
* or according to browser preference
|
||||
* or the default language
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return PLL_Language|false browser preferred language or default language
|
||||
*/
|
||||
public function get_preferred_language() {
|
||||
$language = false;
|
||||
$cookie = false;
|
||||
|
||||
if ( isset( $_COOKIE[ PLL_COOKIE ] ) ) {
|
||||
// Check first if the user was already browsing this site.
|
||||
$language = sanitize_key( $_COOKIE[ PLL_COOKIE ] );
|
||||
$cookie = true;
|
||||
} elseif ( $this->options['browser'] ) {
|
||||
$language = $this->get_preferred_browser_language();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the visitor's preferred language (normally set first by cookie
|
||||
* if this is not the first visit, then by the browser preferences).
|
||||
* If no preferred language has been found or set by this filter,
|
||||
* Polylang fallbacks to the default language
|
||||
*
|
||||
* @since 1.0
|
||||
* @since 2.7 Added $cookie parameter.
|
||||
*
|
||||
* @param string|bool $language Preferred language code, false if none has been found.
|
||||
* @param bool $cookie Whether the preferred language has been defined by the cookie.
|
||||
*/
|
||||
$slug = apply_filters( 'pll_preferred_language', $language, $cookie );
|
||||
|
||||
// Return default if there is no preferences in the browser or preferences does not match our languages or it is requested not to use the browser preference
|
||||
return ( $lang = $this->model->get_language( $slug ) ) ? $lang : $this->model->get_default_language();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language when home page is requested
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function home_language() {
|
||||
// Test referer in case PLL_COOKIE is set to false. Since WP 3.6.1, wp_get_referer() validates the host which is exactly what we want
|
||||
// Thanks to Ov3rfly http://wordpress.org/support/topic/enhance-feature-when-front-page-is-visited-set-language-according-to-browser
|
||||
$language = $this->options['hide_default'] && ( wp_get_referer() || ! $this->options['browser'] ) ?
|
||||
$this->model->get_default_language() :
|
||||
$this->get_preferred_language(); // Sets the language according to browser preference or default language
|
||||
$this->set_language( $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* To call when the home page has been requested
|
||||
* Make sure to call this after 'setup_theme' has been fired as we need $wp_query
|
||||
* Performs a redirection to the home page in the current language if needed
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function home_requested() {
|
||||
if ( empty( $this->curlang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We are already on the right page
|
||||
if ( $this->curlang->is_default && $this->options['hide_default'] ) {
|
||||
$this->set_curlang_in_query( $GLOBALS['wp_query'] );
|
||||
|
||||
/**
|
||||
* Fires when the site root page is requested
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
do_action( 'pll_home_requested' );
|
||||
}
|
||||
// Redirect to the home page in the right language
|
||||
// Test to avoid crash if get_home_url returns something wrong
|
||||
// FIXME why this happens? http://wordpress.org/support/topic/polylang-crashes-1
|
||||
// Don't redirect if $_POST is not empty as it could break other plugins
|
||||
elseif ( is_string( $redirect = $this->curlang->get_home_url() ) && empty( $_POST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
// Don't forget the query string which may be added by plugins
|
||||
$query_string = wp_parse_url( pll_get_requested_url(), PHP_URL_QUERY );
|
||||
if ( ! empty( $query_string ) ) {
|
||||
$redirect .= ( $this->links_model->using_permalinks ? '?' : '&' ) . $query_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a visitor reaches the site home, Polylang redirects to the home page in the correct language.
|
||||
* This filter allows plugins to modify the redirected url or prevent this redirection
|
||||
* /!\ this filter may be fired *before* the theme is loaded
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param string $redirect the url the visitor will be redirected to
|
||||
*/
|
||||
$redirect = apply_filters( 'pll_redirect_home', $redirect );
|
||||
if ( $redirect && wp_validate_redirect( $redirect ) ) {
|
||||
$this->maybe_setcookie();
|
||||
header( 'Vary: Accept-Language' );
|
||||
wp_safe_redirect( $redirect, 302, POLYLANG );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the language when posting a comment
|
||||
*
|
||||
* @since 0.8.4
|
||||
*
|
||||
* @param int $post_id the post being commented
|
||||
* @return void
|
||||
*/
|
||||
public function pre_comment_on_post( $post_id ) {
|
||||
$this->set_language( $this->model->post->get_language( $post_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies some main query vars for the home page and the page for posts
|
||||
* to enable one home page (and one page for posts) per language.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param WP_Query $query Instance of WP_Query.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_main_query( $query ) {
|
||||
if ( ! $query->is_main_query() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This filter allows to set the language based on information contained in the main query
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param PLL_Language|false $lang Language object or false.
|
||||
* @param WP_Query $query WP_Query object.
|
||||
*/
|
||||
if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) {
|
||||
$this->set_language( $lang );
|
||||
$this->set_curlang_in_query( $query );
|
||||
} elseif ( ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) ) && $lang = get_query_var( 'lang' ) ) {
|
||||
$lang = $this->model->get_language( $lang );
|
||||
$this->set_language( $lang ); // Set the language now otherwise it will be too late to filter sticky posts!
|
||||
|
||||
// Set is_home on translated home page when it displays posts. It must be true on page 2, 3... too.
|
||||
$query->is_home = true;
|
||||
$query->is_tax = false;
|
||||
$query->is_archive = false;
|
||||
|
||||
// Filters is_front_page() in case a static front page is not translated in this language.
|
||||
add_filter( 'option_show_on_front', array( $this, 'filter_option_show_on_front' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the option show_on_front when the current front page displays posts.
|
||||
*
|
||||
* This is useful when a static front page is not translated in all languages.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function filter_option_show_on_front() {
|
||||
return 'posts';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current language in the query.
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
* @param WP_Query $query Instance of WP_Query.
|
||||
* @return void
|
||||
*/
|
||||
protected function set_curlang_in_query( &$query ) {
|
||||
if ( ! empty( $this->curlang ) ) {
|
||||
$pll_query = new PLL_Query( $query, $this->model );
|
||||
$pll_query->set_language( $this->curlang );
|
||||
}
|
||||
}
|
||||
}
|
||||
331
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-auto-translate.php
vendored
Normal file
331
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-auto-translate.php
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto translates the posts and terms ids
|
||||
* Useful for example for themes querying a specific cat
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
class PLL_Frontend_Auto_Translate {
|
||||
/**
|
||||
* @var PLL_Model
|
||||
*/
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->model = &$polylang->model;
|
||||
$this->curlang = &$polylang->curlang;
|
||||
|
||||
add_action( 'parse_query', array( $this, 'translate_included_ids_in_query' ), 100 ); // After all Polylang filters.
|
||||
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 20, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the translated post in the current language.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $post_id The ID of the post to translate.
|
||||
* @return int
|
||||
*
|
||||
* @phpstan-return int<0, max>
|
||||
*/
|
||||
protected function get_post( $post_id ) {
|
||||
return $this->model->post->get( $post_id, $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the translated term in the current language.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param int $term_id The ID of the term to translate.
|
||||
* @return int
|
||||
*
|
||||
* @phpstan-return int<0, max>
|
||||
*/
|
||||
protected function get_term( $term_id ) {
|
||||
return $this->model->term->get( $term_id, $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters posts query to automatically translate included ids
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param WP_Query $query WP_Query object
|
||||
* @return void
|
||||
*/
|
||||
public function translate_included_ids_in_query( $query ) {
|
||||
global $wpdb;
|
||||
$qv = &$query->query_vars;
|
||||
|
||||
if ( $query->is_main_query() || isset( $qv['lang'] ) || ( ! empty( $qv['post_type'] ) && ! $this->model->is_translated_post_type( $qv['post_type'] ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// /!\ always keep untranslated as is
|
||||
|
||||
// Term ids separated by a comma
|
||||
$arr = array();
|
||||
if ( ! empty( $qv['cat'] ) ) {
|
||||
foreach ( explode( ',', $qv['cat'] ) as $cat ) {
|
||||
$tr = $this->get_term( abs( $cat ) );
|
||||
$arr[] = $cat < 0 ? -$tr : $tr;
|
||||
}
|
||||
|
||||
$qv['cat'] = implode( ',', $arr );
|
||||
}
|
||||
|
||||
// Category_name
|
||||
$arr = array();
|
||||
if ( ! empty( $qv['category_name'] ) ) {
|
||||
foreach ( explode( ',', $qv['category_name'] ) as $slug ) {
|
||||
$arr[] = $this->get_translated_term_by( 'slug', $slug, 'category' );
|
||||
}
|
||||
|
||||
$qv['category_name'] = implode( ',', $arr );
|
||||
}
|
||||
|
||||
// Array of term ids
|
||||
foreach ( array( 'category__and', 'category__in', 'category__not_in', 'tag__and', 'tag__in', 'tag__not_in' ) as $key ) {
|
||||
$arr = array();
|
||||
if ( ! empty( $qv[ $key ] ) ) {
|
||||
foreach ( $qv[ $key ] as $cat ) {
|
||||
$arr[] = ( $tr = $this->get_term( $cat ) ) ? $tr : $cat;
|
||||
}
|
||||
$qv[ $key ] = $arr;
|
||||
}
|
||||
}
|
||||
|
||||
// Tag
|
||||
if ( ! empty( $qv['tag'] ) ) {
|
||||
$qv['tag'] = $this->translate_terms_list( $qv['tag'], 'post_tag' );
|
||||
}
|
||||
|
||||
// tag_id can only take one id
|
||||
if ( ! empty( $qv['tag_id'] ) && $tr_id = $this->get_term( $qv['tag_id'] ) ) {
|
||||
$qv['tag_id'] = $tr_id;
|
||||
}
|
||||
|
||||
// Array of tag slugs
|
||||
foreach ( array( 'tag_slug__and', 'tag_slug__in' ) as $key ) {
|
||||
$arr = array();
|
||||
if ( ! empty( $qv[ $key ] ) ) {
|
||||
foreach ( $qv[ $key ] as $slug ) {
|
||||
$arr[] = $this->get_translated_term_by( 'slug', $slug, 'post_tag' );
|
||||
}
|
||||
|
||||
$qv[ $key ] = $arr;
|
||||
}
|
||||
}
|
||||
|
||||
// Custom taxonomies
|
||||
// According to the codex, this type of query is deprecated as of WP 3.1 but it does not appear in WP 3.5 source code
|
||||
foreach ( array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) ) as $taxonomy ) {
|
||||
$tax = get_taxonomy( $taxonomy );
|
||||
if ( ! empty( $tax ) && ! empty( $qv[ $tax->query_var ] ) ) {
|
||||
$qv[ $tax->query_var ] = $this->translate_terms_list( $qv[ $tax->query_var ], $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
// Tax_query since WP 3.1
|
||||
if ( ! empty( $qv['tax_query'] ) && is_array( $qv['tax_query'] ) ) {
|
||||
$qv['tax_query'] = $this->translate_tax_query_recursive( $qv['tax_query'] );
|
||||
}
|
||||
|
||||
// p, page_id, post_parent can only take one id
|
||||
foreach ( array( 'p', 'page_id', 'post_parent' ) as $key ) {
|
||||
if ( ! empty( $qv[ $key ] ) && $tr_id = $this->get_post( $qv[ $key ] ) ) {
|
||||
$qv[ $key ] = $tr_id;
|
||||
}
|
||||
}
|
||||
|
||||
// name, can only take one slug
|
||||
if ( ! empty( $qv['name'] ) && is_string( $qv['name'] ) ) {
|
||||
if ( empty( $qv['post_type'] ) ) {
|
||||
$post_types = array( 'post' );
|
||||
} elseif ( 'any' === $qv['post_type'] ) {
|
||||
$post_types = get_post_types( array( 'exclude_from_search' => false ) ); // May return a empty array
|
||||
} else {
|
||||
$post_types = (array) $qv['post_type'];
|
||||
}
|
||||
|
||||
if ( ! empty( $post_types ) ) {
|
||||
// No function to get post by name except get_posts itself
|
||||
$id = $wpdb->get_var(
|
||||
sprintf(
|
||||
"SELECT ID from {$wpdb->posts}
|
||||
WHERE {$wpdb->posts}.post_type IN ( '%s' )
|
||||
AND post_name='%s'",
|
||||
implode( "', '", esc_sql( $post_types ) ),
|
||||
esc_sql( $qv['name'] )
|
||||
)
|
||||
);
|
||||
$qv['name'] = ( $id && ( $tr_id = $this->get_post( $id ) ) && $tr = get_post( $tr_id ) ) ? $tr->post_name : $qv['name'];
|
||||
}
|
||||
}
|
||||
|
||||
// pagename, the page id is already available in queried_object_id
|
||||
if ( ! empty( $qv['pagename'] ) && ! empty( $query->queried_object_id ) && $tr_id = $this->get_post( $query->queried_object_id ) ) {
|
||||
$query->queried_object_id = $tr_id;
|
||||
$qv['pagename'] = get_page_uri( $tr_id );
|
||||
}
|
||||
|
||||
// Array of post ids
|
||||
// post_parent__in & post_parent__not_in since WP 3.6
|
||||
foreach ( array( 'post__in', 'post__not_in', 'post_parent__in', 'post_parent__not_in' ) as $key ) { // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn
|
||||
$arr = array();
|
||||
if ( ! empty( $qv[ $key ] ) ) {
|
||||
// post__in used by the 2 functions below
|
||||
// Useless to filter them as output is already in the right language and would result in performance loss
|
||||
foreach ( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ) as $trace ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
if ( in_array( $trace['function'], array( 'wp_nav_menu', 'gallery_shortcode' ) ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $qv[ $key ] as $p ) {
|
||||
$arr[] = ( $tr = $this->get_post( $p ) ) ? $tr : $p;
|
||||
}
|
||||
|
||||
$qv[ $key ] = $arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the terms query to automatically translate included ids.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param array $args An array of get_terms() arguments.
|
||||
* @param array $taxonomies An array of taxonomy names.
|
||||
* @return array
|
||||
*/
|
||||
public function get_terms_args( $args, $taxonomies ) {
|
||||
if ( ! isset( $args['lang'] ) && ! empty( $args['include'] ) && ( empty( $taxonomies ) || $this->model->is_translated_taxonomy( $taxonomies ) ) ) {
|
||||
$arr = array();
|
||||
|
||||
foreach ( wp_parse_id_list( $args['include'] ) as $id ) {
|
||||
$arr[] = ( $tr = $this->get_term( $id ) ) ? $tr : $id;
|
||||
}
|
||||
|
||||
$args['include'] = $arr;
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates tax queries
|
||||
* Compatible with nested tax queries introduced in WP 4.1
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param array $tax_queries An array of tax queries.
|
||||
* @return array Translated tax queries.
|
||||
*/
|
||||
protected function translate_tax_query_recursive( $tax_queries ) {
|
||||
foreach ( $tax_queries as $key => $q ) {
|
||||
if ( ! is_array( $q ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $q['taxonomy'], $q['terms'] ) && $this->model->is_translated_taxonomy( $q['taxonomy'] ) ) {
|
||||
$arr = array();
|
||||
$field = isset( $q['field'] ) && in_array( $q['field'], array( 'slug', 'name' ) ) ? $q['field'] : 'term_id';
|
||||
foreach ( (array) $q['terms'] as $t ) {
|
||||
$arr[] = $this->get_translated_term_by( $field, $t, $q['taxonomy'] );
|
||||
}
|
||||
|
||||
$tax_queries[ $key ]['terms'] = $arr;
|
||||
} else {
|
||||
// Nested queries.
|
||||
$tax_queries[ $key ] = $this->translate_tax_query_recursive( $q );
|
||||
}
|
||||
}
|
||||
|
||||
return $tax_queries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a term given one field.
|
||||
*
|
||||
* @since 2.3.3
|
||||
*
|
||||
* @param string $field Either 'slug', 'name', 'term_id', or 'term_taxonomy_id'
|
||||
* @param string|int $term Search for this term value
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @return string|int Translated term slug, name, term_id or term_taxonomy_id
|
||||
*/
|
||||
protected function get_translated_term_by( $field, $term, $taxonomy ) {
|
||||
if ( 'term_id' === $field ) {
|
||||
if ( $tr_id = $this->get_term( $term ) ) {
|
||||
return $tr_id;
|
||||
}
|
||||
} else {
|
||||
$terms = get_terms( array( 'taxonomy' => $taxonomy, $field => $term, 'lang' => '' ) );
|
||||
|
||||
if ( ! empty( $terms ) && is_array( $terms ) ) {
|
||||
$t = reset( $terms );
|
||||
if ( ! $t instanceof WP_Term ) {
|
||||
return $term;
|
||||
}
|
||||
$tr_id = $this->get_term( $t->term_id );
|
||||
|
||||
if ( ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) {
|
||||
return $tr->$field;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $term;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a list of term slugs provided either as an array or a string
|
||||
* with slugs separated by a comma or a '+'.
|
||||
*
|
||||
* @since 3.2.8
|
||||
*
|
||||
* @param string|string[] $query_var The list of term slugs.
|
||||
* @param string $taxonomy The taxonomy for terms.
|
||||
* @return string|string[] The translated list.
|
||||
*/
|
||||
protected function translate_terms_list( $query_var, $taxonomy ) {
|
||||
$slugs = array();
|
||||
|
||||
if ( is_array( $query_var ) ) {
|
||||
$slugs = &$query_var;
|
||||
} elseif ( is_string( $query_var ) ) {
|
||||
$sep = strpos( $query_var, ',' ) !== false ? ',' : '+'; // Two possible separators.
|
||||
$slugs = explode( $sep, $query_var );
|
||||
}
|
||||
|
||||
foreach ( $slugs as &$slug ) {
|
||||
$slug = $this->get_translated_term_by( 'slug', $slug, $taxonomy );
|
||||
}
|
||||
|
||||
if ( ! empty( $sep ) ) {
|
||||
$query_var = implode( $sep, $slugs );
|
||||
}
|
||||
|
||||
return $query_var;
|
||||
}
|
||||
}
|
||||
350
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-links.php
vendored
Normal file
350
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-links.php
vendored
Normal file
@@ -0,0 +1,350 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages links filters on frontend
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* Our internal non persistent cache object
|
||||
*
|
||||
* @var PLL_Cache<string>
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* Stores a list of files and functions that home_url() must not filter.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $black_list = array();
|
||||
|
||||
/**
|
||||
* Stores a list of files and functions that home_url() must filter.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $white_list = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Adds filters once the language is defined
|
||||
* Low priority on links filters to come after any other modification
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->curlang = &$polylang->curlang;
|
||||
$this->cache = new PLL_Cache();
|
||||
|
||||
// Rewrites author and date links to filter them by language
|
||||
foreach ( array( 'feed_link', 'author_link', 'search_link', 'year_link', 'month_link', 'day_link' ) as $filter ) {
|
||||
add_filter( $filter, array( $this, 'archive_link' ), 20 );
|
||||
}
|
||||
|
||||
// Meta in the html head section
|
||||
add_action( 'wp_head', array( $this, 'wp_head' ), 1 );
|
||||
|
||||
// Modifies the home url
|
||||
if ( pll_get_constant( 'PLL_FILTER_HOME_URL', true ) ) {
|
||||
add_filter( 'home_url', array( $this, 'home_url' ), 10, 2 );
|
||||
}
|
||||
|
||||
if ( $this->options['force_lang'] > 1 ) {
|
||||
// Rewrites next and previous post links when not automatically done by WordPress
|
||||
add_filter( 'get_pagenum_link', array( $this, 'archive_link' ), 20 );
|
||||
|
||||
add_filter( 'get_shortlink', array( $this, 'shortlink' ), 20, 2 );
|
||||
|
||||
// Rewrites ajax url
|
||||
add_filter( 'admin_url', array( $this, 'admin_url' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the author and date links to add the language parameter (as well as feed link).
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param string $link The permalink to the archive.
|
||||
* @return string The modified link.
|
||||
*/
|
||||
public function archive_link( $link ) {
|
||||
return $this->links_model->switch_language_in_link( $link, $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies page links
|
||||
* and caches the result
|
||||
*
|
||||
* @since 1.7
|
||||
*
|
||||
* @param string $link The page link.
|
||||
* @param int $post_id The post ID.
|
||||
* @return string The modified page link.
|
||||
*/
|
||||
public function _get_page_link( $link, $post_id ) {
|
||||
$cache_key = "post:{$post_id}:{$link}";
|
||||
if ( false === $_link = $this->cache->get( $cache_key ) ) {
|
||||
$_link = parent::_get_page_link( $link, $post_id );
|
||||
$this->cache->set( $cache_key, $_link );
|
||||
}
|
||||
return $_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies attachment links
|
||||
* and caches the result
|
||||
*
|
||||
* @since 1.6.2
|
||||
*
|
||||
* @param string $link The attachment link.
|
||||
* @param int $post_id The attachment post ID.
|
||||
* @return string The modified attachment link.
|
||||
*/
|
||||
public function attachment_link( $link, $post_id ) {
|
||||
$cache_key = "post:{$post_id}:{$link}";
|
||||
if ( false === $_link = $this->cache->get( $cache_key ) ) {
|
||||
$_link = parent::attachment_link( $link, $post_id );
|
||||
$this->cache->set( $cache_key, $_link );
|
||||
}
|
||||
return $_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies custom posts links
|
||||
* and caches the result.
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param string $link The post link.
|
||||
* @param WP_Post $post The post object.
|
||||
* @return string The modified post link.
|
||||
*/
|
||||
public function post_type_link( $link, $post ) {
|
||||
$cache_key = "post:{$post->ID}:{$link}";
|
||||
if ( false === $_link = $this->cache->get( $cache_key ) ) {
|
||||
$_link = parent::post_type_link( $link, $post );
|
||||
$this->cache->set( $cache_key, $_link );
|
||||
}
|
||||
return $_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies filtered taxonomies ( post format like ) and translated taxonomies links
|
||||
* and caches the result.
|
||||
*
|
||||
* @since 0.7
|
||||
*
|
||||
* @param string $link The term link.
|
||||
* @param WP_Term $term The term object.
|
||||
* @param string $tax The taxonomy name.
|
||||
* @return string The modified link.
|
||||
*/
|
||||
public function term_link( $link, $term, $tax ) {
|
||||
$cache_key = "term:{$term->term_id}:{$link}";
|
||||
if ( false === $_link = $this->cache->get( $cache_key ) ) {
|
||||
if ( in_array( $tax, $this->model->get_filtered_taxonomies() ) ) {
|
||||
$_link = $this->links_model->switch_language_in_link( $link, $this->curlang );
|
||||
|
||||
/** This filter is documented in include/filters-links.php */
|
||||
$_link = apply_filters( 'pll_term_link', $_link, $this->curlang, $term );
|
||||
}
|
||||
|
||||
else {
|
||||
$_link = parent::term_link( $link, $term, $tax );
|
||||
}
|
||||
$this->cache->set( $cache_key, $_link );
|
||||
}
|
||||
return $_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the post short link when using one domain or subdomain per language.
|
||||
*
|
||||
* @since 2.6.9
|
||||
*
|
||||
* @param string $link Post permalink.
|
||||
* @param int $post_id Post id.
|
||||
* @return string Post permalink with the correct domain.
|
||||
*/
|
||||
public function shortlink( $link, $post_id ) {
|
||||
$post_type = get_post_type( $post_id );
|
||||
return $this->model->is_translated_post_type( $post_type ) ? $this->links_model->switch_language_in_link( $link, $this->model->post->get_language( $post_id ) ) : $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs references to translated pages ( if exists ) in the html head section
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wp_head() {
|
||||
// Don't output anything on paged archives: see https://wordpress.org/support/topic/hreflang-on-page2
|
||||
// Don't output anything on paged pages and paged posts
|
||||
if ( is_paged() || ( is_singular() && ( $page = get_query_var( 'page' ) ) && $page > 1 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$urls = array();
|
||||
|
||||
// Google recommends to include self link https://support.google.com/webmasters/answer/189077?hl=en
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
if ( $url = $this->links->get_translation_url( $language ) ) {
|
||||
$urls[ $language->get_locale( 'display' ) ] = $url;
|
||||
}
|
||||
}
|
||||
|
||||
// Outputs the section only if there are translations ( $urls always contains self link )
|
||||
if ( ! empty( $urls ) && count( $urls ) > 1 ) {
|
||||
$languages = array();
|
||||
$hreflangs = array();
|
||||
|
||||
// Prepare the list of languages to remove the country code
|
||||
foreach ( array_keys( $urls ) as $locale ) {
|
||||
$split = explode( '-', $locale );
|
||||
$languages[ $locale ] = reset( $split );
|
||||
}
|
||||
|
||||
$count = array_count_values( $languages );
|
||||
|
||||
foreach ( $urls as $locale => $url ) {
|
||||
$lang = $count[ $languages[ $locale ] ] > 1 ? $locale : $languages[ $locale ]; // Output the country code only when necessary
|
||||
$hreflangs[ $lang ] = $url;
|
||||
}
|
||||
|
||||
// Adds the site root url when the default language code is not hidden
|
||||
// See https://wordpress.org/support/topic/implementation-of-hreflangx-default
|
||||
if ( is_front_page() && ! $this->options['hide_default'] && $this->options['force_lang'] < 3 ) {
|
||||
$hreflangs['x-default'] = home_url( '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of rel hreflang attributes
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @param array $hreflangs Array of urls with language codes as keys
|
||||
*/
|
||||
$hreflangs = apply_filters( 'pll_rel_hreflang_attributes', $hreflangs );
|
||||
|
||||
foreach ( $hreflangs as $lang => $url ) {
|
||||
printf( '<link rel="alternate" href="%s" hreflang="%s" />' . "\n", esc_url( $url ), esc_attr( $lang ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the home url to get the right language.
|
||||
*
|
||||
* @since 0.4
|
||||
*
|
||||
* @param string $url The home URL including scheme and path.
|
||||
* @param string $path Path relative to the home URL.
|
||||
* @return string
|
||||
*/
|
||||
public function home_url( $url, $path ) {
|
||||
if ( ! ( did_action( 'template_redirect' ) || did_action( 'login_init' ) ) || rtrim( $url, '/' ) != $this->links_model->home ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// We *want* to filter the home url in these cases
|
||||
if ( empty( $this->white_list ) ) {
|
||||
// On Windows get_theme_root() mixes / and \
|
||||
// We want only \ for the comparison with debug_backtrace
|
||||
$theme_root = get_theme_root();
|
||||
$theme_root = ( false === strpos( $theme_root, '\\' ) ) ? $theme_root : str_replace( '/', '\\', $theme_root );
|
||||
|
||||
$white_list = array(
|
||||
array( 'file' => $theme_root ),
|
||||
array( 'function' => 'wp_nav_menu' ),
|
||||
array( 'function' => 'login_footer' ),
|
||||
array( 'function' => 'get_custom_logo' ),
|
||||
array( 'function' => 'render_block_core_site_title' ),
|
||||
);
|
||||
|
||||
if ( 3 === $this->options['force_lang'] ) {
|
||||
$white_list[] = array( 'function' => 'redirect_canonical' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the white list of the Polylang 'home_url' filter.
|
||||
*
|
||||
* @since 1.1.2
|
||||
*
|
||||
* @param string[][] $white_list An array of arrays each of them having a 'file' key
|
||||
* and/or a 'function' key to decide which functions in
|
||||
* which files using home_url() calls must be filtered.
|
||||
*/
|
||||
$this->white_list = apply_filters( 'pll_home_url_white_list', $white_list );
|
||||
}
|
||||
|
||||
// We don't want to filter the home url in these cases.
|
||||
if ( empty( $this->black_list ) ) {
|
||||
$black_list = array(
|
||||
array( 'file' => 'searchform.php' ), // Since WP 3.6 searchform.php is passed through get_search_form.
|
||||
array( 'function' => 'get_search_form' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the black list of the Polylang 'home_url' filter.
|
||||
*
|
||||
* @since 1.1.2
|
||||
*
|
||||
* @param string[][] $black_list An array of arrays each of them having a 'file' key
|
||||
* and/or a 'function' key to decide which functions in
|
||||
* which files using home_url() calls must be filtered.
|
||||
*/
|
||||
$this->black_list = apply_filters( 'pll_home_url_black_list', $black_list );
|
||||
}
|
||||
|
||||
$traces = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
||||
unset( $traces[0], $traces[1] ); // We don't need the last 2 calls: this function + call_user_func_array (or apply_filters on PHP7+)
|
||||
|
||||
foreach ( $traces as $trace ) {
|
||||
// Black list first
|
||||
foreach ( $this->black_list as $v ) {
|
||||
if ( ( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) ) || ( ! empty( $v['function'] ) && $trace['function'] === $v['function'] ) ) {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->white_list as $v ) {
|
||||
if ( ( ! empty( $v['function'] ) && $trace['function'] === $v['function'] ) ||
|
||||
( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) && in_array( $trace['function'], array( 'home_url', 'get_home_url', 'bloginfo', 'get_bloginfo' ) ) ) ) {
|
||||
$ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return empty( $ok ) ? $url : ( empty( $path ) ? rtrim( $this->links->get_home_url( $this->curlang ), '/' ) : $this->links->get_home_url( $this->curlang ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the ajax url when using domains or subdomains.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param string $url The admin url with path evaluated by WordPress.
|
||||
* @param string $path Path relative to the admin URL.
|
||||
* @return string
|
||||
*/
|
||||
public function admin_url( $url, $path ) {
|
||||
return 'admin-ajax.php' === $path ? $this->links_model->switch_language_in_link( $url, $this->curlang ) : $url;
|
||||
}
|
||||
}
|
||||
183
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-search.php
vendored
Normal file
183
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-search.php
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filters search forms when using permalinks
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Frontend_Filters_Search {
|
||||
/**
|
||||
* Instance of a child class of PLL_Links_Model.
|
||||
*
|
||||
* @var PLL_Links_Model
|
||||
*/
|
||||
public $links_model;
|
||||
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->links_model = &$polylang->links_model;
|
||||
$this->curlang = &$polylang->curlang;
|
||||
|
||||
// Adds the language information in the search form
|
||||
// Low priority in case the search form is created using the same filter as described in http://codex.wordpress.org/Function_Reference/get_search_form
|
||||
add_filter( 'get_search_form', array( $this, 'get_search_form' ), 99 );
|
||||
|
||||
// Adds the language information in the search block.
|
||||
add_filter( 'render_block_core/search', array( $this, 'get_search_form' ) );
|
||||
|
||||
// Adds the language information in admin bar search form
|
||||
add_action( 'add_admin_bar_menus', array( $this, 'add_admin_bar_menus' ) );
|
||||
|
||||
|
||||
// Adds javascript at the end of the document
|
||||
// Was used for WP < 3.6. kept just in case
|
||||
if ( defined( 'PLL_SEARCH_FORM_JS' ) && PLL_SEARCH_FORM_JS ) {
|
||||
add_action( 'wp_footer', array( $this, 'wp_print_footer_scripts' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language information in the search form.
|
||||
*
|
||||
* Does not work if searchform.php ( prior to WP 3.6 ) is used or if the search form is hardcoded in another template file
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $form The search form HTML.
|
||||
* @return string Modified search form.
|
||||
*/
|
||||
public function get_search_form( $form ) {
|
||||
if ( empty( $form ) || empty( $this->curlang ) ) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
if ( $this->links_model->using_permalinks ) {
|
||||
// Take care to modify only the url in the <form> tag.
|
||||
preg_match( '#<form.+?>#s', $form, $matches );
|
||||
$old = reset( $matches );
|
||||
if ( empty( $old ) ) {
|
||||
return $form;
|
||||
}
|
||||
// Replace action attribute (a text with no space and no closing tag within double quotes or simple quotes or without quotes).
|
||||
$new = preg_replace( '#\saction=("[^"\r\n]+"|\'[^\'\r\n]+\'|[^\'"][^>\s]+)#', ' action="' . esc_url( $this->curlang->get_search_url() ) . '"', $old );
|
||||
if ( empty( $new ) ) {
|
||||
return $form;
|
||||
}
|
||||
$form = str_replace( $old, $new, $form );
|
||||
} else {
|
||||
$form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form );
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the language information in the admin bar search form.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_admin_bar_menus() {
|
||||
// Backward compatibility with WP < 6.6. The priority was 4 before this version, 9999 since then.
|
||||
$priority = has_action( 'admin_bar_menu', 'wp_admin_bar_search_menu' );
|
||||
if ( ! is_int( $priority ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', $priority );
|
||||
add_action( 'admin_bar_menu', array( $this, 'admin_bar_search_menu' ), $priority );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites the admin bar search form to pass our get_search_form filter. See #21342.
|
||||
* Code last checked: WP 5.4.1.
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance, passed by reference.
|
||||
* @return void
|
||||
*/
|
||||
public function admin_bar_search_menu( $wp_admin_bar ) {
|
||||
$form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
|
||||
$form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
|
||||
$form .= '<label for="adminbar-search" class="screen-reader-text">' .
|
||||
/* translators: Hidden accessibility text. */
|
||||
esc_html__( 'Search', 'polylang' ) .
|
||||
'</label>';
|
||||
$form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search', 'polylang' ) . '" />';
|
||||
$form .= '</form>';
|
||||
|
||||
$wp_admin_bar->add_node(
|
||||
array(
|
||||
'parent' => 'top-secondary',
|
||||
'id' => 'search',
|
||||
'title' => $this->get_search_form( $form ), // Pass the get_search_form filter.
|
||||
'meta' => array(
|
||||
'class' => 'admin-bar-search',
|
||||
'tabindex' => -1,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows modifying the search form if it does not pass get_search_form.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wp_print_footer_scripts() {
|
||||
/*
|
||||
* Don't use directly e[0] just in case there is somewhere else an element named 's'
|
||||
* Check before if the hidden input has not already been introduced by get_search_form ( FIXME: is there a way to improve this ) ?
|
||||
* Thanks to AndyDeGroo for improving the code for compatibility with old browsers
|
||||
* http://wordpress.org/support/topic/development-of-polylang-version-08?replies=6#post-2645559
|
||||
*/
|
||||
$lang = esc_js( $this->curlang->slug );
|
||||
$js = "e = document.getElementsByName( 's' );
|
||||
for ( i = 0; i < e.length; i++ ) {
|
||||
if ( e[i].tagName.toUpperCase() == 'INPUT' ) {
|
||||
s = e[i].parentNode.parentNode.children;
|
||||
l = 0;
|
||||
for ( j = 0; j < s.length; j++ ) {
|
||||
if ( s[j].name == 'lang' ) {
|
||||
l = 1;
|
||||
}
|
||||
}
|
||||
if ( l == 0 ) {
|
||||
var ih = document.createElement( 'input' );
|
||||
ih.type = 'hidden';
|
||||
ih.name = 'lang';
|
||||
ih.value = '{$lang}';
|
||||
e[i].parentNode.appendChild( ih );
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
$type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"';
|
||||
|
||||
if ( $type_attr ) {
|
||||
$js = "/* <![CDATA[ */\n{$js}\n/* ]]> */";
|
||||
}
|
||||
|
||||
echo "<script{$type_attr}>\n{$js}\n</script>\n"; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
}
|
||||
153
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-widgets.php
vendored
Normal file
153
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters-widgets.php
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filters widgets by language on frontend
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class PLL_Frontend_Filters_Widgets {
|
||||
/**
|
||||
* Internal non persistent cache object.
|
||||
*
|
||||
* @var PLL_Cache<array>
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
$this->curlang = &$polylang->curlang;
|
||||
$this->cache = new PLL_Cache();
|
||||
|
||||
add_filter( 'sidebars_widgets', array( $this, 'sidebars_widgets' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove widgets from sidebars if they are not visible in the current language
|
||||
* Needed to allow is_active_sidebar() to return false if all widgets are not for the current language. See #54
|
||||
*
|
||||
* @since 2.1
|
||||
* @since 2.4 The result is cached as the function can be very expensive in case there are a lot of widgets
|
||||
*
|
||||
* @param array $sidebars_widgets An associative array of sidebars and their widgets
|
||||
* @return array
|
||||
*/
|
||||
public function sidebars_widgets( $sidebars_widgets ) {
|
||||
global $wp_registered_widgets;
|
||||
|
||||
if ( empty( $wp_registered_widgets ) ) {
|
||||
return $sidebars_widgets;
|
||||
}
|
||||
|
||||
$cache_key = $this->cache->get_unique_key( 'sidebars_widgets_', $sidebars_widgets );
|
||||
$_sidebars_widgets = $this->cache->get( $cache_key );
|
||||
|
||||
if ( false !== $_sidebars_widgets ) {
|
||||
return $_sidebars_widgets;
|
||||
}
|
||||
|
||||
$sidebars_widgets = $this->filter_widgets_sidebars( $sidebars_widgets, $wp_registered_widgets );
|
||||
|
||||
return $this->cache->set( $cache_key, $sidebars_widgets );
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that handles the removal of widgets in the sidebars depending on their display language.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $widget_data An array containing the widget data
|
||||
* @param array $sidebars_widgets An associative array of sidebars and their widgets
|
||||
* @param string $sidebar Sidebar name
|
||||
* @param int $key Widget number
|
||||
* @return array An associative array of sidebars and their widgets
|
||||
*/
|
||||
public function handle_widget_in_sidebar_callback( $widget_data, $sidebars_widgets, $sidebar, $key ) {
|
||||
// Remove the widget if not visible in the current language
|
||||
if ( ! empty( $widget_data['settings'][ $widget_data['number'] ]['pll_lang'] ) && $widget_data['settings'][ $widget_data['number'] ]['pll_lang'] !== $this->curlang->slug ) {
|
||||
unset( $sidebars_widgets[ $sidebar ][ $key ] );
|
||||
}
|
||||
return $sidebars_widgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse the widgets sidebars and sort the ones that should be displayed or not.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $sidebars_widgets An associative array of sidebars and their widgets
|
||||
* @param array $wp_registered_widgets Array of all registered widgets.
|
||||
* @return array An associative array of sidebars and their widgets
|
||||
*/
|
||||
public function filter_widgets_sidebars( $sidebars_widgets, $wp_registered_widgets ) {
|
||||
foreach ( $sidebars_widgets as $sidebar => $widgets ) {
|
||||
if ( 'wp_inactive_widgets' === $sidebar || empty( $widgets ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $widgets as $key => $widget ) {
|
||||
if ( ! $this->is_widget_object( $wp_registered_widgets, $widget ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widget_data = $this->get_widget_data( $wp_registered_widgets, $widget );
|
||||
|
||||
$sidebars_widgets = $this->handle_widget_in_sidebar_callback( $widget_data, $sidebars_widgets, $sidebar, $key );
|
||||
}
|
||||
}
|
||||
return $sidebars_widgets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the widget is an object.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $wp_registered_widgets Array of all registered widgets.
|
||||
* @param string $widget String that identifies the widget.
|
||||
* @return bool True if object, false otherwise.
|
||||
*/
|
||||
protected function is_widget_object( $wp_registered_widgets, $widget ) {
|
||||
// Nothing can be done if the widget is created using pre WP2.8 API :(
|
||||
// There is no object, so we can't access it to get the widget options
|
||||
return isset( $wp_registered_widgets[ $widget ]['callback'] ) &&
|
||||
is_array( $wp_registered_widgets[ $widget ]['callback'] ) &&
|
||||
isset( $wp_registered_widgets[ $widget ]['callback'][0] ) &&
|
||||
is_object( $wp_registered_widgets[ $widget ]['callback'][0] ) &&
|
||||
method_exists( $wp_registered_widgets[ $widget ]['callback'][0], 'get_settings' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widgets settings and number.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param array $wp_registered_widgets Array of all registered widgets.
|
||||
* @param string $widget String that identifies the widget.
|
||||
* @return array An array containing the widget settings and number.
|
||||
*/
|
||||
protected function get_widget_data( $wp_registered_widgets, $widget ) {
|
||||
$widget_settings = $wp_registered_widgets[ $widget ]['callback'][0]->get_settings();
|
||||
$number = $wp_registered_widgets[ $widget ]['params'][0]['number'];
|
||||
|
||||
return array(
|
||||
'settings' => $widget_settings,
|
||||
'number' => $number,
|
||||
);
|
||||
}
|
||||
}
|
||||
210
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters.php
vendored
Normal file
210
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-filters.php
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filters content by language on frontend
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Frontend_Filters extends PLL_Filters {
|
||||
/**
|
||||
* Constructor: setups filters and actions
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
// Filters the WordPress locale
|
||||
add_filter( 'locale', array( $this, 'get_locale' ) );
|
||||
|
||||
// Filter sticky posts by current language
|
||||
add_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) );
|
||||
|
||||
// Rewrites archives links to filter them by language
|
||||
add_filter( 'getarchives_join', array( $this, 'getarchives_join' ), 10, 2 );
|
||||
add_filter( 'getarchives_where', array( $this, 'getarchives_where' ), 10, 2 );
|
||||
|
||||
// Filters the widgets according to the current language
|
||||
add_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ) );
|
||||
|
||||
if ( $this->options['media_support'] ) {
|
||||
add_filter( 'widget_media_image_instance', array( $this, 'widget_media_instance' ), 1 ); // Since WP 4.8
|
||||
}
|
||||
|
||||
// Strings translation ( must be applied before WordPress applies its default formatting filters )
|
||||
foreach ( array( 'widget_text', 'widget_title' ) as $filter ) {
|
||||
add_filter( $filter, 'pll__', 1 );
|
||||
}
|
||||
|
||||
// Translates biography
|
||||
add_filter( 'get_user_metadata', array( $this, 'get_user_metadata' ), 10, 4 );
|
||||
|
||||
if ( Polylang::is_ajax_on_front() ) {
|
||||
add_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locale based on current language
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_locale() {
|
||||
return $this->curlang->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters sticky posts by current language.
|
||||
*
|
||||
* @since 0.8
|
||||
*
|
||||
* @param int[] $posts List of sticky posts ids.
|
||||
* @return int[] Modified list of sticky posts ids
|
||||
*/
|
||||
public function option_sticky_posts( $posts ) {
|
||||
global $wpdb;
|
||||
|
||||
// Do not filter sticky posts on REST requests as $this->curlang is *not* the 'lang' parameter set in the request
|
||||
if ( ! defined( 'REST_REQUEST' ) && ! empty( $this->curlang ) && ! empty( $posts ) ) {
|
||||
$_posts = wp_cache_get( 'sticky_posts', 'options' ); // This option is usually cached in 'all_options' by WP.
|
||||
$tt_id = $this->curlang->get_tax_prop( 'language', 'term_taxonomy_id' );
|
||||
|
||||
if ( empty( $_posts ) || ! is_array( $_posts ) || empty( $_posts[ $tt_id ] ) || ! is_array( $_posts[ $tt_id ] ) ) {
|
||||
$posts = array_map( 'intval', $posts );
|
||||
$posts = implode( ',', $posts );
|
||||
|
||||
$languages = array();
|
||||
foreach ( $this->model->get_languages_list() as $language ) {
|
||||
$languages[] = $language->get_tax_prop( 'language', 'term_taxonomy_id' );
|
||||
}
|
||||
|
||||
$_posts = array_fill_keys( $languages, array() ); // Init with empty arrays
|
||||
$languages = implode( ',', $languages );
|
||||
|
||||
// PHPCS:ignore WordPress.DB.PreparedSQL
|
||||
$relations = $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM {$wpdb->term_relationships} WHERE object_id IN ({$posts}) AND term_taxonomy_id IN ({$languages})" );
|
||||
|
||||
foreach ( $relations as $relation ) {
|
||||
$_posts[ $relation->term_taxonomy_id ][] = (int) $relation->object_id;
|
||||
}
|
||||
wp_cache_add( 'sticky_posts', $_posts, 'options' );
|
||||
}
|
||||
|
||||
$posts = $_posts[ $tt_id ];
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the sql request for wp_get_archives to filter by the current language
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param string $sql JOIN clause
|
||||
* @param array $r wp_get_archives arguments
|
||||
* @return string modified JOIN clause
|
||||
*/
|
||||
public function getarchives_join( $sql, $r ) {
|
||||
return ! empty( $r['post_type'] ) && $this->model->is_translated_post_type( $r['post_type'] ) ? $sql . $this->model->post->join_clause() : $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the sql request for wp_get_archives to filter by the current language
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param string $sql WHERE clause
|
||||
* @param array $r wp_get_archives arguments
|
||||
* @return string modified WHERE clause
|
||||
*/
|
||||
public function getarchives_where( $sql, $r ) {
|
||||
if ( ! $this->curlang instanceof PLL_Language ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty( $r['post_type'] ) || ! $this->model->is_translated_post_type( $r['post_type'] ) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
return $sql . $this->model->post->where_clause( $this->curlang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the widgets according to the current language
|
||||
* Don't display if a language filter is set and this is not the current one
|
||||
* Needed for {@see https://developer.wordpress.org/reference/functions/the_widget/ the_widget()}.
|
||||
*
|
||||
* @since 0.3
|
||||
*
|
||||
* @param array $instance Widget settings
|
||||
* @return bool|array false if we hide the widget, unmodified $instance otherwise
|
||||
*/
|
||||
public function widget_display_callback( $instance ) {
|
||||
return ! empty( $instance['pll_lang'] ) && $instance['pll_lang'] != $this->curlang->slug ? false : $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates media in media widgets
|
||||
*
|
||||
* @since 2.1.5
|
||||
*
|
||||
* @param array $instance Widget instance data
|
||||
* @return array
|
||||
*/
|
||||
public function widget_media_instance( $instance ) {
|
||||
if ( empty( $instance['pll_lang'] ) && $instance['attachment_id'] && $tr_id = pll_get_post( $instance['attachment_id'] ) ) {
|
||||
$instance['attachment_id'] = $tr_id;
|
||||
$attachment = get_post( $tr_id );
|
||||
|
||||
if ( $instance['caption'] && ! empty( $attachment->post_excerpt ) ) {
|
||||
$instance['caption'] = $attachment->post_excerpt;
|
||||
}
|
||||
|
||||
if ( $instance['alt'] && $alt_text = get_post_meta( $tr_id, '_wp_attachment_image_alt', true ) ) {
|
||||
$instance['alt'] = $alt_text;
|
||||
}
|
||||
|
||||
if ( $instance['image_title'] && ! empty( $attachment->post_title ) ) {
|
||||
$instance['image_title'] = $attachment->post_title;
|
||||
}
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the biography.
|
||||
*
|
||||
* @since 0.9
|
||||
*
|
||||
* @param null $null Expecting the default null value.
|
||||
* @param int $id The user id.
|
||||
* @param string $meta_key The metadata key.
|
||||
* @param bool $single Whether to return only the first value of the specified $meta_key.
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_user_metadata( $null, $id, $meta_key, $single ) {
|
||||
return 'description' === $meta_key && ! empty( $this->curlang ) && ! $this->curlang->is_default ? get_user_meta( $id, 'description_' . $this->curlang->slug, $single ) : $null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the translation files to load when doing ajax on front
|
||||
* This is needed because WP the language files associated to the user locale when a user is logged in
|
||||
*
|
||||
* @since 2.2.6
|
||||
*
|
||||
* @param string $mofile Translation file name
|
||||
* @return string
|
||||
*/
|
||||
public function load_textdomain_mofile( $mofile ) {
|
||||
$user_locale = get_user_locale();
|
||||
return str_replace( "{$user_locale}.mo", "{$this->curlang->locale}.mo", $mofile );
|
||||
}
|
||||
}
|
||||
228
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-links.php
vendored
Normal file
228
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-links.php
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages links filters and url of translations on frontend
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Frontend_Links extends PLL_Links {
|
||||
|
||||
/**
|
||||
* Internal non persistent cache object.
|
||||
*
|
||||
* @var PLL_Cache<string>
|
||||
*/
|
||||
public $cache;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->curlang = &$polylang->curlang;
|
||||
$this->cache = new PLL_Cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url of the translation (if it exists) of the current page.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param PLL_Language $language Language object.
|
||||
* @return string
|
||||
*/
|
||||
public function get_translation_url( $language ) {
|
||||
global $wp_query;
|
||||
|
||||
if ( false !== $translation_url = $this->cache->get( 'translation_url:' . $language->slug ) ) {
|
||||
return $translation_url;
|
||||
}
|
||||
|
||||
// Make sure that we have the queried object
|
||||
// See https://wordpress.org/support/topic/patch-for-fixing-a-notice
|
||||
$queried_object_id = $wp_query->get_queried_object_id();
|
||||
|
||||
/**
|
||||
* Filters the translation url before Polylang attempts to find one.
|
||||
* Internally used by Polylang for the static front page and posts page.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $url Empty string or the url of the translation of the current page.
|
||||
* @param PLL_Language $language Language of the translation.
|
||||
* @param int $queried_object_id Queried object ID.
|
||||
*/
|
||||
if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
|
||||
$qv = $wp_query->query_vars;
|
||||
|
||||
// Post and attachment
|
||||
if ( is_single() && ( $this->options['media_support'] || ! is_attachment() ) && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
|
||||
$url = get_permalink( $id );
|
||||
}
|
||||
|
||||
// Page
|
||||
elseif ( is_page() && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
|
||||
$url = get_page_link( $id );
|
||||
}
|
||||
|
||||
elseif ( is_search() ) {
|
||||
$url = $this->get_archive_url( $language );
|
||||
|
||||
// Special case for search filtered by translated taxonomies: taxonomy terms are translated in the translation url
|
||||
if ( ! empty( $wp_query->tax_query->queries ) ) {
|
||||
foreach ( $wp_query->tax_query->queries as $tax_query ) {
|
||||
if ( ! empty( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) ) {
|
||||
|
||||
$tax = get_taxonomy( $tax_query['taxonomy'] );
|
||||
$terms = get_terms( array( 'taxonomy' => $tax->name, 'fields' => 'id=>slug' ) ); // Filtered by current language
|
||||
|
||||
foreach ( $tax_query['terms'] as $slug ) {
|
||||
$term_id = array_search( $slug, $terms ); // What is the term_id corresponding to taxonomy term?
|
||||
if ( $term_id && $term_id = $this->model->term->get_translation( $term_id, $language ) ) { // Get the translated term_id
|
||||
$term = get_term( $term_id, $tax->name );
|
||||
|
||||
if ( ! $term instanceof WP_Term ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = str_replace( $slug, $term->slug, $url );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Translated taxonomy
|
||||
// Take care that is_tax() is false for categories and tags
|
||||
elseif ( ( is_category() || is_tag() || is_tax() ) && ( $term = get_queried_object() ) && $this->model->is_translated_taxonomy( $term->taxonomy ) ) {
|
||||
$lang = $this->model->term->get_language( $term->term_id );
|
||||
|
||||
if ( ! $lang || $language->slug == $lang->slug ) {
|
||||
$url = get_term_link( $term, $term->taxonomy ); // Self link
|
||||
}
|
||||
|
||||
elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
|
||||
$tr_term = get_term( $tr_id, $term->taxonomy );
|
||||
if ( $tr_term instanceof WP_Term ) {
|
||||
// Check if translated term ( or children ) have posts
|
||||
$count = $tr_term->count || ( is_taxonomy_hierarchical( $term->taxonomy ) && array_sum( wp_list_pluck( get_terms( array( 'taxonomy' => $term->taxonomy, 'child_of' => $tr_term->term_id, 'lang' => $language->slug ) ), 'count' ) ) );
|
||||
|
||||
/**
|
||||
* Filter whether to hide an archive translation url
|
||||
*
|
||||
* @since 2.2.4
|
||||
*
|
||||
* @param bool $hide True to hide the translation url.
|
||||
* defaults to true when the translated archive is empty, false otherwise.
|
||||
* @param string $lang The language code of the translation
|
||||
* @param array $args Arguments used to evaluated the number of posts in the archive
|
||||
*/
|
||||
if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, array( 'taxonomy' => $term->taxonomy ) ) ) {
|
||||
$url = get_term_link( $tr_term, $term->taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post type archive
|
||||
elseif ( is_post_type_archive() ) {
|
||||
if ( $this->model->is_translated_post_type( $qv['post_type'] ) ) {
|
||||
$args = array( 'post_type' => $qv['post_type'] );
|
||||
$count = $this->model->count_posts( $language, $args );
|
||||
|
||||
/** This filter is documented in frontend/frontend-links.php */
|
||||
if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, $args ) ) {
|
||||
$url = $this->get_archive_url( $language );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Other archives
|
||||
elseif ( is_archive() ) {
|
||||
$keys = array( 'post_type', 'm', 'year', 'monthnum', 'day', 'author', 'author_name' );
|
||||
$keys = array_merge( $keys, $this->model->get_filtered_taxonomies_query_vars() );
|
||||
$args = array_intersect_key( $qv, array_flip( $keys ) );
|
||||
$count = $this->model->count_posts( $language, $args );
|
||||
|
||||
/** This filter is documented in frontend/frontend-links.php */
|
||||
if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, $args ) ) {
|
||||
$url = $this->get_archive_url( $language );
|
||||
}
|
||||
}
|
||||
|
||||
// Front page when it is the list of posts
|
||||
elseif ( is_front_page() ) {
|
||||
$url = $this->get_home_url( $language );
|
||||
}
|
||||
}
|
||||
|
||||
$url = ! empty( $url ) && ! is_wp_error( $url ) ? $url : null;
|
||||
|
||||
/**
|
||||
* Filter the translation url of the current page before Polylang caches it
|
||||
*
|
||||
* @since 1.1.2
|
||||
*
|
||||
* @param null|string $url The translation url, null if none was found
|
||||
* @param string $language The language code of the translation
|
||||
*/
|
||||
$translation_url = (string) apply_filters( 'pll_translation_url', $url, $language->slug );
|
||||
|
||||
// Don't cache before template_redirect to avoid a conflict with Barrel + WP Bakery Page Builder
|
||||
if ( did_action( 'template_redirect' ) ) {
|
||||
$this->cache->set( 'translation_url:' . $language->slug, $translation_url );
|
||||
}
|
||||
|
||||
return $translation_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation of the current archive url
|
||||
* used also for search
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param PLL_Language $language An object representing a language.
|
||||
* @return string
|
||||
*/
|
||||
public function get_archive_url( $language ) {
|
||||
$url = pll_get_requested_url();
|
||||
$url = $this->links_model->switch_language_in_link( $url, $language );
|
||||
$url = $this->links_model->remove_paged_from_link( $url );
|
||||
|
||||
/**
|
||||
* Filter the archive url
|
||||
*
|
||||
* @since 1.6
|
||||
*
|
||||
* @param string $url Url of the archive
|
||||
* @param object $language Language of the archive
|
||||
*/
|
||||
return apply_filters( 'pll_get_archive_url', $url, $language );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the home url in the right language.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param PLL_Language|string $language Optional, defaults to current language.
|
||||
* @param bool $is_search Optional, whether we need the home url for a search form, defaults to false.
|
||||
*/
|
||||
public function get_home_url( $language = '', $is_search = false ) {
|
||||
if ( empty( $language ) ) {
|
||||
$language = $this->curlang;
|
||||
}
|
||||
|
||||
return parent::get_home_url( $language, $is_search );
|
||||
}
|
||||
}
|
||||
339
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-nav-menu.php
vendored
Normal file
339
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-nav-menu.php
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages custom menus translations as well as the language switcher menu item on frontend
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null|false
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->curlang = &$polylang->curlang;
|
||||
|
||||
// Split the language switcher menu item in several language menu items
|
||||
add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items' ), 20 ); // after the customizer menus
|
||||
add_filter( 'wp_nav_menu_objects', array( $this, 'wp_nav_menu_objects' ) );
|
||||
add_filter( 'nav_menu_link_attributes', array( $this, 'nav_menu_link_attributes' ), 10, 2 );
|
||||
|
||||
// Filters menus by language
|
||||
add_filter( 'theme_mod_nav_menu_locations', array( $this, 'nav_menu_locations' ), 20 );
|
||||
add_filter( 'wp_nav_menu_args', array( $this, 'wp_nav_menu_args' ) );
|
||||
|
||||
// The customizer
|
||||
if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
add_filter( 'wp_nav_menu_args', array( $this, 'filter_args_before_customizer' ) );
|
||||
add_filter( 'wp_nav_menu_args', array( $this, 'filter_args_after_customizer' ), 2000 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts menu items by menu order.
|
||||
*
|
||||
* @since 1.7.9
|
||||
*
|
||||
* @param stdClass $a The first object to compare.
|
||||
* @param stdClass $b The second object to compare.
|
||||
* @return int -1 or 1 if $a is considered to be respectively less than or greater than $b.
|
||||
*/
|
||||
protected function usort_menu_items( $a, $b ) {
|
||||
return ( $a->menu_order < $b->menu_order ) ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a language switcher menu item title based on options
|
||||
*
|
||||
* @since 2.2.6
|
||||
*
|
||||
* @param string $flag Formatted flag
|
||||
* @param string $name Language name
|
||||
* @param array $options Language switcher options
|
||||
* @return string Formatted menu item title
|
||||
*/
|
||||
protected function get_item_title( $flag, $name, $options ) {
|
||||
if ( $options['show_flags'] ) {
|
||||
if ( $options['show_names'] ) {
|
||||
$title = sprintf( '%1$s<span style="margin-%2$s:0.3em;">%3$s</span>', $flag, is_rtl() ? 'right' : 'left', esc_html( $name ) );
|
||||
} else {
|
||||
$title = $flag;
|
||||
}
|
||||
} else {
|
||||
$title = esc_html( $name );
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the one language switcher menu item of backend in several menu items on frontend.
|
||||
* Takes care to menu_order as it is used later in wp_nav_menu().
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param stdClass[] $items Menu items.
|
||||
* @return stdClass[] Modified menu items.
|
||||
*/
|
||||
public function wp_get_nav_menu_items( $items ) {
|
||||
if ( empty( $this->curlang ) ) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
if ( doing_action( 'customize_register' ) ) { // needed since WP 4.3, doing_action available since WP 3.9
|
||||
return $items;
|
||||
}
|
||||
|
||||
// The customizer menus does not sort the items and we need them to be sorted before splitting the language switcher
|
||||
usort( $items, array( $this, 'usort_menu_items' ) );
|
||||
|
||||
$new_items = array();
|
||||
|
||||
$offset = 0;
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) {
|
||||
/** This filter is documented in include/switcher.php */
|
||||
$options = apply_filters( 'pll_the_languages_args', $options ); // Honor the filter here for 'show_flags', 'show_names' and 'dropdown'.
|
||||
|
||||
$switcher = new PLL_Switcher();
|
||||
$args = array_merge( array( 'raw' => 1 ), $options );
|
||||
|
||||
/** @var array */
|
||||
$the_languages = $switcher->the_languages( PLL()->links, $args );
|
||||
|
||||
// parent item for dropdown
|
||||
if ( ! empty( $options['dropdown'] ) ) {
|
||||
$name = isset( $options['display_names_as'] ) && 'slug' === $options['display_names_as'] ? $this->curlang->slug : $this->curlang->name;
|
||||
$item->title = $this->get_item_title( $this->curlang->get_display_flag( empty( $options['show_names'] ) ? 'alt' : 'no-alt' ), $name, $options );
|
||||
$item->attr_title = '';
|
||||
$item->classes = array( 'pll-parent-menu-item' );
|
||||
$item->menu_order += $offset;
|
||||
$new_items[] = $item;
|
||||
++$offset;
|
||||
}
|
||||
|
||||
$i = 0; // for incrementation of menu order only in case of dropdown
|
||||
foreach ( $the_languages as $lang ) {
|
||||
++$i;
|
||||
$lang_item = clone $item;
|
||||
$lang_item->ID = $lang_item->ID . '-' . $lang['slug']; // A unique ID
|
||||
$lang_item->title = $this->get_item_title( $lang['flag'], $lang['name'], $options );
|
||||
$lang_item->attr_title = '';
|
||||
$lang_item->url = $lang['url'];
|
||||
$lang_item->lang = $lang['locale']; // Save this for use in nav_menu_link_attributes
|
||||
$lang_item->classes = $lang['classes'];
|
||||
if ( ! empty( $options['dropdown'] ) ) {
|
||||
$lang_item->menu_order = $item->menu_order + $i;
|
||||
$lang_item->menu_item_parent = $item->db_id;
|
||||
$lang_item->db_id = 0; // to avoid recursion
|
||||
} else {
|
||||
$lang_item->menu_order += $offset;
|
||||
}
|
||||
$new_items[] = $lang_item;
|
||||
++$offset;
|
||||
}
|
||||
--$offset;
|
||||
} else {
|
||||
$item->menu_order += $offset;
|
||||
$new_items[] = $item;
|
||||
}
|
||||
}
|
||||
return $new_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ancestors of a menu item.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param stdClass $item Menu item.
|
||||
* @return int[] Ancestors ids.
|
||||
*/
|
||||
public function get_ancestors( $item ) {
|
||||
$ids = array();
|
||||
$_anc_id = (int) $item->db_id;
|
||||
while ( ( $_anc_id = get_post_meta( $_anc_id, '_menu_item_menu_item_parent', true ) ) && ! in_array( $_anc_id, $ids ) ) {
|
||||
$ids[] = $_anc_id;
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes current-menu and current-menu-ancestor classes to lang switcher when not on the home page.
|
||||
*
|
||||
* @since 1.1.1
|
||||
*
|
||||
* @param stdClass[] $items An array of menu items.
|
||||
* @return stdClass[]
|
||||
*/
|
||||
public function wp_nav_menu_objects( $items ) {
|
||||
$r_ids = $k_ids = array();
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
if ( ! empty( $item->classes ) && is_array( $item->classes ) ) {
|
||||
if ( in_array( 'current-lang', $item->classes ) ) {
|
||||
$item->current = false;
|
||||
$item->classes = array_diff( $item->classes, array( 'current-menu-item' ) );
|
||||
$r_ids = array_merge( $r_ids, $this->get_ancestors( $item ) ); // Remove the classes for these ancestors
|
||||
} elseif ( in_array( 'current-menu-item', $item->classes ) ) {
|
||||
$k_ids = array_merge( $k_ids, $this->get_ancestors( $item ) ); // Keep the classes for these ancestors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$r_ids = array_diff( $r_ids, $k_ids );
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
if ( ! empty( $item->db_id ) && in_array( $item->db_id, $r_ids ) ) {
|
||||
$item->classes = array_diff( $item->classes, array( 'current-menu-ancestor', 'current-menu-parent', 'current_page_parent', 'current_page_ancestor' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds hreflang attribute for the language switcher menu items.
|
||||
* available since WP 3.6.
|
||||
*
|
||||
* @since 1.1
|
||||
*
|
||||
* @param string[] $atts HTML attributes applied to the menu item's `<a>` element.
|
||||
* @param stdClass $item Menu item.
|
||||
* @return string[] Modified attributes.
|
||||
*/
|
||||
public function nav_menu_link_attributes( $atts, $item ) {
|
||||
if ( isset( $item->lang ) ) {
|
||||
$atts['lang'] = $atts['hreflang'] = esc_attr( $item->lang );
|
||||
}
|
||||
return $atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the theme nav menus locations with the right menu in the right language
|
||||
* Needs to wait for the language to be defined
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param array|bool $menus list of nav menus locations, false if menu locations have not been filled yet
|
||||
* @return array|bool modified list of nav menus locations
|
||||
*/
|
||||
public function nav_menu_locations( $menus ) {
|
||||
if ( is_array( $menus ) && ! empty( $this->curlang ) ) {
|
||||
// First get multilingual menu locations from DB
|
||||
$theme = get_option( 'stylesheet' );
|
||||
|
||||
foreach ( array_keys( $menus ) as $loc ) {
|
||||
$menus[ $loc ] = empty( $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ] ) ? 0 : $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ];
|
||||
}
|
||||
|
||||
// Support for theme customizer
|
||||
if ( is_customize_preview() ) {
|
||||
global $wp_customize;
|
||||
foreach ( $wp_customize->unsanitized_post_values() as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'nav_menu_locations[' ) ) {
|
||||
$loc = substr( trim( $key, ']' ), 19 );
|
||||
$infos = $this->explode_location( $loc );
|
||||
if ( $infos['lang'] === $this->curlang->slug ) {
|
||||
$menus[ $infos['location'] ] = (int) $value;
|
||||
} elseif ( $this->curlang->is_default ) {
|
||||
$menus[ $loc ] = (int) $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $menus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to translate the nav menu when it is hardcoded or when no location is defined in wp_nav_menu().
|
||||
*
|
||||
* @since 1.7.10
|
||||
*
|
||||
* @param array $args Array of `wp_nav_menu()` arguments.
|
||||
* @return array
|
||||
*/
|
||||
public function wp_nav_menu_args( $args ) {
|
||||
$theme = get_option( 'stylesheet' );
|
||||
|
||||
if ( empty( $this->curlang ) || empty( $this->options['nav_menus'][ $theme ] ) ) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
// Get the nav menu based on the requested menu
|
||||
$menu = wp_get_nav_menu_object( $args['menu'] );
|
||||
|
||||
// Attempt to find a translation of this menu
|
||||
// This obviously does not work if the nav menu has no associated theme location
|
||||
if ( $menu ) {
|
||||
foreach ( $this->options['nav_menus'][ $theme ] as $menus ) {
|
||||
if ( in_array( $menu->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) {
|
||||
$args['menu'] = $menus[ $this->curlang->slug ];
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the first menu that has items and and is in the current language if we still can't find a menu
|
||||
if ( ! $menu && ! $args['theme_location'] ) {
|
||||
$menus = wp_get_nav_menus();
|
||||
foreach ( $menus as $menu_maybe ) {
|
||||
if ( wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
|
||||
foreach ( $this->options['nav_menus'][ $theme ] as $menus ) {
|
||||
if ( in_array( $menu_maybe->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) {
|
||||
$args['menu'] = $menus[ $this->curlang->slug ];
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the nav menu location before the customizer so that it matches the temporary location in the customizer
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param array $args wp_nav_menu $args
|
||||
* @return array modified $args
|
||||
*/
|
||||
public function filter_args_before_customizer( $args ) {
|
||||
if ( ! empty( $this->curlang ) ) {
|
||||
$args['theme_location'] = $this->combine_location( $args['theme_location'], $this->curlang );
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the nav menu location after the customizer to get back the true nav menu location for the theme
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param array $args wp_nav_menu $args
|
||||
* @return array modified $args
|
||||
*/
|
||||
public function filter_args_after_customizer( $args ) {
|
||||
$infos = $this->explode_location( $args['theme_location'] );
|
||||
$args['theme_location'] = $infos['location'];
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
318
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-static-pages.php
vendored
Normal file
318
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend-static-pages.php
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages the static front page and the page for posts on frontend
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
||||
/**
|
||||
* Instance of a child class of PLL_Links_Model.
|
||||
*
|
||||
* @var PLL_Links_Model
|
||||
*/
|
||||
protected $links_model;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Links|null
|
||||
*/
|
||||
protected $links;
|
||||
|
||||
/**
|
||||
* Stores plugin's options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Constructor: setups filters and actions.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param object $polylang The Polylang object.
|
||||
*/
|
||||
public function __construct( &$polylang ) {
|
||||
parent::__construct( $polylang );
|
||||
|
||||
$this->links_model = &$polylang->links_model;
|
||||
$this->links = &$polylang->links;
|
||||
$this->options = &$polylang->options;
|
||||
|
||||
add_action( 'pll_home_requested', array( $this, 'pll_home_requested' ) );
|
||||
|
||||
// Manages the redirection of the homepage.
|
||||
add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ) );
|
||||
|
||||
add_filter( 'pll_pre_translation_url', array( $this, 'pll_pre_translation_url' ), 10, 3 );
|
||||
add_filter( 'pll_check_canonical_url', array( $this, 'pll_check_canonical_url' ) );
|
||||
|
||||
add_filter( 'pll_set_language_from_query', array( $this, 'page_on_front_query' ), 10, 2 );
|
||||
add_filter( 'pll_set_language_from_query', array( $this, 'page_for_posts_query' ), 10, 2 );
|
||||
|
||||
// Specific cases for the customizer.
|
||||
add_action( 'customize_register', array( $this, 'filter_customizer' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the page_id query var when the site root page is requested
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function pll_home_requested() {
|
||||
set_query_var( 'page_id', $this->curlang->page_on_front );
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the canonical redirect of the homepage when using a page on front.
|
||||
*
|
||||
* @since 0.1
|
||||
*
|
||||
* @param string $redirect_url The redirect url.
|
||||
* @return string|false The modified url, false if the redirect is canceled.
|
||||
*/
|
||||
public function redirect_canonical( $redirect_url ) {
|
||||
if ( is_page() && ! is_feed() && get_queried_object_id() == $this->curlang->page_on_front ) {
|
||||
$url = is_paged() ? $this->links_model->add_paged_to_link( $this->links->get_home_url(), get_query_var( 'page' ) ) : $this->links->get_home_url();
|
||||
|
||||
// Don't forget additional query vars
|
||||
$query = wp_parse_url( $redirect_url, PHP_URL_QUERY );
|
||||
if ( ! empty( $query ) ) {
|
||||
parse_str( $query, $query_vars );
|
||||
$query_vars = rawurlencode_deep( $query_vars ); // WP encodes query vars values
|
||||
$url = add_query_arg( $query_vars, $url );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
return $redirect_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the url of the page on front and page for posts.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $url Empty string or the url of the translation of the current page.
|
||||
* @param PLL_Language $language Language of the translation.
|
||||
* @param int $queried_object_id Queried object ID.
|
||||
* @return string The translation url.
|
||||
*/
|
||||
public function pll_pre_translation_url( $url, $language, $queried_object_id ) {
|
||||
if ( empty( $queried_object_id ) ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Page for posts.
|
||||
if ( $GLOBALS['wp_query']->is_posts_page ) {
|
||||
$id = $this->model->post->get( $queried_object_id, $language );
|
||||
|
||||
if ( ! empty( $id ) ) {
|
||||
return (string) get_permalink( $id );
|
||||
}
|
||||
}
|
||||
|
||||
// Page on front.
|
||||
if ( is_front_page() && ! empty( $language->page_on_front ) ) {
|
||||
$id = $this->model->post->get( $queried_object_id, $language );
|
||||
|
||||
if ( $language->page_on_front === $id ) {
|
||||
return $language->get_home_url();
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the canonical redirect if we are on a static front page.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param string $redirect_url The redirect url.
|
||||
* @return string|false
|
||||
*/
|
||||
public function pll_check_canonical_url( $redirect_url ) {
|
||||
return $this->options['redirect_lang'] && ! $this->options['force_lang'] && ! empty( $this->curlang->page_on_front ) && is_page( $this->curlang->page_on_front ) ? false : $redirect_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the query for a the static front page (redirected from the language page)?
|
||||
*
|
||||
* @since 2.3
|
||||
*
|
||||
* @param WP_Query $query The WP_Query object.
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_front_page( $query ) {
|
||||
$query = array_diff( array_keys( $query->query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) );
|
||||
return 1 === count( $query ) && in_array( 'lang', $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups query vars when requesting a static front page
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param PLL_Language|false $lang The current language, false if it is not set yet.
|
||||
* @param WP_Query $query The main WP query.
|
||||
* @return PLL_Language|false
|
||||
*/
|
||||
public function page_on_front_query( $lang, $query ) {
|
||||
if ( ! empty( $lang ) || ! $this->page_on_front ) {
|
||||
return $lang;
|
||||
}
|
||||
|
||||
// Redirect the language page to the homepage when using a static front page
|
||||
if ( ( $this->options['redirect_lang'] || $this->options['hide_default'] ) && $this->is_front_page( $query ) && $lang = $this->model->get_language( get_query_var( 'lang' ) ) ) {
|
||||
$query->is_archive = $query->is_tax = false;
|
||||
if ( 'page' === get_option( 'show_on_front' ) && ! empty( $lang->page_on_front ) ) {
|
||||
$query->set( 'page_id', $lang->page_on_front );
|
||||
$query->is_singular = $query->is_page = true;
|
||||
unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object
|
||||
} else {
|
||||
// Handle case where the static front page hasn't be translated to avoid a possible infinite redirect loop.
|
||||
$query->is_home = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix paged static front page in plain permalinks when Settings > Reading doesn't match the default language
|
||||
elseif ( ! $this->links_model->using_permalinks && count( $query->query ) === 1 && ! empty( $query->query['page'] ) ) {
|
||||
$lang = $this->model->get_default_language();
|
||||
if ( empty( $lang ) ) {
|
||||
return $lang;
|
||||
}
|
||||
$query->set( 'page_id', $lang->page_on_front );
|
||||
$query->is_singular = $query->is_page = true;
|
||||
$query->is_archive = $query->is_tax = false;
|
||||
unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object
|
||||
}
|
||||
|
||||
// Set the language when requesting a static front page
|
||||
else {
|
||||
$page_id = $this->get_page_id( $query );
|
||||
$languages = $this->model->get_languages_list();
|
||||
$pages = wp_list_pluck( $languages, 'page_on_front' );
|
||||
|
||||
if ( ! empty( $page_id ) && false !== $n = array_search( $page_id, $pages ) ) {
|
||||
$lang = $languages[ $n ];
|
||||
}
|
||||
}
|
||||
|
||||
// Fix <!--nextpage--> for page_on_front
|
||||
if ( ( $this->options['force_lang'] < 2 || ! $this->options['redirect_lang'] ) && $this->links_model->using_permalinks && ! empty( $lang ) && isset( $query->query['paged'] ) ) {
|
||||
$query->set( 'page', $query->query['paged'] );
|
||||
unset( $query->query['paged'] );
|
||||
} elseif ( ! $this->links_model->using_permalinks && ! empty( $query->query['page'] ) ) {
|
||||
$query->is_paged = true;
|
||||
}
|
||||
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups query vars when requesting a posts page
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param PLL_Language|false $lang The current language, false if it is not set yet.
|
||||
* @param WP_Query $query The main WP query.
|
||||
* @return PLL_Language|false
|
||||
*/
|
||||
public function page_for_posts_query( $lang, $query ) {
|
||||
if ( ! empty( $lang ) || ! $this->page_for_posts ) {
|
||||
return $lang;
|
||||
}
|
||||
|
||||
$page_id = $this->get_page_id( $query );
|
||||
|
||||
if ( empty( $page_id ) ) {
|
||||
return $lang;
|
||||
}
|
||||
|
||||
$pages = $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) );
|
||||
$pages = array_filter( $pages );
|
||||
|
||||
if ( in_array( $page_id, $pages ) ) {
|
||||
_prime_post_caches( $pages ); // Fill the cache with all pages for posts to avoid one query per page later.
|
||||
|
||||
$lang = $this->model->post->get_language( $page_id );
|
||||
$query->is_singular = $query->is_page = false;
|
||||
$query->is_home = $query->is_posts_page = true;
|
||||
}
|
||||
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the queried page_id (if it exists ).
|
||||
*
|
||||
* If permalinks are used, WordPress does set and use `$query->queried_object_id` and sets `$query->query_vars['page_id']` to 0,
|
||||
* and does set and use `$query->query_vars['page_id']` if permalinks are not used :(.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param WP_Query $query Instance of WP_Query.
|
||||
* @return int The page_id.
|
||||
*/
|
||||
protected function get_page_id( $query ) {
|
||||
if ( ! empty( $query->query_vars['pagename'] ) && isset( $query->queried_object_id ) ) {
|
||||
return $query->queried_object_id;
|
||||
}
|
||||
|
||||
if ( isset( $query->query_vars['page_id'] ) ) {
|
||||
return $query->query_vars['page_id'];
|
||||
}
|
||||
|
||||
return 0; // No page queried.
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds support for the theme customizer.
|
||||
*
|
||||
* @since 3.4.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filter_customizer() {
|
||||
add_filter( 'pre_option_page_on_front', array( $this, 'customize_page' ), 20 ); // After the customizer.
|
||||
add_filter( 'pre_option_page_for_post', array( $this, 'customize_page' ), 20 );
|
||||
|
||||
add_filter( 'pll_pre_translation_url', array( $this, 'customize_translation_url' ), 20, 2 ); // After the generic hook in this class.
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the page ID when customized.
|
||||
*
|
||||
* @since 3.4.2
|
||||
*
|
||||
* @param int|false $pre A page ID if the setting is customized, false otherwise.
|
||||
* @return int|false
|
||||
*/
|
||||
public function customize_page( $pre ) {
|
||||
return is_numeric( $pre ) ? pll_get_post( (int) $pre ) : $pre;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes the translation URL if the option 'show_on_front' is customized.
|
||||
*
|
||||
* @since 3.4.2
|
||||
*
|
||||
* @param string $url An empty string or the URL of the translation of the current page.
|
||||
* @param PLL_Language $language The language of the translation.
|
||||
* @return string
|
||||
*/
|
||||
public function customize_translation_url( $url, $language ) {
|
||||
if ( 'posts' === get_option( 'show_on_front' ) && is_front_page() ) {
|
||||
// When the page on front displays posts, the home URL is the same as the search URL.
|
||||
return $language->get_search_url();
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
287
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend.php
vendored
Normal file
287
wp-content/plugins/polylang-pro/vendor/wpsyntex/polylang/frontend/frontend.php
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Polylang
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main Polylang class when on frontend, accessible from @see PLL().
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
class PLL_Frontend extends PLL_Base {
|
||||
/**
|
||||
* Current language.
|
||||
*
|
||||
* @var PLL_Language|null
|
||||
*/
|
||||
public $curlang;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Auto_Translate|null
|
||||
*/
|
||||
public $auto_translate;
|
||||
|
||||
/**
|
||||
* The class selecting the current language.
|
||||
*
|
||||
* @var PLL_Choose_Lang|null
|
||||
*/
|
||||
public $choose_lang;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Filters|null
|
||||
*/
|
||||
public $filters;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Filters_Links|null
|
||||
*/
|
||||
public $filters_links;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Filters_Search|null
|
||||
*/
|
||||
public $filters_search;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Links|null
|
||||
*/
|
||||
public $links;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Nav_Menu|null
|
||||
*/
|
||||
public $nav_menu;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Static_Pages|null
|
||||
*/
|
||||
public $static_pages;
|
||||
|
||||
/**
|
||||
* @var PLL_Frontend_Filters_Widgets|null
|
||||
*/
|
||||
public $filters_widgets;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param PLL_Links_Model $links_model Reference to the links model.
|
||||
*/
|
||||
public function __construct( &$links_model ) {
|
||||
parent::__construct( $links_model );
|
||||
|
||||
add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ), 1 );
|
||||
|
||||
// Avoids the language being the queried object when querying multiple taxonomies
|
||||
add_action( 'parse_tax_query', array( $this, 'parse_tax_query' ), 1 );
|
||||
|
||||
// Filters posts by language
|
||||
add_action( 'parse_query', array( $this, 'parse_query' ), 6 );
|
||||
|
||||
// Not before 'check_canonical_url'
|
||||
if ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) {
|
||||
add_action( 'template_redirect', array( $this, 'auto_translate' ), 7 );
|
||||
}
|
||||
|
||||
add_action( 'admin_bar_menu', array( $this, 'remove_customize_admin_bar' ), 41 ); // After WP_Admin_Bar::add_menus
|
||||
|
||||
/*
|
||||
* Static front page and page for posts.
|
||||
*
|
||||
* Early instantiated to be able to correctly initialize language properties.
|
||||
* Also loaded in customizer preview, directly reading the request as we act before WP.
|
||||
*/
|
||||
if ( 'page' === get_option( 'show_on_front' ) || ( isset( $_REQUEST['wp_customize'] ) && 'on' === $_REQUEST['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$this->static_pages = new PLL_Frontend_Static_Pages( $this );
|
||||
}
|
||||
|
||||
$this->model->set_languages_ready();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups the language chooser based on options
|
||||
*
|
||||
* @since 1.2
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
$this->links = new PLL_Frontend_Links( $this );
|
||||
|
||||
// Setup the language chooser
|
||||
$c = array( 'Content', 'Url', 'Url', 'Domain' );
|
||||
$class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ];
|
||||
$this->choose_lang = new $class( $this );
|
||||
$this->choose_lang->init();
|
||||
|
||||
// Need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content
|
||||
$this->nav_menu = new PLL_Frontend_Nav_Menu( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups filters and nav menus once the language has been defined
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function pll_language_defined() {
|
||||
// Filters
|
||||
$this->filters_links = new PLL_Frontend_Filters_Links( $this );
|
||||
$this->filters = new PLL_Frontend_Filters( $this );
|
||||
$this->filters_search = new PLL_Frontend_Filters_Search( $this );
|
||||
$this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
|
||||
|
||||
/*
|
||||
* Redirects to canonical url before WordPress redirect_canonical
|
||||
* but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!!
|
||||
* and restores it in 'template_redirect' with priority 1.
|
||||
*/
|
||||
$this->canonical = new PLL_Canonical( $this );
|
||||
add_action( 'template_redirect', array( $this->canonical, 'check_canonical_url' ), 4 );
|
||||
|
||||
// Auto translate for Ajax
|
||||
if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
|
||||
$this->auto_translate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When querying multiple taxonomies, makes sure that the language is not the queried object.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @param WP_Query $query WP_Query object.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_tax_query( $query ) {
|
||||
$pll_query = new PLL_Query( $query, $this->model );
|
||||
$queried_taxonomies = $pll_query->get_queried_taxonomies();
|
||||
|
||||
if ( ! empty( $queried_taxonomies ) && 'language' == reset( $queried_taxonomies ) ) {
|
||||
$query->tax_query->queried_terms['language'] = array_shift( $query->tax_query->queried_terms );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @param WP_Query $query WP_Query object.
|
||||
* @return void
|
||||
*/
|
||||
public function parse_query( $query ) {
|
||||
$qv = $query->query_vars;
|
||||
$pll_query = new PLL_Query( $query, $this->model );
|
||||
$taxonomies = $pll_query->get_queried_taxonomies();
|
||||
|
||||
// Allow filtering recent posts and secondary queries by the current language
|
||||
if ( ! empty( $this->curlang ) ) {
|
||||
$pll_query->filter_query( $this->curlang );
|
||||
}
|
||||
|
||||
// Modifies query vars when the language is queried
|
||||
if ( ! empty( $qv['lang'] ) || ( ! empty( $taxonomies ) && array( 'language' ) == array_values( $taxonomies ) ) ) {
|
||||
// Do we query a custom taxonomy?
|
||||
$taxonomies = array_diff( $taxonomies, array( 'language', 'category', 'post_tag' ) );
|
||||
|
||||
// Remove pages query when the language is set unless we do a search
|
||||
// Take care not to break the single page, attachment and taxonomies queries!
|
||||
if ( empty( $qv['post_type'] ) && ! $query->is_search && ! $query->is_singular && empty( $taxonomies ) && ! $query->is_category && ! $query->is_tag ) {
|
||||
$query->set( 'post_type', 'post' );
|
||||
}
|
||||
|
||||
// Unset the is_archive flag for language pages to prevent loading the archive template
|
||||
// Keep archive flag for comment feed otherwise the language filter does not work
|
||||
if ( empty( $taxonomies ) && ! $query->is_comment_feed && ! $query->is_post_type_archive && ! $query->is_date && ! $query->is_author && ! $query->is_category && ! $query->is_tag ) {
|
||||
$query->is_archive = false;
|
||||
}
|
||||
|
||||
// Unset the is_tax flag except if another custom tax is queried
|
||||
if ( empty( $taxonomies ) && ( $query->is_category || $query->is_tag || $query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search || $query->is_feed ) ) {
|
||||
$query->is_tax = false;
|
||||
unset( $query->queried_object ); // FIXME useless?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto translate posts and terms ids
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function auto_translate() {
|
||||
$this->auto_translate = new PLL_Frontend_Auto_Translate( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets some variables when the blog is switched.
|
||||
* Overrides the parent method.
|
||||
*
|
||||
* @since 1.5.1
|
||||
*
|
||||
* @param int $new_blog_id New blog ID.
|
||||
* @param int $prev_blog_id Previous blog ID.
|
||||
* @return void
|
||||
*/
|
||||
public function switch_blog( $new_blog_id, $prev_blog_id ) {
|
||||
if ( (int) $new_blog_id === (int) $prev_blog_id ) {
|
||||
// Do nothing if same blog.
|
||||
return;
|
||||
}
|
||||
|
||||
parent::switch_blog( $new_blog_id, $prev_blog_id );
|
||||
|
||||
// Need to check that some languages are defined when user is logged in, has several blogs, some without any languages.
|
||||
if ( ! $this->is_active_on_current_site() || ! $this->model->has_languages() || ! did_action( 'pll_language_defined' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
static $restore_curlang;
|
||||
|
||||
if ( empty( $restore_curlang ) ) {
|
||||
$restore_curlang = $this->curlang->slug; // To always remember the current language through blogs.
|
||||
}
|
||||
|
||||
$lang = $this->model->get_language( $restore_curlang );
|
||||
$this->curlang = $lang ? $lang : $this->model->get_default_language();
|
||||
if ( empty( $this->curlang ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $this->static_pages ) ) {
|
||||
$this->static_pages->init();
|
||||
}
|
||||
|
||||
// Send the slug instead of the locale here to avoid conflicts with same locales.
|
||||
$this->load_strings_translations( $this->curlang->slug );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the customize admin bar on front-end when using a block theme.
|
||||
*
|
||||
* WordPress removes the Customizer menu if a block theme is activated and no other plugins interact with it.
|
||||
* As Polylang interacts with the Customizer, we have to delete this menu ourselves in the case of a block theme,
|
||||
* unless another plugin than Polylang interacts with the Customizer.
|
||||
*
|
||||
* @since 3.2
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function remove_customize_admin_bar() {
|
||||
if ( ! $this->should_customize_menu_be_removed() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wp_admin_bar;
|
||||
|
||||
remove_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); // To avoid the script launch.
|
||||
$wp_admin_bar->remove_menu( 'customize' );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user