PluginProbe
Translate and boost SEO – Automatic AI translation – wpLingua / 2.16.8
Translate and boost SEO – Automatic AI translation – wpLingua v2.16.8
2.16.8 2.16.7 2.16.6 2.16.5 2.16.4 2.16.3 2.16.2 2.16.1 2.16.0 2.15.2 2.15.1 2.15.0 2.14.3 2.14.2 2.14.1 2.14.0 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 trunk 1.0.3 1.0.4 1.0.5 All 113 releases
← All changes | inc/browser-language.php +195 -195 2.16.62.16.8 View file →
@@ -1,195 +1,195 @@
1 -<?php
2 -
3 -// If this file is called directly, abort.
4 -if ( ! defined( 'WPINC' ) ) {
5 - die;
6 -}
7 -
8 -
9 -/**
10 - * Outputs a JavaScript snippet to handle browser language-based redirection.
11 - *
12 - * This function is designed to inject a JavaScript script into the front-end
13 - * for redirecting users based on their browser's language settings. It ensures
14 - * that the script is only output under specific conditions:
15 - * - The user is not logged in with editing permissions.
16 - * - The user is not a bot.
17 - * - The current page is the front page.
18 - * - The current language matches the website's default language.
19 - *
20 - * If the JavaScript file is missing or empty, the function exits early.
21 - *
22 - * @return void
23 - */
24 -function wplng_browser_language_redirect_js_only() {
25 -
26 - if ( current_user_can( 'edit_posts' )
27 - || wplng_is_bot()
28 - || ! is_front_page()
29 - || ( wplng_get_language_website_id() !== wplng_get_language_current_id() )
30 - ) {
31 - return;
32 - }
33 -
34 - $script = file_get_contents( WPLNG_PLUGIN_DIR . '/assets/js/browser-redirect.js' );
35 -
36 - if ( empty( $script ) ) {
37 - return;
38 - }
39 -
40 - $script = str_replace(
41 - array( '[wplng-cookie-path]', '//# sourceMappingURL=browser-redirect.js.map' ),
42 - array( COOKIEPATH, '' ),
43 - $script
44 - );
45 -
46 - echo '<script id="wplingue-browser-redirect-js">' . rtrim( $script ) . '</script>';
47 -}
48 -
49 -
50 -/**
51 - * Redirects the user to the translated version of the page based on browser language or a user-defined cookie.
52 - *
53 - * This function is designed to run on the 'template_redirect' hook. It handles the logic for
54 - * redirecting users to the appropriate language version of a page. The redirection is based on
55 - * a stored cookie (if available) or the browser's 'Accept-Language' header.
56 - *
57 - * It prevents redirection for specific user types (e.g., logged-in users with 'edit_posts' capability)
58 - * and for known web crawlers and bots.
59 - *
60 - * @return void
61 - */
62 -function wplng_browser_language_redirect_php_js() {
63 -
64 - // Exit early for users with editing permissions or for bots to prevent redirection loops.
65 - if ( current_user_can( 'edit_posts' )
66 - || wplng_is_bot()
67 - ) {
68 - return;
69 - }
70 -
71 - $language_website_id = wplng_get_language_website_id();
72 - $language_current_id = wplng_get_language_current_id();
73 - $is_translated_page = $language_website_id !== $language_current_id;
74 - $cookie = wplng_browser_language_cookie_get();
75 -
76 - // If the user is on a translated page.
77 - if ( $is_translated_page ) {
78 - // Update the cookie with the selected language code.
79 - // This is a voluntary choice by the user.
80 - wplng_browser_language_cookie_set( $language_current_id );
81 - return;
82 - }
83 -
84 - // The user is on the original language page (no language prefix).
85 -
86 - // Determine the language to redirect to.
87 - $redirect_language_id = false;
88 -
89 - if ( $cookie !== false ) {
90 - // If the cookie contains a valid language code, use it for redirection.
91 - // This honors the user's last choice.
92 - if ( wplng_is_valid_language_id( $cookie ) ) {
93 -
94 - if ( $cookie === $language_website_id ) {
95 - return;
96 - } else {
97 - $redirect_language_id = $cookie;
98 - }
99 - }
100 - } else {
101 - // This is the very first visit (no cookie). Use the browser's language.
102 - if ( ! empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
103 - $langs = explode( ',', sanitize_text_field( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) );
104 - if ( ! empty( $langs ) ) {
105 - $language_browser_id = strtolower( substr( trim( $langs[0] ), 0, 2 ) );
106 - $redirect_language_id = $language_browser_id;
107 - }
108 - }
109 - }
110 -
111 - // Check if the determined language is a valid target language.
112 - if ( empty( $redirect_language_id )
113 - || ( $redirect_language_id === $language_website_id )
114 - || ! in_array( $redirect_language_id, wplng_get_languages_target_ids(), true )
115 - ) {
116 - // If not, set the cookie to 'original' to prevent future redirects on the original page.
117 - wplng_browser_language_cookie_set( $language_website_id );
118 - return;
119 - }
120 -
121 - // Check if the URL to redirect is translatable.
122 - $url_to_redirect = wplng_get_url_current_for_language( $redirect_language_id );
123 -
124 - if ( $url_to_redirect === wplng_get_url_original() ) {
125 - wplng_browser_language_cookie_set( $language_website_id );
126 - return;
127 - }
128 -
129 - // Perform the redirection.
130 - wplng_browser_language_cookie_set( $redirect_language_id );
131 - wp_safe_redirect(
132 - $url_to_redirect,
133 - 302
134 - );
135 - exit;
136 -}
137 -
138 -
139 -/**
140 - * Retrieves the language code from the 'wplingua-lang' cookie.
141 - *
142 - * This function safely retrieves the language code stored in the user's cookie,
143 - * sanitizing the value to prevent security issues. It returns the language code
144 - * if it's valid ('original' or a known language ID), otherwise it returns false.
145 - *
146 - * @return string|false The language code from the cookie, or false if the cookie is not set or invalid.
147 - */
148 -function wplng_browser_language_cookie_get() {
149 - $cookie = false;
150 - if ( ! empty( $_COOKIE['wplingua-lang'] ) ) {
151 - $cookie = sanitize_text_field( $_COOKIE['wplingua-lang'] );
152 - if ( ! wplng_is_valid_language_id( $cookie ) ) {
153 - $cookie = false;
154 - }
155 - }
156 -
157 - return $cookie;
158 -}
159 -
160 -
161 -/**
162 - * Sets the 'wplingua-lang' cookie with a specified language ID.
163 - *
164 - * This function creates or updates a cookie to store the user's preferred language choice.
165 - * The cookie is set to expire in 30 days and is accessible across the site's domain.
166 - *
167 - * @param string $language_id The language code to be stored (e.g., 'en', 'fr', 'es', or 'original').
168 - * @return void
169 - */
170 -function wplng_browser_language_cookie_set( $language_id ) {
171 - setcookie(
172 - 'wplingua-lang',
173 - $language_id,
174 - time() + 30 * DAY_IN_SECONDS,
175 - COOKIEPATH,
176 - COOKIE_DOMAIN
177 - );
178 -}
179 -
180 -
181 -/**
182 - * Determines if the current user agent is a bot or a web crawler.
183 - *
184 - * This function checks the user agent string against a predefined list of known bots
185 - * using a regular expression. The result is cached for the duration of the request
186 - * to improve performance on multiple calls.
187 - *
188 - * @return bool True if the user agent is a bot, false otherwise.
189 - */
190 -function wplng_is_bot() {
191 - return (bool) preg_match(
192 - '/googlebot|bingbot|slurp|duckduckbot|baiduspider|yandex|semrushbot|ahrefsbot|mj12bot|dotbot|exabot|facebookexternalhit/i',
193 - strtolower( $_SERVER['HTTP_USER_AGENT'] ?? '' )
194 - );
195 -}
1 +<?php
2 +
3 +// If this file is called directly, abort.
4 +if ( ! defined( 'WPINC' ) ) {
5 + die;
6 +}
7 +
8 +
9 +/**
10 + * Outputs a JavaScript snippet to handle browser language-based redirection.
11 + *
12 + * This function is designed to inject a JavaScript script into the front-end
13 + * for redirecting users based on their browser's language settings. It ensures
14 + * that the script is only output under specific conditions:
15 + * - The user is not logged in with editing permissions.
16 + * - The user is not a bot.
17 + * - The current page is the front page.
18 + * - The current language matches the website's default language.
19 + *
20 + * If the JavaScript file is missing or empty, the function exits early.
21 + *
22 + * @return void
23 + */
24 +function wplng_browser_language_redirect_js_only() {
25 +
26 + if ( current_user_can( 'edit_posts' )
27 + || wplng_is_bot()
28 + || ! is_front_page()
29 + || ( wplng_get_language_website_id() !== wplng_get_language_current_id() )
30 + ) {
31 + return;
32 + }
33 +
34 + $script = file_get_contents( WPLNG_PLUGIN_DIR . '/assets/js/browser-redirect.js' );
35 +
36 + if ( empty( $script ) ) {
37 + return;
38 + }
39 +
40 + $script = str_replace(
41 + array( '[wplng-cookie-path]', '//# sourceMappingURL=browser-redirect.js.map' ),
42 + array( COOKIEPATH, '' ),
43 + $script
44 + );
45 +
46 + echo '<script id="wplingue-browser-redirect-js">' . rtrim( $script ) . '</script>';
47 +}
48 +
49 +
50 +/**
51 + * Redirects the user to the translated version of the page based on browser language or a user-defined cookie.
52 + *
53 + * This function is designed to run on the 'template_redirect' hook. It handles the logic for
54 + * redirecting users to the appropriate language version of a page. The redirection is based on
55 + * a stored cookie (if available) or the browser's 'Accept-Language' header.
56 + *
57 + * It prevents redirection for specific user types (e.g., logged-in users with 'edit_posts' capability)
58 + * and for known web crawlers and bots.
59 + *
60 + * @return void
61 + */
62 +function wplng_browser_language_redirect_php_js() {
63 +
64 + // Exit early for users with editing permissions or for bots to prevent redirection loops.
65 + if ( current_user_can( 'edit_posts' )
66 + || wplng_is_bot()
67 + ) {
68 + return;
69 + }
70 +
71 + $language_website_id = wplng_get_language_website_id();
72 + $language_current_id = wplng_get_language_current_id();
73 + $is_translated_page = $language_website_id !== $language_current_id;
74 + $cookie = wplng_browser_language_cookie_get();
75 +
76 + // If the user is on a translated page.
77 + if ( $is_translated_page ) {
78 + // Update the cookie with the selected language code.
79 + // This is a voluntary choice by the user.
80 + wplng_browser_language_cookie_set( $language_current_id );
81 + return;
82 + }
83 +
84 + // The user is on the original language page (no language prefix).
85 +
86 + // Determine the language to redirect to.
87 + $redirect_language_id = false;
88 +
89 + if ( $cookie !== false ) {
90 + // If the cookie contains a valid language code, use it for redirection.
91 + // This honors the user's last choice.
92 + if ( wplng_is_valid_language_id( $cookie ) ) {
93 +
94 + if ( $cookie === $language_website_id ) {
95 + return;
96 + } else {
97 + $redirect_language_id = $cookie;
98 + }
99 + }
100 + } else {
101 + // This is the very first visit (no cookie). Use the browser's language.
102 + if ( ! empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
103 + $langs = explode( ',', sanitize_text_field( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) );
104 + if ( ! empty( $langs ) ) {
105 + $language_browser_id = strtolower( substr( trim( $langs[0] ), 0, 2 ) );
106 + $redirect_language_id = $language_browser_id;
107 + }
108 + }
109 + }
110 +
111 + // Check if the determined language is a valid target language.
112 + if ( empty( $redirect_language_id )
113 + || ( $redirect_language_id === $language_website_id )
114 + || ! in_array( $redirect_language_id, wplng_get_languages_target_ids(), true )
115 + ) {
116 + // If not, set the cookie to 'original' to prevent future redirects on the original page.
117 + wplng_browser_language_cookie_set( $language_website_id );
118 + return;
119 + }
120 +
121 + // Check if the URL to redirect is translatable.
122 + $url_to_redirect = wplng_get_url_current_for_language( $redirect_language_id );
123 +
124 + if ( $url_to_redirect === wplng_get_url_original() ) {
125 + wplng_browser_language_cookie_set( $language_website_id );
126 + return;
127 + }
128 +
129 + // Perform the redirection.
130 + wplng_browser_language_cookie_set( $redirect_language_id );
131 + wp_safe_redirect(
132 + $url_to_redirect,
133 + 302
134 + );
135 + exit;
136 +}
137 +
138 +
139 +/**
140 + * Retrieves the language code from the 'wplingua-lang' cookie.
141 + *
142 + * This function safely retrieves the language code stored in the user's cookie,
143 + * sanitizing the value to prevent security issues. It returns the language code
144 + * if it's valid ('original' or a known language ID), otherwise it returns false.
145 + *
146 + * @return string|false The language code from the cookie, or false if the cookie is not set or invalid.
147 + */
148 +function wplng_browser_language_cookie_get() {
149 + $cookie = false;
150 + if ( ! empty( $_COOKIE['wplingua-lang'] ) ) {
151 + $cookie = sanitize_text_field( $_COOKIE['wplingua-lang'] );
152 + if ( ! wplng_is_valid_language_id( $cookie ) ) {
153 + $cookie = false;
154 + }
155 + }
156 +
157 + return $cookie;
158 +}
159 +
160 +
161 +/**
162 + * Sets the 'wplingua-lang' cookie with a specified language ID.
163 + *
164 + * This function creates or updates a cookie to store the user's preferred language choice.
165 + * The cookie is set to expire in 30 days and is accessible across the site's domain.
166 + *
167 + * @param string $language_id The language code to be stored (e.g., 'en', 'fr', 'es', or 'original').
168 + * @return void
169 + */
170 +function wplng_browser_language_cookie_set( $language_id ) {
171 + setcookie(
172 + 'wplingua-lang',
173 + $language_id,
174 + time() + 30 * DAY_IN_SECONDS,
175 + COOKIEPATH,
176 + COOKIE_DOMAIN
177 + );
178 +}
179 +
180 +
181 +/**
182 + * Determines if the current user agent is a bot or a web crawler.
183 + *
184 + * This function checks the user agent string against a predefined list of known bots
185 + * using a regular expression. The result is cached for the duration of the request
186 + * to improve performance on multiple calls.
187 + *
188 + * @return bool True if the user agent is a bot, false otherwise.
189 + */
190 +function wplng_is_bot() {
191 + return (bool) preg_match(
192 + '/googlebot|bingbot|slurp|duckduckbot|baiduspider|yandex|semrushbot|ahrefsbot|mj12bot|dotbot|exabot|facebookexternalhit/i',
193 + strtolower( $_SERVER['HTTP_USER_AGENT'] ?? '' )
194 + );
195 +}