Version Description
(2020-04-06) =
- Minimum WordPress version is now 4.9
- Pro: Strings translations can now be exported and imported (in PO format)
- Pro: Allow to decide individually which ACF fields to copy or synchronize
- Pro: Add action pll_inactive_language_requested
- Pro; Fix fatal error in The Events Calendar compatibility when no language is defined yet
- Pro: Fix bulk translate when a post has no language
- Pro: Fix reusable block saved without language
- Pro: Fix post requested by slug not filtered in REST API, when the slug is shared
- Add a setup wizard
- Add Swahili, Upper Sorbian, Sindhi and Spanish from Uruguay to the list of predefined languages
- Add flags in the predefined list of languages
- Allow to hide the metaboxes from the screen options
- The deletion of the plugin's data at uninstall is now controlled by a PHP constant instead of an option #456
- Add parent in ajax response when selecting a term in autocomplete field #328
- Add Vary: Accept-Language http header in home page redirect. Props @chesio #452
- Improve performance to register/unregister WPML strings
- Add support for the action wpml_switch_language
- Add post_status to the list of accepted args of pll_count_posts()
- Apply the filter pll_preferred_language in wp-login.php
- Use filtered wrappers to create meta when creating media translations #231
- Allow to translate the Twenty Seventeen header video Youtube url #460
- Notices are now dismissed per site instead of per user #478
- Fix terms not visible in the quick edit when only one language is defined and teh admin language filter is active
- Fix post state not displayed for translations of the privacy policy page #395
- Fix wildcards not correctly interpreted in wpml-config.xml
- Fix product categories with special characters duplicated when importing WooCommerce products #474
Download this release
Release Info
Developer | Chouby |
Plugin | Polylang |
Version | 2.7 |
Comparing to | |
See all releases |
Code changes from version 2.6.10 to 2.7
- admin/admin-base.php +24 -2
- admin/admin-classic-editor.php +7 -7
- admin/admin-filters-columns.php +28 -15
- admin/admin-filters-post-base.php +2 -0
- admin/admin-filters-post.php +5 -2
- admin/admin-filters-term.php +36 -25
- admin/admin-filters.php +22 -0
- admin/admin-model.php +23 -8
- admin/admin-nav-menu.php +7 -7
- admin/admin-notices.php +81 -54
- admin/admin-static-pages.php +2 -2
- admin/admin-strings.php +0 -1
- admin/admin.php +16 -5
- admin/view-translations-media.php +2 -2
- css/admin.css +14 -2
- css/admin.min.css +1 -1
- css/selectmenu.css +29 -1
- css/selectmenu.min.css +1 -1
- frontend/choose-lang.php +18 -6
- frontend/frontend-auto-translate.php +4 -2
- frontend/frontend-filters-links.php +5 -1
- frontend/frontend-links.php +2 -3
- frontend/frontend-nav-menu.php +3 -3
- frontend/frontend.php +5 -3
- include/api.php +3 -3
- include/base.php +2 -2
- include/class-polylang.php +18 -4
- include/crud-posts.php +25 -21
- include/filters.php +3 -3
- include/functions.php +1 -48
- include/language.php +23 -10
- include/license.php +119 -1
- include/links-directory.php +9 -7
- include/links-domain.php +4 -9
- include/links-permalinks.php +1 -1
- include/links-subdomain.php +3 -1
- include/model.php +7 -5
- include/nav-menu.php +2 -0
- include/rest-request.php +5 -3
- include/switcher.php +4 -2
- include/translated-object.php +3 -2
- include/translated-term.php +4 -2
- include/walker-dropdown.php +2 -2
- include/widget-languages.php +1 -1
- install/install.php +2 -2
- install/upgrade.php +40 -6
- js/admin.js +260 -188
- js/admin.min.js +1 -1
- js/block-editor.js +194 -145
- js/block-editor.min.js +1 -1
- js/classic-editor.js +199 -149
- js/classic-editor.min.js +1 -1
- js/nav-menu.js +88 -61
- js/nav-menu.min.js +1 -1
- js/post.js +191 -128
- js/post.min.js +1 -1
- js/term.js +181 -145
- js/term.min.js +1 -1
- js/user.js +25 -18
- js/user.min.js +1 -1
- js/widgets.js +76 -66
- js/widgets.min.js +1 -1
- lingotek/lingotek.php +2 -4
- modules/plugins/featured-content.php +1 -1
- modules/plugins/plugins-compat.php +12 -4
- modules/plugins/wp-import.php +4 -0
- modules/sync/admin-sync.php +2 -2
- modules/sync/settings-sync.php +1 -1
- modules/sync/sync-metas.php +0 -2
- modules/sync/sync.php +0 -1
- modules/wpml/wpml-api.php +33 -3
- modules/wpml/wpml-compat.php +13 -17
- modules/wpml/wpml-config.php +43 -55
- modules/wpml/wpml-legacy-api.php +3 -3
- polylang.php +3 -3
- readme.txt +35 -5
- settings/languages.php +27 -0
- settings/settings-cpt.php +2 -0
- settings/settings-licenses.php +1 -103
- settings/settings-module.php +2 -0
- settings/settings-tools.php +0 -52
- settings/settings-url.php +2 -0
- settings/settings.php +29 -5
- settings/table-languages.php +0 -1
- settings/table-settings.php +5 -8
- settings/table-string.php +7 -4
- settings/view-languages.php +1 -1
- settings/view-tab-lang.php +9 -21
- settings/view-tab-strings.php +7 -0
- uninstall.php +12 -8
admin/admin-base.php
CHANGED
@@ -48,18 +48,27 @@ class PLL_Admin_Base extends PLL_Base {
|
|
48 |
public function init() {
|
49 |
parent::init();
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
if ( ! $this->model->get_languages_list() ) {
|
52 |
return;
|
53 |
}
|
54 |
|
55 |
-
$this->notices = new PLL_Admin_Notices( $this );
|
56 |
$this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
|
57 |
$this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ?
|
58 |
$this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
|
59 |
|
60 |
// Filter admin language for users
|
61 |
// We must not call user info before WordPress defines user roles in wp-settings.php
|
62 |
-
|
63 |
add_filter( 'request', array( $this, 'request' ) );
|
64 |
|
65 |
// Adds the languages in admin bar
|
@@ -78,6 +87,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
78 |
* @since 0.1
|
79 |
*/
|
80 |
public function add_menus() {
|
|
|
|
|
81 |
// Prepare the list of tabs
|
82 |
$tabs = array( 'lang' => __( 'Languages', 'polylang' ) );
|
83 |
|
@@ -97,11 +108,14 @@ class PLL_Admin_Base extends PLL_Base {
|
|
97 |
*/
|
98 |
$tabs = apply_filters( 'pll_settings_tabs', $tabs );
|
99 |
|
|
|
|
|
100 |
foreach ( $tabs as $tab => $title ) {
|
101 |
$page = 'lang' === $tab ? 'mlang' : "mlang_$tab";
|
102 |
if ( empty( $parent ) ) {
|
103 |
$parent = $page;
|
104 |
add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page, null, 'dashicons-translation' );
|
|
|
105 |
}
|
106 |
|
107 |
add_submenu_page( $parent, $title, $title, 'manage_options', $page, array( $this, 'languages_page' ) );
|
@@ -421,4 +435,12 @@ class PLL_Admin_Base extends PLL_Base {
|
|
421 |
);
|
422 |
}
|
423 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
}
|
48 |
public function init() {
|
49 |
parent::init();
|
50 |
|
51 |
+
$this->notices = new PLL_Admin_Notices( $this );
|
52 |
+
|
53 |
+
if ( Polylang::is_wizard() && class_exists( 'PLL_Wizard_Pro' ) ) {
|
54 |
+
// Instantiate PLL_Wizard_Pro class after all PLL_Admin object is all initialized.
|
55 |
+
// After PLL_Admin::maybe_load_sync_post which is hooked on admin_init with priority 20.
|
56 |
+
add_action( 'admin_init', array( $this, 'instantiate_wizard_pro' ), 30 );
|
57 |
+
}
|
58 |
+
|
59 |
+
$this->wizard = new PLL_Wizard( $this );
|
60 |
+
|
61 |
if ( ! $this->model->get_languages_list() ) {
|
62 |
return;
|
63 |
}
|
64 |
|
|
|
65 |
$this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
|
66 |
$this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ?
|
67 |
$this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
|
68 |
|
69 |
// Filter admin language for users
|
70 |
// We must not call user info before WordPress defines user roles in wp-settings.php
|
71 |
+
add_action( 'setup_theme', array( $this, 'init_user' ) );
|
72 |
add_filter( 'request', array( $this, 'request' ) );
|
73 |
|
74 |
// Adds the languages in admin bar
|
87 |
* @since 0.1
|
88 |
*/
|
89 |
public function add_menus() {
|
90 |
+
global $admin_page_hooks;
|
91 |
+
|
92 |
// Prepare the list of tabs
|
93 |
$tabs = array( 'lang' => __( 'Languages', 'polylang' ) );
|
94 |
|
108 |
*/
|
109 |
$tabs = apply_filters( 'pll_settings_tabs', $tabs );
|
110 |
|
111 |
+
$parent = '';
|
112 |
+
|
113 |
foreach ( $tabs as $tab => $title ) {
|
114 |
$page = 'lang' === $tab ? 'mlang' : "mlang_$tab";
|
115 |
if ( empty( $parent ) ) {
|
116 |
$parent = $page;
|
117 |
add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page, null, 'dashicons-translation' );
|
118 |
+
$admin_page_hooks[ $page ] = 'languages'; // Hack to avoid the localization of the hook name. See: https://core.trac.wordpress.org/ticket/18857
|
119 |
}
|
120 |
|
121 |
add_submenu_page( $parent, $title, $title, 'manage_options', $page, array( $this, 'languages_page' ) );
|
435 |
);
|
436 |
}
|
437 |
}
|
438 |
+
/**
|
439 |
+
* Instantiate PLL_Wizard_Pro class.
|
440 |
+
*
|
441 |
+
* @since 2.7
|
442 |
+
*/
|
443 |
+
public function instantiate_wizard_pro() {
|
444 |
+
$this->wizard_pro = new PLL_Wizard_Pro( $this );
|
445 |
+
}
|
446 |
}
|
admin/admin-classic-editor.php
CHANGED
@@ -66,10 +66,10 @@ class PLL_Admin_Classic_Editor {
|
|
66 |
*/
|
67 |
public function post_language() {
|
68 |
global $post_ID;
|
69 |
-
$post_id = $post_ID;
|
70 |
$post_type = get_post_type( $post_ID );
|
71 |
|
72 |
-
|
|
|
73 |
|
74 |
$lang = ( $lg = $this->model->post->get_language( $post_ID ) ) ? $lg :
|
75 |
( isset( $_GET['new_lang'] ) ? $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -130,9 +130,8 @@ class PLL_Admin_Classic_Editor {
|
|
130 |
}
|
131 |
|
132 |
global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
|
133 |
-
$
|
134 |
-
$lang
|
135 |
-
|
136 |
$post_type = sanitize_key( $_POST['post_type'] );
|
137 |
|
138 |
if ( ! post_type_exists( $post_type ) ) {
|
@@ -159,8 +158,9 @@ class PLL_Admin_Classic_Editor {
|
|
159 |
ob_end_clean();
|
160 |
|
161 |
// Categories
|
162 |
-
if ( isset( $_POST['taxonomies'] ) ) {
|
163 |
-
|
|
|
164 |
foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
|
165 |
$taxonomy = get_taxonomy( $taxname );
|
166 |
|
66 |
*/
|
67 |
public function post_language() {
|
68 |
global $post_ID;
|
|
|
69 |
$post_type = get_post_type( $post_ID );
|
70 |
|
71 |
+
// phpcs:ignore WordPress.Security.NonceVerification, WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
|
72 |
+
$from_post_id = isset( $_GET['from_post'] ) ? (int) $_GET['from_post'] : 0;
|
73 |
|
74 |
$lang = ( $lg = $this->model->post->get_language( $post_ID ) ) ? $lg :
|
75 |
( isset( $_GET['new_lang'] ) ? $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification
|
130 |
}
|
131 |
|
132 |
global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
|
133 |
+
$post_ID = (int) $_POST['post_id'];
|
134 |
+
$lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
|
|
|
135 |
$post_type = sanitize_key( $_POST['post_type'] );
|
136 |
|
137 |
if ( ! post_type_exists( $post_type ) ) {
|
158 |
ob_end_clean();
|
159 |
|
160 |
// Categories
|
161 |
+
if ( isset( $_POST['taxonomies'] ) ) { // Not set for pages
|
162 |
+
$supplemental = array();
|
163 |
+
|
164 |
foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
|
165 |
$taxonomy = get_taxonomy( $taxname );
|
166 |
|
admin/admin-filters-columns.php
CHANGED
@@ -21,25 +21,28 @@ class PLL_Admin_Filters_Columns {
|
|
21 |
$this->model = &$polylang->model;
|
22 |
$this->filter_lang = &$polylang->filter_lang;
|
23 |
|
24 |
-
//
|
|
|
|
|
|
|
25 |
foreach ( $this->model->get_translated_post_types() as $type ) {
|
26 |
// Use the latest filter late as some plugins purely overwrite what's done by others :(
|
27 |
-
// Specific case for media
|
28 |
add_filter( 'manage_' . ( 'attachment' == $type ? 'upload' : 'edit-' . $type ) . '_columns', array( $this, 'add_post_column' ), 100 );
|
29 |
add_action( 'manage_' . ( 'attachment' == $type ? 'media' : $type . '_posts' ) . '_custom_column', array( $this, 'post_column' ), 10, 2 );
|
30 |
}
|
31 |
|
32 |
-
// Quick edit and bulk edit
|
33 |
add_filter( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
|
34 |
add_filter( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
|
35 |
|
36 |
-
// Adds the language column in the 'Categories' and 'Post Tags' tables
|
37 |
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
38 |
add_filter( 'manage_edit-' . $tax . '_columns', array( $this, 'add_term_column' ) );
|
39 |
add_filter( 'manage_' . $tax . '_custom_column', array( $this, 'term_column' ), 10, 3 );
|
40 |
}
|
41 |
|
42 |
-
// Ajax responses to update list table rows
|
43 |
add_action( 'wp_ajax_pll_update_post_rows', array( $this, 'ajax_update_post_rows' ) );
|
44 |
add_action( 'wp_ajax_pll_update_term_rows', array( $this, 'ajax_update_term_rows' ) );
|
45 |
}
|
@@ -60,10 +63,7 @@ class PLL_Admin_Filters_Columns {
|
|
60 |
}
|
61 |
|
62 |
foreach ( $this->model->get_languages_list() as $language ) {
|
63 |
-
|
64 |
-
if ( empty( $this->filter_lang ) || $language->slug != $this->filter_lang->slug ) {
|
65 |
-
$columns[ 'language_' . $language->slug ] = $language->flag ? $language->flag . '<span class="screen-reader-text">' . esc_html( $language->name ) . '</span>' : esc_html( $language->slug );
|
66 |
-
}
|
67 |
}
|
68 |
|
69 |
return isset( $end ) ? array_merge( $columns, $end ) : $columns;
|
@@ -77,15 +77,30 @@ class PLL_Admin_Filters_Columns {
|
|
77 |
* @return string first language column name
|
78 |
*/
|
79 |
protected function get_first_language_column() {
|
|
|
|
|
80 |
foreach ( $this->model->get_languages_list() as $language ) {
|
81 |
-
|
82 |
-
$columns[] = 'language_' . $language->slug;
|
83 |
-
}
|
84 |
}
|
85 |
|
86 |
return empty( $columns ) ? '' : reset( $columns );
|
87 |
}
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
/**
|
90 |
* Adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables
|
91 |
*
|
@@ -122,8 +137,6 @@ class PLL_Admin_Filters_Columns {
|
|
122 |
printf( '<div class="hidden" id="lang_%d">%s</div>', intval( $post_id ), esc_html( $lang->slug ) );
|
123 |
}
|
124 |
|
125 |
-
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
126 |
-
|
127 |
// Link to edit post ( or a translation )
|
128 |
if ( $id = $this->model->post->get( $post_id, $language ) ) {
|
129 |
// get_edit_post_link returns nothing if the user cannot edit the post
|
@@ -273,7 +286,7 @@ class PLL_Admin_Filters_Columns {
|
|
273 |
esc_html( $s )
|
274 |
);
|
275 |
} elseif ( $id === $term_id ) {
|
276 |
-
$out .=
|
277 |
'<span class="pll_icon_tick"><span class="screen-reader-text">%s</span></span>',
|
278 |
/* translators: accessibility text, %s is a native language name */
|
279 |
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) )
|
21 |
$this->model = &$polylang->model;
|
22 |
$this->filter_lang = &$polylang->filter_lang;
|
23 |
|
24 |
+
// Hide the column of the filtered language.
|
25 |
+
add_filter( 'hidden_columns', array( $this, 'hidden_columns' ) ); // Since WP 4.4.
|
26 |
+
|
27 |
+
// Add the language and translations columns in 'All Posts', 'All Pages' and 'Media library' panels.
|
28 |
foreach ( $this->model->get_translated_post_types() as $type ) {
|
29 |
// Use the latest filter late as some plugins purely overwrite what's done by others :(
|
30 |
+
// Specific case for media.
|
31 |
add_filter( 'manage_' . ( 'attachment' == $type ? 'upload' : 'edit-' . $type ) . '_columns', array( $this, 'add_post_column' ), 100 );
|
32 |
add_action( 'manage_' . ( 'attachment' == $type ? 'media' : $type . '_posts' ) . '_custom_column', array( $this, 'post_column' ), 10, 2 );
|
33 |
}
|
34 |
|
35 |
+
// Quick edit and bulk edit.
|
36 |
add_filter( 'quick_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
|
37 |
add_filter( 'bulk_edit_custom_box', array( $this, 'quick_edit_custom_box' ), 10, 2 );
|
38 |
|
39 |
+
// Adds the language column in the 'Categories' and 'Post Tags' tables.
|
40 |
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
41 |
add_filter( 'manage_edit-' . $tax . '_columns', array( $this, 'add_term_column' ) );
|
42 |
add_filter( 'manage_' . $tax . '_custom_column', array( $this, 'term_column' ), 10, 3 );
|
43 |
}
|
44 |
|
45 |
+
// Ajax responses to update list table rows.
|
46 |
add_action( 'wp_ajax_pll_update_post_rows', array( $this, 'ajax_update_post_rows' ) );
|
47 |
add_action( 'wp_ajax_pll_update_term_rows', array( $this, 'ajax_update_term_rows' ) );
|
48 |
}
|
63 |
}
|
64 |
|
65 |
foreach ( $this->model->get_languages_list() as $language ) {
|
66 |
+
$columns[ 'language_' . $language->slug ] = $language->flag ? $language->flag . '<span class="screen-reader-text">' . esc_html( $language->name ) . '</span>' : esc_html( $language->slug );
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
return isset( $end ) ? array_merge( $columns, $end ) : $columns;
|
77 |
* @return string first language column name
|
78 |
*/
|
79 |
protected function get_first_language_column() {
|
80 |
+
$columns = array();
|
81 |
+
|
82 |
foreach ( $this->model->get_languages_list() as $language ) {
|
83 |
+
$columns[] = 'language_' . $language->slug;
|
|
|
|
|
84 |
}
|
85 |
|
86 |
return empty( $columns ) ? '' : reset( $columns );
|
87 |
}
|
88 |
|
89 |
+
/**
|
90 |
+
* Hide the column for the filtered language
|
91 |
+
*
|
92 |
+
* @since 2.7
|
93 |
+
*
|
94 |
+
* @param array $hidden Array of hidden columns
|
95 |
+
* @return array
|
96 |
+
*/
|
97 |
+
public function hidden_columns( $hidden ) {
|
98 |
+
if ( ! empty( $this->filter_lang ) ) {
|
99 |
+
$hidden[] = 'language_' . $this->filter_lang->slug;
|
100 |
+
}
|
101 |
+
return $hidden;
|
102 |
+
}
|
103 |
+
|
104 |
/**
|
105 |
* Adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables
|
106 |
*
|
137 |
printf( '<div class="hidden" id="lang_%d">%s</div>', intval( $post_id ), esc_html( $lang->slug ) );
|
138 |
}
|
139 |
|
|
|
|
|
140 |
// Link to edit post ( or a translation )
|
141 |
if ( $id = $this->model->post->get( $post_id, $language ) ) {
|
142 |
// get_edit_post_link returns nothing if the user cannot edit the post
|
286 |
esc_html( $s )
|
287 |
);
|
288 |
} elseif ( $id === $term_id ) {
|
289 |
+
$out .= sprintf(
|
290 |
'<span class="pll_icon_tick"><span class="screen-reader-text">%s</span></span>',
|
291 |
/* translators: accessibility text, %s is a native language name */
|
292 |
esc_html( sprintf( __( 'This item is in %s', 'polylang' ), $language->name ) )
|
admin/admin-filters-post-base.php
CHANGED
@@ -34,6 +34,8 @@ abstract class PLL_Admin_Filters_Post_Base {
|
|
34 |
// Security check as 'wp_insert_post' can be called from outside WP admin
|
35 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
36 |
|
|
|
|
|
37 |
// Save translations after checking the translated post is in the right language
|
38 |
foreach ( $arr as $lang => $tr_id ) {
|
39 |
$translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
|
34 |
// Security check as 'wp_insert_post' can be called from outside WP admin
|
35 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
36 |
|
37 |
+
$translations = array();
|
38 |
+
|
39 |
// Save translations after checking the translated post is in the right language
|
40 |
foreach ( $arr as $lang => $tr_id ) {
|
41 |
$translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
|
admin/admin-filters-post.php
CHANGED
@@ -47,6 +47,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
47 |
// Hierarchical taxonomies
|
48 |
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'object' ) ) {
|
49 |
// Get translated hierarchical taxonomies
|
|
|
50 |
foreach ( $taxonomies as $taxonomy ) {
|
51 |
if ( $taxonomy->hierarchical && $taxonomy->show_in_quick_edit && $this->model->is_translated_taxonomy( $taxonomy->name ) ) {
|
52 |
$hierarchical_taxonomies[] = $taxonomy->name;
|
@@ -54,7 +55,8 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
54 |
}
|
55 |
|
56 |
if ( ! empty( $hierarchical_taxonomies ) ) {
|
57 |
-
$terms
|
|
|
58 |
|
59 |
foreach ( $terms as $term ) {
|
60 |
if ( $lang = $this->model->term->get_language( $term->term_id ) ) {
|
@@ -71,7 +73,8 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
71 |
|
72 |
// Hierarchical post types
|
73 |
if ( 'edit' == $screen->base && is_post_type_hierarchical( $screen->post_type ) ) {
|
74 |
-
$pages
|
|
|
75 |
|
76 |
foreach ( $pages as $page ) {
|
77 |
if ( $lang = $this->model->post->get_language( $page->ID ) ) {
|
47 |
// Hierarchical taxonomies
|
48 |
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'object' ) ) {
|
49 |
// Get translated hierarchical taxonomies
|
50 |
+
$hierarchical_taxonomies = array();
|
51 |
foreach ( $taxonomies as $taxonomy ) {
|
52 |
if ( $taxonomy->hierarchical && $taxonomy->show_in_quick_edit && $this->model->is_translated_taxonomy( $taxonomy->name ) ) {
|
53 |
$hierarchical_taxonomies[] = $taxonomy->name;
|
55 |
}
|
56 |
|
57 |
if ( ! empty( $hierarchical_taxonomies ) ) {
|
58 |
+
$terms = get_terms( $hierarchical_taxonomies, array( 'get' => 'all' ) );
|
59 |
+
$term_languages = array();
|
60 |
|
61 |
foreach ( $terms as $term ) {
|
62 |
if ( $lang = $this->model->term->get_language( $term->term_id ) ) {
|
73 |
|
74 |
// Hierarchical post types
|
75 |
if ( 'edit' == $screen->base && is_post_type_hierarchical( $screen->post_type ) ) {
|
76 |
+
$pages = get_pages();
|
77 |
+
$page_languages = array();
|
78 |
|
79 |
foreach ( $pages as $page ) {
|
80 |
if ( $lang = $this->model->post->get_language( $page->ID ) ) {
|
admin/admin-filters-term.php
CHANGED
@@ -133,8 +133,8 @@ class PLL_Admin_Filters_Term {
|
|
133 |
return;
|
134 |
}
|
135 |
|
136 |
-
$term_id
|
137 |
-
$taxonomy = $tag->taxonomy;
|
138 |
|
139 |
$lang = $this->model->term->get_language( $term_id );
|
140 |
$lang = empty( $lang ) ? $this->pref_lang : $lang;
|
@@ -271,8 +271,10 @@ class PLL_Admin_Filters_Term {
|
|
271 |
|
272 |
// If we have several terms with the same name, they are translations of each other
|
273 |
if ( count( $terms ) > 1 ) {
|
|
|
|
|
274 |
foreach ( $terms as $term ) {
|
275 |
-
|
276 |
}
|
277 |
|
278 |
$this->model->term->save_translations( $term_id, $translations );
|
@@ -368,7 +370,7 @@ class PLL_Admin_Filters_Term {
|
|
368 |
$this->save_language( $term_id, $taxonomy );
|
369 |
|
370 |
if ( isset( $_POST['term_tr_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
371 |
-
$
|
372 |
}
|
373 |
}
|
374 |
}
|
@@ -433,9 +435,9 @@ class PLL_Admin_Filters_Term {
|
|
433 |
wp_die( 0 );
|
434 |
}
|
435 |
|
436 |
-
$lang
|
437 |
-
$term_id
|
438 |
-
$taxonomy
|
439 |
$post_type = sanitize_key( $_POST['post_type'] );
|
440 |
|
441 |
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
@@ -502,7 +504,7 @@ class PLL_Admin_Filters_Term {
|
|
502 |
|
503 |
$s = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
504 |
$post_type = sanitize_key( $_GET['post_type'] );
|
505 |
-
$taxonomy
|
506 |
|
507 |
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
508 |
wp_die( 0 );
|
@@ -511,32 +513,40 @@ class PLL_Admin_Filters_Term {
|
|
511 |
$term_language = $this->model->get_language( sanitize_key( $_GET['term_language'] ) );
|
512 |
$translation_language = $this->model->get_language( sanitize_key( $_GET['translation_language'] ) );
|
513 |
|
|
|
514 |
$return = array();
|
515 |
|
516 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
517 |
foreach ( get_terms( $taxonomy, 'hide_empty=0&lang=0&name__like=' . $s ) as $term ) {
|
518 |
$lang = $this->model->term->get_language( $term->term_id );
|
519 |
|
520 |
if ( $lang && $lang->slug == $translation_language->slug && ! $this->model->term->get_translation( $term->term_id, $term_language ) ) {
|
521 |
-
$
|
522 |
-
'id' => $term->term_id,
|
523 |
-
'value' => $term->name,
|
524 |
-
'link' => $this->links->edit_term_translation_link( $term->term_id, $taxonomy, $post_type ),
|
525 |
-
);
|
526 |
}
|
527 |
}
|
528 |
|
529 |
-
//
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
|
|
|
|
|
|
|
|
|
|
540 |
);
|
541 |
}
|
542 |
|
@@ -607,6 +617,7 @@ class PLL_Admin_Filters_Term {
|
|
607 |
|
608 |
$avoid_recursion = true;
|
609 |
$lang = $this->model->term->get_language( $term_id );
|
|
|
610 |
|
611 |
foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
|
612 |
if ( $lang->slug == $key ) {
|
133 |
return;
|
134 |
}
|
135 |
|
136 |
+
$term_id = $tag->term_id;
|
137 |
+
$taxonomy = $tag->taxonomy; // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
|
138 |
|
139 |
$lang = $this->model->term->get_language( $term_id );
|
140 |
$lang = empty( $lang ) ? $this->pref_lang : $lang;
|
271 |
|
272 |
// If we have several terms with the same name, they are translations of each other
|
273 |
if ( count( $terms ) > 1 ) {
|
274 |
+
$translations = array();
|
275 |
+
|
276 |
foreach ( $terms as $term ) {
|
277 |
+
$translations[ $this->model->term->get_language( $term->term_id )->slug ] = $term->term_id;
|
278 |
}
|
279 |
|
280 |
$this->model->term->save_translations( $term_id, $translations );
|
370 |
$this->save_language( $term_id, $taxonomy );
|
371 |
|
372 |
if ( isset( $_POST['term_tr_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
373 |
+
$this->save_translations( $term_id );
|
374 |
}
|
375 |
}
|
376 |
}
|
435 |
wp_die( 0 );
|
436 |
}
|
437 |
|
438 |
+
$lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
|
439 |
+
$term_id = isset( $_POST['term_id'] ) ? (int) $_POST['term_id'] : null; // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
|
440 |
+
$taxonomy = sanitize_key( $_POST['taxonomy'] ); // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
|
441 |
$post_type = sanitize_key( $_POST['post_type'] );
|
442 |
|
443 |
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
504 |
|
505 |
$s = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
506 |
$post_type = sanitize_key( $_GET['post_type'] );
|
507 |
+
$taxonomy = sanitize_key( $_GET['taxonomy'] );
|
508 |
|
509 |
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
510 |
wp_die( 0 );
|
513 |
$term_language = $this->model->get_language( sanitize_key( $_GET['term_language'] ) );
|
514 |
$translation_language = $this->model->get_language( sanitize_key( $_GET['translation_language'] ) );
|
515 |
|
516 |
+
$terms = array();
|
517 |
$return = array();
|
518 |
|
519 |
+
// Add current translation in list.
|
520 |
+
// Not in add term as term_id is not set.
|
521 |
+
if ( isset( $_GET['term_id'] ) && 'undefined' !== $_GET['term_id'] && $term_id = $this->model->term->get_translation( (int) $_GET['term_id'], $translation_language ) ) {
|
522 |
+
$terms = array( get_term( $term_id, $taxonomy ) );
|
523 |
+
}
|
524 |
+
|
525 |
+
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
526 |
foreach ( get_terms( $taxonomy, 'hide_empty=0&lang=0&name__like=' . $s ) as $term ) {
|
527 |
$lang = $this->model->term->get_language( $term->term_id );
|
528 |
|
529 |
if ( $lang && $lang->slug == $translation_language->slug && ! $this->model->term->get_translation( $term->term_id, $term_language ) ) {
|
530 |
+
$terms[] = $term;
|
|
|
|
|
|
|
|
|
531 |
}
|
532 |
}
|
533 |
|
534 |
+
// Format the ajax response.
|
535 |
+
foreach ( $terms as $term ) {
|
536 |
+
$return[] = array(
|
537 |
+
'id' => $term->term_id,
|
538 |
+
'value' => rtrim( // Trim the seperator added at the end by WP.
|
539 |
+
get_term_parents_list(
|
540 |
+
$term->term_id,
|
541 |
+
$term->taxonomy,
|
542 |
+
array(
|
543 |
+
'separator' => ' > ',
|
544 |
+
'link' => false,
|
545 |
+
)
|
546 |
+
),
|
547 |
+
' >'
|
548 |
+
),
|
549 |
+
'link' => $this->links->edit_term_translation_link( $term->term_id, $term->taxonomy, $post_type ),
|
550 |
);
|
551 |
}
|
552 |
|
617 |
|
618 |
$avoid_recursion = true;
|
619 |
$lang = $this->model->term->get_language( $term_id );
|
620 |
+
$translations = array();
|
621 |
|
622 |
foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
|
623 |
if ( $lang->slug == $key ) {
|
admin/admin-filters.php
CHANGED
@@ -42,6 +42,9 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
42 |
}
|
43 |
|
44 |
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
|
|
|
|
|
|
45 |
}
|
46 |
|
47 |
/**
|
@@ -265,4 +268,23 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
265 |
}
|
266 |
return $classes;
|
267 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
}
|
42 |
}
|
43 |
|
44 |
add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
|
45 |
+
|
46 |
+
// Add post state for translations of the privacy policy page
|
47 |
+
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
48 |
}
|
49 |
|
50 |
/**
|
268 |
}
|
269 |
return $classes;
|
270 |
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Add post state for translations of the privacy policy page
|
274 |
+
*
|
275 |
+
* @since 2.7
|
276 |
+
*
|
277 |
+
* @param array $post_states An array of post display states.
|
278 |
+
* @param object $post The current post object.
|
279 |
+
* @return array
|
280 |
+
*/
|
281 |
+
public function display_post_states( $post_states, $post ) {
|
282 |
+
$page_for_privacy_policy = get_option( 'wp_page_for_privacy_policy' );
|
283 |
+
|
284 |
+
if ( $page_for_privacy_policy && in_array( $post->ID, $this->model->post->get_translations( $page_for_privacy_policy ) ) ) {
|
285 |
+
$post_states['page_for_privacy_policy'] = __( 'Privacy Policy Page', 'polylang' );
|
286 |
+
}
|
287 |
+
|
288 |
+
return $post_states;
|
289 |
+
}
|
290 |
}
|
admin/admin-model.php
CHANGED
@@ -125,7 +125,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
125 |
// Delete menus locations
|
126 |
if ( ! empty( $this->options['nav_menus'] ) ) {
|
127 |
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
128 |
-
foreach ( $locations as $location
|
129 |
unset( $this->options['nav_menus'][ $theme ][ $location ][ $lang->slug ] );
|
130 |
}
|
131 |
}
|
@@ -211,7 +211,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
211 |
// Update menus locations
|
212 |
if ( ! empty( $this->options['nav_menus'] ) ) {
|
213 |
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
214 |
-
foreach ( $locations as $location
|
215 |
if ( ! empty( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] ) ) {
|
216 |
$this->options['nav_menus'][ $theme ][ $location ][ $slug ] = $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ];
|
217 |
unset( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] );
|
@@ -318,9 +318,10 @@ class PLL_Admin_Model extends PLL_Model {
|
|
318 |
public function set_language_in_mass( $type, $ids, $lang ) {
|
319 |
global $wpdb;
|
320 |
|
321 |
-
$ids
|
322 |
-
$lang
|
323 |
-
$tt_id
|
|
|
324 |
|
325 |
foreach ( $ids as $id ) {
|
326 |
$values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
|
@@ -334,6 +335,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
334 |
|
335 |
if ( 'term' === $type ) {
|
336 |
clean_term_cache( $ids, 'term_language' );
|
|
|
337 |
|
338 |
foreach ( $ids as $id ) {
|
339 |
$translations[] = array( $lang->slug => $id );
|
@@ -358,7 +360,11 @@ class PLL_Admin_Model extends PLL_Model {
|
|
358 |
public function set_translation_in_mass( $type, $translations ) {
|
359 |
global $wpdb;
|
360 |
|
361 |
-
$taxonomy
|
|
|
|
|
|
|
|
|
362 |
|
363 |
foreach ( $translations as $t ) {
|
364 |
$term = uniqid( 'pll_' ); // the term name
|
@@ -376,7 +382,9 @@ class PLL_Admin_Model extends PLL_Model {
|
|
376 |
|
377 |
// Get all terms with their term_id
|
378 |
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
379 |
-
$terms
|
|
|
|
|
380 |
|
381 |
// Prepare terms taxonomy relationship
|
382 |
foreach ( $terms as $term ) {
|
@@ -392,6 +400,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
392 |
|
393 |
// Get all terms with term_taxonomy_id
|
394 |
$terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
|
|
|
395 |
|
396 |
// Prepare objects relationships
|
397 |
foreach ( $terms as $term ) {
|
@@ -492,7 +501,11 @@ class PLL_Admin_Model extends PLL_Model {
|
|
492 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
493 |
global $wpdb;
|
494 |
|
495 |
-
$terms
|
|
|
|
|
|
|
|
|
496 |
|
497 |
foreach ( $terms as $term ) {
|
498 |
$term_ids[ $term->taxonomy ][] = $term->term_id;
|
@@ -563,6 +576,8 @@ class PLL_Admin_Model extends PLL_Model {
|
|
563 |
// The nav menus stored in theme locations should be in the default language
|
564 |
$theme = get_stylesheet();
|
565 |
if ( ! empty( $this->options['nav_menus'][ $theme ] ) ) {
|
|
|
|
|
566 |
foreach ( $this->options['nav_menus'][ $theme ] as $key => $loc ) {
|
567 |
$menus[ $key ] = empty( $loc[ $slug ] ) ? 0 : $loc[ $slug ];
|
568 |
}
|
125 |
// Delete menus locations
|
126 |
if ( ! empty( $this->options['nav_menus'] ) ) {
|
127 |
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
128 |
+
foreach ( array_keys( $locations ) as $location ) {
|
129 |
unset( $this->options['nav_menus'][ $theme ][ $location ][ $lang->slug ] );
|
130 |
}
|
131 |
}
|
211 |
// Update menus locations
|
212 |
if ( ! empty( $this->options['nav_menus'] ) ) {
|
213 |
foreach ( $this->options['nav_menus'] as $theme => $locations ) {
|
214 |
+
foreach ( array_keys( $locations ) as $location ) {
|
215 |
if ( ! empty( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] ) ) {
|
216 |
$this->options['nav_menus'][ $theme ][ $location ][ $slug ] = $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ];
|
217 |
unset( $this->options['nav_menus'][ $theme ][ $location ][ $old_slug ] );
|
318 |
public function set_language_in_mass( $type, $ids, $lang ) {
|
319 |
global $wpdb;
|
320 |
|
321 |
+
$ids = array_map( 'intval', $ids );
|
322 |
+
$lang = $this->get_language( $lang );
|
323 |
+
$tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
324 |
+
$values = array();
|
325 |
|
326 |
foreach ( $ids as $id ) {
|
327 |
$values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
|
335 |
|
336 |
if ( 'term' === $type ) {
|
337 |
clean_term_cache( $ids, 'term_language' );
|
338 |
+
$translations = array();
|
339 |
|
340 |
foreach ( $ids as $id ) {
|
341 |
$translations[] = array( $lang->slug => $id );
|
360 |
public function set_translation_in_mass( $type, $translations ) {
|
361 |
global $wpdb;
|
362 |
|
363 |
+
$taxonomy = $type . '_translations';
|
364 |
+
$terms = array();
|
365 |
+
$slugs = array();
|
366 |
+
$description = array();
|
367 |
+
$count = array();
|
368 |
|
369 |
foreach ( $translations as $t ) {
|
370 |
$term = uniqid( 'pll_' ); // the term name
|
382 |
|
383 |
// Get all terms with their term_id
|
384 |
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
385 |
+
$terms = $wpdb->get_results( "SELECT term_id, slug FROM {$wpdb->terms} WHERE slug IN ( " . implode( ',', $slugs ) . ' )' );
|
386 |
+
$term_ids = array();
|
387 |
+
$tts = array();
|
388 |
|
389 |
// Prepare terms taxonomy relationship
|
390 |
foreach ( $terms as $term ) {
|
400 |
|
401 |
// Get all terms with term_taxonomy_id
|
402 |
$terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
|
403 |
+
$trs = array();
|
404 |
|
405 |
// Prepare objects relationships
|
406 |
foreach ( $terms as $term ) {
|
501 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
502 |
global $wpdb;
|
503 |
|
504 |
+
$terms = get_terms( array( 'post_translations', 'term_translations' ) );
|
505 |
+
$term_ids = array();
|
506 |
+
$dr = array();
|
507 |
+
$dt = array();
|
508 |
+
$ut = array();
|
509 |
|
510 |
foreach ( $terms as $term ) {
|
511 |
$term_ids[ $term->taxonomy ][] = $term->term_id;
|
576 |
// The nav menus stored in theme locations should be in the default language
|
577 |
$theme = get_stylesheet();
|
578 |
if ( ! empty( $this->options['nav_menus'][ $theme ] ) ) {
|
579 |
+
$menus = array();
|
580 |
+
|
581 |
foreach ( $this->options['nav_menus'][ $theme ] as $key => $loc ) {
|
582 |
$menus[ $key ] = empty( $loc[ $slug ] ) ? 0 : $loc[ $slug ];
|
583 |
}
|
admin/admin-nav-menu.php
CHANGED
@@ -94,8 +94,11 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
94 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
95 |
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/nav-menu' . $suffix . '.js', POLYLANG_FILE ), array( 'jquery' ), POLYLANG_VERSION );
|
96 |
|
97 |
-
$data
|
98 |
-
|
|
|
|
|
|
|
99 |
|
100 |
// Get all language switcher menu items
|
101 |
$items = get_posts(
|
@@ -109,7 +112,6 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
109 |
);
|
110 |
|
111 |
// The options values for the language switcher
|
112 |
-
$data['val'] = array();
|
113 |
foreach ( $items as $item ) {
|
114 |
$data['val'][ $item ] = get_post_meta( $item, '_pll_menu_item', true );
|
115 |
}
|
@@ -143,7 +145,7 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
143 |
}
|
144 |
}
|
145 |
else {
|
146 |
-
foreach ( $options as $opt
|
147 |
$options[ $opt ] = empty( $_POST[ 'menu-item-' . $opt ][ $menu_item_db_id ] ) ? 0 : 1;
|
148 |
}
|
149 |
update_post_meta( $menu_item_db_id, '_pll_menu_item', $options ); // Allow us to easily identify our nav menu item
|
@@ -160,8 +162,6 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
160 |
* @return array
|
161 |
*/
|
162 |
public function update_nav_menu_locations( $locations ) {
|
163 |
-
$default = $this->options['default_lang'];
|
164 |
-
|
165 |
// Extract language and menu from locations
|
166 |
foreach ( $locations as $loc => $menu ) {
|
167 |
$infos = $this->explode_location( $loc );
|
@@ -232,7 +232,7 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
232 |
}
|
233 |
|
234 |
if ( is_array( $menus ) ) {
|
235 |
-
foreach ( $menus as $loc
|
236 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
237 |
if ( ! empty( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ] ) && term_exists( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ], 'nav_menu' ) ) {
|
238 |
$menus[ $this->combine_location( $loc, $lang ) ] = $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ];
|
94 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
95 |
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/nav-menu' . $suffix . '.js', POLYLANG_FILE ), array( 'jquery' ), POLYLANG_VERSION );
|
96 |
|
97 |
+
$data = array(
|
98 |
+
'strings' => PLL_Switcher::get_switcher_options( 'menu', 'string' ), // The strings for the options
|
99 |
+
'title' => __( 'Languages', 'polylang' ), // The title
|
100 |
+
'val' => array(),
|
101 |
+
);
|
102 |
|
103 |
// Get all language switcher menu items
|
104 |
$items = get_posts(
|
112 |
);
|
113 |
|
114 |
// The options values for the language switcher
|
|
|
115 |
foreach ( $items as $item ) {
|
116 |
$data['val'][ $item ] = get_post_meta( $item, '_pll_menu_item', true );
|
117 |
}
|
145 |
}
|
146 |
}
|
147 |
else {
|
148 |
+
foreach ( array_keys( $options ) as $opt ) {
|
149 |
$options[ $opt ] = empty( $_POST[ 'menu-item-' . $opt ][ $menu_item_db_id ] ) ? 0 : 1;
|
150 |
}
|
151 |
update_post_meta( $menu_item_db_id, '_pll_menu_item', $options ); // Allow us to easily identify our nav menu item
|
162 |
* @return array
|
163 |
*/
|
164 |
public function update_nav_menu_locations( $locations ) {
|
|
|
|
|
165 |
// Extract language and menu from locations
|
166 |
foreach ( $locations as $loc => $menu ) {
|
167 |
$infos = $this->explode_location( $loc );
|
232 |
}
|
233 |
|
234 |
if ( is_array( $menus ) ) {
|
235 |
+
foreach ( array_keys( $menus ) as $loc ) {
|
236 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
237 |
if ( ! empty( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ] ) && term_exists( $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ], 'nav_menu' ) ) {
|
238 |
$menus[ $this->combine_location( $loc, $lang ) ] = $this->options['nav_menus'][ $this->theme ][ $loc ][ $lang->slug ];
|
admin/admin-notices.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* and only on dashboard, plugins and Polylang admin pages
|
7 |
*
|
8 |
* @since 2.3.9
|
|
|
9 |
*/
|
10 |
class PLL_Admin_Notices {
|
11 |
private static $notices = array();
|
@@ -57,8 +58,22 @@ class PLL_Admin_Notices {
|
|
57 |
* @return bool
|
58 |
*/
|
59 |
public static function is_dismissed( $notice ) {
|
60 |
-
$dismissed =
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
|
64 |
/**
|
@@ -66,21 +81,34 @@ class PLL_Admin_Notices {
|
|
66 |
*
|
67 |
* @since 2.3.9
|
68 |
*
|
|
|
69 |
* @return bool
|
70 |
*/
|
71 |
-
protected function can_display_notice() {
|
72 |
$screen = get_current_screen();
|
73 |
$screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
);
|
85 |
}
|
86 |
|
@@ -92,13 +120,11 @@ class PLL_Admin_Notices {
|
|
92 |
* @param string $notice
|
93 |
*/
|
94 |
public static function dismiss( $notice ) {
|
95 |
-
|
96 |
-
$dismissed = array();
|
97 |
-
}
|
98 |
|
99 |
if ( ! in_array( $notice, $dismissed ) ) {
|
100 |
$dismissed[] = $notice;
|
101 |
-
|
102 |
}
|
103 |
}
|
104 |
|
@@ -123,14 +149,19 @@ class PLL_Admin_Notices {
|
|
123 |
* @since 2.3.9
|
124 |
*/
|
125 |
public function display_notices() {
|
126 |
-
if ( current_user_can( 'manage_options' )
|
127 |
// Core notices
|
128 |
-
$this->
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
// Custom notices
|
132 |
foreach ( $this->get_notices() as $notice => $html ) {
|
133 |
-
if ( ! $this->is_dismissed( $notice ) ) {
|
134 |
?>
|
135 |
<div class="pll-notice notice notice-info">
|
136 |
<?php
|
@@ -166,23 +197,21 @@ class PLL_Admin_Notices {
|
|
166 |
* @since 2.3.9
|
167 |
*/
|
168 |
private function pllwc_notice() {
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
<?php
|
185 |
-
}
|
186 |
}
|
187 |
|
188 |
/**
|
@@ -191,22 +220,20 @@ class PLL_Admin_Notices {
|
|
191 |
* @since 2.3.9
|
192 |
*/
|
193 |
private function review_notice() {
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
<?php
|
210 |
-
}
|
211 |
}
|
212 |
}
|
6 |
* and only on dashboard, plugins and Polylang admin pages
|
7 |
*
|
8 |
* @since 2.3.9
|
9 |
+
* @since 2.7 Dismissed notices are stored in an option instead of a user meta
|
10 |
*/
|
11 |
class PLL_Admin_Notices {
|
12 |
private static $notices = array();
|
58 |
* @return bool
|
59 |
*/
|
60 |
public static function is_dismissed( $notice ) {
|
61 |
+
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
62 |
+
|
63 |
+
// Handle legacy user meta
|
64 |
+
$dismissed_meta = get_user_meta( get_current_user_id(), 'pll_dismissed_notices', true );
|
65 |
+
if ( is_array( $dismissed_meta ) ) {
|
66 |
+
if ( array_diff( $dismissed_meta, $dismissed ) ) {
|
67 |
+
$dismissed = array_merge( $dismissed, $dismissed_meta );
|
68 |
+
update_option( 'pll_dismissed_notices', $dismissed );
|
69 |
+
}
|
70 |
+
if ( ! is_multisite() ) {
|
71 |
+
// Don't delete on multisite to avoid the notices to appear in other sites.
|
72 |
+
delete_user_meta( get_current_user_id(), 'pll_dismissed_notices' );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
return in_array( $notice, $dismissed );
|
77 |
}
|
78 |
|
79 |
/**
|
81 |
*
|
82 |
* @since 2.3.9
|
83 |
*
|
84 |
+
* @param string $notice The notice name.
|
85 |
* @return bool
|
86 |
*/
|
87 |
+
protected function can_display_notice( $notice ) {
|
88 |
$screen = get_current_screen();
|
89 |
$screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
|
90 |
|
91 |
+
/**
|
92 |
+
* Filter admin notices which can be displayed
|
93 |
+
*
|
94 |
+
* @since 2.7.0
|
95 |
+
*
|
96 |
+
* @param bool $display Whether the notice should be displayed or not.
|
97 |
+
* @param string $notice The notice name.
|
98 |
+
*/
|
99 |
+
return apply_filters(
|
100 |
+
'pll_can_display_notice',
|
101 |
+
in_array(
|
102 |
+
$screen->id,
|
103 |
+
array(
|
104 |
+
'dashboard',
|
105 |
+
'plugins',
|
106 |
+
'toplevel_page_mlang',
|
107 |
+
$screen_id . '_page_mlang_strings',
|
108 |
+
$screen_id . '_page_mlang_settings',
|
109 |
+
)
|
110 |
+
),
|
111 |
+
$notice
|
112 |
);
|
113 |
}
|
114 |
|
120 |
* @param string $notice
|
121 |
*/
|
122 |
public static function dismiss( $notice ) {
|
123 |
+
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
|
|
|
|
124 |
|
125 |
if ( ! in_array( $notice, $dismissed ) ) {
|
126 |
$dismissed[] = $notice;
|
127 |
+
update_option( 'pll_dismissed_notices', array_unique( $dismissed ) );
|
128 |
}
|
129 |
}
|
130 |
|
149 |
* @since 2.3.9
|
150 |
*/
|
151 |
public function display_notices() {
|
152 |
+
if ( current_user_can( 'manage_options' ) ) {
|
153 |
// Core notices
|
154 |
+
if ( defined( 'WOOCOMMERCE_VERSION' ) && ! defined( 'PLLWC_VERSION' ) && $this->can_display_notice( 'pllwc' ) && ! $this->is_dismissed( 'pllwc' ) ) {
|
155 |
+
$this->pllwc_notice();
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( ! defined( 'POLYLANG_PRO' ) && $this->can_display_notice( 'review' ) && ! $this->is_dismissed( 'review' ) && ! empty( $this->options['first_activation'] ) && time() > $this->options['first_activation'] + 15 * DAY_IN_SECONDS ) {
|
159 |
+
$this->review_notice();
|
160 |
+
}
|
161 |
|
162 |
// Custom notices
|
163 |
foreach ( $this->get_notices() as $notice => $html ) {
|
164 |
+
if ( $this->can_display_notice( $notice ) && ! $this->is_dismissed( $notice ) ) {
|
165 |
?>
|
166 |
<div class="pll-notice notice notice-info">
|
167 |
<?php
|
197 |
* @since 2.3.9
|
198 |
*/
|
199 |
private function pllwc_notice() {
|
200 |
+
?>
|
201 |
+
<div class="pll-notice notice notice-warning">
|
202 |
+
<?php $this->dismiss_button( 'pllwc' ); ?>
|
203 |
+
<p>
|
204 |
+
<?php
|
205 |
+
printf(
|
206 |
+
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
207 |
+
esc_html__( 'We have noticed that you are using Polylang with WooCommerce. To ensure compatibility, we recommend you use %1$sPolylang for WooCommerce%2$s.', 'polylang' ),
|
208 |
+
'<a href="https://polylang.pro/downloads/polylang-for-woocommerce/">',
|
209 |
+
'</a>'
|
210 |
+
);
|
211 |
+
?>
|
212 |
+
</p>
|
213 |
+
</div>
|
214 |
+
<?php
|
|
|
|
|
215 |
}
|
216 |
|
217 |
/**
|
220 |
* @since 2.3.9
|
221 |
*/
|
222 |
private function review_notice() {
|
223 |
+
?>
|
224 |
+
<div class="pll-notice notice notice-info">
|
225 |
+
<?php $this->dismiss_button( 'review' ); ?>
|
226 |
+
<p>
|
227 |
+
<?php
|
228 |
+
printf(
|
229 |
+
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
230 |
+
esc_html__( 'We have noticed that you have been using Polylang for some time. We hope you love it, and we would really appreciate it if you would %1$sgive us a 5 stars rating%2$s.', 'polylang' ),
|
231 |
+
'<a href="https://wordpress.org/support/plugin/polylang/reviews/?rate=5#new-post">',
|
232 |
+
'</a>'
|
233 |
+
);
|
234 |
+
?>
|
235 |
+
</p>
|
236 |
+
</div>
|
237 |
+
<?php
|
|
|
|
|
238 |
}
|
239 |
}
|
admin/admin-static-pages.php
CHANGED
@@ -86,8 +86,8 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
86 |
*
|
87 |
* @since 1.8
|
88 |
*
|
89 |
-
* @param array $post_states
|
90 |
-
* @param object $post
|
91 |
* @return array
|
92 |
*/
|
93 |
public function display_post_states( $post_states, $post ) {
|
86 |
*
|
87 |
* @since 1.8
|
88 |
*
|
89 |
+
* @param array $post_states An array of post display states.
|
90 |
+
* @param object $post The current post object.
|
91 |
* @return array
|
92 |
*/
|
93 |
public function display_post_states( $post_states, $post ) {
|
admin/admin-strings.php
CHANGED
@@ -118,7 +118,6 @@ class PLL_Admin_Strings {
|
|
118 |
* @return string
|
119 |
*/
|
120 |
public static function sanitize_string_translation( $translation, $name ) {
|
121 |
-
$translation = wp_unslash( trim( $translation ) );
|
122 |
|
123 |
if ( false !== ( $option = array_search( $name, self::$default_strings['options'], true ) ) ) {
|
124 |
$translation = sanitize_option( $option, $translation );
|
118 |
* @return string
|
119 |
*/
|
120 |
public static function sanitize_string_translation( $translation, $name ) {
|
|
|
121 |
|
122 |
if ( false !== ( $option = array_search( $name, self::$default_strings['options'], true ) ) ) {
|
123 |
$translation = sanitize_option( $option, $translation );
|
admin/admin.php
CHANGED
@@ -25,8 +25,12 @@
|
|
25 |
* block_editor => reference to PLL_Admin_Block_Editor object
|
26 |
* classic_editor => reference to PLL_Admin_Classic_Editor object
|
27 |
* filters_media => optional, reference to PLL_Admin_Filters_Media object
|
|
|
|
|
28 |
*
|
29 |
* @since 1.2
|
|
|
|
|
30 |
*/
|
31 |
class PLL_Admin extends PLL_Admin_Base {
|
32 |
public $filters, $filters_columns, $filters_post, $filters_term, $nav_menu, $sync, $filters_media;
|
@@ -61,11 +65,6 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
61 |
if ( $this->model->get_languages_list() ) {
|
62 |
add_action( 'wp_loaded', array( $this, 'add_filters' ), 5 );
|
63 |
add_action( 'admin_init', array( $this, 'maybe_load_sync_post' ), 20 ); // After fusion Builder.
|
64 |
-
|
65 |
-
// Bulk Translate
|
66 |
-
if ( class_exists( 'PLL_Bulk_Translate' ) ) {
|
67 |
-
add_action( 'current_screen', array( $this->bulk_translate = new PLL_Bulk_Translate( $this ), 'init' ) );
|
68 |
-
}
|
69 |
}
|
70 |
}
|
71 |
|
@@ -100,6 +99,7 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
100 |
* Setup filters for admin pages
|
101 |
*
|
102 |
* @since 1.2
|
|
|
103 |
*/
|
104 |
public function add_filters() {
|
105 |
// All these are separated just for convenience and maintainability
|
@@ -127,6 +127,13 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
127 |
$this->posts = new PLL_CRUD_Posts( $this );
|
128 |
$this->terms = new PLL_CRUD_Terms( $this );
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
// Advanced media
|
131 |
if ( $this->options['media_support'] && class_exists( 'PLL_Admin_Advanced_Media' ) ) {
|
132 |
$this->advanced_media = new PLL_Admin_Advanced_Media( $this );
|
@@ -146,6 +153,10 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
146 |
$this->duplicate_rest = new PLL_Duplicate_REST();
|
147 |
}
|
148 |
|
|
|
|
|
|
|
|
|
149 |
// Block editor metabox
|
150 |
if ( pll_use_block_editor_plugin() ) {
|
151 |
$this->block_editor_plugin = new PLL_Block_Editor_Plugin( $this );
|
25 |
* block_editor => reference to PLL_Admin_Block_Editor object
|
26 |
* classic_editor => reference to PLL_Admin_Classic_Editor object
|
27 |
* filters_media => optional, reference to PLL_Admin_Filters_Media object
|
28 |
+
* bulk_translate => reference, a PLL_Bulk_Translate subclass instance
|
29 |
+
* wizard => reference, a PLL_Wizard object
|
30 |
*
|
31 |
* @since 1.2
|
32 |
+
* @since 2.7 Added a reference to a PLL_Bulk_Translate instance.
|
33 |
+
* @since 2.7 Added a reference to a PLL_Wizard object.
|
34 |
*/
|
35 |
class PLL_Admin extends PLL_Admin_Base {
|
36 |
public $filters, $filters_columns, $filters_post, $filters_term, $nav_menu, $sync, $filters_media;
|
65 |
if ( $this->model->get_languages_list() ) {
|
66 |
add_action( 'wp_loaded', array( $this, 'add_filters' ), 5 );
|
67 |
add_action( 'admin_init', array( $this, 'maybe_load_sync_post' ), 20 ); // After fusion Builder.
|
|
|
|
|
|
|
|
|
|
|
68 |
}
|
69 |
}
|
70 |
|
99 |
* Setup filters for admin pages
|
100 |
*
|
101 |
* @since 1.2
|
102 |
+
* @since 2.7 instantiate a PLL_Bulk_Translate instance.
|
103 |
*/
|
104 |
public function add_filters() {
|
105 |
// All these are separated just for convenience and maintainability
|
127 |
$this->posts = new PLL_CRUD_Posts( $this );
|
128 |
$this->terms = new PLL_CRUD_Terms( $this );
|
129 |
|
130 |
+
// Bulk Translate
|
131 |
+
// Needs to be loaded before other modules.
|
132 |
+
if ( class_exists( 'PLL_Bulk_Translate' ) ) {
|
133 |
+
$this->bulk_translate = new PLL_Bulk_Translate( $this->model );
|
134 |
+
add_action( 'current_screen', array( $this->bulk_translate, 'init' ) );
|
135 |
+
}
|
136 |
+
|
137 |
// Advanced media
|
138 |
if ( $this->options['media_support'] && class_exists( 'PLL_Admin_Advanced_Media' ) ) {
|
139 |
$this->advanced_media = new PLL_Admin_Advanced_Media( $this );
|
153 |
$this->duplicate_rest = new PLL_Duplicate_REST();
|
154 |
}
|
155 |
|
156 |
+
if ( class_exists( 'PLL_Sync_Post_Model' ) ) {
|
157 |
+
$this->sync_post_model = new PLL_Sync_Post_Model( $this );
|
158 |
+
}
|
159 |
+
|
160 |
// Block editor metabox
|
161 |
if ( pll_use_block_editor_plugin() ) {
|
162 |
$this->block_editor_plugin = new PLL_Block_Editor_Plugin( $this );
|
admin/view-translations-media.php
CHANGED
@@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
21 |
<td class = "pll-media-language-column"><span class = "pll-translation-flag"><?php echo $language->flag; // phpcs:ignore WordPress.Security.EscapeOutput ?></span><?php echo esc_html( $language->name ); ?></td>
|
22 |
<td class = "pll-media-edit-column">
|
23 |
<?php
|
24 |
-
if ( ( $translation_id = $this->model->post->get_translation( $
|
25 |
// The translation exists
|
26 |
printf(
|
27 |
'<input type="hidden" name="media_tr_lang[%s]" value="%d" />',
|
@@ -31,7 +31,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
31 |
echo $this->links->edit_post_translation_link( $translation_id ); // phpcs:ignore WordPress.Security.EscapeOutput
|
32 |
} else {
|
33 |
// No translation
|
34 |
-
echo $this->links->new_post_translation_link( $
|
35 |
}
|
36 |
?>
|
37 |
</td>
|
21 |
<td class = "pll-media-language-column"><span class = "pll-translation-flag"><?php echo $language->flag; // phpcs:ignore WordPress.Security.EscapeOutput ?></span><?php echo esc_html( $language->name ); ?></td>
|
22 |
<td class = "pll-media-edit-column">
|
23 |
<?php
|
24 |
+
if ( ( $translation_id = $this->model->post->get_translation( $post_ID, $language ) ) && $translation_id !== $post_ID ) {
|
25 |
// The translation exists
|
26 |
printf(
|
27 |
'<input type="hidden" name="media_tr_lang[%s]" value="%d" />',
|
31 |
echo $this->links->edit_post_translation_link( $translation_id ); // phpcs:ignore WordPress.Security.EscapeOutput
|
32 |
} else {
|
33 |
// No translation
|
34 |
+
echo $this->links->new_post_translation_link( $post_ID, $language ); // phpcs:ignore WordPress.Security.EscapeOutput
|
35 |
}
|
36 |
?>
|
37 |
</td>
|
css/admin.css
CHANGED
@@ -21,6 +21,14 @@
|
|
21 |
font-family: 'dashicons';
|
22 |
content: "\f155";
|
23 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
.form-field input[type="radio"] {
|
26 |
width: auto;
|
@@ -324,6 +332,10 @@ td[class*='column-language_'] {
|
|
324 |
text-decoration: none;
|
325 |
}
|
326 |
|
|
|
|
|
|
|
|
|
327 |
/* Bulk translate */
|
328 |
.bulk-translate-save .button {
|
329 |
margin-right: 20px;
|
@@ -340,8 +352,8 @@ td[class*='column-language_'] {
|
|
340 |
|
341 |
#pll-translate .title {
|
342 |
display: block;
|
343 |
-
|
344 |
-
|
345 |
}
|
346 |
|
347 |
@media screen and ( max-width: 782px ) {
|
21 |
font-family: 'dashicons';
|
22 |
content: "\f155";
|
23 |
}
|
24 |
+
.pll-icon:before{
|
25 |
+
display: inline-block;
|
26 |
+
text-align: left;
|
27 |
+
width: 15px;
|
28 |
+
}
|
29 |
+
.pll-circle:before{
|
30 |
+
content: "\25cf";
|
31 |
+
}
|
32 |
|
33 |
.form-field input[type="radio"] {
|
34 |
width: auto;
|
332 |
text-decoration: none;
|
333 |
}
|
334 |
|
335 |
+
.pll-notice .button {
|
336 |
+
margin-right: 10px;
|
337 |
+
}
|
338 |
+
|
339 |
/* Bulk translate */
|
340 |
.bulk-translate-save .button {
|
341 |
margin-right: 20px;
|
352 |
|
353 |
#pll-translate .title {
|
354 |
display: block;
|
355 |
+
margin: 0.2em 0;
|
356 |
+
line-height: 2.5;
|
357 |
}
|
358 |
|
359 |
@media screen and ( max-width: 782px ) {
|
css/admin.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#
|
1 |
+
#add-lang select{width:95%}.column-locale,.languages .column-slug{width:15%}.column-default_lang{width:5%}.column-count,.column-flag,.column-term_group{width:10%}.icon-default-lang:before{font-family:dashicons;content:"\f155"}.pll-icon:before{display:inline-block;text-align:left;width:15px}.pll-circle:before{content:"\25cf"}.form-field input[type=radio]{width:auto;margin-right:2px}#pll-about-box p,#pll-recommended p{text-align:justify}#pll-about-box input{margin:0;padding:0;float:right}.stringstranslations .column-context,.stringstranslations .column-name{width:10%}.stringstranslations .column-string{width:33%}.translation label{display:inline-block;width:23%;vertical-align:top}.translation input,.translation textarea{width:72%}.pll-settings{margin-top:20px}.pll-settings .plugin-title{width:25%}#wpbody-content .pll-settings .pll-configure tr{display:table-row}#wpbody-content .pll-settings .pll-configure td{display:table-cell}#wpbody-content .pll-settings .pll-configure>td{padding:20px 20px 20px 40px}.pll-configure legend{font-size:14px;font-weight:600;margin-bottom:.5em}.pll-configure td .description{margin-top:2px;margin-bottom:.5em}.pll-configure p.submit{margin-top:20px}.pll-configure .button{margin-right:20px}.pll-configure fieldset{margin-bottom:1.5em}.pll-inline-block-list{margin:0}.pll-inline-block-list li{display:inline-block;margin:0;width:250px}#pll-domains-table td{padding:2px 2px 2px 1.5em;-webkit-box-shadow:none;box-shadow:none;border:none}.pll-settings-url-col{display:inline-block;width:49%;vertical-align:top}#pll-licenses-table td{vertical-align:top}#pll-licenses-table label{font-size:1em;font-weight:600}.pll-configure .pll-deactivate-license{margin:0 0 0 20px}td[class*=column-language_],th[class*=column-language_]{width:1.5em}.pll-dir-rtl input[type=text],.pll-dir-rtl textarea{direction:rtl}.pll-dir-ltr input[type=text],.pll-dir-ltr textarea{direction:ltr}.pll-dir-ltr .tr_lang,.pll-dir-rtl .tr_lang{direction:inherit}#post-translations p{float:left}#post-translations table{table-layout:fixed;width:100%;clear:both}#post-translations a{text-decoration:none}#post-translations .pll-column-icon,#post-translations .pll-language-column{width:20px}#post-translations .tr_lang{width:100%}#post-translations td{padding:2px}#post-translations .spinner,#term-translations .spinner{float:none;margin:0;background-position:center;width:auto}.pll-column-icon{text-align:center}#select-post-language .pll-select-flag{padding:4px;margin-right:32px}#select-media-language .pll-select-flag{padding:4px;margin-right:10px}.pll-media-edit-column{float:right}.pll-button{padding:0;height:20px;background:0 0;border:none;font-size:20px;cursor:pointer}.pll-button:not(.wp-ui-text-highlight){color:#ddd}#pll-duplicate{float:right;margin:13px 7px}.pll-translation-flag{margin-right:14px}#select-add-term-language .pll-select-flag{padding:11px;margin-right:13px}#select-edit-term-language .pll-select-flag{padding:11px;margin-right:4px}#term-translations p{font-weight:400;font-style:normal;padding:2px;color:#23282d}#add-term-translations,#edit-term-translations{width:95%}#term-translations .pll-language-column{line-height:28px;width:20%}#add-term-translations .pll-language-column,#term-translations .pll-edit-column{width:20px}#edit-term-translations .pll-language-column{padding:15px 10px;font-weight:400}.pll_icon_tick:before{content:"\f147"}.pll_icon_add:before{content:"\f132"}.pll_icon_edit:before{content:"\f464"}[class^=pll_icon_]{font:20px/1 dashicons;vertical-align:middle}#wpadminbar #wp-admin-bar-languages .ab-item img{margin:0 8px 0 2px}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{float:none;top:4px}#wpadminbar #wp-admin-bar-languages .ab-icon:before{content:"\f326";top:1px}.pll-notice.notice{padding-right:38px;position:relative}.pll-notice a.notice-dismiss{text-decoration:none}.pll-notice .button{margin-right:10px}.bulk-translate-save .button{margin-right:20px}#wpbody-content #pll-translate fieldset{display:inline-block;width:300px}#pll-translate .pll-translation-flag{margin-right:.3em}#pll-translate .title{display:block;margin:.2em 0;line-height:2.5}@media screen and (max-width:782px){#wpbody-content .pll-settings .pll-configure>td{padding:20px}#wpbody-content .pll-settings #cb{padding:20px 9px}.pll-inline-block{width:auto}.pll-settings-url-col{display:block;width:100%}#wpbody-content .pll-settings #pll-licenses-table td{display:block}.pll-configure .pll-deactivate-license{margin:10px 0 5px}.stringstranslations .column-context,.stringstranslations .column-name{display:none}.translation label{display:block;width:95%;padding-left:0}.translation input{width:95%}#edit-term-translations .pll-language-name,#select-add-term-language .pll-select-flag,#select-edit-term-language .pll-select-flag{display:none}#edit-term-translations{width:100%}#add-term-translations .pll-language-column{line-height:38px}#edit-term-translations td{padding:8px 10px}#edit-term-translations .pll-edit-column,#edit-term-translations .pll-language-column{width:20px}.term-translations .pll-edit-column,.term-translations .pll-language-column,.term-translations .pll-translation-column{display:table-cell}.term-translations .hidden{display:none}#wpadminbar #wp-admin-bar-languages{display:block}#wpadminbar #wp-admin-bar-languages>.ab-item{width:50px;text-align:center}#wpadminbar #wp-admin-bar-languages>.ab-item .ab-icon:before{font:32px/1 dashicons;top:-1px}#wpadminbar #wp-admin-bar-languages>.ab-item img{margin:19px 0}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{margin-right:6px;font-size:20px!important;line-height:20px!important}}
|
css/selectmenu.css
CHANGED
@@ -24,11 +24,17 @@
|
|
24 |
position: relative;
|
25 |
margin: 0;
|
26 |
padding: 3px 1em 3px .4em;
|
|
|
27 |
min-height: 0; /* support: IE7 */
|
28 |
/* support: IE10, see #8844 */
|
29 |
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
32 |
/* icon support */
|
33 |
.ui-menu-icons {
|
34 |
position: relative;
|
@@ -37,6 +43,10 @@
|
|
37 |
.ui-menu-icons .ui-menu-item {
|
38 |
padding-left: 2em;
|
39 |
}
|
|
|
|
|
|
|
|
|
40 |
|
41 |
/* left-aligned */
|
42 |
.ui-selectmenu-text .ui-icon,
|
@@ -44,10 +54,16 @@
|
|
44 |
position: absolute;
|
45 |
top: 0;
|
46 |
bottom: 0;
|
47 |
-
left: .
|
48 |
margin: auto 0;
|
49 |
}
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
/* right-aligned */
|
52 |
.ui-menu .ui-menu-icon {
|
53 |
left: auto;
|
@@ -97,8 +113,15 @@
|
|
97 |
margin-top: -10px;
|
98 |
position: absolute;
|
99 |
top: 50%;
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
101 |
|
|
|
102 |
.ui-selectmenu-button span.ui-selectmenu-text {
|
103 |
text-align: left;
|
104 |
padding: 0.2em 2.1em 0.2em 2em;
|
@@ -109,6 +132,11 @@
|
|
109 |
white-space: nowrap;
|
110 |
}
|
111 |
|
|
|
|
|
|
|
|
|
|
|
112 |
.ui-widget-content,
|
113 |
.ui-state-default,
|
114 |
.ui-widget-content .ui-state-default,
|
24 |
position: relative;
|
25 |
margin: 0;
|
26 |
padding: 3px 1em 3px .4em;
|
27 |
+
cursor: pointer;
|
28 |
min-height: 0; /* support: IE7 */
|
29 |
/* support: IE10, see #8844 */
|
30 |
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
|
31 |
}
|
32 |
|
33 |
+
.rtl .ui-menu .ui-menu-item {
|
34 |
+
text-align: right;
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
/* icon support */
|
39 |
.ui-menu-icons {
|
40 |
position: relative;
|
43 |
.ui-menu-icons .ui-menu-item {
|
44 |
padding-left: 2em;
|
45 |
}
|
46 |
+
.rtl .ui-menu-icons .ui-menu-item {
|
47 |
+
padding-left: 1em;
|
48 |
+
padding-right: 2em;
|
49 |
+
}
|
50 |
|
51 |
/* left-aligned */
|
52 |
.ui-selectmenu-text .ui-icon,
|
54 |
position: absolute;
|
55 |
top: 0;
|
56 |
bottom: 0;
|
57 |
+
left: .3em;
|
58 |
margin: auto 0;
|
59 |
}
|
60 |
|
61 |
+
.rtl .ui-selectmenu-text .ui-icon,
|
62 |
+
.rtl .ui-menu .ui-icon {
|
63 |
+
right: .3em;
|
64 |
+
left: auto;
|
65 |
+
}
|
66 |
+
|
67 |
/* right-aligned */
|
68 |
.ui-menu .ui-menu-icon {
|
69 |
left: auto;
|
113 |
margin-top: -10px;
|
114 |
position: absolute;
|
115 |
top: 50%;
|
116 |
+
text-indent: 0; /* due to text-indent for jquery ui-dialog in wizard */
|
117 |
+
}
|
118 |
+
|
119 |
+
.rtl .ui-selectmenu-button span.ui-icon {
|
120 |
+
left: 0.5em;
|
121 |
+
right: auto;
|
122 |
}
|
123 |
|
124 |
+
|
125 |
.ui-selectmenu-button span.ui-selectmenu-text {
|
126 |
text-align: left;
|
127 |
padding: 0.2em 2.1em 0.2em 2em;
|
132 |
white-space: nowrap;
|
133 |
}
|
134 |
|
135 |
+
.rtl .ui-selectmenu-button span.ui-selectmenu-text {
|
136 |
+
text-align: right;
|
137 |
+
padding: 0.2em 2em 0.2em 2.1em;
|
138 |
+
}
|
139 |
+
|
140 |
.ui-widget-content,
|
141 |
.ui-state-default,
|
142 |
.ui-widget-content .ui-state-default,
|
css/selectmenu.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;min-height:0;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon,.ui-selectmenu-text .ui-icon{position:absolute;top:0;bottom:0;left:.
|
1 |
+
.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.rtl .ui-menu .ui-menu-item{text-align:right}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.rtl .ui-menu-icons .ui-menu-item{padding-left:1em;padding-right:2em}.ui-menu .ui-icon,.ui-selectmenu-text .ui-icon{position:absolute;top:0;bottom:0;left:.3em;margin:auto 0}.rtl .ui-menu .ui-icon,.rtl .ui-selectmenu-text .ui-icon{right:.3em;left:auto}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:700;line-height:23px;padding:2px .4em;margin:.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;margin-top:-10px;position:absolute;top:50%;text-indent:0}.rtl .ui-selectmenu-button span.ui-icon{left:.5em;right:auto}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.2em 2.1em .2em 2em;display:block;line-height:23px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rtl .ui-selectmenu-button span.ui-selectmenu-text{text-align:right;padding:.2em 2em .2em 2.1em}.ui-state-default,.ui-widget-content,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{background:#fff;border:1px solid #ddd;box-shadow:0 1px 2px rgba(0,0,0,.07) inset;color:#32373c}.ui-widget-content .ui-state-focus,.ui-widget-content .ui-state-hover{background:#f5f5f5}.ui-selectmenu-button.ui-state-focus{border:1px solid #5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}.ui-icon-triangle-1-s:before{content:"\f140";font:20px/1 dashicons}.ui-widget-content{max-height:231px;box-shadow:0 2px 6px rgba(100,100,100,.3)}
|
frontend/choose-lang.php
CHANGED
@@ -191,16 +191,25 @@ abstract class PLL_Choose_Lang {
|
|
191 |
}
|
192 |
|
193 |
/**
|
194 |
-
* Returns the
|
|
|
|
|
|
|
195 |
*
|
196 |
* @since 0.1
|
197 |
*
|
198 |
* @return object browser preferred language or default language
|
199 |
*/
|
200 |
public function get_preferred_language() {
|
201 |
-
|
|
|
|
|
202 |
if ( isset( $_COOKIE[ PLL_COOKIE ] ) ) {
|
203 |
-
|
|
|
|
|
|
|
|
|
204 |
}
|
205 |
|
206 |
/**
|
@@ -210,12 +219,14 @@ abstract class PLL_Choose_Lang {
|
|
210 |
* Polylang fallbacks to the default language
|
211 |
*
|
212 |
* @since 1.0
|
|
|
213 |
*
|
214 |
-
* @param string $language
|
|
|
215 |
*/
|
216 |
-
$slug = apply_filters( 'pll_preferred_language', $
|
217 |
|
218 |
-
//
|
219 |
return ( $lang = $this->model->get_language( $slug ) ) ? $lang : $this->model->get_language( $this->options['default_lang'] );
|
220 |
}
|
221 |
|
@@ -274,6 +285,7 @@ abstract class PLL_Choose_Lang {
|
|
274 |
*/
|
275 |
if ( $redirect = apply_filters( 'pll_redirect_home', $redirect ) ) {
|
276 |
$this->maybe_setcookie();
|
|
|
277 |
wp_safe_redirect( $redirect, 302, POLYLANG );
|
278 |
exit;
|
279 |
}
|
191 |
}
|
192 |
|
193 |
/**
|
194 |
+
* Returns the preferred language
|
195 |
+
* either from the cookie if it's a returning visit
|
196 |
+
* or according to browser preference
|
197 |
+
* or the default language
|
198 |
*
|
199 |
* @since 0.1
|
200 |
*
|
201 |
* @return object browser preferred language or default language
|
202 |
*/
|
203 |
public function get_preferred_language() {
|
204 |
+
$language = false;
|
205 |
+
$cookie = false;
|
206 |
+
|
207 |
if ( isset( $_COOKIE[ PLL_COOKIE ] ) ) {
|
208 |
+
// Check first if the user was already browsing this site.
|
209 |
+
$language = sanitize_key( $_COOKIE[ PLL_COOKIE ] );
|
210 |
+
$cookie = true;
|
211 |
+
} elseif ( $this->options['browser'] ) {
|
212 |
+
$language = $this->get_preferred_browser_language();
|
213 |
}
|
214 |
|
215 |
/**
|
219 |
* Polylang fallbacks to the default language
|
220 |
*
|
221 |
* @since 1.0
|
222 |
+
* @since 2.7 Added $cookie parameter.
|
223 |
*
|
224 |
+
* @param string|bool $language Preferred language code, false if none has been found.
|
225 |
+
* @param bool $cookie Whether the preferred language has been defined by the cookie.
|
226 |
*/
|
227 |
+
$slug = apply_filters( 'pll_preferred_language', $language, $cookie );
|
228 |
|
229 |
+
// Return default if there is no preferences in the browser or preferences does not match our languages or it is requested not to use the browser preference
|
230 |
return ( $lang = $this->model->get_language( $slug ) ) ? $lang : $this->model->get_language( $this->options['default_lang'] );
|
231 |
}
|
232 |
|
285 |
*/
|
286 |
if ( $redirect = apply_filters( 'pll_redirect_home', $redirect ) ) {
|
287 |
$this->maybe_setcookie();
|
288 |
+
header( 'Vary: Accept-Language' );
|
289 |
wp_safe_redirect( $redirect, 302, POLYLANG );
|
290 |
exit;
|
291 |
}
|
frontend/frontend-auto-translate.php
CHANGED
@@ -185,12 +185,12 @@ class PLL_Frontend_Auto_Translate {
|
|
185 |
|
186 |
// Array of post ids
|
187 |
// post_parent__in & post_parent__not_in since WP 3.6
|
188 |
-
foreach ( array( 'post__in', 'post__not_in', 'post_parent__in', 'post_parent__not_in' ) as $key ) {
|
189 |
$arr = array();
|
190 |
if ( ! empty( $qv[ $key ] ) ) {
|
191 |
// post__in used by the 2 functions below
|
192 |
// Useless to filter them as output is already in the right language and would result in performance loss
|
193 |
-
foreach ( debug_backtrace() as $trace ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
194 |
if ( in_array( $trace['function'], array( 'wp_nav_menu', 'gallery_shortcode' ) ) ) {
|
195 |
return;
|
196 |
}
|
@@ -216,6 +216,8 @@ class PLL_Frontend_Auto_Translate {
|
|
216 |
*/
|
217 |
public function get_terms_args( $args, $taxonomies ) {
|
218 |
if ( ! isset( $args['lang'] ) && ! empty( $args['include'] ) && ( empty( $taxonomies ) || $this->model->is_translated_taxonomy( $taxonomies ) ) ) {
|
|
|
|
|
219 |
foreach ( wp_parse_id_list( $args['include'] ) as $id ) {
|
220 |
$arr[] = ( $tr = $this->get_term( $id ) ) ? $tr : $id;
|
221 |
}
|
185 |
|
186 |
// Array of post ids
|
187 |
// post_parent__in & post_parent__not_in since WP 3.6
|
188 |
+
foreach ( array( 'post__in', 'post__not_in', 'post_parent__in', 'post_parent__not_in' ) as $key ) { // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn
|
189 |
$arr = array();
|
190 |
if ( ! empty( $qv[ $key ] ) ) {
|
191 |
// post__in used by the 2 functions below
|
192 |
// Useless to filter them as output is already in the right language and would result in performance loss
|
193 |
+
foreach ( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ) as $trace ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
194 |
if ( in_array( $trace['function'], array( 'wp_nav_menu', 'gallery_shortcode' ) ) ) {
|
195 |
return;
|
196 |
}
|
216 |
*/
|
217 |
public function get_terms_args( $args, $taxonomies ) {
|
218 |
if ( ! isset( $args['lang'] ) && ! empty( $args['include'] ) && ( empty( $taxonomies ) || $this->model->is_translated_taxonomy( $taxonomies ) ) ) {
|
219 |
+
$arr = array();
|
220 |
+
|
221 |
foreach ( wp_parse_id_list( $args['include'] ) as $id ) {
|
222 |
$arr[] = ( $tr = $this->get_term( $id ) ) ? $tr : $id;
|
223 |
}
|
frontend/frontend-filters-links.php
CHANGED
@@ -175,6 +175,8 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
175 |
return;
|
176 |
}
|
177 |
|
|
|
|
|
178 |
// Google recommends to include self link https://support.google.com/webmasters/answer/189077?hl=en
|
179 |
foreach ( $this->model->get_languages_list() as $language ) {
|
180 |
if ( $url = $this->links->get_translation_url( $language ) ) {
|
@@ -184,6 +186,8 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
184 |
|
185 |
// Outputs the section only if there are translations ( $urls always contains self link )
|
186 |
if ( ! empty( $urls ) && count( $urls ) > 1 ) {
|
|
|
|
|
187 |
|
188 |
// Prepare the list of languages to remove the country code
|
189 |
foreach ( array_keys( $urls ) as $locale ) {
|
@@ -285,7 +289,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
285 |
);
|
286 |
}
|
287 |
|
288 |
-
$traces =
|
289 |
unset( $traces[0], $traces[1] ); // We don't need the last 2 calls: this function + call_user_func_array (or apply_filters on PHP7+)
|
290 |
|
291 |
foreach ( $traces as $trace ) {
|
175 |
return;
|
176 |
}
|
177 |
|
178 |
+
$urls = array();
|
179 |
+
|
180 |
// Google recommends to include self link https://support.google.com/webmasters/answer/189077?hl=en
|
181 |
foreach ( $this->model->get_languages_list() as $language ) {
|
182 |
if ( $url = $this->links->get_translation_url( $language ) ) {
|
186 |
|
187 |
// Outputs the section only if there are translations ( $urls always contains self link )
|
188 |
if ( ! empty( $urls ) && count( $urls ) > 1 ) {
|
189 |
+
$languages = array();
|
190 |
+
$hreflangs = array();
|
191 |
|
192 |
// Prepare the list of languages to remove the country code
|
193 |
foreach ( array_keys( $urls ) as $locale ) {
|
289 |
);
|
290 |
}
|
291 |
|
292 |
+
$traces = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
293 |
unset( $traces[0], $traces[1] ); // We don't need the last 2 calls: this function + call_user_func_array (or apply_filters on PHP7+)
|
294 |
|
295 |
foreach ( $traces as $trace ) {
|
frontend/frontend-links.php
CHANGED
@@ -55,7 +55,6 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
55 |
*/
|
56 |
if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
|
57 |
$qv = $wp_query->query_vars;
|
58 |
-
$hide = $this->options['default_lang'] == $language->slug && $this->options['hide_default'];
|
59 |
|
60 |
// Post and attachment
|
61 |
if ( is_single() && ( $this->options['media_support'] || ! is_attachment() ) && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
|
@@ -96,7 +95,7 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
96 |
$lang = $this->model->term->get_language( $term->term_id );
|
97 |
|
98 |
if ( ! $lang || $language->slug == $lang->slug ) {
|
99 |
-
$url =
|
100 |
}
|
101 |
|
102 |
elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
|
@@ -115,7 +114,7 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
115 |
* @param array $args Arguments used to evaluated the number of posts in the archive
|
116 |
*/
|
117 |
if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, array( 'taxonomy' => $term->taxonomy ) ) ) {
|
118 |
-
$url =
|
119 |
}
|
120 |
}
|
121 |
}
|
55 |
*/
|
56 |
if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
|
57 |
$qv = $wp_query->query_vars;
|
|
|
58 |
|
59 |
// Post and attachment
|
60 |
if ( is_single() && ( $this->options['media_support'] || ! is_attachment() ) && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
|
95 |
$lang = $this->model->term->get_language( $term->term_id );
|
96 |
|
97 |
if ( ! $lang || $language->slug == $lang->slug ) {
|
98 |
+
$url = get_term_link( $term, $term->taxonomy ); // Self link
|
99 |
}
|
100 |
|
101 |
elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
|
114 |
* @param array $args Arguments used to evaluated the number of posts in the archive
|
115 |
*/
|
116 |
if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, array( 'taxonomy' => $term->taxonomy ) ) ) {
|
117 |
+
$url = get_term_link( $tr_term, $term->taxonomy );
|
118 |
}
|
119 |
}
|
120 |
}
|
frontend/frontend-nav-menu.php
CHANGED
@@ -92,7 +92,7 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
92 |
$new_items = array();
|
93 |
$offset = 0;
|
94 |
|
95 |
-
foreach ( $items as $
|
96 |
if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) {
|
97 |
$i = 0;
|
98 |
|
@@ -219,7 +219,7 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
219 |
// First get multilingual menu locations from DB
|
220 |
$theme = get_option( 'stylesheet' );
|
221 |
|
222 |
-
foreach ( $menus as $loc
|
223 |
$menus[ $loc ] = empty( $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ] ) ? 0 : $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ];
|
224 |
}
|
225 |
|
@@ -275,7 +275,7 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
275 |
if ( ! $menu && ! $args['theme_location'] ) {
|
276 |
$menus = wp_get_nav_menus();
|
277 |
foreach ( $menus as $menu_maybe ) {
|
278 |
-
if (
|
279 |
foreach ( $this->options['nav_menus'][ $theme ] as $menus ) {
|
280 |
if ( in_array( $menu_maybe->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) {
|
281 |
$args['menu'] = $menus[ $this->curlang->slug ];
|
92 |
$new_items = array();
|
93 |
$offset = 0;
|
94 |
|
95 |
+
foreach ( $items as $item ) {
|
96 |
if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) {
|
97 |
$i = 0;
|
98 |
|
219 |
// First get multilingual menu locations from DB
|
220 |
$theme = get_option( 'stylesheet' );
|
221 |
|
222 |
+
foreach ( array_keys( $menus ) as $loc ) {
|
223 |
$menus[ $loc ] = empty( $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ] ) ? 0 : $this->options['nav_menus'][ $theme ][ $loc ][ $this->curlang->slug ];
|
224 |
}
|
225 |
|
275 |
if ( ! $menu && ! $args['theme_location'] ) {
|
276 |
$menus = wp_get_nav_menus();
|
277 |
foreach ( $menus as $menu_maybe ) {
|
278 |
+
if ( wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
|
279 |
foreach ( $this->options['nav_menus'][ $theme ] as $menus ) {
|
280 |
if ( in_array( $menu_maybe->term_id, $menus ) && ! empty( $menus[ $this->curlang->slug ] ) ) {
|
281 |
$args['menu'] = $menus[ $this->curlang->slug ];
|
frontend/frontend.php
CHANGED
@@ -92,12 +92,14 @@ class PLL_Frontend extends PLL_Base {
|
|
92 |
|
93 |
// Share term slugs
|
94 |
if ( $this->options['force_lang'] && class_exists( 'PLL_Share_Term_Slug' ) ) {
|
95 |
-
$this->share_term_slug =
|
96 |
-
new PLL_Frontend_Share_Term_Slug( $this ) :
|
97 |
-
new PLL_Share_Term_Slug( $this );
|
98 |
}
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
101 |
if ( class_exists( 'PLL_Sync_Post' ) ) {
|
102 |
$this->sync_post = new PLL_Sync_Post( $this );
|
103 |
}
|
92 |
|
93 |
// Share term slugs
|
94 |
if ( $this->options['force_lang'] && class_exists( 'PLL_Share_Term_Slug' ) ) {
|
95 |
+
$this->share_term_slug = new PLL_Share_Term_Slug( $this );
|
|
|
|
|
96 |
}
|
97 |
}
|
98 |
|
99 |
+
if ( class_exists( 'PLL_Sync_Post_Model' ) ) {
|
100 |
+
$this->sync_post_model = new PLL_Sync_Post_Model( $this );
|
101 |
+
}
|
102 |
+
|
103 |
if ( class_exists( 'PLL_Sync_Post' ) ) {
|
104 |
$this->sync_post = new PLL_Sync_Post( $this );
|
105 |
}
|
include/api.php
CHANGED
@@ -372,9 +372,9 @@ function pll_get_term_translations( $term_id ) {
|
|
372 |
*
|
373 |
* @since 1.5
|
374 |
*
|
375 |
-
* @param string $lang
|
376 |
-
* @param array $args ( accepted keys: post_type, m, year, monthnum, day, author, author_name, post_format )
|
377 |
-
* @return int
|
378 |
*/
|
379 |
function pll_count_posts( $lang, $args = array() ) {
|
380 |
return PLL()->model->count_posts( PLL()->model->get_language( $lang ), $args );
|
372 |
*
|
373 |
* @since 1.5
|
374 |
*
|
375 |
+
* @param string $lang Language code.
|
376 |
+
* @param array $args WP_Query arguments ( accepted keys: post_type, m, year, monthnum, day, author, author_name, post_format, post_status ).
|
377 |
+
* @return int Posts count.
|
378 |
*/
|
379 |
function pll_count_posts( $lang, $args = array() ) {
|
380 |
return PLL()->model->count_posts( PLL()->model->get_language( $lang ), $args );
|
include/base.php
CHANGED
@@ -139,7 +139,7 @@ abstract class PLL_Base {
|
|
139 |
foreach ( $this as $prop => &$obj ) {
|
140 |
if ( is_object( $obj ) && method_exists( $obj, $func ) ) {
|
141 |
if ( WP_DEBUG ) {
|
142 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
143 |
$i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
|
144 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
145 |
sprintf(
|
@@ -155,7 +155,7 @@ abstract class PLL_Base {
|
|
155 |
}
|
156 |
}
|
157 |
|
158 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
159 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
160 |
sprintf(
|
161 |
'Call to undefined function PLL()->%1$s() in %2$s on line %3$s' . "\nError handler",
|
139 |
foreach ( $this as $prop => &$obj ) {
|
140 |
if ( is_object( $obj ) && method_exists( $obj, $func ) ) {
|
141 |
if ( WP_DEBUG ) {
|
142 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
143 |
$i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
|
144 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
145 |
sprintf(
|
155 |
}
|
156 |
}
|
157 |
|
158 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
159 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
160 |
sprintf(
|
161 |
'Call to undefined function PLL()->%1$s() in %2$s on line %3$s' . "\nError handler",
|
include/class-polylang.php
CHANGED
@@ -30,6 +30,9 @@ class Polylang {
|
|
30 |
require_once PLL_INC . '/functions.php'; // VIP functions
|
31 |
spl_autoload_register( array( $this, 'autoload' ) ); // Autoload classes
|
32 |
|
|
|
|
|
|
|
33 |
$install = new PLL_Install( POLYLANG_BASENAME );
|
34 |
|
35 |
// Stopping here if we are going to deactivate the plugin ( avoids breaking rewrite rules )
|
@@ -98,7 +101,7 @@ class Polylang {
|
|
98 |
|
99 |
foreach ( $dirs as $dir ) {
|
100 |
if ( file_exists( $file = "$dir/$class.php" ) ) {
|
101 |
-
require_once $file;
|
102 |
return;
|
103 |
}
|
104 |
}
|
@@ -155,6 +158,17 @@ class Polylang {
|
|
155 |
return 0 === strpos( $req_uri, rest_get_url_prefix() . '/' ) || ! empty( $rest_route );
|
156 |
}
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
/**
|
159 |
* Defines constants
|
160 |
* May be overridden by a plugin if set before plugins_loaded, 1
|
@@ -177,9 +191,9 @@ class Polylang {
|
|
177 |
define( 'PLL_ADMIN', wp_doing_cron() || ( defined( 'WP_CLI' ) && WP_CLI ) || ( is_admin() && ! PLL_AJAX_ON_FRONT ) );
|
178 |
}
|
179 |
|
180 |
-
// Settings page whatever the tab
|
181 |
if ( ! defined( 'PLL_SETTINGS' ) ) {
|
182 |
-
define( 'PLL_SETTINGS', is_admin() && ( ( isset( $_GET['page'] ) && 0 === strpos( sanitize_key( $_GET['page'] ), 'mlang' ) ) || ! empty( $_REQUEST['pll_ajax_settings'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
183 |
}
|
184 |
}
|
185 |
|
@@ -219,7 +233,7 @@ class Polylang {
|
|
219 |
*
|
220 |
* @param string $class either PLL_Model or PLL_Admin_Model
|
221 |
*/
|
222 |
-
$class = apply_filters( 'pll_model', PLL_SETTINGS ? 'PLL_Admin_Model' : 'PLL_Model' );
|
223 |
$model = new $class( $options );
|
224 |
$links_model = $model->get_links_model();
|
225 |
|
30 |
require_once PLL_INC . '/functions.php'; // VIP functions
|
31 |
spl_autoload_register( array( $this, 'autoload' ) ); // Autoload classes
|
32 |
|
33 |
+
// register an action when plugin is activating.
|
34 |
+
register_activation_hook( POLYLANG_BASENAME, array( 'PLL_Wizard', 'start_wizard' ) );
|
35 |
+
|
36 |
$install = new PLL_Install( POLYLANG_BASENAME );
|
37 |
|
38 |
// Stopping here if we are going to deactivate the plugin ( avoids breaking rewrite rules )
|
101 |
|
102 |
foreach ( $dirs as $dir ) {
|
103 |
if ( file_exists( $file = "$dir/$class.php" ) ) {
|
104 |
+
require_once $file; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
|
105 |
return;
|
106 |
}
|
107 |
}
|
158 |
return 0 === strpos( $req_uri, rest_get_url_prefix() . '/' ) || ! empty( $rest_route );
|
159 |
}
|
160 |
|
161 |
+
/**
|
162 |
+
* Tells if we are in the wizard process.
|
163 |
+
*
|
164 |
+
* @since 2.7
|
165 |
+
*
|
166 |
+
* @return bool
|
167 |
+
*/
|
168 |
+
public static function is_wizard() {
|
169 |
+
return isset( $_GET['page'] ) && ! empty( $_GET['page'] ) && 'mlang_wizard' === sanitize_key( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
170 |
+
}
|
171 |
+
|
172 |
/**
|
173 |
* Defines constants
|
174 |
* May be overridden by a plugin if set before plugins_loaded, 1
|
191 |
define( 'PLL_ADMIN', wp_doing_cron() || ( defined( 'WP_CLI' ) && WP_CLI ) || ( is_admin() && ! PLL_AJAX_ON_FRONT ) );
|
192 |
}
|
193 |
|
194 |
+
// Settings page whatever the tab except for the wizard which needs to be an admin process.
|
195 |
if ( ! defined( 'PLL_SETTINGS' ) ) {
|
196 |
+
define( 'PLL_SETTINGS', is_admin() && ( ( isset( $_GET['page'] ) && 0 === strpos( sanitize_key( $_GET['page'] ), 'mlang' ) && ! self::is_wizard() ) || ! empty( $_REQUEST['pll_ajax_settings'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
197 |
}
|
198 |
}
|
199 |
|
233 |
*
|
234 |
* @param string $class either PLL_Model or PLL_Admin_Model
|
235 |
*/
|
236 |
+
$class = apply_filters( 'pll_model', PLL_SETTINGS || self::is_wizard() ? 'PLL_Admin_Model' : 'PLL_Model' );
|
237 |
$model = new $class( $options );
|
238 |
$links_model = $model->get_links_model();
|
239 |
|
include/crud-posts.php
CHANGED
@@ -227,7 +227,7 @@ class PLL_CRUD_Posts {
|
|
227 |
if ( ! empty( $ids ) ) {
|
228 |
// Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ).
|
229 |
require_once ABSPATH . 'wp-admin/includes/image.php'; // In case the file is deleted outside admin.
|
230 |
-
wp_update_attachment_metadata( $ids[0], wp_generate_attachment_metadata( $ids[0], $file ) );
|
231 |
return ''; // Prevent deleting the main file.
|
232 |
}
|
233 |
|
@@ -239,9 +239,9 @@ class PLL_CRUD_Posts {
|
|
239 |
*
|
240 |
* @since 1.8
|
241 |
*
|
242 |
-
* @param int $post_id
|
243 |
-
* @param string|object $lang
|
244 |
-
* @return int id of the translated media
|
245 |
*/
|
246 |
public function create_media_translation( $post_id, $lang ) {
|
247 |
if ( empty( $post_id ) ) {
|
@@ -254,30 +254,34 @@ class PLL_CRUD_Posts {
|
|
254 |
return $post;
|
255 |
}
|
256 |
|
257 |
-
$lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug
|
258 |
|
259 |
-
// Create a new attachment ( translate attachment parent if exists )
|
260 |
-
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload
|
261 |
$post->ID = null; // Will force the creation
|
262 |
$post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0;
|
263 |
-
$post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language
|
264 |
$tr_id = wp_insert_attachment( wp_slash( (array) $post ) );
|
265 |
-
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload
|
266 |
|
267 |
-
// Copy metadata
|
268 |
-
|
269 |
-
|
270 |
-
add_post_meta( $tr_id, $key, wp_slash( $meta ) );
|
271 |
-
}
|
272 |
}
|
273 |
|
274 |
-
|
|
|
|
|
|
|
275 |
|
276 |
-
|
277 |
-
if (
|
278 |
-
|
279 |
}
|
280 |
|
|
|
|
|
|
|
281 |
$translations[ $lang->slug ] = $tr_id;
|
282 |
$this->model->post->save_translations( $tr_id, $translations );
|
283 |
|
@@ -286,9 +290,9 @@ class PLL_CRUD_Posts {
|
|
286 |
*
|
287 |
* @since 1.6.4
|
288 |
*
|
289 |
-
* @param int $post_id
|
290 |
-
* @param int $tr_id
|
291 |
-
* @param string $slug
|
292 |
*/
|
293 |
do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug );
|
294 |
return $tr_id;
|
227 |
if ( ! empty( $ids ) ) {
|
228 |
// Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ).
|
229 |
require_once ABSPATH . 'wp-admin/includes/image.php'; // In case the file is deleted outside admin.
|
230 |
+
wp_update_attachment_metadata( $ids[0], wp_slash( wp_generate_attachment_metadata( $ids[0], $file ) ) ); // Directly uses update_post_meta, so expects slashed.
|
231 |
return ''; // Prevent deleting the main file.
|
232 |
}
|
233 |
|
239 |
*
|
240 |
* @since 1.8
|
241 |
*
|
242 |
+
* @param int $post_id Original attachment id.
|
243 |
+
* @param string|object $lang New translation language.
|
244 |
+
* @return int Attachment id of the translated media.
|
245 |
*/
|
246 |
public function create_media_translation( $post_id, $lang ) {
|
247 |
if ( empty( $post_id ) ) {
|
254 |
return $post;
|
255 |
}
|
256 |
|
257 |
+
$lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
|
258 |
|
259 |
+
// Create a new attachment ( translate attachment parent if exists ).
|
260 |
+
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
|
261 |
$post->ID = null; // Will force the creation
|
262 |
$post->post_parent = ( $post->post_parent && $tr_parent = $this->model->post->get_translation( $post->post_parent, $lang->slug ) ) ? $tr_parent : 0;
|
263 |
+
$post->tax_input = array( 'language' => array( $lang->slug ) ); // Assigns the language.
|
264 |
$tr_id = wp_insert_attachment( wp_slash( (array) $post ) );
|
265 |
+
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
|
266 |
|
267 |
+
// Copy metadata.
|
268 |
+
if ( $data = wp_get_attachment_metadata( $post_id, true ) ) { // Unfiltered.
|
269 |
+
wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
|
|
|
|
|
270 |
}
|
271 |
|
272 |
+
// Copy attached file.
|
273 |
+
if ( $file = get_attached_file( $post_id, true ) ) { // Unfiltered.
|
274 |
+
update_attached_file( $tr_id, wp_slash( $file ) ); // Directly uses update_post_meta, so expects slashed.
|
275 |
+
}
|
276 |
|
277 |
+
// Copy alternative text. Direct use of the meta as there is no filtered wrapper to manipulate it.
|
278 |
+
if ( $text = get_post_meta( $post_id, '_wp_attachment_image_alt', true ) ) {
|
279 |
+
add_post_meta( $tr_id, '_wp_attachment_image_alt', wp_slash( $text ) );
|
280 |
}
|
281 |
|
282 |
+
$this->model->post->set_language( $tr_id, $lang );
|
283 |
+
|
284 |
+
$translations = $this->model->post->get_translations( $post_id );
|
285 |
$translations[ $lang->slug ] = $tr_id;
|
286 |
$this->model->post->save_translations( $tr_id, $translations );
|
287 |
|
290 |
*
|
291 |
* @since 1.6.4
|
292 |
*
|
293 |
+
* @param int $post_id Post id of the source media.
|
294 |
+
* @param int $tr_id Post id of the new media translation.
|
295 |
+
* @param string $slug Language code of the new translation.
|
296 |
*/
|
297 |
do_action( 'pll_translate_media', $post_id, $tr_id, $lang->slug );
|
298 |
return $tr_id;
|
include/filters.php
CHANGED
@@ -335,9 +335,9 @@ class PLL_Filters {
|
|
335 |
* @return array Personal data
|
336 |
*/
|
337 |
public function user_data_exporter( $email_address ) {
|
338 |
-
$email_address
|
339 |
-
|
340 |
-
$
|
341 |
|
342 |
if ( $user = get_user_by( 'email', $email_address ) ) {
|
343 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
335 |
* @return array Personal data
|
336 |
*/
|
337 |
public function user_data_exporter( $email_address ) {
|
338 |
+
$email_address = trim( $email_address );
|
339 |
+
$data_to_export = array();
|
340 |
+
$user_data_to_export = array();
|
341 |
|
342 |
if ( $user = get_user_by( 'email', $email_address ) ) {
|
343 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
include/functions.php
CHANGED
@@ -18,54 +18,7 @@ if ( ! function_exists( 'wpcom_vip_get_page_by_title' ) ) {
|
|
18 |
* @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
|
19 |
*/
|
20 |
function wpcom_vip_get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) {
|
21 |
-
return get_page_by_title( $page_title, $output, $post_type );
|
22 |
-
}
|
23 |
-
}
|
24 |
-
|
25 |
-
if ( ! function_exists( 'wpcom_vip_get_category_by_slug' ) ) {
|
26 |
-
/**
|
27 |
-
* Retrieve category object by category slug.
|
28 |
-
*
|
29 |
-
* @since 2.0
|
30 |
-
*
|
31 |
-
* @param string $slug The category slug.
|
32 |
-
* @return object Category data object
|
33 |
-
*/
|
34 |
-
function wpcom_vip_get_category_by_slug( $slug ) {
|
35 |
-
return get_category_by_slug( $slug );
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
if ( ! function_exists( 'wpcom_vip_get_term_by' ) ) {
|
40 |
-
/**
|
41 |
-
* Get all Term data from database by Term field and data.
|
42 |
-
*
|
43 |
-
* @since 2.0
|
44 |
-
*
|
45 |
-
* @param string $field Either 'slug', 'name', 'id' (term_id), or 'term_taxonomy_id'
|
46 |
-
* @param string|int $value Search for this term value
|
47 |
-
* @param string $taxonomy Taxonomy name. Optional, if `$field` is 'term_taxonomy_id'.
|
48 |
-
* @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N. Default OBJECT.
|
49 |
-
* @param string $filter Optional, default is raw or no WordPress defined filter will applied.
|
50 |
-
* @return WP_Term|array|false WP_Term instance (or array) on success. Will return false if `$taxonomy` does not exist or `$term` was not found.
|
51 |
-
*/
|
52 |
-
function wpcom_vip_get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) {
|
53 |
-
return get_term_by( $field, $value, $taxonomy, $output, $filter );
|
54 |
-
}
|
55 |
-
}
|
56 |
-
|
57 |
-
if ( ! function_exists( 'wpcom_vip_get_term_link' ) ) {
|
58 |
-
/**
|
59 |
-
* Generate a permalink for a taxonomy term archive.
|
60 |
-
*
|
61 |
-
* @since 2.0
|
62 |
-
*
|
63 |
-
* @param object|int|string $term The term object, ID, or slug whose link will be retrieved.
|
64 |
-
* @param string $taxonomy Optional. Taxonomy. Default empty.
|
65 |
-
* @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist.
|
66 |
-
*/
|
67 |
-
function wpcom_vip_get_term_link( $term, $taxonomy = '' ) {
|
68 |
-
return get_term_link( $term, $taxonomy );
|
69 |
}
|
70 |
}
|
71 |
|
18 |
* @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
|
19 |
*/
|
20 |
function wpcom_vip_get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) {
|
21 |
+
return get_page_by_title( $page_title, $output, $post_type ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_page_by_title_get_page_by_title
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
}
|
23 |
}
|
24 |
|
include/language.php
CHANGED
@@ -102,7 +102,7 @@ class PLL_Language {
|
|
102 |
* @return array Flag informations.
|
103 |
*/
|
104 |
public static function get_flag_informations( $code ) {
|
105 |
-
$flag
|
106 |
|
107 |
// Polylang builtin flags
|
108 |
if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
|
@@ -145,7 +145,7 @@ class PLL_Language {
|
|
145 |
* @since 1.2
|
146 |
*/
|
147 |
public function set_flag() {
|
148 |
-
$flags
|
149 |
|
150 |
// Custom flags ?
|
151 |
$directories = array(
|
@@ -210,19 +210,32 @@ class PLL_Language {
|
|
210 |
*/
|
211 |
$this->{$key} = apply_filters(
|
212 |
'pll_get_flag',
|
213 |
-
|
214 |
-
'<img src="%s" title="%s" alt="%s"%s%s />',
|
215 |
-
$flag['src'],
|
216 |
-
esc_attr( $title ),
|
217 |
-
esc_attr( $this->name ),
|
218 |
-
empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] ),
|
219 |
-
empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] )
|
220 |
-
),
|
221 |
$this->slug
|
222 |
);
|
223 |
}
|
224 |
}
|
225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
/**
|
227 |
* Replace flag by custom flag
|
228 |
* Takes care of url scheme
|
102 |
* @return array Flag informations.
|
103 |
*/
|
104 |
public static function get_flag_informations( $code ) {
|
105 |
+
$flag = array( 'url' => '' );
|
106 |
|
107 |
// Polylang builtin flags
|
108 |
if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
|
145 |
* @since 1.2
|
146 |
*/
|
147 |
public function set_flag() {
|
148 |
+
$flags = array( 'flag' => self::get_flag_informations( $this->flag_code ) );
|
149 |
|
150 |
// Custom flags ?
|
151 |
$directories = array(
|
210 |
*/
|
211 |
$this->{$key} = apply_filters(
|
212 |
'pll_get_flag',
|
213 |
+
self::get_flag_html( $flag, $title, $this->name ),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
$this->slug
|
215 |
);
|
216 |
}
|
217 |
}
|
218 |
|
219 |
+
/**
|
220 |
+
* Get HTML code for flag
|
221 |
+
*
|
222 |
+
* @since 2.7
|
223 |
+
*
|
224 |
+
* @param array $flag flag properties: src, width and height
|
225 |
+
* @param string $title optional title attribute
|
226 |
+
* @param string $alt optional alt attribute
|
227 |
+
*/
|
228 |
+
public static function get_flag_html( $flag, $title = '', $alt = '' ) {
|
229 |
+
return empty( $flag['src'] ) ? '' : sprintf(
|
230 |
+
'<img src="%s"%s%s%s%s />',
|
231 |
+
$flag['src'],
|
232 |
+
empty( $title ) ? '' : sprintf( ' title="%s"', esc_attr( $title ) ),
|
233 |
+
empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) ),
|
234 |
+
empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] ),
|
235 |
+
empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] )
|
236 |
+
);
|
237 |
+
}
|
238 |
+
|
239 |
/**
|
240 |
* Replace flag by custom flag
|
241 |
* Takes care of url scheme
|
include/license.php
CHANGED
@@ -153,7 +153,7 @@ class PLL_License {
|
|
153 |
$response = wp_remote_post(
|
154 |
$this->api_url,
|
155 |
array(
|
156 |
-
'timeout' =>
|
157 |
'sslverify' => false,
|
158 |
'body' => $api_params,
|
159 |
)
|
@@ -175,4 +175,122 @@ class PLL_License {
|
|
175 |
|
176 |
update_option( 'polylang_licenses', $licenses ); // FIXME called multiple times when saving all licenses
|
177 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
153 |
$response = wp_remote_post(
|
154 |
$this->api_url,
|
155 |
array(
|
156 |
+
'timeout' => 3,
|
157 |
'sslverify' => false,
|
158 |
'body' => $api_params,
|
159 |
)
|
175 |
|
176 |
update_option( 'polylang_licenses', $licenses ); // FIXME called multiple times when saving all licenses
|
177 |
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Get the html form field in a table row (one per license key) for display
|
181 |
+
*
|
182 |
+
* @since 2.7
|
183 |
+
*
|
184 |
+
* @return string
|
185 |
+
*/
|
186 |
+
public function get_form_field() {
|
187 |
+
if ( ! empty( $this->license_data ) ) {
|
188 |
+
$license = $this->license_data;
|
189 |
+
}
|
190 |
+
|
191 |
+
$class = 'license-null';
|
192 |
+
|
193 |
+
$out = sprintf(
|
194 |
+
'<td><label for="pll-licenses[%1$s]">%2$s</label></td>' .
|
195 |
+
'<td><input name="licenses[%1$s]" id="pll-licenses[%1$s]" type="text" value="%3$s" class="regular-text code" />',
|
196 |
+
esc_attr( $this->id ),
|
197 |
+
esc_attr( $this->name ),
|
198 |
+
esc_html( $this->license_key )
|
199 |
+
);
|
200 |
+
|
201 |
+
if ( ! empty( $license ) && is_object( $license ) ) {
|
202 |
+
$now = time();
|
203 |
+
$expiration = isset( $license->expires ) ? strtotime( $license->expires ) : false;
|
204 |
+
|
205 |
+
// Special case: the license expired after the last check
|
206 |
+
if ( $license->success && $expiration && $expiration < $now ) {
|
207 |
+
$license->success = false;
|
208 |
+
$license->error = 'expired';
|
209 |
+
}
|
210 |
+
|
211 |
+
if ( false === $license->success ) {
|
212 |
+
$class = 'notice-error notice-alt';
|
213 |
+
|
214 |
+
switch ( $license->error ) {
|
215 |
+
case 'expired':
|
216 |
+
$message = sprintf(
|
217 |
+
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
218 |
+
esc_html__( 'Your license key expired on %1$s. Please %2$srenew your license key%3$s.', 'polylang' ),
|
219 |
+
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
220 |
+
sprintf( '<a href="%s" target="_blank">', esc_url( 'https://polylang.pro/checkout/?edd_license_key=' . $this->license_key ) ),
|
221 |
+
'</a>'
|
222 |
+
);
|
223 |
+
break;
|
224 |
+
|
225 |
+
case 'disabled':
|
226 |
+
case 'revoked':
|
227 |
+
$message = esc_html__( 'Your license key has been disabled.', 'polylang' );
|
228 |
+
break;
|
229 |
+
|
230 |
+
case 'missing':
|
231 |
+
$message = sprintf(
|
232 |
+
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
233 |
+
esc_html__( 'Invalid license. Please %1$svisit your account page%2$s and verify it.', 'polylang' ),
|
234 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
235 |
+
'</a>'
|
236 |
+
);
|
237 |
+
break;
|
238 |
+
|
239 |
+
case 'invalid':
|
240 |
+
case 'site_inactive':
|
241 |
+
$message = sprintf(
|
242 |
+
/* translators: %1$s is a product name, %2$s is link start tag, %3$s is link end tag. */
|
243 |
+
esc_html__( 'Your %1$s license key is not active for this URL. Please %2$svisit your account page%3$s to manage your license key URLs.', 'polylang' ),
|
244 |
+
esc_html( $this->name ),
|
245 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
246 |
+
'</a>'
|
247 |
+
);
|
248 |
+
break;
|
249 |
+
|
250 |
+
case 'item_name_mismatch':
|
251 |
+
/* translators: %s is a product name */
|
252 |
+
$message = sprintf( esc_html__( 'This is not a %s license key.', 'polylang' ), esc_html( $this->name ) );
|
253 |
+
break;
|
254 |
+
|
255 |
+
case 'no_activations_left':
|
256 |
+
$message = sprintf(
|
257 |
+
/* translators: %1$s is link start tag, %2$s is link end tag */
|
258 |
+
esc_html__( 'Your license key has reached its activation limit. %1$sView possible upgrades%2$s now.', 'polylang' ),
|
259 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
260 |
+
'</a>'
|
261 |
+
);
|
262 |
+
break;
|
263 |
+
}
|
264 |
+
} else {
|
265 |
+
$class = 'license-valid';
|
266 |
+
|
267 |
+
$out .= sprintf( '<button id="deactivate_%s" type="button" class="button button-secondary pll-deactivate-license">%s</button>', esc_attr( $this->id ), esc_html__( 'Deactivate', 'polylang' ) );
|
268 |
+
|
269 |
+
if ( 'lifetime' === $license->expires ) {
|
270 |
+
$message = esc_html__( 'The license key never expires.', 'polylang' );
|
271 |
+
} elseif ( $expiration > $now && $expiration - $now < ( DAY_IN_SECONDS * 30 ) ) {
|
272 |
+
$class = 'notice-warning notice-alt';
|
273 |
+
$message = sprintf(
|
274 |
+
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
275 |
+
esc_html__( 'Your license key will expire soon! Precisely, it will expire on %1$s. %2$sRenew your license key today!%3$s.', 'polylang' ),
|
276 |
+
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
277 |
+
sprintf( '<a href="%s" target="_blank">', esc_url( 'https://polylang.pro/checkout/?edd_license_key=' . $this->license_key ) ),
|
278 |
+
'</a>'
|
279 |
+
);
|
280 |
+
} else {
|
281 |
+
$message = sprintf(
|
282 |
+
/* translators: %s is a date */
|
283 |
+
esc_html__( 'Your license key expires on %s.', 'polylang' ),
|
284 |
+
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) )
|
285 |
+
);
|
286 |
+
}
|
287 |
+
}
|
288 |
+
}
|
289 |
+
|
290 |
+
if ( ! empty( $message ) ) {
|
291 |
+
$out .= '<p>' . $message . '</p>';
|
292 |
+
}
|
293 |
+
|
294 |
+
return sprintf( '<tr id="pll-license-%s" class="%s">%s</tr>', esc_attr( $this->id ), $class, $out );
|
295 |
+
}
|
296 |
}
|
include/links-directory.php
CHANGED
@@ -59,10 +59,10 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
59 |
if ( ! empty( $lang ) ) {
|
60 |
$base = $this->options['rewrite'] ? '' : 'language/';
|
61 |
$slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base . $lang->slug . '/';
|
62 |
-
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '
|
63 |
|
64 |
if ( false === strpos( $url, $new = $root . $slug ) ) {
|
65 |
-
$pattern =
|
66 |
$pattern = '#' . $pattern . '#';
|
67 |
return preg_replace( $pattern, $new, $url, 1 ); // Only once
|
68 |
}
|
@@ -80,6 +80,8 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
80 |
* @return string modified url
|
81 |
*/
|
82 |
public function remove_language_from_link( $url ) {
|
|
|
|
|
83 |
foreach ( $this->model->get_languages_list() as $language ) {
|
84 |
if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) {
|
85 |
$languages[] = $language->slug;
|
@@ -87,10 +89,10 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
87 |
}
|
88 |
|
89 |
if ( ! empty( $languages ) ) {
|
90 |
-
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '
|
91 |
|
92 |
-
$pattern =
|
93 |
-
$pattern = '#' . $pattern . ( $this->options['rewrite'] ? '' : 'language
|
94 |
$url = preg_replace( $pattern, $root, $url );
|
95 |
}
|
96 |
return $url;
|
@@ -115,8 +117,8 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
115 |
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : $this->home . '/' . $this->root;
|
116 |
|
117 |
$pattern = wp_parse_url( $root . ( $this->options['rewrite'] ? '' : 'language/' ), PHP_URL_PATH );
|
118 |
-
$pattern =
|
119 |
-
$pattern = '#^' . $pattern . '(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(
|
120 |
return preg_match( $pattern, trailingslashit( $path ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
|
121 |
}
|
122 |
|
59 |
if ( ! empty( $lang ) ) {
|
60 |
$base = $this->options['rewrite'] ? '' : 'language/';
|
61 |
$slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base . $lang->slug . '/';
|
62 |
+
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '#^https?://#', '://', $this->home . '/' . $this->root );
|
63 |
|
64 |
if ( false === strpos( $url, $new = $root . $slug ) ) {
|
65 |
+
$pattern = preg_quote( $root, '#' );
|
66 |
$pattern = '#' . $pattern . '#';
|
67 |
return preg_replace( $pattern, $new, $url, 1 ); // Only once
|
68 |
}
|
80 |
* @return string modified url
|
81 |
*/
|
82 |
public function remove_language_from_link( $url ) {
|
83 |
+
$languages = array();
|
84 |
+
|
85 |
foreach ( $this->model->get_languages_list() as $language ) {
|
86 |
if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) {
|
87 |
$languages[] = $language->slug;
|
89 |
}
|
90 |
|
91 |
if ( ! empty( $languages ) ) {
|
92 |
+
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '#^https?://#', '://', $this->home . '/' . $this->root );
|
93 |
|
94 |
+
$pattern = preg_quote( $root, '#' );
|
95 |
+
$pattern = '#' . $pattern . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')(/|$)#';
|
96 |
$url = preg_replace( $pattern, $root, $url );
|
97 |
}
|
98 |
return $url;
|
117 |
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : $this->home . '/' . $this->root;
|
118 |
|
119 |
$pattern = wp_parse_url( $root . ( $this->options['rewrite'] ? '' : 'language/' ), PHP_URL_PATH );
|
120 |
+
$pattern = preg_quote( $pattern, '#' );
|
121 |
+
$pattern = '#^' . $pattern . '(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(/|$)#';
|
122 |
return preg_match( $pattern, trailingslashit( $path ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
|
123 |
}
|
124 |
|
include/links-domain.php
CHANGED
@@ -38,7 +38,7 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
38 |
*/
|
39 |
public function add_language_to_link( $url, $lang ) {
|
40 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
41 |
-
$url = preg_replace( '
|
42 |
}
|
43 |
return $url;
|
44 |
}
|
@@ -54,7 +54,7 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
54 |
*/
|
55 |
public function remove_language_from_link( $url ) {
|
56 |
if ( ! empty( $this->hosts ) ) {
|
57 |
-
$url = preg_replace( '
|
58 |
}
|
59 |
return $url;
|
60 |
}
|
@@ -83,13 +83,8 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
83 |
$hosts = array();
|
84 |
foreach ( $this->options['domains'] as $lang => $domain ) {
|
85 |
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
86 |
-
//
|
87 |
-
|
88 |
-
// The use of the constant is mandatory in PHP 7.2 and PHP 7.3 to avoid a deprecated notice.
|
89 |
-
$hosts[ $lang ] = defined( 'INTL_IDNA_VARIANT_UTS46' ) ? idn_to_ascii( $host, 0, INTL_IDNA_VARIANT_UTS46 ) : idn_to_ascii( $host );
|
90 |
-
} else {
|
91 |
-
$hosts[ $lang ] = Requests_IDNAEncoder::encode( $host );
|
92 |
-
}
|
93 |
}
|
94 |
|
95 |
return $hosts;
|
38 |
*/
|
39 |
public function add_language_to_link( $url, $lang ) {
|
40 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
41 |
+
$url = preg_replace( '#://(' . wp_parse_url( $this->home, PHP_URL_HOST ) . ')($|/.*)#', '://' . $this->hosts[ $lang->slug ] . '$2', $url );
|
42 |
}
|
43 |
return $url;
|
44 |
}
|
54 |
*/
|
55 |
public function remove_language_from_link( $url ) {
|
56 |
if ( ! empty( $this->hosts ) ) {
|
57 |
+
$url = preg_replace( '#://(' . implode( '|', $this->hosts ) . ')($|/.*)#', '://' . wp_parse_url( $this->home, PHP_URL_HOST ) . '$2', $url );
|
58 |
}
|
59 |
return $url;
|
60 |
}
|
83 |
$hosts = array();
|
84 |
foreach ( $this->options['domains'] as $lang => $domain ) {
|
85 |
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
86 |
+
// The use of the constant is mandatory in PHP 7.2 and PHP 7.3 to avoid a deprecated notice.
|
87 |
+
$hosts[ $lang ] = defined( 'INTL_IDNA_VARIANT_UTS46' ) ? idn_to_ascii( $host, 0, INTL_IDNA_VARIANT_UTS46 ) : idn_to_ascii( $host );
|
|
|
|
|
|
|
|
|
|
|
88 |
}
|
89 |
|
90 |
return $hosts;
|
include/links-permalinks.php
CHANGED
@@ -44,7 +44,7 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
44 |
* @param string $modified_url The link to the first page
|
45 |
* @param string $original_url The link to the original paged page
|
46 |
*/
|
47 |
-
return apply_filters( 'pll_remove_paged_from_link', preg_replace( '
|
48 |
}
|
49 |
|
50 |
/**
|
44 |
* @param string $modified_url The link to the first page
|
45 |
* @param string $original_url The link to the original paged page
|
46 |
*/
|
47 |
+
return apply_filters( 'pll_remove_paged_from_link', preg_replace( '#/page/[0-9]+/?#', $this->use_trailing_slashes ? '/' : '', $url ), $url );
|
48 |
}
|
49 |
|
50 |
/**
|
include/links-subdomain.php
CHANGED
@@ -49,6 +49,8 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
49 |
* @return string modified url
|
50 |
*/
|
51 |
public function remove_language_from_link( $url ) {
|
|
|
|
|
52 |
foreach ( $this->model->get_languages_list() as $language ) {
|
53 |
if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) {
|
54 |
$languages[] = $language->slug;
|
@@ -56,7 +58,7 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
56 |
}
|
57 |
|
58 |
if ( ! empty( $languages ) ) {
|
59 |
-
$url = preg_replace( '
|
60 |
}
|
61 |
|
62 |
return $url;
|
49 |
* @return string modified url
|
50 |
*/
|
51 |
public function remove_language_from_link( $url ) {
|
52 |
+
$languages = array();
|
53 |
+
|
54 |
foreach ( $this->model->get_languages_list() as $language ) {
|
55 |
if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) {
|
56 |
$languages[] = $language->slug;
|
58 |
}
|
59 |
|
60 |
if ( ! empty( $languages ) ) {
|
61 |
+
$url = preg_replace( '#://(' . implode( '|', $languages ) . ')\.#', $this->www, $url );
|
62 |
}
|
63 |
|
64 |
return $url;
|
include/model.php
CHANGED
@@ -182,6 +182,7 @@ class PLL_Model {
|
|
182 |
$this->cache->set( 'language:' . $lang->tl_term_id, $lang );
|
183 |
$this->cache->set( 'language:' . $lang->slug, $lang );
|
184 |
$this->cache->set( 'language:' . $lang->locale, $lang );
|
|
|
185 |
}
|
186 |
$return = $this->cache->get( 'language:' . $value );
|
187 |
}
|
@@ -427,6 +428,7 @@ class PLL_Model {
|
|
427 |
global $wpdb;
|
428 |
|
429 |
$term_name = trim( wp_unslash( $term_name ) );
|
|
|
430 |
|
431 |
$select = "SELECT t.term_id FROM $wpdb->terms AS t";
|
432 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
@@ -448,13 +450,13 @@ class PLL_Model {
|
|
448 |
* @since 1.2
|
449 |
*
|
450 |
* @param object $lang PLL_Language instance.
|
451 |
-
* @param array $q WP_Query arguments ( accepted: post_type, m, year, monthnum, day, author, author_name, post_format ).
|
452 |
* @return int
|
453 |
*/
|
454 |
public function count_posts( $lang, $q = array() ) {
|
455 |
global $wpdb;
|
456 |
|
457 |
-
$q = wp_parse_args( $q, array( 'post_type' => 'post' ) );
|
458 |
|
459 |
if ( ! is_array( $q['post_type'] ) ) {
|
460 |
$q['post_type'] = array( $q['post_type'] );
|
@@ -476,7 +478,7 @@ class PLL_Model {
|
|
476 |
if ( false === $counts ) {
|
477 |
$select = "SELECT pll_tr.term_taxonomy_id, COUNT( * ) AS num_posts FROM {$wpdb->posts}";
|
478 |
$join = $this->post->join_clause();
|
479 |
-
$where = " WHERE post_status = '
|
480 |
$where .= sprintf( " AND {$wpdb->posts}.post_type IN ( '%s' )", join( "', '", esc_sql( $q['post_type'] ) ) );
|
481 |
$where .= $this->post->where_clause( $this->get_languages_list() );
|
482 |
$groupby = ' GROUP BY pll_tr.term_taxonomy_id';
|
@@ -610,7 +612,7 @@ class PLL_Model {
|
|
610 |
|
611 |
if ( ! empty( $o ) && is_object( $this->$o ) && method_exists( $this->$o, $f ) ) {
|
612 |
if ( WP_DEBUG ) {
|
613 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
614 |
$i = 1 + empty( $debug[1]['line'] ); // the file and line are in $debug[2] if the function was called using call_user_func
|
615 |
|
616 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
@@ -627,7 +629,7 @@ class PLL_Model {
|
|
627 |
return call_user_func_array( array( $this->$o, $f ), $args );
|
628 |
}
|
629 |
|
630 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
631 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
632 |
sprintf(
|
633 |
'Call to undefined function PLL()->model->%1$s() in %2$s on line %3$s' . "\nError handler",
|
182 |
$this->cache->set( 'language:' . $lang->tl_term_id, $lang );
|
183 |
$this->cache->set( 'language:' . $lang->slug, $lang );
|
184 |
$this->cache->set( 'language:' . $lang->locale, $lang );
|
185 |
+
$this->cache->set( 'language:' . $lang->w3c, $lang );
|
186 |
}
|
187 |
$return = $this->cache->get( 'language:' . $value );
|
188 |
}
|
428 |
global $wpdb;
|
429 |
|
430 |
$term_name = trim( wp_unslash( $term_name ) );
|
431 |
+
$term_name = _wp_specialchars( $term_name );
|
432 |
|
433 |
$select = "SELECT t.term_id FROM $wpdb->terms AS t";
|
434 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
450 |
* @since 1.2
|
451 |
*
|
452 |
* @param object $lang PLL_Language instance.
|
453 |
+
* @param array $q WP_Query arguments ( accepted: post_type, m, year, monthnum, day, author, author_name, post_format, post_status ).
|
454 |
* @return int
|
455 |
*/
|
456 |
public function count_posts( $lang, $q = array() ) {
|
457 |
global $wpdb;
|
458 |
|
459 |
+
$q = wp_parse_args( $q, array( 'post_type' => 'post', 'post_status' => 'publish' ) );
|
460 |
|
461 |
if ( ! is_array( $q['post_type'] ) ) {
|
462 |
$q['post_type'] = array( $q['post_type'] );
|
478 |
if ( false === $counts ) {
|
479 |
$select = "SELECT pll_tr.term_taxonomy_id, COUNT( * ) AS num_posts FROM {$wpdb->posts}";
|
480 |
$join = $this->post->join_clause();
|
481 |
+
$where = sprintf( " WHERE post_status = '%s'", esc_sql( $q['post_status'] ) );
|
482 |
$where .= sprintf( " AND {$wpdb->posts}.post_type IN ( '%s' )", join( "', '", esc_sql( $q['post_type'] ) ) );
|
483 |
$where .= $this->post->where_clause( $this->get_languages_list() );
|
484 |
$groupby = ' GROUP BY pll_tr.term_taxonomy_id';
|
612 |
|
613 |
if ( ! empty( $o ) && is_object( $this->$o ) && method_exists( $this->$o, $f ) ) {
|
614 |
if ( WP_DEBUG ) {
|
615 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
616 |
$i = 1 + empty( $debug[1]['line'] ); // the file and line are in $debug[2] if the function was called using call_user_func
|
617 |
|
618 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
629 |
return call_user_func_array( array( $this->$o, $f ), $args );
|
630 |
}
|
631 |
|
632 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
633 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
634 |
sprintf(
|
635 |
'Call to undefined function PLL()->model->%1$s() in %2$s on line %3$s' . "\nError handler",
|
include/nav-menu.php
CHANGED
@@ -57,6 +57,8 @@ class PLL_Nav_Menu {
|
|
57 |
static $once;
|
58 |
global $_wp_registered_nav_menus;
|
59 |
|
|
|
|
|
60 |
if ( isset( $_wp_registered_nav_menus ) && ! $once ) {
|
61 |
foreach ( $_wp_registered_nav_menus as $loc => $name ) {
|
62 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
57 |
static $once;
|
58 |
global $_wp_registered_nav_menus;
|
59 |
|
60 |
+
$arr = array();
|
61 |
+
|
62 |
if ( isset( $_wp_registered_nav_menus ) && ! $once ) {
|
63 |
foreach ( $_wp_registered_nav_menus as $loc => $name ) {
|
64 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
include/rest-request.php
CHANGED
@@ -51,9 +51,7 @@ class PLL_REST_Request extends PLL_Base {
|
|
51 |
|
52 |
// Share term slugs
|
53 |
if ( get_option( 'permalink_structure' ) && $this->options['force_lang'] && class_exists( 'PLL_Share_Term_Slug' ) ) {
|
54 |
-
$this->share_term_slug =
|
55 |
-
new PLL_Frontend_Share_Term_Slug( $this ) :
|
56 |
-
new PLL_Share_Term_Slug( $this );
|
57 |
}
|
58 |
|
59 |
// Translate slugs, only for pretty permalinks
|
@@ -63,6 +61,10 @@ class PLL_REST_Request extends PLL_Base {
|
|
63 |
$this->translate_slugs = new PLL_Translate_Slugs( $slugs_model, $curlang );
|
64 |
}
|
65 |
|
|
|
|
|
|
|
|
|
66 |
if ( class_exists( 'PLL_Sync_Post_REST' ) ) {
|
67 |
$this->sync_post = new PLL_Sync_Post_REST( $this );
|
68 |
}
|
51 |
|
52 |
// Share term slugs
|
53 |
if ( get_option( 'permalink_structure' ) && $this->options['force_lang'] && class_exists( 'PLL_Share_Term_Slug' ) ) {
|
54 |
+
$this->share_term_slug = new PLL_Share_Term_Slug( $this );
|
|
|
|
|
55 |
}
|
56 |
|
57 |
// Translate slugs, only for pretty permalinks
|
61 |
$this->translate_slugs = new PLL_Translate_Slugs( $slugs_model, $curlang );
|
62 |
}
|
63 |
|
64 |
+
if ( class_exists( 'PLL_Sync_Post_Model' ) ) {
|
65 |
+
$this->sync_post_model = new PLL_Sync_Post_Model( $this );
|
66 |
+
}
|
67 |
+
|
68 |
if ( class_exists( 'PLL_Sync_Post_REST' ) ) {
|
69 |
$this->sync_post = new PLL_Sync_Post_REST( $this );
|
70 |
}
|
include/switcher.php
CHANGED
@@ -42,8 +42,8 @@ class PLL_Switcher {
|
|
42 |
* @return array
|
43 |
*/
|
44 |
protected function get_elements( $links, $args ) {
|
45 |
-
|
46 |
$first = true;
|
|
|
47 |
|
48 |
foreach ( $links->model->get_languages_list( array( 'hide_empty' => $args['hide_if_empty'] ) ) as $language ) {
|
49 |
$id = (int) $language->term_id;
|
@@ -100,7 +100,7 @@ class PLL_Switcher {
|
|
100 |
$out[ $slug ] = compact( 'id', 'order', 'slug', 'locale', 'name', 'url', 'flag', 'current_lang', 'no_translation', 'classes' );
|
101 |
}
|
102 |
|
103 |
-
return
|
104 |
}
|
105 |
|
106 |
/**
|
@@ -187,6 +187,8 @@ class PLL_Switcher {
|
|
187 |
|
188 |
// Javascript to switch the language when using a dropdown list
|
189 |
if ( $args['dropdown'] ) {
|
|
|
|
|
190 |
foreach ( $links->model->get_languages_list() as $language ) {
|
191 |
$url = $links->get_translation_url( $language );
|
192 |
$urls[ $language->slug ] = $args['force_home'] || empty( $url ) ? $links->get_home_url( $language ) : $url;
|
42 |
* @return array
|
43 |
*/
|
44 |
protected function get_elements( $links, $args ) {
|
|
|
45 |
$first = true;
|
46 |
+
$out = array();
|
47 |
|
48 |
foreach ( $links->model->get_languages_list( array( 'hide_empty' => $args['hide_if_empty'] ) ) as $language ) {
|
49 |
$id = (int) $language->term_id;
|
100 |
$out[ $slug ] = compact( 'id', 'order', 'slug', 'locale', 'name', 'url', 'flag', 'current_lang', 'no_translation', 'classes' );
|
101 |
}
|
102 |
|
103 |
+
return $out;
|
104 |
}
|
105 |
|
106 |
/**
|
187 |
|
188 |
// Javascript to switch the language when using a dropdown list
|
189 |
if ( $args['dropdown'] ) {
|
190 |
+
$urls = array();
|
191 |
+
|
192 |
foreach ( $links->model->get_languages_list() as $language ) {
|
193 |
$url = $links->get_translation_url( $language );
|
194 |
$urls[ $language->slug ] = $args['force_home'] || empty( $url ) ? $links->get_home_url( $language ) : $url;
|
include/translated-object.php
CHANGED
@@ -50,6 +50,7 @@ abstract class PLL_Translated_Object {
|
|
50 |
$taxonomies = array( $this->tax_language, $this->tax_translations );
|
51 |
|
52 |
// query terms
|
|
|
53 |
foreach ( wp_get_object_terms( $object_id, $taxonomies, array( 'update_term_meta_cache' => false ) ) as $t ) {
|
54 |
$terms[ $t->taxonomy ] = $t;
|
55 |
if ( $t->taxonomy == $taxonomy ) {
|
@@ -239,7 +240,6 @@ abstract class PLL_Translated_Object {
|
|
239 |
* @return string where clause
|
240 |
*/
|
241 |
public function where_clause( $lang ) {
|
242 |
-
global $wpdb;
|
243 |
$tt_id = $this->tax_tt;
|
244 |
|
245 |
// $lang is an object
|
@@ -250,7 +250,8 @@ abstract class PLL_Translated_Object {
|
|
250 |
|
251 |
// $lang is a comma separated list of slugs ( or an array of slugs )
|
252 |
// generally the case is the query is coming from outside with 'lang' parameter
|
253 |
-
$slugs
|
|
|
254 |
foreach ( $slugs as $slug ) {
|
255 |
$languages[] = absint( $this->model->get_language( $slug )->$tt_id );
|
256 |
}
|
50 |
$taxonomies = array( $this->tax_language, $this->tax_translations );
|
51 |
|
52 |
// query terms
|
53 |
+
$terms = array();
|
54 |
foreach ( wp_get_object_terms( $object_id, $taxonomies, array( 'update_term_meta_cache' => false ) ) as $t ) {
|
55 |
$terms[ $t->taxonomy ] = $t;
|
56 |
if ( $t->taxonomy == $taxonomy ) {
|
240 |
* @return string where clause
|
241 |
*/
|
242 |
public function where_clause( $lang ) {
|
|
|
243 |
$tt_id = $this->tax_tt;
|
244 |
|
245 |
// $lang is an object
|
250 |
|
251 |
// $lang is a comma separated list of slugs ( or an array of slugs )
|
252 |
// generally the case is the query is coming from outside with 'lang' parameter
|
253 |
+
$slugs = is_array( $lang ) ? $lang : explode( ',', $lang );
|
254 |
+
$languages = array();
|
255 |
foreach ( $slugs as $slug ) {
|
256 |
$languages[] = absint( $this->model->get_language( $slug )->$tt_id );
|
257 |
}
|
include/translated-term.php
CHANGED
@@ -85,7 +85,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
85 |
|
86 |
// get_term_by still not cached in WP 3.5.1 but internally, the function is always called by term_id
|
87 |
elseif ( is_string( $value ) && $taxonomy ) {
|
88 |
-
$term_id =
|
89 |
}
|
90 |
|
91 |
// Get the language and make sure it is a PLL_Language object
|
@@ -128,7 +128,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
128 |
|
129 |
if ( ! doing_action( 'pre_delete_term' ) && $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM $wpdb->terms WHERE term_id = %d;", $id ) ) ) {
|
130 |
// Always keep a group for terms to allow relationships remap when importing from a WXR file
|
131 |
-
$translations
|
132 |
wp_insert_term( $group = uniqid( 'pll_' ), 'term_translations', array( 'description' => maybe_serialize( $translations ) ) );
|
133 |
wp_set_object_terms( $id, $group, 'term_translations' );
|
134 |
}
|
@@ -158,6 +158,8 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
158 |
* @return array unmodified $terms
|
159 |
*/
|
160 |
public function _prime_terms_cache( $terms, $taxonomies ) {
|
|
|
|
|
161 |
if ( is_array( $terms ) && $this->model->is_translated_taxonomy( $taxonomies ) ) {
|
162 |
foreach ( $terms as $term ) {
|
163 |
$term_ids[] = is_object( $term ) ? $term->term_id : (int) $term;
|
85 |
|
86 |
// get_term_by still not cached in WP 3.5.1 but internally, the function is always called by term_id
|
87 |
elseif ( is_string( $value ) && $taxonomy ) {
|
88 |
+
$term_id = get_term_by( 'slug', $value, $taxonomy )->term_id;
|
89 |
}
|
90 |
|
91 |
// Get the language and make sure it is a PLL_Language object
|
128 |
|
129 |
if ( ! doing_action( 'pre_delete_term' ) && $wpdb->get_var( $wpdb->prepare( "SELECT COUNT( * ) FROM $wpdb->terms WHERE term_id = %d;", $id ) ) ) {
|
130 |
// Always keep a group for terms to allow relationships remap when importing from a WXR file
|
131 |
+
$translations = array( $slug => $id );
|
132 |
wp_insert_term( $group = uniqid( 'pll_' ), 'term_translations', array( 'description' => maybe_serialize( $translations ) ) );
|
133 |
wp_set_object_terms( $id, $group, 'term_translations' );
|
134 |
}
|
158 |
* @return array unmodified $terms
|
159 |
*/
|
160 |
public function _prime_terms_cache( $terms, $taxonomies ) {
|
161 |
+
$term_ids = array();
|
162 |
+
|
163 |
if ( is_array( $terms ) && $this->model->is_translated_taxonomy( $taxonomies ) ) {
|
164 |
foreach ( $terms as $term ) {
|
165 |
$term_ids[] = is_object( $term ) ? $term->term_id : (int) $term;
|
include/walker-dropdown.php
CHANGED
@@ -101,8 +101,8 @@ class PLL_Walker_Dropdown extends Walker {
|
|
101 |
|
102 |
$output .= sprintf(
|
103 |
'<select name="%1$s"%2$s%3$s%4$s>' . "\n" . '%5$s' . "\n" . '</select>' . "\n",
|
104 |
-
|
105 |
-
isset( $args['id'] ) && ! $args['id'] ? '' : ' id="' . ( empty( $args['id'] ) ? $name : esc_attr( $args['id'] ) ) . '"',
|
106 |
empty( $args['class'] ) ? '' : ' class="' . esc_attr( $args['class'] ) . '"',
|
107 |
disabled( empty( $args['disabled'] ), false, false ),
|
108 |
parent::walk( $elements, $max_depth, $args )
|
101 |
|
102 |
$output .= sprintf(
|
103 |
'<select name="%1$s"%2$s%3$s%4$s>' . "\n" . '%5$s' . "\n" . '</select>' . "\n",
|
104 |
+
esc_attr( $args['name'] ),
|
105 |
+
isset( $args['id'] ) && ! $args['id'] ? '' : ' id="' . ( empty( $args['id'] ) ? esc_attr( $args['name'] ) : esc_attr( $args['id'] ) ) . '"',
|
106 |
empty( $args['class'] ) ? '' : ' class="' . esc_attr( $args['class'] ) . '"',
|
107 |
disabled( empty( $args['disabled'] ), false, false ),
|
108 |
parent::walk( $elements, $max_depth, $args )
|
include/widget-languages.php
CHANGED
@@ -64,7 +64,7 @@ class PLL_Widget_Languages extends WP_Widget {
|
|
64 |
* @return array Settings to save or bool false to cancel saving
|
65 |
*/
|
66 |
public function update( $new_instance, $old_instance ) {
|
67 |
-
$instance
|
68 |
foreach ( array_keys( PLL_Switcher::get_switcher_options( 'widget' ) ) as $key ) {
|
69 |
$instance[ $key ] = ! empty( $new_instance[ $key ] ) ? 1 : 0;
|
70 |
}
|
64 |
* @return array Settings to save or bool false to cancel saving
|
65 |
*/
|
66 |
public function update( $new_instance, $old_instance ) {
|
67 |
+
$instance = array( 'title' => sanitize_text_field( $new_instance['title'] ) );
|
68 |
foreach ( array_keys( PLL_Switcher::get_switcher_options( 'widget' ) ) as $key ) {
|
69 |
$instance[ $key ] = ! empty( $new_instance[ $key ] ) ? 1 : 0;
|
70 |
}
|
install/install.php
CHANGED
@@ -40,7 +40,7 @@ class PLL_Install extends PLL_Install_Base {
|
|
40 |
'<div class="error"><p>%s</p></div>',
|
41 |
sprintf(
|
42 |
/* translators: 1: Plugin name 2: Current PHP version 3: Required PHP version */
|
43 |
-
esc_html__( '%1$s has deactivated itself because you are using an old PHP
|
44 |
esc_html( POLYLANG ),
|
45 |
PHP_VERSION,
|
46 |
esc_html( PLL_MIN_PHP_VERSION )
|
@@ -62,7 +62,7 @@ class PLL_Install extends PLL_Install_Base {
|
|
62 |
'<div class="error"><p>%s</p></div>',
|
63 |
sprintf(
|
64 |
/* translators: 1: Plugin name 2: Current WordPress version 3: Required WordPress version */
|
65 |
-
esc_html__( '%1$s has deactivated itself because you are using an old WordPress
|
66 |
esc_html( POLYLANG ),
|
67 |
esc_html( $wp_version ),
|
68 |
esc_html( PLL_MIN_WP_VERSION )
|
40 |
'<div class="error"><p>%s</p></div>',
|
41 |
sprintf(
|
42 |
/* translators: 1: Plugin name 2: Current PHP version 3: Required PHP version */
|
43 |
+
esc_html__( '%1$s has deactivated itself because you are using an old version of PHP. You are using using PHP %2$s. %1$s requires PHP %3$s.', 'polylang' ),
|
44 |
esc_html( POLYLANG ),
|
45 |
PHP_VERSION,
|
46 |
esc_html( PLL_MIN_PHP_VERSION )
|
62 |
'<div class="error"><p>%s</p></div>',
|
63 |
sprintf(
|
64 |
/* translators: 1: Plugin name 2: Current WordPress version 3: Required WordPress version */
|
65 |
+
esc_html__( '%1$s has deactivated itself because you are using an old version of WordPress. You are using using WordPress %2$s. %1$s requires at least WordPress %3$s.', 'polylang' ),
|
66 |
esc_html( POLYLANG ),
|
67 |
esc_html( $wp_version ),
|
68 |
esc_html( PLL_MIN_WP_VERSION )
|
install/upgrade.php
CHANGED
@@ -89,7 +89,7 @@ class PLL_Upgrade {
|
|
89 |
* @since 1.2
|
90 |
*/
|
91 |
public function _upgrade() {
|
92 |
-
foreach ( array( '0.9', '1.0', '1.1', '1.2', '1.2.1', '1.2.3', '1.3', '1.4', '1.4.1', '1.4.4', '1.5', '1.6', '1.7.4', '1.8', '2.0.8', '2.1', '2.3' ) as $version ) {
|
93 |
if ( version_compare( $this->options['version'], $version, '<' ) ) {
|
94 |
call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
|
95 |
}
|
@@ -143,7 +143,7 @@ class PLL_Upgrade {
|
|
143 |
// Update strings register with icl_register_string
|
144 |
$strings = get_option( 'polylang_wpml_strings' );
|
145 |
if ( $strings ) {
|
146 |
-
foreach ( $strings as $key
|
147 |
$strings[ $key ]['icl'] = 1;
|
148 |
}
|
149 |
update_option( 'polylang_wpml_strings', $strings );
|
@@ -179,7 +179,8 @@ class PLL_Upgrade {
|
|
179 |
// Upgrade old model based on metas to new model based on taxonomies
|
180 |
global $wpdb;
|
181 |
$wpdb->termmeta = $wpdb->prefix . 'termmeta'; // Registers the termmeta table in wpdb
|
182 |
-
$languages
|
|
|
183 |
|
184 |
foreach ( $languages as $lang ) {
|
185 |
// First update language with new storage for locale and text direction
|
@@ -208,8 +209,12 @@ class PLL_Upgrade {
|
|
208 |
|
209 |
// Translations
|
210 |
foreach ( array( 'post', 'term' ) as $type ) {
|
211 |
-
$table
|
212 |
-
$terms
|
|
|
|
|
|
|
|
|
213 |
|
214 |
// Get all translated objects
|
215 |
// PHPCS:ignore WordPress.DB.PreparedSQL
|
@@ -307,6 +312,8 @@ class PLL_Upgrade {
|
|
307 |
// Multilingal locations and switcher item were stored in a dedicated option
|
308 |
if ( version_compare( $this->options['version'], '1.1', '<' ) ) {
|
309 |
if ( $menu_lang = get_option( 'polylang_nav_menus' ) ) {
|
|
|
|
|
310 |
foreach ( $menu_lang as $location => $arr ) {
|
311 |
if ( ! in_array( $location, array_keys( get_registered_nav_menus() ) ) ) {
|
312 |
continue;
|
@@ -355,7 +362,7 @@ class PLL_Upgrade {
|
|
355 |
// Clean the WP option as it was a bad idea to pollute it
|
356 |
if ( version_compare( $this->options['version'], '1.2', '<' ) ) {
|
357 |
foreach ( $menus as $loc => $menu ) {
|
358 |
-
if (
|
359 |
unset( $menus[ $loc ] );
|
360 |
}
|
361 |
}
|
@@ -518,6 +525,8 @@ class PLL_Upgrade {
|
|
518 |
return;
|
519 |
}
|
520 |
|
|
|
|
|
521 |
foreach ( $translations as $translation ) {
|
522 |
if ( in_array( $translation['language'], $languages ) ) {
|
523 |
$translation['type'] = 'core';
|
@@ -608,4 +617,29 @@ class PLL_Upgrade {
|
|
608 |
protected function upgrade_2_3() {
|
609 |
delete_transient( 'pll_languages_list' );
|
610 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
}
|
89 |
* @since 1.2
|
90 |
*/
|
91 |
public function _upgrade() {
|
92 |
+
foreach ( array( '0.9', '1.0', '1.1', '1.2', '1.2.1', '1.2.3', '1.3', '1.4', '1.4.1', '1.4.4', '1.5', '1.6', '1.7.4', '1.8', '2.0.8', '2.1', '2.3', '2.7' ) as $version ) {
|
93 |
if ( version_compare( $this->options['version'], $version, '<' ) ) {
|
94 |
call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
|
95 |
}
|
143 |
// Update strings register with icl_register_string
|
144 |
$strings = get_option( 'polylang_wpml_strings' );
|
145 |
if ( $strings ) {
|
146 |
+
foreach ( array_keys( $strings ) as $key ) {
|
147 |
$strings[ $key ]['icl'] = 1;
|
148 |
}
|
149 |
update_option( 'polylang_wpml_strings', $strings );
|
179 |
// Upgrade old model based on metas to new model based on taxonomies
|
180 |
global $wpdb;
|
181 |
$wpdb->termmeta = $wpdb->prefix . 'termmeta'; // Registers the termmeta table in wpdb
|
182 |
+
$languages = get_terms( 'language', array( 'hide_empty' => 0 ) ); // Don't use get_languages_list which can't work with the old model
|
183 |
+
$lang_tt_ids = array();
|
184 |
|
185 |
foreach ( $languages as $lang ) {
|
186 |
// First update language with new storage for locale and text direction
|
209 |
|
210 |
// Translations
|
211 |
foreach ( array( 'post', 'term' ) as $type ) {
|
212 |
+
$table = $type . 'meta';
|
213 |
+
$terms = array();
|
214 |
+
$slugs = array();
|
215 |
+
$tts = array();
|
216 |
+
$trs = array();
|
217 |
+
$description = array();
|
218 |
|
219 |
// Get all translated objects
|
220 |
// PHPCS:ignore WordPress.DB.PreparedSQL
|
312 |
// Multilingal locations and switcher item were stored in a dedicated option
|
313 |
if ( version_compare( $this->options['version'], '1.1', '<' ) ) {
|
314 |
if ( $menu_lang = get_option( 'polylang_nav_menus' ) ) {
|
315 |
+
$locations = array();
|
316 |
+
|
317 |
foreach ( $menu_lang as $location => $arr ) {
|
318 |
if ( ! in_array( $location, array_keys( get_registered_nav_menus() ) ) ) {
|
319 |
continue;
|
362 |
// Clean the WP option as it was a bad idea to pollute it
|
363 |
if ( version_compare( $this->options['version'], '1.2', '<' ) ) {
|
364 |
foreach ( $menus as $loc => $menu ) {
|
365 |
+
if ( strpos( $loc, '#' ) ) {
|
366 |
unset( $menus[ $loc ] );
|
367 |
}
|
368 |
}
|
525 |
return;
|
526 |
}
|
527 |
|
528 |
+
$translations_to_load = array();
|
529 |
+
|
530 |
foreach ( $translations as $translation ) {
|
531 |
if ( in_array( $translation['language'], $languages ) ) {
|
532 |
$translation['type'] = 'core';
|
617 |
protected function upgrade_2_3() {
|
618 |
delete_transient( 'pll_languages_list' );
|
619 |
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* Upgrades if the previous version is < 2.7
|
623 |
+
* Replace numeric keys by hashes in WPML registered strings
|
624 |
+
* Dismiss the wizard notice for existing sites
|
625 |
+
*
|
626 |
+
* @since 2.7
|
627 |
+
*/
|
628 |
+
protected function upgrade_2_7() {
|
629 |
+
$strings = get_option( 'polylang_wpml_strings' );
|
630 |
+
if ( is_array( $strings ) ) {
|
631 |
+
$new_strings = array();
|
632 |
+
|
633 |
+
foreach ( $strings as $string ) {
|
634 |
+
$context = $string['context'];
|
635 |
+
$name = $string['name'];
|
636 |
+
|
637 |
+
$key = md5( "$context | $name" );
|
638 |
+
$new_strings[ $key ] = $string;
|
639 |
+
}
|
640 |
+
update_option( 'polylang_wpml_strings', $new_strings );
|
641 |
+
}
|
642 |
+
|
643 |
+
PLL_Admin_Notices::dismiss( 'wizard' );
|
644 |
+
}
|
645 |
}
|
js/admin.js
CHANGED
@@ -1,195 +1,267 @@
|
|
1 |
-
jQuery( document ).ready(
|
2 |
-
|
3 |
-
|
4 |
-
// languages list table
|
5 |
-
// accessibility to row actions on focus
|
6 |
-
// mainly copy paste of WP code from common.js
|
7 |
-
$( 'table.languages' ).on({ // restricted to languages list table
|
8 |
-
focusin: function() {
|
9 |
-
clearTimeout( transitionTimeout );
|
10 |
-
focusedRowActions = $( this ).find( '.row-actions' );
|
11 |
-
// transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
|
12 |
-
$( '.row-actions' ).not( this ).removeClass( 'visible' );
|
13 |
-
focusedRowActions.addClass( 'visible' );
|
14 |
-
},
|
15 |
-
focusout: function() {
|
16 |
-
// Tabbing between post title and .row-actions links needs a brief pause, otherwise
|
17 |
-
// the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
|
18 |
-
transitionTimeout = setTimeout(function() {
|
19 |
-
focusedRowActions.removeClass( 'visible' );
|
20 |
-
}, 30 );
|
21 |
-
}
|
22 |
-
}, 'tr' ); // acts on the whole tr instead of single td as we have actions links in several columns
|
23 |
-
|
24 |
-
// extends selectmenu to add flags in menu items
|
25 |
-
$.widget( "custom.iconselectmenu", $.ui.selectmenu, {
|
26 |
-
_renderItem: function( ul, item ) {
|
27 |
-
var li = $( "<li>", { text: item.label } );
|
28 |
-
var el = $( item.element );
|
29 |
-
var url = el.data( "url" );
|
30 |
-
|
31 |
-
if ( url ) {
|
32 |
-
var w = el.data( "width" );
|
33 |
-
var h = el.data( "height" );
|
34 |
-
$( "<img class='ui-icon' />" ).prop( "src", url ).prop( "width", w ).prop( "height", h ).appendTo( li );
|
35 |
-
}
|
36 |
-
|
37 |
-
return li.appendTo( ul );
|
38 |
-
}
|
39 |
-
});
|
40 |
-
|
41 |
-
// allows to display the flag for the selected menu item
|
42 |
-
function add_icon( event, ui ) {
|
43 |
-
var sel = $( this ).find( ":selected" );
|
44 |
-
var url = sel.data( "url" );
|
45 |
-
|
46 |
-
if ( url ) {
|
47 |
-
var txt = $( this ).iconselectmenu( "widget" ).children( ":last" );
|
48 |
-
var w = sel.data( "width" );
|
49 |
-
var h = sel.data( "height" );
|
50 |
-
$( "<img class='ui-icon' />" ).prop( "src", url ).prop( "width", w ).prop( "height", h ).appendTo( txt );
|
51 |
-
}
|
52 |
-
}
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
111 |
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
149 |
}
|
150 |
-
}
|
151 |
-
|
152 |
-
});
|
153 |
-
|
154 |
-
// act when pressing enter or esc in configurations
|
155 |
-
$( '.pll-configure' ).keypress(function( event ){
|
156 |
-
if ( 13 === event.keyCode ) {
|
157 |
-
event.preventDefault();
|
158 |
-
$( this ).find( '.save' ).click();
|
159 |
-
}
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
|
|
|
|
173 |
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
// settings license
|
182 |
-
// deactivate button
|
183 |
-
$( '.pll-deactivate-license' ).on( 'click', function() {
|
184 |
-
var data = {
|
185 |
-
action: 'pll_deactivate_license',
|
186 |
-
pll_ajax_settings: true,
|
187 |
-
id: $( this ).attr( 'id' ),
|
188 |
-
_pll_nonce: $( '#_pll_nonce' ).val()
|
189 |
-
}
|
190 |
-
$.post( ajaxurl, data , function( response ){
|
191 |
-
$( '#pll-license-' + response.id ).replaceWith( response.html );
|
192 |
-
});
|
193 |
-
});
|
194 |
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery( document ).ready(
|
2 |
+
function( $ ) {
|
3 |
+
var transitionTimeout;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
+
// languages list table
|
6 |
+
// accessibility to row actions on focus
|
7 |
+
// mainly copy paste of WP code from common.js
|
8 |
+
$( 'table.languages' ).on(
|
9 |
+
{ // restricted to languages list table
|
10 |
+
focusin: function() {
|
11 |
+
clearTimeout( transitionTimeout );
|
12 |
+
focusedRowActions = $( this ).find( '.row-actions' );
|
13 |
+
// transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
|
14 |
+
$( '.row-actions' ).not( this ).removeClass( 'visible' );
|
15 |
+
focusedRowActions.addClass( 'visible' );
|
16 |
+
},
|
17 |
+
focusout: function() {
|
18 |
+
// Tabbing between post title and .row-actions links needs a brief pause, otherwise
|
19 |
+
// the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
|
20 |
+
transitionTimeout = setTimeout(
|
21 |
+
function() {
|
22 |
+
focusedRowActions.removeClass( 'visible' );
|
23 |
+
},
|
24 |
+
30
|
25 |
+
);
|
26 |
+
}
|
27 |
+
},
|
28 |
+
'tr'
|
29 |
+
); // acts on the whole tr instead of single td as we have actions links in several columns
|
30 |
+
|
31 |
+
// Common functions for overriding language and flag dropdown list.
|
32 |
+
var selectmenuRenderItem = function( wrapper, item ) {
|
33 |
+
var li = $( '<li>' ).text( item.label ).prepend( $( item.element ).data( 'flag-html' ) );
|
34 |
+
li.children( 'img' ).addClass( 'ui-icon' );
|
35 |
+
return li.appendTo( wrapper );
|
36 |
+
};
|
37 |
+
var selectmenuRefreshButtonText = function( selectElement ) {
|
38 |
+
var buttonText = $( selectElement ).selectmenu( 'instance' ).buttonText;
|
39 |
+
buttonText.prepend( $( selectElement ).children( ':selected' ).data( 'flag-html' ) );
|
40 |
+
buttonText.children( 'img' ).addClass( 'ui-icon' );
|
41 |
+
};
|
42 |
+
// Overrides the flag dropdown list with our customized jquery ui selectmenu.
|
43 |
+
|
44 |
+
// Inject flag image when jQuery UI selectmenu is created or an item is selected.
|
45 |
+
$( '#flag_list' ).on(
|
46 |
+
'selectmenucreate selectmenuselect',
|
47 |
+
function(){
|
48 |
+
selectmenuRefreshButtonText( this );
|
49 |
+
}
|
50 |
+
);
|
51 |
+
// Refresh jQuery UI selectmenu when the value is changed programmatically: select another language or edit an existing language.
|
52 |
+
// For putting the focus in the list on the selected item and injecting the right flag on the selected item.
|
53 |
+
$( '#flag_list' ).on(
|
54 |
+
'selectmenuopen',
|
55 |
+
function(){
|
56 |
+
$( this ).selectmenu( 'refresh' ).trigger( 'selectmenuselect' );
|
57 |
+
}
|
58 |
+
);
|
59 |
+
// Create the jQuery UI selectmenu widget
|
60 |
+
$( '#flag_list' ).selectmenu( { width: '100%' } );
|
61 |
+
// Overrides each item in the jQuery UI selectmenu list by injecting flag image.
|
62 |
+
$( '#flag_list' ).selectmenu( 'instance' )._renderItem = selectmenuRenderItem;
|
63 |
|
64 |
+
// Language choice in predefined languages in Polylang Languages settings page and wizard.
|
65 |
+
// Overrides the predefined language dropdown list with our customized jquery ui selectmenu.
|
66 |
+
|
67 |
+
// Inject flag image when jQuery UI selectmenu is created or an item is selected.
|
68 |
+
$( '#lang_list' ).on(
|
69 |
+
'selectmenucreate selectmenuselect',
|
70 |
+
function() {
|
71 |
+
selectmenuRefreshButtonText( this );
|
72 |
+
}
|
73 |
+
);
|
74 |
+
// Create the jQuery UI selectmenu widget
|
75 |
+
$( '#lang_list' ).selectmenu( { width: '100%' } );
|
76 |
+
// Overrides each element in the jQuery UI selectmenu list by injecting flag image.
|
77 |
+
$( '#lang_list' ).selectmenu( 'instance' )._renderItem = selectmenuRenderItem;
|
78 |
+
|
79 |
+
// Languages form
|
80 |
+
// Fills the fields based on the language dropdown list choice
|
81 |
+
$( '#add-lang #lang_list' ).on(
|
82 |
+
'selectmenuchange',
|
83 |
+
function() {
|
84 |
+
var value = $( this ).val().split( ':' );
|
85 |
+
var selected = $( "option:selected", this ).text().split( ' - ' );
|
86 |
+
$( '#lang_slug' ).val( value[0] );
|
87 |
+
$( '#lang_locale' ).val( value[1] );
|
88 |
+
$( 'input[name="rtl"]' ).val( [value[2]] );
|
89 |
+
$( '#lang_name' ).val( selected[0] );
|
90 |
+
$( '#flag_list').val( value[3] );
|
91 |
+
|
92 |
+
// Refresh the jQuery UI selectmenu flags list.
|
93 |
+
$( '#flag_list' ).selectmenu( 'refresh' ).trigger( 'selectmenuselect' );
|
94 |
+
}
|
95 |
+
);
|
96 |
+
|
97 |
+
// strings translations
|
98 |
+
// save translations when pressing enter
|
99 |
+
$( '.translation input' ).keypress(
|
100 |
+
function( event ){
|
101 |
+
if ( 13 === event.keyCode ) {
|
102 |
+
event.preventDefault();
|
103 |
+
$( '#submit' ).click();
|
104 |
}
|
105 |
+
}
|
106 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
+
// settings page
|
109 |
+
// click on configure link
|
110 |
+
$( '#the-list' ).on(
|
111 |
+
'click',
|
112 |
+
'.configure>a',
|
113 |
+
function(){
|
114 |
+
$( '.pll-configure' ).hide().prev().show();
|
115 |
+
$( this ).closest( 'tr' ).hide().next().show();
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
);
|
119 |
|
120 |
+
// cancel
|
121 |
+
$( '#the-list' ).on(
|
122 |
+
'click',
|
123 |
+
'.cancel',
|
124 |
+
function(){
|
125 |
+
$( this ).closest( 'tr' ).hide().prev().show();
|
126 |
+
}
|
127 |
+
);
|
128 |
|
129 |
+
// save settings
|
130 |
+
$( '#the-list' ).on(
|
131 |
+
'click',
|
132 |
+
'.save',
|
133 |
+
function(){
|
134 |
+
var tr = $( this ).closest( 'tr' );
|
135 |
+
var parts = tr.attr( 'id' ).split( '-' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
var data = {
|
138 |
+
action: 'pll_save_options',
|
139 |
+
pll_ajax_settings: true,
|
140 |
+
module: parts[parts.length - 1],
|
141 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
142 |
+
};
|
143 |
+
|
144 |
+
data = tr.find( ':input' ).serialize() + '&' + $.param( data );
|
145 |
+
|
146 |
+
$.post(
|
147 |
+
ajaxurl,
|
148 |
+
data,
|
149 |
+
function( response ) {
|
150 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
151 |
+
$.each(
|
152 |
+
res.responses,
|
153 |
+
function() {
|
154 |
+
switch ( this.what ) {
|
155 |
+
case 'license-update':
|
156 |
+
$( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
|
157 |
+
break;
|
158 |
+
case 'success':
|
159 |
+
tr.hide().prev().show(); // close only if there is no error
|
160 |
+
case 'error':
|
161 |
+
$( '.settings-error' ).remove(); // remove previous messages if any
|
162 |
+
$( 'h1' ).after( this.data );
|
163 |
+
|
164 |
+
// Make notices dismissible
|
165 |
+
// copy paste of common.js from WP 4.2.2
|
166 |
+
$( '.notice.is-dismissible' ).each(
|
167 |
+
function() {
|
168 |
+
var $this = $( this ),
|
169 |
+
$button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
|
170 |
+
btnText = commonL10n.dismiss || '';
|
171 |
+
|
172 |
+
// Ensure plain text
|
173 |
+
$button.find( '.screen-reader-text' ).text( btnText );
|
174 |
+
|
175 |
+
// Whitelist because of how the button is built. See above
|
176 |
+
$this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
177 |
+
|
178 |
+
$button.on(
|
179 |
+
'click.wp-dismiss-notice',
|
180 |
+
function( event ) {
|
181 |
+
event.preventDefault();
|
182 |
+
$this.fadeTo(
|
183 |
+
100,
|
184 |
+
0,
|
185 |
+
function() {
|
186 |
+
$( this ).slideUp(
|
187 |
+
100,
|
188 |
+
function() {
|
189 |
+
$( this ).remove();
|
190 |
+
}
|
191 |
+
);
|
192 |
+
}
|
193 |
+
);
|
194 |
+
}
|
195 |
+
);
|
196 |
+
}
|
197 |
+
);
|
198 |
+
break;
|
199 |
+
}
|
200 |
+
}
|
201 |
+
);
|
202 |
+
}
|
203 |
+
);
|
204 |
+
}
|
205 |
+
);
|
206 |
+
|
207 |
+
// act when pressing enter or esc in configurations
|
208 |
+
$( '.pll-configure' ).keypress(
|
209 |
+
function( event ){
|
210 |
+
if ( 13 === event.keyCode ) {
|
211 |
+
event.preventDefault();
|
212 |
+
$( this ).find( '.save' ).click();
|
213 |
+
}
|
214 |
+
|
215 |
+
if ( 27 === event.keyCode ) {
|
216 |
+
event.preventDefault();
|
217 |
+
$( this ).find( '.cancel' ).click();
|
218 |
+
}
|
219 |
+
}
|
220 |
+
);
|
221 |
+
|
222 |
+
// settings URL modifications
|
223 |
+
// manages visibility of fields
|
224 |
+
$( "input[name='force_lang']" ).change(
|
225 |
+
function() {
|
226 |
+
function pll_toggle( a, test ) {
|
227 |
+
test ? a.show() : a.hide();
|
228 |
+
}
|
229 |
+
|
230 |
+
var value = $( this ).val();
|
231 |
+
pll_toggle( $( '#pll-domains-table' ), 3 == value );
|
232 |
+
pll_toggle( $( "#pll-hide-default" ), 3 > value );
|
233 |
+
pll_toggle( $( "#pll-rewrite" ), 2 > value );
|
234 |
+
pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
|
235 |
+
}
|
236 |
+
);
|
237 |
+
|
238 |
+
// settings license
|
239 |
+
// deactivate button
|
240 |
+
$( '.pll-deactivate-license' ).on(
|
241 |
+
'click',
|
242 |
+
function() {
|
243 |
+
var data = {
|
244 |
+
action: 'pll_deactivate_license',
|
245 |
+
pll_ajax_settings: true,
|
246 |
+
id: $( this ).attr( 'id' ),
|
247 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
248 |
+
};
|
249 |
+
$.post(
|
250 |
+
ajaxurl,
|
251 |
+
data,
|
252 |
+
function( response ){
|
253 |
+
$( '#pll-license-' + response.id ).replaceWith( response.html );
|
254 |
+
}
|
255 |
+
);
|
256 |
+
}
|
257 |
+
);
|
258 |
+
|
259 |
+
// Manage closing the metabox.
|
260 |
+
// close postboxes that should be closed
|
261 |
+
$( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
|
262 |
+
// postboxes setup
|
263 |
+
if ( 'undefined' !== typeof postboxes ) {
|
264 |
+
postboxes.add_postbox_toggles( pagenow );
|
265 |
+
}
|
266 |
+
}
|
267 |
+
);
|
js/admin.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function(e){
|
1 |
+
jQuery(document).ready(function(e){var t;e("table.languages").on({focusin:function(){clearTimeout(t),focusedRowActions=e(this).find(".row-actions"),e(".row-actions").not(this).removeClass("visible"),focusedRowActions.addClass("visible")},focusout:function(){t=setTimeout(function(){focusedRowActions.removeClass("visible")},30)}},"tr");var n=function(t,n){var s=e("<li>").text(n.label).prepend(e(n.element).data("flag-html"));return s.children("img").addClass("ui-icon"),s.appendTo(t)},s=function(t){var n=e(t).selectmenu("instance").buttonText;n.prepend(e(t).children(":selected").data("flag-html")),n.children("img").addClass("ui-icon")};e("#flag_list").on("selectmenucreate selectmenuselect",function(){s(this)}),e("#flag_list").on("selectmenuopen",function(){e(this).selectmenu("refresh").trigger("selectmenuselect")}),e("#flag_list").selectmenu({width:"100%"}),e("#flag_list").selectmenu("instance")._renderItem=n,e("#lang_list").on("selectmenucreate selectmenuselect",function(){s(this)}),e("#lang_list").selectmenu({width:"100%"}),e("#lang_list").selectmenu("instance")._renderItem=n,e("#add-lang #lang_list").on("selectmenuchange",function(){var t=e(this).val().split(":"),n=e("option:selected",this).text().split(" - ");e("#lang_slug").val(t[0]),e("#lang_locale").val(t[1]),e('input[name="rtl"]').val([t[2]]),e("#lang_name").val(n[0]),e("#flag_list").val(t[3]),e("#flag_list").selectmenu("refresh").trigger("selectmenuselect")}),e(".translation input").keypress(function(t){13===t.keyCode&&(t.preventDefault(),e("#submit").click())}),e("#the-list").on("click",".configure>a",function(){return e(".pll-configure").hide().prev().show(),e(this).closest("tr").hide().next().show(),!1}),e("#the-list").on("click",".cancel",function(){e(this).closest("tr").hide().prev().show()}),e("#the-list").on("click",".save",function(){var t=e(this).closest("tr"),n=t.attr("id").split("-"),s={action:"pll_save_options",pll_ajax_settings:!0,module:n[n.length-1],_pll_nonce:e("#_pll_nonce").val()};s=t.find(":input").serialize()+"&"+e.param(s),e.post(ajaxurl,s,function(n){var s=wpAjax.parseAjaxResponse(n,"ajax-response");e.each(s.responses,function(){switch(this.what){case"license-update":e("#pll-license-"+this.data).replaceWith(this.supplemental.html);break;case"success":t.hide().prev().show();case"error":e(".settings-error").remove(),e("h1").after(this.data),e(".notice.is-dismissible").each(function(){var t=e(this),n=e('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),s=commonL10n.dismiss||"";n.find(".screen-reader-text").text(s),t.append(n),n.on("click.wp-dismiss-notice",function(n){n.preventDefault(),t.fadeTo(100,0,function(){e(this).slideUp(100,function(){e(this).remove()})})})})}})})}),e(".pll-configure").keypress(function(t){13===t.keyCode&&(t.preventDefault(),e(this).find(".save").click()),27===t.keyCode&&(t.preventDefault(),e(this).find(".cancel").click())}),e("input[name='force_lang']").change(function(){function t(e,t){t?e.show():e.hide()}var n=e(this).val();t(e("#pll-domains-table"),3==n),t(e("#pll-hide-default"),3>n),t(e("#pll-rewrite"),2>n),t(e("#pll-redirect-lang"),2>n)}),e(".pll-deactivate-license").on("click",function(){var t={action:"pll_deactivate_license",pll_ajax_settings:!0,id:e(this).attr("id"),_pll_nonce:e("#_pll_nonce").val()};e.post(ajaxurl,t,function(t){e("#pll-license-"+t.id).replaceWith(t.html)})}),e(".if-js-closed").removeClass("if-js-closed").addClass("closed"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(pagenow)});
|
js/block-editor.js
CHANGED
@@ -3,19 +3,22 @@
|
|
3 |
*
|
4 |
* @since 2.5
|
5 |
*/
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
15 |
}
|
|
|
16 |
}
|
17 |
-
|
18 |
-
} );
|
19 |
|
20 |
/**
|
21 |
* Get the language from the HTML form
|
@@ -33,63 +36,77 @@ function getCurrentLanguage() {
|
|
33 |
*
|
34 |
* @since 2.5
|
35 |
*/
|
36 |
-
jQuery( document ).ready(
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
const
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
}
|
56 |
}
|
57 |
-
} );
|
58 |
-
});
|
59 |
-
|
60 |
-
// Specific case for empty posts
|
61 |
-
if ( location.pathname.match( /post-new.php/gi ) ) {
|
62 |
-
const title = select('core/editor').getEditedPostAttribute('title');
|
63 |
-
const content = select('core/editor').getEditedPostAttribute('content');
|
64 |
-
const excerpt = select('core/editor').getEditedPostAttribute('excerpt');
|
65 |
-
if ( '' === title && '' === content && '' === excerpt ) {
|
66 |
-
// Change the new_lang parameter with the new language value for reloading the page
|
67 |
-
if ( -1 != location.search.indexOf( 'new_lang' ) ) {
|
68 |
-
window.location.search = window.location.search.replace( /(?:new_lang=[^&]*)(&)?(.*)/, 'new_lang=' + this.value + '$1$2' );;
|
69 |
-
} else {
|
70 |
-
window.location.search = window.location.search + ( ( -1 != window.location.search.indexOf( '?' ) ) ? '&' : '?' ) + 'new_lang=' + this.value;
|
71 |
-
}
|
72 |
-
}
|
73 |
-
}
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
}
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
/**
|
95 |
* Handles internals of the metabox:
|
@@ -97,88 +114,120 @@ jQuery( document ).ready(function( $ ) {
|
|
97 |
*
|
98 |
* @since 1.5
|
99 |
*/
|
100 |
-
jQuery( document ).ready(
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
$.post( ajaxurl, data , function( response ) {
|
112 |
-
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
113 |
-
$.each( res.responses, function() {
|
114 |
-
switch ( this.what ) {
|
115 |
-
case 'translations': // Translations fields
|
116 |
-
$( '.translations' ).html( this.data );
|
117 |
-
init_translations();
|
118 |
-
break;
|
119 |
-
case 'flag': // Flag in front of the select dropdown
|
120 |
-
$( '.pll-select-flag' ).html( this.data );
|
121 |
-
break;
|
122 |
-
}
|
123 |
-
});
|
124 |
-
});
|
125 |
-
});
|
126 |
-
|
127 |
-
// Translations autocomplete input box
|
128 |
-
function init_translations() {
|
129 |
-
$( '.tr_lang' ).each(function(){
|
130 |
-
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
131 |
-
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
132 |
-
|
133 |
-
$( this ).autocomplete({
|
134 |
-
minLength: 0,
|
135 |
-
|
136 |
-
source: ajaxurl + '?action=pll_posts_not_translated' +
|
137 |
-
'&post_language=' + $( '.post_lang_choice' ).val() +
|
138 |
-
'&translation_language=' + tr_lang +
|
139 |
-
'&post_type=' + $( '#post_type' ).val() +
|
140 |
-
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
141 |
-
|
142 |
-
select: function( event, ui ) {
|
143 |
-
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
144 |
-
td.html( ui.item.link );
|
145 |
-
},
|
146 |
-
});
|
147 |
-
|
148 |
-
// When the input box is emptied
|
149 |
-
$( this ).blur(function() {
|
150 |
-
if ( ! $( this ).val() ) {
|
151 |
-
$( '#htr_lang_' + tr_lang ).val( 0 );
|
152 |
-
td.html( td.siblings( '.hidden' ).children().clone() );
|
153 |
}
|
154 |
-
});
|
155 |
-
});
|
156 |
-
}
|
157 |
|
158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
}
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
$.each( res.responses, function() {
|
177 |
-
id = id.replace( '[', '\\[' ).replace( ']', '\\]' );
|
178 |
-
$( '#' + id ).toggleClass( 'wp-ui-text-highlight' ).attr( 'title', this.data ).children( 'span' ).html( this.data );
|
179 |
-
$( 'input[name="' + id + '"]' ).val( ! data['value'] );
|
180 |
-
});
|
181 |
-
});
|
182 |
-
}
|
183 |
-
});
|
184 |
-
});
|
3 |
*
|
4 |
* @since 2.5
|
5 |
*/
|
6 |
+
|
7 |
+
wp.apiFetch.use(
|
8 |
+
function( options, next ) {
|
9 |
+
// If options.url is defined, this is not a REST request but a direct call to post.php for legacy metaboxes.
|
10 |
+
if ( 'undefined' === typeof options.url ) {
|
11 |
+
if ( 'undefined' === typeof options.data ) {
|
12 |
+
// GET
|
13 |
+
options.path += ( ( options.path.indexOf( '?' ) >= 0 ) ? '&lang=' : '?lang=' ) + getCurrentLanguage();
|
14 |
+
} else {
|
15 |
+
// PUT, POST
|
16 |
+
options.data.lang = getCurrentLanguage();
|
17 |
+
}
|
18 |
}
|
19 |
+
return next( options );
|
20 |
}
|
21 |
+
);
|
|
|
22 |
|
23 |
/**
|
24 |
* Get the language from the HTML form
|
36 |
*
|
37 |
* @since 2.5
|
38 |
*/
|
39 |
+
jQuery( document ).ready(
|
40 |
+
function( $ ) {
|
41 |
+
// savePost after changing the post's language and reload page for refreshing post translated data
|
42 |
+
$( '.post_lang_choice' ).change(
|
43 |
+
function() {
|
44 |
+
const select = wp.data.select;
|
45 |
+
const dispatch = wp.data.dispatch;
|
46 |
+
const subscribe = wp.data.subscribe;
|
47 |
+
|
48 |
+
let unsubscribe = null;
|
49 |
+
|
50 |
+
// Listen if the savePost is done
|
51 |
+
const savePostIsDone = new Promise(
|
52 |
+
function( resolve, reject ) {
|
53 |
+
unsubscribe = subscribe(
|
54 |
+
function() {
|
55 |
+
const isSavePostSucceeded = select( 'core/editor' ).didPostSaveRequestSucceed();
|
56 |
+
const isSavePostFailed = select( 'core/editor' ).didPostSaveRequestFail();
|
57 |
+
if ( isSavePostSucceeded || isSavePostFailed ) {
|
58 |
+
if ( isSavePostFailed ) {
|
59 |
+
reject();
|
60 |
+
} else {
|
61 |
+
resolve();
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
);
|
66 |
+
}
|
67 |
+
);
|
68 |
+
|
69 |
+
// Specific case for empty posts
|
70 |
+
if ( location.pathname.match( /post-new.php/gi ) ) {
|
71 |
+
const title = select( 'core/editor' ).getEditedPostAttribute( 'title' );
|
72 |
+
const content = select( 'core/editor' ).getEditedPostAttribute( 'content' );
|
73 |
+
const excerpt = select( 'core/editor' ).getEditedPostAttribute( 'excerpt' );
|
74 |
+
if ( '' === title && '' === content && '' === excerpt ) {
|
75 |
+
// Change the new_lang parameter with the new language value for reloading the page
|
76 |
+
// WPCS location.search is never written in the page, just used to relaoad page ( See line 94 ) with the right value of new_lang
|
77 |
+
// new_lang input is controlled server side in PHP. The value come from the dropdown list of language returned and escaped server side
|
78 |
+
if ( -1 != location.search.indexOf( 'new_lang' ) ) {
|
79 |
+
// use regexp non capturing group to replace new_lang parameter no matter where it is and capture other parameters which can be behind it
|
80 |
+
window.location.search = window.location.search.replace( /(?:new_lang=[^&]*)(&)?(.*)/, 'new_lang=' + this.value + '$1$2' ); // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
81 |
+
} else {
|
82 |
+
window.location.search = window.location.search + ( ( -1 != window.location.search.indexOf( '?' ) ) ? '&' : '?' ) + 'new_lang=' + this.value; // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
83 |
+
}
|
84 |
}
|
85 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
+
// For empty posts savePost does nothing
|
88 |
+
dispatch( 'core/editor' ).savePost();
|
89 |
+
|
90 |
+
savePostIsDone.then(
|
91 |
+
function() {
|
92 |
+
// If the post is well saved, we can reload the page
|
93 |
+
unsubscribe();
|
94 |
+
window.location.reload();
|
95 |
+
},
|
96 |
+
function() {
|
97 |
+
// If the post save failed
|
98 |
+
unsubscribe();
|
99 |
+
}
|
100 |
+
).catch(
|
101 |
+
function() {
|
102 |
+
// If an exception is thrown
|
103 |
+
unsubscribe();
|
104 |
+
}
|
105 |
+
);
|
106 |
+
}
|
107 |
+
);
|
108 |
+
}
|
109 |
+
);
|
110 |
|
111 |
/**
|
112 |
* Handles internals of the metabox:
|
114 |
*
|
115 |
* @since 1.5
|
116 |
*/
|
117 |
+
jQuery( document ).ready(
|
118 |
+
function( $ ) {
|
119 |
+
// Ajax for changing the post's language in the languages metabox
|
120 |
+
$( '.post_lang_choice' ).change(
|
121 |
+
function() {
|
122 |
+
var data = {
|
123 |
+
action: 'post_lang_choice',
|
124 |
+
lang: $( this ).val(),
|
125 |
+
post_type: $( '#post_type' ).val(),
|
126 |
+
post_id: $( '#post_ID' ).val(),
|
127 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
}
|
|
|
|
|
|
|
129 |
|
130 |
+
$.post(
|
131 |
+
ajaxurl,
|
132 |
+
data,
|
133 |
+
function( response ) {
|
134 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
135 |
+
$.each(
|
136 |
+
res.responses,
|
137 |
+
function() {
|
138 |
+
switch ( this.what ) {
|
139 |
+
case 'translations': // Translations fields
|
140 |
+
// Data is built and come from server side and is well escaped when necessary
|
141 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
142 |
+
init_translations();
|
143 |
+
break;
|
144 |
+
case 'flag': // Flag in front of the select dropdown
|
145 |
+
// Data is built and come from server side and is well escaped when necessary
|
146 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
147 |
+
break;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
);
|
151 |
+
}
|
152 |
+
);
|
153 |
+
}
|
154 |
+
);
|
155 |
+
|
156 |
+
// Translations autocomplete input box
|
157 |
+
function init_translations() {
|
158 |
+
$( '.tr_lang' ).each(
|
159 |
+
function(){
|
160 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
161 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
162 |
+
|
163 |
+
$( this ).autocomplete(
|
164 |
+
{
|
165 |
+
minLength: 0,
|
166 |
+
|
167 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
168 |
+
'&post_language=' + $( '.post_lang_choice' ).val() +
|
169 |
+
'&translation_language=' + tr_lang +
|
170 |
+
'&post_type=' + $( '#post_type' ).val() +
|
171 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
172 |
+
|
173 |
+
select: function( event, ui ) {
|
174 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
175 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
176 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
177 |
+
},
|
178 |
+
}
|
179 |
+
);
|
180 |
+
|
181 |
+
// When the input box is emptied
|
182 |
+
$( this ).blur(
|
183 |
+
function() {
|
184 |
+
if ( ! $( this ).val() ) {
|
185 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
186 |
+
// Value is retrieved from HTML already generated server side
|
187 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
188 |
+
}
|
189 |
+
}
|
190 |
+
);
|
191 |
+
}
|
192 |
+
);
|
193 |
+
}
|
194 |
|
195 |
+
init_translations();
|
196 |
+
|
197 |
+
// Handle the response to a click on a Languages metabox button
|
198 |
+
$( '#ml_box' ).on(
|
199 |
+
'click',
|
200 |
+
'.pll-button',
|
201 |
+
function(){
|
202 |
+
var value = $( this ).hasClass( 'wp-ui-text-highlight' );
|
203 |
+
var id = $( this ).attr( 'id' );
|
204 |
+
var post_id = $( '#htr_lang_' + id.replace( 'pll_sync_post[', '' ).replace( ']', '' ) ).val();
|
205 |
+
|
206 |
+
if ( 'undefined' == typeof( post_id ) || 0 == post_id || value || confirm( confirm_text ) ) {
|
207 |
+
var data = {
|
208 |
+
action: 'toggle_' + id,
|
209 |
+
value: value,
|
210 |
+
post_type: $( '#post_type' ).val(),
|
211 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
212 |
+
}
|
213 |
|
214 |
+
$.post(
|
215 |
+
ajaxurl,
|
216 |
+
data,
|
217 |
+
function( response ){
|
218 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
219 |
+
$.each(
|
220 |
+
res.responses,
|
221 |
+
function() {
|
222 |
+
id = id.replace( '[', '\\[' ).replace( ']', '\\]' );
|
223 |
+
$( '#' + id ).toggleClass( 'wp-ui-text-highlight' ).attr( 'title', this.data ).children( 'span' ).text( this.data );
|
224 |
+
$( 'input[name="' + id + '"]' ).val( ! data['value'] );
|
225 |
+
}
|
226 |
+
);
|
227 |
+
}
|
228 |
+
);
|
229 |
+
}
|
230 |
}
|
231 |
+
);
|
232 |
+
}
|
233 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/block-editor.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
wp.apiFetch.use(function(
|
1 |
+
function getCurrentLanguage(){return document.querySelector("[name=post_lang_choice]").value}wp.apiFetch.use(function(t,e){return void 0===t.url&&(void 0===t.data?t.path+=(t.path.indexOf("?")>=0?"&lang=":"?lang=")+getCurrentLanguage():t.data.lang=getCurrentLanguage()),e(t)}),jQuery(document).ready(function(t){t(".post_lang_choice").change(function(){const t=wp.data.select,e=wp.data.dispatch,n=wp.data.subscribe;let a=null;const o=new Promise(function(e,o){a=n(function(){const n=t("core/editor").didPostSaveRequestSucceed(),a=t("core/editor").didPostSaveRequestFail();(n||a)&&(a?o():e())})});if(location.pathname.match(/post-new.php/gi)){const e=t("core/editor").getEditedPostAttribute("title"),n=t("core/editor").getEditedPostAttribute("content"),a=t("core/editor").getEditedPostAttribute("excerpt");""===e&&""===n&&""===a&&(-1!=location.search.indexOf("new_lang")?window.location.search=window.location.search.replace(/(?:new_lang=[^&]*)(&)?(.*)/,"new_lang="+this.value+"$1$2"):window.location.search=window.location.search+(-1!=window.location.search.indexOf("?")?"&":"?")+"new_lang="+this.value)}e("core/editor").savePost(),o.then(function(){a(),window.location.reload()},function(){a()}).catch(function(){a()})})}),jQuery(document).ready(function(t){function e(){t(".tr_lang").each(function(){var e=t(this).attr("id").substring(8),n=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+e+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(a,o){t("#htr_lang_"+e).val(o.item.id),n.html(o.item.link)}}),t(this).blur(function(){t(this).val()||(t("#htr_lang_"+e).val(0),n.html(n.siblings(".hidden").children().clone()))})})}t(".post_lang_choice").change(function(){var n={action:"post_lang_choice",lang:t(this).val(),post_type:t("#post_type").val(),post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,n,function(n){var a=wpAjax.parseAjaxResponse(n,"ajax-response");t.each(a.responses,function(){switch(this.what){case"translations":t(".translations").html(this.data),e();break;case"flag":t(".pll-select-flag").html(this.data)}})})}),e(),t("#ml_box").on("click",".pll-button",function(){var e=t(this).hasClass("wp-ui-text-highlight"),n=t(this).attr("id"),a=t("#htr_lang_"+n.replace("pll_sync_post[","").replace("]","")).val();if(void 0===a||0==a||e||confirm(confirm_text)){var o={action:"toggle_"+n,value:e,post_type:t("#post_type").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,o,function(e){var a=wpAjax.parseAjaxResponse(e,"ajax-response");t.each(a.responses,function(){n=n.replace("[","\\[").replace("]","\\]"),t("#"+n).toggleClass("wp-ui-text-highlight").attr("title",this.data).children("span").text(this.data),t('input[name="'+n+'"]').val(!o.value)})})}})});
|
js/classic-editor.js
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
// tag suggest in metabox
|
2 |
(function( $ ){
|
3 |
-
$.ajaxPrefilter(
|
4 |
-
|
5 |
-
options.data
|
|
|
|
|
6 |
}
|
7 |
-
|
8 |
})( jQuery );
|
9 |
|
10 |
// overrides tagBox.get
|
@@ -20,163 +22,211 @@
|
|
20 |
tax: tax
|
21 |
}
|
22 |
|
23 |
-
$.post(
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
|
31 |
-
return false;
|
32 |
-
});
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
$( '.the-tagcloud' ).
|
37 |
-
$( '
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
42 |
-
|
43 |
}
|
44 |
})( jQuery );
|
45 |
|
46 |
-
jQuery( document ).ready(
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
64 |
);
|
65 |
-
});
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
-
|
109 |
}
|
110 |
-
|
|
|
|
|
|
|
111 |
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
114 |
var id = $( this ).attr( 'id' );
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
select: function( event, ui ) {
|
141 |
-
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
142 |
-
td.html( ui.item.link );
|
143 |
-
},
|
144 |
-
});
|
145 |
-
|
146 |
-
// when the input box is emptied
|
147 |
-
$( this ).blur(function() {
|
148 |
-
if ( ! $( this ).val() ) {
|
149 |
-
$( '#htr_lang_' + tr_lang ).val( 0 );
|
150 |
-
td.html( td.siblings( '.hidden' ).children().clone() );
|
151 |
}
|
152 |
-
});
|
153 |
-
});
|
154 |
-
}
|
155 |
-
|
156 |
-
init_translations();
|
157 |
-
|
158 |
-
// Handle the response to a click on a Languages metabox button
|
159 |
-
$( '#ml_box' ).on( 'click', '.pll-button', function(){
|
160 |
-
var value = $( this ).hasClass( 'wp-ui-text-highlight' );
|
161 |
-
var id = $( this ).attr( 'id' );
|
162 |
-
var post_id = $( '#htr_lang_' + id.replace( 'pll_sync_post[', '' ).replace( ']', '' ) ).val();
|
163 |
-
|
164 |
-
if ( 'undefined' == typeof( post_id ) || 0 == post_id || value || confirm( confirm_text ) ) {
|
165 |
-
var data = {
|
166 |
-
action: 'toggle_' + id,
|
167 |
-
value: value,
|
168 |
-
post_type: $( '#post_type' ).val(),
|
169 |
-
_pll_nonce: $( '#_pll_nonce' ).val()
|
170 |
}
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
$.each( res.responses, function() {
|
175 |
-
id = id.replace( '[', '\\[' ).replace( ']', '\\]' );
|
176 |
-
$( '#' + id ).toggleClass( 'wp-ui-text-highlight' ).attr( 'title', this.data ).children( 'span' ).html( this.data );
|
177 |
-
$( 'input[name="' + id + '"]' ).val( ! data['value'] );
|
178 |
-
});
|
179 |
-
});
|
180 |
-
}
|
181 |
-
});
|
182 |
-
});
|
1 |
// tag suggest in metabox
|
2 |
(function( $ ){
|
3 |
+
$.ajaxPrefilter(
|
4 |
+
function( options, originalOptions, jqXHR ) {
|
5 |
+
if ( 'string' === typeof options.data && -1 !== options.url.indexOf( 'action=ajax-tag-search' ) && ( lang = $( '.post_lang_choice' ).val() ) ) {
|
6 |
+
options.data = 'lang=' + lang + '&' + options.data;
|
7 |
+
}
|
8 |
}
|
9 |
+
);
|
10 |
})( jQuery );
|
11 |
|
12 |
// overrides tagBox.get
|
22 |
tax: tax
|
23 |
}
|
24 |
|
25 |
+
$.post(
|
26 |
+
ajaxurl,
|
27 |
+
data,
|
28 |
+
function( r, stat ) {
|
29 |
+
if ( 0 == r || 'success' != stat ) {
|
30 |
+
r = wpAjax.broken;
|
31 |
+
}
|
|
|
|
|
|
|
32 |
|
33 |
+
// @see code from WordPress core https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/js/tags-box.js#L291
|
34 |
+
// @see wp_generate_tag_cloud function which generate the escaped HTML https://github.com/WordPress/WordPress/blob/a02b5cc2a8eecb8e076fbb7cf4de7bd2ec8a8eb1/wp-includes/category-template.php#L966-L975
|
35 |
+
r = $( '<div />' ).addClass( 'the-tagcloud' ).attr( 'id', 'tagcloud-' + tax ).html( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
36 |
+
$( 'a', r ).click(
|
37 |
+
function(){
|
38 |
+
tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
|
39 |
+
return false;
|
40 |
+
}
|
41 |
+
);
|
42 |
+
|
43 |
+
// add an if else condition to allow modifying the tags outputed when switching the language
|
44 |
+
if ( v = $( '.the-tagcloud' ).css( 'display' ) ) {
|
45 |
+
$( '.the-tagcloud' ).replaceWith( r );
|
46 |
+
$( '.the-tagcloud' ).css( 'display', v );
|
47 |
+
}
|
48 |
+
else {
|
49 |
+
$( '#' + id ).after( r );
|
50 |
+
}
|
51 |
}
|
52 |
+
);
|
53 |
}
|
54 |
})( jQuery );
|
55 |
|
56 |
+
jQuery( document ).ready(
|
57 |
+
function( $ ) {
|
58 |
+
// collect taxonomies - code partly copied from WordPress
|
59 |
+
var taxonomies = new Array();
|
60 |
+
$( '.categorydiv' ).each(
|
61 |
+
function(){
|
62 |
+
var this_id = $( this ).attr( 'id' ), taxonomyParts, taxonomy;
|
63 |
+
|
64 |
+
taxonomyParts = this_id.split( '-' );
|
65 |
+
taxonomyParts.shift();
|
66 |
+
taxonomy = taxonomyParts.join( '-' );
|
67 |
+
taxonomies.push( taxonomy ); // store the taxonomy for future use
|
68 |
+
|
69 |
+
// add our hidden field in the new category form - for each hierarchical taxonomy
|
70 |
+
// to set the language when creating a new category
|
71 |
+
$( '#' + taxonomy + '-add-submit' ).before(
|
72 |
+
$( '<input />' ).attr( 'type', 'hidden' )
|
73 |
+
.attr( 'id', taxonomy + '-lang' )
|
74 |
+
.attr( 'name', 'term_lang_choice' )
|
75 |
+
.attr( 'value', $( '.post_lang_choice' ).val() )
|
76 |
+
);
|
77 |
+
}
|
78 |
);
|
|
|
79 |
|
80 |
+
// ajax for changing the post's language in the languages metabox
|
81 |
+
$( '.post_lang_choice' ).change(
|
82 |
+
function() {
|
83 |
+
var value = $( this ).val();
|
84 |
+
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
85 |
+
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' );
|
86 |
+
|
87 |
+
var data = {
|
88 |
+
action: 'post_lang_choice',
|
89 |
+
lang: value,
|
90 |
+
post_type: $( '#post_type' ).val(),
|
91 |
+
taxonomies: taxonomies,
|
92 |
+
post_id: $( '#post_ID' ).val(),
|
93 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
94 |
+
}
|
95 |
|
96 |
+
$.post(
|
97 |
+
ajaxurl,
|
98 |
+
data,
|
99 |
+
function( response ) {
|
100 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
101 |
+
$.each(
|
102 |
+
res.responses,
|
103 |
+
function() {
|
104 |
+
switch ( this.what ) {
|
105 |
+
case 'translations': // translations fields
|
106 |
+
// Data is built and come from server side and is well escaped when necessary
|
107 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
108 |
+
init_translations();
|
109 |
+
break;
|
110 |
+
case 'taxonomy': // categories metabox for posts
|
111 |
+
var tax = this.data;
|
112 |
+
// @see wp_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L175
|
113 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/class-walker-category-checklist.php#L89-L111
|
114 |
+
$( '#' + tax + 'checklist' ).html( this.supplemental.all ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
115 |
+
// @see wp_popular_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L236
|
116 |
+
$( '#' + tax + 'checklist-pop' ).html( this.supplemental.populars ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
117 |
+
$( '#new' + tax + '_parent' ).replaceWith( this.supplemental.dropdown );
|
118 |
+
$( '#' + tax + '-lang' ).val( $( '.post_lang_choice' ).val() ); // hidden field
|
119 |
+
break;
|
120 |
+
case 'pages': // parent dropdown list for pages
|
121 |
+
// @see wp_dropdown_pages https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/post-template.php#L1186-L1208
|
122 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/class-walker-page-dropdown.php#L88
|
123 |
+
$( '#parent_id' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
124 |
+
break;
|
125 |
+
case 'flag': // flag in front of the select dropdown
|
126 |
+
// Data is built and come from server side and is well escaped when necessary
|
127 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
128 |
+
break;
|
129 |
+
case 'permalink': // Sample permalink
|
130 |
+
var div = $( '#edit-slug-box' );
|
131 |
+
if ( '-1' != this.data && div.children().length ) {
|
132 |
+
// @see get_sample_permalink_html https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/post.php#L1425-L1454
|
133 |
+
div.html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
134 |
+
}
|
135 |
+
break;
|
136 |
+
}
|
137 |
+
}
|
138 |
+
);
|
139 |
+
|
140 |
+
// modifies the language in the tag cloud
|
141 |
+
$( '.tagcloud-link' ).each(
|
142 |
+
function() {
|
143 |
+
var id = $( this ).attr( 'id' );
|
144 |
+
tagBox.get( id );
|
145 |
+
}
|
146 |
+
);
|
147 |
+
|
148 |
+
// Modifies the text direction
|
149 |
+
$( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
|
150 |
+
$( '#content_ifr' ).contents().find( 'html' ).attr( 'lang', lang ).attr( 'dir', dir );
|
151 |
+
$( '#content_ifr' ).contents().find( 'body' ).attr( 'dir', dir );
|
152 |
+
}
|
153 |
+
);
|
154 |
+
}
|
155 |
+
);
|
156 |
|
157 |
+
// translations autocomplete input box
|
158 |
+
function init_translations() {
|
159 |
+
$( '.tr_lang' ).each(
|
160 |
+
function(){
|
161 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
162 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
163 |
+
|
164 |
+
$( this ).autocomplete(
|
165 |
+
{
|
166 |
+
minLength: 0,
|
167 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
168 |
+
'&post_language=' + $( '.post_lang_choice' ).val() +
|
169 |
+
'&translation_language=' + tr_lang +
|
170 |
+
'&post_type=' + $( '#post_type' ).val() +
|
171 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
172 |
+
select: function( event, ui ) {
|
173 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
174 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
175 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
176 |
+
},
|
177 |
+
}
|
178 |
+
);
|
179 |
+
|
180 |
+
// when the input box is emptied
|
181 |
+
$( this ).blur(
|
182 |
+
function() {
|
183 |
+
if ( ! $( this ).val() ) {
|
184 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
185 |
+
// Value is retrieved from HTML already generated server side
|
186 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
187 |
+
}
|
188 |
}
|
189 |
+
);
|
190 |
}
|
191 |
+
);
|
192 |
+
}
|
193 |
+
|
194 |
+
init_translations();
|
195 |
|
196 |
+
// Handle the response to a click on a Languages metabox button
|
197 |
+
$( '#ml_box' ).on(
|
198 |
+
'click',
|
199 |
+
'.pll-button',
|
200 |
+
function(){
|
201 |
+
var value = $( this ).hasClass( 'wp-ui-text-highlight' );
|
202 |
var id = $( this ).attr( 'id' );
|
203 |
+
var post_id = $( '#htr_lang_' + id.replace( 'pll_sync_post[', '' ).replace( ']', '' ) ).val();
|
204 |
+
|
205 |
+
if ( 'undefined' == typeof( post_id ) || 0 == post_id || value || confirm( confirm_text ) ) {
|
206 |
+
var data = {
|
207 |
+
action: 'toggle_' + id,
|
208 |
+
value: value,
|
209 |
+
post_type: $( '#post_type' ).val(),
|
210 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
211 |
+
}
|
212 |
+
|
213 |
+
$.post(
|
214 |
+
ajaxurl,
|
215 |
+
data,
|
216 |
+
function( response ){
|
217 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
218 |
+
$.each(
|
219 |
+
res.responses,
|
220 |
+
function() {
|
221 |
+
id = id.replace( '[', '\\[' ).replace( ']', '\\]' );
|
222 |
+
$( '#' + id ).toggleClass( 'wp-ui-text-highlight' ).attr( 'title', this.data ).children( 'span' ).text( this.data );
|
223 |
+
$( 'input[name="' + id + '"]' ).val( ! data['value'] );
|
224 |
+
}
|
225 |
+
);
|
226 |
+
}
|
227 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
+
);
|
231 |
+
}
|
232 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/classic-editor.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(t){t.ajaxPrefilter(function(a){"string"==typeof a.data&&-1!==a.url.indexOf("action=ajax-tag-search")&&(lang=t(".post_lang_choice").val())&&(a.data="lang="+lang+"&"+a.data)})}(jQuery),function(t){tagBox.get=function(a){var l=a.substr(a.indexOf("-")+1),n={action:"get-tagcloud",lang:t(".post_lang_choice").val(),tax:l};t.post(ajaxurl,n,function(n,e){0!=n&&"success"==e||(n=wpAjax.broken),n=t(
|
1 |
+
!function(t){t.ajaxPrefilter(function(a,l,n){"string"==typeof a.data&&-1!==a.url.indexOf("action=ajax-tag-search")&&(lang=t(".post_lang_choice").val())&&(a.data="lang="+lang+"&"+a.data)})}(jQuery),function(t){tagBox.get=function(a){var l=a.substr(a.indexOf("-")+1),n={action:"get-tagcloud",lang:t(".post_lang_choice").val(),tax:l};t.post(ajaxurl,n,function(n,e){0!=n&&"success"==e||(n=wpAjax.broken),n=t("<div />").addClass("the-tagcloud").attr("id","tagcloud-"+l).html(n),t("a",n).click(function(){return tagBox.flushTags(t(this).closest(".inside").children(".tagsdiv"),this),!1}),(v=t(".the-tagcloud").css("display"))?(t(".the-tagcloud").replaceWith(n),t(".the-tagcloud").css("display",v)):t("#"+a).after(n)})}}(jQuery),jQuery(document).ready(function(t){var a=new Array;function l(){t(".tr_lang").each(function(){var a=t(this).attr("id").substring(8),l=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+a+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(n,e){t("#htr_lang_"+a).val(e.item.id),l.html(e.item.link)}}),t(this).blur(function(){t(this).val()||(t("#htr_lang_"+a).val(0),l.html(l.siblings(".hidden").children().clone()))})})}t(".categorydiv").each(function(){var l,n;(l=t(this).attr("id").split("-")).shift(),n=l.join("-"),a.push(n),t("#"+n+"-add-submit").before(t("<input />").attr("type","hidden").attr("id",n+"-lang").attr("name","term_lang_choice").attr("value",t(".post_lang_choice").val()))}),t(".post_lang_choice").change(function(){var n=t(this).val(),e=t(this).children('option[value="'+n+'"]').attr("lang"),i=t('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),s={action:"post_lang_choice",lang:n,post_type:t("#post_type").val(),taxonomies:a,post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,s,function(a){var n=wpAjax.parseAjaxResponse(a,"ajax-response");t.each(n.responses,function(){switch(this.what){case"translations":t(".translations").html(this.data),l();break;case"taxonomy":var a=this.data;t("#"+a+"checklist").html(this.supplemental.all),t("#"+a+"checklist-pop").html(this.supplemental.populars),t("#new"+a+"_parent").replaceWith(this.supplemental.dropdown),t("#"+a+"-lang").val(t(".post_lang_choice").val());break;case"pages":t("#parent_id").html(this.data);break;case"flag":t(".pll-select-flag").html(this.data);break;case"permalink":var n=t("#edit-slug-box");"-1"!=this.data&&n.children().length&&n.html(this.data)}}),t(".tagcloud-link").each(function(){var a=t(this).attr("id");tagBox.get(a)}),t("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+i),t("#content_ifr").contents().find("html").attr("lang",e).attr("dir",i),t("#content_ifr").contents().find("body").attr("dir",i)})}),l(),t("#ml_box").on("click",".pll-button",function(){var a=t(this).hasClass("wp-ui-text-highlight"),l=t(this).attr("id"),n=t("#htr_lang_"+l.replace("pll_sync_post[","").replace("]","")).val();if(void 0===n||0==n||a||confirm(confirm_text)){var e={action:"toggle_"+l,value:a,post_type:t("#post_type").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,e,function(a){var n=wpAjax.parseAjaxResponse(a,"ajax-response");t.each(n.responses,function(){l=l.replace("[","\\[").replace("]","\\]"),t("#"+l).toggleClass("wp-ui-text-highlight").attr("title",this.data).children("span").text(this.data),t('input[name="'+l+'"]').val(!e.value)})})}})});
|
js/nav-menu.js
CHANGED
@@ -1,68 +1,95 @@
|
|
1 |
-
jQuery( document ).ready(
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
|
|
|
|
|
|
|
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
|
|
|
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
32 |
|
33 |
-
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
}
|
63 |
-
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
}
|
68 |
-
|
1 |
+
jQuery( document ).ready(
|
2 |
+
function( $ ) {
|
3 |
+
$( '#update-nav-menu' ).bind(
|
4 |
+
'click',
|
5 |
+
function( e ) {
|
6 |
+
if ( e.target && e.target.className && -1 != e.target.className.indexOf( 'item-edit' ) ) {
|
7 |
+
$( "input[value='#pll_switcher'][type=text]" ).parent().parent().parent().each(
|
8 |
+
function(){
|
9 |
+
var item = $( this ).attr( 'id' ).substring( 19 );
|
10 |
+
$( this ).children( 'p:not( .field-move )' ).remove(); // remove default fields we don't need
|
11 |
|
12 |
+
// item is a number part of id of parent menu item built by WordPress
|
13 |
+
// pll_data is built server side with i18n strings without HTML and data retrieved from post meta
|
14 |
+
// the usage of attr method is safe before append call.
|
15 |
+
h = $( '<input>' ).attr(
|
16 |
+
{
|
17 |
+
type: 'hidden',
|
18 |
+
id: 'edit-menu-item-title-' + item,
|
19 |
+
name: 'menu-item-title[' + item + ']',
|
20 |
+
value: pll_data.title
|
21 |
+
}
|
22 |
+
);
|
23 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
24 |
|
25 |
+
h = $( '<input>' ).attr(
|
26 |
+
{
|
27 |
+
type: 'hidden',
|
28 |
+
id: 'edit-menu-item-url-' + item,
|
29 |
+
name: 'menu-item-url[' + item + ']',
|
30 |
+
value: '#pll_switcher'
|
31 |
+
}
|
32 |
+
);
|
33 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
34 |
|
35 |
+
// a hidden field which exits only if our jQuery code has been executed
|
36 |
+
h = $( '<input>' ).attr(
|
37 |
+
{
|
38 |
+
type: 'hidden',
|
39 |
+
id: 'edit-menu-item-pll-detect-' + item,
|
40 |
+
name: 'menu-item-pll-detect[' + item + ']',
|
41 |
+
value: 1
|
42 |
+
}
|
43 |
+
);
|
44 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
45 |
|
46 |
+
ids = Array( 'hide_if_no_translation', 'hide_current', 'force_home', 'show_flags', 'show_names', 'dropdown' ); // reverse order
|
47 |
|
48 |
+
// add the fields
|
49 |
+
for ( var i = 0, idsLength = ids.length; i < idsLength; i++ ) {
|
50 |
+
p = $( '<p>' ).attr( 'class', 'description' );
|
51 |
+
$( this ).prepend( p );
|
52 |
+
// item is a number part of id of parent menu item built by WordPress
|
53 |
+
// pll_data is built server side with i18n strings without HTML
|
54 |
+
label = $( '<label>' ).attr( 'for', 'edit-menu-item-' + ids[ i ] + '-' + item ).text( ' ' + pll_data.strings[ ids[ i ] ] );
|
55 |
+
p.append( label ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
56 |
+
cb = $( '<input>' ).attr(
|
57 |
+
{
|
58 |
+
type: 'checkbox',
|
59 |
+
id: 'edit-menu-item-' + ids[ i ] + '-' + item,
|
60 |
+
name: 'menu-item-' + ids[ i ] + '[' + item + ']',
|
61 |
+
value: 1
|
62 |
+
}
|
63 |
+
);
|
64 |
+
if ( ( typeof( pll_data.val[ item ] ) != 'undefined' && pll_data.val[ item ][ ids[ i ] ] == 1 ) || ( typeof( pll_data.val[ item ] ) == 'undefined' && ids[ i ] == 'show_names' ) ) { // show_names as default value
|
65 |
+
cb.prop( 'checked', true );
|
66 |
+
}
|
67 |
+
label.prepend( cb );
|
68 |
+
}
|
69 |
+
}
|
70 |
+
);
|
71 |
|
72 |
+
// disallow unchecking both show names and show flags
|
73 |
+
$( '.menu-item-data-object-id' ).each(
|
74 |
+
function() {
|
75 |
+
var id = $( this ).val();
|
76 |
+
var options = ['names-', 'flags-'];
|
77 |
+
$.each(
|
78 |
+
options,
|
79 |
+
function( i, v ) {
|
80 |
+
$( '#edit-menu-item-show_' + v + id ).change(
|
81 |
+
function() {
|
82 |
+
if ( 'checked' != $( this ).attr( 'checked' ) ) {
|
83 |
+
$( '#edit-menu-item-show_' + options[ 1 - i ] + id ).prop( 'checked', true );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
);
|
87 |
+
}
|
88 |
+
);
|
89 |
}
|
90 |
+
);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
);
|
94 |
+
}
|
95 |
+
);
|
js/nav-menu.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function(
|
1 |
+
jQuery(document).ready(function(e){e("#update-nav-menu").bind("click",function(t){t.target&&t.target.className&&-1!=t.target.className.indexOf("item-edit")&&(e("input[value='#pll_switcher'][type=text]").parent().parent().parent().each(function(){var t=e(this).attr("id").substring(19);e(this).children("p:not( .field-move )").remove(),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-title-"+t,name:"menu-item-title["+t+"]",value:pll_data.title}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-url-"+t,name:"menu-item-url["+t+"]",value:"#pll_switcher"}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-pll-detect-"+t,name:"menu-item-pll-detect["+t+"]",value:1}),e(this).append(h),ids=Array("hide_if_no_translation","hide_current","force_home","show_flags","show_names","dropdown");for(var i=0,a=ids.length;i<a;i++)p=e("<p>").attr("class","description"),e(this).prepend(p),label=e("<label>").attr("for","edit-menu-item-"+ids[i]+"-"+t).text(" "+pll_data.strings[ids[i]]),p.append(label),cb=e("<input>").attr({type:"checkbox",id:"edit-menu-item-"+ids[i]+"-"+t,name:"menu-item-"+ids[i]+"["+t+"]",value:1}),(void 0!==pll_data.val[t]&&1==pll_data.val[t][ids[i]]||void 0===pll_data.val[t]&&"show_names"==ids[i])&&cb.prop("checked",!0),label.prepend(cb)}),e(".menu-item-data-object-id").each(function(){var t=e(this).val(),i=["names-","flags-"];e.each(i,function(a,n){e("#edit-menu-item-show_"+n+t).change(function(){"checked"!=e(this).attr("checked")&&e("#edit-menu-item-show_"+i[1-a]+t).prop("checked",!0)})})}))})});
|
js/post.js
CHANGED
@@ -1,68 +1,91 @@
|
|
1 |
/**
|
2 |
* Tag suggest in quick edit
|
3 |
*/
|
|
|
4 |
(function( $ ){
|
5 |
-
$.ajaxPrefilter(
|
6 |
-
|
7 |
-
options.data
|
|
|
|
|
8 |
}
|
9 |
-
|
10 |
})( jQuery );
|
11 |
|
12 |
/**
|
13 |
* Quick edit
|
14 |
*/
|
15 |
(function( $ ) {
|
16 |
-
$( document ).bind(
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
37 |
}
|
38 |
-
}
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
-
}
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
}
|
65 |
-
|
66 |
})( jQuery );
|
67 |
|
68 |
/**
|
@@ -70,43 +93,54 @@
|
|
70 |
* Acts on ajaxSuccess event
|
71 |
*/
|
72 |
(function( $ ) {
|
73 |
-
$( document ).ajaxSuccess(
|
74 |
-
function
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
}
|
89 |
|
90 |
-
//
|
91 |
-
|
92 |
-
if (
|
93 |
-
|
94 |
-
$.each( res.responses, function() {
|
95 |
-
if ( 'row' == this.what ) {
|
96 |
-
$( "#post-" + this.supplemental.post_id ).replaceWith( this.data );
|
97 |
-
}
|
98 |
-
});
|
99 |
}
|
100 |
-
});
|
101 |
-
}
|
102 |
-
|
103 |
-
if ( 'string' == typeof( settings.data ) ) { // Need to check the type due to block editor sometime sending FormData objects
|
104 |
-
var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
|
105 |
-
if ( 'undefined' != typeof( data['action'] ) && 'inline-save' == data['action'] ) {
|
106 |
-
update_rows( data['post_ID'] );
|
107 |
}
|
108 |
}
|
109 |
-
|
110 |
})( jQuery );
|
111 |
|
112 |
/**
|
@@ -114,61 +148,90 @@
|
|
114 |
* When clicking on attach link, filters find post list per media language
|
115 |
*/
|
116 |
(function( $ ){
|
117 |
-
$.ajaxPrefilter(
|
118 |
-
|
119 |
-
options.data
|
|
|
|
|
120 |
}
|
121 |
-
|
122 |
-
})( jQuery )
|
123 |
-
|
124 |
|
125 |
/**
|
126 |
* Bulk translate
|
127 |
*/
|
128 |
-
jQuery( document ).ready(
|
129 |
-
|
|
|
130 |
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
t.whichBulkButtonId = $( this ).attr( 'id' );
|
137 |
-
var n = t.whichBulkButtonId.substr( 2 );
|
138 |
|
139 |
-
|
140 |
-
e
|
|
|
|
|
141 |
|
142 |
-
|
143 |
-
|
144 |
-
}
|
145 |
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
$( '#pll-translate' ).find( '.cancel' ).click(); // Close the form on any other bulk action
|
150 |
-
}
|
151 |
-
} );
|
152 |
-
|
153 |
-
// Cancel
|
154 |
-
$( '#pll-translate' ).on( 'click', '.cancel', function(){
|
155 |
-
$( '#pll-translate' ).siblings( '.hidden' ).remove();
|
156 |
-
$( '#pll-bulk-translate' ).append( $( '#pll-translate' ) );
|
157 |
-
|
158 |
-
// Move focus back to the Bulk Action button that was activated.
|
159 |
-
$( '#' + t.whichBulkButtonId ).focus();
|
160 |
-
} );
|
161 |
-
|
162 |
-
// Act when pressing enter or esc
|
163 |
-
$( '#pll-translate' ).keydown( function( event ){
|
164 |
-
if ( 13 === event.keyCode && ! $( event.target ).hasClass( 'cancel' ) ) {
|
165 |
-
event.preventDefault();
|
166 |
-
$( this ).find( 'input[type=submit]' ).click();
|
167 |
-
}
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
/**
|
2 |
* Tag suggest in quick edit
|
3 |
*/
|
4 |
+
|
5 |
(function( $ ){
|
6 |
+
$.ajaxPrefilter(
|
7 |
+
function( options, originalOptions, jqXHR ) {
|
8 |
+
if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=ajax-tag-search' ) && ( lang = $( ':input[name="inline_lang_choice"]' ).val() ) ) {
|
9 |
+
options.data = 'lang=' + lang + '&' + options.data;
|
10 |
+
}
|
11 |
}
|
12 |
+
);
|
13 |
})( jQuery );
|
14 |
|
15 |
/**
|
16 |
* Quick edit
|
17 |
*/
|
18 |
(function( $ ) {
|
19 |
+
$( document ).bind(
|
20 |
+
'DOMNodeInserted',
|
21 |
+
function( e ) {
|
22 |
+
var t = $( e.target );
|
23 |
+
|
24 |
+
// WP inserts the quick edit from
|
25 |
+
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
26 |
+
var post_id = t.prev().attr( 'id' ).replace( "post-", "" );
|
27 |
+
|
28 |
+
if ( post_id > 0 ) {
|
29 |
+
// language dropdown
|
30 |
+
var select = t.find( ':input[name="inline_lang_choice"]' );
|
31 |
+
var lang = $( '#lang_' + post_id ).html();
|
32 |
+
select.val( lang ); // populates the dropdown
|
33 |
+
|
34 |
+
filter_terms( lang ); // initial filter for category checklist
|
35 |
+
filter_pages( lang ); // initial filter for parent dropdown
|
36 |
+
|
37 |
+
// modify category checklist an parent dropdown on language change
|
38 |
+
select.change(
|
39 |
+
function() {
|
40 |
+
filter_terms( $( this ).val() );
|
41 |
+
filter_pages( $( this ).val() );
|
42 |
+
}
|
43 |
+
);
|
44 |
+
}
|
45 |
}
|
|
|
46 |
|
47 |
+
// filter category checklist
|
48 |
+
function filter_terms( lang ) {
|
49 |
+
if ( "undefined" != typeof( pll_term_languages ) ) {
|
50 |
+
$.each(
|
51 |
+
pll_term_languages,
|
52 |
+
function( lg, term_tax ) {
|
53 |
+
$.each(
|
54 |
+
term_tax,
|
55 |
+
function( tax, terms ) {
|
56 |
+
$.each(
|
57 |
+
terms,
|
58 |
+
function( i ) {
|
59 |
+
id = '#' + tax + '-' + pll_term_languages[ lg ][ tax ][ i ];
|
60 |
+
lang == lg ? $( id ).show() : $( id ).hide();
|
61 |
+
}
|
62 |
+
);
|
63 |
+
}
|
64 |
+
);
|
65 |
+
}
|
66 |
+
);
|
67 |
+
}
|
68 |
}
|
|
|
69 |
|
70 |
+
// filter parent page dropdown list
|
71 |
+
function filter_pages( lang ) {
|
72 |
+
if ( "undefined" != typeof( pll_page_languages ) ) {
|
73 |
+
$.each(
|
74 |
+
pll_page_languages,
|
75 |
+
function( lg, pages ) {
|
76 |
+
$.each(
|
77 |
+
pages,
|
78 |
+
function( i ) {
|
79 |
+
v = $( '#post_parent option[value="' + pll_page_languages[ lg ][ i ] + '"]' );
|
80 |
+
lang == lg ? v.show() : v.hide();
|
81 |
+
}
|
82 |
+
);
|
83 |
+
}
|
84 |
+
);
|
85 |
+
}
|
86 |
}
|
87 |
}
|
88 |
+
);
|
89 |
})( jQuery );
|
90 |
|
91 |
/**
|
93 |
* Acts on ajaxSuccess event
|
94 |
*/
|
95 |
(function( $ ) {
|
96 |
+
$( document ).ajaxSuccess(
|
97 |
+
function( event, xhr, settings ) {
|
98 |
+
function update_rows( post_id ) {
|
99 |
+
// collect old translations
|
100 |
+
var translations = new Array();
|
101 |
+
$( '.translation_' + post_id ).each(
|
102 |
+
function() {
|
103 |
+
translations.push( $( this ).parent().parent().attr( 'id' ).substring( 5 ) );
|
104 |
+
}
|
105 |
+
);
|
106 |
+
|
107 |
+
var data = {
|
108 |
+
action: 'pll_update_post_rows',
|
109 |
+
post_id: post_id,
|
110 |
+
translations: translations.join( ',' ),
|
111 |
+
post_type: $( "input[name='post_type']" ).val(),
|
112 |
+
screen: $( "input[name='screen']" ).val(),
|
113 |
+
_pll_nonce: $( "input[name='_inline_edit']" ).val() // reuse quick edit nonce
|
114 |
+
};
|
115 |
+
|
116 |
+
// get the modified rows in ajax and update them
|
117 |
+
$.post(
|
118 |
+
ajaxurl,
|
119 |
+
data,
|
120 |
+
function( response ) {
|
121 |
+
if ( response ) {
|
122 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
123 |
+
$.each(
|
124 |
+
res.responses,
|
125 |
+
function() {
|
126 |
+
if ( 'row' == this.what ) {
|
127 |
+
$( "#post-" + this.supplemental.post_id ).replaceWith( this.data );
|
128 |
+
}
|
129 |
+
}
|
130 |
+
);
|
131 |
+
}
|
132 |
+
}
|
133 |
+
);
|
134 |
}
|
135 |
|
136 |
+
if ( 'string' == typeof( settings.data ) ) { // Need to check the type due to block editor sometime sending FormData objects
|
137 |
+
var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
|
138 |
+
if ( 'undefined' != typeof( data['action'] ) && 'inline-save' == data['action'] ) {
|
139 |
+
update_rows( data['post_ID'] );
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
}
|
142 |
}
|
143 |
+
);
|
144 |
})( jQuery );
|
145 |
|
146 |
/**
|
148 |
* When clicking on attach link, filters find post list per media language
|
149 |
*/
|
150 |
(function( $ ){
|
151 |
+
$.ajaxPrefilter(
|
152 |
+
function ( options, originalOptions, jqXHR ) {
|
153 |
+
if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=find_posts' ) ) {
|
154 |
+
options.data = 'pll_post_id=' + $( '#affected' ).val() + '&' + options.data;
|
155 |
+
}
|
156 |
}
|
157 |
+
);
|
158 |
+
})( jQuery );
|
|
|
159 |
|
160 |
/**
|
161 |
* Bulk translate
|
162 |
*/
|
163 |
+
jQuery( document ).ready(
|
164 |
+
function( $ ) {
|
165 |
+
var t = this;
|
166 |
|
167 |
+
$( '.editinline' ).click(
|
168 |
+
function(){
|
169 |
+
$( '#pll-translate' ).find( '.cancel' ).click(); // Close the form on quick edit
|
170 |
+
}
|
171 |
+
);
|
|
|
|
|
172 |
|
173 |
+
$( '#doaction, #doaction2' ).click(
|
174 |
+
function( e ){
|
175 |
+
t.whichBulkButtonId = $( this ).attr( 'id' );
|
176 |
+
var n = t.whichBulkButtonId.substr( 2 );
|
177 |
|
178 |
+
if ( 'pll_translate' === $( 'select[name="' + n + '"]' ).val() ) {
|
179 |
+
e.preventDefault();
|
|
|
180 |
|
181 |
+
if ( typeof inlineEditPost !== 'undefined' ) { // Not available for media.
|
182 |
+
inlineEditPost.revert(); // Close Bulk edit and Quick edit if open.
|
183 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
|
185 |
+
$( '#pll-translate td' ).attr( 'colspan', $( 'th:visible, td:visible', '.widefat:first thead' ).length );
|
186 |
+
$( 'table.widefat tbody' ).prepend( $( '#pll-translate' ) ).prepend( '<tr class="hidden"></tr>' ); // The hidden tr allows to keep the background color
|
187 |
+
} else {
|
188 |
+
$( '#pll-translate' ).find( '.cancel' ).click();
|
189 |
+
}
|
190 |
+
}
|
191 |
+
);
|
192 |
+
|
193 |
+
// Cancel
|
194 |
+
$( '#pll-translate' ).on(
|
195 |
+
'click',
|
196 |
+
'.cancel',
|
197 |
+
function(){
|
198 |
+
// Close the form on any other bulk action
|
199 |
+
$( '#pll-translate' ).siblings( '.hidden' ).remove();
|
200 |
+
// #pll-translate is built and come from server side and is well escaped when necessary
|
201 |
+
$( '#pll-bulk-translate' ).append( $( '#pll-translate' ) ); //phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
202 |
+
|
203 |
+
// Move focus back to the Bulk Action button that was activated.
|
204 |
+
$( '#' + t.whichBulkButtonId ).focus();
|
205 |
+
}
|
206 |
+
);
|
207 |
+
|
208 |
+
// Act when pressing enter or esc
|
209 |
+
$( '#pll-translate' ).keydown(
|
210 |
+
function( event ){
|
211 |
+
if ( 13 === event.keyCode && ! $( event.target ).hasClass( 'cancel' ) ) {
|
212 |
+
event.preventDefault();
|
213 |
+
$( this ).find( 'input[type=submit]' ).click();
|
214 |
+
}
|
215 |
+
if ( 27 === event.keyCode ) {
|
216 |
+
event.preventDefault();
|
217 |
+
$( this ).find( '.cancel' ).click();
|
218 |
+
}
|
219 |
+
}
|
220 |
+
);
|
221 |
+
|
222 |
+
// Clean DOM in case of file download
|
223 |
+
$( '#posts-filter' ).on(
|
224 |
+
'submit',
|
225 |
+
function() {
|
226 |
+
$( '.settings-error' ).remove();
|
227 |
+
setTimeout(
|
228 |
+
function() {
|
229 |
+
$( 'input[type=checkbox]:checked' ).attr( 'checked', false );
|
230 |
+
$( '#pll-translate' ).find( '.cancel' ).trigger( 'click' );
|
231 |
+
},
|
232 |
+
500
|
233 |
+
);
|
234 |
+
}
|
235 |
+
);
|
236 |
+
}
|
237 |
+
);
|
js/post.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(t){t.ajaxPrefilter(function(n){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=t(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)})}(jQuery),function(t){t(document).bind("DOMNodeInserted",function(n){function
|
1 |
+
!function(t){t.ajaxPrefilter(function(n){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=t(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)})}(jQuery),function(t){t(document).bind("DOMNodeInserted",function(n){function e(n){"undefined"!=typeof pll_term_languages&&t.each(pll_term_languages,function(e,a){t.each(a,function(a,i){t.each(i,function(i){id="#"+a+"-"+pll_term_languages[e][a][i],n==e?t(id).show():t(id).hide()})})})}function a(n){"undefined"!=typeof pll_page_languages&&t.each(pll_page_languages,function(e,a){t.each(a,function(a){v=t('#post_parent option[value="'+pll_page_languages[e][a]+'"]'),n==e?v.show():v.hide()})})}var i=t(n.target);if("inline-edit"==i.attr("id")){var l=i.prev().attr("id").replace("post-","");if(l>0){var c=i.find(':input[name="inline_lang_choice"]'),o=t("#lang_"+l).html();c.val(o),e(o),a(o),c.change(function(){e(t(this).val()),a(t(this).val())})}}})}(jQuery),function(t){t(document).ajaxSuccess(function(n,e,a){function i(n){var e=new Array;t(".translation_"+n).each(function(){e.push(t(this).parent().parent().attr("id").substring(5))});var a={action:"pll_update_post_rows",post_id:n,translations:e.join(","),post_type:t("input[name='post_type']").val(),screen:t("input[name='screen']").val(),_pll_nonce:t("input[name='_inline_edit']").val()};t.post(ajaxurl,a,function(n){if(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");t.each(e.responses,function(){"row"==this.what&&t("#post-"+this.supplemental.post_id).replaceWith(this.data)})}})}if("string"==typeof a.data){var l=wpAjax.unserialize(a.data);"undefined"!=typeof l.action&&"inline-save"==l.action&&i(l.post_ID)}})}(jQuery),function(t){t.ajaxPrefilter(function(n){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+t("#affected").val()+"&"+n.data)})}(jQuery),jQuery(document).ready(function(t){var n=this;t(".editinline").click(function(){t("#pll-translate").find(".cancel").click()}),t("#doaction, #doaction2").click(function(e){n.whichBulkButtonId=t(this).attr("id");var a=n.whichBulkButtonId.substr(2);"pll_translate"===t('select[name="'+a+'"]').val()?(e.preventDefault(),"undefined"!=typeof inlineEditPost&&inlineEditPost.revert(),t("#pll-translate td").attr("colspan",t("th:visible, td:visible",".widefat:first thead").length),t("table.widefat tbody").prepend(t("#pll-translate")).prepend('<tr class="hidden"></tr>')):t("#pll-translate").find(".cancel").click()}),t("#pll-translate").on("click",".cancel",function(){t("#pll-translate").siblings(".hidden").remove(),t("#pll-bulk-translate").append(t("#pll-translate")),t("#"+n.whichBulkButtonId).focus()}),t("#pll-translate").keydown(function(n){13!==n.keyCode||t(n.target).hasClass("cancel")||(n.preventDefault(),t(this).find("input[type=submit]").click()),27===n.keyCode&&(n.preventDefault(),t(this).find(".cancel").click())}),t("#posts-filter").on("submit",function(){t(".settings-error").remove(),setTimeout(function(){t("input[type=checkbox]:checked").attr("checked",!1),t("#pll-translate").find(".cancel").trigger("click")},500)})});
|
js/term.js
CHANGED
@@ -1,167 +1,203 @@
|
|
1 |
// quick edit
|
2 |
(function( $ ) {
|
3 |
-
$( document ).bind(
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
20 |
}
|
21 |
}
|
22 |
}
|
23 |
-
|
24 |
})( jQuery );
|
25 |
|
26 |
|
27 |
// update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit
|
28 |
// acts on ajaxSuccess event
|
29 |
(function( $ ) {
|
30 |
-
$( document ).ajaxSuccess(
|
31 |
-
function
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
res = wpAjax.parseAjaxResponse( xhr.responseXML, 'ajax-response' );
|
67 |
-
$.each( res.responses, function() {
|
68 |
-
if ( 'term' == this.what ) {
|
69 |
-
update_rows( this.supplemental.term_id );
|
70 |
}
|
71 |
-
}
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
86 |
}
|
87 |
}
|
88 |
-
|
89 |
})( jQuery );
|
90 |
|
91 |
-
jQuery( document ).ready(
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
-
|
122 |
-
});
|
123 |
-
}
|
124 |
-
|
125 |
-
init_translations();
|
126 |
-
|
127 |
-
// ajax for changing the term's language
|
128 |
-
$( '#term_lang_choice' ).change(function() {
|
129 |
-
var value = $( this ).val();
|
130 |
-
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
131 |
-
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' );
|
132 |
-
|
133 |
-
var data = {
|
134 |
-
action: 'term_lang_choice',
|
135 |
-
lang: value,
|
136 |
-
from_tag: $( "input[name='from_tag']" ).val(),
|
137 |
-
term_id: $( "input[name='tag_ID']" ).val(),
|
138 |
-
taxonomy: $( "input[name='taxonomy']" ).val(),
|
139 |
-
post_type: typenow,
|
140 |
-
_pll_nonce: $( '#_pll_nonce' ).val()
|
141 |
}
|
142 |
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
}
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
// quick edit
|
2 |
(function( $ ) {
|
3 |
+
$( document ).bind(
|
4 |
+
'DOMNodeInserted',
|
5 |
+
function( e ) {
|
6 |
+
var t = $( e.target );
|
7 |
+
|
8 |
+
// WP inserts the quick edit from
|
9 |
+
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
10 |
+
var term_id = t.prev().attr( 'id' ).replace( "tag-", "" );
|
11 |
+
|
12 |
+
if ( term_id > 0 ) {
|
13 |
+
// language dropdown
|
14 |
+
var select = t.find( ':input[name="inline_lang_choice"]' );
|
15 |
+
var lang = $( '#lang_' + term_id ).html();
|
16 |
+
select.val( lang ); // populates the dropdown
|
17 |
+
|
18 |
+
// disable the language dropdown for default categories
|
19 |
+
var default_cat = $( '#default_cat_' + term_id ).html();
|
20 |
+
if ( term_id == default_cat ) {
|
21 |
+
select.prop( 'disabled', true );
|
22 |
+
}
|
23 |
}
|
24 |
}
|
25 |
}
|
26 |
+
);
|
27 |
})( jQuery );
|
28 |
|
29 |
|
30 |
// update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit
|
31 |
// acts on ajaxSuccess event
|
32 |
(function( $ ) {
|
33 |
+
$( document ).ajaxSuccess(
|
34 |
+
function( event, xhr, settings ) {
|
35 |
+
function update_rows( term_id ) {
|
36 |
+
// collect old translations
|
37 |
+
var translations = new Array();
|
38 |
+
$( '.translation_' + term_id ).each(
|
39 |
+
function() {
|
40 |
+
translations.push( $( this ).parent().parent().attr( 'id' ).substring( 4 ) );
|
41 |
+
}
|
42 |
+
);
|
43 |
+
|
44 |
+
var data = {
|
45 |
+
action: 'pll_update_term_rows',
|
46 |
+
term_id: term_id,
|
47 |
+
translations: translations.join( ',' ),
|
48 |
+
taxonomy: $( "input[name='taxonomy']" ).val(),
|
49 |
+
post_type: $( "input[name='post_type']" ).val(),
|
50 |
+
screen: $( "input[name='screen']" ).val(),
|
51 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
52 |
+
};
|
53 |
+
|
54 |
+
// get the modified rows in ajax and update them
|
55 |
+
$.post(
|
56 |
+
ajaxurl,
|
57 |
+
data,
|
58 |
+
function( response ) {
|
59 |
+
if ( response ) {
|
60 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
61 |
+
$.each(
|
62 |
+
res.responses,
|
63 |
+
function() {
|
64 |
+
if ( 'row' == this.what ) {
|
65 |
+
$( "#tag-" + this.supplemental.term_id ).replaceWith( this.data );
|
66 |
+
}
|
67 |
+
}
|
68 |
+
);
|
|
|
|
|
|
|
|
|
69 |
}
|
70 |
+
}
|
71 |
+
);
|
72 |
+
}
|
73 |
|
74 |
+
var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
|
75 |
+
if ( 'undefined' != typeof( data['action'] ) ) {
|
76 |
+
switch ( data['action'] ) {
|
77 |
+
// when adding a term, the new term_id is in the ajax response
|
78 |
+
case 'add-tag':
|
79 |
+
res = wpAjax.parseAjaxResponse( xhr.responseXML, 'ajax-response' );
|
80 |
+
$.each(
|
81 |
+
res.responses,
|
82 |
+
function() {
|
83 |
+
if ( 'term' == this.what ) {
|
84 |
+
update_rows( this.supplemental.term_id );
|
85 |
+
}
|
86 |
+
}
|
87 |
+
);
|
88 |
+
|
89 |
+
// and also reset translations hidden input fields
|
90 |
+
$( '.htr_lang' ).val( 0 );
|
91 |
+
break;
|
92 |
|
93 |
+
// when deleting a term
|
94 |
+
case 'delete-tag':
|
95 |
+
update_rows( data['tag_ID'] );
|
96 |
+
break;
|
97 |
|
98 |
+
// in case the language is modified in quick edit and breaks translations
|
99 |
+
case 'inline-save-tax':
|
100 |
+
update_rows( data['tax_ID'] );
|
101 |
+
break;
|
102 |
+
}
|
103 |
}
|
104 |
}
|
105 |
+
);
|
106 |
})( jQuery );
|
107 |
|
108 |
+
jQuery( document ).ready(
|
109 |
+
function( $ ) {
|
110 |
+
// translations autocomplete input box
|
111 |
+
function init_translations() {
|
112 |
+
$( '.tr_lang' ).each(
|
113 |
+
function(){
|
114 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
115 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
116 |
+
|
117 |
+
$( this ).autocomplete(
|
118 |
+
{
|
119 |
+
minLength: 0,
|
120 |
+
source: ajaxurl + '?action=pll_terms_not_translated' +
|
121 |
+
'&term_language=' + $( '#term_lang_choice' ).val() +
|
122 |
+
'&term_id=' + $( "input[name='tag_ID']" ).val() +
|
123 |
+
'&taxonomy=' + $( "input[name='taxonomy']" ).val() +
|
124 |
+
'&translation_language=' + tr_lang +
|
125 |
+
'&post_type=' + typenow +
|
126 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
127 |
+
select: function( event, ui ) {
|
128 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
129 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
130 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
131 |
+
},
|
132 |
+
}
|
133 |
+
);
|
134 |
+
|
135 |
+
// when the input box is emptied
|
136 |
+
$( this ).blur(
|
137 |
+
function() {
|
138 |
+
if ( ! $( this ).val() ) {
|
139 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
140 |
+
// Value is retrieved from HTML already generated server side
|
141 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
142 |
+
}
|
143 |
+
}
|
144 |
+
);
|
145 |
}
|
146 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
}
|
148 |
|
149 |
+
init_translations();
|
150 |
+
|
151 |
+
// ajax for changing the term's language
|
152 |
+
$( '#term_lang_choice' ).change(
|
153 |
+
function() {
|
154 |
+
var value = $( this ).val();
|
155 |
+
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
156 |
+
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' );
|
157 |
+
|
158 |
+
var data = {
|
159 |
+
action: 'term_lang_choice',
|
160 |
+
lang: value,
|
161 |
+
from_tag: $( "input[name='from_tag']" ).val(),
|
162 |
+
term_id: $( "input[name='tag_ID']" ).val(),
|
163 |
+
taxonomy: $( "input[name='taxonomy']" ).val(),
|
164 |
+
post_type: typenow,
|
165 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
166 |
+
};
|
167 |
+
|
168 |
+
$.post(
|
169 |
+
ajaxurl,
|
170 |
+
data,
|
171 |
+
function( response ) {
|
172 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
173 |
+
$.each(
|
174 |
+
res.responses,
|
175 |
+
function() {
|
176 |
+
switch ( this.what ) {
|
177 |
+
case 'translations': // translations fields
|
178 |
+
// Data is built and come from server side and is well escaped when necessary
|
179 |
+
$( "#term-translations" ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
180 |
+
init_translations();
|
181 |
+
break;
|
182 |
+
case 'parent': // parent dropdown list for hierarchical taxonomies
|
183 |
+
$( '#parent' ).replaceWith( this.data );
|
184 |
+
break;
|
185 |
+
case 'tag_cloud': // popular items
|
186 |
+
$( '.tagcloud' ).replaceWith( this.data );
|
187 |
+
break;
|
188 |
+
case 'flag': // flag in front of the select dropdown
|
189 |
+
// Data is built and come from server side and is well escaped when necessary
|
190 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
191 |
+
break;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
);
|
195 |
+
|
196 |
+
// Modifies the text direction
|
197 |
+
$( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
|
198 |
+
}
|
199 |
+
);
|
200 |
+
}
|
201 |
+
);
|
202 |
+
}
|
203 |
+
);
|
js/term.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(a){a(document).bind("DOMNodeInserted",function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i)
|
1 |
+
!function(a){a(document).bind("DOMNodeInserted",function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i),e==a("#default_cat_"+e).html()&&l.prop("disabled",!0)}}})}(jQuery),function(a){a(document).ajaxSuccess(function(t,n,e){function l(t){var n=new Array;a(".translation_"+t).each(function(){n.push(a(this).parent().parent().attr("id").substring(4))});var e={action:"pll_update_term_rows",term_id:t,translations:n.join(","),taxonomy:a("input[name='taxonomy']").val(),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,e,function(t){if(t){var n=wpAjax.parseAjaxResponse(t,"ajax-response");a.each(n.responses,function(){"row"==this.what&&a("#tag-"+this.supplemental.term_id).replaceWith(this.data)})}})}var i=wpAjax.unserialize(e.data);if(void 0!==i.action)switch(i.action){case"add-tag":res=wpAjax.parseAjaxResponse(n.responseXML,"ajax-response"),a.each(res.responses,function(){"term"==this.what&&l(this.supplemental.term_id)}),a(".htr_lang").val(0);break;case"delete-tag":l(i.tag_ID);break;case"inline-save-tax":l(i.tax_ID)}})}(jQuery),jQuery(document).ready(function(a){function t(){a(".tr_lang").each(function(){var t=a(this).attr("id").substring(8),n=a(this).parent().parent().siblings(".pll-edit-column");a(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_terms_not_translated&term_language="+a("#term_lang_choice").val()+"&term_id="+a("input[name='tag_ID']").val()+"&taxonomy="+a("input[name='taxonomy']").val()+"&translation_language="+t+"&post_type="+typenow+"&_pll_nonce="+a("#_pll_nonce").val(),select:function(e,l){a("#htr_lang_"+t).val(l.item.id),n.html(l.item.link)}}),a(this).blur(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))})})}t(),a("#term_lang_choice").change(function(){var n=a(this).val(),e=a(this).children('option[value="'+n+'"]').attr("lang"),l=a('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),i={action:"term_lang_choice",lang:n,from_tag:a("input[name='from_tag']").val(),term_id:a("input[name='tag_ID']").val(),taxonomy:a("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,i,function(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(e.responses,function(){switch(this.what){case"translations":a("#term-translations").html(this.data),t();break;case"parent":a("#parent").replaceWith(this.data);break;case"tag_cloud":a(".tagcloud").replaceWith(this.data);break;case"flag":a(".pll-select-flag").html(this.data)}}),a("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)})})});
|
js/user.js
CHANGED
@@ -1,20 +1,27 @@
|
|
1 |
-
jQuery( document ).ready(
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
|
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
1 |
+
jQuery( document ).ready(
|
2 |
+
function( $ ) {
|
3 |
+
// biography
|
4 |
+
// FIXME there is probably a more efficient way to do this
|
5 |
+
var td = $( '#description' ).parent();
|
6 |
+
var d = $( '#description' ).clone();
|
7 |
+
var span = td.children( '.description' ).clone();
|
8 |
+
td.children().remove();
|
9 |
|
10 |
+
$( '.biography' ).each(
|
11 |
+
function(){
|
12 |
+
lang = $( this ).attr( 'name' ).split( '___' );
|
13 |
+
desc = d.clone();
|
14 |
+
desc.attr( 'name', 'description_' + lang[0] );
|
15 |
+
desc.attr( 'id', 'description_' + lang[0] );
|
16 |
+
// Whitelist because description and lang value is already escaped by the side of PHP
|
17 |
+
desc.html( $( this ).val() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
18 |
+
td.append( $( '<div></div>' ).text( lang[1] ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
19 |
+
td.append( desc ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
20 |
+
}
|
21 |
+
);
|
22 |
|
23 |
+
td.append( '<br />' );
|
24 |
+
// Whitelist because description come from html code generated by WordPress
|
25 |
+
td.append( span ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
26 |
+
}
|
27 |
+
);
|
js/user.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function(e){var n=e("#description").parent(),d=e("#description").clone(),i=n.children(".description").clone();n.children().remove(),e(".biography").each(function(){lang=e(this).attr("name").split("___"),desc=d.clone(),desc.attr("name","description_"+lang[0]),desc.html(e(this).val()),n.append("<div>"
|
1 |
+
jQuery(document).ready(function(e){var n=e("#description").parent(),d=e("#description").clone(),i=n.children(".description").clone();n.children().remove(),e(".biography").each(function(){lang=e(this).attr("name").split("___"),desc=d.clone(),desc.attr("name","description_"+lang[0]),desc.attr("id","description_"+lang[0]),desc.html(e(this).val()),n.append(e("<div></div>").text(lang[1])),n.append(desc)}),n.append("<br />"),n.append(i)});
|
js/widgets.js
CHANGED
@@ -1,83 +1,93 @@
|
|
1 |
-
jQuery(
|
2 |
-
|
|
|
3 |
|
4 |
-
|
5 |
-
|
6 |
-
}
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Prepend widget titles with a flag once a language is selected.
|
10 |
-
* @param {object} widget The widget element.
|
11 |
-
* @return {void} Nothing.
|
12 |
-
*/
|
13 |
-
function add_flag( widget ) {
|
14 |
-
if ( ! flags ) {
|
15 |
-
return;
|
16 |
}
|
17 |
-
widget = $( widget );
|
18 |
-
var title = $( '.widget-top .widget-title h3', widget ),
|
19 |
-
locale = $( '.pll-lang-choice option:selected', widget ).val(),
|
20 |
-
icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
|
21 |
-
|
22 |
-
if ( icon ) {
|
23 |
-
icon += ' ';
|
24 |
-
var current = $( '.pll-lang', title );
|
25 |
-
if ( current.length ) {
|
26 |
-
current.html( icon );
|
27 |
-
} else {
|
28 |
-
flag = '<span class="pll-lang">' + icon + '</span>';
|
29 |
-
title.prepend( flag );
|
30 |
-
}
|
31 |
-
} else {
|
32 |
-
$( '.pll-lang', title ).remove();
|
33 |
-
}
|
34 |
-
}
|
35 |
-
|
36 |
-
if ( 'undefined' !== typeof wp.customize ) {
|
37 |
-
|
38 |
-
widgets_container = $( '#customize-controls' );
|
39 |
-
widgets_selector = '.customize-control .widget';
|
40 |
|
41 |
/**
|
42 |
-
*
|
43 |
-
*
|
44 |
-
* @
|
45 |
-
*
|
46 |
-
* @param {object} control The control type.
|
47 |
* @return {void} Nothing.
|
48 |
*/
|
49 |
-
function
|
50 |
-
if ( !
|
51 |
return;
|
52 |
}
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
*/
|
58 |
-
control
|
|
|
|
|
|
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
|
67 |
|
68 |
-
|
69 |
-
|
70 |
|
71 |
-
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
77 |
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
}
|
|
1 |
+
jQuery(
|
2 |
+
function( $ ) {
|
3 |
+
var widgets_container, widgets_selector, flags;
|
4 |
|
5 |
+
if ( 'undefined' !== typeof pll_widgets && pll_widgets.hasOwnProperty( 'flags' ) ) {
|
6 |
+
flags = pll_widgets.flags;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
/**
|
10 |
+
* Prepend widget titles with a flag once a language is selected.
|
11 |
+
*
|
12 |
+
* @param {object} widget The widget element.
|
|
|
|
|
13 |
* @return {void} Nothing.
|
14 |
*/
|
15 |
+
function add_flag( widget ) {
|
16 |
+
if ( ! flags ) {
|
17 |
return;
|
18 |
}
|
19 |
+
widget = $( widget );
|
20 |
+
var title = $( '.widget-top .widget-title h3', widget ),
|
21 |
+
locale = $( '.pll-lang-choice option:selected', widget ).val(),
|
22 |
+
// Icon is HTML built and come from server side and is well escaped when necessary
|
23 |
+
icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
|
24 |
|
25 |
+
if ( icon ) {
|
26 |
+
icon += ' ';
|
27 |
+
var current = $( '.pll-lang', title );
|
28 |
+
if ( current.length ) {
|
29 |
+
current.html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
30 |
+
} else {
|
31 |
+
flag = $( '<span />' ).addClass( 'pll-lang' ).html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
32 |
+
title.prepend( flag );
|
33 |
+
}
|
34 |
+
} else {
|
35 |
+
$( '.pll-lang', title ).remove();
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
if ( 'undefined' !== typeof wp.customize ) {
|
40 |
+
|
41 |
+
widgets_container = $( '#customize-controls' );
|
42 |
+
widgets_selector = '.customize-control .widget';
|
43 |
+
|
44 |
+
/**
|
45 |
+
* WP Customizer add control listener.
|
46 |
+
*
|
47 |
+
* @link https://wordpress.stackexchange.com/questions/256536/callback-after-wordpress-customizer-complete-loading
|
48 |
+
*
|
49 |
+
* @param {object} control The control type.
|
50 |
+
* @return {void} Nothing.
|
51 |
*/
|
52 |
+
function customize_add_flag( control ) {
|
53 |
+
if ( ! control.extended( wp.customize.Widgets.WidgetControl ) ) {
|
54 |
+
return;
|
55 |
+
}
|
56 |
|
57 |
+
/*
|
58 |
+
* Make sure the widget's contents are embedded; normally this is done
|
59 |
+
* when the control is expanded, for DOM performance reasons.
|
60 |
+
*/
|
61 |
+
control.embedWidgetContent();
|
62 |
+
|
63 |
+
// Now we know for sure the widget is fully embedded.
|
64 |
+
add_flag( control.container.find( '.widget' ) );
|
65 |
+
}
|
66 |
+
wp.customize.control.each( customize_add_flag );
|
67 |
+
wp.customize.control.bind( 'add', customize_add_flag );
|
68 |
|
69 |
+
} else {
|
70 |
|
71 |
+
widgets_container = $( '#widgets-right' );
|
72 |
+
widgets_selector = '.widget';
|
73 |
|
74 |
+
}
|
75 |
|
76 |
+
// Add flags on load.
|
77 |
+
$( widgets_selector, widgets_container ).each(
|
78 |
+
function() {
|
79 |
+
add_flag( this );
|
80 |
+
}
|
81 |
+
);
|
82 |
|
83 |
+
// Update flags.
|
84 |
+
widgets_container.on(
|
85 |
+
'change',
|
86 |
+
'.pll-lang-choice',
|
87 |
+
function() {
|
88 |
+
add_flag( $( this ).parents( '.widget' ) );
|
89 |
+
}
|
90 |
+
);
|
91 |
|
92 |
+
}
|
93 |
+
);
|
js/widgets.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
jQuery(function(e){function
|
1 |
+
jQuery(function(e){var t,l,n;function i(t){if(n){t=e(t);var l=e(".widget-top .widget-title h3",t),i=e(".pll-lang-choice option:selected",t).val(),o=i&&n.hasOwnProperty(i)?n[i]:null;if(o){o+=" ";var d=e(".pll-lang",l);d.length?d.html(o):(flag=e("<span />").addClass("pll-lang").html(o),l.prepend(flag))}else e(".pll-lang",l).remove()}}if("undefined"!=typeof pll_widgets&&pll_widgets.hasOwnProperty("flags")&&(n=pll_widgets.flags),void 0!==wp.customize){function o(e){e.extended(wp.customize.Widgets.WidgetControl)&&(e.embedWidgetContent(),i(e.container.find(".widget")))}t=e("#customize-controls"),l=".customize-control .widget",wp.customize.control.each(o),wp.customize.control.bind("add",o)}else t=e("#widgets-right"),l=".widget";e(l,t).each(function(){i(this)}),t.on("change",".pll-lang-choice",function(){i(e(this).parents(".widget"))})});
|
lingotek/lingotek.php
CHANGED
@@ -14,8 +14,6 @@ class PLL_Lingotek {
|
|
14 |
* @since 1.7.7
|
15 |
*/
|
16 |
public function init() {
|
17 |
-
$options = get_option( 'polylang' );
|
18 |
-
|
19 |
// The Lingotek tab
|
20 |
add_filter( 'pll_settings_tabs', array( $this, 'add_tab' ) );
|
21 |
add_action( 'pll_settings_active_tab_lingotek', array( $this, 'display_tab' ) );
|
@@ -30,7 +28,7 @@ class PLL_Lingotek {
|
|
30 |
$content = __( 'You’ve just upgraded to the latest version of Polylang! Would you like to automatically translate your website for free?', 'polylang' );
|
31 |
|
32 |
$buttons = sprintf(
|
33 |
-
'<a href="%s" class="button button-primary"
|
34 |
admin_url( 'admin.php?page=mlang_lingotek' ),
|
35 |
__( 'Learn more', 'polylang' )
|
36 |
);
|
@@ -39,7 +37,7 @@ class PLL_Lingotek {
|
|
39 |
$content .= ' ' . __( 'Click on Activate Lingotek to start translating.', 'polylang' );
|
40 |
|
41 |
$buttons = sprintf(
|
42 |
-
'<a href="%s" class="button button-primary"
|
43 |
$link,
|
44 |
__( 'Activate Lingotek', 'polylang' )
|
45 |
) . $buttons;
|
14 |
* @since 1.7.7
|
15 |
*/
|
16 |
public function init() {
|
|
|
|
|
17 |
// The Lingotek tab
|
18 |
add_filter( 'pll_settings_tabs', array( $this, 'add_tab' ) );
|
19 |
add_action( 'pll_settings_active_tab_lingotek', array( $this, 'display_tab' ) );
|
28 |
$content = __( 'You’ve just upgraded to the latest version of Polylang! Would you like to automatically translate your website for free?', 'polylang' );
|
29 |
|
30 |
$buttons = sprintf(
|
31 |
+
'<a href="%s" class="button button-primary">%s</a>',
|
32 |
admin_url( 'admin.php?page=mlang_lingotek' ),
|
33 |
__( 'Learn more', 'polylang' )
|
34 |
);
|
37 |
$content .= ' ' . __( 'Click on Activate Lingotek to start translating.', 'polylang' );
|
38 |
|
39 |
$buttons = sprintf(
|
40 |
+
'<a href="%s" class="button button-primary">%s</a>',
|
41 |
$link,
|
42 |
__( 'Activate Lingotek', 'polylang' )
|
43 |
) . $buttons;
|
modules/plugins/featured-content.php
CHANGED
@@ -61,7 +61,7 @@ class PLL_Featured_Content {
|
|
61 |
|
62 |
$settings = Featured_Content::get_setting();
|
63 |
|
64 |
-
if ( ! $term =
|
65 |
return $featured_ids;
|
66 |
}
|
67 |
|
61 |
|
62 |
$settings = Featured_Content::get_setting();
|
63 |
|
64 |
+
if ( ! $term = get_term_by( 'name', $settings['tag-name'], 'post_tag' ) ) {
|
65 |
return $featured_ids;
|
66 |
}
|
67 |
|
modules/plugins/plugins-compat.php
CHANGED
@@ -266,10 +266,18 @@ class PLL_Plugins_Compat {
|
|
266 |
* @since 2.0.10
|
267 |
*/
|
268 |
public function twenty_seventeen_init() {
|
269 |
-
if ( 'twentyseventeen' === get_template() &&
|
270 |
-
|
271 |
-
|
272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
}
|
274 |
}
|
275 |
}
|
266 |
* @since 2.0.10
|
267 |
*/
|
268 |
public function twenty_seventeen_init() {
|
269 |
+
if ( 'twentyseventeen' === get_template() && did_action( 'pll_init' ) ) {
|
270 |
+
if ( function_exists( 'twentyseventeen_panel_count' ) && PLL() instanceof PLL_Frontend ) {
|
271 |
+
$num_sections = twentyseventeen_panel_count();
|
272 |
+
for ( $i = 1; $i < ( 1 + $num_sections ); $i++ ) {
|
273 |
+
add_filter( 'theme_mod_panel_' . $i, 'pll_get_post' );
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
if ( PLL() instanceof PLL_Frontend ) {
|
278 |
+
add_filter( 'theme_mod_external_header_video', 'pll__' );
|
279 |
+
} else {
|
280 |
+
pll_register_string( __( 'Header video', 'polylang' ), get_theme_mod( 'external_header_video' ), 'Twenty Seventeen', false );
|
281 |
}
|
282 |
}
|
283 |
}
|
modules/plugins/wp-import.php
CHANGED
@@ -113,6 +113,8 @@ class PLL_WP_Import extends WP_Import {
|
|
113 |
protected function remap_terms_relations( &$terms ) {
|
114 |
global $wpdb;
|
115 |
|
|
|
|
|
116 |
foreach ( $terms as $term ) {
|
117 |
$translations = maybe_unserialize( $term['term_description'] );
|
118 |
foreach ( $translations as $slug => $old_id ) {
|
@@ -161,6 +163,8 @@ class PLL_WP_Import extends WP_Import {
|
|
161 |
protected function remap_translations( &$terms, &$processed_objects ) {
|
162 |
global $wpdb;
|
163 |
|
|
|
|
|
164 |
foreach ( $terms as $term ) {
|
165 |
$translations = maybe_unserialize( $term['term_description'] );
|
166 |
$new_translations = array();
|
113 |
protected function remap_terms_relations( &$terms ) {
|
114 |
global $wpdb;
|
115 |
|
116 |
+
$trs = array();
|
117 |
+
|
118 |
foreach ( $terms as $term ) {
|
119 |
$translations = maybe_unserialize( $term['term_description'] );
|
120 |
foreach ( $translations as $slug => $old_id ) {
|
163 |
protected function remap_translations( &$terms, &$processed_objects ) {
|
164 |
global $wpdb;
|
165 |
|
166 |
+
$u = array();
|
167 |
+
|
168 |
foreach ( $terms as $term ) {
|
169 |
$translations = maybe_unserialize( $term['term_description'] );
|
170 |
$new_translations = array();
|
modules/sync/admin-sync.php
CHANGED
@@ -189,7 +189,7 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
189 |
|
190 |
if ( is_object( $this->$obj ) && method_exists( $this->$obj, 'copy' ) ) {
|
191 |
if ( WP_DEBUG ) {
|
192 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
193 |
$i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
|
194 |
|
195 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
@@ -205,7 +205,7 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
205 |
return call_user_func_array( array( $this->$obj, 'copy' ), $args );
|
206 |
}
|
207 |
|
208 |
-
$debug = debug_backtrace(); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
209 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
210 |
sprintf(
|
211 |
'Call to undefined function PLL()->sync->%1$s() in %2$s on line %3$s' . "\nError handler",
|
189 |
|
190 |
if ( is_object( $this->$obj ) && method_exists( $this->$obj, 'copy' ) ) {
|
191 |
if ( WP_DEBUG ) {
|
192 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
193 |
$i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
|
194 |
|
195 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
205 |
return call_user_func_array( array( $this->$obj, 'copy' ), $args );
|
206 |
}
|
207 |
|
208 |
+
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
209 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
210 |
sprintf(
|
211 |
'Call to undefined function PLL()->sync->%1$s() in %2$s on line %3$s' . "\nError handler",
|
modules/sync/settings-sync.php
CHANGED
@@ -65,7 +65,7 @@ class PLL_Settings_Sync extends PLL_Settings_Module {
|
|
65 |
* @param array $options
|
66 |
*/
|
67 |
protected function update( $options ) {
|
68 |
-
$newoptions
|
69 |
return $newoptions; // take care to return only validated options
|
70 |
}
|
71 |
|
65 |
* @param array $options
|
66 |
*/
|
67 |
protected function update( $options ) {
|
68 |
+
$newoptions = array( 'sync' => empty( $options['sync'] ) ? array() : array_keys( $options['sync'], 1 ) );
|
69 |
return $newoptions; // take care to return only validated options
|
70 |
}
|
71 |
|
modules/sync/sync-metas.php
CHANGED
@@ -359,8 +359,6 @@ abstract class PLL_Sync_Metas {
|
|
359 |
* @param array $translations The list of translations object ids
|
360 |
*/
|
361 |
public function save_object( $object_id, $obj, $translations ) {
|
362 |
-
$src_lang = array_search( $object_id, $translations );
|
363 |
-
|
364 |
foreach ( $translations as $tr_lang => $tr_id ) {
|
365 |
if ( $tr_id != $object_id ) {
|
366 |
$this->copy( $object_id, $tr_id, $tr_lang, true );
|
359 |
* @param array $translations The list of translations object ids
|
360 |
*/
|
361 |
public function save_object( $object_id, $obj, $translations ) {
|
|
|
|
|
362 |
foreach ( $translations as $tr_lang => $tr_id ) {
|
363 |
if ( $tr_id != $object_id ) {
|
364 |
$this->copy( $object_id, $tr_id, $tr_lang, true );
|
modules/sync/sync.php
CHANGED
@@ -83,7 +83,6 @@ class PLL_Sync {
|
|
83 |
public function can_sync_post_parent( $post_parent, $post_id, $postarr ) {
|
84 |
if ( ! empty( $postarr['ID'] ) && ! $this->model->post->current_user_can_synchronize( $postarr['ID'] ) ) {
|
85 |
$tr_ids = $this->model->post->get_translations( $postarr['ID'] );
|
86 |
-
$orig_lang = array_search( $postarr['ID'], $tr_ids );
|
87 |
foreach ( $tr_ids as $tr_id ) {
|
88 |
if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
|
89 |
$post_parent = $post->post_parent;
|
83 |
public function can_sync_post_parent( $post_parent, $post_id, $postarr ) {
|
84 |
if ( ! empty( $postarr['ID'] ) && ! $this->model->post->current_user_can_synchronize( $postarr['ID'] ) ) {
|
85 |
$tr_ids = $this->model->post->get_translations( $postarr['ID'] );
|
|
|
86 |
foreach ( $tr_ids as $tr_id ) {
|
87 |
if ( $tr_id !== $postarr['ID'] && $post = get_post( $tr_id ) ) {
|
88 |
$post_parent = $post->post_parent;
|
modules/wpml/wpml-api.php
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
* @since 2.0
|
10 |
*/
|
11 |
class PLL_WPML_API {
|
|
|
12 |
|
13 |
/**
|
14 |
* Constructor
|
@@ -29,7 +30,7 @@ class PLL_WPML_API {
|
|
29 |
add_filter( 'wpml_language_is_active', array( $this, 'wpml_language_is_active' ), 10, 2 );
|
30 |
add_filter( 'wpml_is_rtl', array( $this, 'wpml_is_rtl' ) );
|
31 |
// wpml_language_form_input_field => See wpml_add_language_form_field
|
32 |
-
// wpml_language_has_switched =>
|
33 |
// wpml_element_trid => not implemented
|
34 |
// wpml_get_element_translations => not implemented
|
35 |
// wpml_language_switcher => not implemented
|
@@ -42,7 +43,7 @@ class PLL_WPML_API {
|
|
42 |
// Retrieving Language Information for Content
|
43 |
|
44 |
add_filter( 'wpml_post_language_details', 'wpml_get_language_information', 10, 2 );
|
45 |
-
|
46 |
add_filter( 'wpml_element_language_code', array( $this, 'wpml_element_language_code' ), 10, 3 );
|
47 |
// wpml_element_language_details => not applicable
|
48 |
|
@@ -175,6 +176,35 @@ class PLL_WPML_API {
|
|
175 |
return pll_current_language( 'is_rtl' );
|
176 |
}
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
/**
|
179 |
* Get the language code for a translatable element
|
180 |
*
|
@@ -188,7 +218,7 @@ class PLL_WPML_API {
|
|
188 |
$type = $args['element_type'];
|
189 |
$id = $args['element_id'];
|
190 |
$pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
|
191 |
-
if ( 'term' === $pll_type && $term =
|
192 |
$id = $term->term_id;
|
193 |
}
|
194 |
return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code;
|
9 |
* @since 2.0
|
10 |
*/
|
11 |
class PLL_WPML_API {
|
12 |
+
private static $original_language = null;
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
30 |
add_filter( 'wpml_language_is_active', array( $this, 'wpml_language_is_active' ), 10, 2 );
|
31 |
add_filter( 'wpml_is_rtl', array( $this, 'wpml_is_rtl' ) );
|
32 |
// wpml_language_form_input_field => See wpml_add_language_form_field
|
33 |
+
// wpml_language_has_switched => See wpml_switch_language
|
34 |
// wpml_element_trid => not implemented
|
35 |
// wpml_get_element_translations => not implemented
|
36 |
// wpml_language_switcher => not implemented
|
43 |
// Retrieving Language Information for Content
|
44 |
|
45 |
add_filter( 'wpml_post_language_details', 'wpml_get_language_information', 10, 2 );
|
46 |
+
add_action( 'wpml_switch_language', array( __CLASS__, 'wpml_switch_language' ), 10, 2 );
|
47 |
add_filter( 'wpml_element_language_code', array( $this, 'wpml_element_language_code' ), 10, 3 );
|
48 |
// wpml_element_language_details => not applicable
|
49 |
|
176 |
return pll_current_language( 'is_rtl' );
|
177 |
}
|
178 |
|
179 |
+
/**
|
180 |
+
* Switches whole site to the given language or restores the language that was set when first calling this function.
|
181 |
+
* Unlike the WPML original action, it is not possible to set the current language and the cookie to different values.
|
182 |
+
*
|
183 |
+
* @since 2.7
|
184 |
+
*
|
185 |
+
* @param null|string $lang Language code to switch into, restores the original language if null.
|
186 |
+
* @param bool|string $cookie Optionally also switches the cookie.
|
187 |
+
*/
|
188 |
+
public static function wpml_switch_language( $lang = null, $cookie = false ) {
|
189 |
+
if ( null === self::$original_language ) {
|
190 |
+
self::$original_language = PLL()->curlang;
|
191 |
+
}
|
192 |
+
|
193 |
+
if ( empty( $lang ) ) {
|
194 |
+
PLL()->curlang = self::$original_language;
|
195 |
+
} elseif ( 'all' === $lang ) {
|
196 |
+
PLL()->curlang = null;
|
197 |
+
} elseif ( in_array( $lang, pll_languages_list() ) ) {
|
198 |
+
PLL()->curlang = PLL()->model->get_language( $lang );
|
199 |
+
}
|
200 |
+
|
201 |
+
if ( $cookie && isset( PLL()->choose_lang ) ) {
|
202 |
+
PLL()->choose_lang->maybe_setcookie();
|
203 |
+
}
|
204 |
+
|
205 |
+
do_action( 'wpml_language_has_switched', $lang, $cookie, self::$original_language );
|
206 |
+
}
|
207 |
+
|
208 |
/**
|
209 |
* Get the language code for a translatable element
|
210 |
*
|
218 |
$type = $args['element_type'];
|
219 |
$id = $args['element_id'];
|
220 |
$pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
|
221 |
+
if ( 'term' === $pll_type && $term = get_term_by( 'term_taxonomy_id', $id ) ) {
|
222 |
$id = $term->term_id;
|
223 |
}
|
224 |
return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code;
|
modules/wpml/wpml-compat.php
CHANGED
@@ -102,7 +102,8 @@ class PLL_WPML_Compat {
|
|
102 |
// Registers the string if it does not exist yet (multiline as in WPML).
|
103 |
$to_register = array( 'context' => $context, 'name' => $name, 'string' => $string, 'multiline' => true, 'icl' => true );
|
104 |
if ( ! in_array( $to_register, self::$strings ) && $to_register['string'] ) {
|
105 |
-
|
|
|
106 |
update_option( 'polylang_wpml_strings', self::$strings );
|
107 |
}
|
108 |
}
|
@@ -112,15 +113,14 @@ class PLL_WPML_Compat {
|
|
112 |
*
|
113 |
* @since 1.0.2
|
114 |
*
|
115 |
-
* @param string $context
|
116 |
-
* @param string $name
|
117 |
*/
|
118 |
public function unregister_string( $context, $name ) {
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
}
|
124 |
}
|
125 |
}
|
126 |
|
@@ -141,16 +141,12 @@ class PLL_WPML_Compat {
|
|
141 |
*
|
142 |
* @since 2.0
|
143 |
*
|
144 |
-
* @param string $context
|
145 |
-
* @param string $name
|
146 |
-
* @return bool|string
|
147 |
*/
|
148 |
public function get_string_by_context_and_name( $context, $name ) {
|
149 |
-
|
150 |
-
|
151 |
-
return $string['string'];
|
152 |
-
}
|
153 |
-
}
|
154 |
-
return false;
|
155 |
}
|
156 |
}
|
102 |
// Registers the string if it does not exist yet (multiline as in WPML).
|
103 |
$to_register = array( 'context' => $context, 'name' => $name, 'string' => $string, 'multiline' => true, 'icl' => true );
|
104 |
if ( ! in_array( $to_register, self::$strings ) && $to_register['string'] ) {
|
105 |
+
$key = md5( "$context | $name" );
|
106 |
+
self::$strings[ $key ] = $to_register;
|
107 |
update_option( 'polylang_wpml_strings', self::$strings );
|
108 |
}
|
109 |
}
|
113 |
*
|
114 |
* @since 1.0.2
|
115 |
*
|
116 |
+
* @param string $context The group in which the string is registered.
|
117 |
+
* @param string $name A unique name for the string.
|
118 |
*/
|
119 |
public function unregister_string( $context, $name ) {
|
120 |
+
$key = md5( "$context | $name" );
|
121 |
+
if ( isset( self::$strings[ $key ] ) ) {
|
122 |
+
unset( self::$strings[ $key ] );
|
123 |
+
update_option( 'polylang_wpml_strings', self::$strings );
|
|
|
124 |
}
|
125 |
}
|
126 |
|
141 |
*
|
142 |
* @since 2.0
|
143 |
*
|
144 |
+
* @param string $context The group in which the string is registered.
|
145 |
+
* @param string $name A unique name for the string.
|
146 |
+
* @return bool|string The registered string, false if none was found.
|
147 |
*/
|
148 |
public function get_string_by_context_and_name( $context, $name ) {
|
149 |
+
$key = md5( "$context | $name" );
|
150 |
+
return isset( self::$strings[ $key ] ) ? self::$strings[ $key ]['string'] : false;
|
|
|
|
|
|
|
|
|
151 |
}
|
152 |
}
|
modules/wpml/wpml-config.php
CHANGED
@@ -84,7 +84,7 @@ class PLL_WPML_Config {
|
|
84 |
$this->options[ $name ] = $key;
|
85 |
add_filter( 'option_' . $name, array( $this, 'translate_strings' ) );
|
86 |
} else {
|
87 |
-
$this->register_string_recursive( $context, get_option( $name ), $key );
|
88 |
}
|
89 |
}
|
90 |
}
|
@@ -200,47 +200,42 @@ class PLL_WPML_Config {
|
|
200 |
* Recursively registers strings for a serialized option
|
201 |
*
|
202 |
* @since 1.0
|
|
|
203 |
*
|
204 |
-
* @param string $context
|
205 |
-
* @param
|
206 |
-
* @param
|
|
|
207 |
*/
|
208 |
-
protected function register_string_recursive( $context, $
|
209 |
$children = $key->children();
|
210 |
if ( count( $children ) ) {
|
211 |
foreach ( $children as $child ) {
|
212 |
$attributes = $child->attributes();
|
213 |
$name = (string) $attributes['name'];
|
214 |
-
if ( '*' === $name && is_array( $
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
}
|
218 |
-
} elseif ( isset( $
|
219 |
-
$this->register_string_recursive( $context, $
|
220 |
}
|
221 |
}
|
222 |
-
}
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Recursively registers strings with a wildcard
|
230 |
-
*
|
231 |
-
* @since 2.1
|
232 |
-
*
|
233 |
-
* @param string $context the group in which the strings will be registered
|
234 |
-
* @param array $options
|
235 |
-
* @param string $name Option name
|
236 |
-
*/
|
237 |
-
protected function register_wildcard_options_recursive( $context, $options, $name ) {
|
238 |
-
if ( is_array( $options ) ) {
|
239 |
-
foreach ( $options as $n => $option ) {
|
240 |
-
$this->register_wildcard_options_recursive( $context, $option, $n );
|
241 |
}
|
242 |
} else {
|
243 |
-
pll_register_string( $
|
244 |
}
|
245 |
}
|
246 |
|
@@ -249,9 +244,9 @@ class PLL_WPML_Config {
|
|
249 |
*
|
250 |
* @since 1.0
|
251 |
*
|
252 |
-
* @param array|string $values
|
253 |
-
* @param object $key
|
254 |
-
* @return array|string
|
255 |
*/
|
256 |
protected function translate_strings_recursive( $values, $key ) {
|
257 |
$children = $key->children();
|
@@ -260,36 +255,29 @@ class PLL_WPML_Config {
|
|
260 |
$attributes = $child->attributes();
|
261 |
$name = (string) $attributes['name'];
|
262 |
if ( '*' === $name && is_array( $values ) ) {
|
263 |
-
|
264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
}
|
266 |
} elseif ( isset( $values[ $name ] ) ) {
|
267 |
$values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
|
268 |
}
|
269 |
}
|
|
|
|
|
|
|
|
|
|
|
270 |
} else {
|
271 |
$values = pll__( $values );
|
272 |
}
|
273 |
return $values;
|
274 |
}
|
275 |
-
|
276 |
-
/**
|
277 |
-
* Recursively translates strings registered by a wildcard
|
278 |
-
*
|
279 |
-
* @since 2.1
|
280 |
-
*
|
281 |
-
* @param array|string $options Either a string to translate or a list of strings to translate
|
282 |
-
* @param string $name Option name
|
283 |
-
* @return array|string Translated string(s)
|
284 |
-
*/
|
285 |
-
protected function translate_wildcard_options_recursive( $options, $name ) {
|
286 |
-
if ( is_array( $options ) ) {
|
287 |
-
foreach ( $options as $n => $option ) {
|
288 |
-
$options[ $n ] = $this->translate_wildcard_options_recursive( $option, $n );
|
289 |
-
}
|
290 |
-
} else {
|
291 |
-
$options = pll__( $options );
|
292 |
-
}
|
293 |
-
return $options;
|
294 |
-
}
|
295 |
}
|
84 |
$this->options[ $name ] = $key;
|
85 |
add_filter( 'option_' . $name, array( $this, 'translate_strings' ) );
|
86 |
} else {
|
87 |
+
$this->register_string_recursive( $context, $name, get_option( $name ), $key );
|
88 |
}
|
89 |
}
|
90 |
}
|
200 |
* Recursively registers strings for a serialized option
|
201 |
*
|
202 |
* @since 1.0
|
203 |
+
* @since 2.7 Signature modified
|
204 |
*
|
205 |
+
* @param string $context The group in which the strings will be registered.
|
206 |
+
* @param string $option Option name.
|
207 |
+
* @param array $values Option value.
|
208 |
+
* @param object $key XML node.
|
209 |
*/
|
210 |
+
protected function register_string_recursive( $context, $option, $values, $key ) {
|
211 |
$children = $key->children();
|
212 |
if ( count( $children ) ) {
|
213 |
foreach ( $children as $child ) {
|
214 |
$attributes = $child->attributes();
|
215 |
$name = (string) $attributes['name'];
|
216 |
+
if ( '*' === $name && is_array( $values ) ) {
|
217 |
+
// This case could be handled by the next one, but we avoid calls to preg_match here.
|
218 |
+
foreach ( $values as $n => $value ) {
|
219 |
+
$this->register_string_recursive( $context, $n, $value, $child );
|
220 |
+
}
|
221 |
+
} elseif ( false !== strpos( $name, '*' ) ) {
|
222 |
+
$pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
|
223 |
+
foreach ( $values as $n => $value ) {
|
224 |
+
if ( preg_match( $pattern, $n ) ) {
|
225 |
+
$this->register_string_recursive( $context, $n, $value, $child );
|
226 |
+
}
|
227 |
}
|
228 |
+
} elseif ( isset( $values[ $name ] ) ) {
|
229 |
+
$this->register_string_recursive( $context, $name, $values[ $name ], $child );
|
230 |
}
|
231 |
}
|
232 |
+
} elseif ( is_array( $values ) ) {
|
233 |
+
// Parent key is a wildcard and no sub-key has been whitelisted.
|
234 |
+
foreach ( $values as $n => $value ) {
|
235 |
+
$this->register_string_recursive( $context, $n, $value, $key );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
}
|
237 |
} else {
|
238 |
+
pll_register_string( $option, $values, $context, true ); // Multiline as in WPML.
|
239 |
}
|
240 |
}
|
241 |
|
244 |
*
|
245 |
* @since 1.0
|
246 |
*
|
247 |
+
* @param array|string $values Either a string to translate or a list of strings to translate.
|
248 |
+
* @param object $key XML node.
|
249 |
+
* @return array|string Translated string(s)
|
250 |
*/
|
251 |
protected function translate_strings_recursive( $values, $key ) {
|
252 |
$children = $key->children();
|
255 |
$attributes = $child->attributes();
|
256 |
$name = (string) $attributes['name'];
|
257 |
if ( '*' === $name && is_array( $values ) ) {
|
258 |
+
// This case could be handled by the next one, but we avoid calls to preg_match here.
|
259 |
+
foreach ( $values as $n => $value ) {
|
260 |
+
$values[ $n ] = $this->translate_strings_recursive( $value, $child );
|
261 |
+
}
|
262 |
+
} elseif ( false !== strpos( $name, '*' ) ) {
|
263 |
+
$pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
|
264 |
+
foreach ( $values as $n => $value ) {
|
265 |
+
if ( preg_match( $pattern, $n ) ) {
|
266 |
+
$values[ $n ] = $this->translate_strings_recursive( $value, $child );
|
267 |
+
}
|
268 |
}
|
269 |
} elseif ( isset( $values[ $name ] ) ) {
|
270 |
$values[ $name ] = $this->translate_strings_recursive( $values[ $name ], $child );
|
271 |
}
|
272 |
}
|
273 |
+
} elseif ( is_array( $values ) ) {
|
274 |
+
// Parent key is a wildcard and no sub-key has been whitelisted.
|
275 |
+
foreach ( $values as $n => $value ) {
|
276 |
+
$values[ $n ] = $this->translate_strings_recursive( $value, $key );
|
277 |
+
}
|
278 |
} else {
|
279 |
$values = pll__( $values );
|
280 |
}
|
281 |
return $values;
|
282 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
modules/wpml/wpml-legacy-api.php
CHANGED
@@ -128,7 +128,7 @@ if ( ! function_exists( 'icl_link_to_element' ) ) {
|
|
128 |
$text = get_the_title( $id );
|
129 |
}
|
130 |
} elseif ( taxonomy_exists( $type ) ) {
|
131 |
-
$link =
|
132 |
if ( empty( $text ) && ( $term = get_term( $id, $type ) ) && ! empty( $term ) && ! is_wp_error( $term ) ) {
|
133 |
$text = $term->name;
|
134 |
}
|
@@ -174,7 +174,7 @@ if ( ! function_exists( 'icl_object_id' ) ) {
|
|
174 |
if ( 'nav_menu' === $type ) {
|
175 |
$theme = get_option( 'stylesheet' );
|
176 |
if ( isset( PLL()->options['nav_menus'][ $theme ] ) ) {
|
177 |
-
foreach ( PLL()->options['nav_menus'][ $theme ] as $
|
178 |
if ( array_search( $id, $menu ) && ! empty( $menu[ $lang ] ) ) {
|
179 |
$tr_id = $menu[ $lang ];
|
180 |
break;
|
@@ -329,7 +329,7 @@ if ( ! function_exists( 'wpml_get_copied_fields_for_post_edit' ) ) {
|
|
329 |
return array();
|
330 |
}
|
331 |
|
332 |
-
$arr
|
333 |
|
334 |
// Don't know what WPML does but Polylang does copy all public meta keys by default
|
335 |
foreach ( $keys = array_unique( array_keys( get_post_custom( $arr['original_post_id'] ) ) ) as $k => $meta_key ) {
|
128 |
$text = get_the_title( $id );
|
129 |
}
|
130 |
} elseif ( taxonomy_exists( $type ) ) {
|
131 |
+
$link = get_term_link( $id, $type );
|
132 |
if ( empty( $text ) && ( $term = get_term( $id, $type ) ) && ! empty( $term ) && ! is_wp_error( $term ) ) {
|
133 |
$text = $term->name;
|
134 |
}
|
174 |
if ( 'nav_menu' === $type ) {
|
175 |
$theme = get_option( 'stylesheet' );
|
176 |
if ( isset( PLL()->options['nav_menus'][ $theme ] ) ) {
|
177 |
+
foreach ( PLL()->options['nav_menus'][ $theme ] as $menu ) {
|
178 |
if ( array_search( $id, $menu ) && ! empty( $menu[ $lang ] ) ) {
|
179 |
$tr_id = $menu[ $lang ];
|
180 |
break;
|
329 |
return array();
|
330 |
}
|
331 |
|
332 |
+
$arr = array( 'original_post_id' => (int) $_GET['from_post'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
333 |
|
334 |
// Don't know what WPML does but Polylang does copy all public meta keys by default
|
335 |
foreach ( $keys = array_unique( array_keys( get_post_custom( $arr['original_post_id'] ) ) ) as $k => $meta_key ) {
|
polylang.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
Plugin Name: Polylang
|
5 |
Plugin URI: https://polylang.pro
|
6 |
-
Version: 2.
|
7 |
Author: WP SYNTEX
|
8 |
Author uri: https://polylang.pro
|
9 |
Description: Adds multilingual capability to WordPress
|
@@ -51,8 +51,8 @@ if ( defined( 'POLYLANG_BASENAME' ) ) {
|
|
51 |
}
|
52 |
} else {
|
53 |
// Go on loading the plugin
|
54 |
-
define( 'POLYLANG_VERSION', '2.
|
55 |
-
define( 'PLL_MIN_WP_VERSION', '4.
|
56 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
57 |
|
58 |
define( 'POLYLANG_FILE', __FILE__ ); // this file
|
3 |
/**
|
4 |
Plugin Name: Polylang
|
5 |
Plugin URI: https://polylang.pro
|
6 |
+
Version: 2.7
|
7 |
Author: WP SYNTEX
|
8 |
Author uri: https://polylang.pro
|
9 |
Description: Adds multilingual capability to WordPress
|
51 |
}
|
52 |
} else {
|
53 |
// Go on loading the plugin
|
54 |
+
define( 'POLYLANG_VERSION', '2.7' );
|
55 |
+
define( 'PLL_MIN_WP_VERSION', '4.9' );
|
56 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
57 |
|
58 |
define( 'POLYLANG_FILE', __FILE__ ); // this file
|
readme.txt
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
=== Polylang ===
|
2 |
-
Contributors: Chouby, manooweb
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
-
Requires at least: 4.
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 2.
|
9 |
License: GPLv3 or later
|
|
|
10 |
|
11 |
Making WordPress multilingual
|
12 |
|
@@ -42,7 +43,7 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
|
|
42 |
|
43 |
== Installation ==
|
44 |
|
45 |
-
1. Make sure you are using WordPress 4.
|
46 |
1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
|
47 |
1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
|
48 |
1. Go to the languages settings page and create the languages you need
|
@@ -77,6 +78,35 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
|
|
77 |
|
78 |
== Changelog ==
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
= 2.6.10 (2020-02-19) =
|
81 |
|
82 |
* Pro: Fix sticky posts not filtered in REST API (introduced in 2.6.9)
|
1 |
=== Polylang ===
|
2 |
+
Contributors: Chouby, manooweb, raaaahman, marianne38
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
+
Requires at least: 4.9
|
6 |
+
Tested up to: 5.4
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 2.7
|
9 |
License: GPLv3 or later
|
10 |
+
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
12 |
Making WordPress multilingual
|
13 |
|
43 |
|
44 |
== Installation ==
|
45 |
|
46 |
+
1. Make sure you are using WordPress 4.9 or later and that your server is running PHP 5.6 or later (same requirement as WordPress itself)
|
47 |
1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
|
48 |
1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
|
49 |
1. Go to the languages settings page and create the languages you need
|
78 |
|
79 |
== Changelog ==
|
80 |
|
81 |
+
= 2.7 (2020-04-06) =
|
82 |
+
|
83 |
+
* Minimum WordPress version is now 4.9
|
84 |
+
* Pro: Strings translations can now be exported and imported (in PO format)
|
85 |
+
* Pro: Allow to decide individually which ACF fields to copy or synchronize
|
86 |
+
* Pro: Add action pll_inactive_language_requested
|
87 |
+
* Pro; Fix fatal error in The Events Calendar compatibility when no language is defined yet
|
88 |
+
* Pro: Fix bulk translate when a post has no language
|
89 |
+
* Pro: Fix reusable block saved without language
|
90 |
+
* Pro: Fix post requested by slug not filtered in REST API, when the slug is shared
|
91 |
+
* Add a setup wizard
|
92 |
+
* Add Swahili, Upper Sorbian, Sindhi and Spanish from Uruguay to the list of predefined languages
|
93 |
+
* Add flags in the predefined list of languages
|
94 |
+
* Allow to hide the metaboxes from the screen options
|
95 |
+
* The deletion of the plugin's data at uninstall is now controlled by a PHP constant instead of an option #456
|
96 |
+
* Add parent in ajax response when selecting a term in autocomplete field #328
|
97 |
+
* Add Vary: Accept-Language http header in home page redirect. Props @chesio #452
|
98 |
+
* Improve performance to register/unregister WPML strings
|
99 |
+
* Add support for the action wpml_switch_language
|
100 |
+
* Add post_status to the list of accepted args of pll_count_posts()
|
101 |
+
* Apply the filter pll_preferred_language in wp-login.php
|
102 |
+
* Use filtered wrappers to create meta when creating media translations #231
|
103 |
+
* Allow to translate the Twenty Seventeen header video Youtube url #460
|
104 |
+
* Notices are now dismissed per site instead of per user #478
|
105 |
+
* Fix terms not visible in the quick edit when only one language is defined and teh admin language filter is active
|
106 |
+
* Fix post state not displayed for translations of the privacy policy page #395
|
107 |
+
* Fix wildcards not correctly interpreted in wpml-config.xml
|
108 |
+
* Fix product categories with special characters duplicated when importing WooCommerce products #474
|
109 |
+
|
110 |
= 2.6.10 (2020-02-19) =
|
111 |
|
112 |
* Pro: Fix sticky posts not filtered in REST API (introduced in 2.6.9)
|
settings/languages.php
CHANGED
@@ -368,6 +368,14 @@ return array(
|
|
368 |
'flag' => 'pe',
|
369 |
'facebook' => 'es_LA',
|
370 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
'es_VE' => array(
|
372 |
'code' => 'es',
|
373 |
'locale' => 'es_VE',
|
@@ -537,6 +545,13 @@ return array(
|
|
537 |
'flag' => 'hu',
|
538 |
'facebook' => 'hu_HU',
|
539 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
540 |
'hy' => array(
|
541 |
'code' => 'hy',
|
542 |
'locale' => 'hy',
|
@@ -923,6 +938,13 @@ return array(
|
|
923 |
'sna' => array(
|
924 |
'facebook' => 'sn_ZW',
|
925 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
'so_SO' => array(
|
927 |
'code' => 'so',
|
928 |
'locale' => 'so_SO',
|
@@ -967,6 +989,11 @@ return array(
|
|
967 |
'facebook' => 'sv_SE',
|
968 |
),
|
969 |
'sw' => array(
|
|
|
|
|
|
|
|
|
|
|
970 |
'facebook' => 'sw_KE',
|
971 |
),
|
972 |
'syr' => array(
|
368 |
'flag' => 'pe',
|
369 |
'facebook' => 'es_LA',
|
370 |
),
|
371 |
+
'es_UY' => array(
|
372 |
+
'code' => 'es',
|
373 |
+
'locale' => 'es_UY',
|
374 |
+
'name' => 'Español',
|
375 |
+
'dir' => 'ltr',
|
376 |
+
'flag' => 'uy',
|
377 |
+
'facebook' => 'es_LA',
|
378 |
+
),
|
379 |
'es_VE' => array(
|
380 |
'code' => 'es',
|
381 |
'locale' => 'es_VE',
|
545 |
'flag' => 'hu',
|
546 |
'facebook' => 'hu_HU',
|
547 |
),
|
548 |
+
'hsb' => array(
|
549 |
+
'code' => 'hsb',
|
550 |
+
'locale' => 'hsb',
|
551 |
+
'name' => 'Hornjoserbšćina',
|
552 |
+
'dir' => 'ltr',
|
553 |
+
'flag' => 'de',
|
554 |
+
),
|
555 |
'hy' => array(
|
556 |
'code' => 'hy',
|
557 |
'locale' => 'hy',
|
938 |
'sna' => array(
|
939 |
'facebook' => 'sn_ZW',
|
940 |
),
|
941 |
+
'snd' => array(
|
942 |
+
'code' => 'sd',
|
943 |
+
'locale' => 'snd',
|
944 |
+
'name' => 'سنڌي',
|
945 |
+
'dir' => 'rtl',
|
946 |
+
'flag' => 'pk',
|
947 |
+
),
|
948 |
'so_SO' => array(
|
949 |
'code' => 'so',
|
950 |
'locale' => 'so_SO',
|
989 |
'facebook' => 'sv_SE',
|
990 |
),
|
991 |
'sw' => array(
|
992 |
+
'code' => 'sw',
|
993 |
+
'locale' => 'sw',
|
994 |
+
'name' => 'Kiswahili',
|
995 |
+
'dir' => 'ltr',
|
996 |
+
'flag' => 'ke',
|
997 |
'facebook' => 'sw_KE',
|
998 |
),
|
999 |
'syr' => array(
|
settings/settings-cpt.php
CHANGED
@@ -116,6 +116,8 @@ class PLL_Settings_CPT extends PLL_Settings_Module {
|
|
116 |
* @param array $options
|
117 |
*/
|
118 |
protected function update( $options ) {
|
|
|
|
|
119 |
foreach ( array( 'post_types', 'taxonomies' ) as $key ) {
|
120 |
$newoptions[ $key ] = empty( $options[ $key ] ) ? array() : array_keys( $options[ $key ], 1 );
|
121 |
}
|
116 |
* @param array $options
|
117 |
*/
|
118 |
protected function update( $options ) {
|
119 |
+
$newoptions = array();
|
120 |
+
|
121 |
foreach ( array( 'post_types', 'taxonomies' ) as $key ) {
|
122 |
$newoptions[ $key ] = empty( $options[ $key ] ) ? array() : array_keys( $options[ $key ], 1 );
|
123 |
}
|
settings/settings-licenses.php
CHANGED
@@ -70,109 +70,7 @@ class PLL_Settings_Licenses extends PLL_Settings_Module {
|
|
70 |
* @return string
|
71 |
*/
|
72 |
protected function get_row( $item ) {
|
73 |
-
|
74 |
-
$license = $item->license_data;
|
75 |
-
}
|
76 |
-
|
77 |
-
$class = 'license-null';
|
78 |
-
|
79 |
-
$out = sprintf(
|
80 |
-
'<td><label for="pll-licenses[%1$s]">%2$s</label></td>' .
|
81 |
-
'<td><input name="licenses[%1$s]" id="pll-licenses[%1$s]" type="text" value="%3$s" class="regular-text code" />',
|
82 |
-
esc_attr( $item->id ),
|
83 |
-
esc_attr( $item->name ),
|
84 |
-
esc_html( $item->license_key )
|
85 |
-
);
|
86 |
-
|
87 |
-
if ( ! empty( $license ) && is_object( $license ) ) {
|
88 |
-
$now = current_time( 'timestamp' );
|
89 |
-
$expiration = strtotime( $license->expires, $now );
|
90 |
-
|
91 |
-
// Special case: the license expired after the last check
|
92 |
-
if ( $license->success && $expiration < $now ) {
|
93 |
-
$license->success = false;
|
94 |
-
$license->error = 'expired';
|
95 |
-
}
|
96 |
-
|
97 |
-
if ( false === $license->success ) {
|
98 |
-
$class = 'notice-error notice-alt';
|
99 |
-
|
100 |
-
switch ( $license->error ) {
|
101 |
-
case 'expired':
|
102 |
-
$message = sprintf(
|
103 |
-
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
104 |
-
__( 'Your license key expired on %1$s. Please %2$srenew your license key%3$s.', 'polylang' ),
|
105 |
-
date_i18n( get_option( 'date_format' ), strtotime( $license->expires, current_time( 'timestamp' ) ) ),
|
106 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/checkout/?edd_license_key=' . $item->license_key ),
|
107 |
-
'</a>'
|
108 |
-
);
|
109 |
-
break;
|
110 |
-
|
111 |
-
case 'missing':
|
112 |
-
$message = sprintf(
|
113 |
-
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
114 |
-
__( 'Invalid license. Please %1$svisit your account page%2$s and verify it.', 'polylang' ),
|
115 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
116 |
-
'</a>'
|
117 |
-
);
|
118 |
-
break;
|
119 |
-
|
120 |
-
case 'invalid':
|
121 |
-
case 'site_inactive':
|
122 |
-
$message = sprintf(
|
123 |
-
/* translators: %1$s is a product name, %2$s is link start tag, %3$s is link end tag. */
|
124 |
-
__( 'Your %1$s license key is not active for this URL. Please %2$svisit your account page%3$s to manage your license key URLs.', 'polylang' ),
|
125 |
-
$item->name,
|
126 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
127 |
-
'</a>'
|
128 |
-
);
|
129 |
-
break;
|
130 |
-
|
131 |
-
case 'item_name_mismatch':
|
132 |
-
/* translators: %s is a product name */
|
133 |
-
$message = sprintf( __( 'This is not a %s license key.', 'polylang' ), $item->name );
|
134 |
-
break;
|
135 |
-
|
136 |
-
case 'no_activations_left':
|
137 |
-
$message = sprintf(
|
138 |
-
/* translators: %1$s is link start tag, %2$s is link end tag */
|
139 |
-
__( 'Your license key has reached its activation limit. %1$sView possible upgrades%2$s now.', 'polylang' ),
|
140 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
141 |
-
'</a>'
|
142 |
-
);
|
143 |
-
break;
|
144 |
-
}
|
145 |
-
} else {
|
146 |
-
$class = 'license-valid';
|
147 |
-
|
148 |
-
$out .= sprintf( '<button id="deactivate_%s" type="button" class="button button-secondary pll-deactivate-license">%s</button>', $item->id, __( 'Deactivate', 'polylang' ) );
|
149 |
-
|
150 |
-
if ( 'lifetime' === $license->expires ) {
|
151 |
-
$message = __( 'The license key never expires.', 'polylang' );
|
152 |
-
} elseif ( $expiration > $now && $expiration - $now < ( DAY_IN_SECONDS * 30 ) ) {
|
153 |
-
$class = 'notice-warning notice-alt';
|
154 |
-
$message = sprintf(
|
155 |
-
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
156 |
-
__( 'Your license key will expire soon! Precisely, it will expire on %1$s. %2$sRenew your license key today!%3$s.', 'polylang' ),
|
157 |
-
date_i18n( get_option( 'date_format' ), strtotime( $license->expires, $now ) ),
|
158 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/checkout/?edd_license_key=' . $item->license_key ),
|
159 |
-
'</a>'
|
160 |
-
);
|
161 |
-
} else {
|
162 |
-
$message = sprintf(
|
163 |
-
/* translators: %s is a date */
|
164 |
-
__( 'Your license key expires on %s.', 'polylang' ),
|
165 |
-
date_i18n( get_option( 'date_format' ), strtotime( $license->expires, $now ) )
|
166 |
-
);
|
167 |
-
}
|
168 |
-
}
|
169 |
-
}
|
170 |
-
|
171 |
-
if ( ! empty( $message ) ) {
|
172 |
-
$out .= '<p>' . $message . '</p>';
|
173 |
-
}
|
174 |
-
|
175 |
-
return sprintf( '<tr id="pll-license-%s" class="%s">%s</tr>', $item->id, $class, $out );
|
176 |
}
|
177 |
|
178 |
/**
|
70 |
* @return string
|
71 |
*/
|
72 |
protected function get_row( $item ) {
|
73 |
+
return $item->get_form_field();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
/**
|
settings/settings-module.php
CHANGED
@@ -194,6 +194,8 @@ class PLL_Settings_Module {
|
|
194 |
* @return array
|
195 |
*/
|
196 |
protected function get_actions() {
|
|
|
|
|
197 |
if ( $this->is_active() && $this->get_form() ) {
|
198 |
$actions[] = 'configure';
|
199 |
}
|
194 |
* @return array
|
195 |
*/
|
196 |
protected function get_actions() {
|
197 |
+
$actions = array();
|
198 |
+
|
199 |
if ( $this->is_active() && $this->get_form() ) {
|
200 |
$actions[] = 'configure';
|
201 |
}
|
settings/settings-tools.php
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Settings class for tools
|
5 |
-
*
|
6 |
-
* @since 1.8
|
7 |
-
*/
|
8 |
-
class PLL_Settings_Tools extends PLL_Settings_Module {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Constructor
|
12 |
-
*
|
13 |
-
* @since 1.8
|
14 |
-
*
|
15 |
-
* @param object $polylang polylang object
|
16 |
-
*/
|
17 |
-
public function __construct( &$polylang ) {
|
18 |
-
parent::__construct(
|
19 |
-
$polylang,
|
20 |
-
array(
|
21 |
-
'module' => 'tools',
|
22 |
-
'title' => __( 'Tools', 'polylang' ),
|
23 |
-
'description' => __( 'Decide whether to remove all data when deleting Polylang.', 'polylang' ),
|
24 |
-
)
|
25 |
-
);
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Displays the settings form
|
30 |
-
*
|
31 |
-
* @since 1.8
|
32 |
-
*/
|
33 |
-
protected function form() {
|
34 |
-
printf(
|
35 |
-
'<label for="uninstall"><input id="uninstall" name="uninstall" type="checkbox" value="1" %s /> %s</label>',
|
36 |
-
checked( empty( $this->options['uninstall'] ), false, false ),
|
37 |
-
esc_html__( 'Remove all Polylang data upon using the "Delete" action in the "Plugins" admin page.', 'polylang' )
|
38 |
-
);
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Sanitizes the settings before saving
|
43 |
-
*
|
44 |
-
* @since 1.8
|
45 |
-
*
|
46 |
-
* @param array $options
|
47 |
-
*/
|
48 |
-
protected function update( $options ) {
|
49 |
-
$newoptions['uninstall'] = isset( $options['uninstall'] ) ? 1 : 0;
|
50 |
-
return $newoptions; // Take care to return only validated options
|
51 |
-
}
|
52 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
settings/settings-url.php
CHANGED
@@ -223,6 +223,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
223 |
* @param array $options
|
224 |
*/
|
225 |
protected function update( $options ) {
|
|
|
|
|
226 |
foreach ( array( 'force_lang', 'rewrite' ) as $key ) {
|
227 |
$newoptions[ $key ] = isset( $options[ $key ] ) ? (int) $options[ $key ] : 0;
|
228 |
}
|
223 |
* @param array $options
|
224 |
*/
|
225 |
protected function update( $options ) {
|
226 |
+
$newoptions = array();
|
227 |
+
|
228 |
foreach ( array( 'force_lang', 'rewrite' ) as $key ) {
|
229 |
$newoptions[ $key ] = isset( $options[ $key ] ) ? (int) $options[ $key ] : 0;
|
230 |
}
|
settings/settings.php
CHANGED
@@ -17,7 +17,27 @@
|
|
17 |
* @since 1.2
|
18 |
*/
|
19 |
class PLL_Settings extends PLL_Admin_Base {
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
/**
|
23 |
* Constructor
|
@@ -35,6 +55,10 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
35 |
|
36 |
PLL_Admin_Strings::init();
|
37 |
|
|
|
|
|
|
|
|
|
38 |
// FIXME put this as late as possible
|
39 |
add_action( 'admin_init', array( $this, 'register_settings_modules' ) );
|
40 |
|
@@ -53,7 +77,6 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
53 |
*/
|
54 |
public function register_settings_modules() {
|
55 |
$modules = array(
|
56 |
-
'PLL_Settings_Tools',
|
57 |
'PLL_Settings_Licenses',
|
58 |
);
|
59 |
|
@@ -108,7 +131,7 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
108 |
'pll-about-box',
|
109 |
__( 'About Polylang', 'polylang' ),
|
110 |
array( $this, 'metabox_about' ),
|
111 |
-
'
|
112 |
'normal'
|
113 |
);
|
114 |
}
|
@@ -298,7 +321,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
298 |
// Handle user input
|
299 |
$action = isset( $_REQUEST['pll_action'] ) ? sanitize_key( $_REQUEST['pll_action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
300 |
if ( 'edit' === $action && ! empty( $_GET['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
301 |
-
|
|
|
302 |
} else {
|
303 |
$this->handle_actions( $action );
|
304 |
}
|
@@ -360,7 +384,7 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
360 |
*
|
361 |
* @since 2.3
|
362 |
*/
|
363 |
-
public function get_predefined_languages() {
|
364 |
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
365 |
|
366 |
$languages = include PLL_SETTINGS_INC . '/languages.php';
|
17 |
* @since 1.2
|
18 |
*/
|
19 |
class PLL_Settings extends PLL_Admin_Base {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Name of the active module
|
23 |
+
*
|
24 |
+
* @var string $active_tab
|
25 |
+
*/
|
26 |
+
protected $active_tab;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Array of modules classes
|
30 |
+
*
|
31 |
+
* @var array $modules
|
32 |
+
*/
|
33 |
+
protected $modules;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Reference to PLL_Import_Export
|
37 |
+
*
|
38 |
+
* @var PLL_Import_Export $import_export
|
39 |
+
*/
|
40 |
+
protected $import_export;
|
41 |
|
42 |
/**
|
43 |
* Constructor
|
55 |
|
56 |
PLL_Admin_Strings::init();
|
57 |
|
58 |
+
if ( class_exists( 'PLL_Import_Export' ) ) {
|
59 |
+
$this->import_export = new PLL_Import_Export( $this );
|
60 |
+
}
|
61 |
+
|
62 |
// FIXME put this as late as possible
|
63 |
add_action( 'admin_init', array( $this, 'register_settings_modules' ) );
|
64 |
|
77 |
*/
|
78 |
public function register_settings_modules() {
|
79 |
$modules = array(
|
|
|
80 |
'PLL_Settings_Licenses',
|
81 |
);
|
82 |
|
131 |
'pll-about-box',
|
132 |
__( 'About Polylang', 'polylang' ),
|
133 |
array( $this, 'metabox_about' ),
|
134 |
+
'toplevel_page_mlang',
|
135 |
'normal'
|
136 |
);
|
137 |
}
|
321 |
// Handle user input
|
322 |
$action = isset( $_REQUEST['pll_action'] ) ? sanitize_key( $_REQUEST['pll_action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
323 |
if ( 'edit' === $action && ! empty( $_GET['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
324 |
+
// phpcs:ignore WordPress.Security.NonceVerification, WordPressVIPMinimum.Variables.VariableAnalysis.UnusedVariable
|
325 |
+
$edit_lang = $this->model->get_language( (int) $_GET['lang'] );
|
326 |
} else {
|
327 |
$this->handle_actions( $action );
|
328 |
}
|
384 |
*
|
385 |
* @since 2.3
|
386 |
*/
|
387 |
+
public static function get_predefined_languages() {
|
388 |
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
389 |
|
390 |
$languages = include PLL_SETTINGS_INC . '/languages.php';
|
settings/table-languages.php
CHANGED
@@ -128,7 +128,6 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
128 |
/* translators: accessibility text */
|
129 |
esc_html__( 'Default language', 'polylang' )
|
130 |
);
|
131 |
-
$actions = array();
|
132 |
}
|
133 |
|
134 |
return $s;
|
128 |
/* translators: accessibility text */
|
129 |
esc_html__( 'Default language', 'polylang' )
|
130 |
);
|
|
|
131 |
}
|
132 |
|
133 |
return $s;
|
settings/table-settings.php
CHANGED
@@ -92,24 +92,21 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
92 |
* @param object $item The current item
|
93 |
*/
|
94 |
protected function single_row_columns( $item ) {
|
95 |
-
|
|
|
|
|
96 |
|
97 |
-
foreach ( $columns as $column_name
|
98 |
$classes = "$column_name column-$column_name";
|
99 |
if ( $primary === $column_name ) {
|
100 |
$classes .= ' column-primary';
|
101 |
}
|
102 |
|
103 |
-
if ( in_array( $column_name, $hidden ) ) {
|
104 |
-
$classes .= ' hidden';
|
105 |
-
}
|
106 |
-
|
107 |
if ( 'cb' == $column_name ) {
|
108 |
echo '<th scope="row" class="check-column">';
|
109 |
echo $this->column_cb( $item ); // phpcs:ignore WordPress.Security.EscapeOutput
|
110 |
echo '</th>';
|
111 |
-
}
|
112 |
-
else {
|
113 |
printf( '<td class="%s">', esc_attr( $classes ) );
|
114 |
echo $this->column_default( $item, $column_name ); // phpcs:ignore WordPress.Security.EscapeOutput
|
115 |
echo '</td>';
|
92 |
* @param object $item The current item
|
93 |
*/
|
94 |
protected function single_row_columns( $item ) {
|
95 |
+
$column_info = $this->get_column_info();
|
96 |
+
$columns = $column_info[0];
|
97 |
+
$primary = $column_info[3];
|
98 |
|
99 |
+
foreach ( array_keys( $columns ) as $column_name ) {
|
100 |
$classes = "$column_name column-$column_name";
|
101 |
if ( $primary === $column_name ) {
|
102 |
$classes .= ' column-primary';
|
103 |
}
|
104 |
|
|
|
|
|
|
|
|
|
105 |
if ( 'cb' == $column_name ) {
|
106 |
echo '<th scope="row" class="check-column">';
|
107 |
echo $this->column_cb( $item ); // phpcs:ignore WordPress.Security.EscapeOutput
|
108 |
echo '</th>';
|
109 |
+
} else {
|
|
|
110 |
printf( '<td class="%s">', esc_attr( $classes ) );
|
111 |
echo $this->column_default( $item, $column_name ); // phpcs:ignore WordPress.Security.EscapeOutput
|
112 |
echo '</td>';
|
settings/table-string.php
CHANGED
@@ -216,6 +216,7 @@ class PLL_Table_String extends WP_List_Table {
|
|
216 |
}
|
217 |
|
218 |
// Load translations
|
|
|
219 |
foreach ( $languages as $language ) {
|
220 |
$mo[ $language->slug ] = new PLL_MO();
|
221 |
$mo[ $language->slug ]->import_from_db( $language );
|
@@ -350,16 +351,18 @@ class PLL_Table_String extends WP_List_Table {
|
|
350 |
$mo = new PLL_MO();
|
351 |
$mo->import_from_db( $language );
|
352 |
|
353 |
-
|
|
|
354 |
/**
|
355 |
* Filter the string translation before it is saved in DB
|
356 |
* Allows to sanitize strings registered with pll_register_string
|
357 |
*
|
358 |
* @since 1.6
|
|
|
359 |
*
|
360 |
-
* @param string $translation
|
361 |
-
* @param string $name
|
362 |
-
* @param string $context
|
363 |
*/
|
364 |
$translation = apply_filters( 'pll_sanitize_string_translation', $translation, $this->strings[ $key ]['name'], $this->strings[ $key ]['context'] );
|
365 |
$mo->add_entry( $mo->make_entry( $this->strings[ $key ]['string'], $translation ) );
|
216 |
}
|
217 |
|
218 |
// Load translations
|
219 |
+
$mo = array();
|
220 |
foreach ( $languages as $language ) {
|
221 |
$mo[ $language->slug ] = new PLL_MO();
|
222 |
$mo[ $language->slug ]->import_from_db( $language );
|
351 |
$mo = new PLL_MO();
|
352 |
$mo->import_from_db( $language );
|
353 |
|
354 |
+
$translations = array_map( 'trim', wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
355 |
+
foreach ( $translations as $key => $translation ) {
|
356 |
/**
|
357 |
* Filter the string translation before it is saved in DB
|
358 |
* Allows to sanitize strings registered with pll_register_string
|
359 |
*
|
360 |
* @since 1.6
|
361 |
+
* @since 2.7 The translation passed to the filter is unslashed.
|
362 |
*
|
363 |
+
* @param string $translation The string translation.
|
364 |
+
* @param string $name The name as defined in pll_register_string.
|
365 |
+
* @param string $context The context as defined in pll_register_string.
|
366 |
*/
|
367 |
$translation = apply_filters( 'pll_sanitize_string_translation', $translation, $this->strings[ $key ]['name'], $this->strings[ $key ]['context'] );
|
368 |
$mo->add_entry( $mo->make_entry( $this->strings[ $key ]['string'], $translation ) );
|
settings/view-languages.php
CHANGED
@@ -18,7 +18,7 @@ require ABSPATH . 'wp-admin/options-head.php'; // Displays the errors messages a
|
|
18 |
case 'strings': // String translations tab
|
19 |
case 'settings': // Settings tab
|
20 |
include PLL_SETTINGS_INC . '/view-tab-' . $this->active_tab . '.php';
|
21 |
-
|
22 |
|
23 |
default:
|
24 |
/**
|
18 |
case 'strings': // String translations tab
|
19 |
case 'settings': // Settings tab
|
20 |
include PLL_SETTINGS_INC . '/view-tab-' . $this->active_tab . '.php';
|
21 |
+
// Intentional fall-through to upgrade to fire the action below.
|
22 |
|
23 |
default:
|
24 |
/**
|
settings/view-tab-lang.php
CHANGED
@@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
<div class="metabox-holder">
|
19 |
<?php
|
20 |
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
21 |
-
do_meta_boxes( '
|
22 |
?>
|
23 |
</div>
|
24 |
</div><!-- col-wrap -->
|
@@ -54,13 +54,17 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
54 |
<option value=""></option>
|
55 |
<?php
|
56 |
foreach ( $this->get_predefined_languages() as $lg ) {
|
|
|
|
|
|
|
57 |
printf(
|
58 |
-
'<option value="%1$s:%2$s:%3$s:%4$s">%5$s - %2$s</option>' . "\n",
|
59 |
esc_attr( $lg['code'] ),
|
60 |
esc_attr( $lg['locale'] ),
|
61 |
'rtl' == $lg['dir'] ? '1' : '0',
|
62 |
esc_attr( $lg['flag'] ),
|
63 |
-
esc_html( $lg['name'] )
|
|
|
64 |
);
|
65 |
}
|
66 |
?>
|
@@ -125,15 +129,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
125 |
<?php
|
126 |
$flags = include PLL_SETTINGS_INC . '/flags.php';
|
127 |
foreach ( $flags as $code => $label ) {
|
128 |
-
/** This filter is documented in include/language.php */
|
129 |
-
$flag = apply_filters( 'pll_flag', array( 'url' => plugins_url( "/flags/{$code}.png", POLYLANG_FILE ) ), $code );
|
130 |
-
|
131 |
printf(
|
132 |
-
'<option value="%s" data-
|
133 |
esc_attr( $code ),
|
134 |
-
|
135 |
-
( empty( $flag['width'] ) ? '' : sprintf( ' data-width="%s"', (int) $flag['width'] ) ),
|
136 |
-
( empty( $flag['height'] ) ? '' : sprintf( ' data-height="%s"', (int) $flag['height'] ) ),
|
137 |
selected( isset( $edit_lang->flag_code ) && $edit_lang->flag_code === $code, true, false ),
|
138 |
esc_html( $label )
|
139 |
);
|
@@ -179,14 +178,3 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
179 |
</div><!-- col-wrap -->
|
180 |
</div><!-- col-left -->
|
181 |
</div><!-- col-container -->
|
182 |
-
|
183 |
-
<script type="text/javascript">
|
184 |
-
//<![CDATA[
|
185 |
-
jQuery( document ).ready( function( $ ) {
|
186 |
-
// close postboxes that should be closed
|
187 |
-
$( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
|
188 |
-
// postboxes setup
|
189 |
-
postboxes.add_postbox_toggles( 'settings_page_mlang' );
|
190 |
-
} );
|
191 |
-
//]]>
|
192 |
-
</script>
|
18 |
<div class="metabox-holder">
|
19 |
<?php
|
20 |
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
21 |
+
do_meta_boxes( 'toplevel_page_mlang', 'normal', array() );
|
22 |
?>
|
23 |
</div>
|
24 |
</div><!-- col-wrap -->
|
54 |
<option value=""></option>
|
55 |
<?php
|
56 |
foreach ( $this->get_predefined_languages() as $lg ) {
|
57 |
+
$lg['flag_code'] = $lg['flag'];
|
58 |
+
$language = new PLL_Language( $lg );
|
59 |
+
$language->set_flag();
|
60 |
printf(
|
61 |
+
'<option value="%1$s:%2$s:%3$s:%4$s" data-flag-html="%6$s">%5$s - %2$s</option>' . "\n",
|
62 |
esc_attr( $lg['code'] ),
|
63 |
esc_attr( $lg['locale'] ),
|
64 |
'rtl' == $lg['dir'] ? '1' : '0',
|
65 |
esc_attr( $lg['flag'] ),
|
66 |
+
esc_html( $lg['name'] ),
|
67 |
+
esc_html( $language->flag )
|
68 |
);
|
69 |
}
|
70 |
?>
|
129 |
<?php
|
130 |
$flags = include PLL_SETTINGS_INC . '/flags.php';
|
131 |
foreach ( $flags as $code => $label ) {
|
|
|
|
|
|
|
132 |
printf(
|
133 |
+
'<option value="%s" data-flag-html="%s"%s>%s</option>' . "\n",
|
134 |
esc_attr( $code ),
|
135 |
+
esc_html( PLL_Language::get_flag_html( PLL_Language::get_flag_informations( $code ) ) ),
|
|
|
|
|
136 |
selected( isset( $edit_lang->flag_code ) && $edit_lang->flag_code === $code, true, false ),
|
137 |
esc_html( $label )
|
138 |
);
|
178 |
</div><!-- col-wrap -->
|
179 |
</div><!-- col-left -->
|
180 |
</div><!-- col-container -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
settings/view-tab-strings.php
CHANGED
@@ -22,4 +22,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
22 |
submit_button(); // Since WP 3.1
|
23 |
?>
|
24 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
</div>
|
22 |
submit_button(); // Since WP 3.1
|
23 |
?>
|
24 |
</form>
|
25 |
+
<div class="metabox-holder">
|
26 |
+
<?php
|
27 |
+
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
28 |
+
do_meta_boxes( 'languages_page_mlang_strings', 'bottom', array() );
|
29 |
+
?>
|
30 |
+
</div>
|
31 |
+
|
32 |
</div>
|
uninstall.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { // If uninstall not called from WordPress exit
|
4 |
-
exit
|
5 |
}
|
6 |
|
7 |
/**
|
@@ -20,6 +20,11 @@ class PLL_Uninstall {
|
|
20 |
public function __construct() {
|
21 |
global $wpdb;
|
22 |
|
|
|
|
|
|
|
|
|
|
|
23 |
// Check if it is a multisite uninstall - if so, run the uninstall function for each blog id
|
24 |
if ( is_multisite() ) {
|
25 |
foreach ( $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ) as $blog_id ) {
|
@@ -40,12 +45,6 @@ class PLL_Uninstall {
|
|
40 |
* @since 0.5
|
41 |
*/
|
42 |
public function uninstall() {
|
43 |
-
$options = get_option( 'polylang' );
|
44 |
-
|
45 |
-
if ( empty( $options['uninstall'] ) ) {
|
46 |
-
return;
|
47 |
-
}
|
48 |
-
|
49 |
global $wpdb;
|
50 |
|
51 |
// Executes each module's uninstall script, if it exists
|
@@ -55,7 +54,7 @@ class PLL_Uninstall {
|
|
55 |
if ( substr( $module, 0, 1 ) !== '.' ) {
|
56 |
$uninstall_script = $pll_modules_dir . '/' . $module . '/uninstall.php';
|
57 |
if ( file_exists( $uninstall_script ) ) {
|
58 |
-
require $uninstall_script;
|
59 |
}
|
60 |
}
|
61 |
}
|
@@ -84,6 +83,7 @@ class PLL_Uninstall {
|
|
84 |
// Delete users options
|
85 |
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
|
86 |
delete_user_meta( $user_id, 'pll_filter_content' );
|
|
|
87 |
foreach ( $languages as $lang ) {
|
88 |
delete_user_meta( $user_id, 'description_' . $lang->slug );
|
89 |
}
|
@@ -126,6 +126,9 @@ class PLL_Uninstall {
|
|
126 |
}
|
127 |
|
128 |
// Delete all what is related to languages and translations
|
|
|
|
|
|
|
129 |
foreach ( get_terms( $pll_taxonomies, array( 'hide_empty' => false ) ) as $term ) {
|
130 |
$term_ids[] = (int) $term->term_id;
|
131 |
$tt_ids[] = (int) $term->term_taxonomy_id;
|
@@ -147,6 +150,7 @@ class PLL_Uninstall {
|
|
147 |
delete_option( 'widget_polylang' ); // Automatically created by WP
|
148 |
delete_option( 'polylang_wpml_strings' ); // Strings registered with icl_register_string
|
149 |
delete_option( 'polylang_licenses' );
|
|
|
150 |
|
151 |
// Delete transients
|
152 |
delete_transient( 'pll_languages_list' );
|
1 |
<?php
|
2 |
|
3 |
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { // If uninstall not called from WordPress exit
|
4 |
+
exit;
|
5 |
}
|
6 |
|
7 |
/**
|
20 |
public function __construct() {
|
21 |
global $wpdb;
|
22 |
|
23 |
+
// Don't do anything except if the constant PLL_REMOVE_ALL_DATA is explicitely defined and true.
|
24 |
+
if ( ! defined( 'PLL_REMOVE_ALL_DATA' ) || ! PLL_REMOVE_ALL_DATA ) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
|
28 |
// Check if it is a multisite uninstall - if so, run the uninstall function for each blog id
|
29 |
if ( is_multisite() ) {
|
30 |
foreach ( $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" ) as $blog_id ) {
|
45 |
* @since 0.5
|
46 |
*/
|
47 |
public function uninstall() {
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
global $wpdb;
|
49 |
|
50 |
// Executes each module's uninstall script, if it exists
|
54 |
if ( substr( $module, 0, 1 ) !== '.' ) {
|
55 |
$uninstall_script = $pll_modules_dir . '/' . $module . '/uninstall.php';
|
56 |
if ( file_exists( $uninstall_script ) ) {
|
57 |
+
require $uninstall_script; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
|
58 |
}
|
59 |
}
|
60 |
}
|
83 |
// Delete users options
|
84 |
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
|
85 |
delete_user_meta( $user_id, 'pll_filter_content' );
|
86 |
+
delete_user_meta( $user_id, 'pll_dismissed_notices' ); // Legacy meta.
|
87 |
foreach ( $languages as $lang ) {
|
88 |
delete_user_meta( $user_id, 'description_' . $lang->slug );
|
89 |
}
|
126 |
}
|
127 |
|
128 |
// Delete all what is related to languages and translations
|
129 |
+
$term_ids = array();
|
130 |
+
$tt_ids = array();
|
131 |
+
|
132 |
foreach ( get_terms( $pll_taxonomies, array( 'hide_empty' => false ) ) as $term ) {
|
133 |
$term_ids[] = (int) $term->term_id;
|
134 |
$tt_ids[] = (int) $term->term_taxonomy_id;
|
150 |
delete_option( 'widget_polylang' ); // Automatically created by WP
|
151 |
delete_option( 'polylang_wpml_strings' ); // Strings registered with icl_register_string
|
152 |
delete_option( 'polylang_licenses' );
|
153 |
+
delete_option( 'pll_dismissed_notices' );
|
154 |
|
155 |
// Delete transients
|
156 |
delete_transient( 'pll_languages_list' );
|