PluginProbe
Translate and boost SEO – Automatic AI translation – wpLingua / 3.0.0
Translate and boost SEO – Automatic AI translation – wpLingua v3.0.0
3.0.0 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 All 114 releases
wplingua / inc / admin / option-page.php

option-page.php in Translate and boost SEO – Automatic AI translation – wpLingua 3.0.0, at inc/admin/option-page.php

971 lines 27.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // If this file is called directly, abort.
4 if ( ! defined( 'WPINC' ) ) {
5 die;
6 }
7
8
9 /**
10 * Register wpLingua settings
11 *
12 * @return void
13 */
14 function wplng_register_settings() {
15
16 // Option page : Settings and register
17 register_setting( 'wplng_settings', 'wplng_website_language' );
18 register_setting( 'wplng_settings', 'wplng_website_flag' );
19 register_setting( 'wplng_settings', 'wplng_target_languages' );
20 register_setting( 'wplng_settings', 'wplng_translate_search' );
21 register_setting( 'wplng_settings', 'wplng_load_in_progress' );
22 register_setting( 'wplng_settings', 'wplng_sitemap_xml' );
23 register_setting( 'wplng_settings', 'wplng_sitemap_xsl_override' );
24 register_setting( 'wplng_settings', 'wplng_hreflang' );
25 register_setting( 'wplng_settings', 'wplng_browser_language_redirect' );
26 register_setting( 'wplng_settings', 'wplng_api_key' );
27 register_setting( 'wplng_settings', 'wplng_request_free_key' );
28
29 // Option page : Exclusions
30 register_setting( 'wplng_exclusions', 'wplng_excluded_selectors' );
31 register_setting( 'wplng_exclusions', 'wplng_excluded_url' );
32
33 // Option page : Switcher
34 register_setting( 'wplng_switcher', 'wplng_insert' );
35 register_setting( 'wplng_switcher', 'wplng_theme' );
36 register_setting( 'wplng_switcher', 'wplng_style' );
37 register_setting( 'wplng_switcher', 'wplng_name_format' );
38 register_setting( 'wplng_switcher', 'wplng_flags_style' );
39 register_setting( 'wplng_switcher', 'wplng_custom_css' );
40
41 // Option page : Dictionary
42 register_setting( 'wplng_dictionary', 'wplng_dictionary_entries' );
43
44 // Option page : Links & Medias
45 register_setting( 'wplng_link_media', 'wplng_link_media_entries' );
46
47 // Option page : Links & Medias
48 register_setting( 'wplng_mail', 'wplng_mail_enable' );
49 register_setting( 'wplng_mail', 'wplng_mail_exclude_address' );
50 register_setting( 'wplng_mail', 'wplng_mail_exclude_url' );
51 }
52
53
54 /**
55 * Determine whether the current page is one of
56 * wpLingua's hidden option pages.
57 */
58 function wplng_is_wplingua_settings_page() {
59
60 if ( empty( $_GET['page'] ) ) {
61 return false;
62 }
63
64 return in_array(
65 sanitize_key( $_GET['page'] ),
66 array(
67 'wplingua-settings',
68 'wplingua-switcher',
69 'wplingua-exclusions',
70 'wplingua-dictionary',
71 'wplingua-link-media',
72 'wplingua-mail',
73 ),
74 true
75 );
76 }
77
78
79 /**
80 * Return true if is a wpLingua Admin page
81 *
82 * @return bool Is a wpLingua Admin page
83 */
84 function wplng_is_wplingua_admin_page() {
85
86 global $pagenow;
87 global $post;
88
89 /**
90 * Check if is a wpLingua option page
91 */
92
93 // TODO : Check if use wplng_is_wplingua_settings_page()
94
95 if ( 'admin.php' === $pagenow
96 && isset( $_GET['page'] )
97 && (
98 $_GET['page'] === 'wplingua-settings'
99 || $_GET['page'] === 'wplingua-switcher'
100 || $_GET['page'] === 'wplingua-dictionary'
101 || $_GET['page'] === 'wplingua-exclusions'
102 || $_GET['page'] === 'wplingua-link-media'
103 || $_GET['page'] === 'wplingua-mail'
104 )
105 ) {
106 return true;
107 }
108
109 /**
110 * Check if is a translations or slugs admin list
111 */
112
113 if (
114 'edit.php' === $pagenow
115 && isset( $_GET['post_type'] )
116 && (
117 $_GET['post_type'] === 'wplng_translation'
118 || $_GET['post_type'] === 'wplng_slug'
119 )
120 ) {
121 return true;
122 }
123
124 /**
125 * Check if is translations or slugs edition
126 */
127
128 if (
129 'post.php' === $pagenow
130 && isset( $post->post_type )
131 && (
132 $post->post_type === 'wplng_translation'
133 || $post->post_type === 'wplng_slug'
134 )
135 ) {
136 return true;
137 }
138
139 return false;
140 }
141
142
143 /**
144 * Add wpLingua admin menu when API Key is not registered
145 *
146 * @return void
147 */
148 function wplng_create_menu_register() {
149
150 add_menu_page(
151 __( 'wpLingua: Register', 'wplingua' ),
152 __( 'wpLingua', 'wplingua' ),
153 'edit_posts',
154 'wplingua-settings',
155 'wplng_option_page_register',
156 'dashicons-translation',
157 31
158 );
159 }
160
161
162 /**
163 * Create wpLingua admin menu.
164 */
165 function wplng_create_menu() {
166
167 /*
168 * Main wpLingua menu
169 */
170 add_menu_page(
171 __( 'wpLingua: Settings', 'wplingua' ),
172 __( 'wpLingua', 'wplingua' ),
173 'edit_posts',
174 'wplingua-settings',
175 '',
176 'dashicons-translation',
177 31
178 );
179
180 /*
181 * Settings
182 *
183 * This is the visible entry used as the parent
184 * for all wpLingua option pages.
185 */
186 add_submenu_page(
187 'wplingua-settings',
188 __( 'wpLingua: Settings', 'wplingua' ),
189 __( 'Settings', 'wplingua' ),
190 'edit_posts',
191 'wplingua-settings',
192 'wplng_option_page_settings'
193 );
194
195 /*
196 * Hidden option pages
197 *
198 * These pages remain registered as children of
199 * wplingua-settings, but their menu entries are
200 * hidden later with CSS.
201 */
202
203 add_submenu_page(
204 'wplingua-settings',
205 __( 'wpLingua: Switcher', 'wplingua' ),
206 __( 'Switcher', 'wplingua' ),
207 'edit_posts',
208 'wplingua-switcher',
209 'wplng_option_page_switcher'
210 );
211
212 add_submenu_page(
213 'wplingua-settings',
214 __( 'wpLingua: Exclusion', 'wplingua' ),
215 __( 'Exclusion', 'wplingua' ),
216 'edit_posts',
217 'wplingua-exclusions',
218 'wplng_option_page_exclusions'
219 );
220
221 add_submenu_page(
222 'wplingua-settings',
223 __( 'wpLingua: Dictionary', 'wplingua' ),
224 __( 'Dictionary', 'wplingua' ),
225 'edit_posts',
226 'wplingua-dictionary',
227 'wplng_option_page_dictionary'
228 );
229
230 add_submenu_page(
231 'wplingua-settings',
232 __( 'wplingua: Links & Medias', 'wplingua' ),
233 __( 'Links & Medias', 'wplingua' ),
234 'edit_posts',
235 'wplingua-link-media',
236 'wplng_option_page_link_media'
237 );
238
239 add_submenu_page(
240 'wplingua-settings',
241 __( 'wplingua: Emails translation', 'wplingua' ),
242 __( 'Emails translation', 'wplingua' ),
243 'edit_posts',
244 'wplingua-mail',
245 'wplng_option_page_mail'
246 );
247
248 /*
249 * Visible custom post type pages
250 */
251
252 add_submenu_page(
253 'wplingua-settings',
254 __( 'wpLingua: Website slugs', 'wplingua' ),
255 __( 'Website slugs', 'wplingua' ),
256 'edit_posts',
257 'edit.php?post_type=wplng_slug',
258 false
259 );
260
261 add_submenu_page(
262 'wplingua-settings',
263 __( 'wpLingua: Translations', 'wplingua' ),
264 __( 'All translations', 'wplingua' ),
265 'edit_posts',
266 'edit.php?post_type=wplng_translation',
267 false
268 );
269 }
270
271
272 /**
273 * Keep wpLingua as the active parent menu
274 * on all wpLingua option pages.
275 *
276 * @param string $parent_file The current parent menu file.
277 *
278 * @return string The parent menu file.
279 */
280 function wplng_option_page_parent_file( $parent_file ) {
281
282 if ( wplng_is_wplingua_settings_page() ) {
283 return 'wplingua-settings';
284 }
285
286 return $parent_file;
287 }
288
289
290 /**
291 * Keep "Settings" as the active submenu
292 * on all wpLingua option pages.
293 *
294 * @param string $submenu_file The current submenu file.
295 *
296 * @return string The submenu file.
297 */
298 function wplng_option_page_submenu_file( $submenu_file ) {
299
300 if ( wplng_is_wplingua_settings_page() ) {
301 return 'wplingua-settings';
302 }
303
304 return $submenu_file;
305 }
306
307
308 /**
309 * Hide the option pages from the wpLingua submenu.
310 *
311 * The pages themselves remain registered in WordPress.
312 * Therefore, they are still accessible directly by URL
313 * and remain correctly associated with the wpLingua menu.
314 */
315 function wplng_option_page_hide_submenu() {
316
317 $css = '<style>';
318 $css .= '#adminmenu .wp-submenu a[href*="page=wplingua-switcher"], ';
319 $css .= '#adminmenu .wp-submenu a[href*="page=wplingua-exclusions"], ';
320 $css .= '#adminmenu .wp-submenu a[href*="page=wplingua-dictionary"], ';
321 $css .= '#adminmenu .wp-submenu a[href*="page=wplingua-link-media"], ';
322 $css .= '#adminmenu .wp-submenu a[href*="page=wplingua-mail"] {';
323 $css .= 'display: none;';
324 $css .= '}';
325 $css .= '</style>';
326
327 echo $css;
328 }
329
330
331
332 /**
333 * Generates the navigation menu for wpLingua option pages.
334 *
335 * Creates a list of links to the different wpLingua settings pages,
336 * highlighting the current page with the `button-primary` class.
337 *
338 * @param bool $display_none Whether to hide the menu by default.
339 *
340 * @return string The HTML markup for the option pages navigation menu.
341 */
342 function wplng_option_page_settings_menu( $display_none = false ) {
343
344 $data = array(
345 array(
346 'page' => 'wplingua-settings',
347 'title' => __( 'General settings', 'wplingua' ),
348 'dashicon' => 'dashicons-admin-generic',
349 ),
350 array(
351 'page' => 'wplingua-switcher',
352 'title' => __( 'Language switcher', 'wplingua' ),
353 'dashicon' => 'dashicons-admin-settings',
354 ),
355 array(
356 'page' => 'wplingua-exclusions',
357 'title' => __( 'Exclusion', 'wplingua' ),
358 'dashicon' => 'dashicons-filter',
359 ),
360 array(
361 'page' => 'wplingua-dictionary',
362 'title' => __( 'Dictionary', 'wplingua' ),
363 'dashicon' => 'dashicons-book',
364 ),
365 array(
366 'page' => 'wplingua-link-media',
367 'title' => __( 'Links & Medias', 'wplingua' ),
368 'dashicon' => 'dashicons-format-gallery',
369 ),
370 array(
371 'page' => 'wplingua-mail',
372 'title' => __( 'Emails translation', 'wplingua' ),
373 'dashicon' => 'dashicons-email-alt',
374 ),
375 );
376
377 $style = '';
378 if ( $display_none === true ) {
379 $style = ' style="display: none;"';
380 }
381
382 $html = '<div class="wplng-option-page-menu"' . $style . '>';
383 $html .= '<ul>';
384
385 foreach ( $data as $value ) {
386
387 $url = add_query_arg(
388 'page',
389 $value['page'],
390 admin_url( 'admin.php' )
391 );
392
393 $class_attr_a = '';
394 if ( $_GET['page'] === $value['page'] ) {
395 $class_attr_a = ' button-primary';
396 }
397
398 if ( isset( $value['is_beta'] )
399 && $value['is_beta'] === true
400 ) {
401 $html .= '<li class="wplng-beta-hidden" style="display: none;">';
402 } else {
403 $html .= '<li>';
404 }
405
406 $html .= '<a href="' . esc_url( $url ) . '" class="button' . $class_attr_a . '">';
407 $html .= '<span class="dashicons ' . esc_attr( $value['dashicon'] ) . '">';
408 $html .= '</span> ';
409 $html .= esc_html( $value['title'] );
410 $html .= '</a>';
411 $html .= '</li>';
412 }
413
414 $html .= '</ul>';
415 $html .= '</div>'; // End .wplng-option-page-menu
416
417 return $html;
418 }
419
420
421 /**
422 * Customize the admin footer text displayed on wpLingua option pages.
423 *
424 * @param string $text The default footer text.
425 * @return string The customized footer text for wpLingua pages.
426 */
427 function wplng_admin_footer_text( $text ) {
428
429 if ( wplng_is_wplingua_admin_page() ) {
430
431 $text = '<span class="dashicons dashicons-heart"></span> ';
432
433 if ( empty( wplng_get_api_data() ) ) {
434 $text .= esc_html__( 'Thank you for choosing wpLingua!', 'wplingua' );
435 } else {
436 $text .= sprintf(
437 esc_html__( 'If you like wpLingua please leave us a %1$s rating. A huge thanks!', 'wplingua' ),
438 '<a href="https://wordpress.org/support/plugin/wplingua/reviews/?filter=5" target="_blank" rel="noopener noreferrer" aria-label="' . esc_attr__( 'five stars', 'wplingua' ) . '">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
439 );
440 }
441 }
442
443 return $text;
444 }
445
446
447 /**
448 * Set custom update_footer text on wpLingua options pages
449 *
450 * @param string $text The default footer text to be modified.
451 * @return string The customized footer text for wpLingua pages.
452 */
453 function wplng_update_footer( $text ) {
454
455 if ( wplng_is_wplingua_admin_page() ) {
456 $text = '<a href="https://wplingua.com/" target="_blank" rel="noopener noreferrer">';
457 $text .= 'wplingua.com';
458 $text .= '</a> | ';
459 $text .= '<a href="https://github.com/julien-jacob/wplingua" target="_blank" rel="noopener noreferrer">';
460 $text .= 'GitHub';
461 $text .= '</a> | wpLingua ';
462 $text .= esc_html( WPLNG_PLUGIN_VERSION );
463
464 if ( defined( 'WPLNGPRO_PLUGIN_VERSION' ) ) {
465 $text .= ' | wpLingua PRO ';
466 $text .= esc_html( WPLNGPRO_PLUGIN_VERSION );
467 }
468 }
469
470 return $text;
471 }
472
473
474 /**
475 * Add 'Settings' link on wpLingua in the plugin list
476 *
477 * @param array $settings
478 * @return array
479 */
480 function wplng_settings_link( $settings ) {
481
482 $url = add_query_arg(
483 'page',
484 'wplingua-settings',
485 get_admin_url() . 'admin.php'
486 );
487
488 $link = '<a href="' . esc_url( $url ) . '">';
489 $link .= esc_html__( 'Settings', 'wplingua' );
490 $link .= '</a>';
491
492 $settings[] = $link;
493
494 return $settings;
495 }
496
497
498 /**
499 * Redirect to the wpLingua settings page upon plugin activation.
500 *
501 * @param string $plugin The plugin file path that was activated.
502 * @return void
503 */
504 function wplng_plugin_activation_redirect( $plugin ) {
505
506 if ( ! wp_doing_ajax() && WPLNG_PLUGIN_FILE === $plugin ) {
507 wp_safe_redirect(
508 admin_url( 'admin.php?page=wplingua-settings' )
509 );
510 exit();
511 }
512 }
513
514
515 /**
516 * Display a notice if the plugin is activate but not configured
517 *
518 * @return void
519 */
520 function wplng_admin_notice_no_key_set() {
521
522 $url = add_query_arg(
523 'page',
524 'wplingua-settings',
525 get_admin_url() . 'admin.php'
526 );
527
528 $html = '<div class="notice notice-info is-dismissible">';
529 $html .= '<p style="font-weight: 600;">';
530 $html .= '<span class="dashicons dashicons-translation"></span> ';
531 $html .= esc_html__( 'wpLingua - Translation solution for multilingual website', 'wplingua' );
532 $html .= '</p>';
533 $html .= '<p>';
534 $html .= esc_html__( 'wpLingua is installed, but not yet configured. You are just a few clicks away from making your website multilingual!', 'wplingua' );
535 $html .= '<br> ';
536 $html .= '<a href="' . esc_url( $url ) . '">';
537 $html .= esc_html__( 'Go to the configuration page', 'wplingua' );
538 $html .= '</a>';
539 $html .= '</p>';
540 $html .= '</div>';
541
542 echo $html;
543 }
544
545
546 /**
547 * Get the list of activated incompatible plugins
548 *
549 * @return array [Plugin name => Plugin file]
550 */
551 function wplng_get_incompatible_plugins() {
552
553 if ( ! function_exists( 'is_plugin_active' ) ) {
554 require_once ABSPATH . '/wp-admin/includes/plugin.php';
555 }
556
557 /**
558 * Get incompatible plugins
559 */
560
561 $incompatible_list = array(
562 'Automatic Translator' => 'auto-translate/auto-translate.php',
563 'Autoglot' => 'autoglot/autoglot.php',
564 'clonable' => 'clonable/clonable-wp.php',
565 'ConveyThis Translate' => 'conveythis-translate/index.php',
566 'Falang' => 'falang/falang.php',
567 'Google Translator' => 'google-language-translator/google-language-translator.php',
568 'Google Website Translator' => 'google-website-translator/google-website-translator.php',
569 'Gtranslate' => 'gtranslate/gtranslate.php',
570 'linguise' => 'linguise/linguise.php',
571 'Lokalise' => 'lokalise/lokalise.php',
572 'localizejs' => 'localizejs/localizejs.php',
573 'Multilanguage' => 'multilanguage/multilanguage.php',
574 'Polylang' => 'polylang/polylang.php',
575 'TranslatePress' => 'translatepress-multilingual/index.php',
576 'WEGLOT' => 'weglot/weglot.php',
577 'WPML' => 'sitepress-multilingual-cms/sitepress.php',
578 'WP Multilang' => 'wp-multilang/wp-multilang.php',
579 );
580
581 $incompatible_detected = array();
582
583 foreach ( $incompatible_list as $name => $file ) {
584 if ( is_plugin_active( $file ) ) {
585 $incompatible_detected[ $name ] = $file;
586 }
587 }
588
589 return $incompatible_detected;
590 }
591
592
593 /**
594 * Display a notice if an incompatible plugin is detected.
595 *
596 * @return void|string Outputs the admin notice or returns nothing if no conflicts are found.
597 */
598 function wplng_admin_notice_incompatible_plugin() {
599
600 $incompatible_plugins = wplng_get_incompatible_plugins();
601
602 if ( empty( $incompatible_plugins ) ) {
603 return;
604 }
605
606 $html = '<div ';
607 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
608 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
609 $html .= '<p style="font-weight: 600;">';
610 $html .= '<span class="dashicons dashicons-translation"></span> ';
611 $html .= esc_html__( 'wpLingua - Incompatible plugin detected', 'wplingua' );
612 $html .= '</p>';
613 $html .= '<p>';
614 $html .= esc_html__( 'You have several translation plugins. This may result in unpredictable or incorrect behavior. For best results, use only one translation plugin at a time. These plugins can cause problems with wpLingua: ', 'wplingua' );
615
616 $html .= '<ul style="list-style: disc; margin-left: 15px;">';
617 foreach ( $incompatible_plugins as $name => $file ) {
618
619 $deactivate_url = wp_nonce_url(
620 add_query_arg(
621 array(
622 'action' => 'deactivate',
623 'plugin' => urlencode( $file ),
624 ),
625 get_admin_url() . 'plugins.php'
626 ),
627 'deactivate-plugin_' . $file
628 );
629
630 $deactivate_title = sprintf(
631 esc_html__( 'Deactivate plugin: %1$s', 'wplingua' ),
632 $name
633 );
634
635 $html .= '<li>';
636 $html .= '<strong>' . esc_html( $name ) . '</strong> | ';
637 $html .= '<a ';
638 $html .= 'href="' . esc_url( $deactivate_url ) . '" ';
639 $html .= 'title="' . esc_attr( $deactivate_title ) . '">';
640 $html .= esc_html__( 'Deactivate', 'wplingua' );
641 $html .= '</a>';
642 $html .= '</li>';
643 }
644 $html .= '</ul>';
645 $html .= '</p>';
646
647 $url_manage_plugins = add_query_arg(
648 'plugin_status',
649 'active',
650 get_admin_url() . 'plugins.php'
651 );
652
653 $html .= '<a ';
654 $html .= 'href="' . esc_url( $url_manage_plugins ) . '" ';
655 $html .= 'class="button button-primary" ';
656 $html .= 'style="margin-bottom: 10px;">';
657 $html .= esc_html__( 'Manage active plugins', 'wplingua' );
658 $html .= '</a>';
659
660 $html .= '</div>'; // End .notice
661
662 echo $html;
663 }
664
665
666 /**
667 * Display a notice if is a multisite
668 *
669 * Note: wpLingua does not officially support multisite installations and
670 * does not guarantee compatibility. Advanced users can bypass this
671 * incompatibility check by returning true from the
672 * `wplng_bypass_multisite_incompatibility` filter.
673 *
674 * @see apply_filters( 'wplng_bypass_multisite_incompatibility', false )
675 *
676 * @return void|string Outputs the admin notice if applicable, or returns void if no action is needed.
677 */
678 function wplng_admin_notice_incompatible_multisite() {
679
680 // Advanced users can bypass the multisite incompatibility notice by
681 // returning true to this filter. Note that bypassing does NOT make
682 // wpLingua officially compatible with multisite installations.
683 if ( ! is_multisite()
684 || apply_filters( 'wplng_bypass_multisite_incompatibility', false )
685 ) {
686 return;
687 }
688
689 $html = '<div ';
690 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
691 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
692 $html .= '<p style="font-weight: 600;">';
693 $html .= '<span class="dashicons dashicons-translation"></span> ';
694 $html .= esc_html__( 'wpLingua - Incompatible with multisite', 'wplingua' );
695 $html .= '</p>';
696 $html .= '<p>';
697 $html .= esc_html__( 'wpLingua is not compatible with multisite.', 'wplingua' );
698 $html .= '</p>';
699 $html .= '</div>'; // End .notice
700
701 echo $html;
702 }
703
704
705 /**
706 * Display a notice if the WordPress installed in a subfolder
707 *
708 * @return void|string Outputs the admin notice if applicable, or returns void if no notice is needed.
709 */
710 function wplng_admin_notice_incompatible_sub_folder() {
711
712 if ( ! wplng_website_in_sub_folder() ) {
713 return;
714 }
715
716 $html = '<div ';
717 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
718 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
719 $html .= '<p style="font-weight: 600;">';
720 $html .= '<span class="dashicons dashicons-translation"></span> ';
721 $html .= esc_html__( 'wpLingua - Incompatible with WordPress installed in a subfolder', 'wplingua' );
722 $html .= '</p>';
723 $html .= '<p>';
724 $html .= esc_html__( 'wpLingua is not compatible with WordPress installed in a subfolder.', 'wplingua' );
725 $html .= '</p>';
726 $html .= '</div>'; // End .notice
727
728 echo $html;
729 }
730
731
732 /**
733 * Display a notice if the PHP version is incompatible
734 *
735 * @return void|string Outputs the admin notice if applicable, or returns void if no notice is required.
736 */
737 function wplng_admin_notice_incompatible_php_version() {
738
739 if ( version_compare( PHP_VERSION, WPLNG_PHP_MIN_VERSION ) >= 0 ) {
740 return;
741 }
742
743 $html = '<div ';
744 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
745 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
746 $html .= '<p style="font-weight: 600;">';
747 $html .= '<span class="dashicons dashicons-translation"></span> ';
748 $html .= esc_html__( 'wpLingua - Incompatible PHP version', 'wplingua' );
749 $html .= '</p>';
750 $html .= '<p>';
751 $html .= esc_html__( 'wpLingua is not compatible with your PHP version. wpLingua requires PHP 7.4 or higher.', 'wplingua' );
752 $html .= '</p>';
753 $html .= '</div>'; // End .notice
754
755 echo $html;
756 }
757
758
759 /**
760 * Check if the HTACCESS file contain code of another plugin who break translated pages
761 *
762 * @return bool HTACCESS file is valid for wpLingua
763 */
764 function wplng_htaccess_is_valid() {
765
766 $htaccess_path = ABSPATH . '.htaccess';
767
768 if ( ! file_exists( $htaccess_path ) ) {
769 return true;
770 }
771
772 $htaccess_content = file_get_contents( $htaccess_path );
773
774 return ! (
775 strpos( $htaccess_content, 'GTranslate' ) !== false
776 || strpos( $htaccess_content, 'LINGUISE' ) !== false
777 );
778 }
779
780
781 /**
782 * Display a notice if the HTACCESS file is incompatible
783 *
784 * @return void|string Outputs the admin notice if applicable, or returns void if no notice is required.
785 */
786 function wplng_admin_notice_incompatible_htaccess() {
787
788 $htaccess_path = ABSPATH . '.htaccess';
789
790 if ( ! file_exists( $htaccess_path ) ) {
791 return;
792 }
793
794 $htaccess_content = file_get_contents( $htaccess_path );
795 $message = '';
796
797 if ( strpos( $htaccess_content, 'GTranslate' ) !== false ) {
798 $message .= '### BEGIN GTranslate config ###' . PHP_EOL;
799 $message .= '...' . PHP_EOL;
800 $message .= '### END GTranslate config ###';
801 } elseif ( strpos( $htaccess_content, 'LINGUISE' ) !== false ) {
802 $message .= '#### LINGUISE DO NOT EDIT ####' . PHP_EOL;
803 $message .= '...' . PHP_EOL;
804 $message .= '#### LINGUISE DO NOT EDIT END ####';
805 }
806
807 if ( ! empty( $message ) ) {
808
809 $html = '<div ';
810 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
811 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
812 $html .= '<p style="font-weight: 600;">';
813 $html .= '<span class="dashicons dashicons-translation"></span> ';
814 $html .= esc_html__( 'wpLingua - Incompatible HTACCESS file', 'wplingua' );
815 $html .= '</p>';
816 $html .= '<p>';
817 $html .= esc_html__( 'It seems that a plugin was incorrectly deactivated and corrupted the site\'s HTACCESS file, preventing the correct redirection of translated pages. Please edit the ".htaccess" file located at the root of the site and delete the lines between :', 'wplingua' );
818 $html .= '<pre style="border: 1px solid #c3c4c7; padding: 8px; background-color: rgba(0,0,0,.05);">';
819 $html .= $message;
820 $html .= '</pre>';
821 $html .= '</p>';
822 $html .= '</div>'; // End .notice
823
824 echo $html;
825 }
826 }
827
828
829 /**
830 * Display a notice if the permalink structure is set to Plain
831 *
832 * @return void|string Outputs the admin notice if applicable, or returns void if no notice is required.
833 */
834 function wplng_admin_notice_incompatible_plain_permalink() {
835
836 if ( ! empty( get_option( 'permalink_structure' ) ) ) {
837 return;
838 }
839
840 $url_permalinks = get_admin_url() . 'options-permalink.php';
841
842 $html = '<div ';
843 $html .= 'class="wplng-notice notice notice-error is-dismissible" ';
844 $html .= 'style="background-color: rgba(255, 0, 0, .1);">';
845 $html .= '<p style="font-weight: 600;">';
846 $html .= '<span class="dashicons dashicons-translation"></span> ';
847 $html .= esc_html__( 'wpLingua - Incompatible permalink structure', 'wplingua' );
848 $html .= '</p>';
849 $html .= '<p>';
850 $html .= esc_html__( 'wpLingua is not compatible with the "Plain" permalink structure. Please update your permalink settings to use "Post name" or "Custom Structure".', 'wplingua' );
851 $html .= '</p>';
852 $html .= '<a ';
853 $html .= 'href="' . esc_url( $url_permalinks ) . '" ';
854 $html .= 'class="button button-primary" ';
855 $html .= 'style="margin-bottom: 10px;">';
856 $html .= esc_html__( 'Manage permalink settings', 'wplingua' );
857 $html .= '</a>';
858 $html .= '</div>'; // End .notice
859
860 echo $html;
861 }
862
863
864 /**
865 * Display a notice related to the PRO plan on wpLingua admin pages
866 * - Only for non free users (STARTER or PREMIUM plans)
867 * - Only on wpLingua admin pages
868 * - If the plan has expired: display an error notice inviting to renew it
869 * - Otherwise, if the PRO plugin is not active: display a warning notice
870 * inviting to download and install it
871 *
872 * @return void Outputs the admin notice if applicable, or nothing otherwise.
873 */
874 function wplng_admin_notice_pro() {
875
876 $data = wplng_get_api_data();
877
878 if ( empty( $data['plan'] )
879 || $data['plan'] === 'FREE'
880 ) {
881 return;
882 }
883
884 $expired = ! empty( $data['expired'] );
885
886 if ( wplng_is_wplingua_admin_page() ) {
887
888 if ( $expired === true ) {
889
890 $html = '<div';
891 $html .= ' class="wplng-notice notice notice-error is-dismissible"';
892 $html .= ' style="text-align: center;"';
893 $html .= '>';
894 $html .= '<p style="font-weight: 600; margin-bottom: 15px;">';
895 $html .= '<span class="dashicons dashicons-translation"></span> ';
896 $html .= esc_html__( 'wpLingua - Your plan has expired', 'wplingua' );
897 $html .= '</p>';
898 $html .= '<hr>';
899 $html .= '<div style="max-width: 850px; margin: 15px auto 20px;">';
900 $html .= '<p>';
901 $html .= sprintf(
902 wp_kses(
903 /* translators: 1: plan name (STARTER or PREMIUM), 2: expiration date */
904 __( 'Your <strong>wpLingua %1$s plan</strong> expired on <strong>%2$s</strong>. Your access to automatic translation services and PRO features has expired.', 'wplingua' ),
905 array( 'strong' => array() )
906 ),
907 esc_html( $data['plan'] ),
908 esc_html( ! empty( $data['expiration'] ) ? $data['expiration'] : '' )
909 );
910 $html .= '</p>';
911
912 $html .= '<p>';
913 $html .= wp_kses(
914 __( 'Keep your website translated as you add new content. Renew your plan to restore automatic translations and all wpLingua PRO features. To renew your wpLingua plan, all you need is your API key, which is available under <strong>wpLingua ➔ Settings ➔ wpLingua API key</strong>.', 'wplingua' ),
915 array( 'strong' => array() )
916 );
917 $html .= '</p>';
918
919 $html .= '</div>';
920 $html .= '<p>';
921 $html .= '<a';
922 $html .= ' href="https://wplingua.com/pricing/#choose-features"';
923 $html .= ' target="_blank"';
924 $html .= ' rel="noopener noreferrer"';
925 $html .= ' class="button button-primary"';
926 $html .= '>';
927 $html .= esc_html__( 'wpLingua.com : Renew your plan', 'wplingua' );
928 $html .= '</a>';
929 $html .= '</p>';
930
931 $html .= '</div>'; // End .notice
932
933 echo $html;
934
935 } elseif ( ! is_plugin_active( 'wplingua-pro/wplingua-pro.php' ) ) {
936
937 $html = '<div';
938 $html .= ' class="wplng-notice notice notice-warning is-dismissible"';
939 $html .= ' style="text-align: center;"';
940 $html .= '>';
941 $html .= '<p style="font-weight: 600; margin-bottom: 15px;">';
942 $html .= '<span class="dashicons dashicons-translation"></span> ';
943 $html .= esc_html__( 'wpLingua - Unlock PRO Features', 'wplingua' );
944 $html .= '</p>';
945 $html .= '<hr>';
946 $html .= '<div style="margin: 15px 0 20px;">';
947 $html .= '<p>';
948 $html .= esc_html__( 'Extend wpLingua with additional features and advanced translation capabilities.', 'wplingua' );
949 $html .= '</p>';
950 $html .= '<p>';
951 $html .= esc_html__( 'Download and install wpLingua PRO to access the features included with your wpLingua plan.', 'wplingua' );
952 $html .= '</p>';
953 $html .= '</div>';
954 $html .= '<p>';
955 $html .= '<a';
956 $html .= ' href="https://wplingua.com/download/#pro"';
957 $html .= ' target="_blank"';
958 $html .= ' rel="noopener noreferrer"';
959 $html .= ' class="button button-primary"';
960 $html .= '>';
961 $html .= esc_html__( 'wpLingua.com : Download PRO plugin', 'wplingua' );
962 $html .= '</a>';
963 $html .= '</p>';
964
965 $html .= '</div>'; // End .notice
966
967 echo $html;
968 }
969 }
970 }
971