PluginProbe
Translate and Go multilingual – Automatic AI translation – wpLingua / 2.12.1
Translate and Go multilingual – Automatic AI translation – wpLingua v2.12.1
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 1.1.0 1.1.1 1.2.0 1.2.1 All 109 releases
wplingua / wplingua.php

wplingua.php in Translate and Go multilingual – Automatic AI translation – wpLingua 2.12.1, at wplingua.php

420 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: wpLingua
4 * Plugin URI: https://wplingua.com/
5 * Description: An all-in-one solution that makes your websites multilingual and translates them automatically, without word or page limits. The highlights: a free first language, an on-page visual editor for editing translations, a customizable language switcher, search engine optimization (SEO), self-hosted data and more!
6 * Author: wpLingua Translation Service
7 * Author URI: https://wplingua.com/
8 * Text Domain: wplingua
9 * Domain Path: /languages/
10 * Version: 2.12.1
11 * Requires PHP: 7.4
12 * License: GPL v2 or later
13 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
14 */
15
16
17 // If this file is called directly, abort.
18 if ( ! defined( 'WPINC' ) ) {
19 die;
20 }
21
22
23 // Define wpLingua constants
24 define( 'WPLNG_API_URL', 'https://api.wplingua.com' );
25 define( 'WPLNG_API_VERSION', '3.0' );
26 define( 'WPLNG_API_SSLVERIFY', true );
27 define( 'WPLNG_PLUGIN_VERSION', '2.12.1' );
28 define( 'WPLNG_PLUGIN_FILE', plugin_basename( __FILE__ ) );
29 define( 'WPLNG_PLUGIN_DIR', __DIR__ );
30 define( 'WPLNG_CACHE_DIR', WP_CONTENT_DIR . '/wplingua-cache' );
31 define( 'WPLNG_PHP_MIN_VERSION', '7.4' );
32 define( 'WPLNG_MAX_TRANSLATIONS_STR', 220 );
33 define( 'WPLNG_MAX_TRANSLATIONS_CHAR', 4200 );
34 define( 'WPLNG_MAX_FILE_SIZE', 5000000 );
35
36
37 // Define debug constants
38 defined( 'WPLNG_DEBUG_JSON' ) || define( 'WPLNG_DEBUG_JSON', false );
39 defined( 'WPLNG_DEBUG_AJAX' ) || define( 'WPLNG_DEBUG_AJAX', false );
40 defined( 'WPLNG_DEBUG_REST' ) || define( 'WPLNG_DEBUG_REST', false );
41 defined( 'WPLNG_DEBUG_BEAT' ) || define( 'WPLNG_DEBUG_BEAT', false );
42 defined( 'WPLNG_DEBUG_XML' ) || define( 'WPLNG_DEBUG_XML', false );
43
44
45 // Load all needed PHP files
46 require_once WPLNG_PLUGIN_DIR . '/loader.php';
47
48
49 /**
50 * Loads wpLingua plugin's translated strings.
51 *
52 * @return void
53 */
54 function wplng_load_plugin_textdomain() {
55 load_plugin_textdomain(
56 'wplingua',
57 false,
58 'wplingua/languages'
59 );
60 }
61
62
63 /**
64 * Register all wpLingua Hook
65 *
66 * @return void
67 */
68 function wplng_start() {
69
70 // Setup $wplng_class_reload
71 global $wplng_class_reload;
72 $wplng_class_reload = false;
73
74 // Setup $wplng_request_uri
75 if ( isset( $_SERVER['REQUEST_URI'] ) ) {
76
77 $request_uri = wp_unslash( (string) $_SERVER['REQUEST_URI'] );
78 $request_uri = wplng_normalize_request_path( $request_uri );
79 $decoded_uri = urldecode( $request_uri );
80
81 // Check if the request URI is clean
82 if ( strtolower( esc_url_raw( $request_uri ) ) !== strtolower( $request_uri )
83 || wplng_str_is_malicious( $request_uri )
84 || wplng_str_is_malicious( $decoded_uri )
85 ) {
86 return;
87 }
88
89 // Also check query string for double-encoded attacks
90 if ( isset( $_SERVER['QUERY_STRING'] ) ) {
91 $query_string = sanitize_text_field( $_SERVER['QUERY_STRING'] );
92 $decoded_query = urldecode( urldecode( $query_string ) );
93
94 if ( wplng_str_is_malicious( $decoded_query ) ) {
95 return;
96 }
97 }
98
99 global $wplng_request_uri;
100 $wplng_request_uri = $request_uri;
101 }
102
103 // The plugin version has changed
104 if ( get_option( 'wplng_version' ) !== WPLNG_PLUGIN_VERSION ) {
105 update_option( 'wplng_version', WPLNG_PLUGIN_VERSION, true );
106 wplng_clear_translations_cache();
107 wplng_clear_slugs_cache();
108 wplng_clear_folder_cache();
109 }
110
111 // Load plugin text domain /languages/
112 add_action( 'init', 'wplng_load_plugin_textdomain' );
113
114 // Do not cache page for connected editor
115 add_action( 'init', 'wplng_init_manage_cache', 1 );
116
117 // Display a notice if incompatibility is detected
118 add_action( 'admin_notices', 'wplng_admin_notice_incompatible_plugin', 1 );
119 add_action( 'admin_notices', 'wplng_admin_notice_incompatible_multisite', 1 );
120 add_action( 'admin_notices', 'wplng_admin_notice_incompatible_php_version', 1 );
121 add_action( 'admin_notices', 'wplng_admin_notice_incompatible_htaccess', 1 );
122 add_action( 'admin_notices', 'wplng_admin_notice_incompatible_plain_permalink', 1 );
123
124 // Return if incompatibility is detected
125 if ( ! empty( wplng_get_incompatible_plugins() )
126 || is_multisite()
127 || ( version_compare( PHP_VERSION, WPLNG_PHP_MIN_VERSION ) < 0 )
128 || ! wplng_htaccess_is_valid()
129 || empty( get_option( 'permalink_structure' ) )
130 ) {
131 return;
132 }
133
134 // Register plugin settings
135 add_action( 'admin_init', 'wplng_register_settings' );
136
137 // Add settings link in plugin list
138 add_filter( 'plugin_action_links_' . WPLNG_PLUGIN_FILE, 'wplng_settings_link' );
139
140 // Redirect to the settings page on plugin activation
141 add_action( 'activated_plugin', 'wplng_plugin_activation_redirect' );
142
143 // Set footer text for options pages
144 add_filter( 'admin_footer_text', 'wplng_admin_footer_text', 11 );
145 add_filter( 'update_footer', 'wplng_update_footer', 11 );
146
147 // Print head script (JSON with all languages informations)
148 add_action( 'toplevel_page_wplingua-settings', 'wplng_inline_script_languages' );
149
150 if ( empty( wplng_get_api_data() ) ) {
151
152 // Add Register option page in back office menu
153 add_action( 'admin_menu', 'wplng_create_menu_register' );
154
155 // Enqueue CSS and JS files for register option pages
156 add_action( 'admin_enqueue_scripts', 'wplng_option_page_register_assets' );
157
158 // Display a notice if the plugin is activate but not configured
159 add_action( 'admin_notices', 'wplng_admin_notice_no_key_set', 1 );
160
161 } else {
162
163 /**
164 * Back office
165 */
166
167 // Add menu in back office
168 add_action( 'admin_menu', 'wplng_create_menu' );
169
170 // Add admin Bar menu
171 add_action( 'admin_bar_menu', 'wplng_admin_bar_menu', 81 );
172 add_action( 'admin_bar_menu', 'wplng_admin_bar_edit', 81 );
173
174 // Switcher in nav menu options
175 add_action( 'admin_enqueue_scripts', 'wplng_switcher_nav_menu_inline_scripts' );
176 add_action( 'admin_head-nav-menus.php', 'wp_nav_menu_switcher_box_add_register' );
177 add_action( 'wp_nav_menu_item_custom_fields', 'wp_nav_menu_switcher_box_edit', 10, 2 );
178
179 // Enqueue CSS and JS files for option pages
180 add_action( 'admin_enqueue_scripts', 'wplng_option_page_settings_assets' );
181 add_action( 'admin_enqueue_scripts', 'wplng_option_page_switcher_assets' );
182 add_action( 'admin_enqueue_scripts', 'wplng_option_page_exclusions_assets' );
183 add_action( 'admin_enqueue_scripts', 'wplng_option_page_dictionary_assets' );
184 add_action( 'admin_enqueue_scripts', 'wplng_option_page_link_media_assets' );
185
186 // Update flags URL
187 add_action( 'update_option_wplng_flags_style', 'wplng_options_switcher_update_flags_style', 10, 2 );
188
189 // Reset API data on API key changing
190 add_action( 'update_option_wplng_api_key', 'wplng_on_update_option_wplng_api_key', 10, 2 );
191
192 // Add edit link on page and post list
193 add_filter( 'page_row_actions', 'wplng_row_edit_translation_link', 10, 2 );
194 add_filter( 'post_row_actions', 'wplng_row_edit_translation_link', 10, 2 );
195
196 /**
197 * wplng_translation : CPT, taxo, meta
198 */
199
200 // Register wplng_translation CPT
201 add_action( 'init', 'wplng_register_post_type_translation' );
202
203 // Add metabox for wplng_translation
204 add_action( 'add_meta_boxes_wplng_translation', 'wplng_translation_add_meta_box' );
205
206 // Save metabox on posts saving
207 add_action( 'save_post_wplng_translation', 'wplng_translation_save_meta_boxes_data', 10, 2 );
208
209 // Clear translation cache on trash / untrash
210 add_action( 'trashed_post', 'wplng_clear_translations_cache_trash_untrash' );
211 add_action( 'untrash_post', 'wplng_clear_translations_cache_trash_untrash' );
212 add_action( 'delete_post', 'wplng_clear_translations_cache_trash_untrash' );
213
214 // Enqueue Script for wplng_translation admin: Edit
215 add_action( 'admin_print_scripts-post.php', 'wplng_translation_edit_assets' );
216
217 // Enqueue Script for wplng_translation admin: List
218 add_action( 'admin_print_scripts-edit.php', 'wplng_translation_list_assets' );
219
220 // Only show translations for the website languages
221 add_action( 'pre_get_posts', 'wplng_filter_wplng_translation_posts' );
222
223 // Remove Quick edit from translations list
224 add_filter( 'post_row_actions', 'wplng_translation_remove_quick_edit', 10, 2 );
225
226 // Ajax function for regenerate translation on edit page
227 add_action( 'wp_ajax_wplng_ajax_translation', 'wplng_ajax_generate_translation' );
228
229 // Ajax function for edit modal: Get HTML modal
230 add_action( 'wp_ajax_wplng_ajax_edit_modal', 'wplng_ajax_edit_modal' );
231
232 // Ajax function for edit modal: Save modal
233 add_action( 'wp_ajax_wplng_ajax_save_modal', 'wplng_ajax_save_modal' );
234
235 // Ajax function for edit modal: HeartBeat
236 add_action( 'wp_ajax_wplng_ajax_heartbeat', 'wplng_ajax_heartbeat' );
237 add_action( 'wp_ajax_nopriv_wplng_ajax_heartbeat', 'wplng_ajax_heartbeat' );
238
239 // Display 100 translation in admin area by default
240 add_filter( 'get_user_option_edit_wplng_translation_per_page', 'wplng_translation_per_page' );
241
242 // Filter translations by status
243 add_action( 'restrict_manage_posts', 'wplng_restrict_manage_posts_translation_status' );
244 add_filter( 'parse_query', 'wplng_posts_filter_translation_status' );
245
246 // Translation status on website translations list
247 add_filter( 'post_class', 'wplng_post_class_translation_status', 10, 3 );
248 add_filter( 'post_row_actions', 'wplng_post_row_actions_translation_status', 10, 2 );
249 add_filter( 'manage_wplng_translation_posts_columns', 'wplng_translation_status_columns' );
250 add_action( 'manage_wplng_translation_posts_custom_column', 'wplng_translation_status_item', 10, 2 );
251
252 /**
253 * wplng_slug : CPT, taxo, meta
254 */
255
256 // Register wplng_translation CPT
257 add_action( 'init', 'wplng_register_post_type_slug' );
258
259 // Add metabox for wplng_slug
260 add_action( 'add_meta_boxes_wplng_slug', 'wplng_slug_add_meta_box' );
261
262 // Save metabox on posts saving
263 add_action( 'save_post_wplng_slug', 'wplng_slug_save_meta_boxes_data', 10, 2 );
264
265 // Clear slugs cache on trash / untrash
266 add_action( 'trashed_post', 'wplng_clear_slugs_cache_trash_untrash' );
267 add_action( 'untrash_post', 'wplng_clear_slugs_cache_trash_untrash' );
268 add_action( 'delete_post', 'wplng_clear_slugs_cache_trash_untrash' );
269
270 // Enqueue Script for wplng_slug admin: Edit
271 add_action( 'admin_print_scripts-post.php', 'wplng_slug_edit_assets' );
272
273 // Enqueue Script for wplng_slug admin: List
274 add_action( 'admin_print_scripts-edit.php', 'wplng_slug_list_assets' );
275
276 // Only show slugs for the website languages
277 add_action( 'pre_get_posts', 'wplng_filter_wplng_slug_posts' );
278
279 // Remove Quick edit from slugs list
280 add_filter( 'post_row_actions', 'wplng_slug_remove_quick_edit', 10, 2 );
281
282 // Ajax function for regenerate slug on edit page
283 add_action( 'wp_ajax_wplng_ajax_slug', 'wplng_ajax_generate_slug' );
284
285 // Display 100 translation in admin area by default
286 add_filter( 'get_user_option_edit_wplng_slug_per_page', 'wplng_slug_per_page' );
287
288 // Filter slugs by status
289 add_action( 'restrict_manage_posts', 'wplng_restrict_manage_posts_slug_status' );
290 add_filter( 'parse_query', 'wplng_posts_filter_slug_status' );
291
292 // Translation status on website slugs list
293 add_filter( 'post_class', 'wplng_post_class_slug_status', 10, 3 );
294 add_filter( 'post_row_actions', 'wplng_post_row_actions_slug_status', 10, 2 );
295 add_filter( 'manage_wplng_slug_posts_columns', 'wplng_slug_status_columns' );
296 add_action( 'manage_wplng_slug_posts_custom_column', 'wplng_slug_status_item', 10, 2 );
297
298 /**
299 * Front
300 */
301
302 // Enqueue CSS and JS files
303 add_action( 'wp_enqueue_scripts', 'wplng_register_assets' );
304
305 // Add custom inline styles (option page: switcher)
306 add_action( 'wp_head', 'wplng_add_custom_inline_styles', 50 );
307
308 // Script JS in page
309 add_action( 'wp_footer', 'wplng_on_page_script' );
310
311 // Add languages switcher before </body>
312 add_action( 'wp_footer', 'wplng_switcher_wp_footer' );
313
314 // Add languages switcher in nav menu
315 add_filter( 'wp_nav_menu_objects', 'wplng_switcher_nav_menu_replace_items' );
316 add_filter( 'nav_menu_link_attributes', 'wplng_add_nav_menu_link_attributes_atts', 10, 2 );
317
318 // Set alternate links with hreflang parametters
319 add_action( 'wp_head', 'wplng_link_alternate_hreflang', 1 );
320
321 // Disable web browser automatic translation
322 add_action( 'language_attributes', 'wplng_disable_web_browser_auto_translate' );
323
324 // Ajax function for Load in progress
325 add_action( 'wp_ajax_wplng_load_in_progress', 'wplng_ajax_load_in_progress' );
326
327 /**
328 * OB and REQUEST_URI
329 */
330
331 // Manage URL with REQUEST_URI and start OB
332 add_action( 'init', 'wplng_ob_start', 1 );
333
334 // Redirect page if is called with an untranslate slug
335 add_action( 'template_redirect', 'wplng_redirect_translated_slug' );
336
337 /**
338 * Generate JSON translation on the fly for wp-i18n.js
339 */
340
341 // Generate JSON translation
342 add_filter( 'load_script_translation_file', 'wplng_load_script_translation_file', 20, 3 );
343
344 /**
345 * Clear wpLingua cache on updates
346 */
347
348 // Clear wpLingua cache on WordPress core, plugins, themes or translations update
349 add_action( 'upgrader_process_complete', 'wplng_clear_cache_on_update', 10, 2 );
350
351 // Clear wpLingua cache on plugin activation/deactivation
352 add_action( 'activated_plugin', 'wplng_clear_folder_cache' );
353 add_action( 'deactivated_plugin', 'wplng_clear_folder_cache' );
354
355 // Clear wpLingua cache on theme switch
356 add_action( 'switch_theme', 'wplng_clear_folder_cache' );
357
358 // Clear wpLingua cache on site language change
359 add_action( 'update_option_WPLANG', 'wplng_clear_folder_cache' );
360
361 // Clear wpLingua cache on wpLingua settings change
362 add_action( 'update_option_wplng_website_language', 'wplng_clear_folder_cache' );
363 add_action( 'update_option_wplng_target_languages', 'wplng_clear_folder_cache' );
364
365 /**
366 * Features
367 */
368
369 // Make multilingua Sitemap XML for All In One SEO plugin
370 // Il other case, multilingual Sitemap is make by output buffering
371 if ( get_option( 'wplng_sitemap_xml', true )
372 && function_exists( 'aioseo' )
373 ) {
374 add_filter( 'aioseo_sitemap_post', 'wplng_aioseo_filter_sitemap_post', 10, 2 );
375 add_filter( 'aioseo_sitemap_term', 'wplng_aioseo_filter_sitemap_term', 10, 2 );
376 }
377
378 // Search from translated languages
379 if ( ! empty( get_option( 'wplng_translate_search' ) )
380 && wplng_api_feature_is_allow( 'search' )
381 ) {
382 add_action( 'parse_query', 'wplng_translate_search_query' );
383 } else {
384 add_filter( 'wplng_url_is_translatable', 'wplng_exclude_search', 20 );
385 }
386
387 // Redirect by browser language
388 $browser_language_redirect = get_option( 'wplng_browser_language_redirect' );
389 if ( $browser_language_redirect === 'js_only' ) {
390 add_action( 'wp_head', 'wplng_browser_language_redirect_js_only', 2 );
391 } elseif ( $browser_language_redirect === 'php_js' ) {
392 add_action( 'template_redirect', 'wplng_browser_language_redirect_php_js' );
393 }
394
395 /**
396 * Shortcode
397 */
398
399 add_shortcode( 'wplng_switcher', 'wplng_shortcode_switcher' );
400 add_shortcode( 'wplng_notranslate', 'wplng_shortcode_notranslate' );
401 add_shortcode( 'wplng_only', 'wplng_shortcode_only' );
402
403 /**
404 * Gutenberg
405 */
406
407 add_filter( 'block_categories_all', 'wplng_block_category' );
408 add_action( 'init', 'wplng_register_block' );
409 add_action( 'enqueue_block_editor_assets', 'wplng_register_block_assets' );
410
411 /**
412 * Do action after wpLingua fully initialized
413 */
414
415 do_action( 'wplng_initialized' );
416
417 }
418 }
419 wplng_start();
420