first commit
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
class WPML_Frontend_Redirection_Url {
|
||||
|
||||
/** @var string $url */
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*/
|
||||
public function __construct( $url ) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL is being checked for apostrophes. If there are any, apostrophes are encoded.
|
||||
*
|
||||
* @return string URL with the encoded apostrophes.
|
||||
*/
|
||||
public function encode_apostrophes_in_url() {
|
||||
return str_replace( "'", rawurlencode( "'" ), $this->url );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
use WPML\Language\Detection\Frontend;
|
||||
|
||||
class WPML_Frontend_Redirection extends WPML_SP_User {
|
||||
|
||||
/** @var Frontend $request_handler */
|
||||
private $request_handler;
|
||||
|
||||
/** @var WPML_Redirection */
|
||||
private $redirect_helper;
|
||||
|
||||
/** @var WPML_Language_Resolution $lang_resolution */
|
||||
private $lang_resolution;
|
||||
|
||||
/**
|
||||
* WPML_Frontend_Redirection constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param Frontend $request_handler
|
||||
* @param WPML_Redirection $redir_helper
|
||||
* @param WPML_Language_Resolution $lang_resolution
|
||||
*/
|
||||
public function __construct(
|
||||
&$sitepress,
|
||||
&$request_handler,
|
||||
&$redir_helper,
|
||||
&$lang_resolution
|
||||
) {
|
||||
parent::__construct( $sitepress );
|
||||
$this->request_handler = &$request_handler;
|
||||
$this->redirect_helper = &$redir_helper;
|
||||
$this->lang_resolution = &$lang_resolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to a URL corrected for the language information in it, in case request URI and $_REQUEST['lang'],
|
||||
* requested domain or $_SERVER['REQUEST_URI'] do not match and gives precedence to the explicit language parameter if
|
||||
* there.
|
||||
*
|
||||
* @return string The language code of the currently requested URL in case no redirection was necessary.
|
||||
*/
|
||||
public function maybe_redirect() {
|
||||
$target = $this->redirect_helper->get_redirect_target();
|
||||
if ( false !== $target ) {
|
||||
$frontend_redirection_url = new WPML_Frontend_Redirection_Url( $target );
|
||||
$target = $frontend_redirection_url->encode_apostrophes_in_url();
|
||||
$this->sitepress->get_wp_api()->wp_safe_redirect( $target );
|
||||
};
|
||||
|
||||
// allow forcing the current language when it can't be decoded from the URL.
|
||||
return $this->lang_resolution->current_lang_filter( $this->request_handler->get_requested_lang(), $this->request_handler );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use WPML\Language\Detection\Frontend;
|
||||
|
||||
/*
|
||||
* @deprecated deprecated since version 4.4.0
|
||||
* This class has been replaced by WPML\Language\Detection\Frontend and is going to be removed in the next major release.
|
||||
*
|
||||
*
|
||||
* @package wpml-core
|
||||
* @subpackage wpml-requests
|
||||
*
|
||||
*/
|
||||
class WPML_Frontend_Request extends WPML_Request {
|
||||
/** @var \WPML\Language\Detection\Frontend */
|
||||
private $frontend;
|
||||
|
||||
public function __construct( $url_converter, $active_languages, $default_language, $cookieLanguage, $wp_api ) {
|
||||
parent::__construct( $url_converter, $active_languages, $default_language, $cookieLanguage );
|
||||
$this->frontend = new Frontend(
|
||||
$url_converter,
|
||||
$active_languages,
|
||||
$default_language,
|
||||
$cookieLanguage,
|
||||
$wp_api
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated deprecated since version 4.4.0
|
||||
* @return false|string
|
||||
*/
|
||||
public function get_requested_lang() {
|
||||
return $this->frontend->get_requested_lang();
|
||||
}
|
||||
|
||||
protected function get_cookie_name() {
|
||||
return $this->cookieLanguage->getFrontendCookieName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
class WPML_Language_Domain_Validation {
|
||||
const VALIDATE_DOMAIN_KEY = '____icl_validate_domain';
|
||||
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
/** @var WP_Http $http */
|
||||
private $http;
|
||||
/** @var string $url */
|
||||
private $url;
|
||||
/** @var string $validation_url */
|
||||
private $validation_url;
|
||||
|
||||
/**
|
||||
* @param WPML_WP_API $wp_api
|
||||
* @param WP_Http $http
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
||||
public function __construct( WPML_WP_API $wp_api, WP_Http $http) {
|
||||
$this->wp_api = $wp_api;
|
||||
$this->http = $http;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid( $url ) {
|
||||
$this->url = $url;
|
||||
$this->validation_url = $this->get_validation_url();
|
||||
if ( ! $this->has_scheme_and_host() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_multisite() && defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$response = $this->get_validation_response();
|
||||
|
||||
if ( $this->is_valid_response( $response ) ) {
|
||||
return in_array( $response['body'], $this->get_accepted_responses( $this->validation_url ), true );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function has_scheme_and_host() {
|
||||
$url_parts = wpml_parse_url( $this->url );
|
||||
return array_key_exists( 'scheme', $url_parts ) && array_key_exists( 'host', $url_parts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_validation_url() {
|
||||
return add_query_arg( array( self::VALIDATE_DOMAIN_KEY => 1 ), trailingslashit( $this->url ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_accepted_responses( $url ) {
|
||||
$accepted_responses = array(
|
||||
'<!--' . untrailingslashit( $this->wp_api->get_home_url() ) . '-->',
|
||||
'<!--' . untrailingslashit( $this->wp_api->get_site_url() ) . '-->',
|
||||
);
|
||||
if ( defined( 'SUNRISE' ) && SUNRISE === 'on' ) {
|
||||
$accepted_responses[] = '<!--' . str_replace( '?' . self::VALIDATE_DOMAIN_KEY . '=1', '', $url ) . '-->';
|
||||
return $accepted_responses;
|
||||
}
|
||||
return $accepted_responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
private function get_validation_response() {
|
||||
return $this->http->request( $this->validation_url, 'timeout=15' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|WP_Error $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_response( $response ) {
|
||||
return ! is_wp_error( $response ) && '200' === (string) $response['response']['code'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_Language_Per_Domain_SSO
|
||||
*/
|
||||
class WPML_Language_Per_Domain_SSO {
|
||||
|
||||
const SSO_NONCE = 'wpml_sso';
|
||||
|
||||
const TRANSIENT_SSO_STARTED = 'wpml_sso_started';
|
||||
const TRANSIENT_DOMAIN = 'wpml_sso_domain_';
|
||||
const TRANSIENT_USER = 'wpml_sso_user_';
|
||||
const TRANSIENT_SESSION_TOKEN = 'wpml_sso_session_';
|
||||
|
||||
const IFRAME_USER_TOKEN_KEY = 'wpml_sso_token';
|
||||
const IFRAME_USER_TOKEN_KEY_FOR_DOMAIN = 'wpml_sso_token_domain';
|
||||
const IFRAME_DOMAIN_HASH_KEY = 'wpml_sso_iframe_hash';
|
||||
const IFRAME_USER_STATUS_KEY = 'wpml_sso_user_status';
|
||||
|
||||
const SSO_TIMEOUT = MINUTE_IN_SECONDS;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var WPML_PHP_Functions $php_functions */
|
||||
private $php_functions;
|
||||
|
||||
/** @var WPML_Cookie */
|
||||
private $wpml_cookie;
|
||||
|
||||
/** @var string */
|
||||
private $site_url;
|
||||
|
||||
/** @var array */
|
||||
private $domains;
|
||||
|
||||
/** @var int $current_user_id */
|
||||
private $current_user_id;
|
||||
|
||||
public function __construct( SitePress $sitepress, WPML_PHP_Functions $php_functions, WPML_Cookie $wpml_cookie ) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->php_functions = $php_functions;
|
||||
$this->wpml_cookie = $wpml_cookie;
|
||||
$this->site_url = $this->sitepress->convert_url( get_home_url(), $this->sitepress->get_default_language() );
|
||||
$this->domains = $this->get_domains();
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
|
||||
if ( $this->is_sso_started() ) {
|
||||
add_action( 'init', [ $this, 'init_action' ] );
|
||||
|
||||
add_action( 'wp_footer', [ $this, 'add_iframes_to_footer' ] );
|
||||
add_action( 'admin_footer', [ $this, 'add_iframes_to_footer' ] );
|
||||
add_action( 'login_footer', [ $this, 'add_iframes_to_footer' ] );
|
||||
}
|
||||
|
||||
add_action( 'wp_login', [ $this, 'wp_login_action' ], 10, 2 );
|
||||
add_filter( 'logout_redirect', [ $this, 'add_redirect_user_token' ], 10, 3 );
|
||||
}
|
||||
|
||||
public function init_action() {
|
||||
$this->send_headers();
|
||||
$this->set_current_user_id();
|
||||
if ( $this->is_iframe_request() ) {
|
||||
$this->process_iframe_request();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user_login
|
||||
* @param WP_User $user
|
||||
*/
|
||||
public function wp_login_action( $user_login, WP_User $user ) {
|
||||
$this->init_sso_transients( (int) $user->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $redirect_to
|
||||
* @param string $requested_redirect_to
|
||||
* @param WP_User|WP_Error $user
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function add_redirect_user_token( $redirect_to, $requested_redirect_to, $user ) {
|
||||
if ( ! is_wp_error( $user ) && ! $this->is_sso_started() ) {
|
||||
$this->init_sso_transients( (int) $user->ID );
|
||||
|
||||
return add_query_arg( self::IFRAME_USER_TOKEN_KEY, $this->create_user_token( $user->ID ), $redirect_to );
|
||||
}
|
||||
|
||||
return $redirect_to;
|
||||
}
|
||||
|
||||
public function add_iframes_to_footer() {
|
||||
$is_user_logged_in = is_user_logged_in();
|
||||
|
||||
if ( $is_user_logged_in && $this->is_sso_started() ) {
|
||||
$this->save_session_token( wp_get_session_token(), $this->current_user_id );
|
||||
}
|
||||
|
||||
foreach ( $this->domains as $domain ) {
|
||||
if ( $domain !== $this->get_current_domain() && $this->is_sso_started_for_domain( $domain ) ) {
|
||||
|
||||
$iframe_url = add_query_arg(
|
||||
[
|
||||
self::IFRAME_DOMAIN_HASH_KEY => $this->get_hash( $domain ),
|
||||
self::IFRAME_USER_STATUS_KEY => $is_user_logged_in ? 'wpml_user_signed_in' : 'wpml_user_signed_out',
|
||||
self::IFRAME_USER_TOKEN_KEY_FOR_DOMAIN => $this->create_user_token_for_domains( $this->current_user_id ),
|
||||
],
|
||||
trailingslashit( $domain )
|
||||
);
|
||||
?>
|
||||
<iframe class="wpml_iframe" style="display:none" src="<?php echo esc_url( $iframe_url ); ?>"></iframe>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function send_headers() {
|
||||
header( sprintf( 'Content-Security-Policy: frame-ancestors %s', implode( ' ', $this->domains ) ) );
|
||||
}
|
||||
|
||||
/** @param int $user_id */
|
||||
private function set_current_user_id( $user_id = null ) {
|
||||
if ( $user_id ) {
|
||||
$this->current_user_id = $user_id;
|
||||
} else {
|
||||
$this->current_user_id = $this->get_user_id_from_token() ?: get_current_user_id();
|
||||
}
|
||||
}
|
||||
|
||||
private function process_iframe_request() {
|
||||
if ( $this->validate_user_sign_request() ) {
|
||||
nocache_headers();
|
||||
wp_clear_auth_cookie();
|
||||
|
||||
if ( $_GET[ self::IFRAME_USER_STATUS_KEY ] == 'wpml_user_signed_in' ) {
|
||||
$user = get_user_by( 'id', $this->current_user_id );
|
||||
|
||||
if ( $user !== false ) {
|
||||
wp_set_current_user( $this->current_user_id );
|
||||
|
||||
if ( is_ssl() ) {
|
||||
$this->set_auth_cookie(
|
||||
$this->current_user_id,
|
||||
$this->get_session_token( $this->current_user_id )
|
||||
);
|
||||
} else {
|
||||
wp_set_auth_cookie(
|
||||
$this->current_user_id,
|
||||
false,
|
||||
'',
|
||||
$this->get_session_token( $this->current_user_id )
|
||||
);
|
||||
}
|
||||
do_action( 'wp_login', $user->user_login, $user );
|
||||
}
|
||||
} else {
|
||||
$sessions = WP_Session_Tokens::get_instance( $this->current_user_id );
|
||||
$sessions->destroy_all();
|
||||
}
|
||||
$this->finish_sso_for_domain( $this->get_current_domain() );
|
||||
}
|
||||
|
||||
$this->php_functions->exit_php();
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
private function validate_user_sign_request() {
|
||||
return isset( $_GET[ self::IFRAME_USER_STATUS_KEY ] )
|
||||
&& $this->is_sso_started_for_domain( $this->get_current_domain() );
|
||||
}
|
||||
|
||||
/** @return int */
|
||||
private function get_user_id_from_token() {
|
||||
$user_id = 0;
|
||||
|
||||
if ( isset( $_GET[ self::IFRAME_USER_TOKEN_KEY ] ) ) {
|
||||
$transient_key = $this->create_transient_key(
|
||||
self::TRANSIENT_USER,
|
||||
null,
|
||||
Sanitize::stringProp( self::IFRAME_USER_TOKEN_KEY, $_GET )
|
||||
);
|
||||
$user_id = (int) get_transient( $transient_key );
|
||||
delete_transient( $transient_key );
|
||||
} elseif ( isset( $_GET[ self::IFRAME_USER_TOKEN_KEY_FOR_DOMAIN ] ) ) {
|
||||
$transient_key = $this->create_transient_key(
|
||||
self::TRANSIENT_USER,
|
||||
$this->get_current_domain(),
|
||||
Sanitize::stringProp( self::IFRAME_USER_TOKEN_KEY_FOR_DOMAIN, $_GET )
|
||||
);
|
||||
$user_id = (int) get_transient( $transient_key );
|
||||
delete_transient( $transient_key );
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*/
|
||||
private function init_sso_transients( $user_id ) {
|
||||
set_transient( self::TRANSIENT_SSO_STARTED, true, self::SSO_TIMEOUT );
|
||||
|
||||
foreach ( $this->domains as $domain ) {
|
||||
if ( $this->get_current_domain() !== $domain ) {
|
||||
set_transient(
|
||||
$this->create_transient_key( self::TRANSIENT_DOMAIN, $domain, $user_id ),
|
||||
$this->get_hash( $domain ),
|
||||
self::SSO_TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
*/
|
||||
private function finish_sso_for_domain( $domain ) {
|
||||
delete_transient(
|
||||
$this->create_transient_key(
|
||||
self::TRANSIENT_DOMAIN,
|
||||
$domain,
|
||||
$this->current_user_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $domain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_sso_started_for_domain( $domain ) {
|
||||
return (bool) get_transient(
|
||||
$this->create_transient_key(
|
||||
self::TRANSIENT_DOMAIN,
|
||||
$domain,
|
||||
$this->current_user_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_current_domain() {
|
||||
$host = '';
|
||||
|
||||
if ( array_key_exists( 'HTTP_HOST', $_SERVER ) ) {
|
||||
$host = (string) $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
|
||||
return $this->get_current_protocol() . $host;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_current_protocol() {
|
||||
return is_ssl() ? 'https://' : 'http://';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_domains() {
|
||||
$domains = $this->sitepress->get_setting( 'language_domains', array() );
|
||||
|
||||
$active_codes = array_keys( $this->sitepress->get_active_languages() );
|
||||
$sso_domains = array( $this->site_url );
|
||||
|
||||
foreach ( $domains as $language_code => $domain ) {
|
||||
if ( in_array( $language_code, $active_codes ) ) {
|
||||
$sso_domains[] = $this->get_current_protocol() . $domain;
|
||||
}
|
||||
}
|
||||
|
||||
return $sso_domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_iframe_request() {
|
||||
return isset( $_GET[ self::IFRAME_DOMAIN_HASH_KEY ] )
|
||||
&& ! wpml_is_ajax()
|
||||
&& $this->is_sso_started_for_domain( $this->get_current_domain() )
|
||||
&& $this->get_hash( $this->get_current_domain() ) === $_GET[ self::IFRAME_DOMAIN_HASH_KEY ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_sso_started() {
|
||||
return (bool) get_transient( self::TRANSIENT_SSO_STARTED );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function create_user_token( $user_id ) {
|
||||
$token = wp_create_nonce( self::SSO_NONCE );
|
||||
set_transient(
|
||||
$this->create_transient_key( self::TRANSIENT_USER, null, $token ),
|
||||
$user_id,
|
||||
self::SSO_TIMEOUT
|
||||
);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function create_user_token_for_domains( $user_id ) {
|
||||
$token = wp_create_nonce( self::SSO_NONCE );
|
||||
foreach ( $this->domains as $domain ) {
|
||||
if ( $this->get_current_domain() !== $domain ) {
|
||||
set_transient(
|
||||
$this->create_transient_key( self::TRANSIENT_USER, $domain, $token ),
|
||||
$user_id,
|
||||
self::SSO_TIMEOUT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $session_token
|
||||
* @param int $user_id
|
||||
*/
|
||||
private function save_session_token( $session_token, $user_id ) {
|
||||
set_transient(
|
||||
$this->create_transient_key( self::TRANSIENT_SESSION_TOKEN, null, $user_id ),
|
||||
$session_token,
|
||||
self::SSO_TIMEOUT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_session_token( $user_id ) {
|
||||
return (string) get_transient( $this->create_transient_key( self::TRANSIENT_SESSION_TOKEN, null, $user_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix
|
||||
* @param string|null $domain
|
||||
* @param string|null $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function create_transient_key( $prefix, $domain = null, $token = null ) {
|
||||
return $prefix . ( $token !== null ? $token : '' ) . ( $domain ? '_' . $this->get_hash( $domain ) : '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_hash( $value ) {
|
||||
return hash( 'sha256', self::SSO_NONCE . $value );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* As the WP doesn't support "SameSite" parameter in cookies, we have to write our own
|
||||
* function for saving authentication cookies to work with iframes.
|
||||
*
|
||||
* @param int $user_id
|
||||
* @param string $token
|
||||
*/
|
||||
private function set_auth_cookie( $user_id, $token = '' ) {
|
||||
$expiration = time() + apply_filters( 'auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user_id, false );
|
||||
$expire = 0;
|
||||
$secure = apply_filters( 'secure_auth_cookie', is_ssl(), $user_id );
|
||||
|
||||
if ( $secure ) {
|
||||
$auth_cookie_name = SECURE_AUTH_COOKIE;
|
||||
$scheme = 'secure_auth';
|
||||
} else {
|
||||
$auth_cookie_name = AUTH_COOKIE;
|
||||
$scheme = 'auth';
|
||||
}
|
||||
|
||||
if ( '' === $token ) {
|
||||
$manager = WP_Session_Tokens::get_instance( $user_id );
|
||||
$token = $manager->create( $expiration );
|
||||
}
|
||||
|
||||
$auth_cookie = wp_generate_auth_cookie( $user_id, $expiration, $scheme, $token );
|
||||
$logged_in_cookie = wp_generate_auth_cookie( $user_id, $expiration, 'logged_in', $token );
|
||||
|
||||
do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme, $token );
|
||||
do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in', $token );
|
||||
|
||||
if ( ! apply_filters( 'send_auth_cookies', true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->wpml_cookie->set_cookie( $auth_cookie_name, $auth_cookie, $expire, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN, true, 'None' );
|
||||
$this->wpml_cookie->set_cookie( $auth_cookie_name, $auth_cookie, $expire, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, true, 'None' );
|
||||
$this->wpml_cookie->set_cookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, COOKIEPATH, COOKIE_DOMAIN, true, 'None' );
|
||||
|
||||
if ( COOKIEPATH != SITECOOKIEPATH ) {
|
||||
$this->wpml_cookie->set_cookie( LOGGED_IN_COOKIE, $logged_in_cookie, $expire, SITECOOKIEPATH, COOKIE_DOMAIN, true, 'None' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Language_Resolution
|
||||
*
|
||||
* @package wpml-core
|
||||
* @subpackage wpml-requests
|
||||
*/
|
||||
class WPML_Language_Resolution {
|
||||
|
||||
private $active_language_codes = array();
|
||||
private $current_request_lang = null;
|
||||
private $default_lang = null;
|
||||
/**
|
||||
* @var array|null $hidden_lang_codes if set to null,
|
||||
* indicates that the cache needs to be reloaded due to changing settings
|
||||
* or current user within the request
|
||||
*/
|
||||
private $hidden_lang_codes = null;
|
||||
|
||||
/**
|
||||
* WPML_Language_Resolution constructor.
|
||||
*
|
||||
* @param string[] $active_language_codes
|
||||
* @param string $default_lang
|
||||
*/
|
||||
public function __construct( $active_language_codes, $default_lang ) {
|
||||
add_action( 'wpml_cache_clear', array( $this, 'reload' ), 11, 0 );
|
||||
$this->active_language_codes = array_fill_keys(
|
||||
$active_language_codes,
|
||||
1
|
||||
);
|
||||
$this->default_lang = $default_lang;
|
||||
$this->hidden_lang_codes = array_fill_keys(
|
||||
wpml_get_setting_filter(
|
||||
array(),
|
||||
'hidden_languages'
|
||||
),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
public function reload() {
|
||||
$this->active_language_codes = array();
|
||||
$this->hidden_lang_codes = null;
|
||||
$this->default_lang = null;
|
||||
$this->maybe_reload();
|
||||
}
|
||||
|
||||
public function current_lang_filter( $lang, WPML_Request $wpml_request_handler ) {
|
||||
if ( $this->current_request_lang !== $lang ) {
|
||||
$preview_lang = apply_filters( 'wpml_should_filter_preview_lang', true )
|
||||
? $this->filter_preview_language_code()
|
||||
: null;
|
||||
|
||||
if ( $preview_lang ) {
|
||||
$lang = $preview_lang;
|
||||
} elseif ( $this->use_cookie_language() ) {
|
||||
$lang = $wpml_request_handler->get_cookie_lang();
|
||||
}
|
||||
}
|
||||
$this->current_request_lang = $this->filter_for_legal_langs( $lang );
|
||||
|
||||
return $this->current_request_lang;
|
||||
}
|
||||
|
||||
public function get_active_language_codes() {
|
||||
$this->maybe_reload();
|
||||
|
||||
return array_keys( $this->active_language_codes );
|
||||
}
|
||||
|
||||
public function is_language_hidden( $lang_code ) {
|
||||
$this->maybe_reload();
|
||||
|
||||
return isset( $this->hidden_lang_codes[ $lang_code ] );
|
||||
}
|
||||
|
||||
public function is_language_active( $lang_code, $is_all_active = false ) {
|
||||
global $wpml_request_handler;
|
||||
$this->maybe_reload();
|
||||
|
||||
return ( $is_all_active === true && $lang_code === 'all' )
|
||||
|| isset( $this->active_language_codes[ $lang_code ] )
|
||||
|| ( $wpml_request_handler->show_hidden() && $this->is_language_hidden( $lang_code ) );
|
||||
}
|
||||
|
||||
private function maybe_reload() {
|
||||
$this->default_lang = $this->default_lang
|
||||
? $this->default_lang : wpml_get_setting_filter( false, 'default_language' );
|
||||
$this->active_language_codes = (bool) $this->active_language_codes === true
|
||||
? $this->active_language_codes : array_fill_keys( wpml_reload_active_languages_setting( true ), 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language_code of the http referrer's location from which a request originated.
|
||||
* Used to correctly determine the language code on ajax link lists for the post edit screen or
|
||||
* the flat taxonomy auto-suggest.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_referrer_language_code() {
|
||||
if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
|
||||
$query_string = wpml_parse_url( $_SERVER['HTTP_REFERER'], PHP_URL_QUERY );
|
||||
$query = array();
|
||||
parse_str( (string) $query_string, $query );
|
||||
$language_code = isset( $query['lang'] ) ? $query['lang'] : null;
|
||||
}
|
||||
|
||||
return isset( $language_code ) ? $language_code : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sets the language of frontend requests to false, if they are not for
|
||||
* a hidden or active language code. The handling of permissions in case of
|
||||
* hidden languages is done in \SitePress::init.
|
||||
*
|
||||
* @param string $lang
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function filter_for_legal_langs( $lang ) {
|
||||
|
||||
$this->maybe_reload();
|
||||
|
||||
$is_wp_cli_request = defined( 'WP_CLI' ) && WP_CLI;
|
||||
if ( $lang === 'all' && ( is_admin() || $is_wp_cli_request ) ) {
|
||||
return 'all';
|
||||
}
|
||||
|
||||
if ( ! isset( $this->hidden_lang_codes[ $lang ] ) && ! isset( $this->active_language_codes[ $lang ] ) ) {
|
||||
$lang = $this->default_lang ? $this->default_lang : icl_get_setting( 'default_language' );
|
||||
}
|
||||
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function use_cookie_language() {
|
||||
|
||||
return ( isset( $_GET['action'] ) && $_GET['action'] === 'ajax-tag-search' )
|
||||
|| ( isset( $_POST['action'] ) && in_array(
|
||||
$_POST['action'],
|
||||
array( 'get-tagcloud', 'wp-link-ajax' ),
|
||||
true
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the output of the filtering for the current language in case
|
||||
* the request is for a preview page.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function filter_preview_language_code() {
|
||||
$preview_id = filter_var(
|
||||
isset( $_GET['preview_id'] ) ? $_GET['preview_id'] : '',
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
);
|
||||
$preview_flag = filter_input( INPUT_GET, 'preview' ) || $preview_id;
|
||||
$preview_id = $preview_id ? $preview_id : filter_input( INPUT_GET, 'p' );
|
||||
$preview_id = $preview_id ? $preview_id : filter_input( INPUT_GET, 'page_id' );
|
||||
$lang = null;
|
||||
|
||||
if ( $preview_flag && $preview_id ) {
|
||||
global $wpml_post_translations;
|
||||
$lang = $wpml_post_translations->get_element_lang_code( $preview_id );
|
||||
}
|
||||
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
class WPML_REST_Request_Analyze_Factory {
|
||||
|
||||
/**
|
||||
* @return WPML_REST_Request_Analyze
|
||||
*/
|
||||
public static function create() {
|
||||
/**
|
||||
* @var \WPML_URL_Converter $wpml_url_converter
|
||||
* @var \WPML_Language_Resolution $wpml_language_resolution
|
||||
*/
|
||||
global $wpml_url_converter, $wpml_language_resolution;
|
||||
|
||||
return new WPML_REST_Request_Analyze(
|
||||
$wpml_url_converter,
|
||||
$wpml_language_resolution->get_active_language_codes(),
|
||||
new WP_Rewrite()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
class WPML_REST_Request_Analyze {
|
||||
|
||||
/** @var WPML_URL_Converter $url_converter */
|
||||
private $url_converter;
|
||||
|
||||
/** @var array $active_language_codes */
|
||||
private $active_language_codes;
|
||||
|
||||
/** @var WP_Rewrite $wp_rewrite */
|
||||
private $wp_rewrite;
|
||||
|
||||
/** @var array $uri_parts */
|
||||
private $uri_parts;
|
||||
|
||||
public function __construct(
|
||||
WPML_URL_Converter $url_converter,
|
||||
array $active_language_codes,
|
||||
WP_Rewrite $wp_rewrite
|
||||
) {
|
||||
$this->url_converter = $url_converter;
|
||||
$this->active_language_codes = $active_language_codes;
|
||||
$this->wp_rewrite = $wp_rewrite;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_rest_request() {
|
||||
if ( array_key_exists( 'rest_route', $_REQUEST ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$rest_url_prefix = 'wp-json';
|
||||
|
||||
if ( function_exists( 'rest_get_url_prefix' ) ) {
|
||||
$rest_url_prefix = rest_get_url_prefix();
|
||||
}
|
||||
|
||||
$uri_part = $this->get_uri_part( $this->has_valid_language_prefix() ? 1 : 0 );
|
||||
|
||||
return $uri_part === $rest_url_prefix;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
private function has_valid_language_prefix() {
|
||||
if ( $this->url_converter->get_strategy() instanceof WPML_URL_Converter_Subdir_Strategy ) {
|
||||
$maybe_lang = $this->get_uri_part();
|
||||
return in_array( $maybe_lang, $this->active_language_codes, true );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_uri_part( $index = 0 ) {
|
||||
if ( null === $this->uri_parts ) {
|
||||
$request_uri = filter_var( $_SERVER['REQUEST_URI'], FILTER_SANITIZE_URL );
|
||||
$cleaned_uri = ltrim( wpml_strip_subdir_from_url( $request_uri ), '/' );
|
||||
|
||||
if ( $this->wp_rewrite->using_index_permalinks() ) {
|
||||
$cleaned_uri = preg_replace( '/^' . $this->wp_rewrite->index . '\//', '', $cleaned_uri, 1 );
|
||||
}
|
||||
|
||||
$this->uri_parts = explode( '/', $cleaned_uri );
|
||||
}
|
||||
|
||||
return isset( $this->uri_parts[ $index ] ) ? $this->uri_parts[ $index ] : '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class WPML_Super_Globals_Validation {
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param int $filter
|
||||
* @param mixed $options
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get( $key, $filter = FILTER_SANITIZE_FULL_SPECIAL_CHARS, $options = null ) {
|
||||
return $this->get_value( $key, $_GET, $filter, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param int $filter
|
||||
* @param mixed $options
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function post( $key, $filter = FILTER_SANITIZE_FULL_SPECIAL_CHARS, $options = null ) {
|
||||
return $this->get_value( $key, $_POST, $filter, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $var
|
||||
* @param int $filter
|
||||
* @param mixed $options
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function get_value( $key, array $var, $filter = FILTER_SANITIZE_FULL_SPECIAL_CHARS, $options = null ) {
|
||||
$value = null;
|
||||
|
||||
if ( array_key_exists( $key, $var ) ) {
|
||||
if ( is_array( $var[ $key ] ) ) {
|
||||
$value = filter_var_array( $var[ $key ], $filter );
|
||||
} elseif ( null !== $options ) {
|
||||
$value = filter_var( $var[ $key ], $filter, $options );
|
||||
} else {
|
||||
$value = filter_var( $var[ $key ], $filter );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @return WPML_Redirection
|
||||
*/
|
||||
function _wpml_get_redirect_helper() {
|
||||
global $wpml_url_converter, $wpml_request_handler, $wpml_language_resolution, $sitepress;
|
||||
|
||||
$lang_neg_type = wpml_get_setting_filter( false, 'language_negotiation_type' );
|
||||
switch ( $lang_neg_type ) {
|
||||
case 1:
|
||||
global $wpml_url_filters;
|
||||
if ( $wpml_url_filters->frontend_uses_root() !== false ) {
|
||||
$redirect_helper = new WPML_Rootpage_Redirect_By_Subdir(
|
||||
wpml_get_setting_filter( array(), 'urls' ),
|
||||
$wpml_request_handler,
|
||||
$wpml_url_converter,
|
||||
$wpml_language_resolution
|
||||
);
|
||||
} else {
|
||||
$redirect_helper = new WPML_Redirect_By_Subdir(
|
||||
$wpml_url_converter,
|
||||
$wpml_request_handler,
|
||||
$wpml_language_resolution
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$wp_api = new WPML_WP_API();
|
||||
$redirect_helper = new WPML_Redirect_By_Domain(
|
||||
icl_get_setting( 'language_domains' ),
|
||||
$wp_api,
|
||||
$wpml_request_handler,
|
||||
$wpml_url_converter,
|
||||
$wpml_language_resolution
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
$redirect_helper = new WPML_Redirect_By_Param(
|
||||
icl_get_setting( 'taxonomies_sync_option', array() ),
|
||||
$wpml_url_converter,
|
||||
$wpml_request_handler,
|
||||
$wpml_language_resolution,
|
||||
$sitepress
|
||||
);
|
||||
$redirect_helper->init_hooks();
|
||||
}
|
||||
|
||||
return $redirect_helper;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
class WPML_Redirect_By_Domain extends WPML_Redirection {
|
||||
|
||||
/** @var array $domains */
|
||||
private $domains;
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
|
||||
/**
|
||||
* @param array $domains
|
||||
* @param WPML_WP_API $wp_api
|
||||
* @param WPML_URL_Converter $url_converter
|
||||
* @param WPML_Request $request_handler
|
||||
* @param WPML_Language_Resolution $lang_resolution
|
||||
*/
|
||||
public function __construct( $domains, &$wp_api, &$request_handler, &$url_converter, &$lang_resolution ) {
|
||||
parent::__construct( $url_converter, $request_handler, $lang_resolution );
|
||||
$this->domains = $domains;
|
||||
$this->wp_api = &$wp_api;
|
||||
}
|
||||
|
||||
public function get_redirect_target( $language = false ) {
|
||||
if ( $this->wp_api->is_admin() && $this->lang_resolution->is_language_hidden( $language )
|
||||
&& strpos( $_SERVER['REQUEST_URI'], 'wp-login.php' ) === false
|
||||
&& ! $this->wp_api->user_can( wp_get_current_user(), 'manage_options' )
|
||||
) {
|
||||
$target = trailingslashit( $this->domains[ $language ] ) . 'wp-login.php';
|
||||
} else {
|
||||
$target = $this->redirect_hidden_home();
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
class WPML_Redirect_By_Param extends WPML_Redirection {
|
||||
|
||||
private $post_like_params = array(
|
||||
'p' => 1,
|
||||
'page_id' => 1,
|
||||
);
|
||||
private $term_like_params = array(
|
||||
'cat_ID' => 1,
|
||||
'cat' => 1,
|
||||
'tag' => 1,
|
||||
);
|
||||
|
||||
/** @var SitePress */
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* @param array $tax_sync_option
|
||||
* @param WPML_URL_Converter $url_converter
|
||||
* @param WPML_Request $request_handler
|
||||
* @param WPML_Language_Resolution $lang_resolution
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( $tax_sync_option, &$url_converter, &$request_handler, &$lang_resolution, &$sitepress ) {
|
||||
parent::__construct( $url_converter, $request_handler, $lang_resolution );
|
||||
global $wp_rewrite;
|
||||
|
||||
$this->sitepress = &$sitepress;
|
||||
|
||||
if ( ! isset( $wp_rewrite ) ) {
|
||||
require_once ABSPATH . WPINC . '/rewrite.php';
|
||||
$wp_rewrite = new WP_Rewrite();
|
||||
}
|
||||
|
||||
$this->term_like_params = array_merge( $this->term_like_params, array_filter( $tax_sync_option ) );
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'template_redirect', array( $this, 'template_redirect_action' ), 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|string
|
||||
*/
|
||||
public function get_redirect_target() {
|
||||
$target = $this->redirect_hidden_home();
|
||||
if ( (bool) $target === false ) {
|
||||
$target = ( $new_qs = $this->get_target_link_querystring() ) !== false
|
||||
? ( $new_qs !== '' ? '/?' . $new_qs : '/' ) : false;
|
||||
$qs_parts = explode( '?', $this->request_handler->get_request_uri() );
|
||||
$path = array_shift( $qs_parts );
|
||||
$target = $target !== false ? rtrim( $path, '/' ) . $target : false;
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
private function find_potential_translation( $query_params, $lang_code ) {
|
||||
if ( count( $translatable_params = array_intersect_key( $query_params, $this->post_like_params ) ) === 1 ) {
|
||||
/** @var WPML_Post_Translation $wpml_post_translations */
|
||||
global $wpml_post_translations;
|
||||
$potential_translation = $wpml_post_translations->element_id_in(
|
||||
$query_params[ ( $parameter = key( $translatable_params ) ) ],
|
||||
$lang_code
|
||||
);
|
||||
} elseif ( count( $translatable_params = array_intersect_key( $query_params, $this->term_like_params ) ) === 1 ) {
|
||||
/** @var WPML_Term_Translation $wpml_term_translations */
|
||||
global $wpml_term_translations;
|
||||
$potential_translation = $wpml_term_translations->term_id_in(
|
||||
$query_params[ ( $parameter = key( $translatable_params ) ) ],
|
||||
$lang_code
|
||||
);
|
||||
}
|
||||
/** @var String $parameter */
|
||||
return isset( $potential_translation, $parameter ) ? array( $parameter, $potential_translation ) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query_params_string
|
||||
* @param string $lang_code
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function needs_redirect( $query_params_string, $lang_code ) {
|
||||
global $sitepress;
|
||||
|
||||
$element_lang = false;
|
||||
parse_str( $query_params_string, $query_params );
|
||||
if ( isset( $query_params['lang'] ) ) {
|
||||
if ( $sitepress->get_default_language() === $query_params['lang'] ) {
|
||||
unset( $query_params['lang'] );
|
||||
$changed = true;
|
||||
}
|
||||
} else {
|
||||
$element_lang = $this->get_element_language( $query_params_string );
|
||||
if ( $element_lang && $element_lang !== $sitepress->get_default_language() ) {
|
||||
$query_params['lang'] = $element_lang;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( $potential_translation = $this->find_potential_translation( $query_params, $lang_code ) ) !== false
|
||||
&& (int) $query_params[ $potential_translation[0] ] !== (int) $potential_translation[1]
|
||||
&& ! $element_lang
|
||||
) {
|
||||
$query_params[ $potential_translation[0] ] = $potential_translation[1];
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
return isset( $changed ) ? $query_params : false;
|
||||
}
|
||||
|
||||
private function get_target_link_querystring() {
|
||||
$raw_query_string = $this->request_handler->get_request_uri();
|
||||
$qs_parts = explode( '?', $raw_query_string );
|
||||
$query_string = array_pop( $qs_parts );
|
||||
|
||||
$query_params_new = $this->needs_redirect(
|
||||
$query_string,
|
||||
$this->url_converter->get_language_from_url( $raw_query_string )
|
||||
);
|
||||
|
||||
return $query_params_new !== false ? rawurldecode( http_build_query( $query_params_new ) ) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query_params_string
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_element_language( $query_params_string ) {
|
||||
$language = '';
|
||||
list( $element_id, $element_type ) = $this->get_element_details( $query_params_string );
|
||||
|
||||
if ( $element_id && $element_type ) {
|
||||
$language = $this->sitepress->get_language_for_element( $element_id, $element_type );
|
||||
}
|
||||
|
||||
return $language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_element_details( $url ) {
|
||||
$element_id = '';
|
||||
$element_type = '';
|
||||
parse_str( $url, $query_args );
|
||||
|
||||
if ( isset( $query_args['p'] ) ) {
|
||||
$element_id = $query_args['p'];
|
||||
$element_type = 'post_' . get_post_type( $element_id );
|
||||
} elseif ( isset( $query_args['cat'] ) ) {
|
||||
$element_id = $query_args['cat'];
|
||||
$term = get_term( $element_id );
|
||||
$element_type = 'tax_' . $term->taxonomy;
|
||||
}
|
||||
|
||||
return array( $element_id, $element_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://onthegosystems.myjetbrains.com/youtrack/issue/wpmlcore-2822
|
||||
*/
|
||||
public function template_redirect_action() {
|
||||
if ( $this->sitepress->get_wp_api()->is_front_page()
|
||||
&& $this->sitepress->get_wp_api()->get_query_var( 'page' )
|
||||
&& $this->sitepress->get_default_language() !== $this->sitepress->get_current_language()
|
||||
) {
|
||||
remove_action( 'template_redirect', 'redirect_canonical' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class WPML_Redirect_By_Subdir extends WPML_Redirection {
|
||||
|
||||
/**
|
||||
* @return bool|string
|
||||
*/
|
||||
public function get_redirect_target() {
|
||||
|
||||
return $this->redirect_hidden_home();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
abstract class WPML_Redirection extends WPML_URL_Converter_User {
|
||||
|
||||
/** @var WPML_Request $request_handler */
|
||||
protected $request_handler;
|
||||
|
||||
/** @var WPML_Language_Resolution $lang_resolution */
|
||||
protected $lang_resolution;
|
||||
|
||||
/**
|
||||
* @param WPML_URL_Converter $url_converter
|
||||
* @param WPML_Request $request_handler
|
||||
* @param WPML_Language_Resolution $lang_resolution
|
||||
*/
|
||||
function __construct( &$url_converter, &$request_handler, &$lang_resolution ) {
|
||||
parent::__construct( $url_converter );
|
||||
$this->request_handler = $request_handler;
|
||||
$this->lang_resolution = $lang_resolution;
|
||||
}
|
||||
|
||||
abstract public function get_redirect_target();
|
||||
|
||||
protected function redirect_hidden_home() {
|
||||
$target = false;
|
||||
if ( $this->lang_resolution->is_language_hidden( $this->request_handler->get_request_uri_lang() )
|
||||
&& ! $this->request_handler->show_hidden()
|
||||
) {
|
||||
$target = $this->url_converter->get_abs_home();
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
class WPML_Rootpage_Redirect_By_Subdir extends WPML_Redirect_By_Subdir {
|
||||
|
||||
/** @var array $urls */
|
||||
private $urls;
|
||||
|
||||
/**
|
||||
* @param array $urls
|
||||
* @param WPML_Request $request_handler
|
||||
* @param WPML_URL_Converter $url_converter
|
||||
* @param WPML_Language_Resolution $lang_resolution
|
||||
*/
|
||||
public function __construct( $urls, &$request_handler, &$url_converter, &$lang_resolution ) {
|
||||
parent::__construct( $url_converter, $request_handler, $lang_resolution );
|
||||
$this->urls = $urls;
|
||||
}
|
||||
|
||||
public function get_redirect_target() {
|
||||
global $wpml_url_filters;
|
||||
|
||||
$request_uri = $this->request_handler->get_request_uri();
|
||||
|
||||
$target = parent::get_redirect_target();
|
||||
$target = $target
|
||||
? $target
|
||||
: ( ( $filtered_root_url = $wpml_url_filters->filter_root_permalink(
|
||||
wpml_strip_subdir_from_url( site_url() ) . $request_uri
|
||||
) ) !== wpml_strip_subdir_from_url( site_url() ) . $request_uri ? $filtered_root_url : false );
|
||||
|
||||
if ( $target === false ) {
|
||||
$this->maybe_setup_rootpage();
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
private function maybe_setup_rootpage() {
|
||||
if ( WPML_Root_Page::is_current_request_root() ) {
|
||||
if ( WPML_Root_Page::uses_html_root() ) {
|
||||
$html_file = ( false === strpos( $this->urls['root_html_file_path'], '/' ) ? ABSPATH : '' )
|
||||
. $this->urls['root_html_file_path'];
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include $html_file;
|
||||
exit;
|
||||
} else {
|
||||
$root_page_actions = wpml_get_root_page_actions_obj();
|
||||
$root_page_actions->wpml_home_url_setup_root_page();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use WPML\Language\Detection\Backend;
|
||||
|
||||
/**
|
||||
* @deprecated This class has been replaced by WPML\Language\Detection\Backend and is going to be removed in the next major release.
|
||||
* @since 4.4.0
|
||||
* @see WPML\Language\Detection\Backend
|
||||
*
|
||||
* @package wpml-core
|
||||
* @subpackage wpml-requests
|
||||
*/
|
||||
class WPML_Backend_Request extends WPML_Request {
|
||||
/** @var Backend */
|
||||
private $backend;
|
||||
|
||||
public function __construct( $url_converter, $active_languages, $default_language, $cookieLanguage ) {
|
||||
parent::__construct( $url_converter, $active_languages, $default_language, $cookieLanguage );
|
||||
$this->backend = new Backend(
|
||||
$url_converter,
|
||||
$active_languages,
|
||||
$default_language,
|
||||
$cookieLanguage
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public function get_requested_lang() {
|
||||
return $this->backend->get_requested_lang();
|
||||
}
|
||||
|
||||
protected function get_cookie_name() {
|
||||
return $this->cookieLanguage->getBackendCookieName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Request
|
||||
*
|
||||
* @package wpml-core
|
||||
* @subpackage wpml-requests
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
use WPML\Language\Detection\CookieLanguage;
|
||||
|
||||
abstract class WPML_Request {
|
||||
|
||||
/** @var WPML_URL_Converter */
|
||||
protected $url_converter;
|
||||
protected $active_languages;
|
||||
protected $default_language;
|
||||
|
||||
/** @var CookieLanguage */
|
||||
protected $cookieLanguage;
|
||||
|
||||
/**
|
||||
* @param WPML_URL_Converter $url_converter
|
||||
* @param array $active_languages
|
||||
* @param string $default_language
|
||||
* @param CookieLanguage $cookieLanguage
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_URL_Converter $url_converter,
|
||||
$active_languages,
|
||||
$default_language,
|
||||
CookieLanguage $cookieLanguage
|
||||
) {
|
||||
$this->url_converter = $url_converter;
|
||||
$this->active_languages = $active_languages;
|
||||
$this->default_language = $default_language;
|
||||
$this->cookieLanguage = $cookieLanguage;
|
||||
}
|
||||
|
||||
abstract protected function get_cookie_name();
|
||||
|
||||
/**
|
||||
* Determines the language of the current request.
|
||||
*
|
||||
* @return string|false language code of the current request, determined from the requested url and the user's
|
||||
* cookie.
|
||||
*/
|
||||
abstract public function get_requested_lang();
|
||||
|
||||
/**
|
||||
* Returns the current REQUEST_URI optionally filtered
|
||||
*
|
||||
* @param null|int $filter filter to apply to the REQUEST_URI, takes the same arguments
|
||||
* as filter_var for the filter type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_request_uri( $filter = null ) {
|
||||
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '/';
|
||||
if ( $filter !== null ) {
|
||||
$request_uri = filter_var( $request_uri, $filter );
|
||||
}
|
||||
|
||||
return $request_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @global $wpml_url_converter
|
||||
*
|
||||
* @return string|false language code that can be determined from the currently requested URI.
|
||||
*/
|
||||
public function get_request_uri_lang() {
|
||||
$req_url = isset( $_SERVER['HTTP_HOST'] )
|
||||
? untrailingslashit( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) : '';
|
||||
|
||||
return $this->url_converter->get_language_from_url( $req_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string language code stored in the user's wp-wpml_current_language cookie
|
||||
*/
|
||||
public function get_cookie_lang() {
|
||||
return $this->cookieLanguage->get( $this->get_cookie_name() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether hidden languages are to be displayed at the moment.
|
||||
* They are displayed in the frontend if the users has the respective option icl_show_hidden_languages set in his
|
||||
* user_meta. The are displayed in the backend for all admins with manage_option capabilities.
|
||||
*
|
||||
* @return bool true if hidden languages are to be shown
|
||||
*/
|
||||
public function show_hidden() {
|
||||
|
||||
return ! did_action( 'init' )
|
||||
|| ( get_user_meta( get_current_user_id(), 'icl_show_hidden_languages', true )
|
||||
|| ( ( is_admin() || wpml_is_rest_request() ) && current_user_can( 'manage_options' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language code of the current screen in the User's wp-wpml_current_language cookie
|
||||
*
|
||||
* When user is not logged we must set cookie with JS to avoid issues with cached pages
|
||||
*
|
||||
* @param string $lang_code
|
||||
*/
|
||||
public function set_language_cookie( $lang_code ) {
|
||||
$this->cookieLanguage->set( $this->get_cookie_name(), $lang_code );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user