Version Description
(2021-03-08) =
- Add compatibility with WordPress 5.7
- Remove upgrades from Polylang older than 1.8
- Remove deprecated class PLL_Pointer
- Pro: Hide the license keys
- Pro: Fix redirect to the home page of a deactivated language
- Pro: Fix synchronization of post status not working
- Pro: Fix language switcher block not working in a post retrieved in REST API
- Pro: Fix PO export of strings with line breaks
- Pro: Fix file block title customization lost
- Add a dialog box to ask a confirmation about a language change in classic and block editors
- Improve browser language detection #591
- Improve robustness and documentation of code
- Fix media library after the language has been chnaged in the editor metabox
- Fix duplicated title attribute on flag link in posts list
- Fix legacy block editor language metabox compatibility with WordPress 5.6
- Fix uploaded theme and plugin files in media library
- Fix site title not translated in email change confirmation email
- Fix remaining deprecated jQuery notices #741
- Fix compatibility with GN publisher
- Fix compatibility with Woodmart theme search form
- Fix compatibility issue with 3rd party ajax requests since jQuery 3.3 #744
- Fix CSS conflict with WooCommerce Bookings
- Fix browser error when displaying an embed and using a cache plugin #757
- Fix post type archive title and metadesc not translated in Yoast SEO
- Fix PHP notice in REST API
Download this release
Release Info
Developer | Chouby |
Plugin | Polylang |
Version | 3.0 |
Comparing to | |
See all releases |
Code changes from version 2.9.2 to 3.0
- admin/admin-base.php +97 -35
- admin/admin-block-editor.php +17 -7
- admin/admin-classic-editor.php +99 -59
- admin/admin-filters-columns.php +60 -26
- admin/admin-filters-media.php +9 -4
- admin/admin-filters-post-base.php +22 -7
- admin/admin-filters-post.php +48 -9
- admin/admin-filters-term.php +106 -42
- admin/admin-filters-widgets-options.php +55 -0
- admin/admin-filters.php +10 -97
- admin/admin-links.php +42 -42
- admin/admin-model.php +103 -89
- admin/admin-nav-menu.php +13 -5
- admin/admin-notices.php +30 -2
- admin/admin-static-pages.php +20 -74
- admin/admin-strings.php +21 -8
- admin/admin.php +32 -50
- css/admin.css +0 -5
- css/admin.min.css +0 -1
- css/build/admin.css +457 -0
- css/build/admin.min.css +1 -0
- css/build/dialog.css +82 -0
- css/build/dialog.min.css +1 -0
- css/build/selectmenu.css +231 -0
- css/build/selectmenu.min.css +1 -0
- css/build/wizard.css +951 -0
- css/build/wizard.min.css +1 -0
- css/dialog.css +82 -0
- css/selectmenu.css +29 -9
- css/selectmenu.min.css +0 -1
- frontend/accept-language.php +112 -0
- frontend/accept-languages-collection.php +149 -0
- frontend/choose-lang-content.php +19 -12
- frontend/choose-lang-domain.php +6 -0
- frontend/choose-lang-url.php +12 -1
- frontend/choose-lang.php +72 -83
- frontend/frontend-auto-translate.php +14 -3
- frontend/frontend-filters-links.php +70 -45
- frontend/frontend-filters-search.php +24 -7
- frontend/frontend-filters.php +10 -6
- frontend/frontend-links.php +22 -11
- frontend/frontend-nav-menu.php +25 -18
- frontend/frontend-static-pages.php +36 -21
- frontend/frontend.php +71 -33
- include/api.php +127 -107
- include/base.php +30 -55
- include/cache.php +16 -1
- include/class-polylang.php +9 -2
- include/cookie.php +1 -0
- include/crud-posts.php +51 -24
- include/crud-terms.php +68 -30
- include/filters-links.php +49 -19
- include/filters-widgets-options.php +105 -0
- include/filters.php +63 -35
- include/functions.php +2 -2
- include/language.php +262 -112
- include/license.php +65 -9
- include/links-abstract-domain.php +5 -5
- include/links-default.php +13 -8
- include/links-directory.php +26 -17
- include/links-domain.php +15 -8
- include/links-model.php +115 -29
- include/links-permalinks.php +43 -9
- include/links-subdomain.php +15 -9
- include/links.php +22 -4
- include/mo.php +18 -11
- include/model.php +133 -169
- include/nav-menu.php +42 -16
- include/olt-manager.php +44 -32
- include/pointer.php +0 -116
- include/query.php +47 -11
- include/rest-request.php +37 -17
- include/static-pages.php +39 -5
- include/switcher.php +113 -62
- include/translate-option.php +24 -19
- include/translated-object.php +158 -79
- include/translated-post.php +33 -21
- include/translated-term.php +31 -22
- include/walker-dropdown.php +21 -12
- include/walker-list.php +21 -12
- include/widget-languages.php +6 -2
- install/install-base.php +13 -0
- install/install.php +11 -1
- install/t15s.php +5 -0
- install/upgrade.php +42 -488
- integrations/cache/cache-compat.php +8 -3
- integrations/custom-field-template/cft.php +2 -2
- integrations/wp-importer/wp-import.php +5 -0
- integrations/wp-offload-media/as3cf.php +5 -0
- integrations/wpseo/wpseo.php +3 -2
- js/admin.js +8 -2
- js/admin.min.js +0 -1
- js/block-editor.js +148 -99
- js/block-editor.min.js +0 -1
- js/build/admin.js +416 -0
- js/build/admin.min.js +1 -0
- js/build/block-editor.js +350 -0
- js/build/block-editor.min.js +1 -0
- js/build/classic-editor.js +436 -0
- js/build/classic-editor.min.js +1 -0
- js/build/languages-step.js +303 -0
- js/build/languages-step.min.js +1 -0
- js/build/nav-menu.js +105 -0
- js/build/nav-menu.min.js +1 -0
- js/build/post.js +178 -0
- js/build/post.min.js +1 -0
- js/build/term.js +222 -0
- js/build/term.min.js +1 -0
- js/build/user.js +34 -0
- js/build/user.min.js +1 -0
- js/build/widgets.js +133 -0
- js/build/widgets.min.js +1 -0
- js/classic-editor.js +196 -71
- js/classic-editor.min.js +0 -1
- js/lib/confirmation-modal.js +95 -0
- js/nav-menu.js +4 -3
- js/nav-menu.min.js +0 -1
- js/post.js +2 -1
- js/post.min.js +0 -1
- js/term.js +2 -1
- js/term.min.js +0 -1
- js/user.js +1 -1
- js/user.min.js +0 -1
- js/widgets.min.js +0 -1
- modules/lingotek/lingotek.php +7 -0
- modules/share-slug/settings-share-slug.php +2 -0
- modules/site-health/admin-site-health.php +3 -3
- modules/sitemaps/abstract-sitemaps.php +37 -0
- modules/sitemaps/load.php +5 -1
- modules/sitemaps/multilingual-sitemaps-provider.php +6 -3
- modules/sitemaps/sitemaps-domain.php +71 -0
- modules/sitemaps/sitemaps.php +14 -65
- modules/sync/admin-sync.php +31 -23
- modules/sync/settings-sync.php +4 -4
- modules/sync/sync-metas.php +57 -20
- modules/sync/sync-post-metas.php +11 -6
- modules/sync/sync-tax.php +47 -27
- modules/sync/sync.php +58 -23
- modules/wizard/css/wizard.css +2 -1
- modules/wizard/css/wizard.min.css +0 -1
- modules/wizard/js/languages-step.min.js +0 -1
- modules/wizard/wizard.php +115 -49
- modules/wpml/wpml-api.php +13 -2
- modules/wpml/wpml-compat.php +22 -3
- modules/wpml/wpml-config.php +83 -52
- modules/wpml/wpml-legacy-api.php +6 -4
- polylang.php +2 -2
- readme.txt +30 -2
- settings/settings-browser.php +2 -0
- settings/settings-cpt.php +4 -4
- settings/settings-licenses.php +6 -4
- settings/settings-module.php +14 -8
- settings/settings-url.php +19 -1
- settings/settings.php +40 -21
- settings/table-languages.php +23 -21
- settings/table-settings.php +15 -11
- settings/table-string.php +44 -13
- settings/view-tab-lang.php +1 -1
- uninstall.php +1 -20
- vendor/autoload.php +1 -1
- vendor/composer/autoload_classmap.php +6 -1
- vendor/composer/autoload_real.php +4 -4
- vendor/composer/autoload_static.php +8 -3
admin/admin-base.php
CHANGED
@@ -4,20 +4,58 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
*
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
-
class PLL_Admin_Base extends PLL_Base {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
*
|
18 |
* @since 1.8
|
19 |
*
|
20 |
-
* @param
|
21 |
*/
|
22 |
public function __construct( &$links_model ) {
|
23 |
parent::__construct( $links_model );
|
@@ -64,6 +102,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
64 |
* Adds the link to the languages panel in the WordPress admin menu
|
65 |
*
|
66 |
* @since 0.1
|
|
|
|
|
67 |
*/
|
68 |
public function add_menus() {
|
69 |
global $admin_page_hooks;
|
@@ -93,7 +133,7 @@ class PLL_Admin_Base extends PLL_Base {
|
|
93 |
$page = 'lang' === $tab ? 'mlang' : "mlang_$tab";
|
94 |
if ( empty( $parent ) ) {
|
95 |
$parent = $page;
|
96 |
-
add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page,
|
97 |
$admin_page_hooks[ $page ] = 'languages'; // Hack to avoid the localization of the hook name. See: https://core.trac.wordpress.org/ticket/18857
|
98 |
}
|
99 |
|
@@ -105,6 +145,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
105 |
* Setup js scripts & css styles ( only on the relevant pages )
|
106 |
*
|
107 |
* @since 0.6
|
|
|
|
|
108 |
*/
|
109 |
public function admin_enqueue_scripts() {
|
110 |
$screen = get_current_screen();
|
@@ -131,12 +173,12 @@ class PLL_Admin_Base extends PLL_Base {
|
|
131 |
|
132 |
// Classic editor.
|
133 |
if ( ! method_exists( $screen, 'is_block_editor' ) || ! $screen->is_block_editor() ) {
|
134 |
-
$scripts['classic-editor'] = array( array( 'post', 'media', 'async-upload' ), array( 'jquery', 'wp-ajax-response', 'post' ), 0, 1 );
|
135 |
}
|
136 |
|
137 |
// Block editor with legacy metabox in WP 5.0+.
|
138 |
if ( method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() && ! pll_use_block_editor_plugin() ) {
|
139 |
-
$scripts['block-editor'] = array( array( 'post' ), array( 'jquery', 'wp-ajax-response', 'wp-api-fetch' ), 0, 1 );
|
140 |
}
|
141 |
}
|
142 |
|
@@ -146,11 +188,12 @@ class PLL_Admin_Base extends PLL_Base {
|
|
146 |
|
147 |
foreach ( $scripts as $script => $v ) {
|
148 |
if ( in_array( $screen->base, $v[0] ) && ( $v[2] || $this->model->get_languages_list() ) ) {
|
149 |
-
wp_enqueue_script( 'pll_' . $script, plugins_url( '/js/' . $script . $suffix . '.js',
|
150 |
}
|
151 |
}
|
152 |
|
153 |
-
|
|
|
154 |
|
155 |
$this->localize_scripts();
|
156 |
}
|
@@ -159,11 +202,13 @@ class PLL_Admin_Base extends PLL_Base {
|
|
159 |
* Enqueue scripts to the WP Customizer.
|
160 |
*
|
161 |
* @since 2.4.0
|
|
|
|
|
162 |
*/
|
163 |
public function customize_controls_enqueue_scripts() {
|
164 |
if ( $this->model->get_languages_list() ) {
|
165 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
166 |
-
wp_enqueue_script( 'pll_widgets', plugins_url( '/js/widgets' . $suffix . '.js',
|
167 |
$this->localize_scripts();
|
168 |
}
|
169 |
}
|
@@ -172,6 +217,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
172 |
* Localize scripts.
|
173 |
*
|
174 |
* @since 2.4.0
|
|
|
|
|
175 |
*/
|
176 |
public function localize_scripts() {
|
177 |
if ( wp_script_is( 'pll_widgets', 'enqueued' ) ) {
|
@@ -198,6 +245,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
198 |
* see: https://wordpress.org/support/topic/invalid-url-during-wordpress-new-dashboard-widget-operation
|
199 |
*
|
200 |
* @since 1.4
|
|
|
|
|
201 |
*/
|
202 |
public function admin_print_footer_scripts() {
|
203 |
global $post_ID, $tag_ID;
|
@@ -217,27 +266,35 @@ class PLL_Admin_Base extends PLL_Base {
|
|
217 |
<script type="text/javascript">
|
218 |
if (typeof jQuery != 'undefined') {
|
219 |
jQuery(
|
220 |
-
function($){
|
221 |
-
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
|
222 |
if ( -1 != options.url.indexOf( ajaxurl ) || -1 != ajaxurl.indexOf( options.url ) ) {
|
223 |
-
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
} else {
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
o = $.extend(o, <?php echo $arr; // phpcs:ignore WordPress.Security.EscapeOutput ?>);
|
233 |
-
options.data = JSON.stringify(o);
|
234 |
-
}
|
235 |
-
catch(e) {
|
236 |
-
options.data = '<?php echo $str; // phpcs:ignore WordPress.Security.EscapeOutput ?>&'+options.data;
|
237 |
-
}
|
238 |
-
}
|
239 |
} else {
|
240 |
-
|
|
|
241 |
}
|
242 |
}
|
243 |
}
|
@@ -253,6 +310,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
253 |
* Sets the admin current language, used to filter the content
|
254 |
*
|
255 |
* @since 2.0
|
|
|
|
|
256 |
*/
|
257 |
public function set_current_language() {
|
258 |
$this->curlang = $this->filter_lang;
|
@@ -298,6 +357,8 @@ class PLL_Admin_Base extends PLL_Base {
|
|
298 |
* Defines the backend language and the admin language filter based on user preferences
|
299 |
*
|
300 |
* @since 1.2.3
|
|
|
|
|
301 |
*/
|
302 |
public function init_user() {
|
303 |
// Language for admin language filter: may be empty
|
@@ -313,12 +374,12 @@ class PLL_Admin_Base extends PLL_Base {
|
|
313 |
$this->pref_lang = empty( $this->filter_lang ) ? $this->model->get_language( $this->options['default_lang'] ) : $this->filter_lang;
|
314 |
|
315 |
/**
|
316 |
-
*
|
317 |
-
* The preferred language is used for example to determine the language of a new post
|
318 |
*
|
319 |
* @since 1.2.3
|
320 |
*
|
321 |
-
* @param
|
322 |
*/
|
323 |
$this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang );
|
324 |
|
@@ -348,11 +409,12 @@ class PLL_Admin_Base extends PLL_Base {
|
|
348 |
}
|
349 |
|
350 |
/**
|
351 |
-
* Adds the languages list in admin bar for the admin languages filter
|
352 |
*
|
353 |
* @since 0.9
|
354 |
*
|
355 |
-
* @param
|
|
|
356 |
*/
|
357 |
public function admin_bar_menu( $wp_admin_bar ) {
|
358 |
$all_item = (object) array(
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Setup features available on all admin pages.
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
+
abstract class PLL_Admin_Base extends PLL_Base {
|
12 |
+
/**
|
13 |
+
* Current language (used to filter the content).
|
14 |
+
*
|
15 |
+
* @var PLL_Language
|
16 |
+
*/
|
17 |
+
public $curlang;
|
18 |
|
19 |
/**
|
20 |
+
* Language selected in the admin language filter.
|
21 |
+
*
|
22 |
+
* @var PLL_Language
|
23 |
+
*/
|
24 |
+
public $filter_lang;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Preferred language to assign to new contents.
|
28 |
+
*
|
29 |
+
* @var PLL_Language
|
30 |
+
*/
|
31 |
+
public $pref_lang;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var PLL_Filters_Links
|
35 |
+
*/
|
36 |
+
public $filters_links;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var PLL_Admin_Links
|
40 |
+
*/
|
41 |
+
public $links;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var PLL_Admin_Notices
|
45 |
+
*/
|
46 |
+
public $notices;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var PLL_Admin_Static_Pages
|
50 |
+
*/
|
51 |
+
public $static_pages;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Setups actions needed on all admin pages.
|
55 |
*
|
56 |
* @since 1.8
|
57 |
*
|
58 |
+
* @param PLL_Links_Model $links_model Reference to the links model.
|
59 |
*/
|
60 |
public function __construct( &$links_model ) {
|
61 |
parent::__construct( $links_model );
|
102 |
* Adds the link to the languages panel in the WordPress admin menu
|
103 |
*
|
104 |
* @since 0.1
|
105 |
+
*
|
106 |
+
* @return void
|
107 |
*/
|
108 |
public function add_menus() {
|
109 |
global $admin_page_hooks;
|
133 |
$page = 'lang' === $tab ? 'mlang' : "mlang_$tab";
|
134 |
if ( empty( $parent ) ) {
|
135 |
$parent = $page;
|
136 |
+
add_menu_page( $title, __( 'Languages', 'polylang' ), 'manage_options', $page, '__return_null', 'dashicons-translation' );
|
137 |
$admin_page_hooks[ $page ] = 'languages'; // Hack to avoid the localization of the hook name. See: https://core.trac.wordpress.org/ticket/18857
|
138 |
}
|
139 |
|
145 |
* Setup js scripts & css styles ( only on the relevant pages )
|
146 |
*
|
147 |
* @since 0.6
|
148 |
+
*
|
149 |
+
* @return void
|
150 |
*/
|
151 |
public function admin_enqueue_scripts() {
|
152 |
$screen = get_current_screen();
|
173 |
|
174 |
// Classic editor.
|
175 |
if ( ! method_exists( $screen, 'is_block_editor' ) || ! $screen->is_block_editor() ) {
|
176 |
+
$scripts['classic-editor'] = array( array( 'post', 'media', 'async-upload' ), array( 'jquery', 'wp-ajax-response', 'post', 'jquery-ui-dialog' ), 0, 1 );
|
177 |
}
|
178 |
|
179 |
// Block editor with legacy metabox in WP 5.0+.
|
180 |
if ( method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() && ! pll_use_block_editor_plugin() ) {
|
181 |
+
$scripts['block-editor'] = array( array( 'post' ), array( 'jquery', 'wp-ajax-response', 'wp-api-fetch', 'jquery-ui-dialog' ), 0, 1 );
|
182 |
}
|
183 |
}
|
184 |
|
188 |
|
189 |
foreach ( $scripts as $script => $v ) {
|
190 |
if ( in_array( $screen->base, $v[0] ) && ( $v[2] || $this->model->get_languages_list() ) ) {
|
191 |
+
wp_enqueue_script( 'pll_' . $script, plugins_url( '/js/build/' . $script . $suffix . '.js', POLYLANG_BASENAME ), $v[1], POLYLANG_VERSION, $v[3] );
|
192 |
}
|
193 |
}
|
194 |
|
195 |
+
wp_register_style( 'polylang_admin', plugins_url( '/css/build/admin' . $suffix . '.css', POLYLANG_BASENAME ), array( 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
|
196 |
+
wp_enqueue_style( 'polylang_dialog', plugins_url( '/css/build/dialog' . $suffix . '.css', POLYLANG_BASENAME ), array( 'polylang_admin' ), POLYLANG_VERSION );
|
197 |
|
198 |
$this->localize_scripts();
|
199 |
}
|
202 |
* Enqueue scripts to the WP Customizer.
|
203 |
*
|
204 |
* @since 2.4.0
|
205 |
+
*
|
206 |
+
* @return void
|
207 |
*/
|
208 |
public function customize_controls_enqueue_scripts() {
|
209 |
if ( $this->model->get_languages_list() ) {
|
210 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
211 |
+
wp_enqueue_script( 'pll_widgets', plugins_url( '/js/build/widgets' . $suffix . '.js', POLYLANG_BASENAME ), array( 'jquery' ), POLYLANG_VERSION, true );
|
212 |
$this->localize_scripts();
|
213 |
}
|
214 |
}
|
217 |
* Localize scripts.
|
218 |
*
|
219 |
* @since 2.4.0
|
220 |
+
*
|
221 |
+
* @return void
|
222 |
*/
|
223 |
public function localize_scripts() {
|
224 |
if ( wp_script_is( 'pll_widgets', 'enqueued' ) ) {
|
245 |
* see: https://wordpress.org/support/topic/invalid-url-during-wordpress-new-dashboard-widget-operation
|
246 |
*
|
247 |
* @since 1.4
|
248 |
+
*
|
249 |
+
* @return void
|
250 |
*/
|
251 |
public function admin_print_footer_scripts() {
|
252 |
global $post_ID, $tag_ID;
|
266 |
<script type="text/javascript">
|
267 |
if (typeof jQuery != 'undefined') {
|
268 |
jQuery(
|
269 |
+
function( $ ){
|
270 |
+
$.ajaxPrefilter( function ( options, originalOptions, jqXHR ) {
|
271 |
if ( -1 != options.url.indexOf( ajaxurl ) || -1 != ajaxurl.indexOf( options.url ) ) {
|
272 |
+
|
273 |
+
function addStringParameters() {
|
274 |
+
if ( 'undefined' === typeof options.data || '' === options.data ) {
|
275 |
+
options.data = '<?php echo $str; // phpcs:ignore WordPress.Security.EscapeOutput ?>';
|
276 |
+
} else {
|
277 |
+
options.data = options.data + '&<?php echo $str; // phpcs:ignore WordPress.Security.EscapeOutput ?>';
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
/*
|
282 |
+
* options.processData set to true is the default jQuery process where the data is converted in a query string by using jQuery.param().
|
283 |
+
* This step is done before applying filters. Thus here the options.data is already a string in this case.
|
284 |
+
* @See https://github.com/jquery/jquery/blob/3.5.1/src/ajax.js#L563-L569 jQuery ajax function.
|
285 |
+
*/
|
286 |
+
if ( options.processData ) {
|
287 |
+
addStringParameters();
|
288 |
} else {
|
289 |
+
/*
|
290 |
+
* If options.processData is set to false data could be undefined or pass as a string.
|
291 |
+
* So data as to be processed as if options.processData is set to true.
|
292 |
+
*/
|
293 |
+
if ( 'undefined' === typeof options.data || 'string' === typeof options.data ) {
|
294 |
+
addStringParameters();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
} else {
|
296 |
+
// Otherwise options.data is probably an object.
|
297 |
+
options.data = Object.assign( options.data, <?php echo $arr; // phpcs:ignore WordPress.Security.EscapeOutput ?> );
|
298 |
}
|
299 |
}
|
300 |
}
|
310 |
* Sets the admin current language, used to filter the content
|
311 |
*
|
312 |
* @since 2.0
|
313 |
+
*
|
314 |
+
* @return void
|
315 |
*/
|
316 |
public function set_current_language() {
|
317 |
$this->curlang = $this->filter_lang;
|
357 |
* Defines the backend language and the admin language filter based on user preferences
|
358 |
*
|
359 |
* @since 1.2.3
|
360 |
+
*
|
361 |
+
* @return void
|
362 |
*/
|
363 |
public function init_user() {
|
364 |
// Language for admin language filter: may be empty
|
374 |
$this->pref_lang = empty( $this->filter_lang ) ? $this->model->get_language( $this->options['default_lang'] ) : $this->filter_lang;
|
375 |
|
376 |
/**
|
377 |
+
* Filters the preferred language on admin side.
|
378 |
+
* The preferred language is used for example to determine the language of a new post.
|
379 |
*
|
380 |
* @since 1.2.3
|
381 |
*
|
382 |
+
* @param PLL_Language $pref_lang Preferred language.
|
383 |
*/
|
384 |
$this->pref_lang = apply_filters( 'pll_admin_preferred_language', $this->pref_lang );
|
385 |
|
409 |
}
|
410 |
|
411 |
/**
|
412 |
+
* Adds the languages list in admin bar for the admin languages filter.
|
413 |
*
|
414 |
* @since 0.9
|
415 |
*
|
416 |
+
* @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar global object.
|
417 |
+
* @return void
|
418 |
*/
|
419 |
public function admin_bar_menu( $wp_admin_bar ) {
|
420 |
$all_item = (object) array(
|
admin/admin-block-editor.php
CHANGED
@@ -9,7 +9,17 @@
|
|
9 |
* @since 2.5
|
10 |
*/
|
11 |
class PLL_Admin_Block_Editor {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor: setups filters and actions
|
@@ -26,15 +36,15 @@ class PLL_Admin_Block_Editor {
|
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
-
*
|
30 |
-
* Necessary otherwise subsequent REST requests all filtered by the language
|
31 |
-
* would not hit the preloaded requests
|
32 |
*
|
33 |
* @since 2.5
|
34 |
*
|
35 |
-
* @param
|
36 |
-
* @param
|
37 |
-
* @return
|
38 |
*/
|
39 |
public function preload_paths( $preload_paths, $post ) {
|
40 |
if ( $this->model->is_translated_post_type( $post->post_type ) ) {
|
9 |
* @since 2.5
|
10 |
*/
|
11 |
class PLL_Admin_Block_Editor {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
+
protected $model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Preferred language to assign to a new post.
|
19 |
+
*
|
20 |
+
* @var PLL_Language
|
21 |
+
*/
|
22 |
+
protected $pref_lang;
|
23 |
|
24 |
/**
|
25 |
* Constructor: setups filters and actions
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
+
* Filters the preload REST requests by the current language of the post.
|
40 |
+
* Necessary otherwise subsequent REST requests, all filtered by the language,
|
41 |
+
* would not hit the preloaded requests.
|
42 |
*
|
43 |
* @since 2.5
|
44 |
*
|
45 |
+
* @param (string|string[])[] $preload_paths Array of paths to preload.
|
46 |
+
* @param WP_Post $post The post resource data.
|
47 |
+
* @return (string|string[])[]
|
48 |
*/
|
49 |
public function preload_paths( $preload_paths, $post ) {
|
50 |
if ( $this->model->is_translated_post_type( $post->post_type ) ) {
|
admin/admin-classic-editor.php
CHANGED
@@ -9,7 +9,29 @@
|
|
9 |
* @since 2.4
|
10 |
*/
|
11 |
class PLL_Admin_Classic_Editor {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor: setups filters and actions
|
@@ -44,6 +66,7 @@ class PLL_Admin_Classic_Editor {
|
|
44 |
* @since 0.1
|
45 |
*
|
46 |
* @param string $post_type Current post type
|
|
|
47 |
*/
|
48 |
public function add_meta_boxes( $post_type ) {
|
49 |
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
@@ -65,6 +88,8 @@ class PLL_Admin_Classic_Editor {
|
|
65 |
* Displays the Languages metabox in the 'Edit Post' and 'Edit Page' panels
|
66 |
*
|
67 |
* @since 0.1
|
|
|
|
|
68 |
*/
|
69 |
public function post_language() {
|
70 |
global $post_ID;
|
@@ -127,6 +152,8 @@ class PLL_Admin_Classic_Editor {
|
|
127 |
* Ajax response for changing the language in the post metabox
|
128 |
*
|
129 |
* @since 0.2
|
|
|
|
|
130 |
*/
|
131 |
public function post_lang_choice() {
|
132 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
@@ -140,11 +167,16 @@ class PLL_Admin_Classic_Editor {
|
|
140 |
$lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
|
141 |
$post_type = sanitize_key( $_POST['post_type'] );
|
142 |
|
143 |
-
if ( ! post_type_exists( $post_type ) ) {
|
144 |
wp_die( 0 );
|
145 |
}
|
146 |
|
147 |
$post_type_object = get_post_type_object( $post_type );
|
|
|
|
|
|
|
|
|
|
|
148 |
if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
|
149 |
wp_die( -1 );
|
150 |
}
|
@@ -157,12 +189,10 @@ class PLL_Admin_Classic_Editor {
|
|
157 |
$this->model->post->save_translations( $post_ID, $translations );
|
158 |
|
159 |
ob_start();
|
160 |
-
if ( $
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
include __DIR__ . '/view-translations-post.php';
|
165 |
-
}
|
166 |
}
|
167 |
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
168 |
ob_end_clean();
|
@@ -174,30 +204,32 @@ class PLL_Admin_Classic_Editor {
|
|
174 |
foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
|
175 |
$taxonomy = get_taxonomy( $taxname );
|
176 |
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
|
|
201 |
}
|
202 |
}
|
203 |
|
@@ -205,21 +237,23 @@ class PLL_Admin_Classic_Editor {
|
|
205 |
if ( in_array( $post_type, get_post_types( array( 'hierarchical' => true ) ) ) ) {
|
206 |
$post = get_post( $post_ID );
|
207 |
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
218 |
|
219 |
-
|
220 |
-
|
221 |
|
222 |
-
|
|
|
223 |
}
|
224 |
|
225 |
// Flag
|
@@ -235,6 +269,8 @@ class PLL_Admin_Classic_Editor {
|
|
235 |
* Ajax response for input in translation autocomplete input box
|
236 |
*
|
237 |
* @since 1.5
|
|
|
|
|
238 |
*/
|
239 |
public function ajax_posts_not_translated() {
|
240 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
@@ -270,27 +306,30 @@ class PLL_Admin_Classic_Editor {
|
|
270 |
// Add current translation in list
|
271 |
if ( $post_id = $this->model->post->get_translation( (int) $_GET['pll_post_id'], $translation_language ) ) {
|
272 |
$post = get_post( $post_id );
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
|
|
|
|
|
|
281 |
}
|
282 |
|
283 |
wp_die( wp_json_encode( $return ) );
|
284 |
}
|
285 |
|
286 |
/**
|
287 |
-
* Filters the pages by language in the parent dropdown list in the page attributes metabox
|
288 |
*
|
289 |
* @since 0.6
|
290 |
*
|
291 |
-
* @param array
|
292 |
-
* @param
|
293 |
-
* @return array Modified arguments
|
294 |
*/
|
295 |
public function page_attributes_dropdown_pages_args( $dropdown_args, $post ) {
|
296 |
$dropdown_args['lang'] = isset( $_POST['lang'] ) ? $this->model->get_language( sanitize_key( $_POST['lang'] ) ) : $this->model->post->get_language( $post->ID ); // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -302,11 +341,12 @@ class PLL_Admin_Classic_Editor {
|
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
-
* Displays a notice if the user has not sufficient rights to overwrite synchronized taxonomies and metas
|
306 |
*
|
307 |
* @since 2.6
|
308 |
*
|
309 |
-
* @param
|
|
|
310 |
*/
|
311 |
public function edit_form_top( $post ) {
|
312 |
if ( ! $this->model->post->current_user_can_synchronize( $post->ID ) ) {
|
9 |
* @since 2.4
|
10 |
*/
|
11 |
class PLL_Admin_Classic_Editor {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
+
public $model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var PLL_Admin_Links
|
19 |
+
*/
|
20 |
+
public $links;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Current language (used to filter the content).
|
24 |
+
*
|
25 |
+
* @var PLL_Language
|
26 |
+
*/
|
27 |
+
public $curlang;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Preferred language to assign to new contents.
|
31 |
+
*
|
32 |
+
* @var PLL_Language
|
33 |
+
*/
|
34 |
+
public $pref_lang;
|
35 |
|
36 |
/**
|
37 |
* Constructor: setups filters and actions
|
66 |
* @since 0.1
|
67 |
*
|
68 |
* @param string $post_type Current post type
|
69 |
+
* @return void
|
70 |
*/
|
71 |
public function add_meta_boxes( $post_type ) {
|
72 |
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
88 |
* Displays the Languages metabox in the 'Edit Post' and 'Edit Page' panels
|
89 |
*
|
90 |
* @since 0.1
|
91 |
+
*
|
92 |
+
* @return void
|
93 |
*/
|
94 |
public function post_language() {
|
95 |
global $post_ID;
|
152 |
* Ajax response for changing the language in the post metabox
|
153 |
*
|
154 |
* @since 0.2
|
155 |
+
*
|
156 |
+
* @return void
|
157 |
*/
|
158 |
public function post_lang_choice() {
|
159 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
167 |
$lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
|
168 |
$post_type = sanitize_key( $_POST['post_type'] );
|
169 |
|
170 |
+
if ( empty( $lang ) || ! post_type_exists( $post_type ) ) {
|
171 |
wp_die( 0 );
|
172 |
}
|
173 |
|
174 |
$post_type_object = get_post_type_object( $post_type );
|
175 |
+
|
176 |
+
if ( empty( $post_type_object ) ) {
|
177 |
+
wp_die( 0 );
|
178 |
+
}
|
179 |
+
|
180 |
if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
|
181 |
wp_die( -1 );
|
182 |
}
|
189 |
$this->model->post->save_translations( $post_ID, $translations );
|
190 |
|
191 |
ob_start();
|
192 |
+
if ( 'attachment' === $post_type ) {
|
193 |
+
include __DIR__ . '/view-translations-media.php';
|
194 |
+
} else {
|
195 |
+
include __DIR__ . '/view-translations-post.php';
|
|
|
|
|
196 |
}
|
197 |
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
198 |
ob_end_clean();
|
204 |
foreach ( array_map( 'sanitize_key', $_POST['taxonomies'] ) as $taxname ) {
|
205 |
$taxonomy = get_taxonomy( $taxname );
|
206 |
|
207 |
+
if ( ! empty( $taxonomy ) ) {
|
208 |
+
ob_start();
|
209 |
+
$popular_ids = wp_popular_terms_checklist( $taxonomy->name );
|
210 |
+
$supplemental['populars'] = ob_get_contents();
|
211 |
+
ob_end_clean();
|
212 |
+
|
213 |
+
ob_start();
|
214 |
+
// Use $post_ID to remember checked terms in case we come back to the original language
|
215 |
+
wp_terms_checklist( $post_ID, array( 'taxonomy' => $taxonomy->name, 'popular_cats' => $popular_ids ) );
|
216 |
+
$supplemental['all'] = ob_get_contents();
|
217 |
+
ob_end_clean();
|
218 |
+
|
219 |
+
$supplemental['dropdown'] = wp_dropdown_categories(
|
220 |
+
array(
|
221 |
+
'taxonomy' => $taxonomy->name,
|
222 |
+
'hide_empty' => 0,
|
223 |
+
'name' => 'new' . $taxonomy->name . '_parent',
|
224 |
+
'orderby' => 'name',
|
225 |
+
'hierarchical' => 1,
|
226 |
+
'show_option_none' => '— ' . $taxonomy->labels->parent_item . ' —',
|
227 |
+
'echo' => 0,
|
228 |
+
)
|
229 |
+
);
|
230 |
+
|
231 |
+
$x->Add( array( 'what' => 'taxonomy', 'data' => $taxonomy->name, 'supplemental' => $supplemental ) );
|
232 |
+
}
|
233 |
}
|
234 |
}
|
235 |
|
237 |
if ( in_array( $post_type, get_post_types( array( 'hierarchical' => true ) ) ) ) {
|
238 |
$post = get_post( $post_ID );
|
239 |
|
240 |
+
if ( ! empty( $post ) ) {
|
241 |
+
// Args and filter from 'page_attributes_meta_box' in wp-admin/includes/meta-boxes.php of WP 4.2.1
|
242 |
+
$dropdown_args = array(
|
243 |
+
'post_type' => $post->post_type,
|
244 |
+
'exclude_tree' => $post->ID,
|
245 |
+
'selected' => $post->post_parent,
|
246 |
+
'name' => 'parent_id',
|
247 |
+
'show_option_none' => __( '(no parent)', 'polylang' ),
|
248 |
+
'sort_column' => 'menu_order, post_title',
|
249 |
+
'echo' => 0,
|
250 |
+
);
|
251 |
|
252 |
+
/** This filter is documented in wp-admin/includes/meta-boxes.php */
|
253 |
+
$dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post ); // Since WP 3.3
|
254 |
|
255 |
+
$x->Add( array( 'what' => 'pages', 'data' => wp_dropdown_pages( $dropdown_args ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput
|
256 |
+
}
|
257 |
}
|
258 |
|
259 |
// Flag
|
269 |
* Ajax response for input in translation autocomplete input box
|
270 |
*
|
271 |
* @since 1.5
|
272 |
+
*
|
273 |
+
* @return void
|
274 |
*/
|
275 |
public function ajax_posts_not_translated() {
|
276 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
306 |
// Add current translation in list
|
307 |
if ( $post_id = $this->model->post->get_translation( (int) $_GET['pll_post_id'], $translation_language ) ) {
|
308 |
$post = get_post( $post_id );
|
309 |
+
|
310 |
+
if ( ! empty( $post ) ) {
|
311 |
+
array_unshift(
|
312 |
+
$return,
|
313 |
+
array(
|
314 |
+
'id' => $post_id,
|
315 |
+
'value' => $post->post_title,
|
316 |
+
'link' => $this->links->edit_post_translation_link( $post_id ),
|
317 |
+
)
|
318 |
+
);
|
319 |
+
}
|
320 |
}
|
321 |
|
322 |
wp_die( wp_json_encode( $return ) );
|
323 |
}
|
324 |
|
325 |
/**
|
326 |
+
* Filters the pages by language in the parent dropdown list in the page attributes metabox.
|
327 |
*
|
328 |
* @since 0.6
|
329 |
*
|
330 |
+
* @param array $dropdown_args Arguments passed to wp_dropdown_pages().
|
331 |
+
* @param WP_Post $post The page being edited.
|
332 |
+
* @return array Modified arguments.
|
333 |
*/
|
334 |
public function page_attributes_dropdown_pages_args( $dropdown_args, $post ) {
|
335 |
$dropdown_args['lang'] = isset( $_POST['lang'] ) ? $this->model->get_language( sanitize_key( $_POST['lang'] ) ) : $this->model->post->get_language( $post->ID ); // phpcs:ignore WordPress.Security.NonceVerification
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
+
* Displays a notice if the user has not sufficient rights to overwrite synchronized taxonomies and metas.
|
345 |
*
|
346 |
* @since 2.6
|
347 |
*
|
348 |
+
* @param WP_Post $post the post currently being edited.
|
349 |
+
* @return void
|
350 |
*/
|
351 |
public function edit_form_top( $post ) {
|
352 |
if ( ! $this->model->post->current_user_can_synchronize( $post->ID ) ) {
|
admin/admin-filters-columns.php
CHANGED
@@ -10,7 +10,22 @@
|
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Columns {
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor: setups filters and actions
|
@@ -51,13 +66,13 @@ class PLL_Admin_Filters_Columns {
|
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
-
* Adds languages and translations columns in posts, pages, media, categories and tags tables
|
55 |
*
|
56 |
* @since 0.8.2
|
57 |
*
|
58 |
-
* @param
|
59 |
-
* @param string
|
60 |
-
* @return
|
61 |
*/
|
62 |
protected function add_column( $columns, $before ) {
|
63 |
if ( $n = array_search( $before, array_keys( $columns ) ) ) {
|
@@ -90,12 +105,12 @@ class PLL_Admin_Filters_Columns {
|
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
-
*
|
94 |
*
|
95 |
* @since 2.7
|
96 |
*
|
97 |
-
* @param
|
98 |
-
* @return
|
99 |
*/
|
100 |
public function hidden_columns( $hidden ) {
|
101 |
if ( ! empty( $this->filter_lang ) ) {
|
@@ -105,12 +120,12 @@ class PLL_Admin_Filters_Columns {
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* Adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables
|
109 |
*
|
110 |
* @since 0.1
|
111 |
*
|
112 |
-
* @param
|
113 |
-
* @return
|
114 |
*/
|
115 |
public function add_post_column( $columns ) {
|
116 |
return $this->add_column( $columns, 'comments' );
|
@@ -124,6 +139,7 @@ class PLL_Admin_Filters_Columns {
|
|
124 |
*
|
125 |
* @param string $column Column name
|
126 |
* @param int $post_id
|
|
|
127 |
*/
|
128 |
public function post_column( $column, $post_id ) {
|
129 |
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -135,6 +151,10 @@ class PLL_Admin_Filters_Columns {
|
|
135 |
|
136 |
$language = $this->model->get_language( substr( $column, 9 ) );
|
137 |
|
|
|
|
|
|
|
|
|
138 |
// Hidden field containing the post language for quick edit
|
139 |
if ( $column == $this->get_first_language_column() ) {
|
140 |
printf( '<div class="hidden" id="lang_%d">%s</div>', intval( $post_id ), esc_html( $lang->slug ) );
|
@@ -156,14 +176,19 @@ class PLL_Admin_Filters_Columns {
|
|
156 |
/* translators: accessibility text, %s is a native language name */
|
157 |
$s = sprintf( __( 'Edit the translation in %s', 'polylang' ), $language->name );
|
158 |
}
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
167 |
} elseif ( $id === $post_id ) {
|
168 |
printf(
|
169 |
'<span class="pll_column_flag" style=""><span class="screen-reader-text">%1$s</span>%2$s</span>',
|
@@ -214,12 +239,12 @@ class PLL_Admin_Filters_Columns {
|
|
214 |
}
|
215 |
|
216 |
/**
|
217 |
-
* Adds the language column ( before the posts column ) in the 'Categories' or 'Post Tags' table
|
218 |
*
|
219 |
* @since 0.1
|
220 |
*
|
221 |
-
* @param
|
222 |
-
* @return
|
223 |
*/
|
224 |
public function add_term_column( $columns ) {
|
225 |
return $this->add_column( $columns, 'posts' );
|
@@ -233,6 +258,7 @@ class PLL_Admin_Filters_Columns {
|
|
233 |
* @param string $out
|
234 |
* @param string $column Column name
|
235 |
* @param int $term_id
|
|
|
236 |
*/
|
237 |
public function term_column( $out, $column, $term_id ) {
|
238 |
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save-tax' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -256,13 +282,17 @@ class PLL_Admin_Filters_Columns {
|
|
256 |
$taxonomy = $GLOBALS['taxonomy'];
|
257 |
}
|
258 |
|
259 |
-
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
260 |
return $out;
|
261 |
}
|
262 |
|
263 |
$term_id = (int) $term_id;
|
264 |
$language = $this->model->get_language( substr( $column, 9 ) );
|
265 |
|
|
|
|
|
|
|
|
|
266 |
if ( $column == $this->get_first_language_column() ) {
|
267 |
$out = sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
|
268 |
|
@@ -316,6 +346,8 @@ class PLL_Admin_Filters_Columns {
|
|
316 |
* Update rows of translated posts when the language is modified in quick edit
|
317 |
*
|
318 |
* @since 1.7
|
|
|
|
|
319 |
*/
|
320 |
public function ajax_update_post_rows() {
|
321 |
check_ajax_referer( 'inlineeditnonce', '_pll_nonce' );
|
@@ -330,7 +362,7 @@ class PLL_Admin_Filters_Columns {
|
|
330 |
wp_die( 0 );
|
331 |
}
|
332 |
|
333 |
-
|
334 |
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
335 |
|
336 |
$x = new WP_Ajax_Response();
|
@@ -358,6 +390,8 @@ class PLL_Admin_Filters_Columns {
|
|
358 |
* Update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit
|
359 |
*
|
360 |
* @since 1.7
|
|
|
|
|
361 |
*/
|
362 |
public function ajax_update_term_rows() {
|
363 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
@@ -372,7 +406,7 @@ class PLL_Admin_Filters_Columns {
|
|
372 |
wp_die( 0 );
|
373 |
}
|
374 |
|
375 |
-
|
376 |
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
377 |
|
378 |
$x = new WP_Ajax_Response();
|
@@ -402,7 +436,7 @@ class PLL_Admin_Filters_Columns {
|
|
402 |
*
|
403 |
* @since 2.8
|
404 |
*
|
405 |
-
* @param
|
406 |
* @return string
|
407 |
*/
|
408 |
protected function get_flag_html( $language ) {
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Columns {
|
13 |
+
/**
|
14 |
+
* @var PLL_Model
|
15 |
+
*/
|
16 |
+
public $model;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var PLL_Admin_Links
|
20 |
+
*/
|
21 |
+
public $links;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Language selected in the admin language filter.
|
25 |
+
*
|
26 |
+
* @var PLL_Language
|
27 |
+
*/
|
28 |
+
public $filter_lang;
|
29 |
|
30 |
/**
|
31 |
* Constructor: setups filters and actions
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
+
* Adds languages and translations columns in posts, pages, media, categories and tags tables.
|
70 |
*
|
71 |
* @since 0.8.2
|
72 |
*
|
73 |
+
* @param string[] $columns List of table columns.
|
74 |
+
* @param string $before The column before which we want to add our languages.
|
75 |
+
* @return string[] Modified list of columns.
|
76 |
*/
|
77 |
protected function add_column( $columns, $before ) {
|
78 |
if ( $n = array_search( $before, array_keys( $columns ) ) ) {
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* Hides the column for the filtered language.
|
109 |
*
|
110 |
* @since 2.7
|
111 |
*
|
112 |
+
* @param string[] $hidden Array of hidden columns.
|
113 |
+
* @return string[]
|
114 |
*/
|
115 |
public function hidden_columns( $hidden ) {
|
116 |
if ( ! empty( $this->filter_lang ) ) {
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Adds the language and translations columns ( before the comments column ) in the posts, pages and media library tables.
|
124 |
*
|
125 |
* @since 0.1
|
126 |
*
|
127 |
+
* @param string[] $columns List of posts table columns.
|
128 |
+
* @return string[] Modified list of columns.
|
129 |
*/
|
130 |
public function add_post_column( $columns ) {
|
131 |
return $this->add_column( $columns, 'comments' );
|
139 |
*
|
140 |
* @param string $column Column name
|
141 |
* @param int $post_id
|
142 |
+
* @return void
|
143 |
*/
|
144 |
public function post_column( $column, $post_id ) {
|
145 |
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
151 |
|
152 |
$language = $this->model->get_language( substr( $column, 9 ) );
|
153 |
|
154 |
+
if ( empty( $language ) ) {
|
155 |
+
return;
|
156 |
+
}
|
157 |
+
|
158 |
// Hidden field containing the post language for quick edit
|
159 |
if ( $column == $this->get_first_language_column() ) {
|
160 |
printf( '<div class="hidden" id="lang_%d">%s</div>', intval( $post_id ), esc_html( $lang->slug ) );
|
176 |
/* translators: accessibility text, %s is a native language name */
|
177 |
$s = sprintf( __( 'Edit the translation in %s', 'polylang' ), $language->name );
|
178 |
}
|
179 |
+
|
180 |
+
$post = get_post( $id );
|
181 |
+
|
182 |
+
if ( ! empty( $post ) ) {
|
183 |
+
printf(
|
184 |
+
'<a class="%1$s" title="%2$s" href="%3$s"><span class="screen-reader-text">%4$s</span>%5$s</a>',
|
185 |
+
esc_attr( $class ),
|
186 |
+
esc_attr( $post->post_title ),
|
187 |
+
esc_url( $link ),
|
188 |
+
esc_html( $s ),
|
189 |
+
$flag // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
190 |
+
);
|
191 |
+
}
|
192 |
} elseif ( $id === $post_id ) {
|
193 |
printf(
|
194 |
'<span class="pll_column_flag" style=""><span class="screen-reader-text">%1$s</span>%2$s</span>',
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
+
* Adds the language column ( before the posts column ) in the 'Categories' or 'Post Tags' table.
|
243 |
*
|
244 |
* @since 0.1
|
245 |
*
|
246 |
+
* @param string[] $columns List of terms table columns.
|
247 |
+
* @return string[] modified List of columns.
|
248 |
*/
|
249 |
public function add_term_column( $columns ) {
|
250 |
return $this->add_column( $columns, 'posts' );
|
258 |
* @param string $out
|
259 |
* @param string $column Column name
|
260 |
* @param int $term_id
|
261 |
+
* @return string
|
262 |
*/
|
263 |
public function term_column( $out, $column, $term_id ) {
|
264 |
$inline = wp_doing_ajax() && isset( $_REQUEST['action'], $_POST['inline_lang_choice'] ) && 'inline-save-tax' === $_REQUEST['action']; // phpcs:ignore WordPress.Security.NonceVerification
|
282 |
$taxonomy = $GLOBALS['taxonomy'];
|
283 |
}
|
284 |
|
285 |
+
if ( ! isset( $taxonomy, $post_type ) || ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
286 |
return $out;
|
287 |
}
|
288 |
|
289 |
$term_id = (int) $term_id;
|
290 |
$language = $this->model->get_language( substr( $column, 9 ) );
|
291 |
|
292 |
+
if ( empty( $language ) ) {
|
293 |
+
return $out;
|
294 |
+
}
|
295 |
+
|
296 |
if ( $column == $this->get_first_language_column() ) {
|
297 |
$out = sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
|
298 |
|
346 |
* Update rows of translated posts when the language is modified in quick edit
|
347 |
*
|
348 |
* @since 1.7
|
349 |
+
*
|
350 |
+
* @return void
|
351 |
*/
|
352 |
public function ajax_update_post_rows() {
|
353 |
check_ajax_referer( 'inlineeditnonce', '_pll_nonce' );
|
362 |
wp_die( 0 );
|
363 |
}
|
364 |
|
365 |
+
/** @var WP_Posts_List_Table $wp_list_table */
|
366 |
$wp_list_table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
367 |
|
368 |
$x = new WP_Ajax_Response();
|
390 |
* Update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit
|
391 |
*
|
392 |
* @since 1.7
|
393 |
+
*
|
394 |
+
* @return void
|
395 |
*/
|
396 |
public function ajax_update_term_rows() {
|
397 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
406 |
wp_die( 0 );
|
407 |
}
|
408 |
|
409 |
+
/** @var WP_Terms_List_Table $wp_list_table */
|
410 |
$wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => sanitize_key( $_POST['screen'] ) ) );
|
411 |
|
412 |
$x = new WP_Ajax_Response();
|
436 |
*
|
437 |
* @since 2.8
|
438 |
*
|
439 |
+
* @param PLL_Language $language PLL_Language object.
|
440 |
* @return string
|
441 |
*/
|
442 |
protected function get_flag_html( $language ) {
|
admin/admin-filters-media.php
CHANGED
@@ -10,6 +10,9 @@
|
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
|
|
|
|
|
|
13 |
public $posts;
|
14 |
|
15 |
/**
|
@@ -37,14 +40,14 @@ class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
-
* Adds the language field and translations tables in the 'Edit Media' panel
|
41 |
* Needs WP 3.5+
|
42 |
*
|
43 |
* @since 0.9
|
44 |
*
|
45 |
-
* @param array
|
46 |
-
* @param
|
47 |
-
* @return array
|
48 |
*/
|
49 |
public function attachment_fields_to_edit( $fields, $post ) {
|
50 |
if ( 'post.php' == $GLOBALS['pagenow'] ) {
|
@@ -76,6 +79,8 @@ class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
|
76 |
* Creates a media translation
|
77 |
*
|
78 |
* @since 0.9
|
|
|
|
|
79 |
*/
|
80 |
public function translate_media() {
|
81 |
if ( isset( $_GET['from_media'], $_GET['new_lang'] ) ) {
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
13 |
+
/**
|
14 |
+
* @var PLL_CRUD_Posts
|
15 |
+
*/
|
16 |
public $posts;
|
17 |
|
18 |
/**
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* Adds the language field and translations tables in the 'Edit Media' panel.
|
44 |
* Needs WP 3.5+
|
45 |
*
|
46 |
* @since 0.9
|
47 |
*
|
48 |
+
* @param array $fields List of form fields.
|
49 |
+
* @param WP_Post $post The attachment being edited.
|
50 |
+
* @return array Modified list of form fields.
|
51 |
*/
|
52 |
public function attachment_fields_to_edit( $fields, $post ) {
|
53 |
if ( 'post.php' == $GLOBALS['pagenow'] ) {
|
79 |
* Creates a media translation
|
80 |
*
|
81 |
* @since 0.9
|
82 |
+
*
|
83 |
+
* @return void
|
84 |
*/
|
85 |
public function translate_media() {
|
86 |
if ( isset( $_GET['from_media'], $_GET['new_lang'] ) ) {
|
admin/admin-filters-post-base.php
CHANGED
@@ -9,7 +9,22 @@
|
|
9 |
* @since 1.5
|
10 |
*/
|
11 |
abstract class PLL_Admin_Filters_Post_Base {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor: setups filters and actions
|
@@ -25,21 +40,21 @@ abstract class PLL_Admin_Filters_Post_Base {
|
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
-
* Save translations from
|
29 |
*
|
30 |
* @since 1.5
|
31 |
*
|
32 |
-
* @param int $post_id
|
33 |
-
* @param
|
34 |
-
* @return array
|
35 |
*/
|
36 |
protected function save_translations( $post_id, $arr ) {
|
37 |
-
// Security check as 'wp_insert_post' can be called from outside WP admin
|
38 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
39 |
|
40 |
$translations = array();
|
41 |
|
42 |
-
// Save translations after checking the translated post is in the right language
|
43 |
foreach ( $arr as $lang => $tr_id ) {
|
44 |
$translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
|
45 |
}
|
9 |
* @since 1.5
|
10 |
*/
|
11 |
abstract class PLL_Admin_Filters_Post_Base {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
+
public $model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var PLL_Links
|
19 |
+
*/
|
20 |
+
public $links;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Language selected in the admin language filter.
|
24 |
+
*
|
25 |
+
* @var PLL_Language
|
26 |
+
*/
|
27 |
+
public $filter_lang;
|
28 |
|
29 |
/**
|
30 |
* Constructor: setups filters and actions
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* Save translations from the languages metabox.
|
44 |
*
|
45 |
* @since 1.5
|
46 |
*
|
47 |
+
* @param int $post_id Post id of the post being saved.
|
48 |
+
* @param int[] $arr An array with language codes as key and post id as value.
|
49 |
+
* @return int[] The array of translated post ids.
|
50 |
*/
|
51 |
protected function save_translations( $post_id, $arr ) {
|
52 |
+
// Security check as 'wp_insert_post' can be called from outside WP admin.
|
53 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
54 |
|
55 |
$translations = array();
|
56 |
|
57 |
+
// Save translations after checking the translated post is in the right language.
|
58 |
foreach ( $arr as $lang => $tr_id ) {
|
59 |
$translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
|
60 |
}
|
admin/admin-filters-post.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $curlang;
|
13 |
|
14 |
/**
|
@@ -43,10 +48,16 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
43 |
* to filter the parent dropdown per post language in quick edit
|
44 |
*
|
45 |
* @since 1.7
|
|
|
|
|
46 |
*/
|
47 |
public function admin_enqueue_scripts() {
|
48 |
$screen = get_current_screen();
|
49 |
|
|
|
|
|
|
|
|
|
50 |
// Hierarchical taxonomies
|
51 |
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'object' ) ) {
|
52 |
// Get translated hierarchical taxonomies
|
@@ -61,9 +72,11 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
61 |
$terms = get_terms( $hierarchical_taxonomies, array( 'get' => 'all' ) );
|
62 |
$term_languages = array();
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
67 |
}
|
68 |
}
|
69 |
|
@@ -95,11 +108,12 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
95 |
}
|
96 |
|
97 |
/**
|
98 |
-
* Filters posts, pages and media by language
|
99 |
*
|
100 |
* @since 0.1
|
101 |
*
|
102 |
-
* @param
|
|
|
103 |
*/
|
104 |
public function parse_query( $query ) {
|
105 |
$pll_query = new PLL_Query( $query, $this->model );
|
@@ -110,14 +124,25 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
110 |
* Save language and translation when editing a post (post.php)
|
111 |
*
|
112 |
* @since 2.3
|
|
|
|
|
113 |
*/
|
114 |
public function edit_post() {
|
115 |
if ( isset( $_POST['post_lang_choice'], $_POST['post_ID'] ) && $post_id = (int) $_POST['post_ID'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
116 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
117 |
|
118 |
$post = get_post( $post_id );
|
|
|
|
|
|
|
|
|
|
|
119 |
$post_type_object = get_post_type_object( $post->post_type );
|
120 |
|
|
|
|
|
|
|
|
|
121 |
if ( current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
|
122 |
$this->model->post->set_language( $post_id, $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) ) );
|
123 |
|
@@ -129,18 +154,28 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
129 |
}
|
130 |
|
131 |
/**
|
132 |
-
*
|
133 |
-
*
|
134 |
*
|
135 |
* @since 2.3
|
136 |
*
|
137 |
-
* @param int
|
138 |
-
* @param
|
|
|
139 |
*/
|
140 |
protected function inline_save_language( $post_id, $lang ) {
|
141 |
$post = get_post( $post_id );
|
|
|
|
|
|
|
|
|
|
|
142 |
$post_type_object = get_post_type_object( $post->post_type );
|
143 |
|
|
|
|
|
|
|
|
|
144 |
if ( current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
|
145 |
$old_lang = $this->model->post->get_language( $post_id ); // Stores the old language
|
146 |
$this->model->post->set_language( $post_id, $lang ); // set new language
|
@@ -166,6 +201,8 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
166 |
* Save language when bulk editing a post
|
167 |
*
|
168 |
* @since 2.3
|
|
|
|
|
169 |
*/
|
170 |
public function bulk_edit_posts() {
|
171 |
if ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'], $_REQUEST['post'] ) && -1 !== $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -184,6 +221,8 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
184 |
* Save language when inline editing a post
|
185 |
*
|
186 |
* @since 2.3
|
|
|
|
|
187 |
*/
|
188 |
public function inline_edit_post() {
|
189 |
check_admin_referer( 'inlineeditnonce', '_inline_edit' );
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
12 |
+
/**
|
13 |
+
* Current language (used to filter the content).
|
14 |
+
*
|
15 |
+
* @var PLL_Language
|
16 |
+
*/
|
17 |
public $curlang;
|
18 |
|
19 |
/**
|
48 |
* to filter the parent dropdown per post language in quick edit
|
49 |
*
|
50 |
* @since 1.7
|
51 |
+
*
|
52 |
+
* @return void
|
53 |
*/
|
54 |
public function admin_enqueue_scripts() {
|
55 |
$screen = get_current_screen();
|
56 |
|
57 |
+
if ( empty( $screen ) ) {
|
58 |
+
return;
|
59 |
+
}
|
60 |
+
|
61 |
// Hierarchical taxonomies
|
62 |
if ( 'edit' == $screen->base && $taxonomies = get_object_taxonomies( $screen->post_type, 'object' ) ) {
|
63 |
// Get translated hierarchical taxonomies
|
72 |
$terms = get_terms( $hierarchical_taxonomies, array( 'get' => 'all' ) );
|
73 |
$term_languages = array();
|
74 |
|
75 |
+
if ( is_array( $terms ) ) {
|
76 |
+
foreach ( $terms as $term ) {
|
77 |
+
if ( $lang = $this->model->term->get_language( $term->term_id ) ) {
|
78 |
+
$term_languages[ $lang->slug ][ $term->taxonomy ][] = $term->term_id;
|
79 |
+
}
|
80 |
}
|
81 |
}
|
82 |
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* Filters posts, pages and media by language.
|
112 |
*
|
113 |
* @since 0.1
|
114 |
*
|
115 |
+
* @param WP_Query $query WP_Query object.
|
116 |
+
* @return void
|
117 |
*/
|
118 |
public function parse_query( $query ) {
|
119 |
$pll_query = new PLL_Query( $query, $this->model );
|
124 |
* Save language and translation when editing a post (post.php)
|
125 |
*
|
126 |
* @since 2.3
|
127 |
+
*
|
128 |
+
* @return void
|
129 |
*/
|
130 |
public function edit_post() {
|
131 |
if ( isset( $_POST['post_lang_choice'], $_POST['post_ID'] ) && $post_id = (int) $_POST['post_ID'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
132 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
133 |
|
134 |
$post = get_post( $post_id );
|
135 |
+
|
136 |
+
if ( empty( $post ) ) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
$post_type_object = get_post_type_object( $post->post_type );
|
141 |
|
142 |
+
if ( empty( $post_type_object ) ) {
|
143 |
+
return;
|
144 |
+
}
|
145 |
+
|
146 |
if ( current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
|
147 |
$this->model->post->set_language( $post_id, $this->model->get_language( sanitize_key( $_POST['post_lang_choice'] ) ) );
|
148 |
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
+
* Saves a post language when inline editing or bulk editing.
|
158 |
+
* Fixes the translations if necessary.
|
159 |
*
|
160 |
* @since 2.3
|
161 |
*
|
162 |
+
* @param int $post_id Post ID.
|
163 |
+
* @param PLL_Language $lang Language.
|
164 |
+
* @return void
|
165 |
*/
|
166 |
protected function inline_save_language( $post_id, $lang ) {
|
167 |
$post = get_post( $post_id );
|
168 |
+
|
169 |
+
if ( empty( $post ) ) {
|
170 |
+
return;
|
171 |
+
}
|
172 |
+
|
173 |
$post_type_object = get_post_type_object( $post->post_type );
|
174 |
|
175 |
+
if ( empty( $post_type_object ) ) {
|
176 |
+
return;
|
177 |
+
}
|
178 |
+
|
179 |
if ( current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
|
180 |
$old_lang = $this->model->post->get_language( $post_id ); // Stores the old language
|
181 |
$this->model->post->set_language( $post_id, $lang ); // set new language
|
201 |
* Save language when bulk editing a post
|
202 |
*
|
203 |
* @since 2.3
|
204 |
+
*
|
205 |
+
* @return void
|
206 |
*/
|
207 |
public function bulk_edit_posts() {
|
208 |
if ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'], $_REQUEST['post'] ) && -1 !== $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
221 |
* Save language when inline editing a post
|
222 |
*
|
223 |
* @since 2.3
|
224 |
+
*
|
225 |
+
* @return void
|
226 |
*/
|
227 |
public function inline_edit_post() {
|
228 |
check_admin_referer( 'inlineeditnonce', '_inline_edit' );
|
admin/admin-filters-term.php
CHANGED
@@ -9,9 +9,50 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Admin_Filters_Term {
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
/**
|
17 |
* Constructor: setups filters and actions
|
@@ -56,6 +97,8 @@ class PLL_Admin_Filters_Term {
|
|
56 |
* Adds the language field in the 'Categories' and 'Post Tags' panels
|
57 |
*
|
58 |
* @since 0.1
|
|
|
|
|
59 |
*/
|
60 |
public function add_term_form() {
|
61 |
if ( isset( $_GET['taxonomy'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -70,7 +113,7 @@ class PLL_Admin_Filters_Term {
|
|
70 |
$post_type = $GLOBALS['post_type'];
|
71 |
}
|
72 |
|
73 |
-
if (
|
74 |
return;
|
75 |
}
|
76 |
|
@@ -117,11 +160,12 @@ class PLL_Admin_Filters_Term {
|
|
117 |
}
|
118 |
|
119 |
/**
|
120 |
-
* Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels
|
121 |
*
|
122 |
* @since 0.1
|
123 |
*
|
124 |
-
* @param
|
|
|
125 |
*/
|
126 |
public function edit_term_form( $tag ) {
|
127 |
if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -132,7 +176,7 @@ class PLL_Admin_Filters_Term {
|
|
132 |
$post_type = $GLOBALS['post_type'];
|
133 |
}
|
134 |
|
135 |
-
if ( ! post_type_exists( $post_type ) ) {
|
136 |
return;
|
137 |
}
|
138 |
|
@@ -153,7 +197,7 @@ class PLL_Admin_Filters_Term {
|
|
153 |
array(
|
154 |
'name' => 'term_lang_choice',
|
155 |
'value' => 'term_id',
|
156 |
-
'selected' => $lang
|
157 |
'disabled' => $disabled,
|
158 |
'flag' => true,
|
159 |
)
|
@@ -177,9 +221,7 @@ class PLL_Admin_Filters_Term {
|
|
177 |
);
|
178 |
|
179 |
echo '<tr id="term-translations" class="form-field">';
|
180 |
-
|
181 |
-
include __DIR__ . '/view-translations-term.php';
|
182 |
-
}
|
183 |
echo '</tr>' . "\n";
|
184 |
}
|
185 |
|
@@ -199,7 +241,7 @@ class PLL_Admin_Filters_Term {
|
|
199 |
if ( isset( $taxonomy, $_GET['from_tag'], $_GET['new_lang'] ) && taxonomy_exists( $taxonomy ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
200 |
$term = get_term( (int) $_GET['from_tag'], $taxonomy ); // phpcs:ignore WordPress.Security.NonceVerification
|
201 |
|
202 |
-
if ( $term && $id = $term->parent ) {
|
203 |
$lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
204 |
if ( $parent = $this->model->term->get_translation( $id, $lang ) ) {
|
205 |
return str_replace( '"' . $parent . '"', '"' . $parent . '" selected="selected"', $output );
|
@@ -215,6 +257,7 @@ class PLL_Admin_Filters_Term {
|
|
215 |
* @since 1.7
|
216 |
*
|
217 |
* @param int $post_id
|
|
|
218 |
*/
|
219 |
public function pre_post_update( $post_id ) {
|
220 |
if ( isset( $_GET['bulk_edit'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -229,6 +272,7 @@ class PLL_Admin_Filters_Term {
|
|
229 |
*
|
230 |
* @param int $term_id
|
231 |
* @param string $taxonomy
|
|
|
232 |
*/
|
233 |
protected function save_language( $term_id, $taxonomy ) {
|
234 |
global $wpdb;
|
@@ -323,20 +367,20 @@ class PLL_Admin_Filters_Term {
|
|
323 |
}
|
324 |
|
325 |
/**
|
326 |
-
* Save translations from our form
|
327 |
*
|
328 |
* @since 1.5
|
329 |
*
|
330 |
-
* @param int $term_id
|
331 |
-
* @return array
|
332 |
*/
|
333 |
protected function save_translations( $term_id ) {
|
334 |
-
// Security check as 'wp_update_term' can be called from outside WP admin
|
335 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
336 |
|
337 |
$translations = array();
|
338 |
|
339 |
-
// Save translations after checking the translated term is in the right language ( as well as cast id to int )
|
340 |
if ( isset( $_POST['term_tr_lang'] ) ) {
|
341 |
foreach ( array_map( 'absint', $_POST['term_tr_lang'] ) as $lang => $tr_id ) {
|
342 |
$tr_lang = $this->model->term->get_language( $tr_id );
|
@@ -358,6 +402,7 @@ class PLL_Admin_Filters_Term {
|
|
358 |
* @param int $term_id
|
359 |
* @param int $tt_id term taxonomy id
|
360 |
* @param string $taxonomy
|
|
|
361 |
*/
|
362 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
363 |
// Does nothing except on taxonomies which are filterable
|
@@ -365,10 +410,15 @@ class PLL_Admin_Filters_Term {
|
|
365 |
return;
|
366 |
}
|
367 |
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
// Capability check
|
369 |
// As 'wp_update_term' can be called from outside WP admin
|
370 |
// 2nd test for creating tags when creating / editing a post
|
371 |
-
$tax = get_taxonomy( $taxonomy );
|
372 |
if ( current_user_can( $tax->cap->edit_terms ) || ( isset( $_POST['tax_input'][ $taxonomy ] ) && current_user_can( $tax->cap->assign_terms ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
373 |
$this->save_language( $term_id, $taxonomy );
|
374 |
|
@@ -434,6 +484,8 @@ class PLL_Admin_Filters_Term {
|
|
434 |
* Ajax response for edit term form
|
435 |
*
|
436 |
* @since 0.2
|
|
|
|
|
437 |
*/
|
438 |
public function term_lang_choice() {
|
439 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
@@ -447,14 +499,12 @@ class PLL_Admin_Filters_Term {
|
|
447 |
$taxonomy = sanitize_key( $_POST['taxonomy'] );
|
448 |
$post_type = sanitize_key( $_POST['post_type'] );
|
449 |
|
450 |
-
if ( ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
451 |
wp_die( 0 );
|
452 |
}
|
453 |
|
454 |
ob_start();
|
455 |
-
|
456 |
-
include __DIR__ . '/view-translations-term.php';
|
457 |
-
}
|
458 |
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
459 |
ob_end_clean();
|
460 |
|
@@ -478,7 +528,7 @@ class PLL_Admin_Filters_Term {
|
|
478 |
// Tests copied from edit_tags.php
|
479 |
else {
|
480 |
$tax = get_taxonomy( $taxonomy );
|
481 |
-
if ( ! is_null( $tax->labels->popular_items ) ) {
|
482 |
$args = array( 'taxonomy' => $taxonomy, 'echo' => false );
|
483 |
if ( current_user_can( $tax->cap->edit_terms ) ) {
|
484 |
$args = array_merge( $args, array( 'link' => 'edit' ) );
|
@@ -501,6 +551,8 @@ class PLL_Admin_Filters_Term {
|
|
501 |
* Ajax response for input in translation autocomplete input box
|
502 |
*
|
503 |
* @since 1.5
|
|
|
|
|
504 |
*/
|
505 |
public function ajax_terms_not_translated() {
|
506 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
@@ -509,6 +561,7 @@ class PLL_Admin_Filters_Term {
|
|
509 |
wp_die( 0 );
|
510 |
}
|
511 |
|
|
|
512 |
$s = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
513 |
$post_type = sanitize_key( $_GET['post_type'] );
|
514 |
$taxonomy = sanitize_key( $_GET['taxonomy'] );
|
@@ -530,31 +583,36 @@ class PLL_Admin_Filters_Term {
|
|
530 |
}
|
531 |
|
532 |
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
533 |
-
|
534 |
-
|
|
|
|
|
535 |
|
536 |
-
|
537 |
-
|
|
|
538 |
}
|
539 |
}
|
540 |
|
541 |
// Format the ajax response.
|
542 |
foreach ( $terms as $term ) {
|
543 |
-
$
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
|
|
|
|
|
|
553 |
),
|
554 |
-
'
|
555 |
-
)
|
556 |
-
|
557 |
-
);
|
558 |
}
|
559 |
|
560 |
wp_die( wp_json_encode( $return ) );
|
@@ -583,6 +641,7 @@ class PLL_Admin_Filters_Term {
|
|
583 |
*
|
584 |
* @param int $old_value
|
585 |
* @param int $value
|
|
|
586 |
*/
|
587 |
public function update_option_default_category( $old_value, $value ) {
|
588 |
$default_cat_lang = $this->model->term->get_language( $value );
|
@@ -610,6 +669,7 @@ class PLL_Admin_Filters_Term {
|
|
610 |
* @param int $new_term_id
|
611 |
* @param int $term_taxonomy_id
|
612 |
* @param string $taxonomy
|
|
|
613 |
*/
|
614 |
public function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
|
615 |
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
@@ -622,8 +682,12 @@ class PLL_Admin_Filters_Term {
|
|
622 |
return;
|
623 |
}
|
624 |
|
625 |
-
$avoid_recursion = true;
|
626 |
$lang = $this->model->term->get_language( $term_id );
|
|
|
|
|
|
|
|
|
|
|
627 |
$translations = array();
|
628 |
|
629 |
foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Admin_Filters_Term {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
public $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var PLL_Admin_Links
|
26 |
+
*/
|
27 |
+
public $links;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Language selected in the admin language filter.
|
31 |
+
*
|
32 |
+
* @var PLL_Language
|
33 |
+
*/
|
34 |
+
public $filter_lang;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Preferred language to assign to the new terms.
|
38 |
+
*
|
39 |
+
* @var PLL_Language
|
40 |
+
*/
|
41 |
+
public $pref_lang;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Stores the term name before creating a slug if needed.
|
45 |
+
*
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
protected $pre_term_name;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Stores the current post_id when bulk editing posts.
|
52 |
+
*
|
53 |
+
* @var int
|
54 |
+
*/
|
55 |
+
protected $post_id;
|
56 |
|
57 |
/**
|
58 |
* Constructor: setups filters and actions
|
97 |
* Adds the language field in the 'Categories' and 'Post Tags' panels
|
98 |
*
|
99 |
* @since 0.1
|
100 |
+
*
|
101 |
+
* @return void
|
102 |
*/
|
103 |
public function add_term_form() {
|
104 |
if ( isset( $_GET['taxonomy'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
113 |
$post_type = $GLOBALS['post_type'];
|
114 |
}
|
115 |
|
116 |
+
if ( ! isset( $taxonomy, $post_type ) || ! taxonomy_exists( $taxonomy ) || ! post_type_exists( $post_type ) ) {
|
117 |
return;
|
118 |
}
|
119 |
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
+
* Adds the language field and translations tables in the 'Edit Category' and 'Edit Tag' panels.
|
164 |
*
|
165 |
* @since 0.1
|
166 |
*
|
167 |
+
* @param WP_Term $tag The term being edited.
|
168 |
+
* @return void
|
169 |
*/
|
170 |
public function edit_term_form( $tag ) {
|
171 |
if ( isset( $_REQUEST['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
176 |
$post_type = $GLOBALS['post_type'];
|
177 |
}
|
178 |
|
179 |
+
if ( ! isset( $post_type ) || ! post_type_exists( $post_type ) ) {
|
180 |
return;
|
181 |
}
|
182 |
|
197 |
array(
|
198 |
'name' => 'term_lang_choice',
|
199 |
'value' => 'term_id',
|
200 |
+
'selected' => $lang->term_id,
|
201 |
'disabled' => $disabled,
|
202 |
'flag' => true,
|
203 |
)
|
221 |
);
|
222 |
|
223 |
echo '<tr id="term-translations" class="form-field">';
|
224 |
+
include __DIR__ . '/view-translations-term.php';
|
|
|
|
|
225 |
echo '</tr>' . "\n";
|
226 |
}
|
227 |
|
241 |
if ( isset( $taxonomy, $_GET['from_tag'], $_GET['new_lang'] ) && taxonomy_exists( $taxonomy ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
242 |
$term = get_term( (int) $_GET['from_tag'], $taxonomy ); // phpcs:ignore WordPress.Security.NonceVerification
|
243 |
|
244 |
+
if ( $term instanceof WP_Term && $id = $term->parent ) {
|
245 |
$lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
246 |
if ( $parent = $this->model->term->get_translation( $id, $lang ) ) {
|
247 |
return str_replace( '"' . $parent . '"', '"' . $parent . '" selected="selected"', $output );
|
257 |
* @since 1.7
|
258 |
*
|
259 |
* @param int $post_id
|
260 |
+
* @return void
|
261 |
*/
|
262 |
public function pre_post_update( $post_id ) {
|
263 |
if ( isset( $_GET['bulk_edit'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
272 |
*
|
273 |
* @param int $term_id
|
274 |
* @param string $taxonomy
|
275 |
+
* @return void
|
276 |
*/
|
277 |
protected function save_language( $term_id, $taxonomy ) {
|
278 |
global $wpdb;
|
367 |
}
|
368 |
|
369 |
/**
|
370 |
+
* Save translations from our form.
|
371 |
*
|
372 |
* @since 1.5
|
373 |
*
|
374 |
+
* @param int $term_id The term id of teh term being saved.
|
375 |
+
* @return int[] The array of translated term ids.
|
376 |
*/
|
377 |
protected function save_translations( $term_id ) {
|
378 |
+
// Security check as 'wp_update_term' can be called from outside WP admin.
|
379 |
check_admin_referer( 'pll_language', '_pll_nonce' );
|
380 |
|
381 |
$translations = array();
|
382 |
|
383 |
+
// Save translations after checking the translated term is in the right language ( as well as cast id to int ).
|
384 |
if ( isset( $_POST['term_tr_lang'] ) ) {
|
385 |
foreach ( array_map( 'absint', $_POST['term_tr_lang'] ) as $lang => $tr_id ) {
|
386 |
$tr_lang = $this->model->term->get_language( $tr_id );
|
402 |
* @param int $term_id
|
403 |
* @param int $tt_id term taxonomy id
|
404 |
* @param string $taxonomy
|
405 |
+
* @return void
|
406 |
*/
|
407 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
408 |
// Does nothing except on taxonomies which are filterable
|
410 |
return;
|
411 |
}
|
412 |
|
413 |
+
$tax = get_taxonomy( $taxonomy );
|
414 |
+
|
415 |
+
if ( empty( $tax ) ) {
|
416 |
+
return;
|
417 |
+
}
|
418 |
+
|
419 |
// Capability check
|
420 |
// As 'wp_update_term' can be called from outside WP admin
|
421 |
// 2nd test for creating tags when creating / editing a post
|
|
|
422 |
if ( current_user_can( $tax->cap->edit_terms ) || ( isset( $_POST['tax_input'][ $taxonomy ] ) && current_user_can( $tax->cap->assign_terms ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
423 |
$this->save_language( $term_id, $taxonomy );
|
424 |
|
484 |
* Ajax response for edit term form
|
485 |
*
|
486 |
* @since 0.2
|
487 |
+
*
|
488 |
+
* @return void
|
489 |
*/
|
490 |
public function term_lang_choice() {
|
491 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
499 |
$taxonomy = sanitize_key( $_POST['taxonomy'] );
|
500 |
$post_type = sanitize_key( $_POST['post_type'] );
|
501 |
|
502 |
+
if ( empty( $lang ) || ! post_type_exists( $post_type ) || ! taxonomy_exists( $taxonomy ) ) {
|
503 |
wp_die( 0 );
|
504 |
}
|
505 |
|
506 |
ob_start();
|
507 |
+
include __DIR__ . '/view-translations-term.php';
|
|
|
|
|
508 |
$x = new WP_Ajax_Response( array( 'what' => 'translations', 'data' => ob_get_contents() ) );
|
509 |
ob_end_clean();
|
510 |
|
528 |
// Tests copied from edit_tags.php
|
529 |
else {
|
530 |
$tax = get_taxonomy( $taxonomy );
|
531 |
+
if ( ! empty( $tax ) && ! is_null( $tax->labels->popular_items ) ) {
|
532 |
$args = array( 'taxonomy' => $taxonomy, 'echo' => false );
|
533 |
if ( current_user_can( $tax->cap->edit_terms ) ) {
|
534 |
$args = array_merge( $args, array( 'link' => 'edit' ) );
|
551 |
* Ajax response for input in translation autocomplete input box
|
552 |
*
|
553 |
* @since 1.5
|
554 |
+
*
|
555 |
+
* @return void
|
556 |
*/
|
557 |
public function ajax_terms_not_translated() {
|
558 |
check_ajax_referer( 'pll_language', '_pll_nonce' );
|
561 |
wp_die( 0 );
|
562 |
}
|
563 |
|
564 |
+
/** @var string */
|
565 |
$s = wp_unslash( $_GET['term'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
566 |
$post_type = sanitize_key( $_GET['post_type'] );
|
567 |
$taxonomy = sanitize_key( $_GET['taxonomy'] );
|
583 |
}
|
584 |
|
585 |
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
586 |
+
$all_terms = get_terms( $taxonomy, 'hide_empty=0&lang=0&name__like=' . $s );
|
587 |
+
if ( is_array( $all_terms ) ) {
|
588 |
+
foreach ( $all_terms as $term ) {
|
589 |
+
$lang = $this->model->term->get_language( $term->term_id );
|
590 |
|
591 |
+
if ( $lang && $lang->slug == $translation_language->slug && ! $this->model->term->get_translation( $term->term_id, $term_language ) ) {
|
592 |
+
$terms[] = $term;
|
593 |
+
}
|
594 |
}
|
595 |
}
|
596 |
|
597 |
// Format the ajax response.
|
598 |
foreach ( $terms as $term ) {
|
599 |
+
if ( $term instanceof WP_Term ) {
|
600 |
+
$return[] = array(
|
601 |
+
'id' => $term->term_id,
|
602 |
+
'value' => rtrim( // Trim the seperator added at the end by WP.
|
603 |
+
get_term_parents_list(
|
604 |
+
$term->term_id,
|
605 |
+
$term->taxonomy,
|
606 |
+
array(
|
607 |
+
'separator' => ' > ',
|
608 |
+
'link' => false,
|
609 |
+
)
|
610 |
+
),
|
611 |
+
' >'
|
612 |
),
|
613 |
+
'link' => $this->links->edit_term_translation_link( $term->term_id, $term->taxonomy, $post_type ),
|
614 |
+
);
|
615 |
+
}
|
|
|
616 |
}
|
617 |
|
618 |
wp_die( wp_json_encode( $return ) );
|
641 |
*
|
642 |
* @param int $old_value
|
643 |
* @param int $value
|
644 |
+
* @return void
|
645 |
*/
|
646 |
public function update_option_default_category( $old_value, $value ) {
|
647 |
$default_cat_lang = $this->model->term->get_language( $value );
|
669 |
* @param int $new_term_id
|
670 |
* @param int $term_taxonomy_id
|
671 |
* @param string $taxonomy
|
672 |
+
* @return void
|
673 |
*/
|
674 |
public function split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) {
|
675 |
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
682 |
return;
|
683 |
}
|
684 |
|
|
|
685 |
$lang = $this->model->term->get_language( $term_id );
|
686 |
+
if ( empty( $lang ) ) {
|
687 |
+
return;
|
688 |
+
}
|
689 |
+
|
690 |
+
$avoid_recursion = true;
|
691 |
$translations = array();
|
692 |
|
693 |
foreach ( $this->model->term->get_translations( $term_id ) as $key => $tr_id ) {
|
admin/admin-filters-widgets-options.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class PLL_Widgets_Filters
|
8 |
+
*
|
9 |
+
* @since 3.0
|
10 |
+
*
|
11 |
+
* Adds new options to {@see https://developer.wordpress.org/reference/classes/wp_widget/ WP_Widget} and saves them.
|
12 |
+
*/
|
13 |
+
class PLL_Admin_Filters_Widgets_Options extends PLL_Filters_Widgets_Options {
|
14 |
+
/**
|
15 |
+
* Modifies the widgets forms to add our language dropdown list.
|
16 |
+
*
|
17 |
+
* @since 0.3
|
18 |
+
* @since 3.0 Moved from PLL_Admin_Filters
|
19 |
+
*
|
20 |
+
* @param WP_Widget $widget Widget instance.
|
21 |
+
* @param null $return Not used.
|
22 |
+
* @param array $instance Widget settings.
|
23 |
+
* @return void
|
24 |
+
*/
|
25 |
+
public function in_widget_form( $widget, $return, $instance ) {
|
26 |
+
$screen = get_current_screen();
|
27 |
+
|
28 |
+
// Test the Widgets screen and the Customizer to avoid displaying the option in page builders
|
29 |
+
// Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET.
|
30 |
+
if ( ( isset( $screen ) && in_array( $screen->base, array( 'widgets', 'appearance_page_gutenberg-widgets' ) ) ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
31 |
+
parent::in_widget_form( $widget, $return, $instance );
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Called when widget options are saved.
|
37 |
+
* Saves the language associated to the widget.
|
38 |
+
*
|
39 |
+
* @since 3.0
|
40 |
+
*
|
41 |
+
* @param array $instance The current Widget's options.
|
42 |
+
* @param array $new_instance The new Widget's options.
|
43 |
+
* @param array $old_instance Not used.
|
44 |
+
* @param WP_Widget $widget The Widget object.
|
45 |
+
* @return array The processed Widget options.
|
46 |
+
*/
|
47 |
+
public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
|
48 |
+
$key = $this->get_language_key( $widget );
|
49 |
+
if ( ! empty( $_POST[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
50 |
+
$new_instance[ $key ] = sanitize_key( $_POST[ $key ] ); // phpcs:ignore WordPress.Security.NonceVerification
|
51 |
+
}
|
52 |
+
return parent::widget_update_callback( $instance, $new_instance, $old_instance, $widget );
|
53 |
+
}
|
54 |
+
|
55 |
+
}
|
admin/admin-filters.php
CHANGED
@@ -20,19 +20,11 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
20 |
public function __construct( &$polylang ) {
|
21 |
parent::__construct( $polylang );
|
22 |
|
23 |
-
// Widgets languages filter
|
24 |
-
add_action( 'in_widget_form', array( $this, 'in_widget_form' ), 10, 3 );
|
25 |
-
add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ), 10, 4 );
|
26 |
-
|
27 |
// Language management for users
|
28 |
add_action( 'personal_options_update', array( $this, 'personal_options_update' ) );
|
29 |
add_action( 'edit_user_profile_update', array( $this, 'personal_options_update' ) );
|
30 |
add_action( 'personal_options', array( $this, 'personal_options' ) );
|
31 |
|
32 |
-
// Upgrades languages files after a core upgrade ( timing is important )
|
33 |
-
// Backward compatibility WP < 4.0 *AND* Polylang < 1.6
|
34 |
-
add_action( '_core_updated_successfully', array( $this, 'upgrade_languages' ), 1 ); // since WP 3.3
|
35 |
-
|
36 |
// Upgrades plugins and themes translations files
|
37 |
add_filter( 'themes_update_check_locales', array( $this, 'update_check_locales' ) );
|
38 |
add_filter( 'plugins_update_check_locales', array( $this, 'update_check_locales' ) );
|
@@ -43,75 +35,13 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
43 |
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
44 |
}
|
45 |
|
46 |
-
/**
|
47 |
-
* Modifies the widgets forms to add our language dropdown list
|
48 |
-
*
|
49 |
-
* @since 0.3
|
50 |
-
*
|
51 |
-
* @param object $widget Widget instance
|
52 |
-
* @param null $return Not used
|
53 |
-
* @param array $instance Widget settings
|
54 |
-
*/
|
55 |
-
public function in_widget_form( $widget, $return, $instance ) {
|
56 |
-
$screen = get_current_screen();
|
57 |
-
|
58 |
-
// Test the Widgets screen and the Customizer to avoid displaying the option in page builders
|
59 |
-
// Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET.
|
60 |
-
if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
61 |
-
$dropdown = new PLL_Walker_Dropdown();
|
62 |
-
|
63 |
-
$dropdown_html = $dropdown->walk(
|
64 |
-
array_merge(
|
65 |
-
array( (object) array( 'slug' => 0, 'name' => __( 'All languages', 'polylang' ) ) ),
|
66 |
-
$this->model->get_languages_list()
|
67 |
-
),
|
68 |
-
-1,
|
69 |
-
array(
|
70 |
-
'name' => $widget->id . '_lang_choice',
|
71 |
-
'class' => 'tags-input pll-lang-choice',
|
72 |
-
'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'],
|
73 |
-
)
|
74 |
-
);
|
75 |
-
|
76 |
-
printf(
|
77 |
-
'<p><label for="%1$s">%2$s %3$s</label></p>',
|
78 |
-
esc_attr( $widget->id . '_lang_choice' ),
|
79 |
-
esc_html__( 'The widget is displayed for:', 'polylang' ),
|
80 |
-
$dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
|
81 |
-
);
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Called when widget options are saved
|
87 |
-
* saves the language associated to the widget
|
88 |
-
*
|
89 |
-
* @since 0.3
|
90 |
-
*
|
91 |
-
* @param array $instance Widget options
|
92 |
-
* @param array $new_instance Not used
|
93 |
-
* @param array $old_instance Not used
|
94 |
-
* @param object $widget WP_Widget object
|
95 |
-
* @return array Widget options
|
96 |
-
*/
|
97 |
-
public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
|
98 |
-
$key = $widget->id . '_lang_choice';
|
99 |
-
|
100 |
-
if ( ! empty( $_POST[ $key ] ) && $lang = $this->model->get_language( sanitize_key( $_POST[ $key ] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
101 |
-
$instance['pll_lang'] = $lang->slug;
|
102 |
-
} else {
|
103 |
-
unset( $instance['pll_lang'] );
|
104 |
-
}
|
105 |
-
|
106 |
-
return $instance;
|
107 |
-
}
|
108 |
-
|
109 |
/**
|
110 |
* Updates language user preference set in user profile
|
111 |
*
|
112 |
* @since 0.4
|
113 |
*
|
114 |
* @param int $user_id
|
|
|
115 |
*/
|
116 |
public function personal_options_update( $user_id ) {
|
117 |
// Biography translations
|
@@ -126,11 +56,12 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
-
* Outputs hidden information to modify the biography form with js
|
130 |
*
|
131 |
* @since 0.4
|
132 |
*
|
133 |
-
* @param
|
|
|
134 |
*/
|
135 |
public function personal_options( $profileuser ) {
|
136 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
@@ -148,31 +79,13 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
148 |
}
|
149 |
}
|
150 |
|
151 |
-
/**
|
152 |
-
* Upgrades languages files after a core upgrade
|
153 |
-
* only for backward compatibility WP < 4.0 *AND* Polylang < 1.6
|
154 |
-
*
|
155 |
-
* @since 0.6
|
156 |
-
*
|
157 |
-
* @param string $version new WP version
|
158 |
-
*/
|
159 |
-
public function upgrade_languages( $version ) {
|
160 |
-
// $GLOBALS['wp_version'] is the old WP version
|
161 |
-
if ( version_compare( $version, '4.0', '>=' ) && version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) {
|
162 |
-
|
163 |
-
/** This filter is documented in wp-admin/includes/update-core.php */
|
164 |
-
apply_filters( 'update_feedback', __( 'Upgrading language files…', 'polylang' ) );
|
165 |
-
PLL_Upgrade::download_language_packs();
|
166 |
-
}
|
167 |
-
}
|
168 |
-
|
169 |
/**
|
170 |
* Allows to update translations files for plugins and themes.
|
171 |
*
|
172 |
* @since 1.6
|
173 |
*
|
174 |
-
* @param
|
175 |
-
* @return
|
176 |
*/
|
177 |
public function update_check_locales( $locales ) {
|
178 |
return array_merge( $locales, $this->model->get_languages_list( array( 'fields' => 'locale' ) ) );
|
@@ -194,13 +107,13 @@ class PLL_Admin_Filters extends PLL_Filters {
|
|
194 |
}
|
195 |
|
196 |
/**
|
197 |
-
*
|
198 |
*
|
199 |
* @since 2.7
|
200 |
*
|
201 |
-
* @param
|
202 |
-
* @param
|
203 |
-
* @return
|
204 |
*/
|
205 |
public function display_post_states( $post_states, $post ) {
|
206 |
$page_for_privacy_policy = get_option( 'wp_page_for_privacy_policy' );
|
20 |
public function __construct( &$polylang ) {
|
21 |
parent::__construct( $polylang );
|
22 |
|
|
|
|
|
|
|
|
|
23 |
// Language management for users
|
24 |
add_action( 'personal_options_update', array( $this, 'personal_options_update' ) );
|
25 |
add_action( 'edit_user_profile_update', array( $this, 'personal_options_update' ) );
|
26 |
add_action( 'personal_options', array( $this, 'personal_options' ) );
|
27 |
|
|
|
|
|
|
|
|
|
28 |
// Upgrades plugins and themes translations files
|
29 |
add_filter( 'themes_update_check_locales', array( $this, 'update_check_locales' ) );
|
30 |
add_filter( 'plugins_update_check_locales', array( $this, 'update_check_locales' ) );
|
35 |
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
36 |
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
/**
|
39 |
* Updates language user preference set in user profile
|
40 |
*
|
41 |
* @since 0.4
|
42 |
*
|
43 |
* @param int $user_id
|
44 |
+
* @return void
|
45 |
*/
|
46 |
public function personal_options_update( $user_id ) {
|
47 |
// Biography translations
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
+
* Outputs hidden information to modify the biography form with js.
|
60 |
*
|
61 |
* @since 0.4
|
62 |
*
|
63 |
+
* @param WP_User $profileuser The current WP_User object.
|
64 |
+
* @return void
|
65 |
*/
|
66 |
public function personal_options( $profileuser ) {
|
67 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
79 |
}
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
/**
|
83 |
* Allows to update translations files for plugins and themes.
|
84 |
*
|
85 |
* @since 1.6
|
86 |
*
|
87 |
+
* @param string[] $locales List of locales to update for plugins and themes.
|
88 |
+
* @return string[]
|
89 |
*/
|
90 |
public function update_check_locales( $locales ) {
|
91 |
return array_merge( $locales, $this->model->get_languages_list( array( 'fields' => 'locale' ) ) );
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
+
* Adds post state for translations of the privacy policy page.
|
111 |
*
|
112 |
* @since 2.7
|
113 |
*
|
114 |
+
* @param string[] $post_states An array of post display states.
|
115 |
+
* @param WP_Post $post The current post object.
|
116 |
+
* @return string[]
|
117 |
*/
|
118 |
public function display_post_states( $post_states, $post ) {
|
119 |
$page_for_privacy_policy = get_option( 'wp_page_for_privacy_policy' );
|
admin/admin-links.php
CHANGED
@@ -4,19 +4,19 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Manages links related functions
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Admin_Links extends PLL_Links {
|
12 |
|
13 |
/**
|
14 |
-
* Returns html markup for a new translation link
|
15 |
*
|
16 |
* @since 2.6
|
17 |
*
|
18 |
-
* @param string
|
19 |
-
* @param
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function new_translation_link( $link, $language ) {
|
@@ -38,12 +38,12 @@ class PLL_Admin_Links extends PLL_Links {
|
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* Returns html markup for a translation link
|
42 |
*
|
43 |
* @since 2.6
|
44 |
*
|
45 |
-
* @param string
|
46 |
-
* @param
|
47 |
* @return string
|
48 |
*/
|
49 |
public function edit_translation_link( $link, $language ) {
|
@@ -56,20 +56,20 @@ class PLL_Admin_Links extends PLL_Links {
|
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
-
* Get the link to create a new post translation
|
60 |
*
|
61 |
* @since 1.5
|
62 |
*
|
63 |
-
* @param int
|
64 |
-
* @param
|
65 |
-
* @param string
|
66 |
-
*
|
67 |
* @return string
|
68 |
*/
|
69 |
public function get_new_post_translation_link( $post_id, $language, $context = 'display' ) {
|
70 |
$post_type = get_post_type( $post_id );
|
71 |
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
72 |
-
if ( ! current_user_can( $post_type_object->cap->create_posts ) ) {
|
73 |
return '';
|
74 |
}
|
75 |
|
@@ -113,24 +113,24 @@ class PLL_Admin_Links extends PLL_Links {
|
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
-
*
|
117 |
*
|
118 |
* @since 1.8
|
119 |
*
|
120 |
-
* @param string
|
121 |
-
* @param
|
122 |
-
* @param int
|
123 |
*/
|
124 |
return apply_filters( 'pll_get_new_post_translation_link', $link, $language, $post_id );
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
-
* Returns html markup for a new post translation link
|
129 |
*
|
130 |
* @since 1.8
|
131 |
*
|
132 |
-
* @param int
|
133 |
-
* @param
|
134 |
* @return string
|
135 |
*/
|
136 |
public function new_post_translation_link( $post_id, $language ) {
|
@@ -139,11 +139,11 @@ class PLL_Admin_Links extends PLL_Links {
|
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
* Returns html markup for a translation link
|
143 |
*
|
144 |
* @since 1.4
|
145 |
*
|
146 |
-
* @param int $post_id translation post id
|
147 |
* @return string
|
148 |
*/
|
149 |
public function edit_post_translation_link( $post_id ) {
|
@@ -153,14 +153,14 @@ class PLL_Admin_Links extends PLL_Links {
|
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
-
* Get the link to create a new term translation
|
157 |
*
|
158 |
* @since 1.5
|
159 |
*
|
160 |
-
* @param int
|
161 |
-
* @param string
|
162 |
-
* @param string
|
163 |
-
* @param
|
164 |
* @return string
|
165 |
*/
|
166 |
public function get_new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
@@ -179,28 +179,28 @@ class PLL_Admin_Links extends PLL_Links {
|
|
179 |
$link = add_query_arg( $args, admin_url( 'edit-tags.php' ) );
|
180 |
|
181 |
/**
|
182 |
-
*
|
183 |
*
|
184 |
* @since 1.8
|
185 |
*
|
186 |
-
* @param string
|
187 |
-
* @param
|
188 |
-
* @param int
|
189 |
-
* @param string
|
190 |
-
* @param string
|
191 |
*/
|
192 |
return apply_filters( 'pll_get_new_term_translation_link', $link, $language, $term_id, $taxonomy, $post_type );
|
193 |
}
|
194 |
|
195 |
/**
|
196 |
-
* Returns html markup for a new term translation
|
197 |
*
|
198 |
* @since 1.8
|
199 |
*
|
200 |
-
* @param int
|
201 |
-
* @param string
|
202 |
-
* @param string
|
203 |
-
* @param
|
204 |
* @return string
|
205 |
*/
|
206 |
public function new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
@@ -209,13 +209,13 @@ class PLL_Admin_Links extends PLL_Links {
|
|
209 |
}
|
210 |
|
211 |
/**
|
212 |
-
* Returns html markup for a term translation link
|
213 |
*
|
214 |
* @since 1.4
|
215 |
*
|
216 |
-
* @param
|
217 |
-
* @param string $taxonomy
|
218 |
-
* @param string $post_type
|
219 |
* @return string
|
220 |
*/
|
221 |
public function edit_term_translation_link( $term_id, $taxonomy, $post_type ) {
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Manages links related functions.
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Admin_Links extends PLL_Links {
|
12 |
|
13 |
/**
|
14 |
+
* Returns the html markup for a new translation link.
|
15 |
*
|
16 |
* @since 2.6
|
17 |
*
|
18 |
+
* @param string $link The new translation link.
|
19 |
+
* @param PLL_Language $language The language of the new translation.
|
20 |
* @return string
|
21 |
*/
|
22 |
protected function new_translation_link( $link, $language ) {
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* Returns the html markup for a translation link.
|
42 |
*
|
43 |
* @since 2.6
|
44 |
*
|
45 |
+
* @param string $link The translation link.
|
46 |
+
* @param PLL_Language $language The language of the translation.
|
47 |
* @return string
|
48 |
*/
|
49 |
public function edit_translation_link( $link, $language ) {
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
+
* Get the link to create a new post translation.
|
60 |
*
|
61 |
* @since 1.5
|
62 |
*
|
63 |
+
* @param int $post_id The source post id.
|
64 |
+
* @param PLL_Language $language The language of the new translation.
|
65 |
+
* @param string $context Optional. Defaults to 'display' which encodes '&' to '&'.
|
66 |
+
* Otherwise, preserves '&'.
|
67 |
* @return string
|
68 |
*/
|
69 |
public function get_new_post_translation_link( $post_id, $language, $context = 'display' ) {
|
70 |
$post_type = get_post_type( $post_id );
|
71 |
$post_type_object = get_post_type_object( get_post_type( $post_id ) );
|
72 |
+
if ( empty( $post_type_object ) || ! current_user_can( $post_type_object->cap->create_posts ) ) {
|
73 |
return '';
|
74 |
}
|
75 |
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
+
* Filters the new post translation link.
|
117 |
*
|
118 |
* @since 1.8
|
119 |
*
|
120 |
+
* @param string $link The new post translation link.
|
121 |
+
* @param PLL_Language $language The language of the new translation.
|
122 |
+
* @param int $post_id The source post id.
|
123 |
*/
|
124 |
return apply_filters( 'pll_get_new_post_translation_link', $link, $language, $post_id );
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
+
* Returns the html markup for a new post translation link.
|
129 |
*
|
130 |
* @since 1.8
|
131 |
*
|
132 |
+
* @param int $post_id The source post id.
|
133 |
+
* @param PLL_Language $language The language of the new translation.
|
134 |
* @return string
|
135 |
*/
|
136 |
public function new_post_translation_link( $post_id, $language ) {
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
+
* Returns the html markup for a post translation link.
|
143 |
*
|
144 |
* @since 1.4
|
145 |
*
|
146 |
+
* @param int $post_id The translation post id.
|
147 |
* @return string
|
148 |
*/
|
149 |
public function edit_post_translation_link( $post_id ) {
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
+
* Get the link to create a new term translation.
|
157 |
*
|
158 |
* @since 1.5
|
159 |
*
|
160 |
+
* @param int $term_id Source term id.
|
161 |
+
* @param string $taxonomy Taxonomy name.
|
162 |
+
* @param string $post_type Post type name.
|
163 |
+
* @param PLL_Language $language The language of the new translation.
|
164 |
* @return string
|
165 |
*/
|
166 |
public function get_new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
179 |
$link = add_query_arg( $args, admin_url( 'edit-tags.php' ) );
|
180 |
|
181 |
/**
|
182 |
+
* Filters the new term translation link.
|
183 |
*
|
184 |
* @since 1.8
|
185 |
*
|
186 |
+
* @param string $link The new term translation link.
|
187 |
+
* @param PLL_Language $language The language of the new translation.
|
188 |
+
* @param int $term_id The source term id.
|
189 |
+
* @param string $taxonomy Taxonomy name.
|
190 |
+
* @param string $post_type Post type name.
|
191 |
*/
|
192 |
return apply_filters( 'pll_get_new_term_translation_link', $link, $language, $term_id, $taxonomy, $post_type );
|
193 |
}
|
194 |
|
195 |
/**
|
196 |
+
* Returns the html markup for a new term translation.
|
197 |
*
|
198 |
* @since 1.8
|
199 |
*
|
200 |
+
* @param int $term_id Source term id.
|
201 |
+
* @param string $taxonomy Taxonomy name.
|
202 |
+
* @param string $post_type Post type name.
|
203 |
+
* @param PLL_Language $language The language of the new translation.
|
204 |
* @return string
|
205 |
*/
|
206 |
public function new_term_translation_link( $term_id, $taxonomy, $post_type, $language ) {
|
209 |
}
|
210 |
|
211 |
/**
|
212 |
+
* Returns the html markup for a term translation link.
|
213 |
*
|
214 |
* @since 1.4
|
215 |
*
|
216 |
+
* @param int $term_id Translation term id.
|
217 |
+
* @param string $taxonomy Taxonomy name.
|
218 |
+
* @param string $post_type Post type name.
|
219 |
* @return string
|
220 |
*/
|
221 |
public function edit_term_translation_link( $term_id, $taxonomy, $post_type ) {
|
admin/admin-model.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Extends the PLL_Model class with methods needed only in Polylang settings pages
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
@@ -12,23 +12,20 @@ class PLL_Admin_Model extends PLL_Model {
|
|
12 |
|
13 |
/**
|
14 |
* Adds a new language
|
15 |
-
*
|
16 |
-
*
|
17 |
-
* List of arguments that $args must contain:
|
18 |
-
* name -> language name ( used only for display )
|
19 |
-
* slug -> language code ( ideally 2-letters ISO 639-1 language code )
|
20 |
-
* locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
21 |
-
* rtl -> 1 if rtl language, 0 otherwise
|
22 |
-
* term_group -> language order when displayed
|
23 |
-
*
|
24 |
-
* Optional arguments that $args can contain:
|
25 |
-
* no_default_cat -> if set, no default category will be created for this language
|
26 |
-
* flag -> country code, see flags.php
|
27 |
*
|
28 |
* @since 1.2
|
29 |
*
|
30 |
-
* @param array $args
|
31 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
*/
|
33 |
public function add_language( $args ) {
|
34 |
$errors = $this->validate_lang( $args );
|
@@ -67,11 +64,11 @@ class PLL_Admin_Model extends PLL_Model {
|
|
67 |
$mo->export_to_db( $this->get_language( $args['slug'] ) );
|
68 |
|
69 |
/**
|
70 |
-
* Fires when a language is added
|
71 |
*
|
72 |
* @since 1.9
|
73 |
*
|
74 |
-
* @param array $args
|
75 |
*/
|
76 |
do_action( 'pll_add_language', $args );
|
77 |
|
@@ -81,11 +78,12 @@ class PLL_Admin_Model extends PLL_Model {
|
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
* Delete a language
|
85 |
*
|
86 |
* @since 1.2
|
87 |
*
|
88 |
-
* @param int $lang_id
|
|
|
89 |
*/
|
90 |
public function delete_language( $lang_id ) {
|
91 |
$lang = $this->get_language( (int) $lang_id );
|
@@ -142,7 +140,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
142 |
|
143 |
// Delete the string translations
|
144 |
$post = wpcom_vip_get_page_by_title( 'polylang_mo_' . $lang->term_id, OBJECT, 'polylang_mo' );
|
145 |
-
if (
|
146 |
wp_delete_post( $post->ID );
|
147 |
}
|
148 |
|
@@ -162,23 +160,20 @@ class PLL_Admin_Model extends PLL_Model {
|
|
162 |
}
|
163 |
|
164 |
/**
|
165 |
-
*
|
166 |
-
*
|
167 |
-
* List of arguments that $args must contain:
|
168 |
-
* lang_id -> term_id of the language to modify
|
169 |
-
* name -> language name ( used only for display )
|
170 |
-
* slug -> language code ( ideally 2-letters ISO 639-1 language code
|
171 |
-
* locale -> WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
172 |
-
* rtl -> 1 if rtl language, 0 otherwise
|
173 |
-
* term_group -> language order when displayed
|
174 |
-
*
|
175 |
-
* Optional arguments that $args can contain:
|
176 |
-
* flag -> country code, see flags.php
|
177 |
*
|
178 |
* @since 1.2
|
179 |
*
|
180 |
-
* @param array $args
|
181 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
*/
|
183 |
public function update_language( $args ) {
|
184 |
$lang = $this->get_language( (int) $args['lang_id'] );
|
@@ -243,11 +238,11 @@ class PLL_Admin_Model extends PLL_Model {
|
|
243 |
wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
|
244 |
|
245 |
/**
|
246 |
-
* Fires when a language is
|
247 |
*
|
248 |
* @since 1.9
|
249 |
*
|
250 |
-
* @param array $args
|
251 |
*/
|
252 |
do_action( 'pll_update_language', $args );
|
253 |
|
@@ -257,15 +252,15 @@ class PLL_Admin_Model extends PLL_Model {
|
|
257 |
}
|
258 |
|
259 |
/**
|
260 |
-
* Validates data entered when creating or updating a language
|
261 |
*
|
262 |
-
* @see PLL_Admin_Model::add_language()
|
263 |
*
|
264 |
* @since 0.4
|
265 |
*
|
266 |
-
* @param array
|
267 |
-
* @param
|
268 |
-
* @return
|
269 |
*/
|
270 |
protected function validate_lang( $args, $lang = null ) {
|
271 |
$errors = new WP_Error();
|
@@ -282,7 +277,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
282 |
|
283 |
// Validate slug is unique
|
284 |
foreach ( $this->get_languages_list() as $language ) {
|
285 |
-
if ( $language->slug === $args['slug'] && ( null === $lang ||
|
286 |
$errors->add( 'pll_non_unique_slug', __( 'The language code must be unique', 'polylang' ) );
|
287 |
}
|
288 |
}
|
@@ -310,21 +305,27 @@ class PLL_Admin_Model extends PLL_Model {
|
|
310 |
}
|
311 |
|
312 |
/**
|
313 |
-
*
|
314 |
*
|
315 |
* @since 1.2
|
316 |
*
|
317 |
-
* @param string
|
318 |
-
* @param
|
319 |
-
* @param
|
|
|
320 |
*/
|
321 |
public function set_language_in_mass( $type, $ids, $lang ) {
|
322 |
global $wpdb;
|
323 |
|
324 |
-
$
|
325 |
-
|
|
|
|
|
|
|
|
|
326 |
$tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
327 |
$values = array();
|
|
|
328 |
|
329 |
foreach ( $ids as $id ) {
|
330 |
$values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
|
@@ -353,12 +354,13 @@ class PLL_Admin_Model extends PLL_Model {
|
|
353 |
}
|
354 |
|
355 |
/**
|
356 |
-
*
|
357 |
*
|
358 |
* @since 1.6.3
|
359 |
*
|
360 |
-
* @param string $type
|
361 |
-
* @param array $translations
|
|
|
362 |
*/
|
363 |
public function set_translation_in_mass( $type, $translations ) {
|
364 |
global $wpdb;
|
@@ -405,13 +407,15 @@ class PLL_Admin_Model extends PLL_Model {
|
|
405 |
$terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
|
406 |
$trs = array();
|
407 |
|
408 |
-
// Prepare objects relationships
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
|
|
|
|
415 |
}
|
416 |
}
|
417 |
}
|
@@ -428,25 +432,30 @@ class PLL_Admin_Model extends PLL_Model {
|
|
428 |
}
|
429 |
|
430 |
/**
|
431 |
-
* Returns untranslated posts and terms ids ( used in settings )
|
432 |
*
|
433 |
* @since 0.9
|
434 |
-
* @since 2.2.6 Add the $limit argument
|
|
|
|
|
|
|
|
|
435 |
*
|
436 |
-
*
|
437 |
-
*
|
|
|
438 |
*/
|
439 |
public function get_objects_with_no_lang( $limit = -1 ) {
|
440 |
global $wpdb;
|
441 |
|
442 |
/**
|
443 |
-
* Filters the max number of posts or terms to return when searching objects with no language
|
444 |
* This filter can be used to decrease the memory usage in case the number of objects
|
445 |
* without language is too big. Using a negative value is equivalent to have no limit.
|
446 |
*
|
447 |
* @since 2.2.6
|
448 |
*
|
449 |
-
* @param int $limit Max number of posts or terms to retrieve from the database
|
450 |
*/
|
451 |
$limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
|
452 |
|
@@ -484,22 +493,24 @@ class PLL_Admin_Model extends PLL_Model {
|
|
484 |
// PHPCS:enable
|
485 |
|
486 |
/**
|
487 |
-
*
|
488 |
*
|
489 |
* @since 0.9
|
490 |
*
|
491 |
-
* @param
|
492 |
*/
|
493 |
return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
|
494 |
}
|
495 |
|
496 |
/**
|
497 |
-
*
|
|
|
498 |
*
|
499 |
* @since 0.5
|
500 |
*
|
501 |
-
* @param string $old_slug
|
502 |
-
* @param string $new_slug
|
|
|
503 |
*/
|
504 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
505 |
global $wpdb;
|
@@ -510,24 +521,26 @@ class PLL_Admin_Model extends PLL_Model {
|
|
510 |
$dt = array();
|
511 |
$ut = array();
|
512 |
|
513 |
-
|
514 |
-
$
|
515 |
-
|
516 |
-
|
517 |
-
if ( $
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
$
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
|
|
|
|
531 |
}
|
532 |
}
|
533 |
}
|
@@ -569,11 +582,12 @@ class PLL_Admin_Model extends PLL_Model {
|
|
569 |
|
570 |
/**
|
571 |
* Updates the default language
|
572 |
-
* taking care to update the default category & the nav menu locations
|
573 |
*
|
574 |
* @since 1.8
|
575 |
*
|
576 |
-
* @param string $slug
|
|
|
577 |
*/
|
578 |
public function update_default_lang( $slug ) {
|
579 |
// The nav menus stored in theme locations should be in the default language
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Extends the PLL_Model class with methods needed only in Polylang settings pages.
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
12 |
|
13 |
/**
|
14 |
* Adds a new language
|
15 |
+
* and creates a default category for this language.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
*
|
17 |
* @since 1.2
|
18 |
*
|
19 |
+
* @param array $args {
|
20 |
+
* @type string $name Language name ( used only for display ).
|
21 |
+
* @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
|
22 |
+
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
23 |
+
* @type int $rtl 1 if rtl language, 0 otherwise.
|
24 |
+
* @type int $term_group Language order when displayed.
|
25 |
+
* @type string $no_default_cat Optional, if set, no default category will be created for this language.
|
26 |
+
* @type string $flag Optional, country code, @see flags.php.
|
27 |
+
* }
|
28 |
+
* @return WP_Error|true true if success / WP_Error if failed.
|
29 |
*/
|
30 |
public function add_language( $args ) {
|
31 |
$errors = $this->validate_lang( $args );
|
64 |
$mo->export_to_db( $this->get_language( $args['slug'] ) );
|
65 |
|
66 |
/**
|
67 |
+
* Fires when a language is added.
|
68 |
*
|
69 |
* @since 1.9
|
70 |
*
|
71 |
+
* @param array $args Arguments used to create the language. @see PLL_Admin_Model::add_language().
|
72 |
*/
|
73 |
do_action( 'pll_add_language', $args );
|
74 |
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
+
* Delete a language.
|
82 |
*
|
83 |
* @since 1.2
|
84 |
*
|
85 |
+
* @param int $lang_id Language term_id.
|
86 |
+
* @return bool
|
87 |
*/
|
88 |
public function delete_language( $lang_id ) {
|
89 |
$lang = $this->get_language( (int) $lang_id );
|
140 |
|
141 |
// Delete the string translations
|
142 |
$post = wpcom_vip_get_page_by_title( 'polylang_mo_' . $lang->term_id, OBJECT, 'polylang_mo' );
|
143 |
+
if ( $post instanceof WP_Post ) {
|
144 |
wp_delete_post( $post->ID );
|
145 |
}
|
146 |
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
+
* Updates language properties.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
*
|
165 |
* @since 1.2
|
166 |
*
|
167 |
+
* @param array $args {
|
168 |
+
* @type int $lang_id Id of the language to modify.
|
169 |
+
* @type string $name Language name ( used only for display ).
|
170 |
+
* @type string $slug Language code ( ideally 2-letters ISO 639-1 language code ).
|
171 |
+
* @type string $locale WordPress locale. If something wrong is used for the locale, the .mo files will not be loaded...
|
172 |
+
* @type int $rtl 1 if rtl language, 0 otherwise.
|
173 |
+
* @type int $term_group Language order when displayed.
|
174 |
+
* @type string $flag Optional, country code, @see flags.php.
|
175 |
+
* }
|
176 |
+
* @return WP_Error|true true if success / WP_Error if failed.
|
177 |
*/
|
178 |
public function update_language( $args ) {
|
179 |
$lang = $this->get_language( (int) $args['lang_id'] );
|
238 |
wp_update_term( (int) $lang->tl_term_id, 'term_language', array( 'slug' => 'pll_' . $slug, 'name' => $args['name'] ) );
|
239 |
|
240 |
/**
|
241 |
+
* Fires when a language is updated.
|
242 |
*
|
243 |
* @since 1.9
|
244 |
*
|
245 |
+
* @param array $args Arguments used to modify the language. @see PLL_Admin_Model::update_language().
|
246 |
*/
|
247 |
do_action( 'pll_update_language', $args );
|
248 |
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
+
* Validates data entered when creating or updating a language.
|
256 |
*
|
257 |
+
* @see PLL_Admin_Model::add_language().
|
258 |
*
|
259 |
* @since 0.4
|
260 |
*
|
261 |
+
* @param array $args Parameters of {@see PLL_Admin_Model::add_language() or @see PLL_Admin_Model::update_language()}.
|
262 |
+
* @param PLL_Language $lang Optional the language currently updated, the language is created if not set.
|
263 |
+
* @return WP_Error
|
264 |
*/
|
265 |
protected function validate_lang( $args, $lang = null ) {
|
266 |
$errors = new WP_Error();
|
277 |
|
278 |
// Validate slug is unique
|
279 |
foreach ( $this->get_languages_list() as $language ) {
|
280 |
+
if ( $language->slug === $args['slug'] && ( null === $lang || $lang->term_id !== $language->term_id ) ) {
|
281 |
$errors->add( 'pll_non_unique_slug', __( 'The language code must be unique', 'polylang' ) );
|
282 |
}
|
283 |
}
|
305 |
}
|
306 |
|
307 |
/**
|
308 |
+
* Assigns a language to posts or terms in mass.
|
309 |
*
|
310 |
* @since 1.2
|
311 |
*
|
312 |
+
* @param string $type Either 'post' or 'term'.
|
313 |
+
* @param int[] $ids Array of post ids or term ids.
|
314 |
+
* @param PLL_Language|string $lang Language to assign to the posts or terms.
|
315 |
+
* @return void
|
316 |
*/
|
317 |
public function set_language_in_mass( $type, $ids, $lang ) {
|
318 |
global $wpdb;
|
319 |
|
320 |
+
$lang = $this->get_language( $lang );
|
321 |
+
|
322 |
+
if ( empty( $lang ) ) {
|
323 |
+
return;
|
324 |
+
}
|
325 |
+
|
326 |
$tt_id = 'term' === $type ? $lang->tl_term_taxonomy_id : $lang->term_taxonomy_id;
|
327 |
$values = array();
|
328 |
+
$ids = array_map( 'intval', $ids );
|
329 |
|
330 |
foreach ( $ids as $id ) {
|
331 |
$values[] = $wpdb->prepare( '( %d, %d )', $id, $tt_id );
|
354 |
}
|
355 |
|
356 |
/**
|
357 |
+
* Creates translations groups in mass.
|
358 |
*
|
359 |
* @since 1.6.3
|
360 |
*
|
361 |
+
* @param string $type Either 'post' or 'term'
|
362 |
+
* @param array $translations Array of translations arrays.
|
363 |
+
* @return void
|
364 |
*/
|
365 |
public function set_translation_in_mass( $type, $translations ) {
|
366 |
global $wpdb;
|
407 |
$terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
|
408 |
$trs = array();
|
409 |
|
410 |
+
// Prepare objects relationships.
|
411 |
+
if ( is_array( $terms ) ) {
|
412 |
+
foreach ( $terms as $term ) {
|
413 |
+
$t = maybe_unserialize( $term->description );
|
414 |
+
if ( in_array( $t, $translations ) ) {
|
415 |
+
foreach ( $t as $object_id ) {
|
416 |
+
if ( ! empty( $object_id ) ) {
|
417 |
+
$trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
|
418 |
+
}
|
419 |
}
|
420 |
}
|
421 |
}
|
432 |
}
|
433 |
|
434 |
/**
|
435 |
+
* Returns untranslated posts and terms ids ( used in settings ).
|
436 |
*
|
437 |
* @since 0.9
|
438 |
+
* @since 2.2.6 Add the $limit argument.
|
439 |
+
*
|
440 |
+
* @param int $limit Max number of posts or terms to return. Defaults to -1 (no limit).
|
441 |
+
* @return array {
|
442 |
+
* Objects without language.
|
443 |
*
|
444 |
+
* @type int[] $posts Array of post ids.
|
445 |
+
* @type int[] $terms Array of term ids.
|
446 |
+
* }
|
447 |
*/
|
448 |
public function get_objects_with_no_lang( $limit = -1 ) {
|
449 |
global $wpdb;
|
450 |
|
451 |
/**
|
452 |
+
* Filters the max number of posts or terms to return when searching objects with no language.
|
453 |
* This filter can be used to decrease the memory usage in case the number of objects
|
454 |
* without language is too big. Using a negative value is equivalent to have no limit.
|
455 |
*
|
456 |
* @since 2.2.6
|
457 |
*
|
458 |
+
* @param int $limit Max number of posts or terms to retrieve from the database.
|
459 |
*/
|
460 |
$limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
|
461 |
|
493 |
// PHPCS:enable
|
494 |
|
495 |
/**
|
496 |
+
* Filters the list of untranslated posts ids and terms ids
|
497 |
*
|
498 |
* @since 0.9
|
499 |
*
|
500 |
+
* @param array|false $objects false if no ids found, list of post and/or term ids otherwise.
|
501 |
*/
|
502 |
return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
|
503 |
}
|
504 |
|
505 |
/**
|
506 |
+
* Updates the translations when a language slug has been modified in settings
|
507 |
+
* or deletes them when a language is removed.
|
508 |
*
|
509 |
* @since 0.5
|
510 |
*
|
511 |
+
* @param string $old_slug The old language slug.
|
512 |
+
* @param string $new_slug Optional, the new language slug, if not set it means that the language has been deleted.
|
513 |
+
* @return void
|
514 |
*/
|
515 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
516 |
global $wpdb;
|
521 |
$dt = array();
|
522 |
$ut = array();
|
523 |
|
524 |
+
if ( is_array( $terms ) ) {
|
525 |
+
foreach ( $terms as $term ) {
|
526 |
+
$term_ids[ $term->taxonomy ][] = $term->term_id;
|
527 |
+
$tr = maybe_unserialize( $term->description );
|
528 |
+
if ( ! empty( $tr[ $old_slug ] ) ) {
|
529 |
+
if ( $new_slug ) {
|
530 |
+
$tr[ $new_slug ] = $tr[ $old_slug ]; // Suppress this for delete
|
531 |
+
} else {
|
532 |
+
$dr['id'][] = (int) $tr[ $old_slug ];
|
533 |
+
$dr['tt'][] = (int) $term->term_taxonomy_id;
|
534 |
+
}
|
535 |
+
unset( $tr[ $old_slug ] );
|
536 |
+
|
537 |
+
if ( empty( $tr ) || 1 == count( $tr ) ) {
|
538 |
+
$dt['t'][] = (int) $term->term_id;
|
539 |
+
$dt['tt'][] = (int) $term->term_taxonomy_id;
|
540 |
+
} else {
|
541 |
+
$ut['case'][] = $wpdb->prepare( 'WHEN %d THEN %s', $term->term_id, maybe_serialize( $tr ) );
|
542 |
+
$ut['in'][] = (int) $term->term_id;
|
543 |
+
}
|
544 |
}
|
545 |
}
|
546 |
}
|
582 |
|
583 |
/**
|
584 |
* Updates the default language
|
585 |
+
* taking care to update the default category & the nav menu locations.
|
586 |
*
|
587 |
* @since 1.8
|
588 |
*
|
589 |
+
* @param string $slug New language slug.
|
590 |
+
* @return void
|
591 |
*/
|
592 |
public function update_default_lang( $slug ) {
|
593 |
// The nav menus stored in theme locations should be in the default language
|
admin/admin-nav-menu.php
CHANGED
@@ -33,6 +33,8 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
33 |
* adds the language switcher metabox and create new nav menu locations
|
34 |
*
|
35 |
* @since 1.1
|
|
|
|
|
36 |
*/
|
37 |
public function admin_init() {
|
38 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
@@ -55,6 +57,8 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
55 |
* Thanks to John Morris for his very interesting post http://www.johnmorrisonline.com/how-to-add-a-fully-functional-custom-meta-box-to-wordpress-navigation-menus/
|
56 |
*
|
57 |
* @since 1.1
|
|
|
|
|
58 |
*/
|
59 |
public function lang_switch() {
|
60 |
global $_nav_menu_placeholder, $nav_menu_selected_id;
|
@@ -87,15 +91,17 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
87 |
* Prepares javascript to modify the language switcher menu item
|
88 |
*
|
89 |
* @since 1.1
|
|
|
|
|
90 |
*/
|
91 |
public function admin_enqueue_scripts() {
|
92 |
$screen = get_current_screen();
|
93 |
-
if ( 'nav-menus'
|
94 |
return;
|
95 |
}
|
96 |
|
97 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
98 |
-
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/nav-menu' . $suffix . '.js',
|
99 |
|
100 |
$data = array(
|
101 |
'strings' => PLL_Switcher::get_switcher_options( 'menu', 'string' ), // The strings for the options
|
@@ -130,6 +136,7 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
130 |
*
|
131 |
* @param int $menu_id not used
|
132 |
* @param int $menu_item_db_id
|
|
|
133 |
*/
|
134 |
public function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0 ) {
|
135 |
if ( empty( $_POST['menu-item-url'][ $menu_item_db_id ] ) || '#pll_switcher' !== $_POST['menu-item-url'][ $menu_item_db_id ] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -179,12 +186,12 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
179 |
}
|
180 |
|
181 |
/**
|
182 |
-
* Assign menu languages and translations based on ( temporary ) locations
|
183 |
*
|
184 |
* @since 1.1
|
185 |
*
|
186 |
-
* @param
|
187 |
-
* @return
|
188 |
*/
|
189 |
public function pre_update_option_theme_mods( $mods ) {
|
190 |
if ( current_user_can( 'edit_theme_options' ) && isset( $mods['nav_menu_locations'] ) ) {
|
@@ -253,6 +260,7 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
|
|
253 |
* @since 1.7.3
|
254 |
*
|
255 |
* @param int $term_id nav menu id
|
|
|
256 |
*/
|
257 |
public function delete_nav_menu( $term_id ) {
|
258 |
if ( isset( $this->options['nav_menus'] ) ) {
|
33 |
* adds the language switcher metabox and create new nav menu locations
|
34 |
*
|
35 |
* @since 1.1
|
36 |
+
*
|
37 |
+
* @return void
|
38 |
*/
|
39 |
public function admin_init() {
|
40 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
57 |
* Thanks to John Morris for his very interesting post http://www.johnmorrisonline.com/how-to-add-a-fully-functional-custom-meta-box-to-wordpress-navigation-menus/
|
58 |
*
|
59 |
* @since 1.1
|
60 |
+
*
|
61 |
+
* @return void
|
62 |
*/
|
63 |
public function lang_switch() {
|
64 |
global $_nav_menu_placeholder, $nav_menu_selected_id;
|
91 |
* Prepares javascript to modify the language switcher menu item
|
92 |
*
|
93 |
* @since 1.1
|
94 |
+
*
|
95 |
+
* @return void
|
96 |
*/
|
97 |
public function admin_enqueue_scripts() {
|
98 |
$screen = get_current_screen();
|
99 |
+
if ( empty( $screen ) || 'nav-menus' !== $screen->base ) {
|
100 |
return;
|
101 |
}
|
102 |
|
103 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
104 |
+
wp_enqueue_script( 'pll_nav_menu', plugins_url( '/js/build/nav-menu' . $suffix . '.js', POLYLANG_BASENAME ), array( 'jquery' ), POLYLANG_VERSION );
|
105 |
|
106 |
$data = array(
|
107 |
'strings' => PLL_Switcher::get_switcher_options( 'menu', 'string' ), // The strings for the options
|
136 |
*
|
137 |
* @param int $menu_id not used
|
138 |
* @param int $menu_item_db_id
|
139 |
+
* @return void
|
140 |
*/
|
141 |
public function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0 ) {
|
142 |
if ( empty( $_POST['menu-item-url'][ $menu_item_db_id ] ) || '#pll_switcher' !== $_POST['menu-item-url'][ $menu_item_db_id ] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
186 |
}
|
187 |
|
188 |
/**
|
189 |
+
* Assign menu languages and translations based on ( temporary ) locations.
|
190 |
*
|
191 |
* @since 1.1
|
192 |
*
|
193 |
+
* @param mixed $mods Theme mods.
|
194 |
+
* @return mixed
|
195 |
*/
|
196 |
public function pre_update_option_theme_mods( $mods ) {
|
197 |
if ( current_user_can( 'edit_theme_options' ) && isset( $mods['nav_menu_locations'] ) ) {
|
260 |
* @since 1.7.3
|
261 |
*
|
262 |
* @param int $term_id nav menu id
|
263 |
+
* @return void
|
264 |
*/
|
265 |
public function delete_nav_menu( $term_id ) {
|
266 |
if ( isset( $this->options['nav_menus'] ) ) {
|
admin/admin-notices.php
CHANGED
@@ -12,6 +12,18 @@
|
|
12 |
* @since 2.7 Dismissed notices are stored in an option instead of a user meta
|
13 |
*/
|
14 |
class PLL_Admin_Notices {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
private static $notices = array();
|
16 |
|
17 |
/**
|
@@ -36,17 +48,18 @@ class PLL_Admin_Notices {
|
|
36 |
*
|
37 |
* @param string $name Notice name
|
38 |
* @param string $html Content of the notice
|
|
|
39 |
*/
|
40 |
public static function add_notice( $name, $html ) {
|
41 |
self::$notices[ $name ] = $html;
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
-
* Get custom notices
|
46 |
*
|
47 |
* @since 2.3.9
|
48 |
*
|
49 |
-
* @return
|
50 |
*/
|
51 |
public static function get_notices() {
|
52 |
return self::$notices;
|
@@ -89,6 +102,11 @@ class PLL_Admin_Notices {
|
|
89 |
*/
|
90 |
protected function can_display_notice( $notice ) {
|
91 |
$screen = get_current_screen();
|
|
|
|
|
|
|
|
|
|
|
92 |
$screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
|
93 |
|
94 |
/**
|
@@ -121,6 +139,7 @@ class PLL_Admin_Notices {
|
|
121 |
* @since 2.3.9
|
122 |
*
|
123 |
* @param string $notice
|
|
|
124 |
*/
|
125 |
public static function dismiss( $notice ) {
|
126 |
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
@@ -135,6 +154,8 @@ class PLL_Admin_Notices {
|
|
135 |
* Handle a click on the dismiss button
|
136 |
*
|
137 |
* @since 2.3.9
|
|
|
|
|
138 |
*/
|
139 |
public function hide_notice() {
|
140 |
if ( isset( $_GET['pll-hide-notice'], $_GET['_pll_notice_nonce'] ) ) {
|
@@ -150,6 +171,8 @@ class PLL_Admin_Notices {
|
|
150 |
* Displays notices
|
151 |
*
|
152 |
* @since 2.3.9
|
|
|
|
|
153 |
*/
|
154 |
public function display_notices() {
|
155 |
if ( current_user_can( 'manage_options' ) ) {
|
@@ -184,6 +207,7 @@ class PLL_Admin_Notices {
|
|
184 |
* @since 2.3.9
|
185 |
*
|
186 |
* @param string $name Notice name
|
|
|
187 |
*/
|
188 |
public function dismiss_button( $name ) {
|
189 |
printf(
|
@@ -198,6 +222,8 @@ class PLL_Admin_Notices {
|
|
198 |
* Displays a notice if WooCommerce is activated without Polylang for WooCommerce
|
199 |
*
|
200 |
* @since 2.3.9
|
|
|
|
|
201 |
*/
|
202 |
private function pllwc_notice() {
|
203 |
?>
|
@@ -221,6 +247,8 @@ class PLL_Admin_Notices {
|
|
221 |
* Displays a notice asking for a review
|
222 |
*
|
223 |
* @since 2.3.9
|
|
|
|
|
224 |
*/
|
225 |
private function review_notice() {
|
226 |
?>
|
12 |
* @since 2.7 Dismissed notices are stored in an option instead of a user meta
|
13 |
*/
|
14 |
class PLL_Admin_Notices {
|
15 |
+
/**
|
16 |
+
* Stores the plugin options.
|
17 |
+
*
|
18 |
+
* @var array
|
19 |
+
*/
|
20 |
+
protected $options;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Stores custom notices.
|
24 |
+
*
|
25 |
+
* @var string[]
|
26 |
+
*/
|
27 |
private static $notices = array();
|
28 |
|
29 |
/**
|
48 |
*
|
49 |
* @param string $name Notice name
|
50 |
* @param string $html Content of the notice
|
51 |
+
* @return void
|
52 |
*/
|
53 |
public static function add_notice( $name, $html ) {
|
54 |
self::$notices[ $name ] = $html;
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
+
* Get custom notices.
|
59 |
*
|
60 |
* @since 2.3.9
|
61 |
*
|
62 |
+
* @return string[]
|
63 |
*/
|
64 |
public static function get_notices() {
|
65 |
return self::$notices;
|
102 |
*/
|
103 |
protected function can_display_notice( $notice ) {
|
104 |
$screen = get_current_screen();
|
105 |
+
|
106 |
+
if ( empty( $screen ) ) {
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
|
110 |
$screen_id = sanitize_title( __( 'Languages', 'polylang' ) );
|
111 |
|
112 |
/**
|
139 |
* @since 2.3.9
|
140 |
*
|
141 |
* @param string $notice
|
142 |
+
* @return void
|
143 |
*/
|
144 |
public static function dismiss( $notice ) {
|
145 |
$dismissed = get_option( 'pll_dismissed_notices', array() );
|
154 |
* Handle a click on the dismiss button
|
155 |
*
|
156 |
* @since 2.3.9
|
157 |
+
*
|
158 |
+
* @return void
|
159 |
*/
|
160 |
public function hide_notice() {
|
161 |
if ( isset( $_GET['pll-hide-notice'], $_GET['_pll_notice_nonce'] ) ) {
|
171 |
* Displays notices
|
172 |
*
|
173 |
* @since 2.3.9
|
174 |
+
*
|
175 |
+
* @return void
|
176 |
*/
|
177 |
public function display_notices() {
|
178 |
if ( current_user_can( 'manage_options' ) ) {
|
207 |
* @since 2.3.9
|
208 |
*
|
209 |
* @param string $name Notice name
|
210 |
+
* @return void
|
211 |
*/
|
212 |
public function dismiss_button( $name ) {
|
213 |
printf(
|
222 |
* Displays a notice if WooCommerce is activated without Polylang for WooCommerce
|
223 |
*
|
224 |
* @since 2.3.9
|
225 |
+
*
|
226 |
+
* @return void
|
227 |
*/
|
228 |
private function pllwc_notice() {
|
229 |
?>
|
247 |
* Displays a notice asking for a review
|
248 |
*
|
249 |
* @since 2.3.9
|
250 |
+
*
|
251 |
+
* @return void
|
252 |
*/
|
253 |
private function review_notice() {
|
254 |
?>
|
admin/admin-static-pages.php
CHANGED
@@ -9,6 +9,9 @@
|
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
|
|
|
|
|
12 |
protected $links;
|
13 |
|
14 |
/**
|
@@ -33,10 +36,6 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
33 |
// Refresh language cache when a static front page has been translated
|
34 |
add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 10, 3 );
|
35 |
|
36 |
-
// Checks if chosen page on front is translated
|
37 |
-
add_filter( 'pre_update_option_page_on_front', array( $this, 'update_page_on_front' ), 10, 2 );
|
38 |
-
add_filter( 'customize_validate_page_on_front', array( $this, 'customize_validate_page_on_front' ), 10, 2 );
|
39 |
-
|
40 |
// Prevents WP resetting the option
|
41 |
add_filter( 'pre_update_option_show_on_front', array( $this, 'update_show_on_front' ), 10, 2 );
|
42 |
|
@@ -65,13 +64,14 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
-
* Removes the editor for translations of the pages for posts
|
69 |
-
* Removes the page template select dropdown in page attributes metabox too
|
70 |
*
|
71 |
* @since 2.2.2
|
72 |
*
|
73 |
-
* @param string
|
74 |
-
* @param
|
|
|
75 |
*/
|
76 |
public function add_meta_boxes( $post_type, $post ) {
|
77 |
if ( 'page' === $post_type ) {
|
@@ -85,13 +85,13 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
-
*
|
89 |
*
|
90 |
* @since 1.8
|
91 |
*
|
92 |
-
* @param
|
93 |
-
* @param
|
94 |
-
* @return
|
95 |
*/
|
96 |
public function display_post_states( $post_states, $post ) {
|
97 |
if ( in_array( $post->ID, $this->model->get_languages_list( array( 'fields' => 'page_on_front' ) ) ) ) {
|
@@ -106,13 +106,14 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
*
|
110 |
*
|
111 |
* @since 1.8
|
112 |
*
|
113 |
-
* @param int
|
114 |
-
* @param
|
115 |
-
* @param
|
|
|
116 |
*/
|
117 |
public function pll_save_post( $post_id, $post, $translations ) {
|
118 |
if ( in_array( $this->page_on_front, $translations ) ) {
|
@@ -120,63 +121,6 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
120 |
}
|
121 |
}
|
122 |
|
123 |
-
/**
|
124 |
-
* Checks if a page is translated in all languages
|
125 |
-
*
|
126 |
-
* @since 2.2
|
127 |
-
*
|
128 |
-
* @param int $page_id
|
129 |
-
* @return bool
|
130 |
-
*/
|
131 |
-
protected function is_page_translated( $page_id ) {
|
132 |
-
if ( $page_id ) {
|
133 |
-
$translations = count( $this->model->post->get_translations( $page_id ) );
|
134 |
-
$languages = count( $this->model->get_languages_list() );
|
135 |
-
|
136 |
-
if ( $languages > 1 && $translations != $languages ) {
|
137 |
-
return false;
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
return true;
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Prevents choosing an untranslated static front page
|
146 |
-
* Displays an error message
|
147 |
-
*
|
148 |
-
* @since 1.6
|
149 |
-
*
|
150 |
-
* @param int $page_id New page on front page id
|
151 |
-
* @param int $old_id Old page on front page_id
|
152 |
-
* @return int
|
153 |
-
*/
|
154 |
-
public function update_page_on_front( $page_id, $old_id ) {
|
155 |
-
if ( ! $this->is_page_translated( $page_id ) ) {
|
156 |
-
$page_id = $old_id;
|
157 |
-
add_settings_error( 'reading', 'pll_page_on_front_error', __( 'The chosen static front page must be translated in all languages.', 'polylang' ) );
|
158 |
-
}
|
159 |
-
|
160 |
-
return $page_id;
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Displays an error message in the customizer when choosing an untranslated static front page
|
165 |
-
*
|
166 |
-
* @since 2.2
|
167 |
-
*
|
168 |
-
* @param object $validity WP_Error object
|
169 |
-
* @param int $page_id New page on front page id
|
170 |
-
* @return object
|
171 |
-
*/
|
172 |
-
public function customize_validate_page_on_front( $validity, $page_id ) {
|
173 |
-
if ( ! $this->is_page_translated( $page_id ) ) {
|
174 |
-
return new WP_Error( 'pll_page_on_front_error', __( 'The chosen static front page must be translated in all languages.', 'polylang' ) );
|
175 |
-
}
|
176 |
-
|
177 |
-
return $validity;
|
178 |
-
}
|
179 |
-
|
180 |
/**
|
181 |
* Prevents WP resetting the option if the admin language filter is active for a language with no pages
|
182 |
*
|
@@ -199,11 +143,13 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
199 |
* The notice is not dismissible and displayed on the Languages pages and the list of pages.
|
200 |
*
|
201 |
* @since 2.6
|
|
|
|
|
202 |
*/
|
203 |
public function notice_must_translate() {
|
204 |
$screen = get_current_screen();
|
205 |
|
206 |
-
if ( 'toplevel_page_mlang' === $screen->id || 'edit-page' === $screen->id ) {
|
207 |
$message = $this->get_must_translate_message();
|
208 |
|
209 |
if ( ! empty( $message ) ) {
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
12 |
+
/**
|
13 |
+
* @var PLL_Admin_Links
|
14 |
+
*/
|
15 |
protected $links;
|
16 |
|
17 |
/**
|
36 |
// Refresh language cache when a static front page has been translated
|
37 |
add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 10, 3 );
|
38 |
|
|
|
|
|
|
|
|
|
39 |
// Prevents WP resetting the option
|
40 |
add_filter( 'pre_update_option_show_on_front', array( $this, 'update_show_on_front' ), 10, 2 );
|
41 |
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
+
* Removes the editor for the translations of the pages for posts.
|
68 |
+
* Removes the page template select dropdown in page attributes metabox too.
|
69 |
*
|
70 |
* @since 2.2.2
|
71 |
*
|
72 |
+
* @param string $post_type Current post type.
|
73 |
+
* @param WP_Post $post Current post.
|
74 |
+
* @return void
|
75 |
*/
|
76 |
public function add_meta_boxes( $post_type, $post ) {
|
77 |
if ( 'page' === $post_type ) {
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
+
* Adds post state for translations of the front page and posts page.
|
89 |
*
|
90 |
* @since 1.8
|
91 |
*
|
92 |
+
* @param string[] $post_states An array of post display states.
|
93 |
+
* @param WP_Post $post The current post object.
|
94 |
+
* @return string[]
|
95 |
*/
|
96 |
public function display_post_states( $post_states, $post ) {
|
97 |
if ( in_array( $post->ID, $this->model->get_languages_list( array( 'fields' => 'page_on_front' ) ) ) ) {
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
+
* Refreshes the language cache when a static front page has been translated.
|
110 |
*
|
111 |
* @since 1.8
|
112 |
*
|
113 |
+
* @param int $post_id Not used.
|
114 |
+
* @param WP_Post $post Not used.
|
115 |
+
* @param int[] $translations Translations of the post being saved.
|
116 |
+
* @return void
|
117 |
*/
|
118 |
public function pll_save_post( $post_id, $post, $translations ) {
|
119 |
if ( in_array( $this->page_on_front, $translations ) ) {
|
121 |
}
|
122 |
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
/**
|
125 |
* Prevents WP resetting the option if the admin language filter is active for a language with no pages
|
126 |
*
|
143 |
* The notice is not dismissible and displayed on the Languages pages and the list of pages.
|
144 |
*
|
145 |
* @since 2.6
|
146 |
+
*
|
147 |
+
* @return void
|
148 |
*/
|
149 |
public function notice_must_translate() {
|
150 |
$screen = get_current_screen();
|
151 |
|
152 |
+
if ( ! empty( $screen ) && ( 'toplevel_page_mlang' === $screen->id || 'edit-page' === $screen->id ) ) {
|
153 |
$message = $this->get_must_translate_message();
|
154 |
|
155 |
if ( ! empty( $message ) ) {
|
admin/admin-strings.php
CHANGED
@@ -9,13 +9,31 @@
|
|
9 |
* @since 1.6
|
10 |
*/
|
11 |
class PLL_Admin_Strings {
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Add filters
|
17 |
*
|
18 |
* @since 1.6
|
|
|
|
|
19 |
*/
|
20 |
public static function init() {
|
21 |
// default strings translations sanitization
|
@@ -31,14 +49,9 @@ class PLL_Admin_Strings {
|
|
31 |
* @param string $string The string to register
|
32 |
* @param string $context Optional, the group in which the string is registered, defaults to 'polylang'
|
33 |
* @param bool $multiline Optional, whether the string table should display a multiline textarea or a single line input, defaults to single line
|
|
|
34 |
*/
|
35 |
public static function register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
36 |
-
// Backward compatibility with Polylang older than 1.1
|
37 |
-
if ( is_bool( $context ) ) {
|
38 |
-
$multiline = $context;
|
39 |
-
$context = 'Polylang';
|
40 |
-
}
|
41 |
-
|
42 |
if ( $string && is_scalar( $string ) ) {
|
43 |
self::$strings[ md5( $string ) ] = compact( 'name', 'string', 'context', 'multiline' );
|
44 |
}
|
9 |
* @since 1.6
|
10 |
*/
|
11 |
class PLL_Admin_Strings {
|
12 |
+
/**
|
13 |
+
* Stores the strings to translate.
|
14 |
+
*
|
15 |
+
* @var array {
|
16 |
+
* @type string $name A unique name for the string.
|
17 |
+
* @type string $string The actual string to translate.
|
18 |
+
* @type string $context The group in which the string is registered.
|
19 |
+
* @type bool $multiline Whether the string table should display a multiline textarea or a single line input.
|
20 |
+
* }
|
21 |
+
*/
|
22 |
+
protected static $strings = array();
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The strings to register by default.
|
26 |
+
*
|
27 |
+
* @var string[]
|
28 |
+
*/
|
29 |
+
protected static $default_strings;
|
30 |
|
31 |
/**
|
32 |
* Add filters
|
33 |
*
|
34 |
* @since 1.6
|
35 |
+
*
|
36 |
+
* @return void
|
37 |
*/
|
38 |
public static function init() {
|
39 |
// default strings translations sanitization
|
49 |
* @param string $string The string to register
|
50 |
* @param string $context Optional, the group in which the string is registered, defaults to 'polylang'
|
51 |
* @param bool $multiline Optional, whether the string table should display a multiline textarea or a single line input, defaults to single line
|
52 |
+
* @return void
|
53 |
*/
|
54 |
public static function register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
if ( $string && is_scalar( $string ) ) {
|
56 |
self::$strings[ md5( $string ) ] = compact( 'name', 'string', 'context', 'multiline' );
|
57 |
}
|
admin/admin.php
CHANGED
@@ -4,79 +4,37 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
*
|
8 |
-
* accessible in $polylang global object
|
9 |
-
*
|
10 |
-
* Properties:
|
11 |
-
* options => inherited, reference to Polylang options array
|
12 |
-
* model => inherited, reference to PLL_Model object
|
13 |
-
* links_model => inherited, reference to PLL_Links_Model object
|
14 |
-
* links => inherited, reference to PLL_Admin_Links object
|
15 |
-
* static_pages => inherited, reference to PLL_Admin_Static_Pages object
|
16 |
-
* filters_links => inherited, reference to PLL_Filters_Links object
|
17 |
-
* curlang => inherited, optional, current language used to filter the content (language of the post or term being edited, equal to filter_lang otherwise)
|
18 |
-
* filter_lang => inherited, optional, current status of the admin languages filter (in the admin bar)
|
19 |
-
* pref_lang => inherited, preferred language used as default when saving posts or terms
|
20 |
-
* posts => reference to PLL_CRUD_Posts object
|
21 |
-
* terms => reference to PLL_CRUD_Terms object
|
22 |
-
* filters => reference to PLL_Admin_Filters object
|
23 |
-
* filters_sanitization => reference to PLL_Filters_Sanitization object
|
24 |
-
* filters_columns => reference to PLL_Admin_Filters_Columns object
|
25 |
-
* filters_post => reference to PLL_Admin_Filters_Post object
|
26 |
-
* filters_term => reference to PLL_Admin_filters_Term object
|
27 |
-
* nav_menu => reference to PLL_Admin_Nav_Menu object
|
28 |
-
* block_editor => reference to PLL_Admin_Block_Editor object
|
29 |
-
* classic_editor => reference to PLL_Admin_Classic_Editor object
|
30 |
-
* filters_media => optional, reference to PLL_Admin_Filters_Media object
|
31 |
*
|
32 |
* @since 1.2
|
33 |
*/
|
34 |
class PLL_Admin extends PLL_Admin_Base {
|
35 |
/**
|
36 |
-
* Instance of PLL_Admin_Filters
|
37 |
-
*
|
38 |
* @var PLL_Admin_Filters
|
39 |
*/
|
40 |
public $filters;
|
41 |
|
42 |
/**
|
43 |
-
* Instance of PLL_Admin_Filters_Columns
|
44 |
-
*
|
45 |
* @var PLL_Admin_Filters_Columns
|
46 |
*/
|
47 |
public $filters_columns;
|
48 |
|
49 |
/**
|
50 |
-
* Instance of PLL_Admin_Filters_Post
|
51 |
-
*
|
52 |
* @var PLL_Admin_Filters_Post
|
53 |
*/
|
54 |
public $filters_post;
|
55 |
|
56 |
/**
|
57 |
-
*
|
58 |
-
*
|
59 |
-
* @var PLL_Admin_filters_Term
|
60 |
*/
|
61 |
public $filters_term;
|
62 |
|
63 |
/**
|
64 |
-
* Instance of PLL_Admin_Nav_Menu
|
65 |
-
*
|
66 |
-
* @var PLL_Admin_Nav_Menu
|
67 |
-
*/
|
68 |
-
public $nav_menu;
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Instance of PLL_Admin_Filters_Media
|
72 |
-
*
|
73 |
* @var PLL_Admin_Filters_Media
|
74 |
*/
|
75 |
public $filters_media;
|
76 |
|
77 |
/**
|
78 |
-
* Instance of PLL_Filters_Sanitization
|
79 |
-
*
|
80 |
* @since 2.9
|
81 |
*
|
82 |
* @var PLL_Filters_Sanitization
|
@@ -84,12 +42,31 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
84 |
public $filters_sanitization;
|
85 |
|
86 |
/**
|
87 |
-
*
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
*
|
90 |
* @since 1.2
|
91 |
*
|
92 |
-
* @param
|
93 |
*/
|
94 |
public function __construct( &$links_model ) {
|
95 |
parent::__construct( $links_model );
|
@@ -116,12 +93,12 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
116 |
}
|
117 |
|
118 |
/**
|
119 |
-
* Adds a 'settings' link in the plugins table
|
120 |
*
|
121 |
* @since 0.1
|
122 |
*
|
123 |
-
* @param
|
124 |
-
* @return
|
125 |
*/
|
126 |
public function plugin_action_links( $links ) {
|
127 |
array_unshift( $links, '<a href="admin.php?page=mlang">' . __( 'Settings', 'polylang' ) . '</a>' );
|
@@ -135,6 +112,7 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
135 |
*
|
136 |
* @param array $plugin_data Not used
|
137 |
* @param object $r Plugin update data
|
|
|
138 |
*/
|
139 |
public function plugin_update_message( $plugin_data, $r ) {
|
140 |
if ( isset( $r->upgrade_notice ) ) {
|
@@ -147,9 +125,12 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
147 |
*
|
148 |
* @since 1.2
|
149 |
* @since 2.7 instantiate a PLL_Bulk_Translate instance.
|
|
|
150 |
*/
|
151 |
public function add_filters() {
|
152 |
$this->filters_sanitization = new PLL_Filters_Sanitization( $this->get_locale_for_sanitization() );
|
|
|
|
|
153 |
// All these are separated just for convenience and maintainability
|
154 |
$classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Classic_Editor', 'Block_Editor' );
|
155 |
|
@@ -172,6 +153,7 @@ class PLL_Admin extends PLL_Admin_Base {
|
|
172 |
$this->$obj = new $class( $this );
|
173 |
}
|
174 |
}
|
|
|
175 |
/**
|
176 |
* Retrieve the locale according to the current language instead of the language
|
177 |
* of the admin interface.
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Main Polylang class for admin (except Polylang pages), accessible from @see PLL().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Admin extends PLL_Admin_Base {
|
12 |
/**
|
|
|
|
|
13 |
* @var PLL_Admin_Filters
|
14 |
*/
|
15 |
public $filters;
|
16 |
|
17 |
/**
|
|
|
|
|
18 |
* @var PLL_Admin_Filters_Columns
|
19 |
*/
|
20 |
public $filters_columns;
|
21 |
|
22 |
/**
|
|
|
|
|
23 |
* @var PLL_Admin_Filters_Post
|
24 |
*/
|
25 |
public $filters_post;
|
26 |
|
27 |
/**
|
28 |
+
* @var PLL_Admin_Filters_Term
|
|
|
|
|
29 |
*/
|
30 |
public $filters_term;
|
31 |
|
32 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
* @var PLL_Admin_Filters_Media
|
34 |
*/
|
35 |
public $filters_media;
|
36 |
|
37 |
/**
|
|
|
|
|
38 |
* @since 2.9
|
39 |
*
|
40 |
* @var PLL_Filters_Sanitization
|
42 |
public $filters_sanitization;
|
43 |
|
44 |
/**
|
45 |
+
* @var PLL_Admin_Block_Editor
|
46 |
+
*/
|
47 |
+
public $block_editor;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @var PLL_Admin_Classic_Editor
|
51 |
+
*/
|
52 |
+
public $classic_editor;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @var PLL_Admin_Nav_Menu
|
56 |
+
*/
|
57 |
+
public $nav_menu;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @var PLL_Admin_Filters_Widgets_Options
|
61 |
+
*/
|
62 |
+
public $filters_widgets;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Setups filters and action needed on all admin pages and on plugins page.
|
66 |
*
|
67 |
* @since 1.2
|
68 |
*
|
69 |
+
* @param PLL_Links_Model $links_model Reference to the links model.
|
70 |
*/
|
71 |
public function __construct( &$links_model ) {
|
72 |
parent::__construct( $links_model );
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
+
* Adds a 'settings' link for our plugin in the plugins list table.
|
97 |
*
|
98 |
* @since 0.1
|
99 |
*
|
100 |
+
* @param string[] $links List of links associated to the plugin.
|
101 |
+
* @return string[] Modified list of links.
|
102 |
*/
|
103 |
public function plugin_action_links( $links ) {
|
104 |
array_unshift( $links, '<a href="admin.php?page=mlang">' . __( 'Settings', 'polylang' ) . '</a>' );
|
112 |
*
|
113 |
* @param array $plugin_data Not used
|
114 |
* @param object $r Plugin update data
|
115 |
+
* @return void
|
116 |
*/
|
117 |
public function plugin_update_message( $plugin_data, $r ) {
|
118 |
if ( isset( $r->upgrade_notice ) ) {
|
125 |
*
|
126 |
* @since 1.2
|
127 |
* @since 2.7 instantiate a PLL_Bulk_Translate instance.
|
128 |
+
* @return void
|
129 |
*/
|
130 |
public function add_filters() {
|
131 |
$this->filters_sanitization = new PLL_Filters_Sanitization( $this->get_locale_for_sanitization() );
|
132 |
+
$this->filters_widgets = new PLL_Admin_Filters_Widgets_Options( $this );
|
133 |
+
|
134 |
// All these are separated just for convenience and maintainability
|
135 |
$classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Classic_Editor', 'Block_Editor' );
|
136 |
|
153 |
$this->$obj = new $class( $this );
|
154 |
}
|
155 |
}
|
156 |
+
|
157 |
/**
|
158 |
* Retrieve the locale according to the current language instead of the language
|
159 |
* of the admin interface.
|
css/admin.css
CHANGED
@@ -376,11 +376,6 @@
|
|
376 |
}
|
377 |
|
378 |
/* strings translations table */
|
379 |
-
.stringstranslations .column-context,
|
380 |
-
.stringstranslations .column-name {
|
381 |
-
display: none; /* backward compatibility WP < 4.3 */
|
382 |
-
}
|
383 |
-
|
384 |
.translation label {
|
385 |
display: block;
|
386 |
width: 95%;
|
376 |
}
|
377 |
|
378 |
/* strings translations table */
|
|
|
|
|
|
|
|
|
|
|
379 |
.translation label {
|
380 |
display: block;
|
381 |
width: 95%;
|
css/admin.min.css
DELETED
@@ -1 +0,0 @@
|
|
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{display:flex}@media screen and (max-width:782px){.translation{display:block}}.translation textarea{display:block}.translation input,.translation textarea{width:72%;box-sizing:border-box;margin-bottom:4px}.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}.wp-list-table td[class*=column-language_],.wp-list-table th[class*=column-language_]{width:1.5em;box-sizing:content-box}.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-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_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}.languages_page_mlang_strings .metabox-holder>div{display:flex}.languages_page_mlang_strings .metabox-holder>div>div{flex-grow:1}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:1rem}.languages_page_mlang_strings .metabox-holder>div>div.closed{border:0;background:0 0}.languages_page_mlang_strings .metabox-holder>div>div.closed .postbox-header{border:1px solid #ccd0d4;background:#fff}@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,.translation textarea{width:95%}.languages_page_mlang_strings .metabox-holder>div{flex-direction:column}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:0}#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/build/admin.css
ADDED
@@ -0,0 +1,457 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* languages admin panel */
|
2 |
+
#add-lang select {
|
3 |
+
width: 95%;
|
4 |
+
}
|
5 |
+
|
6 |
+
.column-locale,
|
7 |
+
.languages .column-slug {
|
8 |
+
width : 15%
|
9 |
+
}
|
10 |
+
|
11 |
+
.column-default_lang {
|
12 |
+
width : 5%;
|
13 |
+
}
|
14 |
+
|
15 |
+
.column-term_group,
|
16 |
+
.column-flag, .column-count {
|
17 |
+
width : 10%;
|
18 |
+
}
|
19 |
+
|
20 |
+
.icon-default-lang:before {
|
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;
|
35 |
+
margin-right: 2px;
|
36 |
+
}
|
37 |
+
|
38 |
+
/* about Polylang metabox */
|
39 |
+
#pll-about-box p,
|
40 |
+
#pll-recommended p {
|
41 |
+
text-align: justify;
|
42 |
+
}
|
43 |
+
|
44 |
+
#pll-about-box input {
|
45 |
+
margin: 0;
|
46 |
+
padding: 0;
|
47 |
+
float: right;
|
48 |
+
}
|
49 |
+
|
50 |
+
/* strings translation table */
|
51 |
+
.stringstranslations .column-name,
|
52 |
+
.stringstranslations .column-context {
|
53 |
+
width: 10%;
|
54 |
+
}
|
55 |
+
|
56 |
+
.stringstranslations .column-string {
|
57 |
+
width: 33%;
|
58 |
+
}
|
59 |
+
|
60 |
+
.translation label {
|
61 |
+
display: inline-block;
|
62 |
+
width: 23%;
|
63 |
+
vertical-align: top;
|
64 |
+
}
|
65 |
+
|
66 |
+
.translation {
|
67 |
+
display: flex; /* fix #691 to remove default margin bottom */
|
68 |
+
}
|
69 |
+
@media screen and (max-width: 782px) { /* reset default display property for small device */
|
70 |
+
.translation{
|
71 |
+
display: block;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
.translation textarea{
|
75 |
+
display: block; /* fix #691 to remove default margin bottom */
|
76 |
+
}
|
77 |
+
.translation input,
|
78 |
+
.translation textarea {
|
79 |
+
width: 72%;
|
80 |
+
box-sizing: border-box; /* to be sure field don't overrun outside their wrapper */
|
81 |
+
margin-bottom: 4px; /* fix #691 set the same margin bottom for both textarea and input tags */
|
82 |
+
}
|
83 |
+
|
84 |
+
/* settings */
|
85 |
+
.pll-settings {
|
86 |
+
margin-top: 20px;
|
87 |
+
}
|
88 |
+
|
89 |
+
.pll-settings .plugin-title {
|
90 |
+
width: 25%;
|
91 |
+
}
|
92 |
+
|
93 |
+
#wpbody-content .pll-settings .pll-configure tr {
|
94 |
+
display: table-row;
|
95 |
+
}
|
96 |
+
|
97 |
+
#wpbody-content .pll-settings .pll-configure td {
|
98 |
+
display: table-cell;
|
99 |
+
}
|
100 |
+
|
101 |
+
#wpbody-content .pll-settings .pll-configure > td {
|
102 |
+
padding: 20px 20px 20px 40px;
|
103 |
+
}
|
104 |
+
|
105 |
+
.pll-configure legend {
|
106 |
+
font-size: 14px;
|
107 |
+
font-weight: 600;
|
108 |
+
margin-bottom: 0.5em;
|
109 |
+
}
|
110 |
+
|
111 |
+
.pll-configure td .description {
|
112 |
+
margin-top: 2px;
|
113 |
+
margin-bottom: 0.5em;
|
114 |
+
}
|
115 |
+
|
116 |
+
.pll-configure p.submit {
|
117 |
+
margin-top: 20px;
|
118 |
+
}
|
119 |
+
|
120 |
+
.pll-configure .button {
|
121 |
+
margin-right: 20px;
|
122 |
+
}
|
123 |
+
|
124 |
+
.pll-configure fieldset {
|
125 |
+
margin-bottom: 1.5em;
|
126 |
+
}
|
127 |
+
|
128 |
+
.pll-inline-block-list {
|
129 |
+
margin: 0;
|
130 |
+
}
|
131 |
+
|
132 |
+
.pll-inline-block-list li {
|
133 |
+
display: inline-block;
|
134 |
+
margin: 0;
|
135 |
+
width: 250px;
|
136 |
+
}
|
137 |
+
|
138 |
+
/* settings URL modifications */
|
139 |
+
#pll-domains-table td {
|
140 |
+
padding: 2px 2px 2px 1.5em;
|
141 |
+
-webkit-box-shadow: none;
|
142 |
+
box-shadow: none;
|
143 |
+
border: none;
|
144 |
+
}
|
145 |
+
|
146 |
+
.pll-settings-url-col {
|
147 |
+
display: inline-block;
|
148 |
+
width: 49%;
|
149 |
+
vertical-align: top;
|
150 |
+
}
|
151 |
+
|
152 |
+
/* settings Activation keys */
|
153 |
+
#pll-licenses-table td {
|
154 |
+
vertical-align: top;
|
155 |
+
}
|
156 |
+
|
157 |
+
#pll-licenses-table label {
|
158 |
+
font-size: 1em;
|
159 |
+
font-weight: 600;
|
160 |
+
}
|
161 |
+
|
162 |
+
.pll-configure .pll-deactivate-license {
|
163 |
+
margin: 0 0 0 20px;
|
164 |
+
}
|
165 |
+
|
166 |
+
/* language columns in edit.php and edit-tags.php */
|
167 |
+
.wp-list-table th[class*='column-language_'],
|
168 |
+
.wp-list-table td[class*='column-language_'] {
|
169 |
+
width: 1.5em;
|
170 |
+
box-sizing: content-box; /* Override ACF 5.9.0 styles */
|
171 |
+
}
|
172 |
+
|
173 |
+
/* Text direction in post.php and edit-tags.php */
|
174 |
+
.pll-dir-rtl textarea,
|
175 |
+
.pll-dir-rtl input[type="text"] {
|
176 |
+
direction: rtl;
|
177 |
+
}
|
178 |
+
|
179 |
+
.pll-dir-ltr textarea,
|
180 |
+
.pll-dir-ltr input[type="text"] {
|
181 |
+
direction: ltr;
|
182 |
+
}
|
183 |
+
|
184 |
+
.pll-dir-ltr .tr_lang,
|
185 |
+
.pll-dir-rtl .tr_lang {
|
186 |
+
direction: inherit;
|
187 |
+
}
|
188 |
+
|
189 |
+
/* languages metabox in post.php */
|
190 |
+
#post-translations p {
|
191 |
+
float: left;
|
192 |
+
}
|
193 |
+
|
194 |
+
#post-translations table {
|
195 |
+
table-layout: fixed;
|
196 |
+
width: 100%;
|
197 |
+
clear: both;
|
198 |
+
}
|
199 |
+
|
200 |
+
#post-translations a {
|
201 |
+
text-decoration: none;
|
202 |
+
}
|
203 |
+
|
204 |
+
#post-translations .pll-language-column,
|
205 |
+
#post-translations .pll-column-icon {
|
206 |
+
width: 20px;
|
207 |
+
}
|
208 |
+
|
209 |
+
#post-translations .tr_lang {
|
210 |
+
width: 100%;
|
211 |
+
}
|
212 |
+
|
213 |
+
#post-translations td {
|
214 |
+
padding: 2px;
|
215 |
+
}
|
216 |
+
|
217 |
+
#post-translations .spinner,
|
218 |
+
#term-translations .spinner {
|
219 |
+
float: none;
|
220 |
+
margin: 0;
|
221 |
+
background-position: center;
|
222 |
+
width: auto;
|
223 |
+
}
|
224 |
+
|
225 |
+
.pll-column-icon {
|
226 |
+
text-align: center;
|
227 |
+
}
|
228 |
+
|
229 |
+
#select-post-language .pll-select-flag {
|
230 |
+
padding: 4px;
|
231 |
+
margin-right: 32px;
|
232 |
+
}
|
233 |
+
|
234 |
+
/* specific cases for media */
|
235 |
+
#select-media-language .pll-select-flag {
|
236 |
+
padding: 4px;
|
237 |
+
margin-right: 10px;
|
238 |
+
}
|
239 |
+
|
240 |
+
.pll-media-edit-column {
|
241 |
+
float: right;
|
242 |
+
}
|
243 |
+
|
244 |
+
/* language and translations in edit-tags.php */
|
245 |
+
.pll-translation-flag { /* also for media */
|
246 |
+
margin-right: 14px;
|
247 |
+
}
|
248 |
+
|
249 |
+
#select-add-term-language .pll-select-flag {
|
250 |
+
padding: 11px;
|
251 |
+
margin-right: 13px;
|
252 |
+
}
|
253 |
+
|
254 |
+
#select-edit-term-language .pll-select-flag {
|
255 |
+
padding: 11px;
|
256 |
+
margin-right: 4px;
|
257 |
+
}
|
258 |
+
|
259 |
+
#term-translations p {
|
260 |
+
/* same style as label */
|
261 |
+
font-weight: 400;
|
262 |
+
font-style: normal;
|
263 |
+
padding: 2px;
|
264 |
+
color: #23282d;
|
265 |
+
}
|
266 |
+
|
267 |
+
#add-term-translations,
|
268 |
+
#edit-term-translations {
|
269 |
+
width: 95%;
|
270 |
+
}
|
271 |
+
|
272 |
+
#term-translations .pll-language-column {
|
273 |
+
line-height: 28px;
|
274 |
+
width: 20%;
|
275 |
+
}
|
276 |
+
|
277 |
+
#term-translations .pll-edit-column,
|
278 |
+
#add-term-translations .pll-language-column {
|
279 |
+
width: 20px;
|
280 |
+
}
|
281 |
+
|
282 |
+
#edit-term-translations .pll-language-column {
|
283 |
+
padding: 15px 10px;
|
284 |
+
font-weight: normal;
|
285 |
+
}
|
286 |
+
|
287 |
+
/* icon fonts */
|
288 |
+
.pll_icon_add:before {
|
289 |
+
content: "\f132";
|
290 |
+
}
|
291 |
+
|
292 |
+
.pll_icon_edit:before {
|
293 |
+
content: "\f464";
|
294 |
+
}
|
295 |
+
|
296 |
+
[class^="pll_icon_"] {
|
297 |
+
font: 20px/1 'dashicons';
|
298 |
+
vertical-align: middle;
|
299 |
+
}
|
300 |
+
|
301 |
+
/* admin bar */
|
302 |
+
#wpadminbar #wp-admin-bar-languages .ab-item img {
|
303 |
+
margin: 0 8px 0 2px;
|
304 |
+
}
|
305 |
+
|
306 |
+
#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
|
307 |
+
float: none;
|
308 |
+
top: 4px;
|
309 |
+
}
|
310 |
+
|
311 |
+
#wpadminbar #wp-admin-bar-languages .ab-icon:before {
|
312 |
+
content: "\f326";
|
313 |
+
top: 1px;
|
314 |
+
}
|
315 |
+
|
316 |
+
/* Notices */
|
317 |
+
.pll-notice.notice {
|
318 |
+
padding-right: 38px;
|
319 |
+
position: relative;
|
320 |
+
}
|
321 |
+
|
322 |
+
.pll-notice a.notice-dismiss {
|
323 |
+
text-decoration: none;
|
324 |
+
}
|
325 |
+
|
326 |
+
.pll-notice .button {
|
327 |
+
margin-right: 10px;
|
328 |
+
}
|
329 |
+
|
330 |
+
/* Metaboxes holder in Strings translations screen */
|
331 |
+
.languages_page_mlang_strings .metabox-holder > div {
|
332 |
+
display: flex;
|
333 |
+
}
|
334 |
+
.languages_page_mlang_strings .metabox-holder > div > div {
|
335 |
+
flex-grow: 1;
|
336 |
+
}
|
337 |
+
.languages_page_mlang_strings .metabox-holder > div > div:nth-child(2n) {
|
338 |
+
margin-left: 1rem;
|
339 |
+
}
|
340 |
+
.languages_page_mlang_strings .metabox-holder > div > div.closed {
|
341 |
+
border:0;
|
342 |
+
background: none;
|
343 |
+
}
|
344 |
+
.languages_page_mlang_strings .metabox-holder > div > div.closed .postbox-header{
|
345 |
+
border: 1px solid #ccd0d4;
|
346 |
+
background: #fff;
|
347 |
+
}
|
348 |
+
|
349 |
+
@media screen and ( max-width: 782px ) {
|
350 |
+
/* settings */
|
351 |
+
#wpbody-content .pll-settings .pll-configure > td {
|
352 |
+
padding: 20px;
|
353 |
+
}
|
354 |
+
|
355 |
+
#wpbody-content .pll-settings #cb {
|
356 |
+
padding: 20px 9px;
|
357 |
+
}
|
358 |
+
|
359 |
+
/* settings URL modifications */
|
360 |
+
.pll-inline-block {
|
361 |
+
width: auto;
|
362 |
+
}
|
363 |
+
|
364 |
+
.pll-settings-url-col {
|
365 |
+
display: block;
|
366 |
+
width: 100%;
|
367 |
+
}
|
368 |
+
|
369 |
+
/* settings licenses */
|
370 |
+
#wpbody-content .pll-settings #pll-licenses-table td {
|
371 |
+
display: block;
|
372 |
+
}
|
373 |
+
|
374 |
+
.pll-configure .pll-deactivate-license {
|
375 |
+
margin: 10px 0 5px;
|
376 |
+
}
|
377 |
+
|
378 |
+
/* strings translations table */
|
379 |
+
.translation label {
|
380 |
+
display: block;
|
381 |
+
width: 95%;
|
382 |
+
padding-left: 0;
|
383 |
+
}
|
384 |
+
|
385 |
+
.translation input,
|
386 |
+
.translation textarea {
|
387 |
+
width: 95%;
|
388 |
+
}
|
389 |
+
|
390 |
+
/* Metaboxes holder in Strings translations screen */
|
391 |
+
.languages_page_mlang_strings .metabox-holder > div {
|
392 |
+
flex-direction: column;
|
393 |
+
}
|
394 |
+
.languages_page_mlang_strings .metabox-holder > div > div:nth-child(2n) {
|
395 |
+
margin-left: 0;
|
396 |
+
}
|
397 |
+
|
398 |
+
/* hide selected language flag and translations language name */
|
399 |
+
#select-add-term-language .pll-select-flag,
|
400 |
+
#select-edit-term-language .pll-select-flag,
|
401 |
+
#edit-term-translations .pll-language-name {
|
402 |
+
display: none;
|
403 |
+
}
|
404 |
+
|
405 |
+
#edit-term-translations {
|
406 |
+
width: 100%;
|
407 |
+
}
|
408 |
+
|
409 |
+
#add-term-translations .pll-language-column {
|
410 |
+
line-height: 38px;
|
411 |
+
}
|
412 |
+
|
413 |
+
#edit-term-translations td {
|
414 |
+
padding: 8px 10px;
|
415 |
+
}
|
416 |
+
|
417 |
+
#edit-term-translations .pll-language-column,
|
418 |
+
#edit-term-translations .pll-edit-column {
|
419 |
+
width: 20px;
|
420 |
+
}
|
421 |
+
|
422 |
+
/* translations tables should be kept as table */
|
423 |
+
.term-translations .pll-language-column,
|
424 |
+
.term-translations .pll-edit-column,
|
425 |
+
.term-translations .pll-translation-column {
|
426 |
+
display: table-cell;
|
427 |
+
}
|
428 |
+
|
429 |
+
.term-translations .hidden {
|
430 |
+
display: none;
|
431 |
+
}
|
432 |
+
|
433 |
+
/* admin bar */
|
434 |
+
#wpadminbar #wp-admin-bar-languages {
|
435 |
+
display: block; /*shows our menu on mobile devices */
|
436 |
+
}
|
437 |
+
|
438 |
+
#wpadminbar #wp-admin-bar-languages > .ab-item {
|
439 |
+
width: 50px;
|
440 |
+
text-align: center;
|
441 |
+
}
|
442 |
+
|
443 |
+
#wpadminbar #wp-admin-bar-languages > .ab-item .ab-icon:before {
|
444 |
+
font: 32px/1 'dashicons';
|
445 |
+
top: -1px;
|
446 |
+
}
|
447 |
+
|
448 |
+
#wpadminbar #wp-admin-bar-languages > .ab-item img {
|
449 |
+
margin: 19px 0;
|
450 |
+
}
|
451 |
+
|
452 |
+
#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
|
453 |
+
margin-right: 6px;
|
454 |
+
font-size: 20px !important;
|
455 |
+
line-height: 20px !important;
|
456 |
+
}
|
457 |
+
}
|
css/build/admin.min.css
ADDED
@@ -0,0 +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{display:flex}@media screen and (max-width:782px){.translation{display:block}}.translation textarea{display:block}.translation input,.translation textarea{width:72%;box-sizing:border-box;margin-bottom:4px}.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}.wp-list-table td[class*=column-language_],.wp-list-table th[class*=column-language_]{width:1.5em;box-sizing:content-box}.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:50%;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-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_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}.languages_page_mlang_strings .metabox-holder>div{display:flex}.languages_page_mlang_strings .metabox-holder>div>div{flex-grow:1}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:1rem}.languages_page_mlang_strings .metabox-holder>div>div.closed{border:0;background:none}.languages_page_mlang_strings .metabox-holder>div>div.closed .postbox-header{border:1px solid #ccd0d4;background:#fff}@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}.translation label{display:block;width:95%;padding-left:0}.translation input,.translation textarea{width:95%}.languages_page_mlang_strings .metabox-holder>div{flex-direction:column}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:0}#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/build/dialog.css
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* By default Polylang dialog box use WordPress jQuery UI dialog styles.
|
2 |
+
However WooCommerce loads its own jQuery UI dialog styles and we need to override them by ours
|
3 |
+
to revert to the default WordPress ones.
|
4 |
+
*/
|
5 |
+
.pll-confirmation-modal.ui-widget,
|
6 |
+
.pll-confirmation-modal.ui-widget .ui-widget,
|
7 |
+
.pll-confirmation-modal .ui-widget {
|
8 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
9 |
+
font-size: 13px;
|
10 |
+
}
|
11 |
+
.pll-confirmation-modal.ui-dialog {
|
12 |
+
padding: 0;
|
13 |
+
z-index: 100102;
|
14 |
+
background: #fff;
|
15 |
+
border: 0;
|
16 |
+
color: #444;
|
17 |
+
}
|
18 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-titlebar {
|
19 |
+
background: #fcfcfc;
|
20 |
+
border-radius: 0;
|
21 |
+
border: 0;
|
22 |
+
border-bottom: 1px solid #dfdfdf;
|
23 |
+
height: 36px;
|
24 |
+
font-size: 18px;
|
25 |
+
font-weight: 600;
|
26 |
+
line-height: 2;
|
27 |
+
padding: 0 36px 0 16px;
|
28 |
+
color: #444;
|
29 |
+
position: static;
|
30 |
+
}
|
31 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-title {
|
32 |
+
float: none;
|
33 |
+
width: auto;
|
34 |
+
margin: 0;
|
35 |
+
}
|
36 |
+
.pll-confirmation-modal .ui-widget-header .ui-icon {
|
37 |
+
background: none;
|
38 |
+
position: static;
|
39 |
+
}
|
40 |
+
.pll-confirmation-modal .ui-button.ui-dialog-titlebar-close {
|
41 |
+
padding: 0;
|
42 |
+
margin: 0;
|
43 |
+
top: 0;
|
44 |
+
right: 0;
|
45 |
+
width: 36px;
|
46 |
+
height: 36px;
|
47 |
+
}
|
48 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-content {
|
49 |
+
border: 0;
|
50 |
+
padding: 16px;
|
51 |
+
color: #444;
|
52 |
+
position: static;
|
53 |
+
box-sizing: border-box;
|
54 |
+
}
|
55 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{
|
56 |
+
margin: 0;
|
57 |
+
padding: 16px;
|
58 |
+
border: 0;
|
59 |
+
background: #fcfcfc;
|
60 |
+
border-top: 1px solid #dfdfdf;
|
61 |
+
}
|
62 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{
|
63 |
+
margin: 0 0 0 16px;
|
64 |
+
padding: 0 10px 1px;
|
65 |
+
background: #f7f7f7;
|
66 |
+
border: 1px solid #cccccc;
|
67 |
+
border-radius: 3px;
|
68 |
+
position: static;
|
69 |
+
line-height: 2;
|
70 |
+
vertical-align: top;
|
71 |
+
}
|
72 |
+
.ui-dialog.pll-confirmation-modal .ui-button:hover,
|
73 |
+
.ui-dialog.pll-confirmation-modal .ui-button:focus {
|
74 |
+
background: #fafafa;
|
75 |
+
border-color: #999;
|
76 |
+
color: #23282d;
|
77 |
+
}
|
78 |
+
.pll-confirmation-modal + .ui-widget-overlay {
|
79 |
+
background: #000;
|
80 |
+
opacity: 0.7;
|
81 |
+
z-index: 100101;
|
82 |
+
}
|
css/build/dialog.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.pll-confirmation-modal.ui-widget,.pll-confirmation-modal .ui-widget,.pll-confirmation-modal.ui-widget .ui-widget{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.pll-confirmation-modal.ui-dialog{padding:0;z-index:100102;background:#fff;border:0;color:#444}.ui-dialog.pll-confirmation-modal .ui-dialog-titlebar{background:#fcfcfc;border-radius:0;border:0;border-bottom:1px solid #dfdfdf;height:36px;font-size:18px;font-weight:600;line-height:2;padding:0 36px 0 16px;color:#444;position:static}.ui-dialog.pll-confirmation-modal .ui-dialog-title{float:none;width:auto;margin:0}.pll-confirmation-modal .ui-widget-header .ui-icon{background:none;position:static}.pll-confirmation-modal .ui-button.ui-dialog-titlebar-close{padding:0;margin:0;top:0;right:0;width:36px;height:36px}.ui-dialog.pll-confirmation-modal .ui-dialog-content{border:0;padding:16px;color:#444;position:static;box-sizing:border-box}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{margin:0;padding:16px;border:0;background:#fcfcfc;border-top:1px solid #dfdfdf}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{margin:0 0 0 16px;padding:0 10px 1px;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;position:static;line-height:2;vertical-align:top}.ui-dialog.pll-confirmation-modal .ui-button:focus,.ui-dialog.pll-confirmation-modal .ui-button:hover{background:#fafafa;border-color:#999;color:#23282d}.pll-confirmation-modal+.ui-widget-overlay{background:#000;opacity:.7;z-index:100101}
|
css/build/selectmenu.css
ADDED
@@ -0,0 +1,231 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Greatly modified version of the jquery-ui.css */
|
2 |
+
|
3 |
+
.ui-widget-overlay {
|
4 |
+
position: fixed;
|
5 |
+
top: 0;
|
6 |
+
left: 0;
|
7 |
+
width: 100%;
|
8 |
+
height: 100%;
|
9 |
+
}
|
10 |
+
|
11 |
+
.ui-menu {
|
12 |
+
list-style: none;
|
13 |
+
padding: 0;
|
14 |
+
margin: 0;
|
15 |
+
display: block;
|
16 |
+
outline: none;
|
17 |
+
}
|
18 |
+
|
19 |
+
.ui-menu .ui-menu {
|
20 |
+
position: absolute;
|
21 |
+
}
|
22 |
+
|
23 |
+
.ui-menu .ui-menu-item {
|
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 |
+
/* for jQuery UI 1.12 which introduces a wrapper */
|
34 |
+
.ui-menu .ui-menu-item:not([role]) {
|
35 |
+
padding: 0;
|
36 |
+
}
|
37 |
+
|
38 |
+
.ui-menu-item-wrapper {
|
39 |
+
padding: 3px 1em 3px 2em;
|
40 |
+
}
|
41 |
+
.rtl .ui-menu .ui-menu-item {
|
42 |
+
text-align: right;
|
43 |
+
}
|
44 |
+
|
45 |
+
/* icon support */
|
46 |
+
.ui-menu-icons {
|
47 |
+
position: relative;
|
48 |
+
}
|
49 |
+
|
50 |
+
.ui-menu-icons .ui-menu-item[role] {
|
51 |
+
padding-left: 2em;
|
52 |
+
}
|
53 |
+
|
54 |
+
.rtl .ui-menu-item-wrapper, /* for jQuery UI 1.12 which introduces a wrapper */
|
55 |
+
.rtl .ui-menu-icons .ui-menu-item[role] {
|
56 |
+
padding-left: 1em;
|
57 |
+
padding-right: 2em;
|
58 |
+
}
|
59 |
+
|
60 |
+
/* left-aligned */
|
61 |
+
.ui-selectmenu-text .ui-icon,
|
62 |
+
.ui-menu .ui-icon {
|
63 |
+
position: absolute;
|
64 |
+
top: 0;
|
65 |
+
bottom: 0;
|
66 |
+
left: .3em;
|
67 |
+
margin: auto 0;
|
68 |
+
}
|
69 |
+
|
70 |
+
.rtl .ui-selectmenu-text .ui-icon,
|
71 |
+
.rtl .ui-menu .ui-icon {
|
72 |
+
right: .3em;
|
73 |
+
left: auto;
|
74 |
+
}
|
75 |
+
|
76 |
+
/* right-aligned */
|
77 |
+
.ui-menu .ui-menu-icon {
|
78 |
+
left: auto;
|
79 |
+
right: 0;
|
80 |
+
}
|
81 |
+
|
82 |
+
.ui-selectmenu-menu {
|
83 |
+
padding: 0;
|
84 |
+
margin: 0;
|
85 |
+
position: absolute;
|
86 |
+
top: 0;
|
87 |
+
left: 0;
|
88 |
+
display: none;
|
89 |
+
}
|
90 |
+
|
91 |
+
.ui-selectmenu-menu .ui-menu {
|
92 |
+
overflow: auto;
|
93 |
+
/* Support: IE7 */
|
94 |
+
overflow-x: hidden;
|
95 |
+
padding-bottom: 1px;
|
96 |
+
}
|
97 |
+
|
98 |
+
.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
|
99 |
+
font-size: 1em;
|
100 |
+
font-weight: bold;
|
101 |
+
line-height: 23px;
|
102 |
+
padding: 2px 0.4em;
|
103 |
+
margin: 0.5em 0 0 0;
|
104 |
+
height: auto;
|
105 |
+
border: 0;
|
106 |
+
}
|
107 |
+
|
108 |
+
.ui-selectmenu-open {
|
109 |
+
display: block;
|
110 |
+
}
|
111 |
+
|
112 |
+
.ui-selectmenu-button.ui-button {
|
113 |
+
display: inline-block;
|
114 |
+
overflow: hidden;
|
115 |
+
position: relative;
|
116 |
+
text-decoration: none;
|
117 |
+
box-sizing: border-box; /* To keep width calculation in percent since WP 5.6 */
|
118 |
+
text-align: left;
|
119 |
+
white-space: nowrap;
|
120 |
+
vertical-align: top;
|
121 |
+
padding: 0;
|
122 |
+
}
|
123 |
+
|
124 |
+
.ui-selectmenu-button span.ui-icon {
|
125 |
+
right: 0.5em;
|
126 |
+
left: auto;
|
127 |
+
position: absolute;
|
128 |
+
top: 26%;
|
129 |
+
width: 16px;
|
130 |
+
height: 16px;
|
131 |
+
text-indent: 0; /* due to text-indent for jquery ui-dialog in wizard */
|
132 |
+
background: none;
|
133 |
+
}
|
134 |
+
|
135 |
+
.rtl .ui-selectmenu-button span.ui-icon {
|
136 |
+
left: 0.5em;
|
137 |
+
right: auto;
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
.ui-selectmenu-button span.ui-selectmenu-text {
|
142 |
+
text-align: left;
|
143 |
+
padding: 0.1em 2.1em 0.2em 2em;
|
144 |
+
display: block;
|
145 |
+
line-height: 23px;
|
146 |
+
overflow: hidden;
|
147 |
+
text-overflow: ellipsis;
|
148 |
+
white-space: nowrap;
|
149 |
+
margin: 0;
|
150 |
+
}
|
151 |
+
|
152 |
+
.rtl .ui-selectmenu-button span.ui-selectmenu-text {
|
153 |
+
text-align: right;
|
154 |
+
padding: 0.2em 2em 0.2em 2.1em;
|
155 |
+
}
|
156 |
+
|
157 |
+
.ui-widget-content,
|
158 |
+
.ui-state-default,
|
159 |
+
.ui-button.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
160 |
+
.ui-button.ui-selectmenu-button-open, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
161 |
+
.ui-widget-content .ui-state-default,
|
162 |
+
.ui-widget-header .ui-state-default {
|
163 |
+
background: #fff;
|
164 |
+
border: 1px solid #ddd;
|
165 |
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
|
166 |
+
color: #32373c;
|
167 |
+
}
|
168 |
+
/* Override to have same styles as WP form styles since WordPress 5.4 */
|
169 |
+
.toplevel_page_mlang .ui-selectmenu-button.ui-state-default,
|
170 |
+
.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
171 |
+
.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open{ /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
172 |
+
box-shadow: 0 0 0 transparent;
|
173 |
+
border-radius: 4px;
|
174 |
+
border: 1px solid #7e8993;
|
175 |
+
}
|
176 |
+
|
177 |
+
/* From this line and below: override WooCommerce bookings plugin styles which overrides default WordPress styles */
|
178 |
+
.pll-selectmenu-menu .ui-widget,
|
179 |
+
.pll-selectmenu-button.ui-widget {
|
180 |
+
font-size: 13px;
|
181 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
182 |
+
}
|
183 |
+
|
184 |
+
.toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{
|
185 |
+
color: #016087; /* Same color as WordPress focused select HTML tag */
|
186 |
+
border-color: #007cba;
|
187 |
+
box-shadow: 0 0 0 1px #007cba;
|
188 |
+
outline: 2px solid transparent;
|
189 |
+
background: #fff; /* Override bookings plugin styles which overrides default WordPress styles */
|
190 |
+
}
|
191 |
+
|
192 |
+
.toplevel_page_mlang .ui-menu-item,
|
193 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-hover,
|
194 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-focus,
|
195 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-active {
|
196 |
+
color: #016087; /* Same color as option in a WordPress focused select HTML tag */
|
197 |
+
margin: 0;
|
198 |
+
}
|
199 |
+
|
200 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-hover,
|
201 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-focus,
|
202 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-active { /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
203 |
+
background: #d5d5d5;
|
204 |
+
border: 0;
|
205 |
+
}
|
206 |
+
|
207 |
+
.ui-selectmenu-button.ui-state-focus {
|
208 |
+
border: 1px solid #5b9dd9;
|
209 |
+
box-shadow: 0 0 2px rgba(30, 140, 190, 0.8);
|
210 |
+
}
|
211 |
+
|
212 |
+
.ui-icon-triangle-1-s:before {
|
213 |
+
content: "";
|
214 |
+
background: #fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0px top 55%;
|
215 |
+
background-size: 16px 16px;
|
216 |
+
box-sizing: border-box;
|
217 |
+
position: absolute;
|
218 |
+
width: 16px;
|
219 |
+
height: 16px;
|
220 |
+
}
|
221 |
+
|
222 |
+
.pll-selectmenu-button.ui-button:hover,
|
223 |
+
.pll-wizard .ui-button:hover,
|
224 |
+
.pll-wizard .ui-button:focus {
|
225 |
+
background: #fff; /* To override jQuery ui-dialog styles provided by WordPress */
|
226 |
+
}
|
227 |
+
|
228 |
+
.ui-widget-content {
|
229 |
+
max-height: 231px;
|
230 |
+
box-shadow: 0 2px 6px rgba(100, 100, 100, 0.3);
|
231 |
+
}
|
css/build/selectmenu.min.css
ADDED
@@ -0,0 +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:none}.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")}.ui-menu .ui-menu-item:not([role]){padding:0}.ui-menu-item-wrapper{padding:3px 1em 3px 2em}.rtl .ui-menu .ui-menu-item{text-align:right}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item[role]{padding-left:2em}.rtl .ui-menu-icons .ui-menu-item[role],.rtl .ui-menu-item-wrapper{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;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button.ui-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;box-sizing:border-box;text-align:left;white-space:nowrap;vertical-align:top;padding:0}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;position:absolute;top:26%;width:16px;height:16px;text-indent:0;background:none}.rtl .ui-selectmenu-button span.ui-icon{left:.5em;right:auto}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.1em 2.1em .2em 2em;display:block;line-height:23px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.rtl .ui-selectmenu-button span.ui-selectmenu-text{text-align:right;padding:.2em 2em .2em 2.1em}.ui-button.ui-selectmenu-button-closed,.ui-button.ui-selectmenu-button-open,.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:inset 0 1px 2px rgba(0,0,0,.07);color:#32373c}.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed,.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open,.toplevel_page_mlang .ui-selectmenu-button.ui-state-default{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993}.pll-selectmenu-button.ui-widget,.pll-selectmenu-menu .ui-widget{font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{color:#016087;border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent;background:#fff}.toplevel_page_mlang .ui-menu-item,.toplevel_page_mlang .ui-widget-content .ui-state-active,.toplevel_page_mlang .ui-widget-content .ui-state-focus,.toplevel_page_mlang .ui-widget-content .ui-state-hover{color:#016087;margin:0}.pll-selectmenu-menu .ui-widget-content .ui-state-active,.pll-selectmenu-menu .ui-widget-content .ui-state-focus,.pll-selectmenu-menu .ui-widget-content .ui-state-hover{background:#d5d5d5;border:0}.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:"";background:#fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0 top 55%;background-size:16px 16px;box-sizing:border-box;position:absolute;width:16px;height:16px}.pll-selectmenu-button.ui-button:hover,.pll-wizard .ui-button:focus,.pll-wizard .ui-button:hover{background:#fff}.ui-widget-content{max-height:231px;box-shadow:0 2px 6px hsla(0,0%,39.2%,.3)}
|
css/build/wizard.css
ADDED
@@ -0,0 +1,951 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@charset "UTF-8";
|
2 |
+
body {
|
3 |
+
margin: 65px auto 24px;
|
4 |
+
box-shadow: none;
|
5 |
+
background: #f1f1f1;
|
6 |
+
padding: 0;
|
7 |
+
border: 0; /* fix-pro #856 override WP install.css */
|
8 |
+
}
|
9 |
+
|
10 |
+
#pll-logo {
|
11 |
+
border: 0;
|
12 |
+
margin: 0 0 24px;
|
13 |
+
padding: 0;
|
14 |
+
text-align: center;
|
15 |
+
font-family: sans-serif;
|
16 |
+
font-size: 64px;
|
17 |
+
text-transform: uppercase;
|
18 |
+
color: #000;
|
19 |
+
line-height: normal;
|
20 |
+
}
|
21 |
+
#pll-logo a {
|
22 |
+
display: flex;
|
23 |
+
justify-content: center;
|
24 |
+
color: #000;
|
25 |
+
text-decoration: none;
|
26 |
+
}
|
27 |
+
|
28 |
+
#pll-logo img {
|
29 |
+
max-width: 100%;
|
30 |
+
margin-right: 16px;
|
31 |
+
}
|
32 |
+
.rtl #pll-logo img {
|
33 |
+
margin-right: 0;
|
34 |
+
margin-left: 16px;
|
35 |
+
}
|
36 |
+
|
37 |
+
.pll-wizard-footer {
|
38 |
+
text-align: center
|
39 |
+
}
|
40 |
+
|
41 |
+
.pll-wizard .select2-container {
|
42 |
+
text-align: left;
|
43 |
+
width: auto
|
44 |
+
}
|
45 |
+
|
46 |
+
.pll-wizard .hidden {
|
47 |
+
display: none
|
48 |
+
}
|
49 |
+
|
50 |
+
.pll-wizard-content {
|
51 |
+
box-shadow: 0 1px 3px rgba(0, 0, 0, .13);
|
52 |
+
padding: 2em;
|
53 |
+
margin: 0 0 20px;
|
54 |
+
background: #fff;
|
55 |
+
overflow: hidden;
|
56 |
+
zoom: 1;
|
57 |
+
text-align: left;
|
58 |
+
}
|
59 |
+
.rtl .pll-wizard-content{
|
60 |
+
text-align: right;
|
61 |
+
}
|
62 |
+
|
63 |
+
.pll-wizard-content h1,
|
64 |
+
.pll-wizard-content h2,
|
65 |
+
.pll-wizard-content h3,
|
66 |
+
.pll-wizard-content table {
|
67 |
+
margin: 0 0 20px;
|
68 |
+
border: 0;
|
69 |
+
padding: 0;
|
70 |
+
color: #666;
|
71 |
+
clear: none;
|
72 |
+
font-weight: 500
|
73 |
+
}
|
74 |
+
|
75 |
+
.pll-wizard-content p {
|
76 |
+
margin: 20px 0;
|
77 |
+
font-size: 1em;
|
78 |
+
line-height: 1.75em;
|
79 |
+
color: #666
|
80 |
+
}
|
81 |
+
|
82 |
+
.pll-wizard-content table {
|
83 |
+
font-size: 1em;
|
84 |
+
line-height: 1.75em;
|
85 |
+
color: #666;
|
86 |
+
width: 100%;
|
87 |
+
margin-top: 20px;
|
88 |
+
}
|
89 |
+
.pll-wizard-content table td span{
|
90 |
+
display: inline-block;
|
91 |
+
}
|
92 |
+
|
93 |
+
.pll-wizard-content table caption {
|
94 |
+
caption-side: bottom;
|
95 |
+
font-style: italic;
|
96 |
+
text-align: right;
|
97 |
+
}
|
98 |
+
.rtl .pll-wizard-content table caption {
|
99 |
+
text-align: left;
|
100 |
+
}
|
101 |
+
|
102 |
+
.pll-wizard-content table caption .icon-default-lang{
|
103 |
+
font-style: normal;
|
104 |
+
}
|
105 |
+
|
106 |
+
.pll-wizard-content a {
|
107 |
+
color: #a03f3f;
|
108 |
+
}
|
109 |
+
|
110 |
+
.pll-wizard-content a:focus,
|
111 |
+
.pll-wizard-content a:hover,
|
112 |
+
.pll-wizard-footer-links:hover {
|
113 |
+
color: #dd5454
|
114 |
+
}
|
115 |
+
|
116 |
+
.pll-wizard-content .pll-wizard-next-steps {
|
117 |
+
overflow: hidden;
|
118 |
+
margin: 0 0 24px;
|
119 |
+
padding-bottom: 2px
|
120 |
+
}
|
121 |
+
|
122 |
+
.pll-wizard-content .pll-wizard-next-steps h2 {
|
123 |
+
margin-bottom: 12px
|
124 |
+
}
|
125 |
+
|
126 |
+
.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first {
|
127 |
+
float: left;
|
128 |
+
width: 50%;
|
129 |
+
box-sizing: border-box
|
130 |
+
}
|
131 |
+
|
132 |
+
.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last {
|
133 |
+
float: right;
|
134 |
+
width: 50%;
|
135 |
+
box-sizing: border-box
|
136 |
+
}
|
137 |
+
|
138 |
+
.pll-wizard-content .pll-wizard-next-steps ul {
|
139 |
+
padding: 0 2em 0 0;
|
140 |
+
list-style: none outside;
|
141 |
+
margin: 0
|
142 |
+
}
|
143 |
+
|
144 |
+
.pll-wizard-content .pll-wizard-next-steps ul li a {
|
145 |
+
display: block;
|
146 |
+
padding: 0 0 .75em
|
147 |
+
}
|
148 |
+
|
149 |
+
.pll-wizard-content .pll-wizard-next-steps ul li a::before {
|
150 |
+
color: #82878c;
|
151 |
+
font: normal 20px/1 dashicons;
|
152 |
+
speak: none;
|
153 |
+
display: inline-block;
|
154 |
+
padding: 0 10px 0 0;
|
155 |
+
top: 1px;
|
156 |
+
position: relative;
|
157 |
+
text-decoration: none!important;
|
158 |
+
vertical-align: top
|
159 |
+
}
|
160 |
+
|
161 |
+
.pll-wizard-steps {
|
162 |
+
padding: 0 0 24px;
|
163 |
+
margin: 0;
|
164 |
+
list-style: none outside;
|
165 |
+
overflow: hidden;
|
166 |
+
color: #ccc;
|
167 |
+
width: 100%;
|
168 |
+
display: -webkit-inline-box;
|
169 |
+
display: -webkit-inline-flex;
|
170 |
+
display: inline-flex
|
171 |
+
}
|
172 |
+
|
173 |
+
.pll-wizard-steps li {
|
174 |
+
width: 100%;
|
175 |
+
float: left;
|
176 |
+
padding: 0 0 .8em;
|
177 |
+
margin: 0;
|
178 |
+
text-align: center;
|
179 |
+
position: relative;
|
180 |
+
border-bottom: 4px solid #ccc;
|
181 |
+
line-height: 1.4em
|
182 |
+
}
|
183 |
+
|
184 |
+
.pll-wizard-steps li a {
|
185 |
+
color: #a03f3f;
|
186 |
+
text-decoration: none;
|
187 |
+
padding: 1.5em;
|
188 |
+
margin: -1.5em;
|
189 |
+
position: relative;
|
190 |
+
z-index: 1
|
191 |
+
}
|
192 |
+
|
193 |
+
.pll-wizard-steps li a:focus,
|
194 |
+
.pll-wizard-steps li a:hover {
|
195 |
+
color: #dd5454;
|
196 |
+
text-decoration: underline
|
197 |
+
}
|
198 |
+
|
199 |
+
.pll-wizard-steps li::before {
|
200 |
+
content: "";
|
201 |
+
border: 4px solid #ccc;
|
202 |
+
border-radius: 100%;
|
203 |
+
width: 4px;
|
204 |
+
height: 4px;
|
205 |
+
position: absolute;
|
206 |
+
bottom: 0;
|
207 |
+
left: 50%;
|
208 |
+
margin-left: -6px;
|
209 |
+
margin-bottom: -8px;
|
210 |
+
background: #fff
|
211 |
+
}
|
212 |
+
|
213 |
+
.pll-wizard-steps li.active {
|
214 |
+
border-color: #a03f3f;
|
215 |
+
color: #a03f3f;
|
216 |
+
font-weight: 700
|
217 |
+
}
|
218 |
+
|
219 |
+
.pll-wizard-steps li.active::before {
|
220 |
+
border-color: #a03f3f
|
221 |
+
}
|
222 |
+
|
223 |
+
.pll-wizard-steps li.done {
|
224 |
+
border-color: #a03f3f;
|
225 |
+
color: #a03f3f
|
226 |
+
}
|
227 |
+
|
228 |
+
.pll-wizard-steps li.done::before {
|
229 |
+
border-color: #a03f3f;
|
230 |
+
background: #a03f3f
|
231 |
+
}
|
232 |
+
|
233 |
+
.pll-wizard .pll-wizard-actions {
|
234 |
+
overflow: hidden;
|
235 |
+
margin: 20px 0 0;
|
236 |
+
position: relative
|
237 |
+
}
|
238 |
+
|
239 |
+
.pll-wizard .pll-wizard-actions .button {
|
240 |
+
font-size: 16px;
|
241 |
+
font-weight: 300;
|
242 |
+
padding: 1em 2em;
|
243 |
+
line-height: 1em;
|
244 |
+
margin-right: .5em;
|
245 |
+
margin-bottom: 2px;
|
246 |
+
margin-top: 10px;
|
247 |
+
height: auto;
|
248 |
+
border-radius: 4px;
|
249 |
+
box-shadow: none;
|
250 |
+
min-width: auto;
|
251 |
+
border-color: #a03f3f;
|
252 |
+
color: #a03f3f;
|
253 |
+
}
|
254 |
+
|
255 |
+
.pll-wizard .pll-wizard-content .button {
|
256 |
+
border-color: #a03f3f;
|
257 |
+
color: #a03f3f;
|
258 |
+
}
|
259 |
+
|
260 |
+
.pll-wizard .pll-wizard-content .button-primary,
|
261 |
+
.pll-wizard .pll-wizard-actions .button-primary {
|
262 |
+
background-color: #a03f3f;
|
263 |
+
border-color: #a03f3f;
|
264 |
+
color: #fff;
|
265 |
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #a03f3f;
|
266 |
+
text-shadow: 0 -1px 1px #a03f3f, 1px 0 1px #a03f3f, 0 1px 1px #a03f3f, -1px 0 1px #a03f3f;
|
267 |
+
margin: 0;
|
268 |
+
opacity: 1
|
269 |
+
}
|
270 |
+
|
271 |
+
.pll-wizard .pll-wizard-content .button-small .dashicons {
|
272 |
+
font-size: 15px;
|
273 |
+
height: auto;
|
274 |
+
vertical-align: middle;
|
275 |
+
}
|
276 |
+
|
277 |
+
.pll-wizard .button-primary:active,
|
278 |
+
.pll-wizard .button-primary:focus,
|
279 |
+
.pll-wizard input[type="checkbox"]:focus + label.button-primary,
|
280 |
+
.pll-wizard .button-primary:hover {
|
281 |
+
background: #dd5454;
|
282 |
+
border-color: #dd5454;
|
283 |
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #dd5454
|
284 |
+
}
|
285 |
+
.pll-wizard .pll-wizard-actions .button-primary[disabled],
|
286 |
+
.pll-wizard .pll-wizard-actions .button-primary:disabled,
|
287 |
+
.pll-wizard .pll-wizard-actions .button-primary.disabled {
|
288 |
+
cursor: wait;
|
289 |
+
background-color: #bb5454 !important;
|
290 |
+
border-color: #bb5454 !important;
|
291 |
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 0 #bb5454 !important;
|
292 |
+
text-shadow: 0 -1px 1px #bb5454, 1px 0 1px #bb5454, 0 1px 1px #bb5454, -1px 0 1px #bb5454 !important;
|
293 |
+
color: #ffa3a3 !important;
|
294 |
+
}
|
295 |
+
.pll-wizard-content p:last-child {
|
296 |
+
margin-bottom: 0
|
297 |
+
}
|
298 |
+
|
299 |
+
.pll-wizard-footer-links {
|
300 |
+
font-size: .85em;
|
301 |
+
color: #7b7b7b;
|
302 |
+
margin: 1.18em auto;
|
303 |
+
display: inline-block;
|
304 |
+
text-align: center
|
305 |
+
}
|
306 |
+
|
307 |
+
.pll-wizard-services {
|
308 |
+
border: 1px solid #eee;
|
309 |
+
padding: 0;
|
310 |
+
margin: 0 0 1em;
|
311 |
+
list-style: none outside;
|
312 |
+
border-radius: 4px;
|
313 |
+
overflow: hidden
|
314 |
+
}
|
315 |
+
|
316 |
+
.pll-wizard-services p {
|
317 |
+
margin: 0 0 1em 0;
|
318 |
+
padding: 0;
|
319 |
+
font-size: 1em;
|
320 |
+
line-height: 1.5em
|
321 |
+
}
|
322 |
+
|
323 |
+
.pll-wizard-service-item {
|
324 |
+
display: -webkit-box;
|
325 |
+
display: -webkit-flex;
|
326 |
+
display: flex;
|
327 |
+
-webkit-flex-wrap: nowrap;
|
328 |
+
flex-wrap: nowrap;
|
329 |
+
-webkit-box-pack: justify;
|
330 |
+
-webkit-justify-content: space-between;
|
331 |
+
justify-content: space-between;
|
332 |
+
padding: 0;
|
333 |
+
border-bottom: 1px solid #eee;
|
334 |
+
color: #666;
|
335 |
+
-webkit-box-align: center;
|
336 |
+
-webkit-align-items: center;
|
337 |
+
align-items: center
|
338 |
+
}
|
339 |
+
|
340 |
+
.media-step .pll-wizard-service-item{
|
341 |
+
border: 0;
|
342 |
+
}
|
343 |
+
|
344 |
+
.media-step .pll-wizard-service-item:last-child{
|
345 |
+
display: block;
|
346 |
+
}
|
347 |
+
|
348 |
+
.media-step .pll-wizard-service-item .pll-wizard-service-enable{
|
349 |
+
padding-bottom: 0;
|
350 |
+
}
|
351 |
+
|
352 |
+
.pll-wizard-service-item:last-child {
|
353 |
+
border-bottom: 0
|
354 |
+
}
|
355 |
+
|
356 |
+
.pll-wizard-service-item .pll-wizard-service-name {
|
357 |
+
-webkit-flex-basis: 0;
|
358 |
+
flex-basis: 0;
|
359 |
+
min-width: 160px;
|
360 |
+
text-align: center;
|
361 |
+
font-weight: 700;
|
362 |
+
padding: 2em 0;
|
363 |
+
-webkit-align-self: stretch;
|
364 |
+
align-self: stretch;
|
365 |
+
display: -webkit-box;
|
366 |
+
display: -webkit-flex;
|
367 |
+
display: flex;
|
368 |
+
-webkit-box-align: baseline;
|
369 |
+
-webkit-align-items: baseline;
|
370 |
+
align-items: baseline
|
371 |
+
}
|
372 |
+
|
373 |
+
.pll-wizard-service-item .pll-wizard-service-name img {
|
374 |
+
max-width: 75px
|
375 |
+
}
|
376 |
+
|
377 |
+
.pll-wizard-service-item .pll-wizard-service-description {
|
378 |
+
-webkit-box-flex: 1;
|
379 |
+
-webkit-flex-grow: 1;
|
380 |
+
flex-grow: 1;
|
381 |
+
padding: 20px
|
382 |
+
}
|
383 |
+
|
384 |
+
.pll-wizard-service-item .pll-wizard-service-example {
|
385 |
+
padding: 0 20px 20px
|
386 |
+
}
|
387 |
+
|
388 |
+
.pll-wizard-service-item .pll-wizard-service-example p{
|
389 |
+
text-align: right;
|
390 |
+
}
|
391 |
+
.rtl .pll-wizard-service-item .pll-wizard-service-example p{
|
392 |
+
text-align: left;
|
393 |
+
}
|
394 |
+
|
395 |
+
.pll-wizard-service-item .pll-wizard-service-description p {
|
396 |
+
margin-bottom: 1em
|
397 |
+
}
|
398 |
+
|
399 |
+
.pll-wizard-service-item .pll-wizard-service-description p:last-child {
|
400 |
+
margin-bottom: 0
|
401 |
+
}
|
402 |
+
|
403 |
+
.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description {
|
404 |
+
display: block;
|
405 |
+
font-style: italic;
|
406 |
+
color: #999
|
407 |
+
}
|
408 |
+
|
409 |
+
.pll-wizard-service-item .pll-wizard-service-enable {
|
410 |
+
-webkit-flex-basis: 0;
|
411 |
+
flex-basis: 0;
|
412 |
+
min-width: 75px;
|
413 |
+
text-align: center;
|
414 |
+
cursor: pointer;
|
415 |
+
padding: 2em 0;
|
416 |
+
position: relative;
|
417 |
+
max-height: 1.5em;
|
418 |
+
-webkit-align-self: flex-start;
|
419 |
+
align-self: flex-start;
|
420 |
+
-webkit-box-ordinal-group: 4;
|
421 |
+
-webkit-order: 3;
|
422 |
+
order: 3
|
423 |
+
}
|
424 |
+
|
425 |
+
.pll-wizard-service-item .pll-wizard-service-toggle {
|
426 |
+
position: relative
|
427 |
+
}
|
428 |
+
|
429 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] {
|
430 |
+
position:absolute;
|
431 |
+
opacity: 0;
|
432 |
+
}
|
433 |
+
|
434 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label {
|
435 |
+
position: relative;
|
436 |
+
display: inline-block;
|
437 |
+
width: 44px;
|
438 |
+
height: 20px;
|
439 |
+
border-radius: 10em;
|
440 |
+
cursor: pointer;
|
441 |
+
text-indent: -9999px;
|
442 |
+
}
|
443 |
+
|
444 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus + label {
|
445 |
+
border:1px dashed #777;
|
446 |
+
}
|
447 |
+
|
448 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::before,
|
449 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::after {
|
450 |
+
content: '';
|
451 |
+
position: absolute;
|
452 |
+
}
|
453 |
+
|
454 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::before {
|
455 |
+
left: 0;
|
456 |
+
top: 0;
|
457 |
+
width: 44px;
|
458 |
+
height: 20px;
|
459 |
+
background: #ddd;
|
460 |
+
border-radius: 10em;
|
461 |
+
transition: background-color .2s;
|
462 |
+
}
|
463 |
+
|
464 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox] + label::after {
|
465 |
+
width: 16px;
|
466 |
+
height: 16px;
|
467 |
+
transition: all .2s;
|
468 |
+
border-radius: 50%;
|
469 |
+
background: #fff;
|
470 |
+
margin: 2px;
|
471 |
+
top: 0;
|
472 |
+
left: 0;
|
473 |
+
}
|
474 |
+
|
475 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked + label::before {
|
476 |
+
background:#a03f3f;
|
477 |
+
}
|
478 |
+
|
479 |
+
.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked + label::after {
|
480 |
+
right: 0;
|
481 |
+
left:auto;
|
482 |
+
}
|
483 |
+
|
484 |
+
.pll-wizard-service-item .pll-wizard-service-settings {
|
485 |
+
display: none;
|
486 |
+
margin-top: .75em;
|
487 |
+
margin-bottom: 0;
|
488 |
+
cursor: default
|
489 |
+
}
|
490 |
+
|
491 |
+
.pll-wizard-service-item .pll-wizard-service-settings.hide {
|
492 |
+
display: none
|
493 |
+
}
|
494 |
+
|
495 |
+
.pll-wizard-service-item.checked .pll-wizard-service-settings {
|
496 |
+
display: inline-block
|
497 |
+
}
|
498 |
+
|
499 |
+
.pll-wizard-service-item.checked .pll-wizard-service-settings.hide {
|
500 |
+
display: none
|
501 |
+
}
|
502 |
+
|
503 |
+
.pll-wizard-service-item.closed {
|
504 |
+
border-bottom: 0
|
505 |
+
}
|
506 |
+
|
507 |
+
.step {
|
508 |
+
text-align: center
|
509 |
+
}
|
510 |
+
|
511 |
+
.pll-wizard .button .dashicons{
|
512 |
+
vertical-align: middle;
|
513 |
+
}
|
514 |
+
.rtl .dashicons-arrow-right-alt2:before {
|
515 |
+
content: "\f341";
|
516 |
+
}
|
517 |
+
.pll-wizard .pll-wizard-actions .button:active,
|
518 |
+
.pll-wizard .pll-wizard-actions .button:focus,
|
519 |
+
.pll-wizard .pll-wizard-actions .button:hover {
|
520 |
+
box-shadow: none
|
521 |
+
}
|
522 |
+
|
523 |
+
.pll-wizard-next-steps {
|
524 |
+
border: 1px solid #eee;
|
525 |
+
border-radius: 4px;
|
526 |
+
list-style: none;
|
527 |
+
padding: 0
|
528 |
+
}
|
529 |
+
|
530 |
+
.pll-wizard-next-steps li {
|
531 |
+
padding: 0
|
532 |
+
}
|
533 |
+
|
534 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item {
|
535 |
+
display: -webkit-box;
|
536 |
+
display: -webkit-flex;
|
537 |
+
display: flex;
|
538 |
+
border-top: 1px solid #eee
|
539 |
+
}
|
540 |
+
|
541 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,
|
542 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item:first-child {
|
543 |
+
border-top: 0
|
544 |
+
}
|
545 |
+
|
546 |
+
.pll-wizard-next-steps .pll-wizard-next-step-description {
|
547 |
+
-webkit-box-flex: 1;
|
548 |
+
-webkit-flex-grow: 1;
|
549 |
+
flex-grow: 1;
|
550 |
+
margin: 1.5em
|
551 |
+
}
|
552 |
+
|
553 |
+
.pll-wizard-next-steps .pll-wizard-next-step-action {
|
554 |
+
-webkit-box-flex: 0;
|
555 |
+
-webkit-flex-grow: 0;
|
556 |
+
flex-grow: 0;
|
557 |
+
display: -webkit-box;
|
558 |
+
display: -webkit-flex;
|
559 |
+
display: flex;
|
560 |
+
-webkit-box-align: center;
|
561 |
+
-webkit-align-items: center;
|
562 |
+
align-items: center
|
563 |
+
}
|
564 |
+
|
565 |
+
.pll-wizard-next-steps .pll-wizard-next-step-action .button {
|
566 |
+
margin: 1em 1.5em
|
567 |
+
}
|
568 |
+
|
569 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description,
|
570 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,
|
571 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button{
|
572 |
+
margin-top: 0;
|
573 |
+
}
|
574 |
+
|
575 |
+
|
576 |
+
.pll-wizard-next-steps p.next-step-heading {
|
577 |
+
margin: 0;
|
578 |
+
font-size: .95em;
|
579 |
+
font-weight: 400;
|
580 |
+
font-variant: all-petite-caps
|
581 |
+
}
|
582 |
+
|
583 |
+
.pll-wizard-next-steps p.next-step-extra-info {
|
584 |
+
margin: 0
|
585 |
+
}
|
586 |
+
|
587 |
+
.pll-wizard-next-steps h3.next-step-description {
|
588 |
+
margin: 0;
|
589 |
+
font-size: 16px;
|
590 |
+
font-weight: 600;
|
591 |
+
}
|
592 |
+
|
593 |
+
.pll-wizard-next-steps .pll-wizard-additional-steps {
|
594 |
+
border-top: 1px solid #eee;
|
595 |
+
}
|
596 |
+
|
597 |
+
.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description {
|
598 |
+
margin-bottom: 0
|
599 |
+
}
|
600 |
+
|
601 |
+
.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions {
|
602 |
+
margin: 0 0 1.5em 0;
|
603 |
+
}
|
604 |
+
|
605 |
+
.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button {
|
606 |
+
font-size: 15px;
|
607 |
+
margin: 1em 0 1em 1.5em;
|
608 |
+
}
|
609 |
+
.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button {
|
610 |
+
margin: 1em 1.5em 1em 0;
|
611 |
+
}
|
612 |
+
|
613 |
+
.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child {
|
614 |
+
margin-right: 1.5em;
|
615 |
+
}
|
616 |
+
|
617 |
+
.pll-wizard-content img{
|
618 |
+
max-width: 100%;
|
619 |
+
margin-right: 0.5em;
|
620 |
+
}
|
621 |
+
.rtl .pll-wizard-content img{
|
622 |
+
margin-left: 0.5em;
|
623 |
+
}
|
624 |
+
|
625 |
+
.pll-wizard-content .form-field label{
|
626 |
+
margin-bottom: 5px;
|
627 |
+
display: block;
|
628 |
+
}
|
629 |
+
|
630 |
+
.pll-wizard-content .form-field select{
|
631 |
+
padding: 3px;
|
632 |
+
}
|
633 |
+
|
634 |
+
.pll-wizard-content .languages-step select,
|
635 |
+
.pll-wizard-content .untranslated-contents-step select{
|
636 |
+
width: 100%;
|
637 |
+
}
|
638 |
+
|
639 |
+
.languages-step .form-field .button{
|
640 |
+
margin-left: 15px;
|
641 |
+
}
|
642 |
+
.languages-step .form-field .button > span{
|
643 |
+
margin-right: 0.3em;
|
644 |
+
}
|
645 |
+
.rtl .languages-step .form-field .button{
|
646 |
+
margin-left: 0;
|
647 |
+
margin-right: 15px;
|
648 |
+
}
|
649 |
+
.rtl .languages-step .form-field .button > span{
|
650 |
+
margin-left: 0.3em;
|
651 |
+
margin-right: 0;
|
652 |
+
}
|
653 |
+
|
654 |
+
.pll-wizard-content .languages-step .select-language-field{
|
655 |
+
display: flex;
|
656 |
+
}
|
657 |
+
|
658 |
+
.pll-wizard-content #languages{
|
659 |
+
display: none;
|
660 |
+
}
|
661 |
+
.pll-wizard-content #languages tr th:first-child{
|
662 |
+
width: 80%;
|
663 |
+
}
|
664 |
+
.pll-wizard-content #languages .dashicons{
|
665 |
+
color: #a03f3f;
|
666 |
+
}
|
667 |
+
.pll-wizard-content #languages img{
|
668 |
+
margin-right: 5px;
|
669 |
+
}
|
670 |
+
.pll-wizard-content .error{
|
671 |
+
color: #a03f3f;
|
672 |
+
font-weight: bold;
|
673 |
+
}
|
674 |
+
.pll-wizard-content #messages .error{
|
675 |
+
background: #fccfcf;
|
676 |
+
padding: 0.5rem;
|
677 |
+
border: 1px solid #a03f3f;
|
678 |
+
margin-bottom: 0.5rem;
|
679 |
+
}
|
680 |
+
|
681 |
+
.pll-wizard-content #slide-toggle{
|
682 |
+
position:absolute;
|
683 |
+
opacity: 0;
|
684 |
+
}
|
685 |
+
|
686 |
+
.pll-wizard-content #slide-toggle + label{
|
687 |
+
position:relative;
|
688 |
+
}
|
689 |
+
.pll-wizard-content #slide-toggle + label + span{
|
690 |
+
display: block;
|
691 |
+
}
|
692 |
+
|
693 |
+
.pll-wizard-content #slide-toggle + label .dashicons{
|
694 |
+
margin-right: 0.3em;
|
695 |
+
}
|
696 |
+
.rtl .pll-wizard-content #slide-toggle + label .dashicons{
|
697 |
+
margin-left: 0.3em;
|
698 |
+
margin-right: 0;
|
699 |
+
}
|
700 |
+
.pll-wizard-content #slide-toggle ~ #screenshot > img {
|
701 |
+
max-height: 500px;
|
702 |
+
margin-top: 10px;
|
703 |
+
-webkit-transition: all .5s cubic-bezier(0, 1, 0.5, 1);
|
704 |
+
transition: all .5s cubic-bezier(0, 1, 0.5, 1);
|
705 |
+
}
|
706 |
+
.pll-wizard-content #slide-toggle:checked ~ #screenshot > img {
|
707 |
+
max-height: 0;
|
708 |
+
}
|
709 |
+
.hide {
|
710 |
+
display: none;
|
711 |
+
}
|
712 |
+
|
713 |
+
input[type="text"].field-in-error,
|
714 |
+
input[type="password"].field-in-error,
|
715 |
+
input[type="checkbox"].field-in-error,
|
716 |
+
input[type="color"].field-in-error,
|
717 |
+
input[type="date"].field-in-error,
|
718 |
+
input[type="datetime"].field-in-error,
|
719 |
+
input[type="datetime-local"].field-in-error,
|
720 |
+
input[type="email"].field-in-error,
|
721 |
+
input[type="month"].field-in-error,
|
722 |
+
input[type="number"].field-in-error,
|
723 |
+
input[type="search"].field-in-error,
|
724 |
+
input[type="radio"].field-in-error,
|
725 |
+
input[type="tel"].field-in-error,
|
726 |
+
input[type="text"].field-in-error,
|
727 |
+
input[type="time"].field-in-error,
|
728 |
+
input[type="url"].field-in-error,
|
729 |
+
input[type="week"].field-in-error,
|
730 |
+
select.field-in-error,
|
731 |
+
textarea.field-in-error,
|
732 |
+
span.field-in-error,
|
733 |
+
.field-in-error{
|
734 |
+
border-color: #a03f3f;
|
735 |
+
}
|
736 |
+
|
737 |
+
input[type="text"].field-in-error:focus,
|
738 |
+
input[type="password"].field-in-error:focus,
|
739 |
+
input[type="checkbox"].field-in-error:focus,
|
740 |
+
input[type="color"].field-in-error:focus,
|
741 |
+
input[type="date"].field-in-error:focus,
|
742 |
+
input[type="datetime"].field-in-error:focus,
|
743 |
+
input[type="datetime-local"].field-in-error:focus,
|
744 |
+
input[type="email"].field-in-error:focus,
|
745 |
+
input[type="month"].field-in-error:focus,
|
746 |
+
input[type="number"].field-in-error:focus,
|
747 |
+
input[type="search"].field-in-error:focus,
|
748 |
+
input[type="radio"].field-in-error:focus,
|
749 |
+
input[type="tel"].field-in-error:focus,
|
750 |
+
input[type="text"].field-in-error:focus,
|
751 |
+
input[type="time"].field-in-error:focus,
|
752 |
+
input[type="url"].field-in-error:focus,
|
753 |
+
input[type="week"].field-in-error:focus,
|
754 |
+
select.field-in-error:focus,
|
755 |
+
textarea.field-in-error:focus,
|
756 |
+
span.field-in-error:focus,
|
757 |
+
.field-in-error:focus{
|
758 |
+
border: 1px solid #a03f3f;
|
759 |
+
box-shadow: 0 0 2px rgba(160, 63, 63, 0.8);
|
760 |
+
outline-color: #a03f3f;
|
761 |
+
outline-style: auto;
|
762 |
+
outline-width: thin;
|
763 |
+
}
|
764 |
+
|
765 |
+
/* override install styles by returning back to forms styles */
|
766 |
+
.form-table input.regular-text{
|
767 |
+
width: 25em;
|
768 |
+
}
|
769 |
+
.form-table input.field-in-error{
|
770 |
+
border-color: #a03f3f;
|
771 |
+
}
|
772 |
+
#pll-licenses-table td{
|
773 |
+
padding: 10px 9px;
|
774 |
+
}
|
775 |
+
#pll-licenses-table .license-valid td p{
|
776 |
+
min-width: 35em;
|
777 |
+
}
|
778 |
+
#pll-licenses-table .pll-deactivate-license{
|
779 |
+
margin: 0 0 0 20px;
|
780 |
+
}
|
781 |
+
.rtl #pll-licenses-table .pll-deactivate-license{
|
782 |
+
margin: 0 10px 0 0;
|
783 |
+
}
|
784 |
+
.pll-wizard-content .documentation {
|
785 |
+
padding: 24px 24px 0;
|
786 |
+
margin: 0 0 24px;
|
787 |
+
overflow: hidden;
|
788 |
+
background: #f5f5f5
|
789 |
+
}
|
790 |
+
|
791 |
+
.pll-wizard-content .documentation p {
|
792 |
+
padding: 0;
|
793 |
+
margin: 0 0 12px;
|
794 |
+
}
|
795 |
+
.documentation-container {
|
796 |
+
display: -webkit-box;
|
797 |
+
display: -webkit-flex;
|
798 |
+
display: flex;
|
799 |
+
justify-content: flex-end;
|
800 |
+
}
|
801 |
+
|
802 |
+
.documentation-container .documentation-button-container {
|
803 |
+
-webkit-box-flex: 0;
|
804 |
+
-webkit-flex-grow: 0;
|
805 |
+
flex-grow: 0;
|
806 |
+
}
|
807 |
+
|
808 |
+
.wc-setup .wc-setup-actions .button.documentation-button {
|
809 |
+
height: 42px;
|
810 |
+
padding: 0 1em;
|
811 |
+
margin: 0;
|
812 |
+
}
|
813 |
+
#dialog{
|
814 |
+
display: none;
|
815 |
+
}
|
816 |
+
.pll-wizard .ui-dialog.ui-widget-content{
|
817 |
+
max-height: none;
|
818 |
+
}
|
819 |
+
.pll-wizard .ui-dialog-title::before{
|
820 |
+
content: "\f534";
|
821 |
+
font-family: dashicons;
|
822 |
+
display: inline-block;
|
823 |
+
line-height: 1;
|
824 |
+
font-weight: 400;
|
825 |
+
font-style: normal;
|
826 |
+
speak: none;
|
827 |
+
text-decoration: inherit;
|
828 |
+
text-transform: none;
|
829 |
+
text-rendering: auto;
|
830 |
+
-webkit-font-smoothing: antialiased;
|
831 |
+
-moz-osx-font-smoothing: grayscale;
|
832 |
+
width: 20px;
|
833 |
+
height: 20px;
|
834 |
+
font-size: 20px;
|
835 |
+
vertical-align: middle;
|
836 |
+
text-align: center;
|
837 |
+
margin: 0 5px 5px 0;
|
838 |
+
transition: color 0.1s ease-in;
|
839 |
+
}
|
840 |
+
.rtl.pll-wizard .ui-dialog-title::before{
|
841 |
+
margin-right: 0;
|
842 |
+
margin-left: 5px;
|
843 |
+
}
|
844 |
+
.pll-wizard .ui-dialog ul{
|
845 |
+
list-style: disc;
|
846 |
+
padding-left: 20px;
|
847 |
+
}
|
848 |
+
.rtl.pll-wizard .ui-dialog ul{
|
849 |
+
padding-left: 0;
|
850 |
+
padding-right: 20px;
|
851 |
+
}
|
852 |
+
.pll-wizard li{
|
853 |
+
margin-bottom: 0;
|
854 |
+
}
|
855 |
+
#translations{
|
856 |
+
border-collapse: collapse;
|
857 |
+
}
|
858 |
+
#translations tbody:nth-child(odd){
|
859 |
+
background-color: #f9f9f9;
|
860 |
+
}
|
861 |
+
#translations.striped > tbody > :nth-child(odd) {
|
862 |
+
background-color: transparent; /* Override common WordPress style */
|
863 |
+
}
|
864 |
+
.pll-wizard-content mark{
|
865 |
+
background: transparent none;
|
866 |
+
}
|
867 |
+
.pll-wizard-content mark{
|
868 |
+
color: #7ad03a;
|
869 |
+
}
|
870 |
+
@media screen and (max-width: 782px) {
|
871 |
+
/* Override WordPress button css rules */
|
872 |
+
.languages-step .form-field .button{
|
873 |
+
font-size: 13px;
|
874 |
+
line-height: 26px;
|
875 |
+
height: 28px;
|
876 |
+
padding: 0 10px 1px;
|
877 |
+
vertical-align: top;
|
878 |
+
}
|
879 |
+
|
880 |
+
#pll-licenses-table .pll-deactivate-license{
|
881 |
+
margin: 10px 0 5px;
|
882 |
+
}
|
883 |
+
}
|
884 |
+
@media only screen and (max-width:620px) {
|
885 |
+
/* Override dialog width rule */
|
886 |
+
.ui-dialog{
|
887 |
+
width: 100% !important;
|
888 |
+
}
|
889 |
+
|
890 |
+
}
|
891 |
+
@media only screen and (max-width:500px) {
|
892 |
+
#pll-logo a,
|
893 |
+
.select-language-field{
|
894 |
+
flex-direction: column;
|
895 |
+
}
|
896 |
+
.select-language-field .action-buttons{
|
897 |
+
display: flex;
|
898 |
+
justify-content: flex-end;
|
899 |
+
}
|
900 |
+
.languages-step .form-field .button{
|
901 |
+
margin: 5px 0 0;
|
902 |
+
}
|
903 |
+
}
|
904 |
+
@media only screen and (max-width:400px) {
|
905 |
+
#pll-logo {
|
906 |
+
font-size: 56px;
|
907 |
+
}
|
908 |
+
.pll-wizard-steps {
|
909 |
+
display: none
|
910 |
+
}
|
911 |
+
.pll-wizard-service-item {
|
912 |
+
-webkit-flex-wrap: wrap;
|
913 |
+
flex-wrap: wrap
|
914 |
+
}
|
915 |
+
.pll-wizard-service-item .pll-wizard-service-enable {
|
916 |
+
-webkit-box-ordinal-group: 3;
|
917 |
+
-webkit-order: 2;
|
918 |
+
order: 2;
|
919 |
+
padding: 20px 0 0
|
920 |
+
}
|
921 |
+
.pll-wizard-service-item .pll-wizard-service-description {
|
922 |
+
-webkit-box-ordinal-group: 4;
|
923 |
+
-webkit-order: 3;
|
924 |
+
order: 3
|
925 |
+
}
|
926 |
+
.pll-wizard-service-item .pll-wizard-service-name {
|
927 |
+
padding: 20px 20px 0;
|
928 |
+
text-align: left;
|
929 |
+
-webkit-box-pack: justify!important;
|
930 |
+
-webkit-justify-content: space-between!important;
|
931 |
+
justify-content: space-between!important
|
932 |
+
}
|
933 |
+
.pll-wizard-service-item .pll-wizard-service-name img {
|
934 |
+
margin: 0
|
935 |
+
}
|
936 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item {
|
937 |
+
-webkit-flex-wrap: wrap;
|
938 |
+
flex-wrap: wrap
|
939 |
+
}
|
940 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description {
|
941 |
+
margin-bottom: 0
|
942 |
+
}
|
943 |
+
.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p {
|
944 |
+
margin: 0
|
945 |
+
}
|
946 |
+
}
|
947 |
+
@media only screen and (max-width:360px) {
|
948 |
+
#pll-logo {
|
949 |
+
font-size: 48px;
|
950 |
+
}
|
951 |
+
}
|
css/build/wizard.min.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
body{margin:65px auto 24px;box-shadow:none;background:#f1f1f1}#pll-logo,body{padding:0;border:0}#pll-logo{margin:0 0 24px;text-align:center;font-family:sans-serif;font-size:64px;text-transform:uppercase;color:#000;line-height:normal}#pll-logo a{display:flex;justify-content:center;color:#000;text-decoration:none}#pll-logo img{max-width:100%;margin-right:16px}.rtl #pll-logo img{margin-right:0;margin-left:16px}.pll-wizard-footer{text-align:center}.pll-wizard .select2-container{text-align:left;width:auto}.pll-wizard .hidden{display:none}.pll-wizard-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:2em;margin:0 0 20px;background:#fff;overflow:hidden;zoom:1;text-align:left}.rtl .pll-wizard-content{text-align:right}.pll-wizard-content h1,.pll-wizard-content h2,.pll-wizard-content h3,.pll-wizard-content table{margin:0 0 20px;border:0;padding:0;color:#666;clear:none;font-weight:500}.pll-wizard-content p{margin:20px 0;font-size:1em;line-height:1.75em;color:#666}.pll-wizard-content table{font-size:1em;line-height:1.75em;color:#666;width:100%;margin-top:20px}.pll-wizard-content table td span{display:inline-block}.pll-wizard-content table caption{caption-side:bottom;font-style:italic;text-align:right}.rtl .pll-wizard-content table caption{text-align:left}.pll-wizard-content table caption .icon-default-lang{font-style:normal}.pll-wizard-content a{color:#a03f3f}.pll-wizard-content a:focus,.pll-wizard-content a:hover,.pll-wizard-footer-links:hover{color:#dd5454}.pll-wizard-content .pll-wizard-next-steps{overflow:hidden;margin:0 0 24px;padding-bottom:2px}.pll-wizard-content .pll-wizard-next-steps h2{margin-bottom:12px}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first{float:left;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last{float:right;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps ul{padding:0 2em 0 0;list-style:none outside;margin:0}.pll-wizard-content .pll-wizard-next-steps ul li a{display:block;padding:0 0 .75em}.pll-wizard-content .pll-wizard-next-steps ul li a:before{color:#82878c;font:normal 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;text-decoration:none!important;vertical-align:top}.pll-wizard-steps{padding:0 0 24px;margin:0;list-style:none outside;overflow:hidden;color:#ccc;width:100%;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex}.pll-wizard-steps li{width:100%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.pll-wizard-steps li a{color:#a03f3f;text-decoration:none;padding:1.5em;margin:-1.5em;position:relative;z-index:1}.pll-wizard-steps li a:focus,.pll-wizard-steps li a:hover{color:#dd5454;text-decoration:underline}.pll-wizard-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.pll-wizard-steps li.active{border-color:#a03f3f;color:#a03f3f;font-weight:700}.pll-wizard-steps li.active:before{border-color:#a03f3f}.pll-wizard-steps li.done{border-color:#a03f3f;color:#a03f3f}.pll-wizard-steps li.done:before{border-color:#a03f3f;background:#a03f3f}.pll-wizard .pll-wizard-actions{overflow:hidden;margin:20px 0 0;position:relative}.pll-wizard .pll-wizard-actions .button{font-size:16px;font-weight:300;padding:1em 2em;line-height:1em;margin-right:.5em;margin-bottom:2px;margin-top:10px;height:auto;border-radius:4px;box-shadow:none;min-width:auto;border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-content .button{border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-actions .button-primary,.pll-wizard .pll-wizard-content .button-primary{background-color:#a03f3f;border-color:#a03f3f;color:#fff;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #a03f3f;text-shadow:0 -1px 1px #a03f3f,1px 0 1px #a03f3f,0 1px 1px #a03f3f,-1px 0 1px #a03f3f;margin:0;opacity:1}.pll-wizard .pll-wizard-content .button-small .dashicons{font-size:15px;height:auto;vertical-align:middle}.pll-wizard .button-primary:active,.pll-wizard .button-primary:focus,.pll-wizard .button-primary:hover,.pll-wizard input[type=checkbox]:focus+label.button-primary{background:#dd5454;border-color:#dd5454;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #dd5454}.pll-wizard .pll-wizard-actions .button-primary.disabled,.pll-wizard .pll-wizard-actions .button-primary:disabled,.pll-wizard .pll-wizard-actions .button-primary[disabled]{cursor:wait;background-color:#bb5454!important;border-color:#bb5454!important;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #bb5454!important;text-shadow:0 -1px 1px #bb5454,1px 0 1px #bb5454,0 1px 1px #bb5454,-1px 0 1px #bb5454!important;color:#ffa3a3!important}.pll-wizard-content p:last-child{margin-bottom:0}.pll-wizard-footer-links{font-size:.85em;color:#7b7b7b;margin:1.18em auto;display:inline-block;text-align:center}.pll-wizard-services{border:1px solid #eee;padding:0;margin:0 0 1em;list-style:none outside;border-radius:4px;overflow:hidden}.pll-wizard-services p{margin:0 0 1em;padding:0;font-size:1em;line-height:1.5em}.pll-wizard-service-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;padding:0;border-bottom:1px solid #eee;color:#666;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.media-step .pll-wizard-service-item{border:0}.media-step .pll-wizard-service-item:last-child{display:block}.media-step .pll-wizard-service-item .pll-wizard-service-enable{padding-bottom:0}.pll-wizard-service-item:last-child{border-bottom:0}.pll-wizard-service-item .pll-wizard-service-name{-webkit-flex-basis:0;flex-basis:0;min-width:160px;text-align:center;font-weight:700;padding:2em 0;-webkit-align-self:stretch;align-self:stretch;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:baseline;-webkit-align-items:baseline;align-items:baseline}.pll-wizard-service-item .pll-wizard-service-name img{max-width:75px}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;padding:20px}.pll-wizard-service-item .pll-wizard-service-example{padding:0 20px 20px}.pll-wizard-service-item .pll-wizard-service-example p{text-align:right}.rtl .pll-wizard-service-item .pll-wizard-service-example p{text-align:left}.pll-wizard-service-item .pll-wizard-service-description p{margin-bottom:1em}.pll-wizard-service-item .pll-wizard-service-description p:last-child{margin-bottom:0}.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description{display:block;font-style:italic;color:#999}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-flex-basis:0;flex-basis:0;min-width:75px;text-align:center;cursor:pointer;padding:2em 0;position:relative;max-height:1.5em;-webkit-align-self:flex-start;align-self:flex-start;-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-toggle{position:relative}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]{position:absolute;opacity:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label{position:relative;display:inline-block;width:44px;height:20px;border-radius:10em;cursor:pointer;text-indent:-9999px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus+label{border:1px dashed #777}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after,.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{content:"";position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{left:0;top:0;width:44px;height:20px;background:#ddd;border-radius:10em;transition:background-color .2s}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after{width:16px;height:16px;transition:all .2s;border-radius:50%;background:#fff;margin:2px;top:0;left:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:before{background:#a03f3f}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:after{right:0;left:auto}.pll-wizard-service-item .pll-wizard-service-settings{display:none;margin-top:.75em;margin-bottom:0;cursor:default}.pll-wizard-service-item .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.checked .pll-wizard-service-settings{display:inline-block}.pll-wizard-service-item.checked .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.closed{border-bottom:0}.step{text-align:center}.pll-wizard .button .dashicons{vertical-align:middle}.rtl .dashicons-arrow-right-alt2:before{content:"\f341"}.pll-wizard .pll-wizard-actions .button:active,.pll-wizard .pll-wizard-actions .button:focus,.pll-wizard .pll-wizard-actions .button:hover{box-shadow:none}.pll-wizard-next-steps{border:1px solid #eee;border-radius:4px;list-style:none;padding:0}.pll-wizard-next-steps li{padding:0}.pll-wizard-next-steps .pll-wizard-next-step-item{display:-webkit-box;display:-webkit-flex;display:flex;border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,.pll-wizard-next-steps .pll-wizard-next-step-item:first-child{border-top:0}.pll-wizard-next-steps .pll-wizard-next-step-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;margin:1.5em}.pll-wizard-next-steps .pll-wizard-next-step-action{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.pll-wizard-next-steps .pll-wizard-next-step-action .button{margin:1em 1.5em}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description{margin-top:0}.pll-wizard-next-steps p.next-step-heading{margin:0;font-size:.95em;font-weight:400;font-variant:all-petite-caps}.pll-wizard-next-steps p.next-step-extra-info{margin:0}.pll-wizard-next-steps h3.next-step-description{margin:0;font-size:16px;font-weight:600}.pll-wizard-next-steps .pll-wizard-additional-steps{border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions{margin:0 0 1.5em}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{font-size:15px;margin:1em 0 1em 1.5em}.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{margin:1em 1.5em 1em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child{margin-right:1.5em}.pll-wizard-content img{max-width:100%;margin-right:.5em}.rtl .pll-wizard-content img{margin-left:.5em}.pll-wizard-content .form-field label{margin-bottom:5px;display:block}.pll-wizard-content .form-field select{padding:3px}.pll-wizard-content .languages-step select,.pll-wizard-content .untranslated-contents-step select{width:100%}.languages-step .form-field .button{margin-left:15px}.languages-step .form-field .button>span{margin-right:.3em}.rtl .languages-step .form-field .button{margin-left:0;margin-right:15px}.rtl .languages-step .form-field .button>span{margin-left:.3em;margin-right:0}.pll-wizard-content .languages-step .select-language-field{display:flex}.pll-wizard-content #languages{display:none}.pll-wizard-content #languages tr th:first-child{width:80%}.pll-wizard-content #languages .dashicons{color:#a03f3f}.pll-wizard-content #languages img{margin-right:5px}.pll-wizard-content .error{color:#a03f3f;font-weight:700}.pll-wizard-content #messages .error{background:#fccfcf;padding:.5rem;border:1px solid #a03f3f;margin-bottom:.5rem}.pll-wizard-content #slide-toggle{position:absolute;opacity:0}.pll-wizard-content #slide-toggle+label{position:relative}.pll-wizard-content #slide-toggle+label+span{display:block}.pll-wizard-content #slide-toggle+label .dashicons{margin-right:.3em}.rtl .pll-wizard-content #slide-toggle+label .dashicons{margin-left:.3em;margin-right:0}.pll-wizard-content #slide-toggle~#screenshot>img{max-height:500px;margin-top:10px;-webkit-transition:all .5s cubic-bezier(0,1,.5,1);transition:all .5s cubic-bezier(0,1,.5,1)}.pll-wizard-content #slide-toggle:checked~#screenshot>img{max-height:0}.hide{display:none}.field-in-error,input[type=checkbox].field-in-error,input[type=color].field-in-error,input[type=date].field-in-error,input[type=datetime-local].field-in-error,input[type=datetime].field-in-error,input[type=email].field-in-error,input[type=month].field-in-error,input[type=number].field-in-error,input[type=password].field-in-error,input[type=radio].field-in-error,input[type=search].field-in-error,input[type=tel].field-in-error,input[type=text].field-in-error,input[type=time].field-in-error,input[type=url].field-in-error,input[type=week].field-in-error,select.field-in-error,span.field-in-error,textarea.field-in-error{border-color:#a03f3f}.field-in-error:focus,input[type=checkbox].field-in-error:focus,input[type=color].field-in-error:focus,input[type=date].field-in-error:focus,input[type=datetime-local].field-in-error:focus,input[type=datetime].field-in-error:focus,input[type=email].field-in-error:focus,input[type=month].field-in-error:focus,input[type=number].field-in-error:focus,input[type=password].field-in-error:focus,input[type=radio].field-in-error:focus,input[type=search].field-in-error:focus,input[type=tel].field-in-error:focus,input[type=text].field-in-error:focus,input[type=time].field-in-error:focus,input[type=url].field-in-error:focus,input[type=week].field-in-error:focus,select.field-in-error:focus,span.field-in-error:focus,textarea.field-in-error:focus{border:1px solid #a03f3f;box-shadow:0 0 2px rgba(160,63,63,.8);outline-color:#a03f3f;outline-style:auto;outline-width:thin}.form-table input.regular-text{width:25em}.form-table input.field-in-error{border-color:#a03f3f}#pll-licenses-table td{padding:10px 9px}#pll-licenses-table .license-valid td p{min-width:35em}#pll-licenses-table .pll-deactivate-license{margin:0 0 0 20px}.rtl #pll-licenses-table .pll-deactivate-license{margin:0 10px 0 0}.pll-wizard-content .documentation{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.pll-wizard-content .documentation p{padding:0;margin:0 0 12px}.documentation-container{display:-webkit-box;display:-webkit-flex;display:flex;justify-content:flex-end}.documentation-container .documentation-button-container{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}.wc-setup .wc-setup-actions .button.documentation-button{height:42px;padding:0 1em;margin:0}#dialog{display:none}.pll-wizard .ui-dialog.ui-widget-content{max-height:none}.pll-wizard .ui-dialog-title:before{content:"\f534";font-family:dashicons;display:inline-block;line-height:1;font-weight:400;font-style:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:20px;height:20px;font-size:20px;vertical-align:middle;text-align:center;margin:0 5px 5px 0;transition:color .1s ease-in}.rtl.pll-wizard .ui-dialog-title:before{margin-right:0;margin-left:5px}.pll-wizard .ui-dialog ul{list-style:disc;padding-left:20px}.rtl.pll-wizard .ui-dialog ul{padding-left:0;padding-right:20px}.pll-wizard li{margin-bottom:0}#translations{border-collapse:collapse}#translations tbody:nth-child(odd){background-color:#f9f9f9}#translations.striped>tbody>:nth-child(odd){background-color:transparent}.pll-wizard-content mark{background:transparent none;color:#7ad03a}@media screen and (max-width:782px){.languages-step .form-field .button{font-size:13px;line-height:26px;height:28px;padding:0 10px 1px;vertical-align:top}#pll-licenses-table .pll-deactivate-license{margin:10px 0 5px}}@media only screen and (max-width:620px){.ui-dialog{width:100%!important}}@media only screen and (max-width:500px){#pll-logo a,.select-language-field{flex-direction:column}.select-language-field .action-buttons{display:flex;justify-content:flex-end}.languages-step .form-field .button{margin:5px 0 0}}@media only screen and (max-width:400px){#pll-logo{font-size:56px}.pll-wizard-steps{display:none}.pll-wizard-service-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:3;-webkit-order:2;order:2;padding:20px 0 0}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-name{padding:20px 20px 0;text-align:left;-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;justify-content:space-between!important}.pll-wizard-service-item .pll-wizard-service-name img{margin:0}.pll-wizard-next-steps .pll-wizard-next-step-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p{margin:0}}@media only screen and (max-width:360px){#pll-logo{font-size:48px}}
|
css/dialog.css
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* By default Polylang dialog box use WordPress jQuery UI dialog styles.
|
2 |
+
However WooCommerce loads its own jQuery UI dialog styles and we need to override them by ours
|
3 |
+
to revert to the default WordPress ones.
|
4 |
+
*/
|
5 |
+
.pll-confirmation-modal.ui-widget,
|
6 |
+
.pll-confirmation-modal.ui-widget .ui-widget,
|
7 |
+
.pll-confirmation-modal .ui-widget {
|
8 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
9 |
+
font-size: 13px;
|
10 |
+
}
|
11 |
+
.pll-confirmation-modal.ui-dialog {
|
12 |
+
padding: 0;
|
13 |
+
z-index: 100102;
|
14 |
+
background: #fff;
|
15 |
+
border: 0;
|
16 |
+
color: #444;
|
17 |
+
}
|
18 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-titlebar {
|
19 |
+
background: #fcfcfc;
|
20 |
+
border-radius: 0;
|
21 |
+
border: 0;
|
22 |
+
border-bottom: 1px solid #dfdfdf;
|
23 |
+
height: 36px;
|
24 |
+
font-size: 18px;
|
25 |
+
font-weight: 600;
|
26 |
+
line-height: 2;
|
27 |
+
padding: 0 36px 0 16px;
|
28 |
+
color: #444;
|
29 |
+
position: static;
|
30 |
+
}
|
31 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-title {
|
32 |
+
float: none;
|
33 |
+
width: auto;
|
34 |
+
margin: 0;
|
35 |
+
}
|
36 |
+
.pll-confirmation-modal .ui-widget-header .ui-icon {
|
37 |
+
background: none;
|
38 |
+
position: static;
|
39 |
+
}
|
40 |
+
.pll-confirmation-modal .ui-button.ui-dialog-titlebar-close {
|
41 |
+
padding: 0;
|
42 |
+
margin: 0;
|
43 |
+
top: 0;
|
44 |
+
right: 0;
|
45 |
+
width: 36px;
|
46 |
+
height: 36px;
|
47 |
+
}
|
48 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-content {
|
49 |
+
border: 0;
|
50 |
+
padding: 16px;
|
51 |
+
color: #444;
|
52 |
+
position: static;
|
53 |
+
box-sizing: border-box;
|
54 |
+
}
|
55 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{
|
56 |
+
margin: 0;
|
57 |
+
padding: 16px;
|
58 |
+
border: 0;
|
59 |
+
background: #fcfcfc;
|
60 |
+
border-top: 1px solid #dfdfdf;
|
61 |
+
}
|
62 |
+
.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{
|
63 |
+
margin: 0 0 0 16px;
|
64 |
+
padding: 0 10px 1px;
|
65 |
+
background: #f7f7f7;
|
66 |
+
border: 1px solid #cccccc;
|
67 |
+
border-radius: 3px;
|
68 |
+
position: static;
|
69 |
+
line-height: 2;
|
70 |
+
vertical-align: top;
|
71 |
+
}
|
72 |
+
.ui-dialog.pll-confirmation-modal .ui-button:hover,
|
73 |
+
.ui-dialog.pll-confirmation-modal .ui-button:focus {
|
74 |
+
background: #fafafa;
|
75 |
+
border-color: #999;
|
76 |
+
color: #23282d;
|
77 |
+
}
|
78 |
+
.pll-confirmation-modal + .ui-widget-overlay {
|
79 |
+
background: #000;
|
80 |
+
opacity: 0.7;
|
81 |
+
z-index: 100101;
|
82 |
+
}
|
css/selectmenu.css
CHANGED
@@ -109,12 +109,16 @@
|
|
109 |
display: block;
|
110 |
}
|
111 |
|
112 |
-
.ui-selectmenu-button {
|
113 |
display: inline-block;
|
114 |
overflow: hidden;
|
115 |
position: relative;
|
116 |
text-decoration: none;
|
117 |
box-sizing: border-box; /* To keep width calculation in percent since WP 5.6 */
|
|
|
|
|
|
|
|
|
118 |
}
|
119 |
|
120 |
.ui-selectmenu-button span.ui-icon {
|
@@ -125,6 +129,7 @@
|
|
125 |
width: 16px;
|
126 |
height: 16px;
|
127 |
text-indent: 0; /* due to text-indent for jquery ui-dialog in wizard */
|
|
|
128 |
}
|
129 |
|
130 |
.rtl .ui-selectmenu-button span.ui-icon {
|
@@ -135,12 +140,13 @@
|
|
135 |
|
136 |
.ui-selectmenu-button span.ui-selectmenu-text {
|
137 |
text-align: left;
|
138 |
-
padding: 0.
|
139 |
display: block;
|
140 |
line-height: 23px;
|
141 |
overflow: hidden;
|
142 |
text-overflow: ellipsis;
|
143 |
white-space: nowrap;
|
|
|
144 |
}
|
145 |
|
146 |
.rtl .ui-selectmenu-button span.ui-selectmenu-text {
|
@@ -150,8 +156,8 @@
|
|
150 |
|
151 |
.ui-widget-content,
|
152 |
.ui-state-default,
|
153 |
-
.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
154 |
-
.ui-selectmenu-button-open, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
155 |
.ui-widget-content .ui-state-default,
|
156 |
.ui-widget-header .ui-state-default {
|
157 |
background: #fff;
|
@@ -168,21 +174,34 @@
|
|
168 |
border: 1px solid #7e8993;
|
169 |
}
|
170 |
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
color: #016087; /* Same color as WordPress focused select HTML tag */
|
173 |
border-color: #007cba;
|
174 |
box-shadow: 0 0 0 1px #007cba;
|
175 |
outline: 2px solid transparent;
|
|
|
176 |
}
|
177 |
|
178 |
-
.toplevel_page_mlang .ui-menu-item
|
|
|
|
|
|
|
179 |
color: #016087; /* Same color as option in a WordPress focused select HTML tag */
|
|
|
180 |
}
|
181 |
|
182 |
-
.ui-widget-content .ui-state-hover,
|
183 |
-
.ui-widget-content .ui-state-focus,
|
184 |
-
.ui-widget-content .ui-state-active { /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
185 |
background: #d5d5d5;
|
|
|
186 |
}
|
187 |
|
188 |
.ui-selectmenu-button.ui-state-focus {
|
@@ -200,6 +219,7 @@
|
|
200 |
height: 16px;
|
201 |
}
|
202 |
|
|
|
203 |
.pll-wizard .ui-button:hover,
|
204 |
.pll-wizard .ui-button:focus {
|
205 |
background: #fff; /* To override jQuery ui-dialog styles provided by WordPress */
|
109 |
display: block;
|
110 |
}
|
111 |
|
112 |
+
.ui-selectmenu-button.ui-button {
|
113 |
display: inline-block;
|
114 |
overflow: hidden;
|
115 |
position: relative;
|
116 |
text-decoration: none;
|
117 |
box-sizing: border-box; /* To keep width calculation in percent since WP 5.6 */
|
118 |
+
text-align: left;
|
119 |
+
white-space: nowrap;
|
120 |
+
vertical-align: top;
|
121 |
+
padding: 0;
|
122 |
}
|
123 |
|
124 |
.ui-selectmenu-button span.ui-icon {
|
129 |
width: 16px;
|
130 |
height: 16px;
|
131 |
text-indent: 0; /* due to text-indent for jquery ui-dialog in wizard */
|
132 |
+
background: none;
|
133 |
}
|
134 |
|
135 |
.rtl .ui-selectmenu-button span.ui-icon {
|
140 |
|
141 |
.ui-selectmenu-button span.ui-selectmenu-text {
|
142 |
text-align: left;
|
143 |
+
padding: 0.1em 2.1em 0.2em 2em;
|
144 |
display: block;
|
145 |
line-height: 23px;
|
146 |
overflow: hidden;
|
147 |
text-overflow: ellipsis;
|
148 |
white-space: nowrap;
|
149 |
+
margin: 0;
|
150 |
}
|
151 |
|
152 |
.rtl .ui-selectmenu-button span.ui-selectmenu-text {
|
156 |
|
157 |
.ui-widget-content,
|
158 |
.ui-state-default,
|
159 |
+
.ui-button.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
160 |
+
.ui-button.ui-selectmenu-button-open, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
161 |
.ui-widget-content .ui-state-default,
|
162 |
.ui-widget-header .ui-state-default {
|
163 |
background: #fff;
|
174 |
border: 1px solid #7e8993;
|
175 |
}
|
176 |
|
177 |
+
/* From this line and below: override WooCommerce bookings plugin styles which overrides default WordPress styles */
|
178 |
+
.pll-selectmenu-menu .ui-widget,
|
179 |
+
.pll-selectmenu-button.ui-widget {
|
180 |
+
font-size: 13px;
|
181 |
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
182 |
+
}
|
183 |
+
|
184 |
+
.toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{
|
185 |
color: #016087; /* Same color as WordPress focused select HTML tag */
|
186 |
border-color: #007cba;
|
187 |
box-shadow: 0 0 0 1px #007cba;
|
188 |
outline: 2px solid transparent;
|
189 |
+
background: #fff; /* Override bookings plugin styles which overrides default WordPress styles */
|
190 |
}
|
191 |
|
192 |
+
.toplevel_page_mlang .ui-menu-item,
|
193 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-hover,
|
194 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-focus,
|
195 |
+
.toplevel_page_mlang .ui-widget-content .ui-state-active {
|
196 |
color: #016087; /* Same color as option in a WordPress focused select HTML tag */
|
197 |
+
margin: 0;
|
198 |
}
|
199 |
|
200 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-hover,
|
201 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-focus,
|
202 |
+
.pll-selectmenu-menu .ui-widget-content .ui-state-active { /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
|
203 |
background: #d5d5d5;
|
204 |
+
border: 0;
|
205 |
}
|
206 |
|
207 |
.ui-selectmenu-button.ui-state-focus {
|
219 |
height: 16px;
|
220 |
}
|
221 |
|
222 |
+
.pll-selectmenu-button.ui-button:hover,
|
223 |
.pll-wizard .ui-button:hover,
|
224 |
.pll-wizard .ui-button:focus {
|
225 |
background: #fff; /* To override jQuery ui-dialog styles provided by WordPress */
|
css/selectmenu.min.css
DELETED
@@ -1 +0,0 @@
|
|
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)}.ui-menu .ui-menu-item:not([role]){padding:0}.ui-menu-item-wrapper{padding:3px 1em 3px 2em}.rtl .ui-menu .ui-menu-item{text-align:right}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item[role]{padding-left:2em}.rtl .ui-menu-icons .ui-menu-item[role],.rtl .ui-menu-item-wrapper{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;box-sizing:border-box}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;position:absolute;top:26%;width:16px;height:16px;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-selectmenu-button-closed,.ui-selectmenu-button-open,.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}.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed,.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open,.toplevel_page_mlang .ui-selectmenu-button.ui-state-default{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993}.toplevel_page_mlang .ui-selectmenu-button:focus{color:#016087;border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent}.toplevel_page_mlang .ui-menu-item{color:#016087}.ui-widget-content .ui-state-active,.ui-widget-content .ui-state-focus,.ui-widget-content .ui-state-hover{background:#d5d5d5}.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:"";background:#fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0 top 55%;background-size:16px 16px;box-sizing:border-box;position:absolute;width:16px;height:16px}.pll-wizard .ui-button:focus,.pll-wizard .ui-button:hover{background:#fff}.ui-widget-content{max-height:231px;box-shadow:0 2px 6px rgba(100,100,100,.3)}
|
|
frontend/accept-language.php
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class Accept_Language.
|
8 |
+
*
|
9 |
+
* Represents an Accept-Language HTTP Header, as defined in RFC 2616 Section 14.4 {@see https://tools.ietf.org/html/rfc2616.html#section-14.4}.
|
10 |
+
*
|
11 |
+
* @since 3.0
|
12 |
+
*/
|
13 |
+
class PLL_Accept_Language {
|
14 |
+
const SUBTAG_PATTERNS = array(
|
15 |
+
'language' => '(\b[a-z]{2,3}|[a-z]{4}|[a-z]{5-8}\b)',
|
16 |
+
'language-extension' => '(?:-(\b[a-z]{3}){1,3}\b)?',
|
17 |
+
'script' => '(?:-(\b[a-z]{4})\b)?',
|
18 |
+
'region' => '(?:-(\b[a-z]{2}|[0-9]{3})\b)?',
|
19 |
+
'variant' => '(?:-(\b[0-9][a-z]{1,3}|[a-z][a-z0-9]{4,7})\b)?',
|
20 |
+
'extension' => '(?:-(\b[a-wy-z]-[a-z0-9]{2,8})\b)?',
|
21 |
+
'private-use' => '(?:-(\bx-[a-z0-9]{1,8})\b)?',
|
22 |
+
);
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var string[] {
|
26 |
+
* @type string $language Usually 2 or three letters (ISO 639).
|
27 |
+
* @type string $language-extension Up to three groups of 3 letters.
|
28 |
+
* @type string $script Four letters.
|
29 |
+
* @type string $region Either two letters of three digits.
|
30 |
+
* @type string $variant Either one digit followed by 1 to 3 letters, or a letter followed by 2 to 7 alphanumerical characters.
|
31 |
+
* @type string $extension One letter that cannot be an 'x', followed by 2 to 8 alphanumerical characters.
|
32 |
+
* @type string $private-use Starts by 'x-', followed by 1 to 8 alphanumerical characters.
|
33 |
+
* }
|
34 |
+
*/
|
35 |
+
protected $subtags;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var float
|
39 |
+
*/
|
40 |
+
protected $quality;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* PLL_Accept_Language constructor.
|
44 |
+
*
|
45 |
+
* @since 3.0
|
46 |
+
*
|
47 |
+
* @param string[] $subtags With subtag name as keys and subtag values as names.
|
48 |
+
* @param float $quality
|
49 |
+
*/
|
50 |
+
public function __construct( $subtags, $quality = 1.0 ) {
|
51 |
+
$this->subtags = $subtags;
|
52 |
+
$this->quality = $quality;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Creates a new instance from an array resulting of a PHP {@see preg_match()} or {@see preg_match_all()} call.
|
57 |
+
*
|
58 |
+
* @since 3.0
|
59 |
+
*
|
60 |
+
* @param string[] $matches Expects first entry to be full match, following entries to be subtags and last entry to be quality factor.
|
61 |
+
* @return PLL_Accept_Language
|
62 |
+
*/
|
63 |
+
public static function from_array( $matches ) {
|
64 |
+
$subtags = array_combine(
|
65 |
+
array_keys( array_slice( self::SUBTAG_PATTERNS, 0, count( $matches ) - 1 ) ),
|
66 |
+
array_slice( $matches, 1, count( self::SUBTAG_PATTERNS ) )
|
67 |
+
);
|
68 |
+
$quality = count( $matches ) === 9 ? floatval( $matches[8] ) : 1.0;
|
69 |
+
|
70 |
+
return new PLL_Accept_Language( $subtags, $quality );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Returns the full language tag.
|
75 |
+
*
|
76 |
+
* @since 3.0
|
77 |
+
*
|
78 |
+
* @return string
|
79 |
+
*/
|
80 |
+
public function __toString() {
|
81 |
+
$subtags = array_filter(
|
82 |
+
$this->subtags,
|
83 |
+
function ( $subtag ) {
|
84 |
+
return ! empty( trim( $subtag ) );
|
85 |
+
}
|
86 |
+
);
|
87 |
+
return implode( '-', $subtags );
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Returns the quality factor as negotiated by the browser agent.
|
92 |
+
*
|
93 |
+
* @since 3.0
|
94 |
+
*
|
95 |
+
* @return float
|
96 |
+
*/
|
97 |
+
public function get_quality() {
|
98 |
+
return $this->quality;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns a subtag from the language tag.
|
103 |
+
*
|
104 |
+
* @since 3.0
|
105 |
+
*
|
106 |
+
* @param string $name A valid subtag name, {@see PLL_Accept_Language::SUBTAG_PATTERNS} for available subtag names.
|
107 |
+
* @return string
|
108 |
+
*/
|
109 |
+
public function get_subtag( $name ) {
|
110 |
+
return isset( $this->subtags[ $name ] ) ? $this->subtags[ $name ] : '';
|
111 |
+
}
|
112 |
+
}
|
frontend/accept-languages-collection.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class PLL_Accept_Languages_Collection.
|
8 |
+
*
|
9 |
+
* Represents a collection of values parsed from an Accept-Language HTTP header.
|
10 |
+
*
|
11 |
+
* @since 3.0
|
12 |
+
*/
|
13 |
+
class PLL_Accept_Languages_Collection {
|
14 |
+
/**
|
15 |
+
* @var PLL_Accept_Language[]
|
16 |
+
*/
|
17 |
+
protected $accept_languages = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Parse Accept-Language HTTP header according to IETF BCP 47.
|
21 |
+
*
|
22 |
+
* @since 3.0
|
23 |
+
*
|
24 |
+
* @param string $http_header Value of the Accept-Language HTTP Header. Formatted as stated BCP 47 for language tags {@see https://tools.ietf.org/html/bcp47}.
|
25 |
+
* @return PLL_Accept_Languages_Collection
|
26 |
+
*/
|
27 |
+
public static function from_accept_language_header( $http_header ) {
|
28 |
+
$lang_parse = array();
|
29 |
+
// Break up string into pieces ( languages and q factors ).
|
30 |
+
$language_pattern = implode( '', PLL_Accept_Language::SUBTAG_PATTERNS );
|
31 |
+
$quality_pattern = '\s*;\s*q\s*=\s*((?>1|0)(?>\.[0-9]+)?)';
|
32 |
+
$full_pattern = "/{$language_pattern}(?:{$quality_pattern})?/i";
|
33 |
+
|
34 |
+
preg_match_all(
|
35 |
+
$full_pattern,
|
36 |
+
$http_header,
|
37 |
+
$lang_parse,
|
38 |
+
PREG_SET_ORDER
|
39 |
+
);
|
40 |
+
|
41 |
+
return new PLL_Accept_Languages_Collection(
|
42 |
+
array_map(
|
43 |
+
array( PLL_Accept_Language::class, 'from_array' ),
|
44 |
+
$lang_parse
|
45 |
+
)
|
46 |
+
);
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* PLL_Accept_Languages_Collection constructor.
|
51 |
+
*
|
52 |
+
* @since 3.0
|
53 |
+
*
|
54 |
+
* @param PLL_Accept_Language[] $accept_languages
|
55 |
+
*/
|
56 |
+
public function __construct( $accept_languages = array() ) {
|
57 |
+
$this->accept_languages = $accept_languages;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Bubble sort ( need a stable sort for Android, so can't use a PHP sort function ).
|
62 |
+
*
|
63 |
+
* @since 3.0
|
64 |
+
*
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public function bubble_sort() {
|
68 |
+
$k = $this->accept_languages;
|
69 |
+
$v = array_map(
|
70 |
+
function ( $accept_lang ) {
|
71 |
+
return $accept_lang->get_quality();
|
72 |
+
},
|
73 |
+
$this->accept_languages
|
74 |
+
);
|
75 |
+
|
76 |
+
if ( $n = count( $k ) ) {
|
77 |
+
// Set default to 1 for any without q factor.
|
78 |
+
foreach ( $v as $key => $val ) {
|
79 |
+
if ( '' === $val || (float) $val > 1 ) {
|
80 |
+
$v[ $key ] = 1;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
if ( $n > 1 ) {
|
85 |
+
for ( $i = 2; $i <= $n; $i++ ) {
|
86 |
+
for ( $j = 0; $j <= $n - 2; $j++ ) {
|
87 |
+
if ( $v[ $j ] < $v[ $j + 1 ] ) {
|
88 |
+
// Swap values.
|
89 |
+
$temp = $v[ $j ];
|
90 |
+
$v[ $j ] = $v[ $j + 1 ];
|
91 |
+
$v[ $j + 1 ] = $temp;
|
92 |
+
// Swap keys.
|
93 |
+
$temp = $k[ $j ];
|
94 |
+
$k[ $j ] = $k[ $j + 1 ];
|
95 |
+
$k[ $j + 1 ] = $temp;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
100 |
+
$this->accept_languages = array_filter(
|
101 |
+
$k,
|
102 |
+
function ( $accept_lang ) {
|
103 |
+
return $accept_lang->get_quality() > 0;
|
104 |
+
}
|
105 |
+
);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Looks through sorted list and use first one that matches our language list.
|
111 |
+
*
|
112 |
+
* @since 3.0
|
113 |
+
*
|
114 |
+
* @param PLL_Language[] $languages
|
115 |
+
* @return string|false A language slug if there's a match, false otherwise.
|
116 |
+
*/
|
117 |
+
public function find_best_match( $languages = array() ) {
|
118 |
+
foreach ( $this->accept_languages as $accept_lang ) {
|
119 |
+
// First loop to match the exact locale.
|
120 |
+
foreach ( $languages as $language ) {
|
121 |
+
if ( 0 === strcasecmp( $accept_lang, $language->get_locale( 'display' ) ) ) {
|
122 |
+
return $language->slug;
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
// In order of priority.
|
127 |
+
$subsets = array();
|
128 |
+
if ( ! empty( $accept_lang->get_subtag( 'region' ) ) ) {
|
129 |
+
$subsets[] = $accept_lang->get_subtag( 'language' ) . '-' . $accept_lang->get_subtag( 'region' );
|
130 |
+
$subsets[] = $accept_lang->get_subtag( 'region' );
|
131 |
+
}
|
132 |
+
if ( ! empty( $accept_lang->get_subtag( 'variant' ) ) ) {
|
133 |
+
$subsets[] = $accept_lang->get_subtag( 'language' ) . '-' . $accept_lang->get_subtag( 'variant' );
|
134 |
+
}
|
135 |
+
$subsets[] = $accept_lang->get_subtag( 'language' );
|
136 |
+
|
137 |
+
// More loops to match the subsets.
|
138 |
+
foreach ( $languages as $language ) {
|
139 |
+
foreach ( $subsets as $subset ) {
|
140 |
+
|
141 |
+
if ( 0 === stripos( $subset, $language->slug ) || 0 === stripos( $language->get_locale( 'display' ), $subset ) ) {
|
142 |
+
return $language->slug;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
}
|
frontend/choose-lang-content.php
CHANGED
@@ -15,6 +15,8 @@ class PLL_Choose_Lang_Content extends PLL_Choose_Lang {
|
|
15 |
* Defers the language choice to the 'wp' action (when the content is known)
|
16 |
*
|
17 |
* @since 1.8
|
|
|
|
|
18 |
*/
|
19 |
public function init() {
|
20 |
parent::init();
|
@@ -29,11 +31,12 @@ class PLL_Choose_Lang_Content extends PLL_Choose_Lang {
|
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
* Overwrites parent::set_language to remove the 'wp' action if the language is set before
|
33 |
*
|
34 |
* @since 1.2
|
35 |
*
|
36 |
-
* @param
|
|
|
37 |
*/
|
38 |
protected function set_language( $curlang ) {
|
39 |
parent::set_language( $curlang );
|
@@ -64,29 +67,31 @@ class PLL_Choose_Lang_Content extends PLL_Choose_Lang {
|
|
64 |
|
65 |
else {
|
66 |
foreach ( $this->model->get_translated_taxonomies() as $taxonomy ) {
|
67 |
-
|
|
|
68 |
$lang = $this->model->term->get_language( $var, $taxonomy );
|
69 |
}
|
70 |
}
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
-
*
|
75 |
*
|
76 |
* @since 0.9
|
77 |
*
|
78 |
-
* @param
|
79 |
*/
|
80 |
return apply_filters( 'pll_get_current_language', isset( $lang ) ? $lang : false );
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
* Sets the language for home page
|
85 |
-
*
|
86 |
*
|
87 |
* @since 1.2
|
88 |
*
|
89 |
-
* @param
|
|
|
90 |
*/
|
91 |
public function parse_main_query( $query ) {
|
92 |
if ( empty( $GLOBALS['wp_the_query'] ) || $query !== $GLOBALS['wp_the_query'] ) {
|
@@ -122,21 +127,23 @@ class PLL_Choose_Lang_Content extends PLL_Choose_Lang {
|
|
122 |
* Sets the language from content
|
123 |
*
|
124 |
* @since 1.2
|
|
|
|
|
125 |
*/
|
126 |
public function wp() {
|
127 |
// Nothing to do if the language has already been set ( although normally the filter has been removed )
|
128 |
-
if (
|
129 |
parent::set_language( $curlang );
|
130 |
}
|
131 |
}
|
132 |
|
133 |
/**
|
134 |
-
* If no language found by get_language_from_content,
|
135 |
*
|
136 |
* @since 0.9
|
137 |
*
|
138 |
-
* @param
|
139 |
-
* @return
|
140 |
*/
|
141 |
public function pll_get_current_language( $lang ) {
|
142 |
return ! $lang ? $this->get_preferred_language() : $lang;
|
15 |
* Defers the language choice to the 'wp' action (when the content is known)
|
16 |
*
|
17 |
* @since 1.8
|
18 |
+
*
|
19 |
+
* @return void
|
20 |
*/
|
21 |
public function init() {
|
22 |
parent::init();
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* Overwrites parent::set_language to remove the 'wp' action if the language is set before.
|
35 |
*
|
36 |
* @since 1.2
|
37 |
*
|
38 |
+
* @param PLL_Language $curlang Current language.
|
39 |
+
* @return void
|
40 |
*/
|
41 |
protected function set_language( $curlang ) {
|
42 |
parent::set_language( $curlang );
|
67 |
|
68 |
else {
|
69 |
foreach ( $this->model->get_translated_taxonomies() as $taxonomy ) {
|
70 |
+
$tax_object = get_taxonomy( $taxonomy );
|
71 |
+
if ( ! empty( $tax_object ) && $var = get_query_var( $tax_object->query_var ) ) {
|
72 |
$lang = $this->model->term->get_language( $var, $taxonomy );
|
73 |
}
|
74 |
}
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
+
* Filters the language before it is set from the content.
|
79 |
*
|
80 |
* @since 0.9
|
81 |
*
|
82 |
+
* @param PLL_Language|false $lang Language object or false if none was found.
|
83 |
*/
|
84 |
return apply_filters( 'pll_get_current_language', isset( $lang ) ? $lang : false );
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
+
* Sets the language for the home page.
|
89 |
+
* Adds the lang query var when querying archives with no language code.
|
90 |
*
|
91 |
* @since 1.2
|
92 |
*
|
93 |
+
* @param WP_Query $query Instance of WP_Query.
|
94 |
+
* @return void
|
95 |
*/
|
96 |
public function parse_main_query( $query ) {
|
97 |
if ( empty( $GLOBALS['wp_the_query'] ) || $query !== $GLOBALS['wp_the_query'] ) {
|
127 |
* Sets the language from content
|
128 |
*
|
129 |
* @since 1.2
|
130 |
+
*
|
131 |
+
* @return void
|
132 |
*/
|
133 |
public function wp() {
|
134 |
// Nothing to do if the language has already been set ( although normally the filter has been removed )
|
135 |
+
if ( empty( $this->curlang ) && $curlang = $this->get_language_from_content() ) {
|
136 |
parent::set_language( $curlang );
|
137 |
}
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* If no language is found by {@see PLL_Choose_Lang_Content::get_language_from_content()}, returns the preferred one.
|
142 |
*
|
143 |
* @since 0.9
|
144 |
*
|
145 |
+
* @param PLL_Language|false $lang Language found by {@see PLL_Choose_Lang_Content::get_language_from_content()}.
|
146 |
+
* @return PLL_Language
|
147 |
*/
|
148 |
public function pll_get_current_language( $lang ) {
|
149 |
return ! $lang ? $this->get_preferred_language() : $lang;
|
frontend/choose-lang-domain.php
CHANGED
@@ -14,6 +14,8 @@ class PLL_Choose_Lang_Domain extends PLL_Choose_Lang_Url {
|
|
14 |
* Don't set any language cookie
|
15 |
*
|
16 |
* @since 1.5
|
|
|
|
|
17 |
*/
|
18 |
public function maybe_setcookie() {}
|
19 |
|
@@ -21,6 +23,8 @@ class PLL_Choose_Lang_Domain extends PLL_Choose_Lang_Url {
|
|
21 |
* Don't redirect according to browser preferences
|
22 |
*
|
23 |
* @since 1.5
|
|
|
|
|
24 |
*/
|
25 |
public function get_preferred_language() {
|
26 |
return $this->model->get_language( $this->links_model->get_language_from_url() );
|
@@ -30,6 +34,8 @@ class PLL_Choose_Lang_Domain extends PLL_Choose_Lang_Url {
|
|
30 |
* Adds query vars to query for home pages in all languages
|
31 |
*
|
32 |
* @since 1.5
|
|
|
|
|
33 |
*/
|
34 |
public function home_requested() {
|
35 |
$this->set_curlang_in_query( $GLOBALS['wp_query'] );
|
14 |
* Don't set any language cookie
|
15 |
*
|
16 |
* @since 1.5
|
17 |
+
*
|
18 |
+
* @return void
|
19 |
*/
|
20 |
public function maybe_setcookie() {}
|
21 |
|
23 |
* Don't redirect according to browser preferences
|
24 |
*
|
25 |
* @since 1.5
|
26 |
+
*
|
27 |
+
* @return PLL_Language
|
28 |
*/
|
29 |
public function get_preferred_language() {
|
30 |
return $this->model->get_language( $this->links_model->get_language_from_url() );
|
34 |
* Adds query vars to query for home pages in all languages
|
35 |
*
|
36 |
* @since 1.5
|
37 |
+
*
|
38 |
+
* @return void
|
39 |
*/
|
40 |
public function home_requested() {
|
41 |
$this->set_curlang_in_query( $GLOBALS['wp_query'] );
|
frontend/choose-lang-url.php
CHANGED
@@ -11,12 +11,21 @@
|
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Choose_Lang_Url extends PLL_Choose_Lang {
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
/**
|
17 |
* Sets the language
|
18 |
*
|
19 |
* @since 1.8
|
|
|
|
|
20 |
*/
|
21 |
public function init() {
|
22 |
parent::init();
|
@@ -32,6 +41,8 @@ class PLL_Choose_Lang_Url extends PLL_Choose_Lang {
|
|
32 |
* Finds the language according to information found in the url
|
33 |
*
|
34 |
* @since 1.2
|
|
|
|
|
35 |
*/
|
36 |
public function set_language_from_url() {
|
37 |
$host = str_replace( 'www.', '', wp_parse_url( $this->links_model->home, PHP_URL_HOST ) ); // Remove www. for the comparison
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Choose_Lang_Url extends PLL_Choose_Lang {
|
14 |
+
/**
|
15 |
+
* The name of the index file which is the entry point to all requests.
|
16 |
+
* We need this before the global $wp_rewrite is created.
|
17 |
+
* Also hardcoded in WP_Rewrite.
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
protected $index = 'index.php';
|
22 |
|
23 |
/**
|
24 |
* Sets the language
|
25 |
*
|
26 |
* @since 1.8
|
27 |
+
*
|
28 |
+
* @return void
|
29 |
*/
|
30 |
public function init() {
|
31 |
parent::init();
|
41 |
* Finds the language according to information found in the url
|
42 |
*
|
43 |
* @since 1.2
|
44 |
+
*
|
45 |
+
* @return void
|
46 |
*/
|
47 |
public function set_language_from_url() {
|
48 |
$host = str_replace( 'www.', '', wp_parse_url( $this->links_model->home, PHP_URL_HOST ) ); // Remove www. for the comparison
|
frontend/choose-lang.php
CHANGED
@@ -9,8 +9,39 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
abstract class PLL_Choose_Lang {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
public $curlang;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor
|
@@ -33,6 +64,8 @@ abstract class PLL_Choose_Lang {
|
|
33 |
* Any child class must call this method if it overrides it
|
34 |
*
|
35 |
* @since 1.8
|
|
|
|
|
36 |
*/
|
37 |
public function init() {
|
38 |
if ( Polylang::is_ajax_on_front() || ! wp_using_themes() ) {
|
@@ -45,13 +78,13 @@ abstract class PLL_Choose_Lang {
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
-
*
|
49 |
-
*
|
50 |
-
* Fires the action 'pll_language_defined'
|
51 |
*
|
52 |
* @since 1.2
|
53 |
*
|
54 |
-
* @param
|
|
|
55 |
*/
|
56 |
protected function set_language( $curlang ) {
|
57 |
// Don't set the language a second time
|
@@ -67,12 +100,12 @@ abstract class PLL_Choose_Lang {
|
|
67 |
wp_styles()->text_direction = $GLOBALS['text_direction'];
|
68 |
|
69 |
/**
|
70 |
-
* Fires when the current language is defined
|
71 |
*
|
72 |
* @since 0.9.5
|
73 |
*
|
74 |
-
* @param string
|
75 |
-
* @param
|
76 |
*/
|
77 |
do_action( 'pll_language_defined', $this->curlang->slug, $this->curlang );
|
78 |
}
|
@@ -82,6 +115,8 @@ abstract class PLL_Choose_Lang {
|
|
82 |
* Setting PLL_COOKIE to false will disable cookie although it will break some functionalities
|
83 |
*
|
84 |
* @since 1.5
|
|
|
|
|
85 |
*/
|
86 |
public function maybe_setcookie() {
|
87 |
// Don't set cookie in javascript when a cache plugin is active.
|
@@ -95,85 +130,32 @@ abstract class PLL_Choose_Lang {
|
|
95 |
}
|
96 |
|
97 |
/**
|
98 |
-
* Get the preferred language according to the browser preferences
|
99 |
-
* Code adapted from http://www.thefutureoftheweb.com/blog/use-accept-language-header
|
100 |
*
|
101 |
* @since 1.8
|
102 |
*
|
103 |
-
* @return string|bool
|
104 |
*/
|
105 |
public function get_preferred_browser_language() {
|
106 |
-
$accept_langs = array();
|
107 |
-
|
108 |
if ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
|
109 |
-
|
110 |
-
preg_match_all(
|
111 |
-
'/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*((?>1|0)(?>\.[0-9]+)?))?/i',
|
112 |
-
sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ),
|
113 |
-
$lang_parse
|
114 |
-
);
|
115 |
-
|
116 |
-
$k = $lang_parse[1];
|
117 |
-
$v = $lang_parse[4];
|
118 |
-
|
119 |
-
if ( $n = count( $k ) ) {
|
120 |
-
// Set default to 1 for any without q factor
|
121 |
-
foreach ( $v as $key => $val ) {
|
122 |
-
if ( '' === $val || (float) $val > 1 ) {
|
123 |
-
$v[ $key ] = 1;
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
// Bubble sort ( need a stable sort for Android, so can't use a PHP sort function )
|
128 |
-
if ( $n > 1 ) {
|
129 |
-
for ( $i = 2; $i <= $n; $i++ ) {
|
130 |
-
for ( $j = 0; $j <= $n - 2; $j++ ) {
|
131 |
-
if ( $v[ $j ] < $v[ $j + 1 ] ) {
|
132 |
-
// Swap values
|
133 |
-
$temp = $v[ $j ];
|
134 |
-
$v[ $j ] = $v[ $j + 1 ];
|
135 |
-
$v[ $j + 1 ] = $temp;
|
136 |
-
// Swap keys
|
137 |
-
$temp = $k[ $j ];
|
138 |
-
$k[ $j ] = $k[ $j + 1 ];
|
139 |
-
$k[ $j + 1 ] = $temp;
|
140 |
-
}
|
141 |
-
}
|
142 |
-
}
|
143 |
-
}
|
144 |
-
$accept_langs = array_combine( $k, $v );
|
145 |
-
}
|
146 |
-
}
|
147 |
|
148 |
-
|
149 |
|
150 |
-
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
// Looks through sorted list and use first one that matches our language list
|
162 |
-
foreach ( array_keys( $accept_langs ) as $accept_lang ) {
|
163 |
-
// First loop to match the exact locale
|
164 |
-
foreach ( $languages as $language ) {
|
165 |
-
if ( 0 === strcasecmp( $accept_lang, $language->get_locale( 'display' ) ) ) {
|
166 |
-
return $language->slug;
|
167 |
-
}
|
168 |
-
}
|
169 |
|
170 |
-
|
171 |
-
foreach ( $languages as $language ) {
|
172 |
-
if ( 0 === stripos( $accept_lang, $language->slug ) || 0 === stripos( $language->get_locale( 'display' ), $accept_lang ) ) {
|
173 |
-
return $language->slug;
|
174 |
-
}
|
175 |
-
}
|
176 |
}
|
|
|
177 |
return false;
|
178 |
}
|
179 |
|
@@ -221,6 +203,8 @@ abstract class PLL_Choose_Lang {
|
|
221 |
* Sets the language when home page is requested
|
222 |
*
|
223 |
* @since 1.2
|
|
|
|
|
224 |
*/
|
225 |
protected function home_language() {
|
226 |
// Test referer in case PLL_COOKIE is set to false. Since WP 3.6.1, wp_get_referer() validates the host which is exactly what we want
|
@@ -237,6 +221,8 @@ abstract class PLL_Choose_Lang {
|
|
237 |
* Performs a redirection to the home page in the current language if needed
|
238 |
*
|
239 |
* @since 0.9
|
|
|
|
|
240 |
*/
|
241 |
public function home_requested() {
|
242 |
// We are already on the right page
|
@@ -285,18 +271,20 @@ abstract class PLL_Choose_Lang {
|
|
285 |
* @since 0.8.4
|
286 |
*
|
287 |
* @param int $post_id the post being commented
|
|
|
288 |
*/
|
289 |
public function pre_comment_on_post( $post_id ) {
|
290 |
$this->set_language( $this->model->post->get_language( $post_id ) );
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
-
* Modifies some main query vars for home page and page for posts
|
295 |
-
* to enable one home page (
|
296 |
*
|
297 |
* @since 1.2
|
298 |
*
|
299 |
-
* @param
|
|
|
300 |
*/
|
301 |
public function parse_main_query( $query ) {
|
302 |
if ( ! $query->is_main_query() ) {
|
@@ -308,8 +296,8 @@ abstract class PLL_Choose_Lang {
|
|
308 |
*
|
309 |
* @since 1.8
|
310 |
*
|
311 |
-
* @param
|
312 |
-
* @param
|
313 |
*/
|
314 |
if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) {
|
315 |
$this->set_language( $lang );
|
@@ -328,11 +316,12 @@ abstract class PLL_Choose_Lang {
|
|
328 |
}
|
329 |
|
330 |
/**
|
331 |
-
* Sets the current language in the query
|
332 |
*
|
333 |
* @since 2.2
|
334 |
*
|
335 |
-
* @param
|
|
|
336 |
*/
|
337 |
protected function set_curlang_in_query( &$query ) {
|
338 |
$pll_query = new PLL_Query( $query, $this->model );
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
abstract class PLL_Choose_Lang {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
public $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Instance of a child class of PLL_Links_Model.
|
26 |
+
*
|
27 |
+
* @var PLL_Links_Model
|
28 |
+
*/
|
29 |
+
public $links_model;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Current language.
|
33 |
+
*
|
34 |
+
* @var PLL_Language
|
35 |
+
*/
|
36 |
public $curlang;
|
37 |
+
/**
|
38 |
+
* @var PLL_Accept_Language
|
39 |
+
*/
|
40 |
+
private $lang_parse;
|
41 |
+
/**
|
42 |
+
* @var PLL_Accept_Languages_Collection
|
43 |
+
*/
|
44 |
+
private $accept_langs;
|
45 |
|
46 |
/**
|
47 |
* Constructor
|
64 |
* Any child class must call this method if it overrides it
|
65 |
*
|
66 |
* @since 1.8
|
67 |
+
*
|
68 |
+
* @return void
|
69 |
*/
|
70 |
public function init() {
|
71 |
if ( Polylang::is_ajax_on_front() || ! wp_using_themes() ) {
|
78 |
}
|
79 |
|
80 |
/**
|
81 |
+
* Sets the current language
|
82 |
+
* and fires the action 'pll_language_defined'.
|
|
|
83 |
*
|
84 |
* @since 1.2
|
85 |
*
|
86 |
+
* @param PLL_Language $curlang Current language.
|
87 |
+
* @return void
|
88 |
*/
|
89 |
protected function set_language( $curlang ) {
|
90 |
// Don't set the language a second time
|
100 |
wp_styles()->text_direction = $GLOBALS['text_direction'];
|
101 |
|
102 |
/**
|
103 |
+
* Fires when the current language is defined.
|
104 |
*
|
105 |
* @since 0.9.5
|
106 |
*
|
107 |
+
* @param string $slug Current language code.
|
108 |
+
* @param PLL_Language $curlang Current language object.
|
109 |
*/
|
110 |
do_action( 'pll_language_defined', $this->curlang->slug, $this->curlang );
|
111 |
}
|
115 |
* Setting PLL_COOKIE to false will disable cookie although it will break some functionalities
|
116 |
*
|
117 |
* @since 1.5
|
118 |
+
*
|
119 |
+
* @return void
|
120 |
*/
|
121 |
public function maybe_setcookie() {
|
122 |
// Don't set cookie in javascript when a cache plugin is active.
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
+
* Get the preferred language according to the browser preferences.
|
|
|
134 |
*
|
135 |
* @since 1.8
|
136 |
*
|
137 |
+
* @return string|bool The preferred language slug or false.
|
138 |
*/
|
139 |
public function get_preferred_browser_language() {
|
|
|
|
|
140 |
if ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) {
|
141 |
+
$accept_langs = PLL_Accept_Languages_Collection::from_accept_language_header( sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
|
143 |
+
$accept_langs->bubble_sort();
|
144 |
|
145 |
+
$languages = $this->model->get_languages_list( array( 'hide_empty' => true ) ); // Hides languages with no post.
|
146 |
|
147 |
+
/**
|
148 |
+
* Filters the list of languages to use to match the browser preferences.
|
149 |
+
*
|
150 |
+
* @since 1.9.3
|
151 |
+
*
|
152 |
+
* @param array $languages Array of PLL_Language objects.
|
153 |
+
*/
|
154 |
+
$languages = apply_filters( 'pll_languages_for_browser_preferences', $languages );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
+
return $accept_langs->find_best_match( $languages );
|
|
|
|
|
|
|
|
|
|
|
157 |
}
|
158 |
+
|
159 |
return false;
|
160 |
}
|
161 |
|
203 |
* Sets the language when home page is requested
|
204 |
*
|
205 |
* @since 1.2
|
206 |
+
*
|
207 |
+
* @return void
|
208 |
*/
|
209 |
protected function home_language() {
|
210 |
// Test referer in case PLL_COOKIE is set to false. Since WP 3.6.1, wp_get_referer() validates the host which is exactly what we want
|
221 |
* Performs a redirection to the home page in the current language if needed
|
222 |
*
|
223 |
* @since 0.9
|
224 |
+
*
|
225 |
+
* @return void
|
226 |
*/
|
227 |
public function home_requested() {
|
228 |
// We are already on the right page
|
271 |
* @since 0.8.4
|
272 |
*
|
273 |
* @param int $post_id the post being commented
|
274 |
+
* @return void
|
275 |
*/
|
276 |
public function pre_comment_on_post( $post_id ) {
|
277 |
$this->set_language( $this->model->post->get_language( $post_id ) );
|
278 |
}
|
279 |
|
280 |
/**
|
281 |
+
* Modifies some main query vars for the home page and the page for posts
|
282 |
+
* to enable one home page (and one page for posts) per language.
|
283 |
*
|
284 |
* @since 1.2
|
285 |
*
|
286 |
+
* @param WP_Query $query Instance of WP_Query.
|
287 |
+
* @return void
|
288 |
*/
|
289 |
public function parse_main_query( $query ) {
|
290 |
if ( ! $query->is_main_query() ) {
|
296 |
*
|
297 |
* @since 1.8
|
298 |
*
|
299 |
+
* @param PLL_Language|false $lang Language object or false.
|
300 |
+
* @param WP_Query $query WP_Query object.
|
301 |
*/
|
302 |
if ( $lang = apply_filters( 'pll_set_language_from_query', false, $query ) ) {
|
303 |
$this->set_language( $lang );
|
316 |
}
|
317 |
|
318 |
/**
|
319 |
+
* Sets the current language in the query.
|
320 |
*
|
321 |
* @since 2.2
|
322 |
*
|
323 |
+
* @param WP_Query $query Instance of WP_Query.
|
324 |
+
* @return void
|
325 |
*/
|
326 |
protected function set_curlang_in_query( &$query ) {
|
327 |
$pll_query = new PLL_Query( $query, $this->model );
|
frontend/frontend-auto-translate.php
CHANGED
@@ -10,7 +10,17 @@
|
|
10 |
* @since 1.1
|
11 |
*/
|
12 |
class PLL_Frontend_Auto_Translate {
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor
|
@@ -56,7 +66,8 @@ class PLL_Frontend_Auto_Translate {
|
|
56 |
*
|
57 |
* @since 1.1
|
58 |
*
|
59 |
-
* @param
|
|
|
60 |
*/
|
61 |
public function pre_get_posts( $query ) {
|
62 |
global $wpdb;
|
@@ -133,7 +144,7 @@ class PLL_Frontend_Auto_Translate {
|
|
133 |
foreach ( array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) ) as $taxonomy ) {
|
134 |
$tax = get_taxonomy( $taxonomy );
|
135 |
$arr = array();
|
136 |
-
if ( ! empty( $qv[ $tax->query_var ] ) ) {
|
137 |
$sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // Two possible separators
|
138 |
foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) {
|
139 |
$arr[] = $this->get_translated_term_by( 'slug', $slug, $taxonomy );
|
10 |
* @since 1.1
|
11 |
*/
|
12 |
class PLL_Frontend_Auto_Translate {
|
13 |
+
/**
|
14 |
+
* @var PLL_Model
|
15 |
+
*/
|
16 |
+
public $model;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Current language.
|
20 |
+
*
|
21 |
+
* @var PLL_Language
|
22 |
+
*/
|
23 |
+
public $curlang;
|
24 |
|
25 |
/**
|
26 |
* Constructor
|
66 |
*
|
67 |
* @since 1.1
|
68 |
*
|
69 |
+
* @param WP_Query $query WP_Query object
|
70 |
+
* @return void
|
71 |
*/
|
72 |
public function pre_get_posts( $query ) {
|
73 |
global $wpdb;
|
144 |
foreach ( array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) ) as $taxonomy ) {
|
145 |
$tax = get_taxonomy( $taxonomy );
|
146 |
$arr = array();
|
147 |
+
if ( ! empty( $tax ) && ! empty( $qv[ $tax->query_var ] ) ) {
|
148 |
$sep = strpos( $qv[ $tax->query_var ], ',' ) !== false ? ',' : '+'; // Two possible separators
|
149 |
foreach ( explode( $sep, $qv[ $tax->query_var ] ) as $slug ) {
|
150 |
$arr[] = $this->get_translated_term_by( 'slug', $slug, $taxonomy );
|
frontend/frontend-filters-links.php
CHANGED
@@ -9,6 +9,12 @@
|
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Our internal non persistent cache object
|
14 |
*
|
@@ -125,13 +131,13 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
125 |
|
126 |
/**
|
127 |
* Modifies custom posts links
|
128 |
-
* and caches the result
|
129 |
*
|
130 |
* @since 1.6
|
131 |
*
|
132 |
-
* @param string
|
133 |
-
* @param
|
134 |
-
* @return string
|
135 |
*/
|
136 |
public function post_type_link( $link, $post ) {
|
137 |
$cache_key = "post:{$post->ID}:{$link}";
|
@@ -144,14 +150,14 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
144 |
|
145 |
/**
|
146 |
* Modifies filtered taxonomies ( post format like ) and translated taxonomies links
|
147 |
-
* and caches the result
|
148 |
*
|
149 |
* @since 0.7
|
150 |
*
|
151 |
-
* @param string
|
152 |
-
* @param
|
153 |
-
* @param string
|
154 |
-
* @return string
|
155 |
*/
|
156 |
public function term_link( $link, $term, $tax ) {
|
157 |
$cache_key = "term:{$term->term_id}:{$link}";
|
@@ -178,7 +184,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
178 |
*
|
179 |
* @param string $link Post permalink.
|
180 |
* @param int $post_id Post id.
|
181 |
-
* @return Post permalink with the correct domain.
|
182 |
*/
|
183 |
public function shortlink( $link, $post_id ) {
|
184 |
$post_type = get_post_type( $post_id );
|
@@ -189,6 +195,8 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
189 |
* Outputs references to translated pages ( if exists ) in the html head section
|
190 |
*
|
191 |
* @since 0.1
|
|
|
|
|
192 |
*/
|
193 |
public function wp_head() {
|
194 |
// Don't output anything on paged archives: see https://wordpress.org/support/topic/hreflang-on-page2
|
@@ -345,30 +353,30 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
345 |
}
|
346 |
|
347 |
/**
|
348 |
-
* If the language code is not in agreement with the language of the content
|
349 |
-
* redirects incoming links to the proper URL to avoid duplicate content
|
350 |
*
|
351 |
* @since 0.9.6
|
352 |
*
|
353 |
-
* @param string $requested_url
|
354 |
-
* @param bool $do_redirect
|
355 |
-
* @return string if redirect is not performed
|
356 |
*/
|
357 |
public function check_canonical_url( $requested_url = '', $do_redirect = true ) {
|
358 |
-
|
359 |
-
|
360 |
-
// Don't redirect in same cases as WP
|
361 |
-
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $is_IIS && ! iis7_supports_permalinks() ) ) {
|
362 |
return;
|
363 |
}
|
364 |
|
365 |
-
// Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id
|
366 |
if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
367 |
return;
|
368 |
}
|
369 |
|
370 |
-
|
371 |
-
|
|
|
|
|
372 |
if ( is_customize_preview() ) {
|
373 |
return;
|
374 |
}
|
@@ -378,15 +386,16 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
378 |
}
|
379 |
|
380 |
if ( is_single() || is_page() ) {
|
381 |
-
|
|
|
382 |
$language = $this->model->post->get_language( (int) $post->ID );
|
383 |
}
|
384 |
}
|
385 |
|
386 |
-
elseif ( $this->links_model->using_permalinks && is_category() && ! empty( $wp_query->query['cat'] ) ) {
|
387 |
// When we receive a plain permaling with a cat query var, we need to redirect to the pretty permalink.
|
388 |
-
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $wp_query->tax_query ) ) ) {
|
389 |
-
$term_id = $this->get_queried_term_id( $wp_query->tax_query );
|
390 |
$language = $this->model->term->get_language( $term_id );
|
391 |
$redirect_url = $this->maybe_add_page_to_redirect_url( get_term_link( $term_id ) );
|
392 |
}
|
@@ -394,28 +403,30 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
394 |
|
395 |
elseif ( is_category() || is_tag() || is_tax() ) {
|
396 |
// We need to switch the language when there is no language provided in a pretty permalink.
|
397 |
-
$obj =
|
398 |
if ( ! empty( $obj ) && $this->model->is_translated_taxonomy( $obj->taxonomy ) ) {
|
399 |
$language = $this->model->term->get_language( (int) $obj->term_id );
|
400 |
}
|
401 |
}
|
402 |
|
403 |
-
elseif ( is_404() && ! empty( $wp_query->tax_query ) ) {
|
404 |
// When a wrong language is passed through a pretty permalink, we just need to switch the language.
|
405 |
-
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $wp_query->tax_query ) ) ) {
|
406 |
-
$term_id = $this->get_queried_term_id( $wp_query->tax_query );
|
407 |
$language = $this->model->term->get_language( $term_id );
|
408 |
}
|
409 |
}
|
410 |
|
411 |
-
elseif ( $this->links_model->using_permalinks && $wp_query->is_posts_page && ! empty( $wp_query->query['page_id'] ) && $id = get_query_var( 'page_id' ) ) {
|
412 |
$language = $this->model->post->get_language( (int) $id );
|
413 |
$redirect_url = $this->maybe_add_page_to_redirect_url( get_permalink( $id ) );
|
414 |
}
|
415 |
|
416 |
-
elseif ( $wp_query->is_posts_page ) {
|
417 |
-
$obj =
|
418 |
-
|
|
|
|
|
419 |
}
|
420 |
|
421 |
if ( 3 === $this->options['force_lang'] ) {
|
@@ -445,19 +456,24 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
445 |
}
|
446 |
|
447 |
/**
|
448 |
-
* Filters the canonical url detected by Polylang
|
449 |
*
|
450 |
* @since 1.6
|
451 |
*
|
452 |
-
* @param
|
453 |
-
* @param
|
454 |
*/
|
455 |
$redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language );
|
456 |
|
457 |
// The language is not correctly set so let's redirect to the correct url for this object
|
458 |
-
if ( $do_redirect
|
459 |
-
|
460 |
-
|
|
|
|
|
|
|
|
|
|
|
461 |
}
|
462 |
|
463 |
return $redirect_url;
|
@@ -472,9 +488,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
472 |
* @return string
|
473 |
*/
|
474 |
protected function maybe_add_page_to_redirect_url( $redirect_url ) {
|
475 |
-
|
476 |
-
|
477 |
-
if ( ! empty( $wp_query->query['paged'] ) && $page = get_query_var( 'paged' ) ) {
|
478 |
$redirect_url = $this->links_model->add_paged_to_link( $redirect_url, $page );
|
479 |
}
|
480 |
return $redirect_url;
|
@@ -485,7 +499,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
485 |
*
|
486 |
* @since 2.9
|
487 |
*
|
488 |
-
* @param
|
489 |
* @return int
|
490 |
*/
|
491 |
protected function get_queried_term_id( $tax_query ) {
|
@@ -517,7 +531,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
517 |
*
|
518 |
* @since 2.9
|
519 |
*
|
520 |
-
* @param
|
521 |
* @return string A taxonomy slug
|
522 |
*/
|
523 |
protected function get_queried_taxonomy( $tax_query ) {
|
@@ -526,4 +540,15 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
526 |
|
527 |
return key( $queried_terms );
|
528 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
529 |
}
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var PLL_Frontend_Links
|
15 |
+
*/
|
16 |
+
public $links;
|
17 |
+
|
18 |
/**
|
19 |
* Our internal non persistent cache object
|
20 |
*
|
131 |
|
132 |
/**
|
133 |
* Modifies custom posts links
|
134 |
+
* and caches the result.
|
135 |
*
|
136 |
* @since 1.6
|
137 |
*
|
138 |
+
* @param string $link Post link.
|
139 |
+
* @param WP_Post $post Post object.
|
140 |
+
* @return string Modified post link.
|
141 |
*/
|
142 |
public function post_type_link( $link, $post ) {
|
143 |
$cache_key = "post:{$post->ID}:{$link}";
|
150 |
|
151 |
/**
|
152 |
* Modifies filtered taxonomies ( post format like ) and translated taxonomies links
|
153 |
+
* and caches the result.
|
154 |
*
|
155 |
* @since 0.7
|
156 |
*
|
157 |
+
* @param string $link Term link.
|
158 |
+
* @param WP_Term $term Term object.
|
159 |
+
* @param string $tax Taxonomy name.
|
160 |
+
* @return string Modified link.
|
161 |
*/
|
162 |
public function term_link( $link, $term, $tax ) {
|
163 |
$cache_key = "term:{$term->term_id}:{$link}";
|
184 |
*
|
185 |
* @param string $link Post permalink.
|
186 |
* @param int $post_id Post id.
|
187 |
+
* @return string Post permalink with the correct domain.
|
188 |
*/
|
189 |
public function shortlink( $link, $post_id ) {
|
190 |
$post_type = get_post_type( $post_id );
|
195 |
* Outputs references to translated pages ( if exists ) in the html head section
|
196 |
*
|
197 |
* @since 0.1
|
198 |
+
*
|
199 |
+
* @return void
|
200 |
*/
|
201 |
public function wp_head() {
|
202 |
// Don't output anything on paged archives: see https://wordpress.org/support/topic/hreflang-on-page2
|
353 |
}
|
354 |
|
355 |
/**
|
356 |
+
* If the language code is not in agreement with the language of the content,
|
357 |
+
* redirects incoming links to the proper URL to avoid duplicate content.
|
358 |
*
|
359 |
* @since 0.9.6
|
360 |
*
|
361 |
+
* @param string $requested_url Optional, defaults to requested url.
|
362 |
+
* @param bool $do_redirect Optional, whether to perform the redirect or not.
|
363 |
+
* @return string|void Returns if redirect is not performed.
|
364 |
*/
|
365 |
public function check_canonical_url( $requested_url = '', $do_redirect = true ) {
|
366 |
+
// Don't redirect in same cases as WP.
|
367 |
+
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $GLOBALS['is_IIS'] && ! iis7_supports_permalinks() ) ) {
|
|
|
|
|
368 |
return;
|
369 |
}
|
370 |
|
371 |
+
// Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id=.
|
372 |
if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
373 |
return;
|
374 |
}
|
375 |
|
376 |
+
/*
|
377 |
+
* If the default language code is not hidden and the static front page url contains the page name,
|
378 |
+
* the customizer lands here and the code below would redirect to the list of posts.
|
379 |
+
*/
|
380 |
if ( is_customize_preview() ) {
|
381 |
return;
|
382 |
}
|
386 |
}
|
387 |
|
388 |
if ( is_single() || is_page() ) {
|
389 |
+
$post = get_post();
|
390 |
+
if ( $post instanceof WP_Post && $this->model->is_translated_post_type( $post->post_type ) ) {
|
391 |
$language = $this->model->post->get_language( (int) $post->ID );
|
392 |
}
|
393 |
}
|
394 |
|
395 |
+
elseif ( $this->links_model->using_permalinks && is_category() && ! empty( $this->wp_query()->query['cat'] ) ) {
|
396 |
// When we receive a plain permaling with a cat query var, we need to redirect to the pretty permalink.
|
397 |
+
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $this->wp_query()->tax_query ) ) ) {
|
398 |
+
$term_id = $this->get_queried_term_id( $this->wp_query()->tax_query );
|
399 |
$language = $this->model->term->get_language( $term_id );
|
400 |
$redirect_url = $this->maybe_add_page_to_redirect_url( get_term_link( $term_id ) );
|
401 |
}
|
403 |
|
404 |
elseif ( is_category() || is_tag() || is_tax() ) {
|
405 |
// We need to switch the language when there is no language provided in a pretty permalink.
|
406 |
+
$obj = get_queried_object();
|
407 |
if ( ! empty( $obj ) && $this->model->is_translated_taxonomy( $obj->taxonomy ) ) {
|
408 |
$language = $this->model->term->get_language( (int) $obj->term_id );
|
409 |
}
|
410 |
}
|
411 |
|
412 |
+
elseif ( is_404() && ! empty( $this->wp_query()->tax_query ) ) {
|
413 |
// When a wrong language is passed through a pretty permalink, we just need to switch the language.
|
414 |
+
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $this->wp_query()->tax_query ) ) ) {
|
415 |
+
$term_id = $this->get_queried_term_id( $this->wp_query()->tax_query );
|
416 |
$language = $this->model->term->get_language( $term_id );
|
417 |
}
|
418 |
}
|
419 |
|
420 |
+
elseif ( $this->links_model->using_permalinks && $this->wp_query()->is_posts_page && ! empty( $this->wp_query()->query['page_id'] ) && $id = get_query_var( 'page_id' ) ) {
|
421 |
$language = $this->model->post->get_language( (int) $id );
|
422 |
$redirect_url = $this->maybe_add_page_to_redirect_url( get_permalink( $id ) );
|
423 |
}
|
424 |
|
425 |
+
elseif ( $this->wp_query()->is_posts_page ) {
|
426 |
+
$obj = get_queried_object();
|
427 |
+
if ( $obj instanceof WP_Post ) {
|
428 |
+
$language = $this->model->post->get_language( (int) $obj->ID );
|
429 |
+
}
|
430 |
}
|
431 |
|
432 |
if ( 3 === $this->options['force_lang'] ) {
|
456 |
}
|
457 |
|
458 |
/**
|
459 |
+
* Filters the canonical url detected by Polylang.
|
460 |
*
|
461 |
* @since 1.6
|
462 |
*
|
463 |
+
* @param string|false $redirect_url False or the url to redirect to.
|
464 |
+
* @param PLL_Language $language The language detected.
|
465 |
*/
|
466 |
$redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language );
|
467 |
|
468 |
// The language is not correctly set so let's redirect to the correct url for this object
|
469 |
+
if ( $do_redirect ) {
|
470 |
+
// Protect against chained redirects.
|
471 |
+
if ( $redirect_url && $requested_url != $redirect_url && $redirect_url === $this->check_canonical_url( $redirect_url, false ) ) {
|
472 |
+
wp_safe_redirect( $redirect_url, 301, POLYLANG );
|
473 |
+
exit;
|
474 |
+
} else {
|
475 |
+
return;
|
476 |
+
}
|
477 |
}
|
478 |
|
479 |
return $redirect_url;
|
488 |
* @return string
|
489 |
*/
|
490 |
protected function maybe_add_page_to_redirect_url( $redirect_url ) {
|
491 |
+
if ( ! empty( $this->wp_query()->query['paged'] ) && $page = get_query_var( 'paged' ) ) {
|
|
|
|
|
492 |
$redirect_url = $this->links_model->add_paged_to_link( $redirect_url, $page );
|
493 |
}
|
494 |
return $redirect_url;
|
499 |
*
|
500 |
* @since 2.9
|
501 |
*
|
502 |
+
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
503 |
* @return int
|
504 |
*/
|
505 |
protected function get_queried_term_id( $tax_query ) {
|
531 |
*
|
532 |
* @since 2.9
|
533 |
*
|
534 |
+
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
535 |
* @return string A taxonomy slug
|
536 |
*/
|
537 |
protected function get_queried_taxonomy( $tax_query ) {
|
540 |
|
541 |
return key( $queried_terms );
|
542 |
}
|
543 |
+
|
544 |
+
/**
|
545 |
+
* Returns the Global WordPress WP_Query object.
|
546 |
+
*
|
547 |
+
* @since 3.0
|
548 |
+
*
|
549 |
+
* @return WP_Query
|
550 |
+
*/
|
551 |
+
protected function wp_query() {
|
552 |
+
return $GLOBALS['wp_query'];
|
553 |
+
}
|
554 |
}
|
frontend/frontend-filters-search.php
CHANGED
@@ -9,7 +9,19 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Filters_Search {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
@@ -37,13 +49,14 @@ class PLL_Frontend_Filters_Search {
|
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
-
* Adds the language information in the search form
|
|
|
41 |
* Does not work if searchform.php ( prior to WP 3.6 ) is used or if the search form is hardcoded in another template file
|
42 |
*
|
43 |
* @since 0.1
|
44 |
*
|
45 |
-
* @param string $form
|
46 |
-
* @return string Modified search form
|
47 |
*/
|
48 |
public function get_search_form( $form ) {
|
49 |
if ( $form ) {
|
@@ -51,10 +64,9 @@ class PLL_Frontend_Filters_Search {
|
|
51 |
// Take care to modify only the url in the <form> tag.
|
52 |
preg_match( '#<form.+>#', $form, $matches );
|
53 |
$old = reset( $matches );
|
54 |
-
$new = preg_replace( '#' . esc_url( $this->
|
55 |
$form = str_replace( $old, $new, $form );
|
56 |
-
}
|
57 |
-
else {
|
58 |
$form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form );
|
59 |
}
|
60 |
}
|
@@ -66,6 +78,8 @@ class PLL_Frontend_Filters_Search {
|
|
66 |
* Adds the language information in admin bar search form
|
67 |
*
|
68 |
* @since 1.2
|
|
|
|
|
69 |
*/
|
70 |
public function add_admin_bar_menus() {
|
71 |
remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 );
|
@@ -79,6 +93,7 @@ class PLL_Frontend_Filters_Search {
|
|
79 |
* @since 0.9
|
80 |
*
|
81 |
* @param WP_Admin_Bar $wp_admin_bar
|
|
|
82 |
*/
|
83 |
public function admin_bar_search_menu( $wp_admin_bar ) {
|
84 |
$form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
|
@@ -104,6 +119,8 @@ class PLL_Frontend_Filters_Search {
|
|
104 |
* Allows modifying the search form if it does not pass get_search_form
|
105 |
*
|
106 |
* @since 0.1
|
|
|
|
|
107 |
*/
|
108 |
public function wp_print_footer_scripts() {
|
109 |
// Don't use directly e[0] just in case there is somewhere else an element named 's'
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Filters_Search {
|
12 |
+
/**
|
13 |
+
* Instance of a child class of PLL_Links_Model.
|
14 |
+
*
|
15 |
+
* @var PLL_Links_Model
|
16 |
+
*/
|
17 |
+
public $links_model;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Current language.
|
21 |
+
*
|
22 |
+
* @var PLL_Language
|
23 |
+
*/
|
24 |
+
public $curlang;
|
25 |
|
26 |
/**
|
27 |
* Constructor
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
+
* Adds the language information in the search form.
|
53 |
+
*
|
54 |
* Does not work if searchform.php ( prior to WP 3.6 ) is used or if the search form is hardcoded in another template file
|
55 |
*
|
56 |
* @since 0.1
|
57 |
*
|
58 |
+
* @param string $form The search form HTML.
|
59 |
+
* @return string Modified search form.
|
60 |
*/
|
61 |
public function get_search_form( $form ) {
|
62 |
if ( $form ) {
|
64 |
// Take care to modify only the url in the <form> tag.
|
65 |
preg_match( '#<form.+>#', $form, $matches );
|
66 |
$old = reset( $matches );
|
67 |
+
$new = preg_replace( '#action="(.+)"#', 'action="' . esc_url( $this->curlang->search_url ) . '"', $old );
|
68 |
$form = str_replace( $old, $new, $form );
|
69 |
+
} else {
|
|
|
70 |
$form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form );
|
71 |
}
|
72 |
}
|
78 |
* Adds the language information in admin bar search form
|
79 |
*
|
80 |
* @since 1.2
|
81 |
+
*
|
82 |
+
* @return void
|
83 |
*/
|
84 |
public function add_admin_bar_menus() {
|
85 |
remove_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 );
|
93 |
* @since 0.9
|
94 |
*
|
95 |
* @param WP_Admin_Bar $wp_admin_bar
|
96 |
+
* @return void
|
97 |
*/
|
98 |
public function admin_bar_search_menu( $wp_admin_bar ) {
|
99 |
$form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
|
119 |
* Allows modifying the search form if it does not pass get_search_form
|
120 |
*
|
121 |
* @since 0.1
|
122 |
+
*
|
123 |
+
* @return void
|
124 |
*/
|
125 |
public function wp_print_footer_scripts() {
|
126 |
// Don't use directly e[0] just in case there is somewhere else an element named 's'
|
frontend/frontend-filters.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Filters extends PLL_Filters {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $cache;
|
13 |
|
14 |
/**
|
@@ -49,8 +54,7 @@ class PLL_Frontend_Filters extends PLL_Filters {
|
|
49 |
// Translates biography
|
50 |
add_filter( 'get_user_metadata', array( $this, 'get_user_metadata' ), 10, 4 );
|
51 |
|
52 |
-
|
53 |
-
if ( Polylang::is_ajax_on_front() && function_exists( 'get_user_locale' ) ) {
|
54 |
add_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ) );
|
55 |
}
|
56 |
}
|
@@ -67,18 +71,18 @@ class PLL_Frontend_Filters extends PLL_Filters {
|
|
67 |
}
|
68 |
|
69 |
/**
|
70 |
-
* Filters sticky posts by current language
|
71 |
*
|
72 |
* @since 0.8
|
73 |
*
|
74 |
-
* @param
|
75 |
-
* @return
|
76 |
*/
|
77 |
public function option_sticky_posts( $posts ) {
|
78 |
global $wpdb;
|
79 |
|
80 |
// Do not filter sticky posts on REST requests as $this->curlang is *not* the 'lang' parameter set in the request
|
81 |
-
if ( ! defined( 'REST_REQUEST' ) && $this->curlang && ! empty( $posts ) ) {
|
82 |
$_posts = wp_cache_get( 'sticky_posts', 'options' ); // This option is usually cached in 'all_options' by WP
|
83 |
|
84 |
if ( empty( $_posts ) || ! is_array( $_posts[ $this->curlang->term_taxonomy_id ] ) ) {
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Filters extends PLL_Filters {
|
12 |
+
/**
|
13 |
+
* Internal non persistent cache object.
|
14 |
+
*
|
15 |
+
* @var PLL_Cache
|
16 |
+
*/
|
17 |
public $cache;
|
18 |
|
19 |
/**
|
54 |
// Translates biography
|
55 |
add_filter( 'get_user_metadata', array( $this, 'get_user_metadata' ), 10, 4 );
|
56 |
|
57 |
+
if ( Polylang::is_ajax_on_front() ) {
|
|
|
58 |
add_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ) );
|
59 |
}
|
60 |
}
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* Filters sticky posts by current language.
|
75 |
*
|
76 |
* @since 0.8
|
77 |
*
|
78 |
+
* @param int[] $posts List of sticky posts ids.
|
79 |
+
* @return int[] Modified list of sticky posts ids
|
80 |
*/
|
81 |
public function option_sticky_posts( $posts ) {
|
82 |
global $wpdb;
|
83 |
|
84 |
// Do not filter sticky posts on REST requests as $this->curlang is *not* the 'lang' parameter set in the request
|
85 |
+
if ( ! defined( 'REST_REQUEST' ) && ! empty( $this->curlang ) && ! empty( $posts ) ) {
|
86 |
$_posts = wp_cache_get( 'sticky_posts', 'options' ); // This option is usually cached in 'all_options' by WP
|
87 |
|
88 |
if ( empty( $_posts ) || ! is_array( $_posts[ $this->curlang->term_taxonomy_id ] ) ) {
|
frontend/frontend-links.php
CHANGED
@@ -9,8 +9,19 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Links extends PLL_Links {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $curlang;
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor
|
@@ -28,11 +39,11 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
* Returns the url of the translation (
|
32 |
*
|
33 |
* @since 0.1
|
34 |
*
|
35 |
-
* @param
|
36 |
* @return string
|
37 |
*/
|
38 |
public function get_translation_url( $language ) {
|
@@ -47,14 +58,14 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
47 |
$queried_object_id = $wp_query->get_queried_object_id();
|
48 |
|
49 |
/**
|
50 |
-
*
|
51 |
-
* Internally used by Polylang for the static front page and posts page
|
52 |
*
|
53 |
* @since 1.8
|
54 |
*
|
55 |
-
* @param string
|
56 |
-
* @param
|
57 |
-
* @param int
|
58 |
*/
|
59 |
if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
|
60 |
$qv = $wp_query->query_vars;
|
@@ -199,12 +210,12 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
199 |
}
|
200 |
|
201 |
/**
|
202 |
-
* Returns the home url in the right language
|
203 |
*
|
204 |
* @since 0.1
|
205 |
*
|
206 |
-
* @param
|
207 |
-
* @param bool
|
208 |
*/
|
209 |
public function get_home_url( $language = '', $is_search = false ) {
|
210 |
if ( empty( $language ) ) {
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Links extends PLL_Links {
|
12 |
+
/**
|
13 |
+
* Current language.
|
14 |
+
*
|
15 |
+
* @var PLL_Language
|
16 |
+
*/
|
17 |
public $curlang;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Internal non persistent cache object.
|
21 |
+
*
|
22 |
+
* @var PLL_Cache
|
23 |
+
*/
|
24 |
+
public $cache;
|
25 |
|
26 |
/**
|
27 |
* Constructor
|
39 |
}
|
40 |
|
41 |
/**
|
42 |
+
* Returns the url of the translation (if it exists) of the current page.
|
43 |
*
|
44 |
* @since 0.1
|
45 |
*
|
46 |
+
* @param PLL_Language $language Language object.
|
47 |
* @return string
|
48 |
*/
|
49 |
public function get_translation_url( $language ) {
|
58 |
$queried_object_id = $wp_query->get_queried_object_id();
|
59 |
|
60 |
/**
|
61 |
+
* Filters the translation url before Polylang attempts to find one.
|
62 |
+
* Internally used by Polylang for the static front page and posts page.
|
63 |
*
|
64 |
* @since 1.8
|
65 |
*
|
66 |
+
* @param string $url Empty or the url of the translation of teh current page.
|
67 |
+
* @param PLL_Language $language Language of the translation.
|
68 |
+
* @param int $queried_object_id Queried object id.
|
69 |
*/
|
70 |
if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
|
71 |
$qv = $wp_query->query_vars;
|
210 |
}
|
211 |
|
212 |
/**
|
213 |
+
* Returns the home url in the right language.
|
214 |
*
|
215 |
* @since 0.1
|
216 |
*
|
217 |
+
* @param PLL_Language|string $language Optional, defaults to current language.
|
218 |
+
* @param bool $is_search Optional, whether we need the home url for a search form, defaults to false.
|
219 |
*/
|
220 |
public function get_home_url( $language = '', $is_search = false ) {
|
221 |
if ( empty( $language ) ) {
|
frontend/frontend-nav-menu.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $curlang;
|
13 |
|
14 |
/**
|
@@ -40,12 +45,12 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
-
*
|
44 |
*
|
45 |
* @since 1.7.9
|
46 |
*
|
47 |
-
* @param
|
48 |
-
* @param
|
49 |
* @return int -1 or 1 if $a is considered to be respectively less than or greater than $b.
|
50 |
*/
|
51 |
protected function usort_menu_items( $a, $b ) {
|
@@ -76,13 +81,13 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
-
* Splits the one item of backend in several items on frontend
|
80 |
-
*
|
81 |
*
|
82 |
* @since 1.1.1
|
83 |
*
|
84 |
-
* @param
|
85 |
-
* @return
|
86 |
*/
|
87 |
public function wp_get_nav_menu_items( $items ) {
|
88 |
if ( doing_action( 'customize_register' ) ) { // needed since WP 4.3, doing_action available since WP 3.9
|
@@ -104,6 +109,8 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
104 |
|
105 |
$switcher = new PLL_Switcher();
|
106 |
$args = array_merge( array( 'raw' => 1 ), $options );
|
|
|
|
|
107 |
$the_languages = $switcher->the_languages( PLL()->links, $args );
|
108 |
|
109 |
// parent item for dropdown
|
@@ -141,12 +148,12 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
141 |
}
|
142 |
|
143 |
/**
|
144 |
-
* Returns the ancestors of a menu item
|
145 |
*
|
146 |
* @since 1.1.1
|
147 |
*
|
148 |
-
* @param
|
149 |
-
* @return
|
150 |
*/
|
151 |
public function get_ancestors( $item ) {
|
152 |
$ids = array();
|
@@ -158,12 +165,12 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
-
* Removes current-menu and current-menu-ancestor classes to lang switcher when not on the home page
|
162 |
*
|
163 |
* @since 1.1.1
|
164 |
*
|
165 |
-
* @param
|
166 |
-
* @return
|
167 |
*/
|
168 |
public function wp_nav_menu_objects( $items ) {
|
169 |
$r_ids = $k_ids = array();
|
@@ -192,14 +199,14 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
192 |
}
|
193 |
|
194 |
/**
|
195 |
-
* Adds hreflang attribute for the language switcher menu items
|
196 |
-
* available since WP 3.6
|
197 |
*
|
198 |
* @since 1.1
|
199 |
*
|
200 |
-
* @param
|
201 |
-
* @param
|
202 |
-
* @return
|
203 |
*/
|
204 |
public function nav_menu_link_attributes( $atts, $item ) {
|
205 |
if ( isset( $item->lang ) ) {
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
12 |
+
/**
|
13 |
+
* Current language.
|
14 |
+
*
|
15 |
+
* @var PLL_Language
|
16 |
+
*/
|
17 |
public $curlang;
|
18 |
|
19 |
/**
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* Sorts menu items by menu order.
|
49 |
*
|
50 |
* @since 1.7.9
|
51 |
*
|
52 |
+
* @param stdClass $a The first object to compare.
|
53 |
+
* @param stdClass $b The second object to compare.
|
54 |
* @return int -1 or 1 if $a is considered to be respectively less than or greater than $b.
|
55 |
*/
|
56 |
protected function usort_menu_items( $a, $b ) {
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
+
* Splits the one language switcher menu item of backend in several menu items on frontend.
|
85 |
+
* Takes care to menu_order as it is used later in wp_nav_menu().
|
86 |
*
|
87 |
* @since 1.1.1
|
88 |
*
|
89 |
+
* @param stdClass[] $items Menu items.
|
90 |
+
* @return stdClass[] Modified menu items.
|
91 |
*/
|
92 |
public function wp_get_nav_menu_items( $items ) {
|
93 |
if ( doing_action( 'customize_register' ) ) { // needed since WP 4.3, doing_action available since WP 3.9
|
109 |
|
110 |
$switcher = new PLL_Switcher();
|
111 |
$args = array_merge( array( 'raw' => 1 ), $options );
|
112 |
+
|
113 |
+
/** @var array */
|
114 |
$the_languages = $switcher->the_languages( PLL()->links, $args );
|
115 |
|
116 |
// parent item for dropdown
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
+
* Returns the ancestors of a menu item.
|
152 |
*
|
153 |
* @since 1.1.1
|
154 |
*
|
155 |
+
* @param stdClass $item Menu item.
|
156 |
+
* @return int[] Ancestors ids.
|
157 |
*/
|
158 |
public function get_ancestors( $item ) {
|
159 |
$ids = array();
|
165 |
}
|
166 |
|
167 |
/**
|
168 |
+
* Removes current-menu and current-menu-ancestor classes to lang switcher when not on the home page.
|
169 |
*
|
170 |
* @since 1.1.1
|
171 |
*
|
172 |
+
* @param stdClass[] $items An array of menu items.
|
173 |
+
* @return stdClass[]
|
174 |
*/
|
175 |
public function wp_nav_menu_objects( $items ) {
|
176 |
$r_ids = $k_ids = array();
|
199 |
}
|
200 |
|
201 |
/**
|
202 |
+
* Adds hreflang attribute for the language switcher menu items.
|
203 |
+
* available since WP 3.6.
|
204 |
*
|
205 |
* @since 1.1
|
206 |
*
|
207 |
+
* @param string[] $atts HTML attributes applied to the menu item's `<a>` element.
|
208 |
+
* @param stdClass $item Menu item.
|
209 |
+
* @return string[] Modified attributes.
|
210 |
*/
|
211 |
public function nav_menu_link_attributes( $atts, $item ) {
|
212 |
if ( isset( $item->lang ) ) {
|
frontend/frontend-static-pages.php
CHANGED
@@ -9,6 +9,17 @@
|
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
* Constructor: setups filters and actions
|
@@ -40,6 +51,8 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
40 |
* Init the filters
|
41 |
*
|
42 |
* @since 1.8
|
|
|
|
|
43 |
*/
|
44 |
public function pll_language_defined() {
|
45 |
// Translates our page on front and page for posts properties
|
@@ -60,6 +73,8 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
60 |
* Translates the page_id query var when the site root page is requested
|
61 |
*
|
62 |
* @since 1.8
|
|
|
|
|
63 |
*/
|
64 |
public function pll_home_requested() {
|
65 |
set_query_var( 'page_id', $this->curlang->page_on_front );
|
@@ -87,9 +102,8 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
87 |
* @return bool|string modified url, false if redirection is canceled
|
88 |
*/
|
89 |
public function redirect_canonical( $redirect_url ) {
|
90 |
-
|
91 |
-
|
92 |
-
$url = is_paged() ? $this->links_model->add_paged_to_link( $this->links->get_home_url(), $wp_query->query_vars['page'] ) : $this->links->get_home_url();
|
93 |
|
94 |
// Don't forget additional query vars
|
95 |
$query = wp_parse_url( $redirect_url, PHP_URL_QUERY );
|
@@ -106,14 +120,14 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
* Translates the url of the page on front and page for posts
|
110 |
*
|
111 |
* @since 1.8
|
112 |
*
|
113 |
-
* @param string
|
114 |
-
* @param
|
115 |
-
* @param int
|
116 |
-
* @return string
|
117 |
*/
|
118 |
public function pll_pre_translation_url( $url, $language, $queried_object_id ) {
|
119 |
if ( ! empty( $queried_object_id ) ) {
|
@@ -148,7 +162,7 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
148 |
*
|
149 |
* @since 2.3
|
150 |
*
|
151 |
-
* @param
|
152 |
* @return bool
|
153 |
*/
|
154 |
protected function is_front_page( $query ) {
|
@@ -161,9 +175,9 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
161 |
*
|
162 |
* @since 1.8
|
163 |
*
|
164 |
-
* @param
|
165 |
-
* @param
|
166 |
-
* @return
|
167 |
*/
|
168 |
public function page_on_front_query( $lang, $query ) {
|
169 |
if ( ! empty( $lang ) || ! $this->page_on_front ) {
|
@@ -224,9 +238,9 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
224 |
*
|
225 |
* @since 1.8
|
226 |
*
|
227 |
-
* @param
|
228 |
-
* @param
|
229 |
-
* @return
|
230 |
*/
|
231 |
public function page_for_posts_query( $lang, $query ) {
|
232 |
if ( empty( $lang ) && $this->page_for_posts ) {
|
@@ -246,14 +260,15 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
246 |
}
|
247 |
|
248 |
/**
|
249 |
-
* Get queried page_id (
|
250 |
-
*
|
251 |
-
*
|
|
|
252 |
*
|
253 |
* @since 1.5
|
254 |
*
|
255 |
-
* @param
|
256 |
-
* @return int page_id
|
257 |
*/
|
258 |
protected function get_page_id( $query ) {
|
259 |
if ( ! empty( $query->query_vars['pagename'] ) && isset( $query->queried_object_id ) ) {
|
@@ -264,6 +279,6 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
264 |
return $query->query_vars['page_id'];
|
265 |
}
|
266 |
|
267 |
-
return 0; // No page queried
|
268 |
}
|
269 |
}
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
12 |
+
/**
|
13 |
+
* Instance of a child class of PLL_Links_Model.
|
14 |
+
*
|
15 |
+
* @var PLL_Links_Model
|
16 |
+
*/
|
17 |
+
protected $links_model;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Frontend_Links
|
21 |
+
*/
|
22 |
+
protected $links;
|
23 |
|
24 |
/**
|
25 |
* Constructor: setups filters and actions
|
51 |
* Init the filters
|
52 |
*
|
53 |
* @since 1.8
|
54 |
+
*
|
55 |
+
* @return void
|
56 |
*/
|
57 |
public function pll_language_defined() {
|
58 |
// Translates our page on front and page for posts properties
|
73 |
* Translates the page_id query var when the site root page is requested
|
74 |
*
|
75 |
* @since 1.8
|
76 |
+
*
|
77 |
+
* @return void
|
78 |
*/
|
79 |
public function pll_home_requested() {
|
80 |
set_query_var( 'page_id', $this->curlang->page_on_front );
|
102 |
* @return bool|string modified url, false if redirection is canceled
|
103 |
*/
|
104 |
public function redirect_canonical( $redirect_url ) {
|
105 |
+
if ( is_page() && ! is_feed() && get_queried_object_id() == $this->curlang->page_on_front ) {
|
106 |
+
$url = is_paged() ? $this->links_model->add_paged_to_link( $this->links->get_home_url(), get_query_var( 'page' ) ) : $this->links->get_home_url();
|
|
|
107 |
|
108 |
// Don't forget additional query vars
|
109 |
$query = wp_parse_url( $redirect_url, PHP_URL_QUERY );
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Translates the url of the page on front and page for posts.
|
124 |
*
|
125 |
* @since 1.8
|
126 |
*
|
127 |
+
* @param string $url Not used.
|
128 |
+
* @param PLL_Language $language Language in which we want the translation.
|
129 |
+
* @param int $queried_object_id Id of the queried object.
|
130 |
+
* @return string The translation url.
|
131 |
*/
|
132 |
public function pll_pre_translation_url( $url, $language, $queried_object_id ) {
|
133 |
if ( ! empty( $queried_object_id ) ) {
|
162 |
*
|
163 |
* @since 2.3
|
164 |
*
|
165 |
+
* @param WP_Query $query The WP_Query object.
|
166 |
* @return bool
|
167 |
*/
|
168 |
protected function is_front_page( $query ) {
|
175 |
*
|
176 |
* @since 1.8
|
177 |
*
|
178 |
+
* @param PLL_Language|false $lang The current language, false if it is not set yet.
|
179 |
+
* @param WP_Query $query The main WP query.
|
180 |
+
* @return PLL_Language|false
|
181 |
*/
|
182 |
public function page_on_front_query( $lang, $query ) {
|
183 |
if ( ! empty( $lang ) || ! $this->page_on_front ) {
|
238 |
*
|
239 |
* @since 1.8
|
240 |
*
|
241 |
+
* @param PLL_Language|false $lang The current language, false if it is not set yet.
|
242 |
+
* @param WP_Query $query The main WP query.
|
243 |
+
* @return PLL_Language|false
|
244 |
*/
|
245 |
public function page_for_posts_query( $lang, $query ) {
|
246 |
if ( empty( $lang ) && $this->page_for_posts ) {
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
+
* Get the queried page_id (if it exists ).
|
264 |
+
*
|
265 |
+
* If permalinks are used, WordPress does set and use `$query->queried_object_id` and sets `$query->query_vars['page_id']` to 0,
|
266 |
+
* and does set and use `$query->query_vars['page_id']` if permalinks are not used :(.
|
267 |
*
|
268 |
* @since 1.5
|
269 |
*
|
270 |
+
* @param WP_Query $query Instance of WP_Query.
|
271 |
+
* @return int The page_id.
|
272 |
*/
|
273 |
protected function get_page_id( $query ) {
|
274 |
if ( ! empty( $query->query_vars['pagename'] ) && isset( $query->queried_object_id ) ) {
|
279 |
return $query->query_vars['page_id'];
|
280 |
}
|
281 |
|
282 |
+
return 0; // No page queried.
|
283 |
}
|
284 |
}
|
frontend/frontend.php
CHANGED
@@ -4,37 +4,66 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
*
|
8 |
-
* accessible as $polylang global object
|
9 |
-
*
|
10 |
-
* Properties:
|
11 |
-
* options => inherited, reference to Polylang options array
|
12 |
-
* model => inherited, reference to PLL_Model object
|
13 |
-
* links_model => inherited, reference to PLL_Links_Model object
|
14 |
-
* links => reference to PLL_Links object
|
15 |
-
* static_pages => reference to PLL_Frontend_Static_Pages object
|
16 |
-
* choose_lang => reference to PLL_Choose_Lang object
|
17 |
-
* curlang => current language
|
18 |
-
* filters => reference to PLL_Frontend_Filters object
|
19 |
-
* filters_links => reference to PLL_Frontend_Filters_Links object
|
20 |
-
* filters_search => reference to PLL_Frontend_Filters_Search object
|
21 |
-
* posts => reference to PLL_CRUD_Posts object
|
22 |
-
* terms => reference to PLL_CRUD_Terms object
|
23 |
-
* nav_menu => reference to PLL_Frontend_Nav_Menu object
|
24 |
-
* auto_translate => optional, reference to PLL_Auto_Translate object
|
25 |
*
|
26 |
* @since 1.2
|
27 |
*/
|
28 |
class PLL_Frontend extends PLL_Base {
|
|
|
|
|
|
|
|
|
|
|
29 |
public $curlang;
|
30 |
-
public $links, $choose_lang, $filters, $filters_search, $nav_menu, $auto_translate;
|
31 |
|
32 |
/**
|
33 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
*
|
35 |
* @since 1.2
|
36 |
*
|
37 |
-
* @param
|
38 |
*/
|
39 |
public function __construct( &$links_model ) {
|
40 |
parent::__construct( $links_model );
|
@@ -82,6 +111,8 @@ class PLL_Frontend extends PLL_Base {
|
|
82 |
* Setups filters and nav menus once the language has been defined
|
83 |
*
|
84 |
* @since 1.2
|
|
|
|
|
85 |
*/
|
86 |
public function pll_language_defined() {
|
87 |
// Filters
|
@@ -96,11 +127,12 @@ class PLL_Frontend extends PLL_Base {
|
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
-
* When querying multiple taxonomies, makes sure that the language is not the queried object
|
100 |
*
|
101 |
* @since 1.8
|
102 |
*
|
103 |
-
* @param
|
|
|
104 |
*/
|
105 |
public function parse_tax_query( $query ) {
|
106 |
$pll_query = new PLL_Query( $query, $this->model );
|
@@ -112,11 +144,12 @@ class PLL_Frontend extends PLL_Base {
|
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
-
* Modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts
|
116 |
*
|
117 |
* @since 1.2
|
118 |
*
|
119 |
-
* @param
|
|
|
120 |
*/
|
121 |
public function parse_query( $query ) {
|
122 |
$qv = $query->query_vars;
|
@@ -157,26 +190,31 @@ class PLL_Frontend extends PLL_Base {
|
|
157 |
* Auto translate posts and terms ids
|
158 |
*
|
159 |
* @since 1.2
|
|
|
|
|
160 |
*/
|
161 |
public function auto_translate() {
|
162 |
$this->auto_translate = new PLL_Frontend_Auto_Translate( $this );
|
163 |
}
|
164 |
|
165 |
/**
|
166 |
-
* Resets some variables when
|
167 |
-
* Overrides parent method
|
168 |
*
|
169 |
* @since 1.5.1
|
170 |
*
|
171 |
-
* @param int $
|
172 |
-
* @param int $
|
|
|
173 |
*/
|
174 |
-
public function switch_blog( $
|
175 |
-
|
176 |
-
|
|
|
|
|
177 |
static $restore_curlang;
|
178 |
if ( empty( $restore_curlang ) ) {
|
179 |
-
$restore_curlang = $this->curlang->slug; // To always remember the current language through blogs
|
180 |
}
|
181 |
|
182 |
$lang = $this->model->get_language( $restore_curlang );
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Main Polylang class when on frontend, accessible from @see PLL().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend extends PLL_Base {
|
12 |
+
/**
|
13 |
+
* Current language.
|
14 |
+
*
|
15 |
+
* @var PLL_Language
|
16 |
+
*/
|
17 |
public $curlang;
|
|
|
18 |
|
19 |
/**
|
20 |
+
* @var PLL_Frontend_Auto_Translate
|
21 |
+
*/
|
22 |
+
public $auto_translate;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The class selecting the current language.
|
26 |
+
*
|
27 |
+
* @var PLL_Choose_Lang
|
28 |
+
*/
|
29 |
+
public $choose_lang;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var PLL_Frontend_Filters
|
33 |
+
*/
|
34 |
+
public $filters;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var PLL_Frontend_Filters_Links
|
38 |
+
*/
|
39 |
+
public $filters_links;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var PLL_Frontend_Filters_Search
|
43 |
+
*/
|
44 |
+
public $filters_search;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var PLL_Frontend_Links
|
48 |
+
*/
|
49 |
+
public $links;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @var PLL_Frontend_Nav_Menu
|
53 |
+
*/
|
54 |
+
public $nav_menu;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @var PLL_Frontend_Static_Pages
|
58 |
+
*/
|
59 |
+
public $static_pages;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Constructor.
|
63 |
*
|
64 |
* @since 1.2
|
65 |
*
|
66 |
+
* @param PLL_Links_Model $links_model Reference to the links model.
|
67 |
*/
|
68 |
public function __construct( &$links_model ) {
|
69 |
parent::__construct( $links_model );
|
111 |
* Setups filters and nav menus once the language has been defined
|
112 |
*
|
113 |
* @since 1.2
|
114 |
+
*
|
115 |
+
* @return void
|
116 |
*/
|
117 |
public function pll_language_defined() {
|
118 |
// Filters
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
+
* When querying multiple taxonomies, makes sure that the language is not the queried object.
|
131 |
*
|
132 |
* @since 1.8
|
133 |
*
|
134 |
+
* @param WP_Query $query WP_Query object.
|
135 |
+
* @return void
|
136 |
*/
|
137 |
public function parse_tax_query( $query ) {
|
138 |
$pll_query = new PLL_Query( $query, $this->model );
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* Modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts.
|
148 |
*
|
149 |
* @since 1.2
|
150 |
*
|
151 |
+
* @param WP_Query $query WP_Query object.
|
152 |
+
* @return void
|
153 |
*/
|
154 |
public function parse_query( $query ) {
|
155 |
$qv = $query->query_vars;
|
190 |
* Auto translate posts and terms ids
|
191 |
*
|
192 |
* @since 1.2
|
193 |
+
*
|
194 |
+
* @return void
|
195 |
*/
|
196 |
public function auto_translate() {
|
197 |
$this->auto_translate = new PLL_Frontend_Auto_Translate( $this );
|
198 |
}
|
199 |
|
200 |
/**
|
201 |
+
* Resets some variables when the blog is switched.
|
202 |
+
* Overrides the parent method.
|
203 |
*
|
204 |
* @since 1.5.1
|
205 |
*
|
206 |
+
* @param int $new_blog_id New blog ID.
|
207 |
+
* @param int $prev_blog_id Previous blog ID.
|
208 |
+
* @return void
|
209 |
*/
|
210 |
+
public function switch_blog( $new_blog_id, $prev_blog_id ) {
|
211 |
+
parent::switch_blog( $new_blog_id, $prev_blog_id );
|
212 |
+
|
213 |
+
// Need to check that some languages are defined when user is logged in, has several blogs, some without any languages.
|
214 |
+
if ( $this->is_active_on_new_blog( $new_blog_id, $prev_blog_id ) && did_action( 'pll_language_defined' ) && $this->model->get_languages_list() ) {
|
215 |
static $restore_curlang;
|
216 |
if ( empty( $restore_curlang ) ) {
|
217 |
+
$restore_curlang = $this->curlang->slug; // To always remember the current language through blogs.
|
218 |
}
|
219 |
|
220 |
$lang = $this->model->get_language( $restore_curlang );
|
include/api.php
CHANGED
@@ -4,48 +4,44 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Template tag: displays the language switcher
|
8 |
-
*
|
9 |
-
* List of parameters accepted in $args:
|
10 |
-
*
|
11 |
-
* - dropdown => displays a dropdown if set to 1, defaults to 0
|
12 |
-
* - echo => echoes the switcher if set to 1 ( default )
|
13 |
-
* - hide_if_empty => hides languages with no posts ( or pages ) if set to 1 ( default )
|
14 |
-
* - show_flags => shows flags if set to 1, defaults to 0
|
15 |
-
* - show_names => shows languages names if set to 1 ( default )
|
16 |
-
* - display_names_as => whether to display the language name or its slug, valid options are 'slug' and 'name',
|
17 |
-
* defaults to name
|
18 |
-
* - force_home => forces linking to the home page is set to 1, defaults to 0
|
19 |
-
* - hide_if_no_translation => hides the link if there is no translation if set to 1, defaults to 0
|
20 |
-
* - hide_current => hides the current language if set to 1, defaults to 0
|
21 |
-
* - post_id => if not null, link to translations of post defined by post_id, defaults to null
|
22 |
-
* - raw => set this to true to build your own custom language switcher, defaults to 0
|
23 |
-
* - item_spacing => whether to preserve or discard whitespace between list items, valid options are
|
24 |
-
* 'preserve' and 'discard', defaults to preserve
|
25 |
*
|
26 |
* @api
|
27 |
* @since 0.5
|
28 |
*
|
29 |
-
* @param array $args
|
30 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
*/
|
32 |
-
function pll_the_languages( $args =
|
33 |
-
|
34 |
-
|
35 |
-
return $switcher->the_languages( PLL()->links, $args );
|
36 |
-
}
|
37 |
-
return '';
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* Returns the current language on frontend
|
42 |
-
* Returns the language set in admin language filter on backend ( false if set to all languages )
|
43 |
*
|
44 |
* @api
|
45 |
* @since 0.8.1
|
46 |
*
|
47 |
-
* @param string $field Optional, the language field to return ( see PLL_Language ), defaults to 'slug'
|
48 |
-
* @return string|PLL_Language|
|
49 |
*/
|
50 |
function pll_current_language( $field = 'slug' ) {
|
51 |
if ( OBJECT === $field ) {
|
@@ -55,13 +51,13 @@ function pll_current_language( $field = 'slug' ) {
|
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
-
* Returns the default language
|
59 |
*
|
60 |
* @api
|
61 |
* @since 1.0
|
62 |
*
|
63 |
-
* @param string $field Optional, the language field to return ( see PLL_Language ), defaults to 'slug'
|
64 |
-
* @return string|PLL_Language|
|
65 |
*/
|
66 |
function pll_default_language( $field = 'slug' ) {
|
67 |
if ( isset( PLL()->options['default_lang'] ) ) {
|
@@ -77,40 +73,40 @@ function pll_default_language( $field = 'slug' ) {
|
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
-
* Among the post and its translations, returns the id of the post which is in the language represented by $
|
81 |
*
|
82 |
* @api
|
83 |
* @since 0.5
|
84 |
*
|
85 |
-
* @param int $post_id
|
86 |
-
* @param string $
|
87 |
-
* @return int|false|null
|
88 |
*/
|
89 |
-
function pll_get_post( $post_id, $
|
90 |
-
return ( $
|
91 |
}
|
92 |
|
93 |
/**
|
94 |
-
* Among the term and its translations, returns the id of the term which is in the language represented by $
|
95 |
*
|
96 |
* @api
|
97 |
* @since 0.5
|
98 |
*
|
99 |
-
* @param int $term_id
|
100 |
-
* @param string $
|
101 |
-
* @return int|false|null
|
102 |
*/
|
103 |
-
function pll_get_term( $term_id, $
|
104 |
-
return ( $
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* Returns the home url in
|
109 |
*
|
110 |
* @api
|
111 |
* @since 0.8
|
112 |
*
|
113 |
-
* @param string $lang language code
|
114 |
* @return string
|
115 |
*/
|
116 |
function pll_home_url( $lang = '' ) {
|
@@ -122,15 +118,17 @@ function pll_home_url( $lang = '' ) {
|
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
-
* Registers a string for translation in the "strings translation" panel
|
126 |
*
|
127 |
* @api
|
128 |
* @since 0.6
|
129 |
*
|
130 |
-
* @param string $name
|
131 |
-
* @param string $string
|
132 |
-
* @param string $context
|
133 |
-
* @param bool $multiline
|
|
|
|
|
134 |
*/
|
135 |
function pll_register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
136 |
if ( PLL() instanceof PLL_Admin_Base ) {
|
@@ -139,13 +137,13 @@ function pll_register_string( $name, $string, $context = 'Polylang', $multiline
|
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
* Translates a string ( previously registered with pll_register_string )
|
143 |
*
|
144 |
* @api
|
145 |
* @since 0.6
|
146 |
*
|
147 |
-
* @param string $string
|
148 |
-
* @return string
|
149 |
*/
|
150 |
function pll__( $string ) {
|
151 |
return is_scalar( $string ) ? __( $string, 'pll_string' ) : $string; // PHPCS:ignore WordPress.WP.I18n
|
@@ -157,8 +155,8 @@ function pll__( $string ) {
|
|
157 |
* @api
|
158 |
* @since 2.1
|
159 |
*
|
160 |
-
* @param string $string
|
161 |
-
* @return string
|
162 |
*/
|
163 |
function pll_esc_html__( $string ) {
|
164 |
return esc_html( pll__( $string ) );
|
@@ -170,8 +168,8 @@ function pll_esc_html__( $string ) {
|
|
170 |
* @api
|
171 |
* @since 2.1
|
172 |
*
|
173 |
-
* @param string $string The string to translate
|
174 |
-
* @return string
|
175 |
*/
|
176 |
function pll_esc_attr__( $string ) {
|
177 |
return esc_attr( pll__( $string ) );
|
@@ -184,7 +182,8 @@ function pll_esc_attr__( $string ) {
|
|
184 |
* @api
|
185 |
* @since 0.6
|
186 |
*
|
187 |
-
* @param string $string The string to translate
|
|
|
188 |
*/
|
189 |
function pll_e( $string ) {
|
190 |
echo pll__( $string ); // phpcs:ignore
|
@@ -196,7 +195,8 @@ function pll_e( $string ) {
|
|
196 |
* @api
|
197 |
* @since 2.1
|
198 |
*
|
199 |
-
* @param string $string The string to translate
|
|
|
200 |
*/
|
201 |
function pll_esc_html_e( $string ) {
|
202 |
echo pll_esc_html__( $string ); // phpcs:ignore WordPress.Security.EscapeOutput
|
@@ -208,21 +208,22 @@ function pll_esc_html_e( $string ) {
|
|
208 |
* @api
|
209 |
* @since 2.1
|
210 |
*
|
211 |
-
* @param string $string The string to translate
|
|
|
212 |
*/
|
213 |
function pll_esc_attr_e( $string ) {
|
214 |
echo pll_esc_attr__( $string ); // phpcs:ignore WordPress.Security.EscapeOutput
|
215 |
}
|
216 |
|
217 |
/**
|
218 |
-
* Translates a string ( previously registered with pll_register_string )
|
219 |
*
|
220 |
* @api
|
221 |
* @since 1.5.4
|
222 |
*
|
223 |
-
* @param string $string
|
224 |
-
* @param string $lang
|
225 |
-
* @return string
|
226 |
*/
|
227 |
function pll_translate_string( $string, $lang ) {
|
228 |
if ( PLL() instanceof PLL_Frontend && pll_current_language() == $lang ) {
|
@@ -233,7 +234,7 @@ function pll_translate_string( $string, $lang ) {
|
|
233 |
return $string;
|
234 |
}
|
235 |
|
236 |
-
static $cache; // Cache object to avoid loading the same translations object several times
|
237 |
|
238 |
if ( empty( $cache ) ) {
|
239 |
$cache = new PLL_Cache();
|
@@ -249,12 +250,12 @@ function pll_translate_string( $string, $lang ) {
|
|
249 |
}
|
250 |
|
251 |
/**
|
252 |
-
* Returns true if Polylang manages languages and translations for this post type
|
253 |
*
|
254 |
* @api
|
255 |
* @since 1.0.1
|
256 |
*
|
257 |
-
* @param string $post_type Post type name
|
258 |
* @return bool
|
259 |
*/
|
260 |
function pll_is_translated_post_type( $post_type ) {
|
@@ -262,12 +263,12 @@ function pll_is_translated_post_type( $post_type ) {
|
|
262 |
}
|
263 |
|
264 |
/**
|
265 |
-
* Returns true if Polylang manages languages and translations for this taxonomy
|
266 |
*
|
267 |
* @api
|
268 |
* @since 1.0.1
|
269 |
*
|
270 |
-
* @param string $tax Taxonomy name
|
271 |
* @return bool
|
272 |
*/
|
273 |
function pll_is_translated_taxonomy( $tax ) {
|
@@ -275,18 +276,18 @@ function pll_is_translated_taxonomy( $tax ) {
|
|
275 |
}
|
276 |
|
277 |
/**
|
278 |
-
* Returns the list of available languages
|
279 |
-
*
|
280 |
-
* List of parameters accepted in $args:
|
281 |
-
*
|
282 |
-
* hide_empty => hides languages with no posts if set to true ( defaults to false )
|
283 |
-
* fields => return only that field if set ( see PLL_Language for a list of fields )
|
284 |
*
|
285 |
* @api
|
286 |
* @since 1.5
|
287 |
*
|
288 |
-
* @param array $args
|
289 |
-
*
|
|
|
|
|
|
|
|
|
|
|
290 |
*/
|
291 |
function pll_languages_list( $args = array() ) {
|
292 |
$args = wp_parse_args( $args, array( 'fields' => 'slug' ) );
|
@@ -294,38 +295,41 @@ function pll_languages_list( $args = array() ) {
|
|
294 |
}
|
295 |
|
296 |
/**
|
297 |
-
*
|
298 |
*
|
299 |
* @api
|
300 |
* @since 1.5
|
301 |
*
|
302 |
-
* @param int $id
|
303 |
-
* @param string $lang
|
|
|
304 |
*/
|
305 |
function pll_set_post_language( $id, $lang ) {
|
306 |
PLL()->model->post->set_language( $id, $lang );
|
307 |
}
|
308 |
|
309 |
/**
|
310 |
-
*
|
311 |
*
|
312 |
* @api
|
313 |
* @since 1.5
|
314 |
*
|
315 |
-
* @param int $id
|
316 |
-
* @param string $lang
|
|
|
317 |
*/
|
318 |
function pll_set_term_language( $id, $lang ) {
|
319 |
PLL()->model->term->set_language( $id, $lang );
|
320 |
}
|
321 |
|
322 |
/**
|
323 |
-
* Save posts translations
|
324 |
*
|
325 |
* @api
|
326 |
* @since 1.5
|
327 |
*
|
328 |
-
* @param
|
|
|
329 |
*/
|
330 |
function pll_save_post_translations( $arr ) {
|
331 |
PLL()->model->post->save_translations( reset( $arr ), $arr );
|
@@ -337,74 +341,88 @@ function pll_save_post_translations( $arr ) {
|
|
337 |
* @api
|
338 |
* @since 1.5
|
339 |
*
|
340 |
-
* @param
|
|
|
341 |
*/
|
342 |
function pll_save_term_translations( $arr ) {
|
343 |
PLL()->model->term->save_translations( reset( $arr ), $arr );
|
344 |
}
|
345 |
|
346 |
/**
|
347 |
-
* Returns the post language
|
348 |
*
|
349 |
* @api
|
350 |
* @since 1.5.4
|
351 |
*
|
352 |
-
* @param int $post_id
|
353 |
-
* @param string $field Optional, the language field to return ( see PLL_Language ), defaults to 'slug'
|
354 |
-
* @return
|
355 |
*/
|
356 |
function pll_get_post_language( $post_id, $field = 'slug' ) {
|
357 |
return ( $lang = PLL()->model->post->get_language( $post_id ) ) ? $lang->$field : false;
|
358 |
}
|
359 |
|
360 |
/**
|
361 |
-
* Returns the term language
|
362 |
*
|
363 |
* @api
|
364 |
* @since 1.5.4
|
365 |
*
|
366 |
-
* @param int $term_id
|
367 |
-
* @param string $field Optional, the language field to return ( see PLL_Language ), defaults to 'slug'
|
368 |
-
* @return
|
369 |
*/
|
370 |
function pll_get_term_language( $term_id, $field = 'slug' ) {
|
371 |
return ( $lang = PLL()->model->term->get_language( $term_id ) ) ? $lang->$field : false;
|
372 |
}
|
373 |
|
374 |
/**
|
375 |
-
* Returns an array of translations of a post
|
376 |
*
|
377 |
* @api
|
378 |
* @since 1.8
|
379 |
*
|
380 |
-
* @param int $post_id
|
381 |
-
* @return
|
382 |
*/
|
383 |
function pll_get_post_translations( $post_id ) {
|
384 |
return PLL()->model->post->get_translations( $post_id );
|
385 |
}
|
386 |
|
387 |
/**
|
388 |
-
* Returns an array of translations of a term
|
389 |
*
|
390 |
* @api
|
391 |
* @since 1.8
|
392 |
*
|
393 |
-
* @param int $term_id
|
394 |
-
* @return
|
395 |
*/
|
396 |
function pll_get_term_translations( $term_id ) {
|
397 |
return PLL()->model->term->get_translations( $term_id );
|
398 |
}
|
399 |
|
400 |
/**
|
401 |
-
*
|
402 |
*
|
403 |
* @api
|
404 |
* @since 1.5
|
405 |
*
|
406 |
* @param string $lang Language code.
|
407 |
-
* @param array $args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
408 |
* @return int Posts count.
|
409 |
*/
|
410 |
function pll_count_posts( $lang, $args = array() ) {
|
@@ -412,11 +430,13 @@ function pll_count_posts( $lang, $args = array() ) {
|
|
412 |
}
|
413 |
|
414 |
/**
|
415 |
-
* Allows to access the Polylang instance
|
416 |
-
*
|
417 |
-
*
|
418 |
*
|
419 |
* @since 1.8
|
|
|
|
|
420 |
*/
|
421 |
function PLL() { // PHPCS:ignore WordPress.NamingConventions.ValidFunctionName
|
422 |
return $GLOBALS['polylang'];
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Template tag: displays the language switcher.
|
8 |
+
* The function does nothing if used outside the frontend.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
*
|
10 |
* @api
|
11 |
* @since 0.5
|
12 |
*
|
13 |
+
* @param array $args {
|
14 |
+
* Optional array of arguments.
|
15 |
+
*
|
16 |
+
* @type int $dropdown The list is displayed as dropdown if set to 1, defaults to 0.
|
17 |
+
* @type int $echo Echoes the list if set to 1, defaults to 1.
|
18 |
+
* @type int $hide_if_empty Hides languages with no posts ( or pages ) if set to 1, defaults to 1.
|
19 |
+
* @type int $show_flags Displays flags if set to 1, defaults to 0.
|
20 |
+
* @type int $show_names Shows language names if set to 1, defaults to 1.
|
21 |
+
* @type string $display_names_as Whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name.
|
22 |
+
* @type int $force_home Will always link to the homepage in the translated language if set to 1, defaults to 0.
|
23 |
+
* @type int $hide_if_no_translation Hides the link if there is no translation if set to 1, defaults to 0.
|
24 |
+
* @type int $hide_current Hides the current language if set to 1, defaults to 0.
|
25 |
+
* @type int $post_id Returns links to the translations of the post defined by post_id if set, defaults to not set.
|
26 |
+
* @type int $raw Return a raw array instead of html markup if set to 1, defaults to 0.
|
27 |
+
* @type string $item_spacing Whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to 'preserve'.
|
28 |
+
* }
|
29 |
+
* @return string|array Either the html markup of the switcher or the raw elements to build a custom language switcher.
|
30 |
*/
|
31 |
+
function pll_the_languages( $args = array() ) {
|
32 |
+
$switcher = new PLL_Switcher();
|
33 |
+
return $switcher->the_languages( PLL()->links, $args );
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
* Returns the current language on frontend.
|
38 |
+
* Returns the language set in admin language filter on backend ( false if set to all languages ).
|
39 |
*
|
40 |
* @api
|
41 |
* @since 0.8.1
|
42 |
*
|
43 |
+
* @param string $field Optional, the language field to return ( @see PLL_Language ), defaults to 'slug'. Pass OBJECT constant to get the language object.
|
44 |
+
* @return string|PLL_Language|false The requested field for the current language.
|
45 |
*/
|
46 |
function pll_current_language( $field = 'slug' ) {
|
47 |
if ( OBJECT === $field ) {
|
51 |
}
|
52 |
|
53 |
/**
|
54 |
+
* Returns the default language.
|
55 |
*
|
56 |
* @api
|
57 |
* @since 1.0
|
58 |
*
|
59 |
+
* @param string $field Optional, the language field to return ( @see PLL_Language ), defaults to 'slug'. Pass OBJECT constant to get the language object.
|
60 |
+
* @return string|PLL_Language|false The requested field for the default language.
|
61 |
*/
|
62 |
function pll_default_language( $field = 'slug' ) {
|
63 |
if ( isset( PLL()->options['default_lang'] ) ) {
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
+
* Among the post and its translations, returns the id of the post which is in the language represented by $lang.
|
77 |
*
|
78 |
* @api
|
79 |
* @since 0.5
|
80 |
*
|
81 |
+
* @param int $post_id Post id.
|
82 |
+
* @param string $lang Optional language code, defaults to the current language.
|
83 |
+
* @return int|false|null Post id of the translation if it exists, false otherwise, null if the current language is not defined yet.
|
84 |
*/
|
85 |
+
function pll_get_post( $post_id, $lang = '' ) {
|
86 |
+
return ( $lang = $lang ? $lang : pll_current_language() ) ? PLL()->model->post->get( $post_id, $lang ) : null;
|
87 |
}
|
88 |
|
89 |
/**
|
90 |
+
* Among the term and its translations, returns the id of the term which is in the language represented by $lang.
|
91 |
*
|
92 |
* @api
|
93 |
* @since 0.5
|
94 |
*
|
95 |
+
* @param int $term_id Term id.
|
96 |
+
* @param string $lang Optional language code, defaults to the current language.
|
97 |
+
* @return int|false|null Term id of the translation if it exists, false otherwise, null if the current language is not defined yet.
|
98 |
*/
|
99 |
+
function pll_get_term( $term_id, $lang = '' ) {
|
100 |
+
return ( $lang = $lang ? $lang : pll_current_language() ) ? PLL()->model->term->get( $term_id, $lang ) : null;
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
+
* Returns the home url in a language.
|
105 |
*
|
106 |
* @api
|
107 |
* @since 0.8
|
108 |
*
|
109 |
+
* @param string $lang Optional language code, defaults to the current language.
|
110 |
* @return string
|
111 |
*/
|
112 |
function pll_home_url( $lang = '' ) {
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
+
* Registers a string for translation in the "strings translation" panel.
|
122 |
*
|
123 |
* @api
|
124 |
* @since 0.6
|
125 |
*
|
126 |
+
* @param string $name A unique name for the string.
|
127 |
+
* @param string $string The string to register.
|
128 |
+
* @param string $context Optional, the group in which the string is registered, defaults to 'polylang'.
|
129 |
+
* @param bool $multiline Optional, true if the string table should display a multiline textarea,
|
130 |
+
* false if should display a single line input, defaults to false.
|
131 |
+
* @return void
|
132 |
*/
|
133 |
function pll_register_string( $name, $string, $context = 'Polylang', $multiline = false ) {
|
134 |
if ( PLL() instanceof PLL_Admin_Base ) {
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
+
* Translates a string ( previously registered with pll_register_string ).
|
141 |
*
|
142 |
* @api
|
143 |
* @since 0.6
|
144 |
*
|
145 |
+
* @param string $string The string to translate.
|
146 |
+
* @return string The string translated in the current language.
|
147 |
*/
|
148 |
function pll__( $string ) {
|
149 |
return is_scalar( $string ) ? __( $string, 'pll_string' ) : $string; // PHPCS:ignore WordPress.WP.I18n
|
155 |
* @api
|
156 |
* @since 2.1
|
157 |
*
|
158 |
+
* @param string $string The string to translate.
|
159 |
+
* @return string The string translated in the current language.
|
160 |
*/
|
161 |
function pll_esc_html__( $string ) {
|
162 |
return esc_html( pll__( $string ) );
|
168 |
* @api
|
169 |
* @since 2.1
|
170 |
*
|
171 |
+
* @param string $string The string to translate.
|
172 |
+
* @return string The string translated in the current language.
|
173 |
*/
|
174 |
function pll_esc_attr__( $string ) {
|
175 |
return esc_attr( pll__( $string ) );
|
182 |
* @api
|
183 |
* @since 0.6
|
184 |
*
|
185 |
+
* @param string $string The string to translate.
|
186 |
+
* @return void
|
187 |
*/
|
188 |
function pll_e( $string ) {
|
189 |
echo pll__( $string ); // phpcs:ignore
|
195 |
* @api
|
196 |
* @since 2.1
|
197 |
*
|
198 |
+
* @param string $string The string to translate.
|
199 |
+
* @return void
|
200 |
*/
|
201 |
function pll_esc_html_e( $string ) {
|
202 |
echo pll_esc_html__( $string ); // phpcs:ignore WordPress.Security.EscapeOutput
|
208 |
* @api
|
209 |
* @since 2.1
|
210 |
*
|
211 |
+
* @param string $string The string to translate.
|
212 |
+
* @return void
|
213 |
*/
|
214 |
function pll_esc_attr_e( $string ) {
|
215 |
echo pll_esc_attr__( $string ); // phpcs:ignore WordPress.Security.EscapeOutput
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
+
* Translates a string ( previously registered with pll_register_string ).
|
220 |
*
|
221 |
* @api
|
222 |
* @since 1.5.4
|
223 |
*
|
224 |
+
* @param string $string The string to translate.
|
225 |
+
* @param string $lang Language code.
|
226 |
+
* @return string The string translated in the requested language.
|
227 |
*/
|
228 |
function pll_translate_string( $string, $lang ) {
|
229 |
if ( PLL() instanceof PLL_Frontend && pll_current_language() == $lang ) {
|
234 |
return $string;
|
235 |
}
|
236 |
|
237 |
+
static $cache; // Cache object to avoid loading the same translations object several times.
|
238 |
|
239 |
if ( empty( $cache ) ) {
|
240 |
$cache = new PLL_Cache();
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
+
* Returns true if Polylang manages languages and translations for this post type.
|
254 |
*
|
255 |
* @api
|
256 |
* @since 1.0.1
|
257 |
*
|
258 |
+
* @param string $post_type Post type name.
|
259 |
* @return bool
|
260 |
*/
|
261 |
function pll_is_translated_post_type( $post_type ) {
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
+
* Returns true if Polylang manages languages and translations for this taxonomy.
|
267 |
*
|
268 |
* @api
|
269 |
* @since 1.0.1
|
270 |
*
|
271 |
+
* @param string $tax Taxonomy name.
|
272 |
* @return bool
|
273 |
*/
|
274 |
function pll_is_translated_taxonomy( $tax ) {
|
276 |
}
|
277 |
|
278 |
/**
|
279 |
+
* Returns the list of available languages.
|
|
|
|
|
|
|
|
|
|
|
280 |
*
|
281 |
* @api
|
282 |
* @since 1.5
|
283 |
*
|
284 |
+
* @param array $args {
|
285 |
+
* Optional array of arguments.
|
286 |
+
*
|
287 |
+
* @type bool $hide_empty Hides languages with no posts if set to true ( defaults to false ).
|
288 |
+
* @type string $fields Return only that field if set ( @see PLL_Language for a list of fields ), defaults to 'slug'.
|
289 |
+
* }
|
290 |
+
* @return string[]
|
291 |
*/
|
292 |
function pll_languages_list( $args = array() ) {
|
293 |
$args = wp_parse_args( $args, array( 'fields' => 'slug' ) );
|
295 |
}
|
296 |
|
297 |
/**
|
298 |
+
* Sets the post language.
|
299 |
*
|
300 |
* @api
|
301 |
* @since 1.5
|
302 |
*
|
303 |
+
* @param int $id Post id.
|
304 |
+
* @param string $lang Language code.
|
305 |
+
* @return void
|
306 |
*/
|
307 |
function pll_set_post_language( $id, $lang ) {
|
308 |
PLL()->model->post->set_language( $id, $lang );
|
309 |
}
|
310 |
|
311 |
/**
|
312 |
+
* Sets the term language.
|
313 |
*
|
314 |
* @api
|
315 |
* @since 1.5
|
316 |
*
|
317 |
+
* @param int $id Term id.
|
318 |
+
* @param string $lang Language code.
|
319 |
+
* @return void
|
320 |
*/
|
321 |
function pll_set_term_language( $id, $lang ) {
|
322 |
PLL()->model->term->set_language( $id, $lang );
|
323 |
}
|
324 |
|
325 |
/**
|
326 |
+
* Save posts translations.
|
327 |
*
|
328 |
* @api
|
329 |
* @since 1.5
|
330 |
*
|
331 |
+
* @param int[] $arr An associative array of translations with language code as key and post id as value.
|
332 |
+
* @return void
|
333 |
*/
|
334 |
function pll_save_post_translations( $arr ) {
|
335 |
PLL()->model->post->save_translations( reset( $arr ), $arr );
|
341 |
* @api
|
342 |
* @since 1.5
|
343 |
*
|
344 |
+
* @param int[] $arr An associative array of translations with language code as key and term id as value.
|
345 |
+
* @return void
|
346 |
*/
|
347 |
function pll_save_term_translations( $arr ) {
|
348 |
PLL()->model->term->save_translations( reset( $arr ), $arr );
|
349 |
}
|
350 |
|
351 |
/**
|
352 |
+
* Returns the post language.
|
353 |
*
|
354 |
* @api
|
355 |
* @since 1.5.4
|
356 |
*
|
357 |
+
* @param int $post_id Post id.
|
358 |
+
* @param string $field Optional, the language field to return ( @see PLL_Language ), defaults to 'slug'.
|
359 |
+
* @return string|false The requested field for the post language, false if no language is associated to that post.
|
360 |
*/
|
361 |
function pll_get_post_language( $post_id, $field = 'slug' ) {
|
362 |
return ( $lang = PLL()->model->post->get_language( $post_id ) ) ? $lang->$field : false;
|
363 |
}
|
364 |
|
365 |
/**
|
366 |
+
* Returns the term language.
|
367 |
*
|
368 |
* @api
|
369 |
* @since 1.5.4
|
370 |
*
|
371 |
+
* @param int $term_id Term id.
|
372 |
+
* @param string $field Optional, the language field to return ( @see PLL_Language ), defaults to 'slug'.
|
373 |
+
* @return string|false The requested field for the term language, false if no language is associated to that term.
|
374 |
*/
|
375 |
function pll_get_term_language( $term_id, $field = 'slug' ) {
|
376 |
return ( $lang = PLL()->model->term->get_language( $term_id ) ) ? $lang->$field : false;
|
377 |
}
|
378 |
|
379 |
/**
|
380 |
+
* Returns an array of translations of a post.
|
381 |
*
|
382 |
* @api
|
383 |
* @since 1.8
|
384 |
*
|
385 |
+
* @param int $post_id Post id.
|
386 |
+
* @return int[] An associative array of translations with language code as key and translation post id as value.
|
387 |
*/
|
388 |
function pll_get_post_translations( $post_id ) {
|
389 |
return PLL()->model->post->get_translations( $post_id );
|
390 |
}
|
391 |
|
392 |
/**
|
393 |
+
* Returns an array of translations of a term.
|
394 |
*
|
395 |
* @api
|
396 |
* @since 1.8
|
397 |
*
|
398 |
+
* @param int $term_id Term id.
|
399 |
+
* @return int[] An associative array of translations with language code as key and translation term id as value.
|
400 |
*/
|
401 |
function pll_get_term_translations( $term_id ) {
|
402 |
return PLL()->model->term->get_translations( $term_id );
|
403 |
}
|
404 |
|
405 |
/**
|
406 |
+
* Counts posts in a language.
|
407 |
*
|
408 |
* @api
|
409 |
* @since 1.5
|
410 |
*
|
411 |
* @param string $lang Language code.
|
412 |
+
* @param array $args {
|
413 |
+
* Optional arguments.
|
414 |
+
* Accepted keys:
|
415 |
+
*
|
416 |
+
* @type string $post_type Post type.
|
417 |
+
* @type int $m YearMonth ( ex: 201307 ).
|
418 |
+
* @type int $year 4 digit year.
|
419 |
+
* @type int $monthnum Month number (from 1 to 12).
|
420 |
+
* @type int $day Day of the month (from 1 to 31).
|
421 |
+
* @type int $author Author id.
|
422 |
+
* @type string $author_name Author nicename.
|
423 |
+
* @type string $post_format Post format.
|
424 |
+
* @type string $post_status Post status.
|
425 |
+
* }
|
426 |
* @return int Posts count.
|
427 |
*/
|
428 |
function pll_count_posts( $lang, $args = array() ) {
|
430 |
}
|
431 |
|
432 |
/**
|
433 |
+
* Allows to access the Polylang instance.
|
434 |
+
* However, it is always preferable to use API functions
|
435 |
+
* as internal methods may be changed without prior notice.
|
436 |
*
|
437 |
* @since 1.8
|
438 |
+
*
|
439 |
+
* @return PLL_Frontend|PLL_Admin|PLL_Settings|PLL_REST_Request
|
440 |
*/
|
441 |
function PLL() { // PHPCS:ignore WordPress.NamingConventions.ValidFunctionName
|
442 |
return $GLOBALS['polylang'];
|
include/base.php
CHANGED
@@ -17,8 +17,6 @@ abstract class PLL_Base {
|
|
17 |
public $options;
|
18 |
|
19 |
/**
|
20 |
-
* Instance of PLL_Model.
|
21 |
-
*
|
22 |
* @var PLL_Model
|
23 |
*/
|
24 |
public $model;
|
@@ -45,11 +43,11 @@ abstract class PLL_Base {
|
|
45 |
public $terms;
|
46 |
|
47 |
/**
|
48 |
-
* Constructor
|
49 |
*
|
50 |
* @since 1.2
|
51 |
*
|
52 |
-
* @param
|
53 |
*/
|
54 |
public function __construct( &$links_model ) {
|
55 |
$this->links_model = &$links_model;
|
@@ -63,6 +61,7 @@ abstract class PLL_Base {
|
|
63 |
// User defined strings translations
|
64 |
add_action( 'pll_language_defined', array( $this, 'load_strings_translations' ), 5 );
|
65 |
add_action( 'change_locale', array( $this, 'load_strings_translations' ) ); // Since WP 4.7
|
|
|
66 |
|
67 |
// Switch_to_blog
|
68 |
add_action( 'switch_blog', array( $this, 'switch_blog' ), 10, 2 );
|
@@ -73,6 +72,8 @@ abstract class PLL_Base {
|
|
73 |
* only when at least one language is defined.
|
74 |
*
|
75 |
* @since 2.6
|
|
|
|
|
76 |
*/
|
77 |
public function init() {
|
78 |
if ( $this->model->get_languages_list() ) {
|
@@ -91,6 +92,8 @@ abstract class PLL_Base {
|
|
91 |
* Registers our widgets
|
92 |
*
|
93 |
* @since 0.1
|
|
|
|
|
94 |
*/
|
95 |
public function widgets_init() {
|
96 |
register_widget( 'PLL_Widget_Languages' );
|
@@ -109,10 +112,11 @@ abstract class PLL_Base {
|
|
109 |
* @since 2.1.3 $locale parameter added.
|
110 |
*
|
111 |
* @param string $locale Locale. Defaults to current locale.
|
|
|
112 |
*/
|
113 |
public function load_strings_translations( $locale = '' ) {
|
114 |
if ( empty( $locale ) ) {
|
115 |
-
$locale = get_locale();
|
116 |
}
|
117 |
|
118 |
$language = $this->model->get_language( $locale );
|
@@ -127,69 +131,40 @@ abstract class PLL_Base {
|
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
-
* Resets some variables when
|
131 |
-
*
|
132 |
*
|
133 |
* @since 1.5.1
|
134 |
*
|
135 |
-
* @param int $
|
136 |
-
* @param int $
|
137 |
-
* @return
|
138 |
*/
|
139 |
-
public function switch_blog( $
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
// 2nd test needed when Polylang is not networked activated
|
144 |
-
// 3rd test needed when Polylang is networked activated and a new site is created
|
145 |
-
if ( $new_blog != $old_blog && in_array( POLYLANG_BASENAME, $plugins ) && get_option( 'polylang' ) ) {
|
146 |
-
$this->options = get_option( 'polylang' ); // Needed for menus
|
147 |
remove_action( 'pre_option_rewrite_rules', array( $this->links_model, 'prepare_rewrite_rules' ) );
|
148 |
$this->links_model = $this->model->get_links_model();
|
149 |
-
return true;
|
150 |
}
|
151 |
-
return false;
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
-
*
|
156 |
-
* Allows for example to call $polylang->get_languages_list() instead of $polylang->model->get_languages_list()
|
157 |
-
* This works but should be slower than the direct call, thus an error is triggered in debug mode
|
158 |
*
|
159 |
-
* @since
|
160 |
*
|
161 |
-
* @param
|
162 |
-
* @param
|
|
|
163 |
*/
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
if ( WP_DEBUG ) {
|
168 |
-
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
169 |
-
$i = 1 + empty( $debug[1]['line'] ); // The file and line are in $debug[2] if the function was called using call_user_func
|
170 |
-
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
171 |
-
sprintf(
|
172 |
-
'%1$s was called incorrectly in %3$s on line %4$s: the call to $polylang->%1$s() has been deprecated in Polylang 1.2, use PLL()->%2$s->%1$s() instead.' . "\nError handler",
|
173 |
-
esc_html( $func ),
|
174 |
-
esc_html( $prop ),
|
175 |
-
esc_html( $debug[ $i ]['file'] ),
|
176 |
-
absint( $debug[ $i ]['line'] )
|
177 |
-
)
|
178 |
-
);
|
179 |
-
}
|
180 |
-
return call_user_func_array( array( $obj, $func ), $args );
|
181 |
-
}
|
182 |
-
}
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
esc_html( $debug[0]['file'] ),
|
190 |
-
absint( $debug[0]['line'] )
|
191 |
-
),
|
192 |
-
E_USER_ERROR
|
193 |
-
);
|
194 |
}
|
195 |
}
|
17 |
public $options;
|
18 |
|
19 |
/**
|
|
|
|
|
20 |
* @var PLL_Model
|
21 |
*/
|
22 |
public $model;
|
43 |
public $terms;
|
44 |
|
45 |
/**
|
46 |
+
* Constructor.
|
47 |
*
|
48 |
* @since 1.2
|
49 |
*
|
50 |
+
* @param PLL_Links_Model $links_model Links Model.
|
51 |
*/
|
52 |
public function __construct( &$links_model ) {
|
53 |
$this->links_model = &$links_model;
|
61 |
// User defined strings translations
|
62 |
add_action( 'pll_language_defined', array( $this, 'load_strings_translations' ), 5 );
|
63 |
add_action( 'change_locale', array( $this, 'load_strings_translations' ) ); // Since WP 4.7
|
64 |
+
add_action( 'personal_options_update', array( $this, 'load_strings_translations' ), 1, 0 ); // Before WP, for confirmation request when changing the user email.
|
65 |
|
66 |
// Switch_to_blog
|
67 |
add_action( 'switch_blog', array( $this, 'switch_blog' ), 10, 2 );
|
72 |
* only when at least one language is defined.
|
73 |
*
|
74 |
* @since 2.6
|
75 |
+
*
|
76 |
+
* @return void
|
77 |
*/
|
78 |
public function init() {
|
79 |
if ( $this->model->get_languages_list() ) {
|
92 |
* Registers our widgets
|
93 |
*
|
94 |
* @since 0.1
|
95 |
+
*
|
96 |
+
* @return void
|
97 |
*/
|
98 |
public function widgets_init() {
|
99 |
register_widget( 'PLL_Widget_Languages' );
|
112 |
* @since 2.1.3 $locale parameter added.
|
113 |
*
|
114 |
* @param string $locale Locale. Defaults to current locale.
|
115 |
+
* @return void
|
116 |
*/
|
117 |
public function load_strings_translations( $locale = '' ) {
|
118 |
if ( empty( $locale ) ) {
|
119 |
+
$locale = ( is_admin() && ! Polylang::is_ajax_on_front() ) ? get_user_locale() : get_locale();
|
120 |
}
|
121 |
|
122 |
$language = $this->model->get_language( $locale );
|
131 |
}
|
132 |
|
133 |
/**
|
134 |
+
* Resets some variables when the blog is switched.
|
135 |
+
* Applied only if Polylang is active on the new blog.
|
136 |
*
|
137 |
* @since 1.5.1
|
138 |
*
|
139 |
+
* @param int $new_blog_id New blog ID.
|
140 |
+
* @param int $prev_blog_id Previous blog ID.
|
141 |
+
* @return void
|
142 |
*/
|
143 |
+
public function switch_blog( $new_blog_id, $prev_blog_id ) {
|
144 |
+
if ( $this->is_active_on_new_blog( $new_blog_id, $prev_blog_id ) ) {
|
145 |
+
$this->options = get_option( 'polylang' ); // Needed for menus.
|
|
|
|
|
|
|
|
|
|
|
146 |
remove_action( 'pre_option_rewrite_rules', array( $this->links_model, 'prepare_rewrite_rules' ) );
|
147 |
$this->links_model = $this->model->get_links_model();
|
|
|
148 |
}
|
|
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
+
* Checks if Polylang is active on the new blog when the blog is switched.
|
|
|
|
|
153 |
*
|
154 |
+
* @since 3.0
|
155 |
*
|
156 |
+
* @param int $new_blog_id New blog ID.
|
157 |
+
* @param int $prev_blog_id Previous blog ID.
|
158 |
+
* @return bool
|
159 |
*/
|
160 |
+
protected function is_active_on_new_blog( $new_blog_id, $prev_blog_id ) {
|
161 |
+
$plugins = ( $sitewide_plugins = get_site_option( 'active_sitewide_plugins' ) ) && is_array( $sitewide_plugins ) ? array_keys( $sitewide_plugins ) : array();
|
162 |
+
$plugins = array_merge( $plugins, get_option( 'active_plugins', array() ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
|
164 |
+
/*
|
165 |
+
* The 2nd test is needed when Polylang is not networked activated.
|
166 |
+
* The 3rd test is needed when Polylang is networked activated and a new site is created.
|
167 |
+
*/
|
168 |
+
return $new_blog_id !== $prev_blog_id && in_array( POLYLANG_BASENAME, $plugins ) && get_option( 'polylang' );
|
|
|
|
|
|
|
|
|
|
|
169 |
}
|
170 |
}
|
include/cache.php
CHANGED
@@ -10,7 +10,19 @@
|
|
10 |
* @since 1.7
|
11 |
*/
|
12 |
class PLL_Cache {
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor
|
@@ -28,6 +40,7 @@ class PLL_Cache {
|
|
28 |
* @since 1.7
|
29 |
*
|
30 |
* @param int $new_blog
|
|
|
31 |
*/
|
32 |
public function switch_blog( $new_blog ) {
|
33 |
$this->blog_id = $new_blog;
|
@@ -40,6 +53,7 @@ class PLL_Cache {
|
|
40 |
*
|
41 |
* @param string $key
|
42 |
* @param mixed $data
|
|
|
43 |
*/
|
44 |
public function set( $key, $data ) {
|
45 |
$this->cache[ $this->blog_id ][ $key ] = $data;
|
@@ -63,6 +77,7 @@ class PLL_Cache {
|
|
63 |
* @since 1.7
|
64 |
*
|
65 |
* @param string $key
|
|
|
66 |
*/
|
67 |
public function clean( $key = '' ) {
|
68 |
if ( empty( $key ) ) {
|
10 |
* @since 1.7
|
11 |
*/
|
12 |
class PLL_Cache {
|
13 |
+
/**
|
14 |
+
* Current site id.
|
15 |
+
*
|
16 |
+
* @var int
|
17 |
+
*/
|
18 |
+
protected $blog_id;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The cache container.
|
22 |
+
*
|
23 |
+
* @var array
|
24 |
+
*/
|
25 |
+
protected $cache;
|
26 |
|
27 |
/**
|
28 |
* Constructor
|
40 |
* @since 1.7
|
41 |
*
|
42 |
* @param int $new_blog
|
43 |
+
* @return void
|
44 |
*/
|
45 |
public function switch_blog( $new_blog ) {
|
46 |
$this->blog_id = $new_blog;
|
53 |
*
|
54 |
* @param string $key
|
55 |
* @param mixed $data
|
56 |
+
* @return void
|
57 |
*/
|
58 |
public function set( $key, $data ) {
|
59 |
$this->cache[ $this->blog_id ][ $key ] = $data;
|
77 |
* @since 1.7
|
78 |
*
|
79 |
* @param string $key
|
80 |
+
* @return void
|
81 |
*/
|
82 |
public function clean( $key = '' ) {
|
83 |
if ( empty( $key ) ) {
|
include/class-polylang.php
CHANGED
@@ -128,6 +128,8 @@ class Polylang {
|
|
128 |
* May be overridden by a plugin if set before plugins_loaded, 1
|
129 |
*
|
130 |
* @since 1.6
|
|
|
|
|
131 |
*/
|
132 |
public static function define_constants() {
|
133 |
// Cookie name. no cookie will be used if set to false
|
@@ -156,6 +158,8 @@ class Polylang {
|
|
156 |
* setups models and separate admin and frontend
|
157 |
*
|
158 |
* @since 1.2
|
|
|
|
|
159 |
*/
|
160 |
public function init() {
|
161 |
global $polylang;
|
@@ -237,8 +241,11 @@ class Polylang {
|
|
237 |
require_once __DIR__ . '/api.php'; // Loads the API
|
238 |
|
239 |
// Loads the modules.
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
242 |
}
|
243 |
|
244 |
$polylang->init();
|
128 |
* May be overridden by a plugin if set before plugins_loaded, 1
|
129 |
*
|
130 |
* @since 1.6
|
131 |
+
*
|
132 |
+
* @return void
|
133 |
*/
|
134 |
public static function define_constants() {
|
135 |
// Cookie name. no cookie will be used if set to false
|
158 |
* setups models and separate admin and frontend
|
159 |
*
|
160 |
* @since 1.2
|
161 |
+
*
|
162 |
+
* @return void
|
163 |
*/
|
164 |
public function init() {
|
165 |
global $polylang;
|
241 |
require_once __DIR__ . '/api.php'; // Loads the API
|
242 |
|
243 |
// Loads the modules.
|
244 |
+
$load_scripts = glob( POLYLANG_DIR . '/modules/*/load.php', GLOB_NOSORT );
|
245 |
+
if ( is_array( $load_scripts ) ) {
|
246 |
+
foreach ( $load_scripts as $load_script ) {
|
247 |
+
require_once $load_script; // phpcs:ignore WordPressVIPMinimum.Files.IncludingFile.UsingVariable
|
248 |
+
}
|
249 |
}
|
250 |
|
251 |
$polylang->init();
|
include/cookie.php
CHANGED
@@ -55,6 +55,7 @@ class PLL_Cookie {
|
|
55 |
* @type bool $httponly Should the cookie accessed only over http protocol? Defaults to false.
|
56 |
* @type string $samesite Either 'Strict', 'Lax' or 'None', defaults to 'Lax'.
|
57 |
* }
|
|
|
58 |
*/
|
59 |
public static function set( $lang, $args = array() ) {
|
60 |
$args = self::parse_args( $args );
|
55 |
* @type bool $httponly Should the cookie accessed only over http protocol? Defaults to false.
|
56 |
* @type string $samesite Either 'Strict', 'Lax' or 'None', defaults to 'Lax'.
|
57 |
* }
|
58 |
+
* @return void
|
59 |
*/
|
60 |
public static function set( $lang, $args = array() ) {
|
61 |
$args = self::parse_args( $args );
|
include/crud-posts.php
CHANGED
@@ -4,12 +4,30 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Adds actions and filters related to languages when creating, updating or deleting posts
|
8 |
-
* Actions
|
9 |
*
|
10 |
* @since 2.4
|
11 |
*/
|
12 |
class PLL_CRUD_Posts {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
@@ -42,6 +60,7 @@ class PLL_CRUD_Posts {
|
|
42 |
* @since 1.5
|
43 |
*
|
44 |
* @param int $post_id
|
|
|
45 |
*/
|
46 |
public function set_default_language( $post_id ) {
|
47 |
if ( ! $this->model->post->get_language( $post_id ) ) {
|
@@ -64,16 +83,17 @@ class PLL_CRUD_Posts {
|
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
-
* Called when a post ( or page ) is saved, published or updated
|
68 |
*
|
69 |
* @since 0.1
|
70 |
-
* @since 2.3 Does not save the language and translations anymore, unless the post has no language yet
|
71 |
*
|
72 |
-
* @param int
|
73 |
-
* @param
|
|
|
74 |
*/
|
75 |
public function save_post( $post_id, $post ) {
|
76 |
-
// Does nothing except on post types which are filterable
|
77 |
if ( $this->model->is_translated_post_type( $post->post_type ) ) {
|
78 |
if ( $id = wp_is_post_revision( $post_id ) ) {
|
79 |
$post_id = $id;
|
@@ -86,27 +106,28 @@ class PLL_CRUD_Posts {
|
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
-
* Fires after the post language and translations are saved
|
90 |
*
|
91 |
* @since 1.2
|
92 |
*
|
93 |
-
* @param int
|
94 |
-
* @param
|
95 |
-
* @param
|
96 |
*/
|
97 |
do_action( 'pll_save_post', $post_id, $post, $this->model->post->get_translations( $post_id ) );
|
98 |
}
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
-
*
|
103 |
*
|
104 |
* @since 2.3
|
105 |
*
|
106 |
-
* @param int
|
107 |
-
* @param
|
108 |
-
* @param
|
109 |
-
* @param string
|
|
|
110 |
*/
|
111 |
public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy ) {
|
112 |
static $avoid_recursion;
|
@@ -198,6 +219,7 @@ class PLL_CRUD_Posts {
|
|
198 |
* @since 0.1
|
199 |
*
|
200 |
* @param int $post_id
|
|
|
201 |
*/
|
202 |
public function delete_post( $post_id ) {
|
203 |
if ( ! wp_is_post_revision( $post_id ) ) {
|
@@ -248,27 +270,32 @@ class PLL_CRUD_Posts {
|
|
248 |
*/
|
249 |
public function create_media_translation( $post_id, $lang ) {
|
250 |
if ( empty( $post_id ) ) {
|
251 |
-
return
|
252 |
}
|
253 |
|
254 |
-
$post = get_post( $post_id );
|
255 |
|
256 |
if ( empty( $post ) ) {
|
257 |
-
return
|
258 |
}
|
259 |
|
260 |
$lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
|
261 |
|
|
|
|
|
|
|
|
|
262 |
// Create a new attachment ( translate attachment parent if exists ).
|
263 |
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
|
264 |
-
$post
|
265 |
-
$post
|
266 |
-
$post
|
267 |
-
$tr_id = wp_insert_attachment( wp_slash(
|
268 |
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
|
269 |
|
270 |
// Copy metadata.
|
271 |
-
|
|
|
272 |
wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
|
273 |
}
|
274 |
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Adds actions and filters related to languages when creating, updating or deleting posts.
|
8 |
+
* Actions and filters triggered when reading posts are handled separately.
|
9 |
*
|
10 |
* @since 2.4
|
11 |
*/
|
12 |
class PLL_CRUD_Posts {
|
13 |
+
/**
|
14 |
+
* @var PLL_Model
|
15 |
+
*/
|
16 |
+
protected $model;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Preferred language to assign to a new post.
|
20 |
+
*
|
21 |
+
* @var PLL_Language
|
22 |
+
*/
|
23 |
+
protected $pref_lang;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Current language.
|
27 |
+
*
|
28 |
+
* @var PLL_Language
|
29 |
+
*/
|
30 |
+
protected $curlang;
|
31 |
|
32 |
/**
|
33 |
* Constructor
|
60 |
* @since 1.5
|
61 |
*
|
62 |
* @param int $post_id
|
63 |
+
* @return void
|
64 |
*/
|
65 |
public function set_default_language( $post_id ) {
|
66 |
if ( ! $this->model->post->get_language( $post_id ) ) {
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
+
* Called when a post ( or page ) is saved, published or updated.
|
87 |
*
|
88 |
* @since 0.1
|
89 |
+
* @since 2.3 Does not save the language and translations anymore, unless the post has no language yet.
|
90 |
*
|
91 |
+
* @param int $post_id Post id of the post being saved.
|
92 |
+
* @param WP_Post $post The post being saved.
|
93 |
+
* @return void
|
94 |
*/
|
95 |
public function save_post( $post_id, $post ) {
|
96 |
+
// Does nothing except on post types which are filterable.
|
97 |
if ( $this->model->is_translated_post_type( $post->post_type ) ) {
|
98 |
if ( $id = wp_is_post_revision( $post_id ) ) {
|
99 |
$post_id = $id;
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
+
* Fires after the post language and translations are saved.
|
110 |
*
|
111 |
* @since 1.2
|
112 |
*
|
113 |
+
* @param int $post_id Post id.
|
114 |
+
* @param WP_Post $post Post object.
|
115 |
+
* @param int[] $translations The list of translations post ids.
|
116 |
*/
|
117 |
do_action( 'pll_save_post', $post_id, $post, $this->model->post->get_translations( $post_id ) );
|
118 |
}
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
+
* Makes sure that saved terms are in the right language (especially tags with same name in different languages).
|
123 |
*
|
124 |
* @since 2.3
|
125 |
*
|
126 |
+
* @param int $object_id Object ID.
|
127 |
+
* @param WP_Term[] $terms An array of object terms.
|
128 |
+
* @param int[] $tt_ids An array of term taxonomy IDs.
|
129 |
+
* @param string $taxonomy Taxonomy slug.
|
130 |
+
* @return void
|
131 |
*/
|
132 |
public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy ) {
|
133 |
static $avoid_recursion;
|
219 |
* @since 0.1
|
220 |
*
|
221 |
* @param int $post_id
|
222 |
+
* @return void
|
223 |
*/
|
224 |
public function delete_post( $post_id ) {
|
225 |
if ( ! wp_is_post_revision( $post_id ) ) {
|
270 |
*/
|
271 |
public function create_media_translation( $post_id, $lang ) {
|
272 |
if ( empty( $post_id ) ) {
|
273 |
+
return 0;
|
274 |
}
|
275 |
|
276 |
+
$post = get_post( $post_id, ARRAY_A );
|
277 |
|
278 |
if ( empty( $post ) ) {
|
279 |
+
return 0;
|
280 |
}
|
281 |
|
282 |
$lang = $this->model->get_language( $lang ); // Make sure we get a valid language slug.
|
283 |
|
284 |
+
if ( empty( $lang ) ) {
|
285 |
+
return 0;
|
286 |
+
}
|
287 |
+
|
288 |
// Create a new attachment ( translate attachment parent if exists ).
|
289 |
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
|
290 |
+
unset( $post['ID'] ); // Will force the creation.
|
291 |
+
$post['post_parent'] = ( $post['post_parent'] && $tr_parent = $this->model->post->get_translation( $post['post_parent'], $lang->slug ) ) ? $tr_parent : 0;
|
292 |
+
$post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
|
293 |
+
$tr_id = wp_insert_attachment( wp_slash( $post ) );
|
294 |
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
|
295 |
|
296 |
// Copy metadata.
|
297 |
+
$data = wp_get_attachment_metadata( $post_id, true ); // Unfiltered.
|
298 |
+
if ( is_array( $data ) ) {
|
299 |
wp_update_attachment_metadata( $tr_id, wp_slash( $data ) ); // Directly uses update_post_meta, so expects slashed.
|
300 |
}
|
301 |
|
include/crud-terms.php
CHANGED
@@ -10,7 +10,37 @@
|
|
10 |
* @since 2.4
|
11 |
*/
|
12 |
class PLL_CRUD_Terms {
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
private $tax_query_lang;
|
15 |
|
16 |
/**
|
@@ -49,6 +79,7 @@ class PLL_CRUD_Terms {
|
|
49 |
*
|
50 |
* @param int $term_id
|
51 |
* @param string $taxonomy
|
|
|
52 |
*/
|
53 |
protected function set_default_language( $term_id, $taxonomy ) {
|
54 |
if ( ! $this->model->term->get_language( $term_id ) ) {
|
@@ -69,14 +100,15 @@ class PLL_CRUD_Terms {
|
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
-
* Called when a category or post tag is created or edited
|
73 |
-
* Does nothing except on taxonomies which are filterable
|
74 |
*
|
75 |
* @since 0.1
|
76 |
*
|
77 |
-
* @param int $term_id
|
78 |
-
* @param int $tt_id Term taxonomy id
|
79 |
-
* @param string $taxonomy
|
|
|
80 |
*/
|
81 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
82 |
if ( $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
@@ -88,28 +120,30 @@ class PLL_CRUD_Terms {
|
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
-
* Fires after the term language and translations are saved
|
92 |
*
|
93 |
* @since 1.2
|
94 |
*
|
95 |
-
* @param int $term_id
|
96 |
-
* @param string $taxonomy
|
97 |
-
* @param
|
98 |
*/
|
99 |
do_action( 'pll_save_term', $term_id, $taxonomy, $this->model->term->get_translations( $term_id ) );
|
100 |
}
|
101 |
}
|
102 |
|
103 |
/**
|
104 |
-
* Get the language(s) to filter
|
105 |
*
|
106 |
* @since 1.7.6
|
107 |
*
|
108 |
-
* @param
|
109 |
-
* @param array
|
110 |
-
* @return
|
111 |
*/
|
112 |
protected function get_queried_language( $taxonomies, $args ) {
|
|
|
|
|
113 |
// Does nothing except on taxonomies which are filterable
|
114 |
// Since WP 4.7, make sure not to filter wp_get_object_terms()
|
115 |
if ( ! $this->model->is_translated_taxonomy( $taxonomies ) || ! empty( $args['object_ids'] ) ) {
|
@@ -122,7 +156,7 @@ class PLL_CRUD_Terms {
|
|
122 |
}
|
123 |
|
124 |
// On tags page, everything should be filtered according to the admin language filter except the parent dropdown
|
125 |
-
if ( 'edit-tags.php' === $
|
126 |
return $this->filter_lang;
|
127 |
}
|
128 |
|
@@ -130,17 +164,17 @@ class PLL_CRUD_Terms {
|
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
-
* Adds language dependent cache domain when querying terms
|
134 |
-
* Useful as the 'lang' parameter is not included in cache key by WordPress
|
135 |
*
|
136 |
* @since 1.3
|
137 |
*
|
138 |
-
* @param array
|
139 |
-
* @param
|
140 |
-
* @return array
|
141 |
*/
|
142 |
public function get_terms_args( $args, $taxonomies ) {
|
143 |
-
// Don't break _get_term_hierarchy()
|
144 |
if ( 'all' === $args['get'] && 'id' === $args['orderby'] && 'id=>parent' === $args['fields'] ) {
|
145 |
$args['lang'] = '';
|
146 |
}
|
@@ -162,10 +196,10 @@ class PLL_CRUD_Terms {
|
|
162 |
*
|
163 |
* @since 0.2
|
164 |
*
|
165 |
-
* @param
|
166 |
-
* @param
|
167 |
-
* @param array
|
168 |
-
* @return
|
169 |
*/
|
170 |
public function terms_clauses( $clauses, $taxonomies, $args ) {
|
171 |
$lang = $this->get_queried_language( $taxonomies, $args );
|
@@ -173,22 +207,25 @@ class PLL_CRUD_Terms {
|
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
-
* Sets the WP_Term_Query language when doing a WP_Query
|
177 |
-
* Needed since WP 4.9
|
178 |
*
|
179 |
* @since 2.3.2
|
180 |
*
|
181 |
-
* @param
|
|
|
182 |
*/
|
183 |
public function set_tax_query_lang( $query ) {
|
184 |
$this->tax_query_lang = isset( $query->query_vars['lang'] ) ? $query->query_vars['lang'] : '';
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
-
* Removes the WP_Term_Query language filter for WP_Query
|
189 |
-
* Needed since WP 4.9
|
190 |
*
|
191 |
* @since 2.3.2
|
|
|
|
|
192 |
*/
|
193 |
public function unset_tax_query_lang() {
|
194 |
unset( $this->tax_query_lang );
|
@@ -201,6 +238,7 @@ class PLL_CRUD_Terms {
|
|
201 |
* @since 0.1
|
202 |
*
|
203 |
* @param int $term_id
|
|
|
204 |
*/
|
205 |
public function delete_term( $term_id ) {
|
206 |
$this->model->term->delete_translation( $term_id );
|
10 |
* @since 2.4
|
11 |
*/
|
12 |
class PLL_CRUD_Terms {
|
13 |
+
/**
|
14 |
+
* @var PLL_Model
|
15 |
+
*/
|
16 |
+
public $model;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Current language (used to filter the content).
|
20 |
+
*
|
21 |
+
* @var PLL_Language
|
22 |
+
*/
|
23 |
+
public $curlang;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Language selected in the admin language filter.
|
27 |
+
*
|
28 |
+
* @var PLL_Language
|
29 |
+
*/
|
30 |
+
public $filter_lang;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Preferred language to assign to new contents.
|
34 |
+
*
|
35 |
+
* @var PLL_Language
|
36 |
+
*/
|
37 |
+
public $pref_lang;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Stores the 'lang' query var from WP_Query.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
private $tax_query_lang;
|
45 |
|
46 |
/**
|
79 |
*
|
80 |
* @param int $term_id
|
81 |
* @param string $taxonomy
|
82 |
+
* @return void
|
83 |
*/
|
84 |
protected function set_default_language( $term_id, $taxonomy ) {
|
85 |
if ( ! $this->model->term->get_language( $term_id ) ) {
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
+
* Called when a category or post tag is created or edited.
|
104 |
+
* Does nothing except on taxonomies which are filterable.
|
105 |
*
|
106 |
* @since 0.1
|
107 |
*
|
108 |
+
* @param int $term_id Term id of the term being saved.
|
109 |
+
* @param int $tt_id Term taxonomy id.
|
110 |
+
* @param string $taxonomy Taxonomy name.
|
111 |
+
* @return void
|
112 |
*/
|
113 |
public function save_term( $term_id, $tt_id, $taxonomy ) {
|
114 |
if ( $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Fires after the term language and translations are saved.
|
124 |
*
|
125 |
* @since 1.2
|
126 |
*
|
127 |
+
* @param int $term_id Term id.
|
128 |
+
* @param string $taxonomy Taxonomy name.
|
129 |
+
* @param int[] $translations The list of translations term ids.
|
130 |
*/
|
131 |
do_action( 'pll_save_term', $term_id, $taxonomy, $this->model->term->get_translations( $term_id ) );
|
132 |
}
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* Get the language(s) to filter WP_Term_Query.
|
137 |
*
|
138 |
* @since 1.7.6
|
139 |
*
|
140 |
+
* @param string[] $taxonomies Queried taxonomies.
|
141 |
+
* @param array $args WP_Term_Query arguments.
|
142 |
+
* @return PLL_Language|string|false The language(s) to use in the filter, false otherwise.
|
143 |
*/
|
144 |
protected function get_queried_language( $taxonomies, $args ) {
|
145 |
+
global $pagenow;
|
146 |
+
|
147 |
// Does nothing except on taxonomies which are filterable
|
148 |
// Since WP 4.7, make sure not to filter wp_get_object_terms()
|
149 |
if ( ! $this->model->is_translated_taxonomy( $taxonomies ) || ! empty( $args['object_ids'] ) ) {
|
156 |
}
|
157 |
|
158 |
// On tags page, everything should be filtered according to the admin language filter except the parent dropdown
|
159 |
+
if ( 'edit-tags.php' === $pagenow && empty( $args['class'] ) ) {
|
160 |
return $this->filter_lang;
|
161 |
}
|
162 |
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
+
* Adds language dependent cache domain when querying terms.
|
168 |
+
* Useful as the 'lang' parameter is not included in cache key by WordPress.
|
169 |
*
|
170 |
* @since 1.3
|
171 |
*
|
172 |
+
* @param array $args WP_Term_Query arguments.
|
173 |
+
* @param string[] $taxonomies Queried taxonomies.
|
174 |
+
* @return array Modified arguments.
|
175 |
*/
|
176 |
public function get_terms_args( $args, $taxonomies ) {
|
177 |
+
// Don't break _get_term_hierarchy().
|
178 |
if ( 'all' === $args['get'] && 'id' === $args['orderby'] && 'id=>parent' === $args['fields'] ) {
|
179 |
$args['lang'] = '';
|
180 |
}
|
196 |
*
|
197 |
* @since 0.2
|
198 |
*
|
199 |
+
* @param string[] $clauses List of sql clauses.
|
200 |
+
* @param string[] $taxonomies List of taxonomies.
|
201 |
+
* @param array $args WP_Term_Query arguments.
|
202 |
+
* @return string[] Modified sql clauses.
|
203 |
*/
|
204 |
public function terms_clauses( $clauses, $taxonomies, $args ) {
|
205 |
$lang = $this->get_queried_language( $taxonomies, $args );
|
207 |
}
|
208 |
|
209 |
/**
|
210 |
+
* Sets the WP_Term_Query language when doing a WP_Query.
|
211 |
+
* Needed since WP 4.9.
|
212 |
*
|
213 |
* @since 2.3.2
|
214 |
*
|
215 |
+
* @param WP_Query $query WP_Query object.
|
216 |
+
* @return void
|
217 |
*/
|
218 |
public function set_tax_query_lang( $query ) {
|
219 |
$this->tax_query_lang = isset( $query->query_vars['lang'] ) ? $query->query_vars['lang'] : '';
|
220 |
}
|
221 |
|
222 |
/**
|
223 |
+
* Removes the WP_Term_Query language filter for WP_Query.
|
224 |
+
* Needed since WP 4.9.
|
225 |
*
|
226 |
* @since 2.3.2
|
227 |
+
*
|
228 |
+
* @return void
|
229 |
*/
|
230 |
public function unset_tax_query_lang() {
|
231 |
unset( $this->tax_query_lang );
|
238 |
* @since 0.1
|
239 |
*
|
240 |
* @param int $term_id
|
241 |
+
* @return void
|
242 |
*/
|
243 |
public function delete_term( $term_id ) {
|
244 |
$this->model->term->delete_translation( $term_id );
|
include/filters-links.php
CHANGED
@@ -9,7 +9,36 @@
|
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Filters_Links {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
@@ -75,13 +104,13 @@ class PLL_Filters_Links {
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
-
* Modifies custom posts links
|
79 |
*
|
80 |
* @since 1.6
|
81 |
*
|
82 |
-
* @param string
|
83 |
-
* @param
|
84 |
-
* @return string
|
85 |
*/
|
86 |
public function post_type_link( $link, $post ) {
|
87 |
// /!\ WP does not use pretty permalinks for preview
|
@@ -90,13 +119,13 @@ class PLL_Filters_Links {
|
|
90 |
$link = $this->options['force_lang'] ? $this->links_model->switch_language_in_link( $link, $lang ) : $link;
|
91 |
|
92 |
/**
|
93 |
-
*
|
94 |
*
|
95 |
* @since 1.6
|
96 |
*
|
97 |
-
* @param string
|
98 |
-
* @param
|
99 |
-
* @param
|
100 |
*/
|
101 |
$link = apply_filters( 'pll_post_type_link', $link, $lang, $post );
|
102 |
}
|
@@ -105,14 +134,14 @@ class PLL_Filters_Links {
|
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* Modifies term
|
109 |
*
|
110 |
* @since 0.7
|
111 |
*
|
112 |
-
* @param string
|
113 |
-
* @param
|
114 |
-
* @param string
|
115 |
-
* @return string
|
116 |
*/
|
117 |
public function term_link( $link, $term, $tax ) {
|
118 |
if ( $this->model->is_translated_taxonomy( $tax ) ) {
|
@@ -124,16 +153,17 @@ class PLL_Filters_Links {
|
|
124 |
*
|
125 |
* @since 1.6
|
126 |
*
|
127 |
-
* @param string
|
128 |
-
* @param
|
129 |
-
* @param
|
130 |
*/
|
131 |
return apply_filters( 'pll_term_link', $link, $lang, $term );
|
132 |
}
|
133 |
|
134 |
-
//
|
135 |
if ( 'language' === $tax ) {
|
136 |
-
|
|
|
137 |
}
|
138 |
|
139 |
return $link;
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Filters_Links {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
public $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Instance of a child class of PLL_Links_Model.
|
26 |
+
*
|
27 |
+
* @var PLL_Links_Model
|
28 |
+
*/
|
29 |
+
public $links_model;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var PLL_Links
|
33 |
+
*/
|
34 |
+
public $links;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Current language.
|
38 |
+
*
|
39 |
+
* @var PLL_Language
|
40 |
+
*/
|
41 |
+
public $curlang;
|
42 |
|
43 |
/**
|
44 |
* Constructor
|
104 |
}
|
105 |
|
106 |
/**
|
107 |
+
* Modifies custom posts links.
|
108 |
*
|
109 |
* @since 1.6
|
110 |
*
|
111 |
+
* @param string $link Post link.
|
112 |
+
* @param WP_Post $post Post object.
|
113 |
+
* @return string Modified post link.
|
114 |
*/
|
115 |
public function post_type_link( $link, $post ) {
|
116 |
// /!\ WP does not use pretty permalinks for preview
|
119 |
$link = $this->options['force_lang'] ? $this->links_model->switch_language_in_link( $link, $lang ) : $link;
|
120 |
|
121 |
/**
|
122 |
+
* Filters a post or custom post type link.
|
123 |
*
|
124 |
* @since 1.6
|
125 |
*
|
126 |
+
* @param string $link The post link.
|
127 |
+
* @param PLL_Language $lang The current language.
|
128 |
+
* @param WP_Post $post The post object.
|
129 |
*/
|
130 |
$link = apply_filters( 'pll_post_type_link', $link, $lang, $post );
|
131 |
}
|
134 |
}
|
135 |
|
136 |
/**
|
137 |
+
* Modifies term links.
|
138 |
*
|
139 |
* @since 0.7
|
140 |
*
|
141 |
+
* @param string $link Term link.
|
142 |
+
* @param WP_Term $term Term object.
|
143 |
+
* @param string $tax Taxonomy name;
|
144 |
+
* @return string Modified term link.
|
145 |
*/
|
146 |
public function term_link( $link, $term, $tax ) {
|
147 |
if ( $this->model->is_translated_taxonomy( $tax ) ) {
|
153 |
*
|
154 |
* @since 1.6
|
155 |
*
|
156 |
+
* @param string $link The term link.
|
157 |
+
* @param PLL_Language $lang The current language.
|
158 |
+
* @param WP_Term $term The term object.
|
159 |
*/
|
160 |
return apply_filters( 'pll_term_link', $link, $lang, $term );
|
161 |
}
|
162 |
|
163 |
+
// In case someone calls get_term_link for the 'language' taxonomy.
|
164 |
if ( 'language' === $tax ) {
|
165 |
+
$lang = $this->model->get_language( $term->term_id );
|
166 |
+
return $this->links_model->home_url( $lang );
|
167 |
}
|
168 |
|
169 |
return $link;
|
include/filters-widgets-options.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Class PLL_Widgets_Filters
|
8 |
+
*
|
9 |
+
* @since 3.0
|
10 |
+
*
|
11 |
+
* Add new options to {@see https://developer.wordpress.org/reference/classes/wp_widget/ WP_Widget} and saves them.
|
12 |
+
*/
|
13 |
+
class PLL_Filters_Widgets_Options {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var PLL_Model
|
17 |
+
*/
|
18 |
+
public $model;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* PLL_Widgets_Filters constructor.
|
22 |
+
*
|
23 |
+
* @since 3.0 Moved actions from PLL_Admin_Filters.
|
24 |
+
*
|
25 |
+
* @param PLL_Base $polylang
|
26 |
+
* @return void
|
27 |
+
*/
|
28 |
+
public function __construct( $polylang ) {
|
29 |
+
$this->model = $polylang->model;
|
30 |
+
|
31 |
+
add_action( 'in_widget_form', array( $this, 'in_widget_form' ), 10, 3 );
|
32 |
+
add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ), 10, 4 );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Add the language filter field to the widgets options form.
|
37 |
+
*
|
38 |
+
* @since 3.0 Moved PLL_Admin_Filters
|
39 |
+
*
|
40 |
+
* @param WP_Widget $widget
|
41 |
+
* @param null $return
|
42 |
+
* @param array $instance
|
43 |
+
* @return void
|
44 |
+
*/
|
45 |
+
public function in_widget_form( $widget, $return, $instance ) {
|
46 |
+
$dropdown = new PLL_Walker_Dropdown();
|
47 |
+
|
48 |
+
$dropdown_html = $dropdown->walk(
|
49 |
+
array_merge(
|
50 |
+
array( (object) array('slug' => 0, 'name' => __( 'All languages', 'polylang' )) ),
|
51 |
+
$this->model->get_languages_list()
|
52 |
+
),
|
53 |
+
-1,
|
54 |
+
array(
|
55 |
+
'name' => $this->get_language_key( $widget ),
|
56 |
+
'class' => 'tags-input pll-lang-choice',
|
57 |
+
'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'],
|
58 |
+
)
|
59 |
+
);
|
60 |
+
|
61 |
+
printf(
|
62 |
+
'<p><label for="%1$s">%2$s %3$s</label></p>',
|
63 |
+
esc_attr( $this->get_language_key( $widget ) ),
|
64 |
+
esc_html__( 'The widget is displayed for:', 'polylang' ),
|
65 |
+
$dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Called when widget options are saved.
|
71 |
+
* Saves the language associated to the widget.
|
72 |
+
*
|
73 |
+
* @since 0.3
|
74 |
+
* @since 3.0 Moved from PLL_Admin_Filters
|
75 |
+
*
|
76 |
+
* @param array $instance The current Widget's options.
|
77 |
+
* @param array $new_instance The new Widget's options.
|
78 |
+
* @param array $old_instance Not used.
|
79 |
+
* @param WP_Widget $widget WP_Widget object.
|
80 |
+
* @return array Widget options.
|
81 |
+
*/
|
82 |
+
public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
|
83 |
+
$key = $this->get_language_key( $widget );
|
84 |
+
|
85 |
+
if ( ! empty( $new_instance[ $key ] ) && $lang = $this->model->get_language( $new_instance[ $key ] ) ) {
|
86 |
+
$instance['pll_lang'] = $lang->slug;
|
87 |
+
} else {
|
88 |
+
unset( $instance['pll_lang'] );
|
89 |
+
}
|
90 |
+
|
91 |
+
return $instance;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Returns the key used by Polylang to pass language data.
|
96 |
+
*
|
97 |
+
* @since 3.0
|
98 |
+
*
|
99 |
+
* @param WP_Widget $widget
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
protected function get_language_key( $widget ) {
|
103 |
+
return $widget->id . '_lang_choice';
|
104 |
+
}
|
105 |
+
}
|
include/filters.php
CHANGED
@@ -9,7 +9,31 @@
|
|
9 |
* @since 1.4
|
10 |
*/
|
11 |
class PLL_Filters {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor: setups filters
|
@@ -64,28 +88,30 @@ class PLL_Filters {
|
|
64 |
* Deletes the cache for multilingual sticky posts.
|
65 |
*
|
66 |
* @since 2.8.4
|
|
|
|
|
67 |
*/
|
68 |
public function delete_sticky_posts_cache() {
|
69 |
wp_cache_delete( 'sticky_posts', 'options' );
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
-
* Get the language to filter a comments query
|
74 |
*
|
75 |
* @since 2.0
|
76 |
*
|
77 |
-
* @param
|
78 |
-
* @return
|
79 |
*/
|
80 |
protected function get_comments_queried_language( $query ) {
|
81 |
-
// Don't filter comments if comment ids or post ids are specified
|
82 |
$plucked = wp_array_slice_assoc( $query->query_vars, array( 'comment__in', 'parent', 'post_id', 'post__in', 'post_parent' ) );
|
83 |
$fields = array_filter( $plucked );
|
84 |
if ( ! empty( $fields ) ) {
|
85 |
return false;
|
86 |
}
|
87 |
|
88 |
-
// Don't filter comments if a non translated post type is specified
|
89 |
if ( ! empty( $query->query_vars['post_type'] ) && ! $this->model->is_translated_post_type( $query->query_vars['post_type'] ) ) {
|
90 |
return false;
|
91 |
}
|
@@ -94,30 +120,32 @@ class PLL_Filters {
|
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
-
* Adds language dependent cache domain when querying comments
|
98 |
-
* Useful as the 'lang' parameter is not included in cache key by WordPress
|
99 |
-
* Needed since WP 4.6 as comments have been added to persistent cache. See #36906, #37419
|
100 |
*
|
101 |
* @since 2.0
|
102 |
*
|
103 |
-
* @param
|
|
|
104 |
*/
|
105 |
public function parse_comment_query( $query ) {
|
106 |
-
|
107 |
-
|
|
|
108 |
$query->query_vars['cache_domain'] = empty( $query->query_vars['cache_domain'] ) ? 'pll' . $key : $query->query_vars['cache_domain'] . $key;
|
109 |
}
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
-
* Filters the comments according to the current language
|
114 |
-
* Used by the recent comments widget and admin language filter
|
115 |
*
|
116 |
* @since 0.2
|
117 |
*
|
118 |
-
* @param
|
119 |
-
* @param
|
120 |
-
* @return
|
121 |
*/
|
122 |
public function comments_clauses( $clauses, $query ) {
|
123 |
global $wpdb;
|
@@ -125,7 +153,7 @@ class PLL_Filters {
|
|
125 |
$lang = $this->get_comments_queried_language( $query );
|
126 |
|
127 |
if ( ! empty( $lang ) ) {
|
128 |
-
// If this clause is not already added by WP
|
129 |
if ( ! strpos( $clauses['join'], '.ID' ) ) {
|
130 |
$clauses['join'] .= " JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
|
131 |
}
|
@@ -137,13 +165,13 @@ class PLL_Filters {
|
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
-
* Filters get_pages per language
|
141 |
*
|
142 |
* @since 1.4
|
143 |
*
|
144 |
-
* @param
|
145 |
-
* @param array
|
146 |
-
* @return
|
147 |
*/
|
148 |
public function get_pages( $pages, $args ) {
|
149 |
if ( isset( $args['lang'] ) && empty( $args['lang'] ) ) {
|
@@ -206,34 +234,34 @@ class PLL_Filters {
|
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
-
* Modifies the sql request for get_adjacent_post to filter by the current language
|
210 |
*
|
211 |
* @since 0.1
|
212 |
*
|
213 |
* @param string $sql The JOIN clause in the SQL.
|
214 |
* @param bool $in_same_term Whether post should be in a same taxonomy term.
|
215 |
-
* @param
|
216 |
* @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true.
|
217 |
* @param WP_Post $post WP_Post object.
|
218 |
-
* @return string
|
219 |
*/
|
220 |
-
public function posts_join( $sql, $in_same_term, $excluded_terms, $taxonomy
|
221 |
return $this->model->is_translated_post_type( $post->post_type ) && ! empty( $this->curlang ) ? $sql . $this->model->post->join_clause( 'p' ) : $sql;
|
222 |
}
|
223 |
|
224 |
/**
|
225 |
-
* Modifies the sql request for wp_get_archives and get_adjacent_post to filter by the current language
|
226 |
*
|
227 |
* @since 0.1
|
228 |
*
|
229 |
* @param string $sql The WHERE clause in the SQL.
|
230 |
* @param bool $in_same_term Whether post should be in a same taxonomy term.
|
231 |
-
* @param
|
232 |
* @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true.
|
233 |
* @param WP_Post $post WP_Post object.
|
234 |
-
* @return string
|
235 |
*/
|
236 |
-
public function posts_where( $sql, $in_same_term, $excluded_terms, $taxonomy
|
237 |
return $this->model->is_translated_post_type( $post->post_type ) && ! empty( $this->curlang ) ? $sql . $this->model->post->where_clause( $this->curlang ) : $sql;
|
238 |
}
|
239 |
|
@@ -278,13 +306,13 @@ class PLL_Filters {
|
|
278 |
}
|
279 |
|
280 |
/**
|
281 |
-
* Translates the site title in emails sent to the user (change email, reset password)
|
282 |
-
* It is necessary to filter the email because WP evaluates the site title before calling switch_to_locale()
|
283 |
*
|
284 |
* @since 2.1.3
|
285 |
*
|
286 |
-
* @param
|
287 |
-
* @return
|
288 |
*/
|
289 |
public function translate_user_email( $email ) {
|
290 |
$blog_name = wp_specialchars_decode( pll__( get_option( 'blogname' ) ), ENT_QUOTES );
|
@@ -333,7 +361,7 @@ class PLL_Filters {
|
|
333 |
* @since 2.3.6
|
334 |
*
|
335 |
* @param array $exporters Personal data exporters
|
336 |
-
* @
|
337 |
*/
|
338 |
public function register_personal_data_exporter( $exporters ) {
|
339 |
$exporters[] = array(
|
9 |
* @since 1.4
|
10 |
*/
|
11 |
class PLL_Filters {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
public $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Instance of a child class of PLL_Links_Model.
|
26 |
+
*
|
27 |
+
* @var PLL_Links_Model
|
28 |
+
*/
|
29 |
+
public $links_model;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Current language.
|
33 |
+
*
|
34 |
+
* @var PLL_Language
|
35 |
+
*/
|
36 |
+
public $curlang;
|
37 |
|
38 |
/**
|
39 |
* Constructor: setups filters
|
88 |
* Deletes the cache for multilingual sticky posts.
|
89 |
*
|
90 |
* @since 2.8.4
|
91 |
+
*
|
92 |
+
* @return void
|
93 |
*/
|
94 |
public function delete_sticky_posts_cache() {
|
95 |
wp_cache_delete( 'sticky_posts', 'options' );
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
+
* Get the language to filter a comments query.
|
100 |
*
|
101 |
* @since 2.0
|
102 |
*
|
103 |
+
* @param WP_Comment_Query $query WP_Comment_Query object.
|
104 |
+
* @return PLL_Language|false The language to use in the filter, false otherwise.
|
105 |
*/
|
106 |
protected function get_comments_queried_language( $query ) {
|
107 |
+
// Don't filter comments if comment ids or post ids are specified.
|
108 |
$plucked = wp_array_slice_assoc( $query->query_vars, array( 'comment__in', 'parent', 'post_id', 'post__in', 'post_parent' ) );
|
109 |
$fields = array_filter( $plucked );
|
110 |
if ( ! empty( $fields ) ) {
|
111 |
return false;
|
112 |
}
|
113 |
|
114 |
+
// Don't filter comments if a non translated post type is specified.
|
115 |
if ( ! empty( $query->query_vars['post_type'] ) && ! $this->model->is_translated_post_type( $query->query_vars['post_type'] ) ) {
|
116 |
return false;
|
117 |
}
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Adds a language dependent cache domain when querying comments.
|
124 |
+
* Useful as the 'lang' parameter is not included in cache key by WordPress.
|
125 |
+
* Needed since WP 4.6 as comments have been added to persistent cache. See #36906, #37419.
|
126 |
*
|
127 |
* @since 2.0
|
128 |
*
|
129 |
+
* @param WP_Comment_Query $query WP_Comment_Query object.
|
130 |
+
* @return void
|
131 |
*/
|
132 |
public function parse_comment_query( $query ) {
|
133 |
+
$lang = $this->get_comments_queried_language( $query );
|
134 |
+
if ( $lang ) {
|
135 |
+
$key = '_' . $lang->slug;
|
136 |
$query->query_vars['cache_domain'] = empty( $query->query_vars['cache_domain'] ) ? 'pll' . $key : $query->query_vars['cache_domain'] . $key;
|
137 |
}
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* Filters the comments according to the current language.
|
142 |
+
* Used by the recent comments widget and admin language filter.
|
143 |
*
|
144 |
* @since 0.2
|
145 |
*
|
146 |
+
* @param string[] $clauses SQL clauses.
|
147 |
+
* @param WP_Comment_Query $query WP_Comment_Query object.
|
148 |
+
* @return string[] Modified $clauses.
|
149 |
*/
|
150 |
public function comments_clauses( $clauses, $query ) {
|
151 |
global $wpdb;
|
153 |
$lang = $this->get_comments_queried_language( $query );
|
154 |
|
155 |
if ( ! empty( $lang ) ) {
|
156 |
+
// If this clause is not already added by WP.
|
157 |
if ( ! strpos( $clauses['join'], '.ID' ) ) {
|
158 |
$clauses['join'] .= " JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
|
159 |
}
|
165 |
}
|
166 |
|
167 |
/**
|
168 |
+
* Filters get_pages() per language.
|
169 |
*
|
170 |
* @since 1.4
|
171 |
*
|
172 |
+
* @param WP_Post[] $pages An array of pages already queried.
|
173 |
+
* @param array $args Array of get_pages() arguments.
|
174 |
+
* @return WP_Post[] Modified list of pages.
|
175 |
*/
|
176 |
public function get_pages( $pages, $args ) {
|
177 |
if ( isset( $args['lang'] ) && empty( $args['lang'] ) ) {
|
234 |
}
|
235 |
|
236 |
/**
|
237 |
+
* Modifies the sql request for get_adjacent_post to filter by the current language.
|
238 |
*
|
239 |
* @since 0.1
|
240 |
*
|
241 |
* @param string $sql The JOIN clause in the SQL.
|
242 |
* @param bool $in_same_term Whether post should be in a same taxonomy term.
|
243 |
+
* @param int[] $excluded_terms Array of excluded term IDs.
|
244 |
* @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true.
|
245 |
* @param WP_Post $post WP_Post object.
|
246 |
+
* @return string Modified JOIN clause.
|
247 |
*/
|
248 |
+
public function posts_join( $sql, $in_same_term, $excluded_terms, $taxonomy, $post ) {
|
249 |
return $this->model->is_translated_post_type( $post->post_type ) && ! empty( $this->curlang ) ? $sql . $this->model->post->join_clause( 'p' ) : $sql;
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
+
* Modifies the sql request for wp_get_archives and get_adjacent_post to filter by the current language.
|
254 |
*
|
255 |
* @since 0.1
|
256 |
*
|
257 |
* @param string $sql The WHERE clause in the SQL.
|
258 |
* @param bool $in_same_term Whether post should be in a same taxonomy term.
|
259 |
+
* @param int[] $excluded_terms Array of excluded term IDs.
|
260 |
* @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true.
|
261 |
* @param WP_Post $post WP_Post object.
|
262 |
+
* @return string Modified WHERE clause.
|
263 |
*/
|
264 |
+
public function posts_where( $sql, $in_same_term, $excluded_terms, $taxonomy, $post ) {
|
265 |
return $this->model->is_translated_post_type( $post->post_type ) && ! empty( $this->curlang ) ? $sql . $this->model->post->where_clause( $this->curlang ) : $sql;
|
266 |
}
|
267 |
|
306 |
}
|
307 |
|
308 |
/**
|
309 |
+
* Translates the site title in emails sent to the user (change email, reset password).
|
310 |
+
* It is necessary to filter the email because WP evaluates the site title before calling switch_to_locale().
|
311 |
*
|
312 |
* @since 2.1.3
|
313 |
*
|
314 |
+
* @param string[] $email Email contents.
|
315 |
+
* @return string[] Translated email contents.
|
316 |
*/
|
317 |
public function translate_user_email( $email ) {
|
318 |
$blog_name = wp_specialchars_decode( pll__( get_option( 'blogname' ) ), ENT_QUOTES );
|
361 |
* @since 2.3.6
|
362 |
*
|
363 |
* @param array $exporters Personal data exporters
|
364 |
+
* @return array
|
365 |
*/
|
366 |
public function register_personal_data_exporter( $exporters ) {
|
367 |
$exporters[] = array(
|
include/functions.php
CHANGED
@@ -47,7 +47,7 @@ if ( ! function_exists( 'wpcom_vip_get_page_by_path' ) ) {
|
|
47 |
*
|
48 |
* @since 2.3.8
|
49 |
*
|
50 |
-
* return bool True if the cache compatibility must be loaded
|
51 |
*/
|
52 |
function pll_is_cache_active() {
|
53 |
/**
|
@@ -95,7 +95,7 @@ function pll_get_requested_url() {
|
|
95 |
*
|
96 |
* @since 2.6.0
|
97 |
*
|
98 |
-
* return bool True to use the block editor plugin.
|
99 |
*/
|
100 |
function pll_use_block_editor_plugin() {
|
101 |
/**
|
47 |
*
|
48 |
* @since 2.3.8
|
49 |
*
|
50 |
+
* @return bool True if the cache compatibility must be loaded
|
51 |
*/
|
52 |
function pll_is_cache_active() {
|
53 |
/**
|
95 |
*
|
96 |
* @since 2.6.0
|
97 |
*
|
98 |
+
* @return bool True to use the block editor plugin.
|
99 |
*/
|
100 |
function pll_use_block_editor_plugin() {
|
101 |
/**
|
include/language.php
CHANGED
@@ -4,84 +4,215 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* A language object is made of two terms in 'language' and 'term_language' taxonomies
|
8 |
-
*
|
9 |
-
*
|
10 |
-
* Properties:
|
11 |
-
* term_id => id of term in 'language' taxonomy
|
12 |
-
* name => language name. Ex: English
|
13 |
-
* slug => language code used in url. Ex: en
|
14 |
-
* term_group => order of the language when displayed in a list of languages
|
15 |
-
* term_taxonomy_id => term taxonomy id in 'language' taxonomy
|
16 |
-
* taxonomy => 'language'
|
17 |
-
* description => language locale for backward compatibility
|
18 |
-
* parent => 0 / not used
|
19 |
-
* count => number of posts and pages in that language
|
20 |
-
* tl_term_id => id of the term in 'term_language' taxonomy
|
21 |
-
* tl_term_taxonomy_id => term taxonomy id in 'term_language' taxonomy
|
22 |
-
* tl_count => number of terms in that language ( not used by Polylang )
|
23 |
-
* locale => WordPress language locale. Ex: en_US
|
24 |
-
* is_rtl => 1 if the language is rtl
|
25 |
-
* w3c => W3C locale
|
26 |
-
* flag_code => code of the flag
|
27 |
-
* flag_url => url of the flag
|
28 |
-
* flag => html img of the flag
|
29 |
-
* custom_flag_url => url of the custom flag if exists, internal use only, moves to flag_url on frontend
|
30 |
-
* custom_flag => html img of the custom flag if exists, internal use only, moves to flag on frontend
|
31 |
-
* home_url => home url in this language
|
32 |
-
* search_url => home url to use in search forms
|
33 |
-
* host => host of this language
|
34 |
-
* mo_id => id of the post storing strings translations
|
35 |
-
* page_on_front => id of the page on front in this language ( set from pll_languages_list filter )
|
36 |
-
* page_for_posts => id of the page for posts in this language ( set from pll_languages_list filter )
|
37 |
*
|
38 |
* @since 1.2
|
39 |
*/
|
40 |
class PLL_Language {
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
public $
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
/**
|
51 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
*
|
53 |
* @since 1.2
|
54 |
*
|
55 |
-
* @param
|
56 |
-
* @param
|
57 |
*/
|
58 |
public function __construct( $language, $term_language = null ) {
|
59 |
-
// Build the object from all properties stored as an array
|
60 |
-
if (
|
61 |
foreach ( $language as $prop => $value ) {
|
62 |
$this->$prop = $value;
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
// Build the object from
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
71 |
|
72 |
$this->tl_term_id = (int) $term_language->term_id;
|
73 |
$this->tl_term_taxonomy_id = (int) $term_language->term_taxonomy_id;
|
74 |
$this->tl_count = (int) $term_language->count;
|
75 |
|
76 |
-
// The description field can contain any property
|
77 |
-
// Backward compatibility for is_rtl
|
78 |
$description = maybe_unserialize( $language->description );
|
79 |
foreach ( $description as $prop => $value ) {
|
80 |
'rtl' == $prop ? $this->is_rtl = $value : $this->$prop = $value;
|
81 |
}
|
82 |
|
83 |
-
$this->description = &$this->locale; // Backward compatibility with Polylang < 1.2
|
84 |
-
|
85 |
$this->mo_id = PLL_MO::get_id( $this );
|
86 |
|
87 |
$languages = include POLYLANG_DIR . '/settings/languages.php';
|
@@ -93,64 +224,72 @@ class PLL_Language {
|
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
-
* Get the flag informations
|
97 |
-
* 'url' => Flag url
|
98 |
-
* 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
|
99 |
-
* 'width' => Optional, flag width in pixels
|
100 |
-
* 'height' => Optional, flag height in pixels
|
101 |
*
|
102 |
* @since 2.6
|
103 |
*
|
104 |
* @param string $code Flag code.
|
105 |
-
* @return array
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
*/
|
107 |
public static function get_flag_informations( $code ) {
|
108 |
$flag = array( 'url' => '' );
|
109 |
|
110 |
-
// Polylang builtin flags
|
111 |
if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
|
112 |
-
$flag['url'] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
-
*
|
117 |
-
* 'url' => Flag url
|
118 |
-
* 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
|
119 |
-
* 'width' => Optional, flag width in pixels
|
120 |
-
* 'height' => Optional, flag height in pixels
|
121 |
*
|
122 |
* @since 2.4
|
123 |
*
|
124 |
-
* @param array $flag
|
125 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
*/
|
127 |
$flag = apply_filters( 'pll_flag', $flag, $code );
|
128 |
|
|
|
|
|
129 |
if ( empty( $flag['src'] ) ) {
|
130 |
-
|
131 |
-
if ( isset( $_url ) && $flag['url'] === $_url && ( ! defined( 'PLL_ENCODED_FLAGS' ) || PLL_ENCODED_FLAGS ) ) {
|
132 |
-
list( $flag['width'], $flag['height'] ) = getimagesize( POLYLANG_DIR . $file );
|
133 |
-
$file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
134 |
-
$flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
135 |
-
} else {
|
136 |
-
$flag['src'] = esc_url( set_url_scheme( $flag['url'], 'relative' ) );
|
137 |
-
}
|
138 |
}
|
139 |
|
140 |
-
$flag['url'] = esc_url_raw( $flag['url'] );
|
141 |
-
|
142 |
return $flag;
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
-
* Sets flag_url and flag properties
|
147 |
*
|
148 |
* @since 1.2
|
|
|
|
|
149 |
*/
|
150 |
public function set_flag() {
|
151 |
$flags = array( 'flag' => self::get_flag_informations( $this->flag_code ) );
|
152 |
|
153 |
-
// Custom flags
|
154 |
$directories = array(
|
155 |
PLL_LOCAL_DIR,
|
156 |
get_stylesheet_directory() . '/polylang',
|
@@ -165,16 +304,19 @@ class PLL_Language {
|
|
165 |
}
|
166 |
|
167 |
/**
|
168 |
-
*
|
169 |
-
* 'url' => Flag url
|
170 |
-
* 'src' => Optional, src attribute value if different of the url, for example if base64 encoded
|
171 |
-
* 'width' => Optional, flag width in pixels
|
172 |
-
* 'height' => Optional, flag height in pixels
|
173 |
*
|
174 |
-
* @
|
|
|
175 |
*
|
176 |
-
*
|
177 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
*/
|
179 |
$flags['custom_flag'] = apply_filters( 'pll_custom_flag', empty( $flags['custom_flag'] ) ? null : $flags['custom_flag'], $this->flag_code );
|
180 |
|
@@ -189,14 +331,14 @@ class PLL_Language {
|
|
189 |
}
|
190 |
|
191 |
/**
|
192 |
-
*
|
193 |
-
* Defaults to the language name
|
194 |
*
|
195 |
* @since 0.7
|
196 |
*
|
197 |
-
* @param string $title
|
198 |
-
* @param string $slug
|
199 |
-
* @param string $locale
|
200 |
*/
|
201 |
$title = apply_filters( 'pll_flag_title', $this->name, $this->slug, $this->locale );
|
202 |
|
@@ -204,12 +346,12 @@ class PLL_Language {
|
|
204 |
$this->{$key . '_url'} = empty( $flag['url'] ) ? '' : $flag['url'];
|
205 |
|
206 |
/**
|
207 |
-
*
|
208 |
*
|
209 |
* @since 1.0.2
|
210 |
*
|
211 |
-
* @param string $flag
|
212 |
-
* @param string $slug
|
213 |
*/
|
214 |
$this->{$key} = apply_filters(
|
215 |
'pll_get_flag',
|
@@ -220,20 +362,20 @@ class PLL_Language {
|
|
220 |
}
|
221 |
|
222 |
/**
|
223 |
-
* Get HTML code for flag
|
224 |
*
|
225 |
* @since 2.7
|
226 |
*
|
227 |
-
* @param array $flag
|
228 |
-
* @param string $title
|
229 |
-
* @param string $alt
|
|
|
230 |
*/
|
231 |
public static function get_flag_html( $flag, $title = '', $alt = '' ) {
|
232 |
if ( empty( $flag['src'] ) ) {
|
233 |
return '';
|
234 |
}
|
235 |
|
236 |
-
$title_attr = empty( $title ) ? '' : sprintf( ' title="%s"', esc_attr( $title ) );
|
237 |
$alt_attr = empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) );
|
238 |
$width_attr = empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] );
|
239 |
$height_attr = empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] );
|
@@ -252,9 +394,8 @@ class PLL_Language {
|
|
252 |
}
|
253 |
|
254 |
return sprintf(
|
255 |
-
'<img src="%s"%s%s%s%s
|
256 |
$flag['src'],
|
257 |
-
$title_attr,
|
258 |
$alt_attr,
|
259 |
$width_attr,
|
260 |
$height_attr,
|
@@ -266,6 +407,8 @@ class PLL_Language {
|
|
266 |
* Returns the html of the custom flag if any, or the default flag otherwise.
|
267 |
*
|
268 |
* @since 2.8
|
|
|
|
|
269 |
*/
|
270 |
public function get_display_flag() {
|
271 |
return empty( $this->custom_flag ) ? $this->flag : $this->custom_flag;
|
@@ -275,28 +418,33 @@ class PLL_Language {
|
|
275 |
* Returns the url of the custom flag if any, or the default flag otherwise.
|
276 |
*
|
277 |
* @since 2.8
|
|
|
|
|
278 |
*/
|
279 |
public function get_display_flag_url() {
|
280 |
return empty( $this->custom_flag_url ) ? $this->flag_url : $this->custom_flag_url;
|
281 |
}
|
282 |
|
283 |
/**
|
284 |
-
* Updates post and term count
|
285 |
*
|
286 |
* @since 1.2
|
|
|
|
|
287 |
*/
|
288 |
public function update_count() {
|
289 |
-
wp_update_term_count( $this->term_taxonomy_id, 'language' ); //
|
290 |
-
wp_update_term_count( $this->tl_term_taxonomy_id, 'term_language' ); //
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
-
* Set home_url and search_url properties
|
295 |
*
|
296 |
* @since 1.3
|
297 |
*
|
298 |
-
* @param string $search_url
|
299 |
-
* @param string $home_url
|
|
|
300 |
*/
|
301 |
public function set_home_url( $search_url, $home_url ) {
|
302 |
$this->search_url = $search_url;
|
@@ -304,11 +452,13 @@ class PLL_Language {
|
|
304 |
}
|
305 |
|
306 |
/**
|
307 |
-
* Sets the scheme of the home url and the flag urls
|
308 |
*
|
309 |
* This can't be cached across pages.
|
310 |
*
|
311 |
* @since 2.8
|
|
|
|
|
312 |
*/
|
313 |
public function set_url_scheme() {
|
314 |
$this->home_url = set_url_scheme( $this->home_url );
|
@@ -322,12 +472,12 @@ class PLL_Language {
|
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
-
* Returns the language locale
|
326 |
-
* Converts WP locales to W3C valid locales for display
|
327 |
*
|
328 |
* @since 1.8
|
329 |
*
|
330 |
-
* @param string $filter
|
331 |
* @return string
|
332 |
*/
|
333 |
public function get_locale( $filter = 'raw' ) {
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* A language object is made of two terms in 'language' and 'term_language' taxonomies.
|
8 |
+
* Manipulating only one object per language instead of two terms should make things easier.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
class PLL_Language {
|
13 |
+
/**
|
14 |
+
* Id of the term in 'language' taxonomy.
|
15 |
+
*
|
16 |
+
* @var int
|
17 |
+
*/
|
18 |
+
public $term_id;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Language name. Ex: English.
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $name;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Language code used in url. Ex: en.
|
29 |
+
*
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $slug;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Order of the language when displayed in a list of languages.
|
36 |
+
*
|
37 |
+
* @var int
|
38 |
+
*/
|
39 |
+
public $term_group;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Term taxonomy id in 'language' taxonomy.
|
43 |
+
*
|
44 |
+
* @var int
|
45 |
+
*/
|
46 |
+
public $term_taxonomy_id;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Number of posts and pages in that language.
|
50 |
+
*
|
51 |
+
* @var int
|
52 |
+
*/
|
53 |
+
public $count;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Id of the term in 'term_language' taxonomy.
|
57 |
+
*
|
58 |
+
* @var int
|
59 |
+
*/
|
60 |
+
public $tl_term_id;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Term taxonomy id in 'term_language' taxonomy.
|
64 |
+
*
|
65 |
+
* @var int
|
66 |
+
*/
|
67 |
+
public $tl_term_taxonomy_id;
|
68 |
|
69 |
/**
|
70 |
+
* Number of terms in that language.
|
71 |
+
*
|
72 |
+
* @var int
|
73 |
+
*/
|
74 |
+
public $tl_count;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* WordPress language locale. Ex: en_US.
|
78 |
+
*
|
79 |
+
* @var string
|
80 |
+
*/
|
81 |
+
public $locale;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* 1 if the language is rtl, 0 otherwise.
|
85 |
+
*
|
86 |
+
* @var int
|
87 |
+
*/
|
88 |
+
public $is_rtl;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* W3C locale.
|
92 |
+
*
|
93 |
+
* @var string.
|
94 |
+
*/
|
95 |
+
public $w3c;
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Facebook locale.
|
99 |
+
*
|
100 |
+
* @var string.
|
101 |
+
*/
|
102 |
+
public $facebook;
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Home url in this language.
|
106 |
+
*
|
107 |
+
* @var string
|
108 |
+
*/
|
109 |
+
public $home_url;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Home url to use in search forms.
|
113 |
+
*
|
114 |
+
* @var string
|
115 |
+
*/
|
116 |
+
public $search_url;
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Host corresponding to this language.
|
120 |
+
*
|
121 |
+
* @var string
|
122 |
+
*/
|
123 |
+
public $host;
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Id of the post storing strings translations.
|
127 |
+
*
|
128 |
+
* @var int
|
129 |
+
*/
|
130 |
+
public $mo_id;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Id of the page on front in this language ( set from pll_languages_list filter ).
|
134 |
+
*
|
135 |
+
* @var int
|
136 |
+
*/
|
137 |
+
public $page_on_front;
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Id of the page for posts in this language ( set from pll_languages_list filter ).
|
141 |
+
*
|
142 |
+
* @var int
|
143 |
+
*/
|
144 |
+
public $page_for_posts;
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Code of the flag.
|
148 |
+
*
|
149 |
+
* @var string
|
150 |
+
*/
|
151 |
+
public $flag_code;
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Url of the flag.
|
155 |
+
*
|
156 |
+
* @var string
|
157 |
+
*/
|
158 |
+
public $flag_url;
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Html markup of the flag.
|
162 |
+
*
|
163 |
+
* @var string
|
164 |
+
*/
|
165 |
+
public $flag;
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Url of the custom flag if it exists.
|
169 |
+
*
|
170 |
+
* @var string
|
171 |
+
*/
|
172 |
+
protected $custom_flag_url;
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Html markup of the custom flag if it exists.
|
176 |
+
*
|
177 |
+
* @var string
|
178 |
+
*/
|
179 |
+
protected $custom_flag;
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Constructor: builds a language object given its two corresponding terms in 'language' and 'term_language' taxonomies.
|
183 |
*
|
184 |
* @since 1.2
|
185 |
*
|
186 |
+
* @param WP_Term|array $language Term in 'language' taxonomy or language object properties stored as an array.
|
187 |
+
* @param WP_Term $term_language Corresponding 'term_language' term.
|
188 |
*/
|
189 |
public function __construct( $language, $term_language = null ) {
|
190 |
+
// Build the object from all properties stored as an array.
|
191 |
+
if ( is_array( $language ) ) {
|
192 |
foreach ( $language as $prop => $value ) {
|
193 |
$this->$prop = $value;
|
194 |
}
|
195 |
}
|
196 |
|
197 |
+
// Build the object from taxonomy terms.
|
198 |
+
elseif ( ! empty( $term_language ) ) {
|
199 |
+
$this->term_id = (int) $language->term_id;
|
200 |
+
$this->name = $language->name;
|
201 |
+
$this->slug = $language->slug;
|
202 |
+
$this->term_group = (int) $language->term_group;
|
203 |
+
$this->term_taxonomy_id = (int) $language->term_taxonomy_id;
|
204 |
+
$this->count = (int) $language->count;
|
205 |
|
206 |
$this->tl_term_id = (int) $term_language->term_id;
|
207 |
$this->tl_term_taxonomy_id = (int) $term_language->term_taxonomy_id;
|
208 |
$this->tl_count = (int) $term_language->count;
|
209 |
|
210 |
+
// The description field can contain any property.
|
|
|
211 |
$description = maybe_unserialize( $language->description );
|
212 |
foreach ( $description as $prop => $value ) {
|
213 |
'rtl' == $prop ? $this->is_rtl = $value : $this->$prop = $value;
|
214 |
}
|
215 |
|
|
|
|
|
216 |
$this->mo_id = PLL_MO::get_id( $this );
|
217 |
|
218 |
$languages = include POLYLANG_DIR . '/settings/languages.php';
|
224 |
}
|
225 |
|
226 |
/**
|
227 |
+
* Get the flag informations:
|
|
|
|
|
|
|
|
|
228 |
*
|
229 |
* @since 2.6
|
230 |
*
|
231 |
* @param string $code Flag code.
|
232 |
+
* @return array {
|
233 |
+
* Flag informations.
|
234 |
+
*
|
235 |
+
* @type string $url Flag url.
|
236 |
+
* @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
|
237 |
+
* @type int $width Optional, flag width in pixels.
|
238 |
+
* @type int $height Optional, flag height in pixels.
|
239 |
+
* }
|
240 |
*/
|
241 |
public static function get_flag_informations( $code ) {
|
242 |
$flag = array( 'url' => '' );
|
243 |
|
244 |
+
// Polylang builtin flags.
|
245 |
if ( ! empty( $code ) && file_exists( POLYLANG_DIR . ( $file = '/flags/' . $code . '.png' ) ) ) {
|
246 |
+
$flag['url'] = plugins_url( $file, POLYLANG_FILE );
|
247 |
+
|
248 |
+
// If base64 encoded flags are preferred.
|
249 |
+
if ( ! defined( 'PLL_ENCODED_FLAGS' ) || PLL_ENCODED_FLAGS ) {
|
250 |
+
list( $flag['width'], $flag['height'] ) = getimagesize( POLYLANG_DIR . $file );
|
251 |
+
$file_contents = file_get_contents( POLYLANG_DIR . $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
252 |
+
$flag['src'] = 'data:image/png;base64,' . base64_encode( $file_contents ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
253 |
+
}
|
254 |
}
|
255 |
|
256 |
/**
|
257 |
+
* Filters flag informations:
|
|
|
|
|
|
|
|
|
258 |
*
|
259 |
* @since 2.4
|
260 |
*
|
261 |
+
* @param array $flag {
|
262 |
+
* Information about the flag.
|
263 |
+
*
|
264 |
+
* @type string $url Flag url.
|
265 |
+
* @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
|
266 |
+
* @type int $width Optional, flag width in pixels.
|
267 |
+
* @type int $height Optional, flag height in pixels.
|
268 |
+
* }
|
269 |
+
* @param string $code Flag code.
|
270 |
*/
|
271 |
$flag = apply_filters( 'pll_flag', $flag, $code );
|
272 |
|
273 |
+
$flag['url'] = esc_url_raw( $flag['url'] );
|
274 |
+
|
275 |
if ( empty( $flag['src'] ) ) {
|
276 |
+
$flag['src'] = esc_url( set_url_scheme( $flag['url'], 'relative' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
}
|
278 |
|
|
|
|
|
279 |
return $flag;
|
280 |
}
|
281 |
|
282 |
/**
|
283 |
+
* Sets flag_url and flag properties.
|
284 |
*
|
285 |
* @since 1.2
|
286 |
+
*
|
287 |
+
* @return void
|
288 |
*/
|
289 |
public function set_flag() {
|
290 |
$flags = array( 'flag' => self::get_flag_informations( $this->flag_code ) );
|
291 |
|
292 |
+
// Custom flags?
|
293 |
$directories = array(
|
294 |
PLL_LOCAL_DIR,
|
295 |
get_stylesheet_directory() . '/polylang',
|
304 |
}
|
305 |
|
306 |
/**
|
307 |
+
* Filters the custom flag informations.
|
|
|
|
|
|
|
|
|
308 |
*
|
309 |
+
* @param array $flag {
|
310 |
+
* Information about the custom flag.
|
311 |
*
|
312 |
+
* @type string $url Flag url.
|
313 |
+
* @type string $src Optional, src attribute value if different of the url, for example if base64 encoded.
|
314 |
+
* @type int $width Optional, flag width in pixels.
|
315 |
+
* @type int $height Optional, flag height in pixels.
|
316 |
+
* }
|
317 |
+
* @param string $code Flag code.
|
318 |
+
*
|
319 |
+
* @since 2.4
|
320 |
*/
|
321 |
$flags['custom_flag'] = apply_filters( 'pll_custom_flag', empty( $flags['custom_flag'] ) ? null : $flags['custom_flag'], $this->flag_code );
|
322 |
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
+
* Filters the flag title attribute.
|
335 |
+
* Defaults to the language name.
|
336 |
*
|
337 |
* @since 0.7
|
338 |
*
|
339 |
+
* @param string $title The flag title attribute.
|
340 |
+
* @param string $slug The language code.
|
341 |
+
* @param string $locale The language locale.
|
342 |
*/
|
343 |
$title = apply_filters( 'pll_flag_title', $this->name, $this->slug, $this->locale );
|
344 |
|
346 |
$this->{$key . '_url'} = empty( $flag['url'] ) ? '' : $flag['url'];
|
347 |
|
348 |
/**
|
349 |
+
* Filters the html markup of a flag.
|
350 |
*
|
351 |
* @since 1.0.2
|
352 |
*
|
353 |
+
* @param string $flag Html markup of the flag or empty string.
|
354 |
+
* @param string $slug Language code.
|
355 |
*/
|
356 |
$this->{$key} = apply_filters(
|
357 |
'pll_get_flag',
|
362 |
}
|
363 |
|
364 |
/**
|
365 |
+
* Get HTML code for flag.
|
366 |
*
|
367 |
* @since 2.7
|
368 |
*
|
369 |
+
* @param array $flag Flag properties: src, width and height.
|
370 |
+
* @param string $title Optional title attribute.
|
371 |
+
* @param string $alt Optional alt attribute.
|
372 |
+
* @return string
|
373 |
*/
|
374 |
public static function get_flag_html( $flag, $title = '', $alt = '' ) {
|
375 |
if ( empty( $flag['src'] ) ) {
|
376 |
return '';
|
377 |
}
|
378 |
|
|
|
379 |
$alt_attr = empty( $alt ) ? '' : sprintf( ' alt="%s"', esc_attr( $alt ) );
|
380 |
$width_attr = empty( $flag['width'] ) ? '' : sprintf( ' width="%s"', (int) $flag['width'] );
|
381 |
$height_attr = empty( $flag['height'] ) ? '' : sprintf( ' height="%s"', (int) $flag['height'] );
|
394 |
}
|
395 |
|
396 |
return sprintf(
|
397 |
+
'<img src="%s"%s%s%s%s />',
|
398 |
$flag['src'],
|
|
|
399 |
$alt_attr,
|
400 |
$width_attr,
|
401 |
$height_attr,
|
407 |
* Returns the html of the custom flag if any, or the default flag otherwise.
|
408 |
*
|
409 |
* @since 2.8
|
410 |
+
*
|
411 |
+
* @return string
|
412 |
*/
|
413 |
public function get_display_flag() {
|
414 |
return empty( $this->custom_flag ) ? $this->flag : $this->custom_flag;
|
418 |
* Returns the url of the custom flag if any, or the default flag otherwise.
|
419 |
*
|
420 |
* @since 2.8
|
421 |
+
*
|
422 |
+
* @return string
|
423 |
*/
|
424 |
public function get_display_flag_url() {
|
425 |
return empty( $this->custom_flag_url ) ? $this->flag_url : $this->custom_flag_url;
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
+
* Updates post and term count.
|
430 |
*
|
431 |
* @since 1.2
|
432 |
+
*
|
433 |
+
* @return void
|
434 |
*/
|
435 |
public function update_count() {
|
436 |
+
wp_update_term_count( $this->term_taxonomy_id, 'language' ); // Posts count.
|
437 |
+
wp_update_term_count( $this->tl_term_taxonomy_id, 'term_language' ); // Terms count.
|
438 |
}
|
439 |
|
440 |
/**
|
441 |
+
* Set home_url and search_url properties.
|
442 |
*
|
443 |
* @since 1.3
|
444 |
*
|
445 |
+
* @param string $search_url Home url to use in search forms.
|
446 |
+
* @param string $home_url Home url.
|
447 |
+
* @return void
|
448 |
*/
|
449 |
public function set_home_url( $search_url, $home_url ) {
|
450 |
$this->search_url = $search_url;
|
452 |
}
|
453 |
|
454 |
/**
|
455 |
+
* Sets the scheme of the home url and the flag urls.
|
456 |
*
|
457 |
* This can't be cached across pages.
|
458 |
*
|
459 |
* @since 2.8
|
460 |
+
*
|
461 |
+
* @return void
|
462 |
*/
|
463 |
public function set_url_scheme() {
|
464 |
$this->home_url = set_url_scheme( $this->home_url );
|
472 |
}
|
473 |
|
474 |
/**
|
475 |
+
* Returns the language locale.
|
476 |
+
* Converts WP locales to W3C valid locales for display.
|
477 |
*
|
478 |
* @since 1.8
|
479 |
*
|
480 |
+
* @param string $filter Either 'display' or 'raw', defaults to raw.
|
481 |
* @return string
|
482 |
*/
|
483 |
public function get_locale( $filter = 'raw' ) {
|
include/license.php
CHANGED
@@ -9,8 +9,60 @@
|
|
9 |
* @since 1.9
|
10 |
*/
|
11 |
class PLL_License {
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
private $api_url = 'https://polylang.pro';
|
15 |
|
16 |
/**
|
@@ -57,6 +109,8 @@ class PLL_License {
|
|
57 |
* Auto updater
|
58 |
*
|
59 |
* @since 1.9
|
|
|
|
|
60 |
*/
|
61 |
public function auto_updater() {
|
62 |
$args = array(
|
@@ -132,6 +186,7 @@ class PLL_License {
|
|
132 |
* @since 1.9
|
133 |
*
|
134 |
* @param string $request check_license | activate_license | deactivate_license
|
|
|
135 |
*/
|
136 |
private function api_request( $request ) {
|
137 |
$licenses = get_option( 'polylang_licenses' );
|
@@ -191,11 +246,12 @@ class PLL_License {
|
|
191 |
$license = $this->license_data;
|
192 |
}
|
193 |
|
194 |
-
$class
|
|
|
195 |
|
196 |
$out = sprintf(
|
197 |
'<td><label for="pll-licenses[%1$s]">%2$s</label></td>' .
|
198 |
-
'<td><input name="licenses[%1$s]" id="pll-licenses[%1$s]" type="
|
199 |
esc_attr( $this->id ),
|
200 |
esc_attr( $this->name ),
|
201 |
esc_html( $this->license_key )
|
@@ -220,7 +276,7 @@ class PLL_License {
|
|
220 |
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
221 |
esc_html__( 'Your license key expired on %1$s. Please %2$srenew your license key%3$s.', 'polylang' ),
|
222 |
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
223 |
-
sprintf( '<a href="%s" target="_blank">',
|
224 |
'</a>'
|
225 |
);
|
226 |
break;
|
@@ -234,7 +290,7 @@ class PLL_License {
|
|
234 |
$message = sprintf(
|
235 |
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
236 |
esc_html__( 'Invalid license. Please %1$svisit your account page%2$s and verify it.', 'polylang' ),
|
237 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
238 |
'</a>'
|
239 |
);
|
240 |
break;
|
@@ -245,7 +301,7 @@ class PLL_License {
|
|
245 |
/* translators: %1$s is a product name, %2$s is link start tag, %3$s is link end tag. */
|
246 |
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' ),
|
247 |
esc_html( $this->name ),
|
248 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
249 |
'</a>'
|
250 |
);
|
251 |
break;
|
@@ -259,7 +315,7 @@ class PLL_License {
|
|
259 |
$message = sprintf(
|
260 |
/* translators: %1$s is link start tag, %2$s is link end tag */
|
261 |
esc_html__( 'Your license key has reached its activation limit. %1$sView possible upgrades%2$s now.', 'polylang' ),
|
262 |
-
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account' ),
|
263 |
'</a>'
|
264 |
);
|
265 |
break;
|
@@ -277,7 +333,7 @@ class PLL_License {
|
|
277 |
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
278 |
esc_html__( 'Your license key will expire soon! Precisely, it will expire on %1$s. %2$sRenew your license key today!%3$s.', 'polylang' ),
|
279 |
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
280 |
-
sprintf( '<a href="%s" target="_blank">',
|
281 |
'</a>'
|
282 |
);
|
283 |
} else {
|
9 |
* @since 1.9
|
10 |
*/
|
11 |
class PLL_License {
|
12 |
+
/**
|
13 |
+
* Sanitized plugin name.
|
14 |
+
*
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
public $id;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Plugin name.
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $name;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* License key.
|
28 |
+
*
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $license_key;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* License data, obtained from the API request.
|
35 |
+
*
|
36 |
+
* @var stdClass
|
37 |
+
*/
|
38 |
+
public $license_data;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Main plugin file.
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
private $file;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Current plugin version.
|
49 |
+
*
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
private $version;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Plugin author.
|
56 |
+
*
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
private $author;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* API url.
|
63 |
+
*
|
64 |
+
* @var string.
|
65 |
+
*/
|
66 |
private $api_url = 'https://polylang.pro';
|
67 |
|
68 |
/**
|
109 |
* Auto updater
|
110 |
*
|
111 |
* @since 1.9
|
112 |
+
*
|
113 |
+
* @return void
|
114 |
*/
|
115 |
public function auto_updater() {
|
116 |
$args = array(
|
186 |
* @since 1.9
|
187 |
*
|
188 |
* @param string $request check_license | activate_license | deactivate_license
|
189 |
+
* @return void
|
190 |
*/
|
191 |
private function api_request( $request ) {
|
192 |
$licenses = get_option( 'polylang_licenses' );
|
246 |
$license = $this->license_data;
|
247 |
}
|
248 |
|
249 |
+
$class = 'license-null';
|
250 |
+
$message = '';
|
251 |
|
252 |
$out = sprintf(
|
253 |
'<td><label for="pll-licenses[%1$s]">%2$s</label></td>' .
|
254 |
+
'<td><input name="licenses[%1$s]" id="pll-licenses[%1$s]" type="password" value="%3$s" class="regular-text code" />',
|
255 |
esc_attr( $this->id ),
|
256 |
esc_attr( $this->name ),
|
257 |
esc_html( $this->license_key )
|
276 |
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
277 |
esc_html__( 'Your license key expired on %1$s. Please %2$srenew your license key%3$s.', 'polylang' ),
|
278 |
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
279 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account/' ),
|
280 |
'</a>'
|
281 |
);
|
282 |
break;
|
290 |
$message = sprintf(
|
291 |
/* translators: %1$s is link start tag, %2$s is link end tag. */
|
292 |
esc_html__( 'Invalid license. Please %1$svisit your account page%2$s and verify it.', 'polylang' ),
|
293 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account/' ),
|
294 |
'</a>'
|
295 |
);
|
296 |
break;
|
301 |
/* translators: %1$s is a product name, %2$s is link start tag, %3$s is link end tag. */
|
302 |
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' ),
|
303 |
esc_html( $this->name ),
|
304 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account/' ),
|
305 |
'</a>'
|
306 |
);
|
307 |
break;
|
315 |
$message = sprintf(
|
316 |
/* translators: %1$s is link start tag, %2$s is link end tag */
|
317 |
esc_html__( 'Your license key has reached its activation limit. %1$sView possible upgrades%2$s now.', 'polylang' ),
|
318 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account/' ),
|
319 |
'</a>'
|
320 |
);
|
321 |
break;
|
333 |
/* translators: %1$s is a date, %2$s is link start tag, %3$s is link end tag. */
|
334 |
esc_html__( 'Your license key will expire soon! Precisely, it will expire on %1$s. %2$sRenew your license key today!%3$s.', 'polylang' ),
|
335 |
esc_html( date_i18n( get_option( 'date_format' ), $expiration ) ),
|
336 |
+
sprintf( '<a href="%s" target="_blank">', 'https://polylang.pro/account/' ),
|
337 |
'</a>'
|
338 |
);
|
339 |
} else {
|
include/links-abstract-domain.php
CHANGED
@@ -11,11 +11,11 @@
|
|
11 |
abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
12 |
|
13 |
/**
|
14 |
-
* Constructor
|
15 |
*
|
16 |
* @since 2.0
|
17 |
*
|
18 |
-
* @param
|
19 |
*/
|
20 |
public function __construct( &$model ) {
|
21 |
parent::__construct( $model );
|
@@ -48,15 +48,15 @@ abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
-
* Sets the home urls
|
52 |
*
|
53 |
* @since 2.2
|
54 |
*
|
55 |
-
* @param
|
56 |
*/
|
57 |
protected function set_home_url( $language ) {
|
58 |
$home_url = $this->home_url( $language );
|
59 |
-
$language->set_home_url( $home_url, $home_url ); // Search url and home url are the same
|
60 |
}
|
61 |
|
62 |
/**
|
11 |
abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
12 |
|
13 |
/**
|
14 |
+
* Constructor.
|
15 |
*
|
16 |
* @since 2.0
|
17 |
*
|
18 |
+
* @param PLL_Model $model Instance of PLL_Model.
|
19 |
*/
|
20 |
public function __construct( &$model ) {
|
21 |
parent::__construct( $model );
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
+
* Sets the home urls.
|
52 |
*
|
53 |
* @since 2.2
|
54 |
*
|
55 |
+
* @param PLL_Language $language Language object.
|
56 |
*/
|
57 |
protected function set_home_url( $language ) {
|
58 |
$home_url = $this->home_url( $language );
|
59 |
+
$language->set_home_url( $home_url, $home_url ); // Search url and home url are the same.
|
60 |
}
|
61 |
|
62 |
/**
|
include/links-default.php
CHANGED
@@ -11,17 +11,22 @@
|
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Default extends PLL_Links_Model {
|
|
|
|
|
|
|
|
|
|
|
14 |
public $using_permalinks = false;
|
15 |
|
16 |
/**
|
17 |
-
* Adds language
|
18 |
-
* links_model interface
|
19 |
*
|
20 |
* @since 1.2
|
21 |
*
|
22 |
-
* @param string
|
23 |
-
* @param
|
24 |
-
* @return string
|
25 |
*/
|
26 |
public function add_language_to_link( $url, $lang ) {
|
27 |
return empty( $lang ) || ( $this->options['hide_default'] && $this->options['default_lang'] == $lang->slug ) ? $url : add_query_arg( 'lang', $lang->slug, $url );
|
@@ -86,12 +91,12 @@ class PLL_Links_Default extends PLL_Links_Model {
|
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
-
* Returns the static front page url
|
90 |
*
|
91 |
* @since 1.8
|
92 |
*
|
93 |
-
* @param
|
94 |
-
* @return string
|
95 |
*/
|
96 |
public function front_page_url( $lang ) {
|
97 |
if ( $this->options['hide_default'] && $lang->slug == $this->options['default_lang'] ) {
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Default extends PLL_Links_Model {
|
14 |
+
/**
|
15 |
+
* Tells this child class of PLL_Links_Model does not use pretty permalinks.
|
16 |
+
*
|
17 |
+
* @var bool
|
18 |
+
*/
|
19 |
public $using_permalinks = false;
|
20 |
|
21 |
/**
|
22 |
+
* Adds the language code in a url.
|
23 |
+
* links_model interface.
|
24 |
*
|
25 |
* @since 1.2
|
26 |
*
|
27 |
+
* @param string $url The url to modify.
|
28 |
+
* @param PLL_Language $lang The language object.
|
29 |
+
* @return string Modified url.
|
30 |
*/
|
31 |
public function add_language_to_link( $url, $lang ) {
|
32 |
return empty( $lang ) || ( $this->options['hide_default'] && $this->options['default_lang'] == $lang->slug ) ? $url : add_query_arg( 'lang', $lang->slug, $url );
|
91 |
}
|
92 |
|
93 |
/**
|
94 |
+
* Returns the static front page url.
|
95 |
*
|
96 |
* @since 1.8
|
97 |
*
|
98 |
+
* @param PLL_Language $lang The language object.
|
99 |
+
* @return string The static front page url.
|
100 |
*/
|
101 |
public function front_page_url( $lang ) {
|
102 |
if ( $this->options['hide_default'] && $lang->slug == $this->options['default_lang'] ) {
|
include/links-directory.php
CHANGED
@@ -11,14 +11,19 @@
|
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
|
|
|
|
|
|
|
|
|
14 |
protected $home_relative;
|
15 |
|
16 |
/**
|
17 |
-
* Constructor
|
18 |
*
|
19 |
* @since 1.2
|
20 |
*
|
21 |
-
* @param
|
22 |
*/
|
23 |
public function __construct( &$model ) {
|
24 |
parent::__construct( $model );
|
@@ -36,6 +41,8 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
36 |
* Called only at first object creation to avoid duplicating filters when switching blog
|
37 |
*
|
38 |
* @since 1.6
|
|
|
|
|
39 |
*/
|
40 |
public function init() {
|
41 |
if ( did_action( 'setup_theme' ) ) {
|
@@ -49,14 +56,14 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* Adds the language code in url
|
53 |
-
* links_model interface
|
54 |
*
|
55 |
* @since 1.2
|
56 |
*
|
57 |
-
* @param string
|
58 |
-
* @param
|
59 |
-
* @return string
|
60 |
*/
|
61 |
public function add_language_to_link( $url, $lang ) {
|
62 |
if ( ! empty( $lang ) ) {
|
@@ -126,12 +133,12 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
-
* Returns the home url
|
130 |
-
* links_model interface
|
131 |
*
|
132 |
* @since 1.3.1
|
133 |
*
|
134 |
-
* @param
|
135 |
* @return string
|
136 |
*/
|
137 |
public function home_url( $lang ) {
|
@@ -144,6 +151,8 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
144 |
* Optionally removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
|
145 |
*
|
146 |
* @since 1.2
|
|
|
|
|
147 |
*/
|
148 |
public function add_permastruct() {
|
149 |
// Language information always in front of the uri ( 'with_front' => false )
|
@@ -155,12 +164,12 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
-
* Prepares rewrite rules filters
|
159 |
*
|
160 |
* @since 0.8.1
|
161 |
*
|
162 |
-
* @param
|
163 |
-
* @return
|
164 |
*/
|
165 |
public function prepare_rewrite_rules( $pre ) {
|
166 |
// Don't modify the rules if there is no languages created yet
|
@@ -180,13 +189,13 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
180 |
|
181 |
/**
|
182 |
* The rewrite rules !
|
183 |
-
*
|
184 |
-
*
|
185 |
*
|
186 |
* @since 0.8.1
|
187 |
*
|
188 |
-
* @param
|
189 |
-
* @return
|
190 |
*/
|
191 |
public function rewrite_rules( $rules ) {
|
192 |
$filter = str_replace( '_rewrite_rules', '', current_filter() );
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Directory extends PLL_Links_Permalinks {
|
14 |
+
/**
|
15 |
+
* Relative path to the home url.
|
16 |
+
*
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
protected $home_relative;
|
20 |
|
21 |
/**
|
22 |
+
* Constructor.
|
23 |
*
|
24 |
* @since 1.2
|
25 |
*
|
26 |
+
* @param PLL_Model $model PLL_Model instance.
|
27 |
*/
|
28 |
public function __construct( &$model ) {
|
29 |
parent::__construct( $model );
|
41 |
* Called only at first object creation to avoid duplicating filters when switching blog
|
42 |
*
|
43 |
* @since 1.6
|
44 |
+
*
|
45 |
+
* @return void
|
46 |
*/
|
47 |
public function init() {
|
48 |
if ( did_action( 'setup_theme' ) ) {
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
+
* Adds the language code in a url.
|
60 |
+
* links_model interface.
|
61 |
*
|
62 |
* @since 1.2
|
63 |
*
|
64 |
+
* @param string $url The url to modify.
|
65 |
+
* @param PLL_Language $lang The language object.
|
66 |
+
* @return string Modified url.
|
67 |
*/
|
68 |
public function add_language_to_link( $url, $lang ) {
|
69 |
if ( ! empty( $lang ) ) {
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* Returns the home url in a given language.
|
137 |
+
* links_model interface.
|
138 |
*
|
139 |
* @since 1.3.1
|
140 |
*
|
141 |
+
* @param PLL_Language $lang PLL_Language object.
|
142 |
* @return string
|
143 |
*/
|
144 |
public function home_url( $lang ) {
|
151 |
* Optionally removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
|
152 |
*
|
153 |
* @since 1.2
|
154 |
+
*
|
155 |
+
* @return void
|
156 |
*/
|
157 |
public function add_permastruct() {
|
158 |
// Language information always in front of the uri ( 'with_front' => false )
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
+
* Prepares the rewrite rules filters.
|
168 |
*
|
169 |
* @since 0.8.1
|
170 |
*
|
171 |
+
* @param mixed $pre Not used as the filter is used as an action.
|
172 |
+
* @return mixed
|
173 |
*/
|
174 |
public function prepare_rewrite_rules( $pre ) {
|
175 |
// Don't modify the rules if there is no languages created yet
|
189 |
|
190 |
/**
|
191 |
* The rewrite rules !
|
192 |
+
* Always make sure that the default language is at the end in case the language information is hidden for default language.
|
193 |
+
* Thanks to brbrbr http://wordpress.org/support/topic/plugin-polylang-rewrite-rules-not-correct.
|
194 |
*
|
195 |
* @since 0.8.1
|
196 |
*
|
197 |
+
* @param string[] $rules Rewrite rules.
|
198 |
+
* @return string[] Modified rewrite rules.
|
199 |
*/
|
200 |
public function rewrite_rules( $rules ) {
|
201 |
$filter = str_replace( '_rewrite_rules', '', current_filter() );
|
include/links-domain.php
CHANGED
@@ -12,6 +12,13 @@
|
|
12 |
*/
|
13 |
class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* Constructor
|
17 |
*
|
@@ -35,9 +42,9 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
35 |
*
|
36 |
* @since 1.2
|
37 |
*
|
38 |
-
* @param string
|
39 |
-
* @param
|
40 |
-
* @return string
|
41 |
*/
|
42 |
public function add_language_to_link( $url, $lang ) {
|
43 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
@@ -63,12 +70,12 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
* Returns the home url
|
67 |
-
* links_model interface
|
68 |
*
|
69 |
* @since 1.3.1
|
70 |
*
|
71 |
-
* @param
|
72 |
* @return string
|
73 |
*/
|
74 |
public function home_url( $lang ) {
|
@@ -76,11 +83,11 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
-
* Get hosts managed on the website
|
80 |
*
|
81 |
* @since 1.5
|
82 |
*
|
83 |
-
* @return
|
84 |
*/
|
85 |
public function get_hosts() {
|
86 |
$hosts = array();
|
12 |
*/
|
13 |
class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
14 |
|
15 |
+
/**
|
16 |
+
* An array with language code as keys and the host as values.
|
17 |
+
*
|
18 |
+
* @var string[]
|
19 |
+
*/
|
20 |
+
protected $hosts;
|
21 |
+
|
22 |
/**
|
23 |
* Constructor
|
24 |
*
|
42 |
*
|
43 |
* @since 1.2
|
44 |
*
|
45 |
+
* @param string $url The url to modify.
|
46 |
+
* @param PLL_Language $lang The language object.
|
47 |
+
* @return string Modified url.
|
48 |
*/
|
49 |
public function add_language_to_link( $url, $lang ) {
|
50 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
+
* Returns the home url in a given language.
|
74 |
+
* links_model interface.
|
75 |
*
|
76 |
* @since 1.3.1
|
77 |
*
|
78 |
+
* @param PLL_Language $lang PLL_Language object.
|
79 |
* @return string
|
80 |
*/
|
81 |
public function home_url( $lang ) {
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
+
* Get hosts managed on the website.
|
87 |
*
|
88 |
* @since 1.5
|
89 |
*
|
90 |
+
* @return string[] List of hosts.
|
91 |
*/
|
92 |
public function get_hosts() {
|
93 |
$hosts = array();
|
include/links-model.php
CHANGED
@@ -4,43 +4,128 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model abstract class
|
8 |
*
|
9 |
* @since 1.5
|
10 |
*/
|
11 |
abstract class PLL_Links_Model {
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
14 |
public $using_permalinks;
|
15 |
|
16 |
/**
|
17 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
*
|
19 |
* @since 1.5
|
20 |
*
|
21 |
-
* @param
|
22 |
*/
|
23 |
public function __construct( &$model ) {
|
24 |
-
$this->model
|
25 |
$this->options = &$model->options;
|
26 |
|
27 |
$this->home = home_url();
|
28 |
|
29 |
-
add_filter( 'pll_languages_list', array( $this, 'pll_languages_list' ), 4 ); //
|
30 |
add_filter( 'pll_after_languages_cache', array( $this, 'pll_after_languages_cache' ) );
|
31 |
|
32 |
-
//
|
33 |
add_filter( 'allowed_redirect_hosts', array( $this, 'allowed_redirect_hosts' ) );
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
*
|
39 |
* @since 1.5
|
40 |
*
|
41 |
-
* @param string
|
42 |
-
* @param
|
43 |
-
* @return string
|
44 |
*/
|
45 |
public function switch_language_in_link( $url, $lang ) {
|
46 |
$url = $this->remove_language_from_link( $url );
|
@@ -48,22 +133,22 @@ abstract class PLL_Links_Model {
|
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
-
* Get hosts managed on the website
|
52 |
*
|
53 |
* @since 1.5
|
54 |
*
|
55 |
-
* @return
|
56 |
*/
|
57 |
public function get_hosts() {
|
58 |
return array( wp_parse_url( $this->home, PHP_URL_HOST ) );
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
-
* Returns the home url
|
63 |
*
|
64 |
* @since 1.3.1
|
65 |
*
|
66 |
-
* @param
|
67 |
* @return string
|
68 |
*/
|
69 |
public function home_url( $lang ) {
|
@@ -72,11 +157,12 @@ abstract class PLL_Links_Model {
|
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
-
* Sets the home urls
|
76 |
*
|
77 |
* @since 1.8
|
78 |
*
|
79 |
-
* @param
|
|
|
80 |
*/
|
81 |
protected function set_home_url( $language ) {
|
82 |
// We should always have a default language here, except, temporarily, in PHPUnit tests. The test here protects against PHP notices.
|
@@ -88,12 +174,12 @@ abstract class PLL_Links_Model {
|
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
-
* Sets the home urls and flags before the languages are persistently cached
|
92 |
*
|
93 |
* @since 1.8
|
94 |
*
|
95 |
-
* @param
|
96 |
-
* @return
|
97 |
*/
|
98 |
public function pll_languages_list( $languages ) {
|
99 |
foreach ( $languages as $language ) {
|
@@ -104,17 +190,17 @@ abstract class PLL_Links_Model {
|
|
104 |
}
|
105 |
|
106 |
/**
|
107 |
-
* Sets the home urls when not cached
|
108 |
-
* Sets the home urls scheme
|
109 |
*
|
110 |
* @since 1.8
|
111 |
*
|
112 |
-
* @param
|
113 |
-
* @return
|
114 |
*/
|
115 |
public function pll_after_languages_cache( $languages ) {
|
116 |
foreach ( $languages as $language ) {
|
117 |
-
// Get the home urls when not cached
|
118 |
if ( ( defined( 'PLL_CACHE_LANGUAGES' ) && ! PLL_CACHE_LANGUAGES ) || ( defined( 'PLL_CACHE_HOME_URL' ) && ! PLL_CACHE_HOME_URL ) ) {
|
119 |
$this->set_home_url( $language );
|
120 |
}
|
@@ -126,12 +212,12 @@ abstract class PLL_Links_Model {
|
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
-
* Adds our domains or subdomains to allowed hosts for safe
|
130 |
*
|
131 |
* @since 1.4.3
|
132 |
*
|
133 |
-
* @param
|
134 |
-
* @return
|
135 |
*/
|
136 |
public function allowed_redirect_hosts( $hosts ) {
|
137 |
return array_unique( array_merge( $hosts, array_values( $this->get_hosts() ) ) );
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model abstract class.
|
8 |
*
|
9 |
* @since 1.5
|
10 |
*/
|
11 |
abstract class PLL_Links_Model {
|
12 |
+
/**
|
13 |
+
* True if the child class uses pretty permalinks, false otherwise.
|
14 |
+
*
|
15 |
+
* @var bool
|
16 |
+
*/
|
17 |
public $using_permalinks;
|
18 |
|
19 |
/**
|
20 |
+
* Stores the plugin options.
|
21 |
+
*
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
+
public $options;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var PLL_Model
|
28 |
+
*/
|
29 |
+
public $model;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Stores the home url before it is filtered.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $home;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Constructor.
|
40 |
*
|
41 |
* @since 1.5
|
42 |
*
|
43 |
+
* @param PLL_Model $model PLL_Model instance.
|
44 |
*/
|
45 |
public function __construct( &$model ) {
|
46 |
+
$this->model = &$model;
|
47 |
$this->options = &$model->options;
|
48 |
|
49 |
$this->home = home_url();
|
50 |
|
51 |
+
add_filter( 'pll_languages_list', array( $this, 'pll_languages_list' ), 4 ); // After PLL_Static_Pages.
|
52 |
add_filter( 'pll_after_languages_cache', array( $this, 'pll_after_languages_cache' ) );
|
53 |
|
54 |
+
// Adds our domains or subdomains to allowed hosts for safe redirection.
|
55 |
add_filter( 'allowed_redirect_hosts', array( $this, 'allowed_redirect_hosts' ) );
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
+
* Adds the language code in url.
|
60 |
+
*
|
61 |
+
* @since 1.2
|
62 |
+
*
|
63 |
+
* @param string $url The url to modify.
|
64 |
+
* @param PLL_Language $lang The language object.
|
65 |
+
* @return string Modified url.
|
66 |
+
*/
|
67 |
+
abstract public function add_language_to_link( $url, $lang );
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Returns the url without language code.
|
71 |
+
*
|
72 |
+
* @since 1.2
|
73 |
+
*
|
74 |
+
* @param string $url The url to modify.
|
75 |
+
* @return string Modified url.
|
76 |
+
*/
|
77 |
+
abstract public function remove_language_from_link( $url );
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Returns the link to the first page.
|
81 |
+
*
|
82 |
+
* @since 1.2
|
83 |
+
*
|
84 |
+
* @param string $url The url to modify.
|
85 |
+
* @return string Modified url.
|
86 |
+
*/
|
87 |
+
abstract public function remove_paged_from_link( $url );
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Returns the link to a paged page.
|
91 |
+
*
|
92 |
+
* @since 1.5
|
93 |
+
*
|
94 |
+
* @param string $url The url to modify.
|
95 |
+
* @param int $page The page number.
|
96 |
+
* @return string Modified url.
|
97 |
+
*/
|
98 |
+
abstract public function add_paged_to_link( $url, $page );
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Returns the language based on language code in url.
|
102 |
+
*
|
103 |
+
* @since 1.2
|
104 |
+
* @since 2.0 add $url argument.
|
105 |
+
*
|
106 |
+
* @param string $url Optional, defaults to thej current url.
|
107 |
+
* @return string Language slug.
|
108 |
+
*/
|
109 |
+
abstract public function get_language_from_url( $url = '' );
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Returns the static front page url.
|
113 |
+
*
|
114 |
+
* @since 1.8
|
115 |
+
*
|
116 |
+
* @param PLL_Language $lang The language object.
|
117 |
+
* @return string The static front page url.
|
118 |
+
*/
|
119 |
+
abstract public function front_page_url( $lang );
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Changes the language code in url.
|
123 |
*
|
124 |
* @since 1.5
|
125 |
*
|
126 |
+
* @param string $url The url to modify.
|
127 |
+
* @param PLL_Language $lang The language object.
|
128 |
+
* @return string Modified url.
|
129 |
*/
|
130 |
public function switch_language_in_link( $url, $lang ) {
|
131 |
$url = $this->remove_language_from_link( $url );
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* Get hosts managed on the website.
|
137 |
*
|
138 |
* @since 1.5
|
139 |
*
|
140 |
+
* @return string[] The list of hosts.
|
141 |
*/
|
142 |
public function get_hosts() {
|
143 |
return array( wp_parse_url( $this->home, PHP_URL_HOST ) );
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* Returns the home url in a given language.
|
148 |
*
|
149 |
* @since 1.3.1
|
150 |
*
|
151 |
+
* @param PLL_Language $lang PLL_Language object.
|
152 |
* @return string
|
153 |
*/
|
154 |
public function home_url( $lang ) {
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
+
* Sets the home urls in PLL_Language.
|
161 |
*
|
162 |
* @since 1.8
|
163 |
*
|
164 |
+
* @param PLL_Language $language PLL_Language object.
|
165 |
+
* @return void
|
166 |
*/
|
167 |
protected function set_home_url( $language ) {
|
168 |
// We should always have a default language here, except, temporarily, in PHPUnit tests. The test here protects against PHP notices.
|
174 |
}
|
175 |
|
176 |
/**
|
177 |
+
* Sets the home urls and flags before the languages are persistently cached.
|
178 |
*
|
179 |
* @since 1.8
|
180 |
*
|
181 |
+
* @param PLL_Language[] $languages Array of PLL_Language objects.
|
182 |
+
* @return PLL_Language[] Array of PLL_Language objects with home url and flag.
|
183 |
*/
|
184 |
public function pll_languages_list( $languages ) {
|
185 |
foreach ( $languages as $language ) {
|
190 |
}
|
191 |
|
192 |
/**
|
193 |
+
* Sets the home urls when not cached.
|
194 |
+
* Sets the home urls scheme.
|
195 |
*
|
196 |
* @since 1.8
|
197 |
*
|
198 |
+
* @param PLL_Language[] $languages Array of PLL_Language objects.
|
199 |
+
* @return PLL_Language[] Array of PLL_Language objects.
|
200 |
*/
|
201 |
public function pll_after_languages_cache( $languages ) {
|
202 |
foreach ( $languages as $language ) {
|
203 |
+
// Get the home urls when not cached.
|
204 |
if ( ( defined( 'PLL_CACHE_LANGUAGES' ) && ! PLL_CACHE_LANGUAGES ) || ( defined( 'PLL_CACHE_HOME_URL' ) && ! PLL_CACHE_HOME_URL ) ) {
|
205 |
$this->set_home_url( $language );
|
206 |
}
|
212 |
}
|
213 |
|
214 |
/**
|
215 |
+
* Adds our domains or subdomains to allowed hosts for safe redirect.
|
216 |
*
|
217 |
* @since 1.4.3
|
218 |
*
|
219 |
+
* @param string[] $hosts Allowed hosts.
|
220 |
+
* @return string[] Modified list of allowed hosts.
|
221 |
*/
|
222 |
public function allowed_redirect_hosts( $hosts ) {
|
223 |
return array_unique( array_merge( $hosts, array_values( $this->get_hosts() ) ) );
|
include/links-permalinks.php
CHANGED
@@ -9,17 +9,49 @@
|
|
9 |
* @since 1.6
|
10 |
*/
|
11 |
abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $using_permalinks = true;
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
protected $always_rewrite = array( 'date', 'root', 'comments', 'search', 'author' );
|
16 |
|
17 |
/**
|
18 |
-
* Constructor
|
19 |
*
|
20 |
* @since 1.8
|
21 |
*
|
22 |
-
* @param
|
23 |
*/
|
24 |
public function __construct( &$model ) {
|
25 |
parent::__construct( $model );
|
@@ -73,11 +105,11 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
-
* Returns the home url
|
77 |
*
|
78 |
* @since 1.3.1
|
79 |
*
|
80 |
-
* @param
|
81 |
* @return string
|
82 |
*/
|
83 |
public function home_url( $lang ) {
|
@@ -85,12 +117,12 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
-
* Returns the static front page url
|
89 |
*
|
90 |
* @since 1.8
|
91 |
*
|
92 |
-
* @param
|
93 |
-
* @return string
|
94 |
*/
|
95 |
public function front_page_url( $lang ) {
|
96 |
if ( $this->options['hide_default'] && $lang->slug == $this->options['default_lang'] ) {
|
@@ -105,6 +137,8 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
105 |
* Prepares rewrite rules filters
|
106 |
*
|
107 |
* @since 1.6
|
|
|
|
|
108 |
*/
|
109 |
public function get_rewrite_rules_filters() {
|
110 |
// Make sure we have the right post types and taxonomies
|
9 |
* @since 1.6
|
10 |
*/
|
11 |
abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
12 |
+
/**
|
13 |
+
* Tells this child class of PLL_Links_Model is for pretty permalinks.
|
14 |
+
*
|
15 |
+
* @var bool
|
16 |
+
*/
|
17 |
public $using_permalinks = true;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* The name of the index file which is the entry point to all requests.
|
21 |
+
* We need this before the global $wp_rewrite is created.
|
22 |
+
* Also hardcoded in WP_Rewrite.
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $index = 'index.php';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* The prefix for all permalink structures.
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $root;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Whether to add trailing slashes.
|
37 |
+
*
|
38 |
+
* @var bool
|
39 |
+
*/
|
40 |
+
protected $use_trailing_slashes;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* The name of the rewrite rules to always modify.
|
44 |
+
*
|
45 |
+
* @var string[]
|
46 |
+
*/
|
47 |
protected $always_rewrite = array( 'date', 'root', 'comments', 'search', 'author' );
|
48 |
|
49 |
/**
|
50 |
+
* Constructor.
|
51 |
*
|
52 |
* @since 1.8
|
53 |
*
|
54 |
+
* @param PLL_Model $model PLL_Model instance.
|
55 |
*/
|
56 |
public function __construct( &$model ) {
|
57 |
parent::__construct( $model );
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* Returns the home url.
|
109 |
*
|
110 |
* @since 1.3.1
|
111 |
*
|
112 |
+
* @param PLL_Language $lang PLL_Language object.
|
113 |
* @return string
|
114 |
*/
|
115 |
public function home_url( $lang ) {
|
117 |
}
|
118 |
|
119 |
/**
|
120 |
+
* Returns the static front page url.
|
121 |
*
|
122 |
* @since 1.8
|
123 |
*
|
124 |
+
* @param PLL_Language $lang The language object.
|
125 |
+
* @return string The static front page url.
|
126 |
*/
|
127 |
public function front_page_url( $lang ) {
|
128 |
if ( $this->options['hide_default'] && $lang->slug == $this->options['default_lang'] ) {
|
137 |
* Prepares rewrite rules filters
|
138 |
*
|
139 |
* @since 1.6
|
140 |
+
*
|
141 |
+
* @return string[]
|
142 |
*/
|
143 |
public function get_rewrite_rules_filters() {
|
144 |
// Make sure we have the right post types and taxonomies
|
include/links-subdomain.php
CHANGED
@@ -11,14 +11,20 @@
|
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
protected $www;
|
15 |
|
16 |
/**
|
17 |
-
* Constructor
|
18 |
*
|
19 |
* @since 1.7.4
|
20 |
*
|
21 |
-
* @param
|
22 |
*/
|
23 |
public function __construct( &$model ) {
|
24 |
parent::__construct( $model );
|
@@ -26,14 +32,14 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
-
* Adds the language code in url
|
30 |
-
* links_model interface
|
31 |
*
|
32 |
* @since 1.2
|
33 |
*
|
34 |
-
* @param string
|
35 |
-
* @param
|
36 |
-
* @return string
|
37 |
*/
|
38 |
public function add_language_to_link( $url, $lang ) {
|
39 |
if ( ! empty( $lang ) && false === strpos( $url, '://' . $lang->slug . '.' ) ) {
|
@@ -68,11 +74,11 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
-
* Get hosts managed on the website
|
72 |
*
|
73 |
* @since 1.5
|
74 |
*
|
75 |
-
* @return
|
76 |
*/
|
77 |
public function get_hosts() {
|
78 |
$hosts = array();
|
11 |
* @since 1.2
|
12 |
*/
|
13 |
class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
14 |
+
/**
|
15 |
+
* Stores whether the home url includes www. or not.
|
16 |
+
* Either '://' or '://www.'.
|
17 |
+
*
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
protected $www;
|
21 |
|
22 |
/**
|
23 |
+
* Constructor.
|
24 |
*
|
25 |
* @since 1.7.4
|
26 |
*
|
27 |
+
* @param PLL_Model $model Instance of PLL_Model.
|
28 |
*/
|
29 |
public function __construct( &$model ) {
|
30 |
parent::__construct( $model );
|
32 |
}
|
33 |
|
34 |
/**
|
35 |
+
* Adds the language code in a url.
|
36 |
+
* links_model interface.
|
37 |
*
|
38 |
* @since 1.2
|
39 |
*
|
40 |
+
* @param string $url The url to modify.
|
41 |
+
* @param PLL_Language $lang The language object.
|
42 |
+
* @return string Modified url.
|
43 |
*/
|
44 |
public function add_language_to_link( $url, $lang ) {
|
45 |
if ( ! empty( $lang ) && false === strpos( $url, '://' . $lang->slug . '.' ) ) {
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
+
* Get hosts managed on the website.
|
78 |
*
|
79 |
* @since 1.5
|
80 |
*
|
81 |
+
* @return string[] The list of hosts.
|
82 |
*/
|
83 |
public function get_hosts() {
|
84 |
$hosts = array();
|
include/links.php
CHANGED
@@ -9,7 +9,24 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Links {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
@@ -25,12 +42,13 @@ class PLL_Links {
|
|
25 |
}
|
26 |
|
27 |
/**
|
28 |
-
* Returns the home url in the requested language
|
29 |
*
|
30 |
* @since 1.3
|
31 |
*
|
32 |
-
* @param
|
33 |
-
* @param bool
|
|
|
34 |
*/
|
35 |
public function get_home_url( $language, $is_search = false ) {
|
36 |
$language = is_object( $language ) ? $language : $this->model->get_language( $language );
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Links {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
public $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
public $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Instance of a child class of PLL_Links_Model.
|
26 |
+
*
|
27 |
+
* @var PLL_Links_Model
|
28 |
+
*/
|
29 |
+
public $links_model;
|
30 |
|
31 |
/**
|
32 |
* Constructor
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
+
* Returns the home url in the requested language.
|
46 |
*
|
47 |
* @since 1.3
|
48 |
*
|
49 |
+
* @param PLL_Language|string $language The language.
|
50 |
+
* @param bool $is_search Optional, whether we need the home url for a search form, defaults to false.
|
51 |
+
* @return string
|
52 |
*/
|
53 |
public function get_home_url( $language, $is_search = false ) {
|
54 |
$language = is_object( $language ) ? $language : $this->model->get_language( $language );
|
include/mo.php
CHANGED
@@ -26,24 +26,27 @@ class PLL_MO extends MO {
|
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
-
* Writes a PLL_MO object into a custom post meta
|
30 |
*
|
31 |
* @since 1.2
|
32 |
*
|
33 |
-
* @param
|
|
|
34 |
*/
|
35 |
public function export_to_db( $lang ) {
|
36 |
$this->add_entry( $this->make_entry( '', '' ) ); // Empty string translation, just in case
|
37 |
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
40 |
$strings = array();
|
41 |
foreach ( $this->entries as $entry ) {
|
42 |
-
$strings[] = array( $entry->singular, $this->translate( $entry->singular ) );
|
43 |
}
|
44 |
|
45 |
-
$strings = wp_slash( $strings ); // Avoid breaking slashed strings in update_post_meta. See https://codex.wordpress.org/Function_Reference/update_post_meta#Character_Escaping
|
46 |
-
|
47 |
if ( empty( $lang->mo_id ) ) {
|
48 |
$post = array(
|
49 |
'post_title' => 'polylang_mo_' . $lang->term_id,
|
@@ -58,11 +61,12 @@ class PLL_MO extends MO {
|
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
-
* Reads a PLL_MO object from a custom post meta
|
62 |
*
|
63 |
* @since 1.2
|
64 |
*
|
65 |
-
* @param
|
|
|
66 |
*/
|
67 |
public function import_from_db( $lang ) {
|
68 |
if ( ! empty( $lang->mo_id ) ) {
|
@@ -76,11 +80,11 @@ class PLL_MO extends MO {
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
-
* Returns the post id of the post storing the strings translations
|
80 |
*
|
81 |
* @since 1.4
|
82 |
*
|
83 |
-
* @param
|
84 |
* @return int
|
85 |
*/
|
86 |
public static function get_id( $lang ) {
|
@@ -101,6 +105,8 @@ class PLL_MO extends MO {
|
|
101 |
* Invalidate the cache when adding a new language
|
102 |
*
|
103 |
* @since 2.0.5
|
|
|
|
|
104 |
*/
|
105 |
public function clean_cache() {
|
106 |
wp_cache_delete( 'polylang_mo_ids' );
|
@@ -112,6 +118,7 @@ class PLL_MO extends MO {
|
|
112 |
* @since 2.9
|
113 |
*
|
114 |
* @param string $string The source string to remove from the translations.
|
|
|
115 |
*/
|
116 |
public function delete_entry( $string ) {
|
117 |
unset( $this->entries[ $string ] );
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
+
* Writes a PLL_MO object into a custom post meta.
|
30 |
*
|
31 |
* @since 1.2
|
32 |
*
|
33 |
+
* @param PLL_Language $lang The language in which we want to export strings.
|
34 |
+
* @return void
|
35 |
*/
|
36 |
public function export_to_db( $lang ) {
|
37 |
$this->add_entry( $this->make_entry( '', '' ) ); // Empty string translation, just in case
|
38 |
|
39 |
+
/*
|
40 |
+
* It would be convenient to store the whole object but it would take a huge space in DB.
|
41 |
+
* So let's keep only the strings in an array.
|
42 |
+
* The strings are slashed to avoid breaking slashed strings in update_post_meta.
|
43 |
+
* @see https://codex.wordpress.org/Function_Reference/update_post_meta#Character_Escaping.
|
44 |
+
*/
|
45 |
$strings = array();
|
46 |
foreach ( $this->entries as $entry ) {
|
47 |
+
$strings[] = wp_slash( array( $entry->singular, $this->translate( $entry->singular ) ) );
|
48 |
}
|
49 |
|
|
|
|
|
50 |
if ( empty( $lang->mo_id ) ) {
|
51 |
$post = array(
|
52 |
'post_title' => 'polylang_mo_' . $lang->term_id,
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
+
* Reads a PLL_MO object from a custom post meta.
|
65 |
*
|
66 |
* @since 1.2
|
67 |
*
|
68 |
+
* @param PLL_Language $lang The language in which we want to get strings.
|
69 |
+
* @return void
|
70 |
*/
|
71 |
public function import_from_db( $lang ) {
|
72 |
if ( ! empty( $lang->mo_id ) ) {
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
+
* Returns the post id of the post storing the strings translations.
|
84 |
*
|
85 |
* @since 1.4
|
86 |
*
|
87 |
+
* @param PLL_Language $lang The language object.
|
88 |
* @return int
|
89 |
*/
|
90 |
public static function get_id( $lang ) {
|
105 |
* Invalidate the cache when adding a new language
|
106 |
*
|
107 |
* @since 2.0.5
|
108 |
+
*
|
109 |
+
* @return void
|
110 |
*/
|
111 |
public function clean_cache() {
|
112 |
wp_cache_delete( 'polylang_mo_ids' );
|
118 |
* @since 2.9
|
119 |
*
|
120 |
* @param string $string The source string to remove from the translations.
|
121 |
+
* @return void
|
122 |
*/
|
123 |
public function delete_entry( $string ) {
|
124 |
unset( $this->entries[ $string ] );
|
include/model.php
CHANGED
@@ -9,27 +9,51 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Model {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
public $options;
|
14 |
-
public $post, $term; // Translated objects models
|
15 |
|
16 |
/**
|
17 |
-
*
|
18 |
-
*
|
19 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
*
|
21 |
* @since 1.2
|
22 |
*
|
23 |
-
* @param array $options Polylang options
|
24 |
*/
|
25 |
public function __construct( &$options ) {
|
26 |
$this->options = &$options;
|
27 |
|
28 |
$this->cache = new PLL_Cache();
|
29 |
-
$this->post = new PLL_Translated_Post( $this ); //
|
30 |
-
$this->term = new PLL_Translated_Term( $this ); //
|
31 |
|
32 |
-
// We need to clean languages cache when editing a language and when modifying the permalink structure
|
33 |
add_action( 'edited_term_taxonomy', array( $this, 'clean_languages_cache' ), 10, 2 );
|
34 |
add_action( 'update_option_permalink_structure', array( $this, 'clean_languages_cache' ) );
|
35 |
add_action( 'update_option_siteurl', array( $this, 'clean_languages_cache' ) );
|
@@ -37,29 +61,27 @@ class PLL_Model {
|
|
37 |
|
38 |
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ) );
|
39 |
|
40 |
-
// Just in case someone would like to display the language description
|
41 |
add_filter( 'language_description', '__return_empty_string' );
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
-
* Returns the list of available languages
|
46 |
-
*
|
47 |
-
*
|
48 |
-
*
|
49 |
-
* List of parameters accepted in $args:
|
50 |
-
*
|
51 |
-
* hide_empty => hides languages with no posts if set to true ( defaults to false )
|
52 |
-
* fields => return only that field if set ( see PLL_Language for a list of fields )
|
53 |
*
|
54 |
* @since 0.1
|
55 |
*
|
56 |
-
* @param array $args
|
57 |
-
*
|
|
|
|
|
|
|
58 |
*/
|
59 |
public function get_languages_list( $args = array() ) {
|
60 |
if ( false === $languages = $this->cache->get( 'languages' ) ) {
|
61 |
|
62 |
-
// Create the languages from taxonomies
|
63 |
if ( ( defined( 'PLL_CACHE_LANGUAGES' ) && ! PLL_CACHE_LANGUAGES ) || false === ( $languages = get_transient( 'pll_languages_list' ) ) ) {
|
64 |
$languages = get_terms( 'language', array( 'hide_empty' => false, 'orderby' => 'term_group' ) );
|
65 |
$languages = empty( $languages ) || is_wp_error( $languages ) ? array() : $languages;
|
@@ -69,36 +91,38 @@ class PLL_Model {
|
|
69 |
array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
|
70 |
|
71 |
if ( ! empty( $languages ) && ! empty( $term_languages ) ) {
|
72 |
-
// Don't use array_map + create_function to instantiate an autoloaded class as it breaks badly in old versions of PHP
|
73 |
foreach ( $languages as $k => $v ) {
|
74 |
$languages[ $k ] = new PLL_Language( $v, $term_languages[ 'pll_' . $v->slug ] );
|
75 |
}
|
76 |
|
77 |
-
// We will need the languages list to allow its access in the filter below
|
78 |
$this->cache->set( 'languages', $languages );
|
79 |
|
80 |
/**
|
81 |
-
*
|
82 |
-
* /!\
|
83 |
*
|
84 |
* @since 1.7.5
|
85 |
*
|
86 |
-
* @param
|
87 |
-
* @param
|
88 |
*/
|
89 |
$languages = apply_filters( 'pll_languages_list', $languages, $this );
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
|
|
94 |
set_transient( 'pll_languages_list', array_map( 'get_object_vars', $languages ) );
|
95 |
}
|
96 |
else {
|
97 |
-
$languages = array(); // In case something went wrong
|
98 |
}
|
99 |
}
|
100 |
|
101 |
-
// Create the languages directly from arrays stored in transients
|
102 |
else {
|
103 |
foreach ( $languages as $k => $v ) {
|
104 |
$languages[ $k ] = new PLL_Language( $v );
|
@@ -106,12 +130,12 @@ class PLL_Model {
|
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
*
|
110 |
-
* /!\
|
111 |
*
|
112 |
* @since 1.8
|
113 |
*
|
114 |
-
* @param
|
115 |
*/
|
116 |
$languages = apply_filters( 'pll_after_languages_cache', $languages );
|
117 |
$this->cache->set( 'languages', $languages );
|
@@ -119,7 +143,7 @@ class PLL_Model {
|
|
119 |
|
120 |
$args = wp_parse_args( $args, array( 'hide_empty' => false ) );
|
121 |
|
122 |
-
// Remove empty languages if requested
|
123 |
if ( $args['hide_empty'] ) {
|
124 |
$languages = wp_list_filter( $languages, array( 'count' => 0 ), 'NOT' );
|
125 |
}
|
@@ -136,6 +160,7 @@ class PLL_Model {
|
|
136 |
*
|
137 |
* @param int $term not used
|
138 |
* @param string $taxonomy taxonomy name
|
|
|
139 |
*/
|
140 |
public function clean_languages_cache( $term = 0, $taxonomy = null ) {
|
141 |
if ( empty( $taxonomy ) || 'language' == $taxonomy ) {
|
@@ -160,12 +185,12 @@ class PLL_Model {
|
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
-
* Returns the language by its term_id, tl_term_id, slug or locale
|
164 |
*
|
165 |
* @since 0.1
|
166 |
*
|
167 |
-
* @param
|
168 |
-
* @return
|
169 |
*/
|
170 |
public function get_language( $value ) {
|
171 |
if ( is_object( $value ) ) {
|
@@ -187,13 +212,13 @@ class PLL_Model {
|
|
187 |
}
|
188 |
|
189 |
/**
|
190 |
-
* Adds terms clauses to
|
191 |
*
|
192 |
* @since 1.2
|
193 |
*
|
194 |
-
* @param
|
195 |
-
* @param
|
196 |
-
* @return
|
197 |
*/
|
198 |
public function terms_clauses( $clauses, $lang ) {
|
199 |
if ( ! empty( $lang ) && false === strpos( $clauses['join'], 'pll_tr' ) ) {
|
@@ -204,14 +229,15 @@ class PLL_Model {
|
|
204 |
}
|
205 |
|
206 |
/**
|
207 |
-
* Returns post types that need to be translated
|
208 |
-
*
|
209 |
-
*
|
|
|
210 |
*
|
211 |
* @since 1.2
|
212 |
*
|
213 |
-
* @param bool $filter
|
214 |
-
* @return
|
215 |
*/
|
216 |
public function get_translated_post_types( $filter = true ) {
|
217 |
if ( false === $post_types = $this->cache->get( 'post_types' ) ) {
|
@@ -226,15 +252,15 @@ class PLL_Model {
|
|
226 |
}
|
227 |
|
228 |
/**
|
229 |
-
*
|
230 |
* The default are post types which have the parameter ‘public’ set to true.
|
231 |
* The filter must be added soon in the WordPress loading process:
|
232 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
233 |
*
|
234 |
* @since 0.8
|
235 |
*
|
236 |
-
* @param
|
237 |
-
* @param bool
|
238 |
*/
|
239 |
$post_types = apply_filters( 'pll_get_post_types', $post_types, false );
|
240 |
|
@@ -247,11 +273,11 @@ class PLL_Model {
|
|
247 |
}
|
248 |
|
249 |
/**
|
250 |
-
* Returns true if Polylang manages languages and translations for this post type
|
251 |
*
|
252 |
* @since 1.2
|
253 |
*
|
254 |
-
* @param string|
|
255 |
* @return bool
|
256 |
*/
|
257 |
public function is_translated_post_type( $post_type ) {
|
@@ -260,12 +286,12 @@ class PLL_Model {
|
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
-
*
|
264 |
*
|
265 |
* @since 1.2
|
266 |
*
|
267 |
-
* @param bool $filter
|
268 |
-
* @return
|
269 |
*/
|
270 |
public function get_translated_taxonomies( $filter = true ) {
|
271 |
if ( false === $taxonomies = $this->cache->get( 'taxonomies' ) ) {
|
@@ -276,15 +302,15 @@ class PLL_Model {
|
|
276 |
}
|
277 |
|
278 |
/**
|
279 |
-
*
|
280 |
* The default are taxonomies which have the parameter ‘public’ set to true.
|
281 |
* The filter must be added soon in the WordPress loading process:
|
282 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
283 |
*
|
284 |
* @since 0.8
|
285 |
*
|
286 |
-
* @param
|
287 |
-
* @param bool
|
288 |
*/
|
289 |
$taxonomies = apply_filters( 'pll_get_taxonomies', $taxonomies, false );
|
290 |
if ( did_action( 'after_setup_theme' ) ) {
|
@@ -296,11 +322,11 @@ class PLL_Model {
|
|
296 |
}
|
297 |
|
298 |
/**
|
299 |
-
* Returns true if Polylang manages languages and translations for this taxonomy
|
300 |
*
|
301 |
* @since 1.2
|
302 |
*
|
303 |
-
* @param string|
|
304 |
* @return bool
|
305 |
*/
|
306 |
public function is_translated_taxonomy( $tax ) {
|
@@ -309,12 +335,12 @@ class PLL_Model {
|
|
309 |
}
|
310 |
|
311 |
/**
|
312 |
-
* Return
|
313 |
*
|
314 |
* @since 1.7
|
315 |
*
|
316 |
-
* @param bool $filter
|
317 |
-
* @return
|
318 |
*/
|
319 |
public function get_filtered_taxonomies( $filter = true ) {
|
320 |
if ( did_action( 'after_setup_theme' ) ) {
|
@@ -325,15 +351,15 @@ class PLL_Model {
|
|
325 |
$taxonomies = array( 'post_format' => 'post_format' );
|
326 |
|
327 |
/**
|
328 |
-
*
|
329 |
* Includes only the post format by default
|
330 |
* The filter must be added soon in the WordPress loading process:
|
331 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
332 |
*
|
333 |
* @since 1.7
|
334 |
*
|
335 |
-
* @param
|
336 |
-
* @param bool
|
337 |
*/
|
338 |
$taxonomies = apply_filters( 'pll_filtered_taxonomies', $taxonomies, false );
|
339 |
}
|
@@ -342,11 +368,11 @@ class PLL_Model {
|
|
342 |
}
|
343 |
|
344 |
/**
|
345 |
-
* Returns true if Polylang filters this taxonomy per language
|
346 |
*
|
347 |
* @since 1.7
|
348 |
*
|
349 |
-
* @param string|
|
350 |
* @return bool
|
351 |
*/
|
352 |
public function is_filtered_taxonomy( $tax ) {
|
@@ -355,7 +381,7 @@ class PLL_Model {
|
|
355 |
}
|
356 |
|
357 |
/**
|
358 |
-
* Returns the query vars of all filtered taxonomies
|
359 |
*
|
360 |
* @since 1.7
|
361 |
*
|
@@ -365,7 +391,9 @@ class PLL_Model {
|
|
365 |
$query_vars = array();
|
366 |
foreach ( $this->get_filtered_taxonomies() as $filtered_tax ) {
|
367 |
$tax = get_taxonomy( $filtered_tax );
|
368 |
-
|
|
|
|
|
369 |
}
|
370 |
return $query_vars;
|
371 |
}
|
@@ -376,6 +404,7 @@ class PLL_Model {
|
|
376 |
* @since 1.2
|
377 |
*
|
378 |
* @param object|string|int $lang language
|
|
|
379 |
*/
|
380 |
public function create_default_category( $lang ) {
|
381 |
$lang = $this->get_language( $lang );
|
@@ -409,16 +438,16 @@ class PLL_Model {
|
|
409 |
|
410 |
/**
|
411 |
* It is possible to have several terms with the same name in the same taxonomy ( one per language )
|
412 |
-
* but the native term_exists will return true even if only one exists
|
413 |
-
*
|
414 |
*
|
415 |
* @since 1.4
|
416 |
*
|
417 |
-
* @param string
|
418 |
-
* @param string
|
419 |
-
* @param int
|
420 |
-
* @param string|
|
421 |
-
* @return null|int
|
422 |
*/
|
423 |
public function term_exists( $term_name, $taxonomy, $parent, $language ) {
|
424 |
global $wpdb;
|
@@ -441,15 +470,15 @@ class PLL_Model {
|
|
441 |
}
|
442 |
|
443 |
/**
|
444 |
-
* Checks if a term slug exists in a given language, taxonomy, hierarchy
|
445 |
*
|
446 |
* @since 1.9
|
447 |
-
* @since 2.8 Moved from PLL_Share_Term_Slug::term_exists() to PLL_Model::term_exists_by_slug()
|
448 |
*
|
449 |
-
* @param string
|
450 |
-
* @param string|
|
451 |
-
* @param string
|
452 |
-
* @param int
|
453 |
* @return null|int The term_id of the found term.
|
454 |
*/
|
455 |
public function term_exists_by_slug( $slug, $language, $taxonomy = '', $parent = 0 ) {
|
@@ -479,8 +508,20 @@ class PLL_Model {
|
|
479 |
*
|
480 |
* @since 1.2
|
481 |
*
|
482 |
-
* @param
|
483 |
-
* @param array
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
* @return int
|
485 |
*/
|
486 |
public function count_posts( $lang, $q = array() ) {
|
@@ -509,7 +550,7 @@ class PLL_Model {
|
|
509 |
$select = "SELECT pll_tr.term_taxonomy_id, COUNT( * ) AS num_posts FROM {$wpdb->posts}";
|
510 |
$join = $this->post->join_clause();
|
511 |
$where = sprintf( " WHERE post_status = '%s'", esc_sql( $q['post_status'] ) );
|
512 |
-
$where .= sprintf( " AND {$wpdb->posts}.post_type IN ( '%s' )",
|
513 |
$where .= $this->post->where_clause( $this->get_languages_list() );
|
514 |
$groupby = ' GROUP BY pll_tr.term_taxonomy_id';
|
515 |
|
@@ -571,103 +612,26 @@ class PLL_Model {
|
|
571 |
}
|
572 |
|
573 |
/**
|
574 |
-
* Setup the links model based on options
|
575 |
*
|
576 |
* @since 1.2
|
577 |
*
|
578 |
-
* @return
|
579 |
*/
|
580 |
public function get_links_model() {
|
581 |
$c = array( 'Directory', 'Directory', 'Subdomain', 'Domain' );
|
582 |
$class = get_option( 'permalink_structure' ) ? 'PLL_Links_' . $c[ $this->options['force_lang'] ] : 'PLL_Links_Default';
|
583 |
|
584 |
/**
|
585 |
-
*
|
586 |
-
* /!\ this filter is fired *before* the $polylang object is available
|
587 |
*
|
588 |
* @since 2.1.1
|
589 |
*
|
590 |
-
* @param string $class A class name: PLL_Links_Default, PLL_Links_Directory, PLL_Links_Subdomain, PLL_Links_Domain
|
591 |
*/
|
592 |
$class = apply_filters( 'pll_links_model', $class );
|
593 |
|
594 |
return new $class( $this );
|
595 |
}
|
596 |
-
|
597 |
-
/**
|
598 |
-
* Some backward compatibility with Polylang < 1.8
|
599 |
-
* allows for example to call $polylang->model->get_post_languages( $post_id ) instead of $polylang->model->post->get_language( $post_id )
|
600 |
-
* this works but should be slower than the direct call, thus an error is triggered in debug mode
|
601 |
-
*
|
602 |
-
* @since 1.8
|
603 |
-
*
|
604 |
-
* @param string $func Function name
|
605 |
-
* @param array $args Function arguments
|
606 |
-
*/
|
607 |
-
public function __call( $func, $args ) {
|
608 |
-
$f = $func;
|
609 |
-
|
610 |
-
switch ( $func ) {
|
611 |
-
case 'get_object_term':
|
612 |
-
$o = ( false === strpos( $args[1], 'term' ) ) ? 'post' : 'term';
|
613 |
-
break;
|
614 |
-
|
615 |
-
case 'save_translations':
|
616 |
-
case 'delete_translation':
|
617 |
-
case 'get_translations':
|
618 |
-
case 'get_translation':
|
619 |
-
case 'join_clause':
|
620 |
-
$o = ( 'post' == $args[0] || $this->is_translated_post_type( $args[0] ) ) ? 'post' : ( 'term' == $args[0] || $this->is_translated_taxonomy( $args[0] ) ? 'term' : false );
|
621 |
-
unset( $args[0] );
|
622 |
-
break;
|
623 |
-
|
624 |
-
case 'set_post_language':
|
625 |
-
case 'get_post_language':
|
626 |
-
case 'set_term_language':
|
627 |
-
case 'get_term_language':
|
628 |
-
case 'delete_term_language':
|
629 |
-
case 'get_post':
|
630 |
-
case 'get_term':
|
631 |
-
$str = explode( '_', $func );
|
632 |
-
$f = empty( $str[2] ) ? $str[0] : $str[0] . '_' . $str[2];
|
633 |
-
$o = $str[1];
|
634 |
-
break;
|
635 |
-
|
636 |
-
case 'where_clause':
|
637 |
-
case 'get_objects_in_language':
|
638 |
-
$o = $args[1];
|
639 |
-
unset( $args[1] );
|
640 |
-
break;
|
641 |
-
}
|
642 |
-
|
643 |
-
if ( ! empty( $o ) && is_object( $this->$o ) && method_exists( $this->$o, $f ) ) {
|
644 |
-
if ( WP_DEBUG ) {
|
645 |
-
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
646 |
-
$i = 1 + empty( $debug[1]['line'] ); // the file and line are in $debug[2] if the function was called using call_user_func
|
647 |
-
|
648 |
-
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
649 |
-
sprintf(
|
650 |
-
'%1$s was called incorrectly in %4$s on line %5$s: the call to $polylang->model->%1$s() has been deprecated in Polylang 1.8, use PLL()->model->%2$s->%3$s() instead.' . "\nError handler",
|
651 |
-
esc_html( $func ),
|
652 |
-
esc_html( $o ),
|
653 |
-
esc_html( $f ),
|
654 |
-
esc_html( $debug[ $i ]['file'] ),
|
655 |
-
absint( $debug[ $i ]['line'] )
|
656 |
-
)
|
657 |
-
);
|
658 |
-
}
|
659 |
-
return call_user_func_array( array( $this->$o, $f ), $args );
|
660 |
-
}
|
661 |
-
|
662 |
-
$debug = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
663 |
-
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
664 |
-
sprintf(
|
665 |
-
'Call to undefined function PLL()->model->%1$s() in %2$s on line %3$s' . "\nError handler",
|
666 |
-
esc_html( $func ),
|
667 |
-
esc_html( $debug[0]['file'] ),
|
668 |
-
absint( $debug[0]['line'] )
|
669 |
-
),
|
670 |
-
E_USER_ERROR
|
671 |
-
);
|
672 |
-
}
|
673 |
}
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Model {
|
12 |
+
/**
|
13 |
+
* Internal non persistent cache object.
|
14 |
+
*
|
15 |
+
* @var PLL_Cache
|
16 |
+
*/
|
17 |
+
public $cache;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Stores the plugin options.
|
21 |
+
*
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
public $options;
|
|
|
25 |
|
26 |
/**
|
27 |
+
* Translated post model.
|
28 |
+
*
|
29 |
+
* @var PLL_Translated_Post
|
30 |
+
*/
|
31 |
+
public $post;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Translated term model.
|
35 |
+
*
|
36 |
+
* @var PLL_Translated_Term
|
37 |
+
*/
|
38 |
+
public $term;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Constructor.
|
42 |
+
* Setups translated objects sub models.
|
43 |
+
* Setups filters and actions.
|
44 |
*
|
45 |
* @since 1.2
|
46 |
*
|
47 |
+
* @param array $options Polylang options.
|
48 |
*/
|
49 |
public function __construct( &$options ) {
|
50 |
$this->options = &$options;
|
51 |
|
52 |
$this->cache = new PLL_Cache();
|
53 |
+
$this->post = new PLL_Translated_Post( $this ); // Translated post sub model.
|
54 |
+
$this->term = new PLL_Translated_Term( $this ); // Translated term sub model.
|
55 |
|
56 |
+
// We need to clean languages cache when editing a language and when modifying the permalink structure.
|
57 |
add_action( 'edited_term_taxonomy', array( $this, 'clean_languages_cache' ), 10, 2 );
|
58 |
add_action( 'update_option_permalink_structure', array( $this, 'clean_languages_cache' ) );
|
59 |
add_action( 'update_option_siteurl', array( $this, 'clean_languages_cache' ) );
|
61 |
|
62 |
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ) );
|
63 |
|
64 |
+
// Just in case someone would like to display the language description ;).
|
65 |
add_filter( 'language_description', '__return_empty_string' );
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
+
* Returns the list of available languages.
|
70 |
+
* - Stores the list in a db transient ( except flags ), unless PLL_CACHE_LANGUAGES is set to false.
|
71 |
+
* - Caches the list ( with flags ) in a PLL_Cache object.
|
|
|
|
|
|
|
|
|
|
|
72 |
*
|
73 |
* @since 0.1
|
74 |
*
|
75 |
+
* @param array $args {
|
76 |
+
* @type bool $hide_empty Hides languages with no posts if set to true ( defaults to false ).
|
77 |
+
* @type string $fields Returns only that field if set; {@see PLL_Language} for a list of fields.
|
78 |
+
* }
|
79 |
+
* @return array List of PLL_Language objects or PLL_Language object properties.
|
80 |
*/
|
81 |
public function get_languages_list( $args = array() ) {
|
82 |
if ( false === $languages = $this->cache->get( 'languages' ) ) {
|
83 |
|
84 |
+
// Create the languages from taxonomies.
|
85 |
if ( ( defined( 'PLL_CACHE_LANGUAGES' ) && ! PLL_CACHE_LANGUAGES ) || false === ( $languages = get_transient( 'pll_languages_list' ) ) ) {
|
86 |
$languages = get_terms( 'language', array( 'hide_empty' => false, 'orderby' => 'term_group' ) );
|
87 |
$languages = empty( $languages ) || is_wp_error( $languages ) ? array() : $languages;
|
91 |
array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
|
92 |
|
93 |
if ( ! empty( $languages ) && ! empty( $term_languages ) ) {
|
94 |
+
// Don't use array_map + create_function() to instantiate an autoloaded class as it breaks badly in old versions of PHP.
|
95 |
foreach ( $languages as $k => $v ) {
|
96 |
$languages[ $k ] = new PLL_Language( $v, $term_languages[ 'pll_' . $v->slug ] );
|
97 |
}
|
98 |
|
99 |
+
// We will need the languages list to allow its access in the filter below.
|
100 |
$this->cache->set( 'languages', $languages );
|
101 |
|
102 |
/**
|
103 |
+
* Filters the list of languages *before* it is stored in the persistent cache.
|
104 |
+
* /!\ This filter is fired *before* the $polylang object is available.
|
105 |
*
|
106 |
* @since 1.7.5
|
107 |
*
|
108 |
+
* @param PLL_Language[] $languages The list of language objects.
|
109 |
+
* @param PLL_Model $model PLL_Model object.
|
110 |
*/
|
111 |
$languages = apply_filters( 'pll_languages_list', $languages, $this );
|
112 |
|
113 |
+
/*
|
114 |
+
* Don't store directly objects as it badly break with some hosts ( GoDaddy ) due to race conditions when using object cache.
|
115 |
+
* Thanks to captin411 for catching this!
|
116 |
+
* @see https://wordpress.org/support/topic/fatal-error-pll_model_languages_list?replies=8#post-6782255
|
117 |
+
*/
|
118 |
set_transient( 'pll_languages_list', array_map( 'get_object_vars', $languages ) );
|
119 |
}
|
120 |
else {
|
121 |
+
$languages = array(); // In case something went wrong.
|
122 |
}
|
123 |
}
|
124 |
|
125 |
+
// Create the languages directly from arrays stored in transients.
|
126 |
else {
|
127 |
foreach ( $languages as $k => $v ) {
|
128 |
$languages[ $k ] = new PLL_Language( $v );
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
+
* Filters the list of languages *after* it is stored in the persistent cache.
|
134 |
+
* /!\ This filter is fired *before* the $polylang object is available.
|
135 |
*
|
136 |
* @since 1.8
|
137 |
*
|
138 |
+
* @param PLL_Language[] $languages The list of language objects.
|
139 |
*/
|
140 |
$languages = apply_filters( 'pll_after_languages_cache', $languages );
|
141 |
$this->cache->set( 'languages', $languages );
|
143 |
|
144 |
$args = wp_parse_args( $args, array( 'hide_empty' => false ) );
|
145 |
|
146 |
+
// Remove empty languages if requested.
|
147 |
if ( $args['hide_empty'] ) {
|
148 |
$languages = wp_list_filter( $languages, array( 'count' => 0 ), 'NOT' );
|
149 |
}
|
160 |
*
|
161 |
* @param int $term not used
|
162 |
* @param string $taxonomy taxonomy name
|
163 |
+
* @return void
|
164 |
*/
|
165 |
public function clean_languages_cache( $term = 0, $taxonomy = null ) {
|
166 |
if ( empty( $taxonomy ) || 'language' == $taxonomy ) {
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
+
* Returns the language by its term_id, tl_term_id, slug or locale.
|
189 |
*
|
190 |
* @since 0.1
|
191 |
*
|
192 |
+
* @param mixed $value term_id, tl_term_id, slug or locale of the queried language.
|
193 |
+
* @return PLL_Language|false Language object, false if no language found.
|
194 |
*/
|
195 |
public function get_language( $value ) {
|
196 |
if ( is_object( $value ) ) {
|
212 |
}
|
213 |
|
214 |
/**
|
215 |
+
* Adds terms clauses to the term query to filter them by languages.
|
216 |
*
|
217 |
* @since 1.2
|
218 |
*
|
219 |
+
* @param string[] $clauses The list of sql clauses in terms query.
|
220 |
+
* @param PLL_Language $lang PLL_Language object.
|
221 |
+
* @return string[] Modified list of clauses.
|
222 |
*/
|
223 |
public function terms_clauses( $clauses, $lang ) {
|
224 |
if ( ! empty( $lang ) && false === strpos( $clauses['join'], 'pll_tr' ) ) {
|
229 |
}
|
230 |
|
231 |
/**
|
232 |
+
* Returns post types that need to be translated.
|
233 |
+
* The post types list is cached for better better performance.
|
234 |
+
* The method waits for 'after_setup_theme' to apply the cache
|
235 |
+
* to allow themes adding the filter in functions.php.
|
236 |
*
|
237 |
* @since 1.2
|
238 |
*
|
239 |
+
* @param bool $filter True if we should return only valid registered post types.
|
240 |
+
* @return string[] Post type names for which Polylang manages languages and translations.
|
241 |
*/
|
242 |
public function get_translated_post_types( $filter = true ) {
|
243 |
if ( false === $post_types = $this->cache->get( 'post_types' ) ) {
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
+
* Filters the list of post types available for translation.
|
256 |
* The default are post types which have the parameter ‘public’ set to true.
|
257 |
* The filter must be added soon in the WordPress loading process:
|
258 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
259 |
*
|
260 |
* @since 0.8
|
261 |
*
|
262 |
+
* @param string[] $post_types List of post type names.
|
263 |
+
* @param bool $is_settings True when displaying the list of custom post types in Polylang settings.
|
264 |
*/
|
265 |
$post_types = apply_filters( 'pll_get_post_types', $post_types, false );
|
266 |
|
273 |
}
|
274 |
|
275 |
/**
|
276 |
+
* Returns true if Polylang manages languages and translations for this post type.
|
277 |
*
|
278 |
* @since 1.2
|
279 |
*
|
280 |
+
* @param string|string[] $post_type Post type name or array of post type names.
|
281 |
* @return bool
|
282 |
*/
|
283 |
public function is_translated_post_type( $post_type ) {
|
286 |
}
|
287 |
|
288 |
/**
|
289 |
+
* Returns taxonomies that need to be translated.
|
290 |
*
|
291 |
* @since 1.2
|
292 |
*
|
293 |
+
* @param bool $filter True if we should return only valid registered taxonomies.
|
294 |
+
* @return string[] Array of registered taxonomy names for which Polylang manages languages and translations.
|
295 |
*/
|
296 |
public function get_translated_taxonomies( $filter = true ) {
|
297 |
if ( false === $taxonomies = $this->cache->get( 'taxonomies' ) ) {
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
+
* Filters the list of taxonomies available for translation.
|
306 |
* The default are taxonomies which have the parameter ‘public’ set to true.
|
307 |
* The filter must be added soon in the WordPress loading process:
|
308 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
309 |
*
|
310 |
* @since 0.8
|
311 |
*
|
312 |
+
* @param string[] $taxonomies List of taxonomy names.
|
313 |
+
* @param bool $is_settings True when displaying the list of custom taxonomies in Polylang settings.
|
314 |
*/
|
315 |
$taxonomies = apply_filters( 'pll_get_taxonomies', $taxonomies, false );
|
316 |
if ( did_action( 'after_setup_theme' ) ) {
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
+
* Returns true if Polylang manages languages and translations for this taxonomy.
|
326 |
*
|
327 |
* @since 1.2
|
328 |
*
|
329 |
+
* @param string|string[] $tax Taxonomy name or array of taxonomy names.
|
330 |
* @return bool
|
331 |
*/
|
332 |
public function is_translated_taxonomy( $tax ) {
|
335 |
}
|
336 |
|
337 |
/**
|
338 |
+
* Return staxonomies that need to be filtered ( post_format like ).
|
339 |
*
|
340 |
* @since 1.7
|
341 |
*
|
342 |
+
* @param bool $filter True if we should return only valid registered taxonomies.
|
343 |
+
* @return string[] Array of registered taxonomy names.
|
344 |
*/
|
345 |
public function get_filtered_taxonomies( $filter = true ) {
|
346 |
if ( did_action( 'after_setup_theme' ) ) {
|
351 |
$taxonomies = array( 'post_format' => 'post_format' );
|
352 |
|
353 |
/**
|
354 |
+
* Filters the list of taxonomies not translatable but filtered by language.
|
355 |
* Includes only the post format by default
|
356 |
* The filter must be added soon in the WordPress loading process:
|
357 |
* in a function hooked to ‘plugins_loaded’ or directly in functions.php for themes.
|
358 |
*
|
359 |
* @since 1.7
|
360 |
*
|
361 |
+
* @param string[] $taxonomies List of taxonomy names.
|
362 |
+
* @param bool $is_settings True when displaying the list of custom taxonomies in Polylang settings.
|
363 |
*/
|
364 |
$taxonomies = apply_filters( 'pll_filtered_taxonomies', $taxonomies, false );
|
365 |
}
|
368 |
}
|
369 |
|
370 |
/**
|
371 |
+
* Returns true if Polylang filters this taxonomy per language.
|
372 |
*
|
373 |
* @since 1.7
|
374 |
*
|
375 |
+
* @param string|string[] $tax Taxonomy name or array of taxonomy names.
|
376 |
* @return bool
|
377 |
*/
|
378 |
public function is_filtered_taxonomy( $tax ) {
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
+
* Returns the query vars of all filtered taxonomies.
|
385 |
*
|
386 |
* @since 1.7
|
387 |
*
|
391 |
$query_vars = array();
|
392 |
foreach ( $this->get_filtered_taxonomies() as $filtered_tax ) {
|
393 |
$tax = get_taxonomy( $filtered_tax );
|
394 |
+
if ( ! empty( $tax ) ) {
|
395 |
+
$query_vars[] = $tax->query_var;
|
396 |
+
}
|
397 |
}
|
398 |
return $query_vars;
|
399 |
}
|
404 |
* @since 1.2
|
405 |
*
|
406 |
* @param object|string|int $lang language
|
407 |
+
* @return void
|
408 |
*/
|
409 |
public function create_default_category( $lang ) {
|
410 |
$lang = $this->get_language( $lang );
|
438 |
|
439 |
/**
|
440 |
* It is possible to have several terms with the same name in the same taxonomy ( one per language )
|
441 |
+
* but the native term_exists() will return true even if only one exists.
|
442 |
+
* So here the function adds the language parameter.
|
443 |
*
|
444 |
* @since 1.4
|
445 |
*
|
446 |
+
* @param string $term_name The term name.
|
447 |
+
* @param string $taxonomy Taxonomy name.
|
448 |
+
* @param int $parent Parent term id.
|
449 |
+
* @param string|PLL_Language $language The language slug or object.
|
450 |
+
* @return null|int The term_id of the found term.
|
451 |
*/
|
452 |
public function term_exists( $term_name, $taxonomy, $parent, $language ) {
|
453 |
global $wpdb;
|
470 |
}
|
471 |
|
472 |
/**
|
473 |
+
* Checks if a term slug exists in a given language, taxonomy, hierarchy.
|
474 |
*
|
475 |
* @since 1.9
|
476 |
+
* @since 2.8 Moved from PLL_Share_Term_Slug::term_exists() to PLL_Model::term_exists_by_slug().
|
477 |
*
|
478 |
+
* @param string $slug The term slug to test.
|
479 |
+
* @param string|PLL_Language $language The language slug or object.
|
480 |
+
* @param string $taxonomy Optional taxonomy name.
|
481 |
+
* @param int $parent Optional parent term id.
|
482 |
* @return null|int The term_id of the found term.
|
483 |
*/
|
484 |
public function term_exists_by_slug( $slug, $language, $taxonomy = '', $parent = 0 ) {
|
508 |
*
|
509 |
* @since 1.2
|
510 |
*
|
511 |
+
* @param PLL_Language $lang PLL_Language instance.
|
512 |
+
* @param array $q {
|
513 |
+
* WP_Query arguments:
|
514 |
+
*
|
515 |
+
* @type string|string[] $post_type Post type or array of post types.
|
516 |
+
* @type int $m Combination YearMonth. Accepts any four-digit year and month.
|
517 |
+
* @type int $year Four-digit year.
|
518 |
+
* @type int $monthnum Two-digit month.
|
519 |
+
* @type int $day Day of the month.
|
520 |
+
* @type int $author Author id.
|
521 |
+
* @type string $author_name User 'user_nicename'.
|
522 |
+
* @type string $post_format Post format.
|
523 |
+
* @type string $post_status Post status.
|
524 |
+
* }
|
525 |
* @return int
|
526 |
*/
|
527 |
public function count_posts( $lang, $q = array() ) {
|
550 |
$select = "SELECT pll_tr.term_taxonomy_id, COUNT( * ) AS num_posts FROM {$wpdb->posts}";
|
551 |
$join = $this->post->join_clause();
|
552 |
$where = sprintf( " WHERE post_status = '%s'", esc_sql( $q['post_status'] ) );
|
553 |
+
$where .= sprintf( " AND {$wpdb->posts}.post_type IN ( '%s' )", implode( "', '", esc_sql( $q['post_type'] ) ) );
|
554 |
$where .= $this->post->where_clause( $this->get_languages_list() );
|
555 |
$groupby = ' GROUP BY pll_tr.term_taxonomy_id';
|
556 |
|
612 |
}
|
613 |
|
614 |
/**
|
615 |
+
* Setup the links model based on options.
|
616 |
*
|
617 |
* @since 1.2
|
618 |
*
|
619 |
+
* @return PLL_Links_Model
|
620 |
*/
|
621 |
public function get_links_model() {
|
622 |
$c = array( 'Directory', 'Directory', 'Subdomain', 'Domain' );
|
623 |
$class = get_option( 'permalink_structure' ) ? 'PLL_Links_' . $c[ $this->options['force_lang'] ] : 'PLL_Links_Default';
|
624 |
|
625 |
/**
|
626 |
+
* Filters the links model class to use.
|
627 |
+
* /!\ this filter is fired *before* the $polylang object is available.
|
628 |
*
|
629 |
* @since 2.1.1
|
630 |
*
|
631 |
+
* @param string $class A class name: PLL_Links_Default, PLL_Links_Directory, PLL_Links_Subdomain, PLL_Links_Domain.
|
632 |
*/
|
633 |
$class = apply_filters( 'pll_links_model', $class );
|
634 |
|
635 |
return new $class( $this );
|
636 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
637 |
}
|
include/nav-menu.php
CHANGED
@@ -10,7 +10,31 @@
|
|
10 |
* @since 1.7.7
|
11 |
*/
|
12 |
class PLL_Nav_Menu {
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor: setups filters and actions
|
@@ -39,8 +63,8 @@ class PLL_Nav_Menu {
|
|
39 |
*
|
40 |
* @since 2.6
|
41 |
*
|
42 |
-
* @param
|
43 |
-
* @return
|
44 |
*/
|
45 |
public function wp_setup_nav_menu_item( $item ) {
|
46 |
if ( '#pll_switcher' === $item->url ) {
|
@@ -55,6 +79,8 @@ class PLL_Nav_Menu {
|
|
55 |
* to do only one time
|
56 |
*
|
57 |
* @since 1.2
|
|
|
|
|
58 |
*/
|
59 |
public function create_nav_menu_locations() {
|
60 |
static $once;
|
@@ -79,8 +105,8 @@ class PLL_Nav_Menu {
|
|
79 |
*
|
80 |
* @since 1.8
|
81 |
*
|
82 |
-
* @param string
|
83 |
-
* @param
|
84 |
* @return string
|
85 |
*/
|
86 |
public function combine_location( $loc, $lang ) {
|
@@ -88,14 +114,15 @@ class PLL_Nav_Menu {
|
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
-
* Get nav menu locations and language from a temporary location
|
92 |
*
|
93 |
* @since 1.8
|
94 |
*
|
95 |
-
* @param string $loc
|
96 |
-
* @return
|
97 |
-
*
|
98 |
-
*
|
|
|
99 |
*/
|
100 |
public function explode_location( $loc ) {
|
101 |
$infos = explode( '___', $loc );
|
@@ -119,13 +146,14 @@ class PLL_Nav_Menu {
|
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
-
* Filters _wp_auto_add_pages_to_menu by language
|
123 |
*
|
124 |
* @since 0.9.4
|
125 |
*
|
126 |
-
* @param string
|
127 |
-
* @param string
|
128 |
-
* @param
|
|
|
129 |
*/
|
130 |
public function auto_add_pages_to_menu( $new_status, $old_status, $post ) {
|
131 |
if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type || ! empty( $post->post_parent ) ) {
|
@@ -133,8 +161,6 @@ class PLL_Nav_Menu {
|
|
133 |
}
|
134 |
|
135 |
if ( ! empty( $this->options['nav_menus'][ $this->theme ] ) ) {
|
136 |
-
$this->auto_add_menus = array();
|
137 |
-
|
138 |
$lang = $this->model->post->get_language( $post->ID );
|
139 |
$lang = empty( $lang ) ? $this->options['default_lang'] : $lang->slug; // If the page has no language yet, the default language will be assigned
|
140 |
|
10 |
* @since 1.7.7
|
11 |
*/
|
12 |
class PLL_Nav_Menu {
|
13 |
+
/**
|
14 |
+
* Stores the plugin options.
|
15 |
+
*
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
public $options;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var PLL_Model
|
22 |
+
*/
|
23 |
+
public $model;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Theme name.
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $theme;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Array of menu ids in a given language used when auto add pages to menus.
|
34 |
+
*
|
35 |
+
* @var int[]
|
36 |
+
*/
|
37 |
+
protected $auto_add_menus = array();
|
38 |
|
39 |
/**
|
40 |
* Constructor: setups filters and actions
|
63 |
*
|
64 |
* @since 2.6
|
65 |
*
|
66 |
+
* @param stdClass $item Menu item.
|
67 |
+
* @return stdClass
|
68 |
*/
|
69 |
public function wp_setup_nav_menu_item( $item ) {
|
70 |
if ( '#pll_switcher' === $item->url ) {
|
79 |
* to do only one time
|
80 |
*
|
81 |
* @since 1.2
|
82 |
+
*
|
83 |
+
* @return void
|
84 |
*/
|
85 |
public function create_nav_menu_locations() {
|
86 |
static $once;
|
105 |
*
|
106 |
* @since 1.8
|
107 |
*
|
108 |
+
* @param string $loc Nav menu location.
|
109 |
+
* @param PLL_Language $lang Language object.
|
110 |
* @return string
|
111 |
*/
|
112 |
public function combine_location( $loc, $lang ) {
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
+
* Get nav menu locations and language from a temporary location.
|
118 |
*
|
119 |
* @since 1.8
|
120 |
*
|
121 |
+
* @param string $loc Temporary location.
|
122 |
+
* @return string[] {
|
123 |
+
* @type string $location Nav menu location.
|
124 |
+
* @type string $lang Language code.
|
125 |
+
* }
|
126 |
*/
|
127 |
public function explode_location( $loc ) {
|
128 |
$infos = explode( '___', $loc );
|
146 |
}
|
147 |
|
148 |
/**
|
149 |
+
* Filters _wp_auto_add_pages_to_menu by language.
|
150 |
*
|
151 |
* @since 0.9.4
|
152 |
*
|
153 |
+
* @param string $new_status Transition to this post status.
|
154 |
+
* @param string $old_status Previous post status.
|
155 |
+
* @param WP_Post $post Post object.
|
156 |
+
* @return void
|
157 |
*/
|
158 |
public function auto_add_pages_to_menu( $new_status, $old_status, $post ) {
|
159 |
if ( 'publish' != $new_status || 'publish' == $old_status || 'page' != $post->post_type || ! empty( $post->post_parent ) ) {
|
161 |
}
|
162 |
|
163 |
if ( ! empty( $this->options['nav_menus'][ $this->theme ] ) ) {
|
|
|
|
|
164 |
$lang = $this->model->post->get_language( $post->ID );
|
165 |
$lang = empty( $lang ) ? $this->options['default_lang'] : $lang->slug; // If the page has no language yet, the default language will be assigned
|
166 |
|
include/olt-manager.php
CHANGED
@@ -13,10 +13,33 @@
|
|
13 |
* @since 1.2
|
14 |
*/
|
15 |
class PLL_OLT_Manager {
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
protected $default_locale;
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
/**
|
22 |
* Constructor: setups relevant filters
|
@@ -28,9 +51,8 @@ class PLL_OLT_Manager {
|
|
28 |
add_filter( 'pre_update_option_active_plugins', array( $this, 'make_polylang_first' ) );
|
29 |
add_filter( 'pre_update_option_active_sitewide_plugins', array( $this, 'make_polylang_first' ) );
|
30 |
|
31 |
-
// Overriding load text domain only on front since WP 4.7
|
32 |
-
|
33 |
-
if ( is_admin() && ! Polylang::is_ajax_on_front() && function_exists( 'get_user_locale' ) ) {
|
34 |
return;
|
35 |
}
|
36 |
|
@@ -66,6 +88,8 @@ class PLL_OLT_Manager {
|
|
66 |
* Loads text domains
|
67 |
*
|
68 |
* @since 0.1
|
|
|
|
|
69 |
*/
|
70 |
public function load_textdomains() {
|
71 |
// Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain
|
@@ -83,7 +107,7 @@ class PLL_OLT_Manager {
|
|
83 |
* See WP_Locale_Switcher::change_locale()
|
84 |
*/
|
85 |
if ( ! class_exists( 'WP_Textdomain_Registry' ) && function_exists( '_get_path_to_translation' ) ) {
|
86 |
-
_get_path_to_translation(
|
87 |
}
|
88 |
|
89 |
foreach ( $this->list_textdomains as $textdomain ) {
|
@@ -139,36 +163,23 @@ class PLL_OLT_Manager {
|
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
*
|
143 |
-
*
|
144 |
-
*
|
145 |
-
* @since 0.1
|
146 |
-
*
|
147 |
-
* @param bool $bool Whether to override the .mo file loading.
|
148 |
-
* @return bool
|
149 |
-
*/
|
150 |
-
public function mofile( $bool ) {
|
151 |
-
return $bool;
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Saves all text domains in a table for later usage
|
156 |
-
* It replaces the 'override_load_textdomain' filter used since 0.1
|
157 |
*
|
158 |
* @since 2.0.4
|
159 |
*
|
160 |
-
* @param string $mofile translation file name
|
161 |
-
* @param string $domain text domain name
|
162 |
-
* @return
|
163 |
*/
|
164 |
public function load_textdomain_mofile( $mofile, $domain ) {
|
165 |
-
// On multisite, 2 files are sharing the same domain so we need to distinguish them
|
166 |
if ( 'default' === $domain && false !== strpos( $mofile, '/ms-' ) ) {
|
167 |
$this->list_textdomains['ms-default'] = array( 'mo' => $mofile, 'domain' => $domain );
|
168 |
} else {
|
169 |
$this->list_textdomains[ $domain ] = array( 'mo' => $mofile, 'domain' => $domain );
|
170 |
}
|
171 |
-
return ''; // Hack to prevent WP loading text domains as we will load them all later
|
172 |
}
|
173 |
|
174 |
/**
|
@@ -205,11 +216,12 @@ class PLL_OLT_Manager {
|
|
205 |
}
|
206 |
|
207 |
/**
|
208 |
-
* Translates post types and taxonomies labels once the language is known
|
209 |
*
|
210 |
* @since 0.9
|
211 |
*
|
212 |
-
* @param
|
|
|
213 |
*/
|
214 |
public function translate_labels( $type ) {
|
215 |
// Use static array to avoid translating several times the same ( default ) labels
|
@@ -232,12 +244,12 @@ class PLL_OLT_Manager {
|
|
232 |
}
|
233 |
|
234 |
/**
|
235 |
-
* Allows Polylang to be the first plugin loaded ;-
|
236 |
*
|
237 |
* @since 1.2
|
238 |
*
|
239 |
-
* @param
|
240 |
-
* @return
|
241 |
*/
|
242 |
public function make_polylang_first( $plugins ) {
|
243 |
if ( $key = array_search( POLYLANG_BASENAME, $plugins ) ) {
|
13 |
* @since 1.2
|
14 |
*/
|
15 |
class PLL_OLT_Manager {
|
16 |
+
/**
|
17 |
+
* Singleton instance
|
18 |
+
*
|
19 |
+
* @var PLL_OLT_Manager
|
20 |
+
*/
|
21 |
+
protected static $instance;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Stores the default site locale before it is modified.
|
25 |
+
*
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
protected $default_locale;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Stores all loaded text domains and mo files.
|
32 |
+
*
|
33 |
+
* @var string[][]
|
34 |
+
*/
|
35 |
+
protected $list_textdomains = array();
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Stores post types an taxonomies labels to translate.
|
39 |
+
*
|
40 |
+
* @var string[][]
|
41 |
+
*/
|
42 |
+
public $labels = array();
|
43 |
|
44 |
/**
|
45 |
* Constructor: setups relevant filters
|
51 |
add_filter( 'pre_update_option_active_plugins', array( $this, 'make_polylang_first' ) );
|
52 |
add_filter( 'pre_update_option_active_sitewide_plugins', array( $this, 'make_polylang_first' ) );
|
53 |
|
54 |
+
// Overriding load text domain only on front since WP 4.7.
|
55 |
+
if ( is_admin() && ! Polylang::is_ajax_on_front() ) {
|
|
|
56 |
return;
|
57 |
}
|
58 |
|
88 |
* Loads text domains
|
89 |
*
|
90 |
* @since 0.1
|
91 |
+
*
|
92 |
+
* @return void
|
93 |
*/
|
94 |
public function load_textdomains() {
|
95 |
// Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain
|
107 |
* See WP_Locale_Switcher::change_locale()
|
108 |
*/
|
109 |
if ( ! class_exists( 'WP_Textdomain_Registry' ) && function_exists( '_get_path_to_translation' ) ) {
|
110 |
+
_get_path_to_translation( '', true );
|
111 |
}
|
112 |
|
113 |
foreach ( $this->list_textdomains as $textdomain ) {
|
163 |
}
|
164 |
|
165 |
/**
|
166 |
+
* Saves all text domains in a table for later usage.
|
167 |
+
* It replaces the 'override_load_textdomain' filter previously used.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
*
|
169 |
* @since 2.0.4
|
170 |
*
|
171 |
+
* @param string $mofile The translation file name.
|
172 |
+
* @param string $domain The text domain name.
|
173 |
+
* @return string
|
174 |
*/
|
175 |
public function load_textdomain_mofile( $mofile, $domain ) {
|
176 |
+
// On multisite, 2 files are sharing the same domain so we need to distinguish them.
|
177 |
if ( 'default' === $domain && false !== strpos( $mofile, '/ms-' ) ) {
|
178 |
$this->list_textdomains['ms-default'] = array( 'mo' => $mofile, 'domain' => $domain );
|
179 |
} else {
|
180 |
$this->list_textdomains[ $domain ] = array( 'mo' => $mofile, 'domain' => $domain );
|
181 |
}
|
182 |
+
return ''; // Hack to prevent WP loading text domains as we will load them all later.
|
183 |
}
|
184 |
|
185 |
/**
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
+
* Translates post types and taxonomies labels once the language is known.
|
220 |
*
|
221 |
* @since 0.9
|
222 |
*
|
223 |
+
* @param WP_Post_Type|WP_Taxonomy $type Either a post type or a taxonomy.
|
224 |
+
* @return void
|
225 |
*/
|
226 |
public function translate_labels( $type ) {
|
227 |
// Use static array to avoid translating several times the same ( default ) labels
|
244 |
}
|
245 |
|
246 |
/**
|
247 |
+
* Allows Polylang to be the first plugin loaded ;-).
|
248 |
*
|
249 |
* @since 1.2
|
250 |
*
|
251 |
+
* @param string[] $plugins List of active plugins.
|
252 |
+
* @return string[] List of active plugins.
|
253 |
*/
|
254 |
public function make_polylang_first( $plugins ) {
|
255 |
if ( $key = array_search( POLYLANG_BASENAME, $plugins ) ) {
|
include/pointer.php
DELETED
@@ -1,116 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Polylang
|
4 |
-
*/
|
5 |
-
|
6 |
-
/**
|
7 |
-
* A class to manage WP pointers
|
8 |
-
* offers the possibility to have customized buttons
|
9 |
-
*
|
10 |
-
* @since 1.7.7
|
11 |
-
* @deprecated 2.3.9
|
12 |
-
*/
|
13 |
-
class PLL_Pointer {
|
14 |
-
protected $args;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Constructor
|
18 |
-
* enqueues the pointer script
|
19 |
-
*
|
20 |
-
* List of parameters accepted in $args:
|
21 |
-
*
|
22 |
-
* pointer => required, unique identifier of the pointer
|
23 |
-
* id => required, the pointer will be attached to this html id
|
24 |
-
* position => optional array, if used both sub parameters are required
|
25 |
-
* edge => 'top' or 'bottom'
|
26 |
-
* align => 'right' or 'left'
|
27 |
-
* width => optional, the width in px
|
28 |
-
* title => required, title
|
29 |
-
* content => required, content
|
30 |
-
* buttons => optional array of arrays, by default the pointer uses the standard dismiss button offered by WP
|
31 |
-
* label => the label of the button
|
32 |
-
* link => optional link for the button. By default, the button just dismisses the pointer
|
33 |
-
*
|
34 |
-
* @since 1.7.7
|
35 |
-
*
|
36 |
-
* @param array $args
|
37 |
-
*/
|
38 |
-
public function __construct( $args ) {
|
39 |
-
trigger_error( 'The class PLL_Pointer has been deprecated since Polylang 2.3.9 and will be removed in a future version.', E_USER_ERROR ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
40 |
-
|
41 |
-
$this->args = $args;
|
42 |
-
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Enqueue javascripts and styles if the pointer has not been dismissed
|
47 |
-
*
|
48 |
-
* @since 1.7.7
|
49 |
-
*/
|
50 |
-
public function enqueue_scripts() {
|
51 |
-
$dismissed = explode( ',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
52 |
-
if ( in_array( $this->args['pointer'], $dismissed ) || ! current_user_can( 'manage_options' ) ) {
|
53 |
-
return;
|
54 |
-
}
|
55 |
-
|
56 |
-
// Add pointer javascript
|
57 |
-
add_action( 'admin_print_footer_scripts', array( $this, 'print_js' ) );
|
58 |
-
|
59 |
-
wp_enqueue_style( 'wp-pointer' );
|
60 |
-
wp_enqueue_script( 'wp-pointer' );
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Adds the javascript of our pointer to the page
|
65 |
-
*
|
66 |
-
* @since 1.7.7
|
67 |
-
*/
|
68 |
-
public function print_js() {
|
69 |
-
|
70 |
-
// Add optional buttons
|
71 |
-
if ( ! empty( $this->args['buttons'] ) ) {
|
72 |
-
$b = "
|
73 |
-
var widget = pointer.pointer( 'widget' );
|
74 |
-
var buttons = $( '.wp-pointer-buttons', widget );
|
75 |
-
$( 'a.close', widget ).remove();"; // removes the WP button
|
76 |
-
|
77 |
-
// All the buttons use the standard WP ajax action to remember the pointer has been dismissed
|
78 |
-
foreach ( $this->args['buttons'] as $button ) {
|
79 |
-
$b .= sprintf(
|
80 |
-
"$( '<a>' ).addClass( '%s' ).html( '%s' ).css( 'margin-left', '10px' ).click( function() {
|
81 |
-
$.post( ajaxurl, {
|
82 |
-
pointer: '%s',
|
83 |
-
action: 'dismiss-wp-pointer'
|
84 |
-
}, function( response ) {
|
85 |
-
%s
|
86 |
-
} );
|
87 |
-
} ).appendTo( buttons );",
|
88 |
-
empty( $button['link'] ) ? 'button' : 'button button-primary',
|
89 |
-
esc_html( $button['label'] ),
|
90 |
-
$this->args['pointer'],
|
91 |
-
empty( $button['link'] ) ? "pointer.pointer( 'close' )" : sprintf( "location.href = '%s'", $button['link'] )
|
92 |
-
);
|
93 |
-
}
|
94 |
-
}
|
95 |
-
|
96 |
-
$js = sprintf(
|
97 |
-
"//<![CDATA[
|
98 |
-
jQuery( document ).ready( function( $ ) {
|
99 |
-
var pointer = $( '#%s' ).pointer( {
|
100 |
-
content: '%s',
|
101 |
-
%s
|
102 |
-
%s
|
103 |
-
} );
|
104 |
-
pointer.pointer( 'open' );
|
105 |
-
%s
|
106 |
-
} );
|
107 |
-
// ]]>",
|
108 |
-
$this->args['id'],
|
109 |
-
sprintf( '<h3>%s</h3><p>%s</p>', esc_html( $this->args['title'] ), esc_html( $this->args['content'] ) ),
|
110 |
-
empty( $this->args['position'] ) ? '' : sprintf( 'position: {edge: "%s", align: "%s",},', $this->args['position']['edge'], $this->args['position']['align'] ),
|
111 |
-
empty( $this->args['width'] ) ? '' : sprintf( 'pointerWidth: %d,', $this->args['width'] ),
|
112 |
-
empty( $b ) ? '' : $b
|
113 |
-
);
|
114 |
-
echo '<script type="text/javascript">' . $js . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput
|
115 |
-
}
|
116 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
include/query.php
CHANGED
@@ -9,19 +9,53 @@
|
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
class PLL_Query {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Constructor
|
14 |
*
|
15 |
* @since 2.2
|
16 |
*
|
17 |
-
* @param
|
18 |
-
* @param
|
19 |
*/
|
20 |
public function __construct( &$query, &$model ) {
|
21 |
$this->query = &$query;
|
22 |
$this->model = &$model;
|
23 |
}
|
24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/**
|
26 |
* Check if translated taxonomy is queried
|
27 |
* Compatible with nested queries introduced in WP 4.1
|
@@ -62,12 +96,13 @@ class PLL_Query {
|
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
-
* Sets the language in query
|
66 |
-
* Optimized for (
|
67 |
*
|
68 |
* @since 2.2
|
69 |
*
|
70 |
-
* @param
|
|
|
71 |
*/
|
72 |
public function set_language( $lang ) {
|
73 |
// Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
|
@@ -98,21 +133,22 @@ class PLL_Query {
|
|
98 |
}
|
99 |
|
100 |
/**
|
101 |
-
*
|
102 |
*
|
103 |
* @since 2.2
|
104 |
*
|
105 |
-
* @param
|
|
|
106 |
*/
|
107 |
public function filter_query( $lang ) {
|
108 |
$qvars = &$this->query->query_vars;
|
109 |
|
110 |
-
if ( !
|
111 |
$taxonomies = array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) );
|
112 |
|
113 |
foreach ( $taxonomies as $tax ) {
|
114 |
-
$
|
115 |
-
if ( ! empty( $qvars[ $
|
116 |
return;
|
117 |
}
|
118 |
}
|
@@ -128,7 +164,7 @@ class PLL_Query {
|
|
128 |
if ( $taxonomies && ( empty( $qvars['post_type'] ) || 'any' === $qvars['post_type'] ) ) {
|
129 |
foreach ( $taxonomies as $taxonomy ) {
|
130 |
$tax_object = get_taxonomy( $taxonomy );
|
131 |
-
if ( $this->model->is_translated_post_type( $tax_object->object_type ) ) {
|
132 |
$this->set_language( $lang );
|
133 |
break;
|
134 |
}
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
class PLL_Query {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
+
public $model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var WP_Query
|
19 |
+
*/
|
20 |
+
public $query;
|
21 |
+
|
22 |
/**
|
23 |
* Constructor
|
24 |
*
|
25 |
* @since 2.2
|
26 |
*
|
27 |
+
* @param WP_Query $query Reference to the WP_Query object.
|
28 |
+
* @param PLL_Model $model Instance of PLL_Model.
|
29 |
*/
|
30 |
public function __construct( &$query, &$model ) {
|
31 |
$this->query = &$query;
|
32 |
$this->model = &$model;
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* Checks if the query already includes a language taxonomy.
|
37 |
+
*
|
38 |
+
* @since 3.0
|
39 |
+
*
|
40 |
+
* @param array $qvars WP_Query query vars.
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
protected function is_already_filtered( $qvars ) {
|
44 |
+
if ( isset( $qvars['lang'] ) ) {
|
45 |
+
return true;
|
46 |
+
}
|
47 |
+
|
48 |
+
if ( ! empty( $qvars['tax_query'] ) && is_array( $qvars['tax_query'] ) ) {
|
49 |
+
foreach ( $qvars['tax_query'] as $tax_query ) {
|
50 |
+
if ( isset( $tax_query['taxonomy'] ) && 'language' === $tax_query['taxonomy'] ) {
|
51 |
+
return true;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
|
59 |
/**
|
60 |
* Check if translated taxonomy is queried
|
61 |
* Compatible with nested queries introduced in WP 4.1
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
+
* Sets the language in query.
|
100 |
+
* Optimized for (and requires) WP 3.5+.
|
101 |
*
|
102 |
* @since 2.2
|
103 |
*
|
104 |
+
* @param PLL_Language $lang Language object.
|
105 |
+
* @return void
|
106 |
*/
|
107 |
public function set_language( $lang ) {
|
108 |
// Defining directly the tax_query ( rather than setting 'lang' avoids transforming the query by WP )
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* Adds the language in the query after it has checked that it won't conflict with other query vars.
|
137 |
*
|
138 |
* @since 2.2
|
139 |
*
|
140 |
+
* @param PLL_Language $lang Language.
|
141 |
+
* @return void
|
142 |
*/
|
143 |
public function filter_query( $lang ) {
|
144 |
$qvars = &$this->query->query_vars;
|
145 |
|
146 |
+
if ( ! $this->is_already_filtered( $qvars ) ) {
|
147 |
$taxonomies = array_intersect( $this->model->get_translated_taxonomies(), get_taxonomies( array( '_builtin' => false ) ) );
|
148 |
|
149 |
foreach ( $taxonomies as $tax ) {
|
150 |
+
$tax_object = get_taxonomy( $tax );
|
151 |
+
if ( ! empty( $tax_object ) && ! empty( $qvars[ $tax_object->query_var ] ) ) {
|
152 |
return;
|
153 |
}
|
154 |
}
|
164 |
if ( $taxonomies && ( empty( $qvars['post_type'] ) || 'any' === $qvars['post_type'] ) ) {
|
165 |
foreach ( $taxonomies as $taxonomy ) {
|
166 |
$tax_object = get_taxonomy( $taxonomy );
|
167 |
+
if ( ! empty( $tax_object ) && $this->model->is_translated_post_type( $tax_object->object_type ) ) {
|
168 |
$this->set_language( $lang );
|
169 |
break;
|
170 |
}
|
include/rest-request.php
CHANGED
@@ -4,29 +4,48 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* REST API
|
8 |
-
* accessible as $polylang global object
|
9 |
-
*
|
10 |
-
* Properties:
|
11 |
-
* options => inherited, reference to Polylang options array
|
12 |
-
* model => inherited, reference to PLL_Model object
|
13 |
-
* links_model => inherited, reference to PLL_Links_Model object
|
14 |
-
* links => reference to PLL_Admin_Links object
|
15 |
-
* static_pages => reference to PLL_Static_Pages object
|
16 |
-
* filters => reference to PLL_Frontend_Filters object
|
17 |
-
* filters_links => reference to PLL_Filters_Links object
|
18 |
-
* posts => reference to PLL_CRUD_Posts object
|
19 |
-
* terms => reference to PLL_CRUD_Terms object
|
20 |
*
|
21 |
* @since 2.6
|
22 |
*/
|
23 |
class PLL_REST_Request extends PLL_Base {
|
24 |
-
public $links, $static_pages, $posts, $terms, $filters, $filters_links;
|
25 |
|
26 |
/**
|
27 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
*
|
29 |
* @since 2.6
|
|
|
|
|
30 |
*/
|
31 |
public function init() {
|
32 |
parent::init();
|
@@ -38,15 +57,16 @@ class PLL_REST_Request extends PLL_Base {
|
|
38 |
|
39 |
$this->filters_links = new PLL_Filters_Links( $this );
|
40 |
$this->filters = new PLL_Filters( $this );
|
|
|
41 |
|
42 |
-
// Static front page and page for posts
|
43 |
if ( 'page' === get_option( 'show_on_front' ) ) {
|
44 |
$this->static_pages = new PLL_Static_Pages( $this );
|
45 |
}
|
46 |
|
47 |
$this->links = new PLL_Admin_Links( $this );
|
48 |
|
49 |
-
$this->nav_menu = new PLL_Nav_Menu( $this ); // For auto added pages to menu
|
50 |
}
|
51 |
}
|
52 |
}
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Main Polylang class for REST API requrests, accessible from @see PLL().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
* @since 2.6
|
10 |
*/
|
11 |
class PLL_REST_Request extends PLL_Base {
|
|
|
12 |
|
13 |
/**
|
14 |
+
* @var PLL_Filters
|
15 |
+
*/
|
16 |
+
public $filters;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var PLL_Filters_Links
|
20 |
+
*/
|
21 |
+
public $filters_links;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var PLL_Admin_Links
|
25 |
+
*/
|
26 |
+
public $links;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var PLL_Nav_Menu
|
30 |
+
*/
|
31 |
+
public $nav_menu;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var PLL_Static_Pages
|
35 |
+
*/
|
36 |
+
public $static_pages;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var PLL_Filters_Widgets_Options
|
40 |
+
*/
|
41 |
+
public $filters_widgets;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Setup filters.
|
45 |
*
|
46 |
* @since 2.6
|
47 |
+
*
|
48 |
+
* @return void
|
49 |
*/
|
50 |
public function init() {
|
51 |
parent::init();
|
57 |
|
58 |
$this->filters_links = new PLL_Filters_Links( $this );
|
59 |
$this->filters = new PLL_Filters( $this );
|
60 |
+
$this->filters_widgets = new PLL_Filters_Widgets_Options( $this );
|
61 |
|
62 |
+
// Static front page and page for posts.
|
63 |
if ( 'page' === get_option( 'show_on_front' ) ) {
|
64 |
$this->static_pages = new PLL_Static_Pages( $this );
|
65 |
}
|
66 |
|
67 |
$this->links = new PLL_Admin_Links( $this );
|
68 |
|
69 |
+
$this->nav_menu = new PLL_Nav_Menu( $this ); // For auto added pages to menu.
|
70 |
}
|
71 |
}
|
72 |
}
|
include/static-pages.php
CHANGED
@@ -9,8 +9,38 @@
|
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Static_Pages {
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor: setups filters and actions
|
@@ -45,6 +75,8 @@ class PLL_Static_Pages {
|
|
45 |
* Stores the page on front and page for posts ids
|
46 |
*
|
47 |
* @since 1.8
|
|
|
|
|
48 |
*/
|
49 |
public function init() {
|
50 |
if ( 'page' == get_option( 'show_on_front' ) ) {
|
@@ -75,12 +107,13 @@ class PLL_Static_Pages {
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
-
* Adds page_on_front and page_for_posts properties to the language objects
|
79 |
*
|
80 |
* @since 1.8
|
81 |
*
|
82 |
-
* @param
|
83 |
-
* @param
|
|
|
84 |
*/
|
85 |
public static function pll_languages_list( $languages, $model ) {
|
86 |
if ( 'page' === get_option( 'show_on_front' ) ) {
|
@@ -114,6 +147,7 @@ class PLL_Static_Pages {
|
|
114 |
*
|
115 |
* @param int $post_id The post ID.
|
116 |
* @param string $url The requested URL.
|
|
|
117 |
*/
|
118 |
public function oembed_request_post_id( $post_id, $url ) {
|
119 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
class PLL_Static_Pages {
|
12 |
+
/**
|
13 |
+
* Id of the page on front.
|
14 |
+
*
|
15 |
+
* @var int
|
16 |
+
*/
|
17 |
+
public $page_on_front;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Id of the page for posts.
|
21 |
+
*
|
22 |
+
* @var int
|
23 |
+
*/
|
24 |
+
public $page_for_posts;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Stores the plugin options.
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
*/
|
31 |
+
protected $options;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var PLL_Model
|
35 |
+
*/
|
36 |
+
protected $model;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Current language.
|
40 |
+
*
|
41 |
+
* @var PLL_Language
|
42 |
+
*/
|
43 |
+
protected $curlang;
|
44 |
|
45 |
/**
|
46 |
* Constructor: setups filters and actions
|
75 |
* Stores the page on front and page for posts ids
|
76 |
*
|
77 |
* @since 1.8
|
78 |
+
*
|
79 |
+
* @return void
|
80 |
*/
|
81 |
public function init() {
|
82 |
if ( 'page' == get_option( 'show_on_front' ) ) {
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
+
* Adds page_on_front and page_for_posts properties to the language objects.
|
111 |
*
|
112 |
* @since 1.8
|
113 |
*
|
114 |
+
* @param PLL_Language[] $languages The list of languages.
|
115 |
+
* @param PLL_Model $model The instance of PLL_Model.
|
116 |
+
* @return PLL_Language[]
|
117 |
*/
|
118 |
public static function pll_languages_list( $languages, $model ) {
|
119 |
if ( 'page' === get_option( 'show_on_front' ) ) {
|
147 |
*
|
148 |
* @param int $post_id The post ID.
|
149 |
* @param string $url The requested URL.
|
150 |
+
* @return int
|
151 |
*/
|
152 |
public function oembed_request_post_id( $post_id, $url ) {
|
153 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
include/switcher.php
CHANGED
@@ -9,6 +9,27 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Switcher {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
* Returns options available for the language switcher - menu or widget
|
@@ -33,29 +54,80 @@ class PLL_Switcher {
|
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
*
|
38 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
*
|
40 |
* @since 1.2
|
41 |
*
|
42 |
-
* @param
|
43 |
-
* @
|
44 |
-
* @return array
|
45 |
*/
|
46 |
-
protected function get_elements( $
|
47 |
$first = true;
|
48 |
$out = array();
|
49 |
|
50 |
-
foreach ( $links->model->get_languages_list( array( 'hide_empty' => $args['hide_if_empty'] ) ) as $language ) {
|
51 |
$id = (int) $language->term_id;
|
52 |
$order = (int) $language->term_group;
|
53 |
$slug = $language->slug;
|
54 |
$locale = $language->get_locale( 'display' );
|
55 |
$classes = array( 'lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr( $slug ) );
|
56 |
-
$
|
57 |
-
$curlang = 0 === $args['admin_render'] ? $links->curlang->slug : $args['admin_current_lang'];
|
58 |
-
$current_lang = $curlang == $slug;
|
59 |
|
60 |
if ( $current_lang ) {
|
61 |
if ( $args['hide_current'] && ! ( $args['dropdown'] && ! $args['raw'] ) ) {
|
@@ -65,11 +137,7 @@ class PLL_Switcher {
|
|
65 |
}
|
66 |
}
|
67 |
|
68 |
-
|
69 |
-
$url = get_permalink( $tr_id );
|
70 |
-
} elseif ( null === $args['post_id'] && 0 === $args['admin_render'] ) {
|
71 |
-
$url = $links->get_translation_url( $language );
|
72 |
-
}
|
73 |
|
74 |
if ( $no_translation = empty( $url ) ) {
|
75 |
$classes[] = 'no-translation';
|
@@ -80,9 +148,9 @@ class PLL_Switcher {
|
|
80 |
*
|
81 |
* @since 0.7
|
82 |
*
|
83 |
-
* @param string $url
|
84 |
-
* @param string
|
85 |
-
* @param string
|
86 |
*/
|
87 |
$url = apply_filters( 'pll_the_language_link', $url, $slug, $language->locale );
|
88 |
|
@@ -91,7 +159,7 @@ class PLL_Switcher {
|
|
91 |
continue;
|
92 |
}
|
93 |
|
94 |
-
$url = empty( $url ) || $args['force_home'] ? $links->get_home_url( $language ) : $url; // If the page is not translated, link to the home page
|
95 |
|
96 |
$name = $args['show_names'] || ! $args['show_flags'] || $args['raw'] ? ( 'slug' == $args['display_names_as'] ? $slug : $language->name ) : '';
|
97 |
$flag = $args['raw'] && ! $args['show_flags'] ? $language->get_display_flag_url() : ( $args['show_flags'] ? $language->get_display_flag() : '' );
|
@@ -109,50 +177,34 @@ class PLL_Switcher {
|
|
109 |
|
110 |
/**
|
111 |
* Displays a language switcher
|
112 |
-
* or returns the raw elements to build a custom language switcher
|
113 |
-
*
|
114 |
-
* List of parameters accepted in $args:
|
115 |
-
*
|
116 |
-
* dropdown => the list is displayed as dropdown if set, defaults to 0
|
117 |
-
* echo => echoes the list if set to 1, defaults to 1
|
118 |
-
* hide_if_empty => hides languages with no posts ( or pages ) if set to 1, defaults to 1
|
119 |
-
* show_flags => displays flags if set to 1, defaults to 0
|
120 |
-
* show_names => show language names if set to 1, defaults to 1
|
121 |
-
* display_names_as => whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name
|
122 |
-
* force_home => will always link to home in translated language if set to 1, defaults to 0
|
123 |
-
* hide_if_no_translation => hide the link if there is no translation if set to 1, defaults to 0
|
124 |
-
* hide_current => hide the current language if set to 1, defaults to 0
|
125 |
-
* post_id => returns links to translations of post defined by post_id if set, defaults not set
|
126 |
-
* raw => return a raw array instead of html markup if set to 1, defaults to 0
|
127 |
-
* item_spacing => whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to preserve
|
128 |
-
* admin_render => allows to force the current language code in an admin context if set, default to 0. Need to set the admin_current_lang argument below
|
129 |
-
* admin_current_lang => the current language code in an admin context. Need to set the admin_render to 1, defaults not set
|
130 |
*
|
131 |
* @since 0.1
|
132 |
*
|
133 |
-
* @param
|
134 |
-
* @param array
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
* @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher
|
136 |
*/
|
137 |
-
public function the_languages( $links, $args =
|
138 |
-
$
|
139 |
-
|
140 |
-
'echo' => 1, // echoes the list
|
141 |
-
'hide_if_empty' => 1, // hides languages with no posts ( or pages )
|
142 |
-
'menu' => 0, // not for nav menu ( this argument is deprecated since v1.1.1 )
|
143 |
-
'show_flags' => 0, // don't show flags
|
144 |
-
'show_names' => 1, // show language names
|
145 |
-
'display_names_as' => 'name', // valid options are slug and name
|
146 |
-
'force_home' => 0, // tries to find a translation
|
147 |
-
'hide_if_no_translation' => 0, // don't hide the link if there is no translation
|
148 |
-
'hide_current' => 0, // don't hide current language
|
149 |
-
'post_id' => null, // if not null, link to translations of post defined by post_id
|
150 |
-
'raw' => 0, // set this to true to build your own custom language switcher
|
151 |
-
'item_spacing' => 'preserve', // 'preserve' or 'discard' whitespace between list items
|
152 |
-
'admin_render' => 0, // make the switcher in an frontend context
|
153 |
-
'admin_current_lang' => null, // use when admin_render is set to 1, if not null use it instead of the current language
|
154 |
-
);
|
155 |
-
$args = wp_parse_args( $args, $defaults );
|
156 |
|
157 |
/**
|
158 |
* Filter the arguments of the 'pll_the_languages' template tag
|
@@ -168,7 +220,7 @@ class PLL_Switcher {
|
|
168 |
$args['show_names'] = 1;
|
169 |
}
|
170 |
|
171 |
-
$elements = $this->get_elements( $
|
172 |
|
173 |
if ( $args['raw'] ) {
|
174 |
return $elements;
|
@@ -177,9 +229,8 @@ class PLL_Switcher {
|
|
177 |
if ( $args['dropdown'] ) {
|
178 |
$args['name'] = 'lang_choice_' . $args['dropdown'];
|
179 |
$walker = new PLL_Walker_Dropdown();
|
180 |
-
$args['selected'] =
|
181 |
-
}
|
182 |
-
else {
|
183 |
$walker = new PLL_Walker_List();
|
184 |
}
|
185 |
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Switcher {
|
12 |
+
const DEFAULTS = array(
|
13 |
+
'dropdown' => 0, // Display as list and not as dropdown.
|
14 |
+
'echo' => 1, // Echoes the list.
|
15 |
+
'hide_if_empty' => 1, // Hides languages with no posts (or pages).
|
16 |
+
'show_flags' => 0, // Don't show flags.
|
17 |
+
'show_names' => 1, // Show language names.
|
18 |
+
'display_names_as' => 'name', // Display the language name.
|
19 |
+
'force_home' => 0, // Tries to find a translation.
|
20 |
+
'hide_if_no_translation' => 0, // Don't hide the link if there is no translation.
|
21 |
+
'hide_current' => 0, // Don't hide the current language.
|
22 |
+
'post_id' => null, // Link to the translations of the current page.
|
23 |
+
'raw' => 0, // Build the language switcher.
|
24 |
+
'item_spacing' => 'preserve', // Preserve whitespace between list items.
|
25 |
+
'admin_render' => 0, // Make the switcher in a frontend context.
|
26 |
+
'admin_current_lang' => null, // Use the global current language.
|
27 |
+
);
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var PLL_Links
|
31 |
+
*/
|
32 |
+
protected $links;
|
33 |
|
34 |
/**
|
35 |
* Returns options available for the language switcher - menu or widget
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
+
* Returns the current language code.
|
58 |
+
*
|
59 |
+
* @since 3.0
|
60 |
+
*
|
61 |
+
* @param array $args Arguments passed to {@see PLL_Switcher::the_languages()}.
|
62 |
+
* @return string
|
63 |
+
*/
|
64 |
+
protected function get_current_language( $args ) {
|
65 |
+
if ( $args['admin_current_lang'] ) {
|
66 |
+
return $args['admin_current_lang'];
|
67 |
+
}
|
68 |
+
|
69 |
+
if ( isset( $this->links->curlang ) ) {
|
70 |
+
return $this->links->curlang->slug;
|
71 |
+
}
|
72 |
+
|
73 |
+
return $this->links->options['default_lang'];
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Returns the link for a given language.
|
78 |
*
|
79 |
+
* @since 3.0
|
80 |
+
*
|
81 |
+
* @param PLL_Language $language Language.
|
82 |
+
* @param array $args Arguments passed to {@see PLL_Switcher::the_languages()}.
|
83 |
+
* @return string|null
|
84 |
+
*/
|
85 |
+
protected function get_link( $language, $args ) {
|
86 |
+
global $post;
|
87 |
+
|
88 |
+
// Priority to the post passed in parameters.
|
89 |
+
if ( null !== $args['post_id'] ) {
|
90 |
+
$tr_id = $this->links->model->post->get( $args['post_id'], $language );
|
91 |
+
if ( $tr_id && $this->links->model->post->current_user_can_read( $tr_id ) ) {
|
92 |
+
return get_permalink( $tr_id );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
// If we are on frontend.
|
97 |
+
if ( $this->links instanceof PLL_Frontend_Links ) {
|
98 |
+
return $this->links->get_translation_url( $language );
|
99 |
+
}
|
100 |
+
|
101 |
+
// For blocks in posts in REST requests.
|
102 |
+
if ( $post instanceof WP_Post ) {
|
103 |
+
$tr_id = $this->links->model->post->get( $post->ID, $language );
|
104 |
+
if ( $tr_id && $this->links->model->post->current_user_can_read( $tr_id ) ) {
|
105 |
+
return get_permalink( $tr_id );
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
return null;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Get the language elements for use in a walker
|
114 |
*
|
115 |
* @since 1.2
|
116 |
*
|
117 |
+
* @param array $args Arguments passed to {@see PLL_Switcher::the_languages()}.
|
118 |
+
* @return array Language switcher elements.
|
|
|
119 |
*/
|
120 |
+
protected function get_elements( $args ) {
|
121 |
$first = true;
|
122 |
$out = array();
|
123 |
|
124 |
+
foreach ( $this->links->model->get_languages_list( array( 'hide_empty' => $args['hide_if_empty'] ) ) as $language ) {
|
125 |
$id = (int) $language->term_id;
|
126 |
$order = (int) $language->term_group;
|
127 |
$slug = $language->slug;
|
128 |
$locale = $language->get_locale( 'display' );
|
129 |
$classes = array( 'lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr( $slug ) );
|
130 |
+
$current_lang = $this->get_current_language( $args ) === $slug;
|
|
|
|
|
131 |
|
132 |
if ( $current_lang ) {
|
133 |
if ( $args['hide_current'] && ! ( $args['dropdown'] && ! $args['raw'] ) ) {
|
137 |
}
|
138 |
}
|
139 |
|
140 |
+
$url = $this->get_link( $language, $args );
|
|
|
|
|
|
|
|
|
141 |
|
142 |
if ( $no_translation = empty( $url ) ) {
|
143 |
$classes[] = 'no-translation';
|
148 |
*
|
149 |
* @since 0.7
|
150 |
*
|
151 |
+
* @param string|null $url The link, null if no translation was found.
|
152 |
+
* @param string $slug The language code.
|
153 |
+
* @param string $locale The language locale
|
154 |
*/
|
155 |
$url = apply_filters( 'pll_the_language_link', $url, $slug, $language->locale );
|
156 |
|
159 |
continue;
|
160 |
}
|
161 |
|
162 |
+
$url = empty( $url ) || $args['force_home'] ? $this->links->get_home_url( $language ) : $url; // If the page is not translated, link to the home page
|
163 |
|
164 |
$name = $args['show_names'] || ! $args['show_flags'] || $args['raw'] ? ( 'slug' == $args['display_names_as'] ? $slug : $language->name ) : '';
|
165 |
$flag = $args['raw'] && ! $args['show_flags'] ? $language->get_display_flag_url() : ( $args['show_flags'] ? $language->get_display_flag() : '' );
|
177 |
|
178 |
/**
|
179 |
* Displays a language switcher
|
180 |
+
* or returns the raw elements to build a custom language switcher.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
*
|
182 |
* @since 0.1
|
183 |
*
|
184 |
+
* @param PLL_Links $links Instance of PLL_Links.
|
185 |
+
* @param array $args {
|
186 |
+
* Optional array of arguments.
|
187 |
+
*
|
188 |
+
* @type int $dropdown The list is displayed as dropdown if set, defaults to 0.
|
189 |
+
* @type int $echo Echoes the list if set to 1, defaults to 1.
|
190 |
+
* @type int $hide_if_empty Hides languages with no posts ( or pages ) if set to 1, defaults to 1.
|
191 |
+
* @type int $show_flags Displays flags if set to 1, defaults to 0.
|
192 |
+
* @type int $show_names Shows language names if set to 1, defaults to 1.
|
193 |
+
* @type string $display_names_as Whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name.
|
194 |
+
* @type int $force_home Will always link to home in translated language if set to 1, defaults to 0.
|
195 |
+
* @type int $hide_if_no_translation Hides the link if there is no translation if set to 1, defaults to 0.
|
196 |
+
* @type int $hide_current Hides the current language if set to 1, defaults to 0.
|
197 |
+
* @type int $post_id Returns links to the translations of the post defined by post_id if set, defaults not set.
|
198 |
+
* @type int $raw Return a raw array instead of html markup if set to 1, defaults to 0.
|
199 |
+
* @type string $item_spacing Whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to 'preserve'.
|
200 |
+
* @type int $admin_render Allows to force the current language code in an admin context if set, default to 0. Need to set the admin_current_lang argument below.
|
201 |
+
* @type string $admin_current_lang The current language code in an admin context. Need to set the admin_render to 1, defaults not set.
|
202 |
+
* }
|
203 |
* @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher
|
204 |
*/
|
205 |
+
public function the_languages( $links, $args = array() ) {
|
206 |
+
$this->links = $links;
|
207 |
+
$args = wp_parse_args( $args, self::DEFAULTS );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
|
209 |
/**
|
210 |
* Filter the arguments of the 'pll_the_languages' template tag
|
220 |
$args['show_names'] = 1;
|
221 |
}
|
222 |
|
223 |
+
$elements = $this->get_elements( $args );
|
224 |
|
225 |
if ( $args['raw'] ) {
|
226 |
return $elements;
|
229 |
if ( $args['dropdown'] ) {
|
230 |
$args['name'] = 'lang_choice_' . $args['dropdown'];
|
231 |
$walker = new PLL_Walker_Dropdown();
|
232 |
+
$args['selected'] = $this->get_current_language( $args );
|
233 |
+
} else {
|
|
|
234 |
$walker = new PLL_Walker_List();
|
235 |
}
|
236 |
|
include/translate-option.php
CHANGED
@@ -31,21 +31,22 @@ class PLL_Translate_Option {
|
|
31 |
* @since 2.9
|
32 |
*
|
33 |
* @param string $name Option name.
|
34 |
-
* @param
|
35 |
-
*
|
36 |
-
*
|
37 |
-
*
|
38 |
-
*
|
39 |
-
*
|
40 |
-
*
|
41 |
-
*
|
42 |
-
*
|
43 |
-
* Note: only keys are interpreted. Any scalar can be used as values.
|
44 |
-
* @param string $args {
|
45 |
-
* Optional. Array of arguments for registering the option.
|
46 |
*
|
47 |
-
*
|
48 |
-
*
|
|
|
|
|
|
|
|
|
49 |
* }
|
50 |
*/
|
51 |
public function __construct( $name, $keys = array(), $args = array() ) {
|
@@ -86,8 +87,8 @@ class PLL_Translate_Option {
|
|
86 |
*
|
87 |
* @since 1.0
|
88 |
*
|
89 |
-
* @param
|
90 |
-
* @param array|bool
|
91 |
* @return array|string Translated string(s)
|
92 |
*/
|
93 |
protected function translate_string_recursive( $values, $key ) {
|
@@ -136,8 +137,9 @@ class PLL_Translate_Option {
|
|
136 |
*
|
137 |
* @param string $context The group in which the strings will be registered.
|
138 |
* @param string $option Option name.
|
139 |
-
* @param
|
140 |
* @param array|bool $key Array of option keys to translate.
|
|
|
141 |
*/
|
142 |
protected function register_string_recursive( $context, $option, $values, $key ) {
|
143 |
if ( is_object( $values ) ) {
|
@@ -186,11 +188,12 @@ class PLL_Translate_Option {
|
|
186 |
* @param mixed $value The new, unserialized option value.
|
187 |
* @param mixed $old_value The old (filtered) option value.
|
188 |
* @param string $name Option name.
|
|
|
189 |
*/
|
190 |
public function pre_update_option( $value, $old_value, $name ) {
|
191 |
// Stores the unfiltered old option value before it is updated in DB.
|
192 |
remove_filter( 'option_' . $name, array( $this, 'translate' ), 10, 2 );
|
193 |
-
$
|
194 |
add_filter( 'option_' . $name, array( $this, 'translate' ), 20, 2 );
|
195 |
|
196 |
// Load strings translations according to the admin language filter
|
@@ -201,7 +204,7 @@ class PLL_Translate_Option {
|
|
201 |
PLL()->load_strings_translations( $locale );
|
202 |
|
203 |
// Filters out the strings which would be updated to their translations and stores the updated strings.
|
204 |
-
$value = $this->check_value_recursive( $
|
205 |
|
206 |
return $value;
|
207 |
}
|
@@ -214,6 +217,8 @@ class PLL_Translate_Option {
|
|
214 |
* the new strings with the old translations.
|
215 |
*
|
216 |
* @since 2.9
|
|
|
|
|
217 |
*/
|
218 |
public function update_option() {
|
219 |
$curlang = pll_current_language();
|
31 |
* @since 2.9
|
32 |
*
|
33 |
* @param string $name Option name.
|
34 |
+
* @param array $keys Recursive array of option keys to translate in the form:
|
35 |
+
* @example array(
|
36 |
+
* 'option_key_to_translate_1' => 1,
|
37 |
+
* 'option_key_to_translate_2' => 1,
|
38 |
+
* 'my_group' => array(
|
39 |
+
* 'sub_key_to_translate_1' => 1,
|
40 |
+
* 'sub_key_to_translate_2' => 1,
|
41 |
+
* ),
|
42 |
+
* )
|
|
|
|
|
|
|
43 |
*
|
44 |
+
* Note: only keys are interpreted. Any scalar can be used as values.
|
45 |
+
* @param array $args {
|
46 |
+
* Optional. Array of arguments for registering the option.
|
47 |
+
*
|
48 |
+
* @type string $context The group in which the strings will be registered.
|
49 |
+
* @type string $sanitize_callback A callback function that sanitizes the option's value.
|
50 |
* }
|
51 |
*/
|
52 |
public function __construct( $name, $keys = array(), $args = array() ) {
|
87 |
*
|
88 |
* @since 1.0
|
89 |
*
|
90 |
+
* @param mixed $values Either a string to translate or a list of strings to translate.
|
91 |
+
* @param array|bool $key Array of option keys to translate.
|
92 |
* @return array|string Translated string(s)
|
93 |
*/
|
94 |
protected function translate_string_recursive( $values, $key ) {
|
137 |
*
|
138 |
* @param string $context The group in which the strings will be registered.
|
139 |
* @param string $option Option name.
|
140 |
+
* @param mixed $values Option value.
|
141 |
* @param array|bool $key Array of option keys to translate.
|
142 |
+
* @return void
|
143 |
*/
|
144 |
protected function register_string_recursive( $context, $option, $values, $key ) {
|
145 |
if ( is_object( $values ) ) {
|
188 |
* @param mixed $value The new, unserialized option value.
|
189 |
* @param mixed $old_value The old (filtered) option value.
|
190 |
* @param string $name Option name.
|
191 |
+
* @return mixed
|
192 |
*/
|
193 |
public function pre_update_option( $value, $old_value, $name ) {
|
194 |
// Stores the unfiltered old option value before it is updated in DB.
|
195 |
remove_filter( 'option_' . $name, array( $this, 'translate' ), 10, 2 );
|
196 |
+
$unfiltered_old_value = get_option( $name );
|
197 |
add_filter( 'option_' . $name, array( $this, 'translate' ), 20, 2 );
|
198 |
|
199 |
// Load strings translations according to the admin language filter
|
204 |
PLL()->load_strings_translations( $locale );
|
205 |
|
206 |
// Filters out the strings which would be updated to their translations and stores the updated strings.
|
207 |
+
$value = $this->check_value_recursive( $unfiltered_old_value, $value, $this->keys );
|
208 |
|
209 |
return $value;
|
210 |
}
|
217 |
* the new strings with the old translations.
|
218 |
*
|
219 |
* @since 2.9
|
220 |
+
*
|
221 |
+
* @return void
|
222 |
*/
|
223 |
public function update_option() {
|
224 |
$curlang = pll_current_language();
|
include/translated-object.php
CHANGED
@@ -4,41 +4,102 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Setups the objects languages and translations model
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
abstract class PLL_Translated_Object {
|
|
|
|
|
|
|
12 |
public $model;
|
13 |
-
protected $object_type, $type, $tax_language, $tax_translations, $tax_tt;
|
14 |
|
15 |
/**
|
16 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
*
|
18 |
* @since 1.8
|
19 |
*
|
20 |
-
* @param
|
21 |
*/
|
22 |
public function __construct( &$model ) {
|
23 |
$this->model = &$model;
|
24 |
|
25 |
-
|
26 |
-
|
|
|
|
|
27 |
$args = array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false, '_pll' => true );
|
28 |
register_taxonomy( $this->tax_language, $this->object_type, $args );
|
29 |
-
$args['update_count_callback'] = '_update_generic_term_count'; //
|
30 |
register_taxonomy( $this->tax_translations, $this->object_type, $args );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
-
*
|
35 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
*
|
37 |
* @since 1.2
|
38 |
*
|
39 |
-
* @param int $object_id post_id or term_id
|
40 |
-
* @param string $taxonomy Polylang taxonomy depending if we are looking for a post ( or term ) language ( or translation )
|
41 |
-
* @return
|
42 |
*/
|
43 |
public function get_object_term( $object_id, $taxonomy ) {
|
44 |
if ( empty( $object_id ) || is_wp_error( $object_id ) ) {
|
@@ -54,20 +115,22 @@ abstract class PLL_Translated_Object {
|
|
54 |
$term = get_object_term_cache( $object_id, $taxonomy );
|
55 |
|
56 |
if ( false === $term ) {
|
57 |
-
//
|
58 |
$taxonomies = array( $this->tax_language, $this->tax_translations );
|
59 |
|
60 |
-
//
|
61 |
$terms = array();
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
$
|
|
|
|
|
|
|
66 |
}
|
67 |
}
|
68 |
|
69 |
-
//
|
70 |
-
// set an empty cache if no term found in the taxonomy
|
71 |
foreach ( $taxonomies as $tax ) {
|
72 |
wp_cache_add( $object_id, empty( $terms[ $tax ] ) ? array() : array( $terms[ $tax ] ), $tax . '_relationships' );
|
73 |
}
|
@@ -80,66 +143,67 @@ abstract class PLL_Translated_Object {
|
|
80 |
}
|
81 |
|
82 |
/**
|
83 |
-
* Tells whether a translation term must be updated
|
84 |
*
|
85 |
* @since 2.3
|
86 |
*
|
87 |
-
* @param
|
88 |
-
* @param
|
|
|
89 |
*/
|
90 |
protected function should_update_translation_group( $id, $translations ) {
|
91 |
-
// Don't do anything if no translations have been added to the group
|
92 |
-
$old_translations = $this->get_translations( $id ); // Includes at least $id itself
|
93 |
return count( array_diff_assoc( $translations, $old_translations ) ) > 0;
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
-
* Saves translations for posts or terms
|
98 |
*
|
99 |
* @since 0.5
|
100 |
*
|
101 |
-
* @param int $id
|
102 |
-
* @param
|
|
|
103 |
*/
|
104 |
public function save_translations( $id, $translations ) {
|
105 |
$id = (int) $id;
|
106 |
|
107 |
-
if ( ( $lang = $this->get_language( $id ) ) &&
|
108 |
-
//
|
109 |
$translations = array_map( 'intval', $translations );
|
110 |
-
$translations = array_merge( array( $lang->slug => $id ), $translations ); //
|
111 |
-
$translations = array_diff( $translations, array( 0 ) ); //
|
112 |
-
$translations = array_intersect_key( $translations, array_flip( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) ); //
|
113 |
|
114 |
-
//
|
115 |
$old_translations = $this->get_translations( $id );
|
116 |
foreach ( array_diff_assoc( $old_translations, $translations ) as $object_id ) {
|
117 |
$this->delete_translation( $object_id );
|
118 |
}
|
119 |
|
120 |
-
// Check id we need to create or update the translation group
|
121 |
if ( $this->should_update_translation_group( $id, $translations ) ) {
|
122 |
$terms = wp_get_object_terms( $translations, $this->tax_translations );
|
123 |
$term = reset( $terms );
|
124 |
|
125 |
-
//
|
126 |
if ( empty( $term ) ) {
|
127 |
wp_insert_term( $group = uniqid( 'pll_' ), $this->tax_translations, array( 'description' => maybe_serialize( $translations ) ) );
|
128 |
-
}
|
129 |
-
|
130 |
-
// take care not to overwrite extra data stored in description field, if any
|
131 |
$d = maybe_unserialize( $term->description );
|
132 |
-
$d = is_array( $d ) ? array_diff_key( $d, $old_translations ) : array(); //
|
133 |
-
$d = array_merge( $d, $translations ); //
|
134 |
wp_update_term( $group = (int) $term->term_id, $this->tax_translations, array( 'description' => maybe_serialize( $d ) ) );
|
135 |
}
|
136 |
|
137 |
-
//
|
138 |
foreach ( $translations as $p ) {
|
139 |
wp_set_object_terms( $p, $group, $this->tax_translations );
|
140 |
}
|
141 |
|
142 |
-
//
|
143 |
foreach ( wp_list_pluck( $terms, 'term_id' ) as $term_id ) {
|
144 |
$term = get_term( $term_id, $this->tax_translations );
|
145 |
if ( empty( $term->count ) ) {
|
@@ -151,11 +215,12 @@ abstract class PLL_Translated_Object {
|
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
-
* Deletes a translation of a post or term
|
155 |
*
|
156 |
* @since 0.5
|
157 |
*
|
158 |
-
* @param int $id
|
|
|
159 |
*/
|
160 |
public function delete_translation( $id ) {
|
161 |
$id = (int) $id;
|
@@ -177,23 +242,23 @@ abstract class PLL_Translated_Object {
|
|
177 |
}
|
178 |
|
179 |
/**
|
180 |
-
* Returns an array of translations of a post or term
|
181 |
*
|
182 |
* @since 0.5
|
183 |
*
|
184 |
-
* @param int $id
|
185 |
-
* @return
|
186 |
*/
|
187 |
public function get_translations( $id ) {
|
188 |
$term = $this->get_object_term( $id, $this->tax_translations );
|
189 |
$translations = empty( $term ) ? array() : maybe_unserialize( $term->description );
|
190 |
|
191 |
-
//
|
192 |
if ( is_array( $translations ) ) {
|
193 |
$translations = array_intersect_key( $translations, array_flip( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) );
|
194 |
}
|
195 |
|
196 |
-
//
|
197 |
if ( empty( $translations ) && $lang = $this->get_language( $id ) ) {
|
198 |
$translations = array( $lang->slug => $id );
|
199 |
}
|
@@ -202,13 +267,13 @@ abstract class PLL_Translated_Object {
|
|
202 |
}
|
203 |
|
204 |
/**
|
205 |
-
* Returns the id of the translation of a post or term
|
206 |
*
|
207 |
* @since 0.5
|
208 |
*
|
209 |
-
* @param int
|
210 |
-
* @param
|
211 |
-
* @return
|
212 |
*/
|
213 |
public function get_translation( $id, $lang ) {
|
214 |
if ( ! $lang = $this->model->get_language( $lang ) ) {
|
@@ -225,40 +290,54 @@ abstract class PLL_Translated_Object {
|
|
225 |
*
|
226 |
* @since 0.1
|
227 |
*
|
228 |
-
* @param int
|
229 |
-
* @param int|string|
|
230 |
-
* @return
|
231 |
*/
|
232 |
public function get( $id, $lang ) {
|
233 |
$id = (int) $id;
|
234 |
-
$
|
235 |
-
|
|
|
236 |
return false;
|
237 |
}
|
238 |
|
239 |
-
$lang = $this->model->get_language( $lang );
|
240 |
return $obj_lang->term_id == $lang->term_id ? $id : $this->get_translation( $id, $lang );
|
241 |
}
|
242 |
|
243 |
/**
|
244 |
-
* A
|
245 |
*
|
246 |
* @since 1.2
|
247 |
*
|
248 |
-
* @param
|
249 |
-
* @return string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
*/
|
251 |
public function where_clause( $lang ) {
|
252 |
$tt_id = $this->tax_tt;
|
253 |
|
254 |
-
|
255 |
-
|
|
|
|
|
256 |
if ( is_object( $lang ) ) {
|
257 |
return ' AND pll_tr.term_taxonomy_id = ' . absint( $lang->$tt_id );
|
258 |
}
|
259 |
|
260 |
-
|
261 |
-
|
|
|
|
|
262 |
$slugs = is_array( $lang ) ? $lang : explode( ',', $lang );
|
263 |
$languages = array();
|
264 |
foreach ( $slugs as $slug ) {
|
@@ -269,13 +348,13 @@ abstract class PLL_Translated_Object {
|
|
269 |
}
|
270 |
|
271 |
/**
|
272 |
-
* Returns ids of objects in a language similarly to get_objects_in_term for a taxonomy
|
273 |
-
* faster than get_objects_in_term as it avoids a JOIN
|
274 |
*
|
275 |
* @since 1.4
|
276 |
*
|
277 |
-
* @param
|
278 |
-
* @return
|
279 |
*/
|
280 |
public function get_objects_in_language( $lang ) {
|
281 |
global $wpdb;
|
@@ -300,24 +379,24 @@ abstract class PLL_Translated_Object {
|
|
300 |
}
|
301 |
|
302 |
/**
|
303 |
-
* Check if a user can synchronize translations
|
304 |
*
|
305 |
* @since 2.6
|
306 |
*
|
307 |
-
* @param int $id Object id
|
308 |
* @return bool
|
309 |
*/
|
310 |
public function current_user_can_synchronize( $id ) {
|
311 |
/**
|
312 |
-
* Filters whether a synchronization capability check should take place
|
313 |
*
|
314 |
* @since 2.6
|
315 |
*
|
316 |
-
* @param $check
|
317 |
-
*
|
318 |
-
*
|
319 |
-
*
|
320 |
-
* @param $id The synchronization source object id
|
321 |
*/
|
322 |
$check = apply_filters( "pll_pre_current_user_can_synchronize_{$this->type}", true, $id );
|
323 |
if ( null !== $check ) {
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Setups the objects languages and translations model.
|
8 |
*
|
9 |
* @since 1.8
|
10 |
*/
|
11 |
abstract class PLL_Translated_Object {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
public $model;
|
|
|
16 |
|
17 |
/**
|
18 |
+
* Object type to use when registering the taxonomies.
|
19 |
+
* Left empty for posts.
|
20 |
+
*
|
21 |
+
* @var string|null
|
22 |
+
*/
|
23 |
+
protected $object_type;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Object type to use when checking capabilities.
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $type;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Taxonomy name for the languages.
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
protected $tax_language;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Taxonomy name for the translation groups.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
protected $tax_translations;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* PLL_Language property name for the term_taxonomy id.
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
protected $tax_tt;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Constructor.
|
55 |
*
|
56 |
* @since 1.8
|
57 |
*
|
58 |
+
* @param PLL_Model $model Instance of PLL_Model.
|
59 |
*/
|
60 |
public function __construct( &$model ) {
|
61 |
$this->model = &$model;
|
62 |
|
63 |
+
/*
|
64 |
+
* Register our taxonomies as soon as possible.
|
65 |
+
* This is early registration, not ready for rewrite rules as $wp_rewrite will be setup later.
|
66 |
+
*/
|
67 |
$args = array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false, '_pll' => true );
|
68 |
register_taxonomy( $this->tax_language, $this->object_type, $args );
|
69 |
+
$args['update_count_callback'] = '_update_generic_term_count'; // Count *all* objects to avoid deleting in clean_translations_terms.
|
70 |
register_taxonomy( $this->tax_translations, $this->object_type, $args );
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* Stores the language in the database.
|
75 |
+
*
|
76 |
+
* @since 0.6
|
77 |
+
*
|
78 |
+
* @param int $id Object id.
|
79 |
+
* @param int|string|PLL_Language $lang Language (term_id or slug or object).
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
+
abstract public function set_language( $id, $lang );
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Returns the language of an object.
|
86 |
+
*
|
87 |
+
* @since 0.1
|
88 |
+
*
|
89 |
+
* @param int $id Object id.
|
90 |
+
* @return PLL_Language|false PLL_Language object, false if no language is associated to that object.
|
91 |
+
*/
|
92 |
+
abstract public function get_language( $id );
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Wrap wp_get_object_terms() to cache it and return only one object.
|
96 |
+
* inspired by the WordPress function get_the_terms().
|
97 |
*
|
98 |
* @since 1.2
|
99 |
*
|
100 |
+
* @param int $object_id Object id ( typically a post_id or term_id ).
|
101 |
+
* @param string $taxonomy Polylang taxonomy depending if we are looking for a post ( or term ) language ( or translation ).
|
102 |
+
* @return WP_Term|false The term associated to the object in the requested taxonomy if it exists, false otherwise.
|
103 |
*/
|
104 |
public function get_object_term( $object_id, $taxonomy ) {
|
105 |
if ( empty( $object_id ) || is_wp_error( $object_id ) ) {
|
115 |
$term = get_object_term_cache( $object_id, $taxonomy );
|
116 |
|
117 |
if ( false === $term ) {
|
118 |
+
// Query language and translations at the same time.
|
119 |
$taxonomies = array( $this->tax_language, $this->tax_translations );
|
120 |
|
121 |
+
// Query terms.
|
122 |
$terms = array();
|
123 |
+
$object_terms = wp_get_object_terms( $object_id, $taxonomies, array( 'update_term_meta_cache' => false ) );
|
124 |
+
if ( is_array( $object_terms ) ) {
|
125 |
+
foreach ( $object_terms as $t ) {
|
126 |
+
$terms[ $t->taxonomy ] = $t;
|
127 |
+
if ( $t->taxonomy == $taxonomy ) {
|
128 |
+
$term = $t;
|
129 |
+
}
|
130 |
}
|
131 |
}
|
132 |
|
133 |
+
// Stores it the way WP expects it. Set an empty cache if no term was found in the taxonomy.
|
|
|
134 |
foreach ( $taxonomies as $tax ) {
|
135 |
wp_cache_add( $object_id, empty( $terms[ $tax ] ) ? array() : array( $terms[ $tax ] ), $tax . '_relationships' );
|
136 |
}
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
+
* Tells whether a translation term must be updated.
|
147 |
*
|
148 |
* @since 2.3
|
149 |
*
|
150 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
151 |
+
* @param int[] $translations An associative array of translations with language code as key and translation id as value.
|
152 |
+
* @return bool
|
153 |
*/
|
154 |
protected function should_update_translation_group( $id, $translations ) {
|
155 |
+
// Don't do anything if no translations have been added to the group.
|
156 |
+
$old_translations = $this->get_translations( $id ); // Includes at least $id itself.
|
157 |
return count( array_diff_assoc( $translations, $old_translations ) ) > 0;
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
+
* Saves translations for posts or terms.
|
162 |
*
|
163 |
* @since 0.5
|
164 |
*
|
165 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
166 |
+
* @param int[] $translations An associative array of translations with language code as key and translation id as value.
|
167 |
+
* @return void
|
168 |
*/
|
169 |
public function save_translations( $id, $translations ) {
|
170 |
$id = (int) $id;
|
171 |
|
172 |
+
if ( ( $lang = $this->get_language( $id ) ) && is_array( $translations ) ) {
|
173 |
+
// Sanitize the translations array.
|
174 |
$translations = array_map( 'intval', $translations );
|
175 |
+
$translations = array_merge( array( $lang->slug => $id ), $translations ); // Make sure this object is in translations.
|
176 |
+
$translations = array_diff( $translations, array( 0 ) ); // Don't keep non translated languages.
|
177 |
+
$translations = array_intersect_key( $translations, array_flip( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) ); // Keep only valid languages slugs as keys.
|
178 |
|
179 |
+
// Unlink removed translations.
|
180 |
$old_translations = $this->get_translations( $id );
|
181 |
foreach ( array_diff_assoc( $old_translations, $translations ) as $object_id ) {
|
182 |
$this->delete_translation( $object_id );
|
183 |
}
|
184 |
|
185 |
+
// Check id we need to create or update the translation group.
|
186 |
if ( $this->should_update_translation_group( $id, $translations ) ) {
|
187 |
$terms = wp_get_object_terms( $translations, $this->tax_translations );
|
188 |
$term = reset( $terms );
|
189 |
|
190 |
+
// Create a new term if necessary.
|
191 |
if ( empty( $term ) ) {
|
192 |
wp_insert_term( $group = uniqid( 'pll_' ), $this->tax_translations, array( 'description' => maybe_serialize( $translations ) ) );
|
193 |
+
} else {
|
194 |
+
// Take care not to overwrite extra data stored in the description field, if any.
|
|
|
195 |
$d = maybe_unserialize( $term->description );
|
196 |
+
$d = is_array( $d ) ? array_diff_key( $d, $old_translations ) : array(); // Remove old translations.
|
197 |
+
$d = array_merge( $d, $translations ); // Add new one.
|
198 |
wp_update_term( $group = (int) $term->term_id, $this->tax_translations, array( 'description' => maybe_serialize( $d ) ) );
|
199 |
}
|
200 |
|
201 |
+
// Link all translations to the new term.
|
202 |
foreach ( $translations as $p ) {
|
203 |
wp_set_object_terms( $p, $group, $this->tax_translations );
|
204 |
}
|
205 |
|
206 |
+
// Clean now unused translation groups.
|
207 |
foreach ( wp_list_pluck( $terms, 'term_id' ) as $term_id ) {
|
208 |
$term = get_term( $term_id, $this->tax_translations );
|
209 |
if ( empty( $term->count ) ) {
|
215 |
}
|
216 |
|
217 |
/**
|
218 |
+
* Deletes a translation of a post or term.
|
219 |
*
|
220 |
* @since 0.5
|
221 |
*
|
222 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
223 |
+
* @return void
|
224 |
*/
|
225 |
public function delete_translation( $id ) {
|
226 |
$id = (int) $id;
|
242 |
}
|
243 |
|
244 |
/**
|
245 |
+
* Returns an array of translations of a post or term.
|
246 |
*
|
247 |
* @since 0.5
|
248 |
*
|
249 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
250 |
+
* @return int[] An associative array of translations with language code as key and translation id as value.
|
251 |
*/
|
252 |
public function get_translations( $id ) {
|
253 |
$term = $this->get_object_term( $id, $this->tax_translations );
|
254 |
$translations = empty( $term ) ? array() : maybe_unserialize( $term->description );
|
255 |
|
256 |
+
// Make sure we return only translations ( thus we allow plugins to store other information in the array ).
|
257 |
if ( is_array( $translations ) ) {
|
258 |
$translations = array_intersect_key( $translations, array_flip( $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) );
|
259 |
}
|
260 |
|
261 |
+
// Make sure to return at least the passed object in its translation array.
|
262 |
if ( empty( $translations ) && $lang = $this->get_language( $id ) ) {
|
263 |
$translations = array( $lang->slug => $id );
|
264 |
}
|
267 |
}
|
268 |
|
269 |
/**
|
270 |
+
* Returns the id of the translation of a post or term.
|
271 |
*
|
272 |
* @since 0.5
|
273 |
*
|
274 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
275 |
+
* @param PLL_Language|string $lang Language ( slug or object ).
|
276 |
+
* @return int|false Object id of the translation, false if there is none.
|
277 |
*/
|
278 |
public function get_translation( $id, $lang ) {
|
279 |
if ( ! $lang = $this->model->get_language( $lang ) ) {
|
290 |
*
|
291 |
* @since 0.1
|
292 |
*
|
293 |
+
* @param int $id Object id ( typically a post_id or term_id ).
|
294 |
+
* @param int|string|PLL_Language $lang Language ( term_id or slug or object ).
|
295 |
+
* @return int|false The translation object id if exists, otherwise the passed id, false if the passed object has no language.
|
296 |
*/
|
297 |
public function get( $id, $lang ) {
|
298 |
$id = (int) $id;
|
299 |
+
$lang = $this->model->get_language( $lang );
|
300 |
+
$obj_lang = $this->get_language( $id );
|
301 |
+
if ( empty( $lang ) || empty( $obj_lang ) ) {
|
302 |
return false;
|
303 |
}
|
304 |
|
|
|
305 |
return $obj_lang->term_id == $lang->term_id ? $id : $this->get_translation( $id, $lang );
|
306 |
}
|
307 |
|
308 |
/**
|
309 |
+
* A join clause to add to sql queries when filtering by language is needed directly in query.
|
310 |
*
|
311 |
* @since 1.2
|
312 |
*
|
313 |
+
* @param string $alias Optional alias for object table.
|
314 |
+
* @return string Join clause.
|
315 |
+
*/
|
316 |
+
abstract public function join_clause( $alias = '' );
|
317 |
+
|
318 |
+
/**
|
319 |
+
* A where clause to add to sql queries when filtering by language is needed directly in query.
|
320 |
+
*
|
321 |
+
* @since 1.2
|
322 |
+
*
|
323 |
+
* @param PLL_Language|string|string[] $lang PLL_Language object or a comma separated list of language slug or an array of language slugs.
|
324 |
+
* @return string Where clause.
|
325 |
*/
|
326 |
public function where_clause( $lang ) {
|
327 |
$tt_id = $this->tax_tt;
|
328 |
|
329 |
+
/*
|
330 |
+
* $lang is an object.
|
331 |
+
* This is generally the case if the query is coming from Polylang.
|
332 |
+
*/
|
333 |
if ( is_object( $lang ) ) {
|
334 |
return ' AND pll_tr.term_taxonomy_id = ' . absint( $lang->$tt_id );
|
335 |
}
|
336 |
|
337 |
+
/*
|
338 |
+
* $lang is a comma separated list of slugs ( or an array of slugs ).
|
339 |
+
* This is generally the case is the query is coming from outside with a 'lang' parameter.
|
340 |
+
*/
|
341 |
$slugs = is_array( $lang ) ? $lang : explode( ',', $lang );
|
342 |
$languages = array();
|
343 |
foreach ( $slugs as $slug ) {
|
348 |
}
|
349 |
|
350 |
/**
|
351 |
+
* Returns ids of objects in a language similarly to get_objects_in_term() for a taxonomy.
|
352 |
+
* It is faster than get_objects_in_term() as it avoids a JOIN.
|
353 |
*
|
354 |
* @since 1.4
|
355 |
*
|
356 |
+
* @param PLL_Language $lang PLL_Language object.
|
357 |
+
* @return int[] Object ids.
|
358 |
*/
|
359 |
public function get_objects_in_language( $lang ) {
|
360 |
global $wpdb;
|
379 |
}
|
380 |
|
381 |
/**
|
382 |
+
* Check if a user can synchronize translations.
|
383 |
*
|
384 |
* @since 2.6
|
385 |
*
|
386 |
+
* @param int $id Object id.
|
387 |
* @return bool
|
388 |
*/
|
389 |
public function current_user_can_synchronize( $id ) {
|
390 |
/**
|
391 |
+
* Filters whether a synchronization capability check should take place.
|
392 |
*
|
393 |
* @since 2.6
|
394 |
*
|
395 |
+
* @param bool|null $check Null to enable the capability check,
|
396 |
+
* true to always allow the synchronization,
|
397 |
+
* false to always disallow the synchronization.
|
398 |
+
* Defaults to true.
|
399 |
+
* @param int $id The synchronization source object id.
|
400 |
*/
|
401 |
$check = apply_filters( "pll_pre_current_user_can_synchronize_{$this->type}", true, $id );
|
402 |
if ( null !== $check ) {
|
include/translated-post.php
CHANGED
@@ -11,11 +11,11 @@
|
|
11 |
class PLL_Translated_Post extends PLL_Translated_Object {
|
12 |
|
13 |
/**
|
14 |
-
* Constructor
|
15 |
*
|
16 |
* @since 1.8
|
17 |
*
|
18 |
-
* @param
|
19 |
*/
|
20 |
public function __construct( &$model ) {
|
21 |
// init properties
|
@@ -38,17 +38,20 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* Store the post language in the database
|
42 |
*
|
43 |
* @since 0.6
|
44 |
*
|
45 |
-
* @param int
|
46 |
-
* @param int|string|
|
|
|
47 |
*/
|
48 |
public function set_language( $post_id, $lang ) {
|
49 |
$old_lang = $this->get_language( $post_id );
|
50 |
$old_lang = $old_lang ? $old_lang->slug : '';
|
51 |
-
|
|
|
|
|
52 |
|
53 |
if ( $old_lang !== $lang ) {
|
54 |
wp_set_post_terms( (int) $post_id, $lang, 'language' );
|
@@ -61,7 +64,7 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
61 |
* @since 0.1
|
62 |
*
|
63 |
* @param int $post_id post id
|
64 |
-
* @return
|
65 |
*/
|
66 |
public function get_language( $post_id ) {
|
67 |
$lang = $this->get_object_term( $post_id, 'language' );
|
@@ -69,15 +72,16 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
-
* Deletes a translation
|
73 |
*
|
74 |
* @since 0.5
|
75 |
*
|
76 |
-
* @param int $id
|
|
|
77 |
*/
|
78 |
public function delete_translation( $id ) {
|
79 |
parent::delete_translation( $id );
|
80 |
-
wp_set_object_terms( $id,
|
81 |
}
|
82 |
|
83 |
/**
|
@@ -100,6 +104,8 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
100 |
* Register the language taxonomy
|
101 |
*
|
102 |
* @since 1.2
|
|
|
|
|
103 |
*/
|
104 |
public function register_taxonomy() {
|
105 |
register_taxonomy(
|
@@ -128,6 +134,7 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
128 |
* @since 1.2
|
129 |
*
|
130 |
* @param string $post_type post type name
|
|
|
131 |
*/
|
132 |
public function registered_post_type( $post_type ) {
|
133 |
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
@@ -137,13 +144,14 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
-
* Forces calling 'update_object_term_cache' when querying posts or pages
|
141 |
-
*
|
142 |
-
*
|
143 |
*
|
144 |
* @since 1.8
|
145 |
*
|
146 |
-
* @param
|
|
|
147 |
*/
|
148 |
public function pre_get_posts( $query ) {
|
149 |
if ( ! empty( $query->query['post_type'] ) && $this->model->is_translated_post_type( $query->query['post_type'] ) ) {
|
@@ -169,6 +177,10 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
169 |
|
170 |
if ( 'inherit' === $post->post_status && $post->post_parent ) {
|
171 |
$post = get_post( $post->post_parent );
|
|
|
|
|
|
|
|
|
172 |
}
|
173 |
|
174 |
if ( 'inherit' === $post->post_status || in_array( $post->post_status, get_post_stati( array( 'public' => true ) ) ) ) {
|
@@ -202,15 +214,15 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
202 |
|
203 |
/**
|
204 |
* Returns a list of posts in a language ( $lang )
|
205 |
-
* not translated in another language ( $untranslated_in )
|
206 |
*
|
207 |
* @since 2.6
|
208 |
*
|
209 |
-
* @param string
|
210 |
-
* @param
|
211 |
-
* @param
|
212 |
-
* @param string
|
213 |
-
* @return
|
214 |
*/
|
215 |
public function get_untranslated( $type, $untranslated_in, $lang, $search = '' ) {
|
216 |
$return = array();
|
@@ -246,7 +258,7 @@ class PLL_Translated_Post extends PLL_Translated_Object {
|
|
246 |
$posts = get_posts( $args );
|
247 |
|
248 |
foreach ( $posts as $post ) {
|
249 |
-
if ( ! $this->get_translation( $post->ID, $untranslated_in ) && $this->current_user_can_read( $post->ID, 'edit' ) ) {
|
250 |
$return[] = $post;
|
251 |
}
|
252 |
}
|
11 |
class PLL_Translated_Post extends PLL_Translated_Object {
|
12 |
|
13 |
/**
|
14 |
+
* Constructor.
|
15 |
*
|
16 |
* @since 1.8
|
17 |
*
|
18 |
+
* @param PLL_Model $model PLL_Model instance.
|
19 |
*/
|
20 |
public function __construct( &$model ) {
|
21 |
// init properties
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* Store the post language in the database.
|
42 |
*
|
43 |
* @since 0.6
|
44 |
*
|
45 |
+
* @param int $post_id Post id.
|
46 |
+
* @param int|string|PLL_Language $lang Language (term_id or slug or object).
|
47 |
+
* @return void
|
48 |
*/
|
49 |
public function set_language( $post_id, $lang ) {
|
50 |
$old_lang = $this->get_language( $post_id );
|
51 |
$old_lang = $old_lang ? $old_lang->slug : '';
|
52 |
+
|
53 |
+
$lang = $this->model->get_language( $lang );
|
54 |
+
$lang = $lang ? $lang->slug : '';
|
55 |
|
56 |
if ( $old_lang !== $lang ) {
|
57 |
wp_set_post_terms( (int) $post_id, $lang, 'language' );
|
64 |
* @since 0.1
|
65 |
*
|
66 |
* @param int $post_id post id
|
67 |
+
* @return PLL_Language|false PLL_Language object, false if no language is associated to that post
|
68 |
*/
|
69 |
public function get_language( $post_id ) {
|
70 |
$lang = $this->get_object_term( $post_id, 'language' );
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
+
* Deletes a translation.
|
76 |
*
|
77 |
* @since 0.5
|
78 |
*
|
79 |
+
* @param int $id Post id.
|
80 |
+
* @return void
|
81 |
*/
|
82 |
public function delete_translation( $id ) {
|
83 |
parent::delete_translation( $id );
|
84 |
+
wp_set_object_terms( $id, array(), $this->tax_translations );
|
85 |
}
|
86 |
|
87 |
/**
|
104 |
* Register the language taxonomy
|
105 |
*
|
106 |
* @since 1.2
|
107 |
+
*
|
108 |
+
* @return void
|
109 |
*/
|
110 |
public function register_taxonomy() {
|
111 |
register_taxonomy(
|
134 |
* @since 1.2
|
135 |
*
|
136 |
* @param string $post_type post type name
|
137 |
+
* @return void
|
138 |
*/
|
139 |
public function registered_post_type( $post_type ) {
|
140 |
if ( $this->model->is_translated_post_type( $post_type ) ) {
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* Forces calling 'update_object_term_cache' when querying posts or pages.
|
148 |
+
* This is especially useful for nav menus with a lot of pages as, without doing this,
|
149 |
+
* we would have one query per page in the menu to get the page language for the permalink.
|
150 |
*
|
151 |
* @since 1.8
|
152 |
*
|
153 |
+
* @param WP_Query $query Reference to the query object.
|
154 |
+
* @return void
|
155 |
*/
|
156 |
public function pre_get_posts( $query ) {
|
157 |
if ( ! empty( $query->query['post_type'] ) && $this->model->is_translated_post_type( $query->query['post_type'] ) ) {
|
177 |
|
178 |
if ( 'inherit' === $post->post_status && $post->post_parent ) {
|
179 |
$post = get_post( $post->post_parent );
|
180 |
+
|
181 |
+
if ( empty( $post ) ) {
|
182 |
+
return false;
|
183 |
+
}
|
184 |
}
|
185 |
|
186 |
if ( 'inherit' === $post->post_status || in_array( $post->post_status, get_post_stati( array( 'public' => true ) ) ) ) {
|
214 |
|
215 |
/**
|
216 |
* Returns a list of posts in a language ( $lang )
|
217 |
+
* not translated in another language ( $untranslated_in ).
|
218 |
*
|
219 |
* @since 2.6
|
220 |
*
|
221 |
+
* @param string $type Post type.
|
222 |
+
* @param PLL_Language $untranslated_in The language the posts must not be translated in.
|
223 |
+
* @param PLL_Language $lang Language of the searched posts.
|
224 |
+
* @param string $search Limit the results to the posts matching this string.
|
225 |
+
* @return WP_Post[] Array of posts.
|
226 |
*/
|
227 |
public function get_untranslated( $type, $untranslated_in, $lang, $search = '' ) {
|
228 |
$return = array();
|
258 |
$posts = get_posts( $args );
|
259 |
|
260 |
foreach ( $posts as $post ) {
|
261 |
+
if ( $post instanceof WP_Post && ! $this->get_translation( $post->ID, $untranslated_in ) && $this->current_user_can_read( $post->ID, 'edit' ) ) {
|
262 |
$return[] = $post;
|
263 |
}
|
264 |
}
|
include/translated-term.php
CHANGED
@@ -28,25 +28,28 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
28 |
|
29 |
// Filters to prime terms cache
|
30 |
add_filter( 'get_terms', array( $this, '_prime_terms_cache' ), 10, 2 );
|
31 |
-
add_filter( '
|
32 |
|
33 |
add_action( 'clean_term_cache', array( $this, 'clean_term_cache' ) );
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
-
* Stores the term language in the database
|
38 |
*
|
39 |
* @since 0.6
|
40 |
*
|
41 |
-
* @param int
|
42 |
-
* @param int|string|
|
|
|
43 |
*/
|
44 |
public function set_language( $term_id, $lang ) {
|
45 |
$term_id = (int) $term_id;
|
46 |
|
47 |
$old_lang = $this->get_language( $term_id );
|
48 |
$old_lang = $old_lang ? $old_lang->tl_term_id : '';
|
49 |
-
|
|
|
|
|
50 |
|
51 |
if ( $old_lang !== $lang ) {
|
52 |
wp_set_object_terms( $term_id, $lang, 'term_language' );
|
@@ -67,6 +70,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
67 |
* @since 0.5
|
68 |
*
|
69 |
* @param int $term_id term id
|
|
|
70 |
*/
|
71 |
public function delete_language( $term_id ) {
|
72 |
wp_delete_object_term_relationships( $term_id, 'term_language' );
|
@@ -79,7 +83,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
79 |
*
|
80 |
* @param int|string $value term id or term slug
|
81 |
* @param string $taxonomy optional taxonomy needed when the term slug is passed as first parameter
|
82 |
-
* @return
|
83 |
*/
|
84 |
public function get_language( $value, $taxonomy = '' ) {
|
85 |
if ( is_numeric( $value ) ) {
|
@@ -88,7 +92,10 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
88 |
|
89 |
// get_term_by still not cached in WP 3.5.1 but internally, the function is always called by term_id
|
90 |
elseif ( is_string( $value ) && $taxonomy ) {
|
91 |
-
$
|
|
|
|
|
|
|
92 |
}
|
93 |
|
94 |
// Get the language and make sure it is a PLL_Language object
|
@@ -96,12 +103,13 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
96 |
}
|
97 |
|
98 |
/**
|
99 |
-
* Tells whether a translation term must updated
|
100 |
*
|
101 |
* @since 2.3
|
102 |
*
|
103 |
-
* @param
|
104 |
-
* @param
|
|
|
105 |
*/
|
106 |
protected function should_update_translation_group( $id, $translations ) {
|
107 |
// Don't do anything if no translations have been added to the group
|
@@ -121,6 +129,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
121 |
* @since 0.5
|
122 |
*
|
123 |
* @param int $id term id
|
|
|
124 |
*/
|
125 |
public function delete_translation( $id ) {
|
126 |
global $wpdb;
|
@@ -152,13 +161,13 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
-
*
|
156 |
*
|
157 |
* @since 1.2
|
158 |
*
|
159 |
-
* @param
|
160 |
-
* @param
|
161 |
-
* @return
|
162 |
*/
|
163 |
public function _prime_terms_cache( $terms, $taxonomies ) {
|
164 |
$term_ids = array();
|
@@ -176,17 +185,16 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
176 |
}
|
177 |
|
178 |
/**
|
179 |
-
* When terms are found for posts, add their language and translations to cache
|
180 |
*
|
181 |
* @since 1.2
|
182 |
*
|
183 |
-
* @param
|
184 |
-
* @param
|
185 |
-
* @param
|
186 |
-
* @return
|
187 |
*/
|
188 |
public function wp_get_object_terms( $terms, $object_ids, $taxonomies ) {
|
189 |
-
$taxonomies = explode( "', '", trim( $taxonomies, "'" ) );
|
190 |
if ( ! in_array( 'term_translations', $taxonomies ) ) {
|
191 |
$this->_prime_terms_cache( $terms, $taxonomies );
|
192 |
}
|
@@ -194,11 +202,12 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
194 |
}
|
195 |
|
196 |
/**
|
197 |
-
* When the term cache is cleaned,
|
198 |
*
|
199 |
* @since 2.0
|
200 |
*
|
201 |
-
* @param
|
|
|
202 |
*/
|
203 |
public function clean_term_cache( $ids ) {
|
204 |
clean_object_term_cache( $ids, 'term' );
|
28 |
|
29 |
// Filters to prime terms cache
|
30 |
add_filter( 'get_terms', array( $this, '_prime_terms_cache' ), 10, 2 );
|
31 |
+
add_filter( 'get_object_terms', array( $this, 'wp_get_object_terms' ), 10, 3 );
|
32 |
|
33 |
add_action( 'clean_term_cache', array( $this, 'clean_term_cache' ) );
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
* Stores the term language in the database.
|
38 |
*
|
39 |
* @since 0.6
|
40 |
*
|
41 |
+
* @param int $term_id Term id.
|
42 |
+
* @param int|string|PLL_Language $lang Language (term_id or slug or object).
|
43 |
+
* @return void
|
44 |
*/
|
45 |
public function set_language( $term_id, $lang ) {
|
46 |
$term_id = (int) $term_id;
|
47 |
|
48 |
$old_lang = $this->get_language( $term_id );
|
49 |
$old_lang = $old_lang ? $old_lang->tl_term_id : '';
|
50 |
+
|
51 |
+
$lang = $this->model->get_language( $lang );
|
52 |
+
$lang = $lang ? $lang->tl_term_id : '';
|
53 |
|
54 |
if ( $old_lang !== $lang ) {
|
55 |
wp_set_object_terms( $term_id, $lang, 'term_language' );
|
70 |
* @since 0.5
|
71 |
*
|
72 |
* @param int $term_id term id
|
73 |
+
* @return void
|
74 |
*/
|
75 |
public function delete_language( $term_id ) {
|
76 |
wp_delete_object_term_relationships( $term_id, 'term_language' );
|
83 |
*
|
84 |
* @param int|string $value term id or term slug
|
85 |
* @param string $taxonomy optional taxonomy needed when the term slug is passed as first parameter
|
86 |
+
* @return PLL_Language|false PLL_Language object, false if no language is associated to that term
|
87 |
*/
|
88 |
public function get_language( $value, $taxonomy = '' ) {
|
89 |
if ( is_numeric( $value ) ) {
|
92 |
|
93 |
// get_term_by still not cached in WP 3.5.1 but internally, the function is always called by term_id
|
94 |
elseif ( is_string( $value ) && $taxonomy ) {
|
95 |
+
$term = get_term_by( 'slug', $value, $taxonomy );
|
96 |
+
if ( $term instanceof WP_Term ) {
|
97 |
+
$term_id = $term->term_id;
|
98 |
+
}
|
99 |
}
|
100 |
|
101 |
// Get the language and make sure it is a PLL_Language object
|
103 |
}
|
104 |
|
105 |
/**
|
106 |
+
* Tells whether a translation term must updated.
|
107 |
*
|
108 |
* @since 2.3
|
109 |
*
|
110 |
+
* @param int $id Post id or term id.
|
111 |
+
* @param int[] $translations An associative array of translations with language code as key and translation id as value.
|
112 |
+
* @return bool
|
113 |
*/
|
114 |
protected function should_update_translation_group( $id, $translations ) {
|
115 |
// Don't do anything if no translations have been added to the group
|
129 |
* @since 0.5
|
130 |
*
|
131 |
* @param int $id term id
|
132 |
+
* @return void
|
133 |
*/
|
134 |
public function delete_translation( $id ) {
|
135 |
global $wpdb;
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
+
* Caches the language and translations when terms are queried by get_terms().
|
165 |
*
|
166 |
* @since 1.2
|
167 |
*
|
168 |
+
* @param WP_Term[]|int[] $terms Queried terms.
|
169 |
+
* @param string[] $taxonomies Queried taxonomies.
|
170 |
+
* @return WP_Term[]|int[] Unmodified $terms.
|
171 |
*/
|
172 |
public function _prime_terms_cache( $terms, $taxonomies ) {
|
173 |
$term_ids = array();
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
+
* When terms are found for posts, add their language and translations to cache.
|
189 |
*
|
190 |
* @since 1.2
|
191 |
*
|
192 |
+
* @param WP_Term[] $terms Array of terms for the given object or objects.
|
193 |
+
* @param int[] $object_ids Array of object IDs for which terms were retrieved.
|
194 |
+
* @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
|
195 |
+
* @return WP_Term[] Unmodified $terms.
|
196 |
*/
|
197 |
public function wp_get_object_terms( $terms, $object_ids, $taxonomies ) {
|
|
|
198 |
if ( ! in_array( 'term_translations', $taxonomies ) ) {
|
199 |
$this->_prime_terms_cache( $terms, $taxonomies );
|
200 |
}
|
202 |
}
|
203 |
|
204 |
/**
|
205 |
+
* When the term cache is cleaned, cleans the object term cache too.
|
206 |
*
|
207 |
* @since 2.0
|
208 |
*
|
209 |
+
* @param int[] $ids An array of term IDs.
|
210 |
+
* @return void
|
211 |
*/
|
212 |
public function clean_term_cache( $ids ) {
|
213 |
clean_object_term_cache( $ids, 'term' );
|
include/walker-dropdown.php
CHANGED
@@ -9,6 +9,13 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Walker_Dropdown extends Walker {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
13 |
|
14 |
/**
|
@@ -16,11 +23,12 @@ class PLL_Walker_Dropdown extends Walker {
|
|
16 |
*
|
17 |
* @since 1.2
|
18 |
*
|
19 |
-
* @param string
|
20 |
-
* @param
|
21 |
-
* @param int
|
22 |
-
* @param array
|
23 |
-
* @param int
|
|
|
24 |
*/
|
25 |
public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
26 |
$value = $args['value'];
|
@@ -38,12 +46,13 @@ class PLL_Walker_Dropdown extends Walker {
|
|
38 |
*
|
39 |
* @since 1.2
|
40 |
*
|
41 |
-
* @param
|
42 |
-
* @param array
|
43 |
-
* @param int
|
44 |
-
* @param int
|
45 |
-
* @param array
|
46 |
-
* @param string
|
|
|
47 |
*/
|
48 |
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
|
49 |
$element = (object) $element; // Make sure we have an object
|
@@ -75,7 +84,7 @@ class PLL_Walker_Dropdown extends Walker {
|
|
75 |
public function walk( $elements, $max_depth, ...$args ) { // // phpcs:ignore WordPressVIPMinimum.Classes.DeclarationCompatibility.DeclarationCompatibility
|
76 |
$output = '';
|
77 |
|
78 |
-
if ( is_array( $max_depth ) ) {
|
79 |
// Backward compatibility with Polylang < 2.6.7
|
80 |
if ( WP_DEBUG ) {
|
81 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Walker_Dropdown extends Walker {
|
12 |
+
/**
|
13 |
+
* Database fields to use.
|
14 |
+
*
|
15 |
+
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
+
*
|
17 |
+
* @var array
|
18 |
+
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
21 |
/**
|
23 |
*
|
24 |
* @since 1.2
|
25 |
*
|
26 |
+
* @param string $output Passed by reference. Used to append additional content.
|
27 |
+
* @param stdClass $element The data object.
|
28 |
+
* @param int $depth Depth of the item.
|
29 |
+
* @param array $args An array of additional arguments.
|
30 |
+
* @param int $current_object_id ID of the current item.
|
31 |
+
* @return void
|
32 |
*/
|
33 |
public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
34 |
$value = $args['value'];
|
46 |
*
|
47 |
* @since 1.2
|
48 |
*
|
49 |
+
* @param stdClass $element Data object.
|
50 |
+
* @param array $children_elements List of elements to continue traversing.
|
51 |
+
* @param int $max_depth Max depth to traverse.
|
52 |
+
* @param int $depth Depth of current element.
|
53 |
+
* @param array $args An array of arguments.
|
54 |
+
* @param string $output Passed by reference. Used to append additional content.
|
55 |
+
* @return void
|
56 |
*/
|
57 |
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
|
58 |
$element = (object) $element; // Make sure we have an object
|
84 |
public function walk( $elements, $max_depth, ...$args ) { // // phpcs:ignore WordPressVIPMinimum.Classes.DeclarationCompatibility.DeclarationCompatibility
|
85 |
$output = '';
|
86 |
|
87 |
+
if ( is_array( $max_depth ) ) { // @phpstan-ignore-line
|
88 |
// Backward compatibility with Polylang < 2.6.7
|
89 |
if ( WP_DEBUG ) {
|
90 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
include/walker-list.php
CHANGED
@@ -9,6 +9,13 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Walker_List extends Walker {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
13 |
|
14 |
/**
|
@@ -16,11 +23,12 @@ class PLL_Walker_List extends Walker {
|
|
16 |
*
|
17 |
* @since 1.2
|
18 |
*
|
19 |
-
* @param string
|
20 |
-
* @param
|
21 |
-
* @param int
|
22 |
-
* @param array
|
23 |
-
* @param int
|
|
|
24 |
*/
|
25 |
public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
26 |
$output .= sprintf(
|
@@ -40,12 +48,13 @@ class PLL_Walker_List extends Walker {
|
|
40 |
*
|
41 |
* @since 1.2
|
42 |
*
|
43 |
-
* @param
|
44 |
-
* @param array
|
45 |
-
* @param int
|
46 |
-
* @param int
|
47 |
-
* @param array
|
48 |
-
* @param string
|
|
|
49 |
*/
|
50 |
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
|
51 |
$element = (object) $element; // Make sure we have an object
|
@@ -65,7 +74,7 @@ class PLL_Walker_List extends Walker {
|
|
65 |
* @return string The hierarchical item output.
|
66 |
*/
|
67 |
public function walk( $elements, $max_depth, ...$args ) { // phpcs:ignore WordPressVIPMinimum.Classes.DeclarationCompatibility.DeclarationCompatibility
|
68 |
-
if ( is_array( $max_depth ) ) {
|
69 |
// Backward compatibility with Polylang < 2.6.7
|
70 |
if ( WP_DEBUG ) {
|
71 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Walker_List extends Walker {
|
12 |
+
/**
|
13 |
+
* Database fields to use.
|
14 |
+
*
|
15 |
+
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
+
*
|
17 |
+
* @var array
|
18 |
+
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
21 |
/**
|
23 |
*
|
24 |
* @since 1.2
|
25 |
*
|
26 |
+
* @param string $output Passed by reference. Used to append additional content.
|
27 |
+
* @param stdClass $element The data object.
|
28 |
+
* @param int $depth Depth of the item.
|
29 |
+
* @param array $args An array of additional arguments.
|
30 |
+
* @param int $current_object_id ID of the current item.
|
31 |
+
* @return void
|
32 |
*/
|
33 |
public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
34 |
$output .= sprintf(
|
48 |
*
|
49 |
* @since 1.2
|
50 |
*
|
51 |
+
* @param stdClass $element Data object.
|
52 |
+
* @param array $children_elements List of elements to continue traversing.
|
53 |
+
* @param int $max_depth Max depth to traverse.
|
54 |
+
* @param int $depth Depth of current element.
|
55 |
+
* @param array $args An array of arguments.
|
56 |
+
* @param string $output Passed by reference. Used to append additional content.
|
57 |
+
* @return void
|
58 |
*/
|
59 |
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
|
60 |
$element = (object) $element; // Make sure we have an object
|
74 |
* @return string The hierarchical item output.
|
75 |
*/
|
76 |
public function walk( $elements, $max_depth, ...$args ) { // phpcs:ignore WordPressVIPMinimum.Classes.DeclarationCompatibility.DeclarationCompatibility
|
77 |
+
if ( is_array( $max_depth ) ) { // @phpstan-ignore-line
|
78 |
// Backward compatibility with Polylang < 2.6.7
|
79 |
if ( WP_DEBUG ) {
|
80 |
trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
include/widget-languages.php
CHANGED
@@ -33,6 +33,7 @@ class PLL_Widget_Languages extends WP_Widget {
|
|
33 |
*
|
34 |
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
35 |
* @param array $instance The settings for the particular instance of the widget
|
|
|
36 |
*/
|
37 |
public function widget( $args, $instance ) {
|
38 |
// Sets a unique id for dropdown.
|
@@ -99,11 +100,12 @@ class PLL_Widget_Languages extends WP_Widget {
|
|
99 |
}
|
100 |
|
101 |
/**
|
102 |
-
* Displays the widget form
|
103 |
*
|
104 |
* @since 0.4
|
105 |
*
|
106 |
-
* @param array $instance Current settings
|
|
|
107 |
*/
|
108 |
public function form( $instance ) {
|
109 |
// Default values
|
@@ -130,5 +132,7 @@ class PLL_Widget_Languages extends WP_Widget {
|
|
130 |
esc_attr( 'pll-' . $key )
|
131 |
);
|
132 |
}
|
|
|
|
|
133 |
}
|
134 |
}
|
33 |
*
|
34 |
* @param array $args Display arguments including before_title, after_title, before_widget, and after_widget.
|
35 |
* @param array $instance The settings for the particular instance of the widget
|
36 |
+
* @return void
|
37 |
*/
|
38 |
public function widget( $args, $instance ) {
|
39 |
// Sets a unique id for dropdown.
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
+
* Displays the widget form.
|
104 |
*
|
105 |
* @since 0.4
|
106 |
*
|
107 |
+
* @param array $instance Current settings.
|
108 |
+
* @return string
|
109 |
*/
|
110 |
public function form( $instance ) {
|
111 |
// Default values
|
132 |
esc_attr( 'pll-' . $key )
|
133 |
);
|
134 |
}
|
135 |
+
|
136 |
+
return ''; // Because the parent class returns a string, however not used.
|
137 |
}
|
138 |
}
|
install/install-base.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.7
|
10 |
*/
|
11 |
class PLL_Install_Base {
|
|
|
|
|
|
|
|
|
|
|
12 |
protected $plugin_basename;
|
13 |
|
14 |
/**
|
@@ -47,6 +52,7 @@ class PLL_Install_Base {
|
|
47 |
*
|
48 |
* @param string $what Either 'activate' or 'deactivate'
|
49 |
* @param bool $networkwide
|
|
|
50 |
*/
|
51 |
protected function do_for_all_blogs( $what, $networkwide ) {
|
52 |
// Network
|
@@ -72,6 +78,7 @@ class PLL_Install_Base {
|
|
72 |
* @since 1.7
|
73 |
*
|
74 |
* @param bool $networkwide
|
|
|
75 |
*/
|
76 |
public function activate( $networkwide ) {
|
77 |
$this->do_for_all_blogs( 'activate', $networkwide );
|
@@ -81,6 +88,8 @@ class PLL_Install_Base {
|
|
81 |
* Plugin activation
|
82 |
*
|
83 |
* @since 0.5
|
|
|
|
|
84 |
*/
|
85 |
protected function _activate() {
|
86 |
// Can be overriden in child class
|
@@ -92,6 +101,7 @@ class PLL_Install_Base {
|
|
92 |
* @since 0.1
|
93 |
*
|
94 |
* @param bool $networkwide
|
|
|
95 |
*/
|
96 |
public function deactivate( $networkwide ) {
|
97 |
$this->do_for_all_blogs( 'deactivate', $networkwide );
|
@@ -101,6 +111,8 @@ class PLL_Install_Base {
|
|
101 |
* Plugin deactivation
|
102 |
*
|
103 |
* @since 0.5
|
|
|
|
|
104 |
*/
|
105 |
protected function _deactivate() {
|
106 |
// Can be overriden in child class
|
@@ -112,6 +124,7 @@ class PLL_Install_Base {
|
|
112 |
* @since 2.6.8
|
113 |
*
|
114 |
* @param WP_Site $new_site New site object.
|
|
|
115 |
*/
|
116 |
public function new_site( $new_site ) {
|
117 |
switch_to_blog( $new_site->id );
|
9 |
* @since 1.7
|
10 |
*/
|
11 |
class PLL_Install_Base {
|
12 |
+
/**
|
13 |
+
* The plugin basename.
|
14 |
+
*
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
protected $plugin_basename;
|
18 |
|
19 |
/**
|
52 |
*
|
53 |
* @param string $what Either 'activate' or 'deactivate'
|
54 |
* @param bool $networkwide
|
55 |
+
* @return void
|
56 |
*/
|
57 |
protected function do_for_all_blogs( $what, $networkwide ) {
|
58 |
// Network
|
78 |
* @since 1.7
|
79 |
*
|
80 |
* @param bool $networkwide
|
81 |
+
* @return void
|
82 |
*/
|
83 |
public function activate( $networkwide ) {
|
84 |
$this->do_for_all_blogs( 'activate', $networkwide );
|
88 |
* Plugin activation
|
89 |
*
|
90 |
* @since 0.5
|
91 |
+
*
|
92 |
+
* @return void
|
93 |
*/
|
94 |
protected function _activate() {
|
95 |
// Can be overriden in child class
|
101 |
* @since 0.1
|
102 |
*
|
103 |
* @param bool $networkwide
|
104 |
+
* @return void
|
105 |
*/
|
106 |
public function deactivate( $networkwide ) {
|
107 |
$this->do_for_all_blogs( 'deactivate', $networkwide );
|
111 |
* Plugin deactivation
|
112 |
*
|
113 |
* @since 0.5
|
114 |
+
*
|
115 |
+
* @return void
|
116 |
*/
|
117 |
protected function _deactivate() {
|
118 |
// Can be overriden in child class
|
124 |
* @since 2.6.8
|
125 |
*
|
126 |
* @param WP_Site $new_site New site object.
|
127 |
+
* @return void
|
128 |
*/
|
129 |
public function new_site( $new_site ) {
|
130 |
switch_to_blog( $new_site->id );
|
install/install.php
CHANGED
@@ -14,6 +14,8 @@ class PLL_Install extends PLL_Install_Base {
|
|
14 |
* Checks min PHP and WP version, displays a notice if a requirement is not met.
|
15 |
*
|
16 |
* @since 2.6.7
|
|
|
|
|
17 |
*/
|
18 |
public function can_activate() {
|
19 |
global $wp_version;
|
@@ -35,6 +37,8 @@ class PLL_Install extends PLL_Install_Base {
|
|
35 |
* Displays a notice if PHP min version is not met.
|
36 |
*
|
37 |
* @since 2.6.7
|
|
|
|
|
38 |
*/
|
39 |
public function php_version_notice() {
|
40 |
load_plugin_textdomain( 'polylang' ); // Plugin i18n.
|
@@ -55,6 +59,8 @@ class PLL_Install extends PLL_Install_Base {
|
|
55 |
* Displays a notice if WP min version is not met.
|
56 |
*
|
57 |
* @since 2.6.7
|
|
|
|
|
58 |
*/
|
59 |
public function wp_version_notice() {
|
60 |
global $wp_version;
|
@@ -78,7 +84,7 @@ class PLL_Install extends PLL_Install_Base {
|
|
78 |
*
|
79 |
* @since 1.8
|
80 |
*
|
81 |
-
* return array
|
82 |
*/
|
83 |
public static function get_default_options() {
|
84 |
return array(
|
@@ -102,6 +108,8 @@ class PLL_Install extends PLL_Install_Base {
|
|
102 |
* Plugin activation
|
103 |
*
|
104 |
* @since 0.5
|
|
|
|
|
105 |
*/
|
106 |
protected function _activate() {
|
107 |
if ( $options = get_option( 'polylang' ) ) {
|
@@ -131,6 +139,8 @@ class PLL_Install extends PLL_Install_Base {
|
|
131 |
* Plugin deactivation
|
132 |
*
|
133 |
* @since 0.5
|
|
|
|
|
134 |
*/
|
135 |
protected function _deactivate() {
|
136 |
delete_option( 'rewrite_rules' ); // Don't use flush_rewrite_rules at network activation. See #32471
|
14 |
* Checks min PHP and WP version, displays a notice if a requirement is not met.
|
15 |
*
|
16 |
* @since 2.6.7
|
17 |
+
*
|
18 |
+
* @return bool
|
19 |
*/
|
20 |
public function can_activate() {
|
21 |
global $wp_version;
|
37 |
* Displays a notice if PHP min version is not met.
|
38 |
*
|
39 |
* @since 2.6.7
|
40 |
+
*
|
41 |
+
* @return void
|
42 |
*/
|
43 |
public function php_version_notice() {
|
44 |
load_plugin_textdomain( 'polylang' ); // Plugin i18n.
|
59 |
* Displays a notice if WP min version is not met.
|
60 |
*
|
61 |
* @since 2.6.7
|
62 |
+
*
|
63 |
+
* @return void
|
64 |
*/
|
65 |
public function wp_version_notice() {
|
66 |
global $wp_version;
|
84 |
*
|
85 |
* @since 1.8
|
86 |
*
|
87 |
+
* @return array
|
88 |
*/
|
89 |
public static function get_default_options() {
|
90 |
return array(
|
108 |
* Plugin activation
|
109 |
*
|
110 |
* @since 0.5
|
111 |
+
*
|
112 |
+
* @return void
|
113 |
*/
|
114 |
protected function _activate() {
|
115 |
if ( $options = get_option( 'polylang' ) ) {
|
139 |
* Plugin deactivation
|
140 |
*
|
141 |
* @since 0.5
|
142 |
+
*
|
143 |
+
* @return void
|
144 |
*/
|
145 |
protected function _deactivate() {
|
146 |
delete_option( 'rewrite_rules' ); // Don't use flush_rewrite_rules at network activation. See #32471
|
install/t15s.php
CHANGED
@@ -89,6 +89,7 @@ class PLL_T15S {
|
|
89 |
* @since 2.6
|
90 |
*
|
91 |
* @param bool|array $value The transient value.
|
|
|
92 |
*/
|
93 |
public function site_transient_update_plugins( $value ) {
|
94 |
if ( ! $value ) {
|
@@ -132,6 +133,8 @@ class PLL_T15S {
|
|
132 |
* Registers actions for clearing translation caches.
|
133 |
*
|
134 |
* @since 2.6
|
|
|
|
|
135 |
*/
|
136 |
public static function register_clean_translations_cache() {
|
137 |
add_action( 'set_site_transient_update_plugins', array( __CLASS__, 'clean_translations_cache' ) );
|
@@ -142,6 +145,8 @@ class PLL_T15S {
|
|
142 |
* Clears existing translation cache.
|
143 |
*
|
144 |
* @since 2.6
|
|
|
|
|
145 |
*/
|
146 |
public static function clean_translations_cache() {
|
147 |
$translations = get_site_transient( self::TRANSIENT_KEY_PLUGIN );
|
89 |
* @since 2.6
|
90 |
*
|
91 |
* @param bool|array $value The transient value.
|
92 |
+
* @return bool|array
|
93 |
*/
|
94 |
public function site_transient_update_plugins( $value ) {
|
95 |
if ( ! $value ) {
|
133 |
* Registers actions for clearing translation caches.
|
134 |
*
|
135 |
* @since 2.6
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
*/
|
139 |
public static function register_clean_translations_cache() {
|
140 |
add_action( 'set_site_transient_update_plugins', array( __CLASS__, 'clean_translations_cache' ) );
|
145 |
* Clears existing translation cache.
|
146 |
*
|
147 |
* @since 2.6
|
148 |
+
*
|
149 |
+
* @return void
|
150 |
*/
|
151 |
public static function clean_translations_cache() {
|
152 |
$translations = get_site_transient( self::TRANSIENT_KEY_PLUGIN );
|
install/upgrade.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Upgrade {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $options;
|
13 |
|
14 |
/**
|
@@ -26,6 +31,8 @@ class PLL_Upgrade {
|
|
26 |
* Check if upgrade is possible otherwise die to avoid activation
|
27 |
*
|
28 |
* @since 1.2
|
|
|
|
|
29 |
*/
|
30 |
public function can_activate() {
|
31 |
if ( ! $this->can_upgrade() ) {
|
@@ -63,14 +70,16 @@ class PLL_Upgrade {
|
|
63 |
* @return bool true if upgrade is possible, false otherwise
|
64 |
*/
|
65 |
public function can_upgrade() {
|
66 |
-
// Don't manage upgrade from version <
|
67 |
-
return version_compare( $this->options['version'], '
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* Displays a notice when ugrading from a too old version
|
72 |
*
|
73 |
* @since 1.0
|
|
|
|
|
74 |
*/
|
75 |
public function admin_notices() {
|
76 |
load_plugin_textdomain( 'polylang' );
|
@@ -80,7 +89,7 @@ class PLL_Upgrade {
|
|
80 |
sprintf(
|
81 |
/* translators: %1$s and %2$s are Polylang version numbers */
|
82 |
esc_html__( 'Before upgrading to %2$s, please upgrade to %1$s.', 'polylang' ),
|
83 |
-
'<strong>
|
84 |
POLYLANG_VERSION // phpcs:ignore WordPress.Security.EscapeOutput
|
85 |
)
|
86 |
);
|
@@ -90,498 +99,28 @@ class PLL_Upgrade {
|
|
90 |
* Upgrades the plugin depending on the previous version
|
91 |
*
|
92 |
* @since 1.2
|
|
|
|
|
93 |
*/
|
94 |
public function _upgrade() {
|
95 |
-
foreach ( array( '
|
96 |
if ( version_compare( $this->options['version'], $version, '<' ) ) {
|
97 |
call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
|
98 |
}
|
99 |
}
|
100 |
|
101 |
-
$delete_pre_1_2_data = get_transient( 'pll_upgrade_1_4' );
|
102 |
-
if ( false !== $delete_pre_1_2_data && absint( $delete_pre_1_2_data ) < time() ) {
|
103 |
-
$this->delete_pre_1_2_data();
|
104 |
-
}
|
105 |
-
|
106 |
$this->options['previous_version'] = $this->options['version']; // Remember the previous version of Polylang since v1.7.7
|
107 |
$this->options['version'] = POLYLANG_VERSION;
|
108 |
update_option( 'polylang', $this->options );
|
109 |
}
|
110 |
|
111 |
-
/**
|
112 |
-
* Upgrades if the previous version is < 0.9
|
113 |
-
*
|
114 |
-
* @since 1.2
|
115 |
-
*/
|
116 |
-
protected function upgrade_0_9() {
|
117 |
-
$this->options['sync'] = defined( 'PLL_SYNC' ) && ! PLL_SYNC ? 0 : 1; // The option replaces PLL_SYNC in 0.9
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Upgrades if the previous version is < 1.0
|
122 |
-
*
|
123 |
-
* @since 1.2
|
124 |
-
*/
|
125 |
-
protected function upgrade_1_0() {
|
126 |
-
// The option replaces PLL_MEDIA_SUPPORT in 1.0
|
127 |
-
$this->options['media_support'] = defined( 'PLL_MEDIA_SUPPORT' ) && ! PLL_MEDIA_SUPPORT ? 0 : 1;
|
128 |
-
|
129 |
-
// Split the synchronization options in 1.0
|
130 |
-
$this->options['sync'] = empty( $this->options['sync'] ) ? array() : array_keys( PLL_Settings_Sync::list_metas_to_sync() );
|
131 |
-
|
132 |
-
// Set default values for post types and taxonomies to translate
|
133 |
-
$this->options['post_types'] = array_values( get_post_types( array( '_builtin' => false, 'show_ui' => true ) ) );
|
134 |
-
$this->options['taxonomies'] = array_values( get_taxonomies( array( '_builtin' => false, 'show_ui' => true ) ) );
|
135 |
-
update_option( 'polylang', $this->options );
|
136 |
-
|
137 |
-
flush_rewrite_rules(); // Rewrite rules have been modified in 1.0
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Upgrades if the previous version is < 1.1
|
142 |
-
*
|
143 |
-
* @since 1.2
|
144 |
-
*/
|
145 |
-
protected function upgrade_1_1() {
|
146 |
-
// Update strings register with icl_register_string
|
147 |
-
$strings = get_option( 'polylang_wpml_strings' );
|
148 |
-
if ( $strings ) {
|
149 |
-
foreach ( array_keys( $strings ) as $key ) {
|
150 |
-
$strings[ $key ]['icl'] = 1;
|
151 |
-
}
|
152 |
-
update_option( 'polylang_wpml_strings', $strings );
|
153 |
-
}
|
154 |
-
|
155 |
-
// Move polylang_widgets options
|
156 |
-
if ( $widgets = get_option( 'polylang_widgets' ) ) {
|
157 |
-
$this->options['widgets'] = $widgets;
|
158 |
-
delete_option( 'polylang_widgets' );
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Upgrades if the previous version is < 1.2
|
164 |
-
*
|
165 |
-
* @since 1.2
|
166 |
-
*/
|
167 |
-
protected function upgrade_1_2() {
|
168 |
-
$this->options['domains'] = array(); // Option added in 1.2
|
169 |
-
|
170 |
-
// Need to register the taxonomies
|
171 |
-
foreach ( array( 'language', 'term_language', 'post_translations', 'term_translations' ) as $taxonomy ) {
|
172 |
-
register_taxonomy( $taxonomy, null, array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false ) );
|
173 |
-
}
|
174 |
-
|
175 |
-
// Abort if the db upgrade has already been done previously
|
176 |
-
if ( get_terms( 'term_language', array( 'hide_empty' => 0 ) ) ) {
|
177 |
-
return;
|
178 |
-
}
|
179 |
-
|
180 |
-
set_time_limit( 0 ); // In case we upgrade a huge site
|
181 |
-
|
182 |
-
// Upgrade old model based on metas to new model based on taxonomies
|
183 |
-
global $wpdb;
|
184 |
-
$wpdb->termmeta = $wpdb->prefix . 'termmeta'; // Registers the termmeta table in wpdb
|
185 |
-
$languages = get_terms( 'language', array( 'hide_empty' => 0 ) ); // Don't use get_languages_list which can't work with the old model
|
186 |
-
$lang_tt_ids = array();
|
187 |
-
|
188 |
-
foreach ( $languages as $lang ) {
|
189 |
-
// First update language with new storage for locale and text direction
|
190 |
-
$text_direction = get_metadata( 'term', $lang->term_id, '_rtl', true );
|
191 |
-
$desc = maybe_serialize( array( 'locale' => $lang->description, 'rtl' => $text_direction ) );
|
192 |
-
wp_update_term( (int) $lang->term_id, 'language', array( 'description' => $desc ) );
|
193 |
-
|
194 |
-
// Add language to new 'term_language' taxonomy
|
195 |
-
$term_lang = wp_insert_term( $lang->name, 'term_language', array( 'slug' => 'pll_' . $lang->slug ) );
|
196 |
-
$lang_tt_ids[ $lang->term_id ] = $term_lang['term_taxonomy_id']; // Keep the term taxonomy id for future
|
197 |
-
}
|
198 |
-
|
199 |
-
// Get all terms with a language defined
|
200 |
-
$terms = $wpdb->get_results( "SELECT term_id, meta_value FROM {$wpdb->termmeta} WHERE meta_key = '_language'" );
|
201 |
-
foreach ( $terms as $key => $term ) {
|
202 |
-
$terms[ $key ] = $wpdb->prepare( '( %d, %d )', $term->term_id, $lang_tt_ids[ $term->meta_value ] );
|
203 |
-
}
|
204 |
-
|
205 |
-
$terms = array_unique( $terms );
|
206 |
-
|
207 |
-
// Assign language to each term
|
208 |
-
if ( ! empty( $terms ) ) {
|
209 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
210 |
-
$wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $terms ) );
|
211 |
-
}
|
212 |
-
|
213 |
-
// Translations
|
214 |
-
foreach ( array( 'post', 'term' ) as $type ) {
|
215 |
-
$table = $type . 'meta';
|
216 |
-
$terms = array();
|
217 |
-
$slugs = array();
|
218 |
-
$tts = array();
|
219 |
-
$trs = array();
|
220 |
-
$description = array();
|
221 |
-
|
222 |
-
// Get all translated objects
|
223 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL
|
224 |
-
$objects = $wpdb->get_col( "SELECT DISTINCT meta_value FROM {$wpdb->$table} WHERE meta_key = '_translations'" );
|
225 |
-
|
226 |
-
if ( empty( $objects ) ) {
|
227 |
-
continue;
|
228 |
-
}
|
229 |
-
|
230 |
-
foreach ( $objects as $obj ) {
|
231 |
-
$term = uniqid( 'pll_' ); // The term name
|
232 |
-
$terms[] = $wpdb->prepare( '( %s, %s )', $term, $term );
|
233 |
-
$slugs[] = $wpdb->prepare( '%s', $term );
|
234 |
-
$translations = maybe_unserialize( maybe_unserialize( $obj ) ); // 2 maybe_unserialize due to an old storage bug
|
235 |
-
$description[ $term ] = maybe_serialize( $translations );
|
236 |
-
}
|
237 |
-
|
238 |
-
$terms = array_unique( $terms );
|
239 |
-
|
240 |
-
// Insert terms
|
241 |
-
if ( ! empty( $terms ) ) {
|
242 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
243 |
-
$wpdb->query( "INSERT INTO {$wpdb->terms} ( slug, name ) VALUES " . implode( ',', $terms ) );
|
244 |
-
}
|
245 |
-
|
246 |
-
// Get all terms with their term_id
|
247 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
248 |
-
$terms = $wpdb->get_results( "SELECT term_id, slug FROM $wpdb->terms WHERE slug IN ( " . implode( ',', $slugs ) . ' )' );
|
249 |
-
|
250 |
-
// Prepare terms taxonomy relationship
|
251 |
-
foreach ( $terms as $term ) {
|
252 |
-
$tts[] = $wpdb->prepare( '( %d, %s, %s )', $term->term_id, $type . '_translations', $description[ $term->slug ] );
|
253 |
-
}
|
254 |
-
|
255 |
-
$tts = array_unique( $tts );
|
256 |
-
|
257 |
-
// Insert term_taxonomy
|
258 |
-
if ( ! empty( $tts ) ) {
|
259 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
260 |
-
$wpdb->query( "INSERT INTO {$wpdb->term_taxonomy} ( term_id, taxonomy, description ) VALUES " . implode( ',', $tts ) );
|
261 |
-
}
|
262 |
-
|
263 |
-
// Get all terms with term_taxonomy_id
|
264 |
-
$terms = get_terms( $type . '_translations', array( 'hide_empty' => false ) );
|
265 |
-
|
266 |
-
// Prepare objects relationships
|
267 |
-
foreach ( $terms as $term ) {
|
268 |
-
$translations = maybe_unserialize( $term->description );
|
269 |
-
foreach ( $translations as $object_id ) {
|
270 |
-
if ( ! empty( $object_id ) ) {
|
271 |
-
$trs[] = $wpdb->prepare( '( %d, %d )', $object_id, $term->term_taxonomy_id );
|
272 |
-
}
|
273 |
-
}
|
274 |
-
}
|
275 |
-
|
276 |
-
$trs = array_unique( $trs );
|
277 |
-
|
278 |
-
// Insert term_relationships
|
279 |
-
if ( ! empty( $trs ) ) {
|
280 |
-
// PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
|
281 |
-
$wpdb->query( "INSERT INTO {$wpdb->term_relationships} ( object_id, term_taxonomy_id ) VALUES " . implode( ',', $trs ) );
|
282 |
-
}
|
283 |
-
}
|
284 |
-
|
285 |
-
// Upgrade of string translations is now in upgrade_1_2_1
|
286 |
-
// Upgrade of nav menus is now in upgrade_1_2_3
|
287 |
-
}
|
288 |
-
|
289 |
-
/**
|
290 |
-
* Upgrades if the previous version is < 1.2.1
|
291 |
-
*
|
292 |
-
* @since 1.2.1
|
293 |
-
*/
|
294 |
-
protected function upgrade_1_2_1() {
|
295 |
-
// Strings translations
|
296 |
-
foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
|
297 |
-
if ( $strings = get_option( 'polylang_mo' . $lang->term_id ) ) {
|
298 |
-
$mo = new PLL_MO();
|
299 |
-
foreach ( $strings as $msg ) {
|
300 |
-
$mo->add_entry( $mo->make_entry( $msg[0], $msg[1] ) );
|
301 |
-
}
|
302 |
-
$mo->export_to_db( $lang );
|
303 |
-
}
|
304 |
-
}
|
305 |
-
}
|
306 |
-
|
307 |
-
/**
|
308 |
-
* Upgrades if the previous version is < 1.2.3
|
309 |
-
* Uprades multilingual menus depending on the old version due to multiple changes in menus management
|
310 |
-
*
|
311 |
-
* @since 1.2.3
|
312 |
-
*/
|
313 |
-
public function upgrade_1_2_3() {
|
314 |
-
// Old version < 1.1
|
315 |
-
// Multilingal locations and switcher item were stored in a dedicated option
|
316 |
-
if ( version_compare( $this->options['version'], '1.1', '<' ) ) {
|
317 |
-
if ( $menu_lang = get_option( 'polylang_nav_menus' ) ) {
|
318 |
-
$locations = array();
|
319 |
-
|
320 |
-
foreach ( $menu_lang as $location => $arr ) {
|
321 |
-
if ( ! in_array( $location, array_keys( get_registered_nav_menus() ) ) ) {
|
322 |
-
continue;
|
323 |
-
}
|
324 |
-
|
325 |
-
$switch_options = array_slice( $arr, -5, 5 );
|
326 |
-
$translations = array_diff_key( $arr, $switch_options );
|
327 |
-
$has_switcher = array_shift( $switch_options );
|
328 |
-
|
329 |
-
foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
|
330 |
-
// Move nav menus locations
|
331 |
-
if ( ! empty( $translations[ $lang->slug ] ) ) {
|
332 |
-
$locations[ $location ][ $lang->slug ] = $translations[ $lang->slug ];
|
333 |
-
}
|
334 |
-
|
335 |
-
// Create the menu items for the language switcher
|
336 |
-
if ( ! empty( $has_switcher ) ) {
|
337 |
-
$menu_item_db_id = wp_update_nav_menu_item(
|
338 |
-
$translations[ $lang->slug ],
|
339 |
-
0,
|
340 |
-
array(
|
341 |
-
'menu-item-title' => __( 'Language switcher', 'polylang' ),
|
342 |
-
'menu-item-url' => '#pll_switcher',
|
343 |
-
'menu-item-status' => 'publish',
|
344 |
-
)
|
345 |
-
);
|
346 |
-
|
347 |
-
update_post_meta( $menu_item_db_id, '_pll_menu_item', $switch_options );
|
348 |
-
}
|
349 |
-
}
|
350 |
-
}
|
351 |
-
|
352 |
-
if ( ! empty( $locations ) ) {
|
353 |
-
$this->options['nav_menus'][ get_option( 'stylesheet' ) ] = $locations;
|
354 |
-
}
|
355 |
-
|
356 |
-
delete_option( 'polylang_nav_menus' );
|
357 |
-
}
|
358 |
-
}
|
359 |
-
|
360 |
-
elseif ( empty( $this->options['nav_menus'] ) ) {
|
361 |
-
$menus = get_theme_mod( 'nav_menu_locations' );
|
362 |
-
|
363 |
-
if ( is_array( $menus ) ) {
|
364 |
-
// If old version < 1.2
|
365 |
-
// Clean the WP option as it was a bad idea to pollute it
|
366 |
-
if ( version_compare( $this->options['version'], '1.2', '<' ) ) {
|
367 |
-
foreach ( $menus as $loc => $menu ) {
|
368 |
-
if ( strpos( $loc, '#' ) ) {
|
369 |
-
unset( $menus[ $loc ] );
|
370 |
-
}
|
371 |
-
}
|
372 |
-
|
373 |
-
set_theme_mod( 'nav_menu_locations', $menus );
|
374 |
-
}
|
375 |
-
|
376 |
-
// Get the multilingual locations
|
377 |
-
foreach ( $menus as $loc => $menu ) {
|
378 |
-
foreach ( get_terms( 'language', array( 'hide_empty' => 0 ) ) as $lang ) {
|
379 |
-
$arr[ $loc ][ $lang->slug ] = pll_get_term( $menu, $lang );
|
380 |
-
}
|
381 |
-
}
|
382 |
-
|
383 |
-
if ( ! empty( $arr ) ) {
|
384 |
-
$this->options['nav_menus'][ get_option( 'stylesheet' ) ] = $arr;
|
385 |
-
}
|
386 |
-
}
|
387 |
-
}
|
388 |
-
}
|
389 |
-
|
390 |
-
/**
|
391 |
-
* Upgrades if the previous version is < 1.3
|
392 |
-
* Moves the user biographies in default language to the 'description' user meta
|
393 |
-
*
|
394 |
-
* @since 1.3
|
395 |
-
*/
|
396 |
-
protected function upgrade_1_3() {
|
397 |
-
$usermeta = 'description_' . $this->options['default_lang'];
|
398 |
-
$query = new WP_User_Query( array( 'blog_id' => $GLOBALS['blog_id'], 'meta_key' => $usermeta ) );
|
399 |
-
|
400 |
-
foreach ( $query->get_results() as $user ) {
|
401 |
-
$desc = get_user_meta( $user->ID, $usermeta, true );
|
402 |
-
if ( ! empty( $desc ) ) {
|
403 |
-
update_user_meta( $user->ID, 'description', $desc );
|
404 |
-
delete_user_meta( $user->ID, $usermeta );
|
405 |
-
}
|
406 |
-
}
|
407 |
-
}
|
408 |
-
|
409 |
-
/**
|
410 |
-
* Upgrades if the previous version is < 1.4
|
411 |
-
* Sets a transient to delete old model data
|
412 |
-
* Deletes language cache (due to bug correction in home urls in 1.3.1 and added mo_id in 1.4)
|
413 |
-
*
|
414 |
-
* @since 1.4
|
415 |
-
*/
|
416 |
-
protected function upgrade_1_4() {
|
417 |
-
set_transient( 'pll_upgrade_1_4', time() + 60 * 24 * 60 * 60 ); // 60 days
|
418 |
-
delete_transient( 'pll_languages_list' );
|
419 |
-
}
|
420 |
-
|
421 |
-
/**
|
422 |
-
* Old data were not deleted in 1.2, just in case...
|
423 |
-
* Delete them at first upgrade at least 60 days after upgrade to 1.4
|
424 |
-
*
|
425 |
-
* @since 1.4
|
426 |
-
*/
|
427 |
-
protected function delete_pre_1_2_data() {
|
428 |
-
// Suppress data of the old model < 1.2
|
429 |
-
global $wpdb;
|
430 |
-
$wpdb->termmeta = $wpdb->prefix . 'termmeta'; // registers the termmeta table in wpdb in case WP < 4.4
|
431 |
-
|
432 |
-
// Do nothing if the termmeta table does not exists
|
433 |
-
if ( count( $wpdb->get_results( "SHOW TABLES LIKE '$wpdb->termmeta'" ) ) ) {
|
434 |
-
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_translations'" );
|
435 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_language'" );
|
436 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_rtl'" );
|
437 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_translations'" );
|
438 |
-
}
|
439 |
-
|
440 |
-
// Delete the strings translations
|
441 |
-
$languages = get_terms( 'language', array( 'hide_empty' => false ) );
|
442 |
-
foreach ( $languages as $lang ) {
|
443 |
-
delete_option( 'polylang_mo' . $lang->term_id );
|
444 |
-
}
|
445 |
-
|
446 |
-
delete_transient( 'pll_upgrade_1_4' );
|
447 |
-
}
|
448 |
-
|
449 |
-
/**
|
450 |
-
* Upgrades if the previous version is < 1.4.1
|
451 |
-
* Disables the browser detection when using multiple domains
|
452 |
-
*
|
453 |
-
* @since 1.4.1
|
454 |
-
*/
|
455 |
-
protected function upgrade_1_4_1() {
|
456 |
-
if ( 3 == $this->options['force_lang'] ) {
|
457 |
-
$this->options['browser'] = $this->options['hide_default'] = 0;
|
458 |
-
}
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Upgrades if the previous version is < 1.4.4
|
463 |
-
* Uprades widgets options for language filter
|
464 |
-
*
|
465 |
-
* @since 1.4.4
|
466 |
-
*/
|
467 |
-
protected function upgrade_1_4_4() {
|
468 |
-
foreach ( $GLOBALS['wp_registered_widgets'] as $widget ) {
|
469 |
-
if ( ! empty( $this->options['widgets'][ $widget['id'] ] ) && ! empty( $widget['callback'][0] ) && ! empty( $widget['params'][0]['number'] ) ) {
|
470 |
-
$obj = $widget['callback'][0];
|
471 |
-
if ( is_object( $obj ) && method_exists( $obj, 'get_settings' ) && method_exists( $obj, 'save_settings' ) ) {
|
472 |
-
$settings = $obj->get_settings();
|
473 |
-
$settings[ $widget['params'][0]['number'] ]['pll_lang'] = $this->options['widgets'][ $widget['id'] ];
|
474 |
-
$obj->save_settings( $settings );
|
475 |
-
}
|
476 |
-
}
|
477 |
-
}
|
478 |
-
unset( $this->options['widgets'] );
|
479 |
-
}
|
480 |
-
|
481 |
-
/**
|
482 |
-
* Upgrades if the previous version is < 1.5
|
483 |
-
* Deletes language cache (due to host property added and bug on search url)
|
484 |
-
*
|
485 |
-
* @since 1.5
|
486 |
-
*/
|
487 |
-
protected function upgrade_1_5() {
|
488 |
-
delete_transient( 'pll_languages_list' );
|
489 |
-
}
|
490 |
-
|
491 |
-
/**
|
492 |
-
* Upgrades if the previous version is < 1.6
|
493 |
-
* Upgrades core language files to get the .po file (only for WP 4.0+)
|
494 |
-
*
|
495 |
-
* @since 1.6
|
496 |
-
*/
|
497 |
-
protected function upgrade_1_6() {
|
498 |
-
if ( version_compare( $GLOBALS['wp_version'], '4.0', '>=' ) ) {
|
499 |
-
self::download_language_packs();
|
500 |
-
}
|
501 |
-
}
|
502 |
-
|
503 |
-
/**
|
504 |
-
* Downloads language packs
|
505 |
-
* Intended to be used only one time (at upgrade to Polylang 1.6 or first upgrade of WP 4.0 or later)
|
506 |
-
* Adapted from wp_download_language_pack
|
507 |
-
* Rewritten because wp_download_language_pack checks the existence of .mo and I need to download .po
|
508 |
-
*
|
509 |
-
* @since 1.6
|
510 |
-
*/
|
511 |
-
public static function download_language_packs() {
|
512 |
-
$languages = pll_languages_list( array( 'fields' => 'locale' ) );
|
513 |
-
|
514 |
-
// Prevents upgrade if the .po file is already here. Let WP manage the upgrades :)
|
515 |
-
foreach ( $languages as $key => $locale ) {
|
516 |
-
if ( file_exists( WP_LANG_DIR . "/$locale.po" ) ) {
|
517 |
-
unset( $languages[ $key ] );
|
518 |
-
}
|
519 |
-
}
|
520 |
-
|
521 |
-
if ( empty( $languages ) ) {
|
522 |
-
return;
|
523 |
-
}
|
524 |
-
|
525 |
-
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
526 |
-
$translations = wp_get_available_translations();
|
527 |
-
if ( ! $translations ) {
|
528 |
-
return;
|
529 |
-
}
|
530 |
-
|
531 |
-
$translations_to_load = array();
|
532 |
-
|
533 |
-
foreach ( $translations as $translation ) {
|
534 |
-
if ( in_array( $translation['language'], $languages ) ) {
|
535 |
-
$translation['type'] = 'core';
|
536 |
-
$translations_to_load[] = (object) $translation;
|
537 |
-
}
|
538 |
-
}
|
539 |
-
|
540 |
-
if ( ! empty( $translations_to_load ) ) {
|
541 |
-
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
542 |
-
$upgrader = new Language_Pack_Upgrader( new Automatic_Upgrader_Skin() );
|
543 |
-
$upgrader->bulk_upgrade( $translations_to_load, array( 'clear_update_cache' => false ) );
|
544 |
-
}
|
545 |
-
}
|
546 |
-
|
547 |
-
/**
|
548 |
-
* Upgrades if the previous version is < 1.7.4
|
549 |
-
*
|
550 |
-
* @since 1.7.4
|
551 |
-
*/
|
552 |
-
protected function upgrade_1_7_4() {
|
553 |
-
delete_transient( 'pll_languages_list' ); // Deletes language cache (due to flag properties added in 1.7, page on front removed in 1.7.2, home url fixes in 1.7.4)
|
554 |
-
flush_rewrite_rules(); // Flush rewrite rules due to custom taxonomy rewrite rule bug fix
|
555 |
-
}
|
556 |
-
|
557 |
-
/**
|
558 |
-
* Upgrades if the previous version is < 1.8
|
559 |
-
*
|
560 |
-
* @since 1.8
|
561 |
-
*/
|
562 |
-
protected function upgrade_1_8() {
|
563 |
-
// Adds the flag code in languages stored in DB
|
564 |
-
$languages = include POLYLANG_DIR . '/settings/languages.php';
|
565 |
-
|
566 |
-
$terms = get_terms( 'language', array( 'hide_empty' => 0 ) );
|
567 |
-
|
568 |
-
foreach ( $terms as $lang ) {
|
569 |
-
$description = maybe_unserialize( $lang->description );
|
570 |
-
if ( isset( $languages[ $description['locale'] ] ) ) {
|
571 |
-
$description['flag_code'] = $languages[ $description['locale'] ]['flag'];
|
572 |
-
$description = maybe_serialize( $description );
|
573 |
-
wp_update_term( (int) $lang->term_id, 'language', array( 'description' => $description ) );
|
574 |
-
}
|
575 |
-
}
|
576 |
-
|
577 |
-
delete_transient( 'pll_languages_list' );
|
578 |
-
}
|
579 |
-
|
580 |
/**
|
581 |
* Upgrades if the previous version is < 2.0.8
|
582 |
* Changes the user meta 'user_lang' to 'locale' to match WP 4.7 choice
|
583 |
*
|
584 |
* @since 2.0.8
|
|
|
|
|
585 |
*/
|
586 |
protected function upgrade_2_0_8() {
|
587 |
global $wpdb;
|
@@ -589,21 +128,32 @@ class PLL_Upgrade {
|
|
589 |
}
|
590 |
|
591 |
/**
|
592 |
-
* Upgrades if the previous version is < 2.1
|
593 |
-
* Moves strings translations from polylang_mo post_content to post meta _pll_strings_translations
|
594 |
*
|
595 |
* @since 2.1
|
|
|
|
|
596 |
*/
|
597 |
protected function upgrade_2_1() {
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
}
|
608 |
}
|
609 |
}
|
@@ -615,6 +165,8 @@ class PLL_Upgrade {
|
|
615 |
* Dismiss the wizard notice for existing sites
|
616 |
*
|
617 |
* @since 2.7
|
|
|
|
|
618 |
*/
|
619 |
protected function upgrade_2_7() {
|
620 |
$strings = get_option( 'polylang_wpml_strings' );
|
@@ -644,6 +196,8 @@ class PLL_Upgrade {
|
|
644 |
* - bug of flags url returning html fixed in 2.8.1
|
645 |
*
|
646 |
* @since 2.8.1
|
|
|
|
|
647 |
*/
|
648 |
protected function upgrade_2_8_1() {
|
649 |
delete_transient( 'pll_languages_list' );
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Upgrade {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
public $options;
|
18 |
|
19 |
/**
|
31 |
* Check if upgrade is possible otherwise die to avoid activation
|
32 |
*
|
33 |
* @since 1.2
|
34 |
+
*
|
35 |
+
* @return void
|
36 |
*/
|
37 |
public function can_activate() {
|
38 |
if ( ! $this->can_upgrade() ) {
|
70 |
* @return bool true if upgrade is possible, false otherwise
|
71 |
*/
|
72 |
public function can_upgrade() {
|
73 |
+
// Don't manage upgrade from version < 1.8
|
74 |
+
return version_compare( $this->options['version'], '1.8', '>=' );
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
* Displays a notice when ugrading from a too old version
|
79 |
*
|
80 |
* @since 1.0
|
81 |
+
*
|
82 |
+
* @return void
|
83 |
*/
|
84 |
public function admin_notices() {
|
85 |
load_plugin_textdomain( 'polylang' );
|
89 |
sprintf(
|
90 |
/* translators: %1$s and %2$s are Polylang version numbers */
|
91 |
esc_html__( 'Before upgrading to %2$s, please upgrade to %1$s.', 'polylang' ),
|
92 |
+
'<strong>2.9</strong>',
|
93 |
POLYLANG_VERSION // phpcs:ignore WordPress.Security.EscapeOutput
|
94 |
)
|
95 |
);
|
99 |
* Upgrades the plugin depending on the previous version
|
100 |
*
|
101 |
* @since 1.2
|
102 |
+
*
|
103 |
+
* @return void
|
104 |
*/
|
105 |
public function _upgrade() {
|
106 |
+
foreach ( array( '2.0.8', '2.1', '2.7', '2.8.1' ) as $version ) {
|
107 |
if ( version_compare( $this->options['version'], $version, '<' ) ) {
|
108 |
call_user_func( array( $this, 'upgrade_' . str_replace( '.', '_', $version ) ) );
|
109 |
}
|
110 |
}
|
111 |
|
|
|
|
|
|
|
|
|
|
|
112 |
$this->options['previous_version'] = $this->options['version']; // Remember the previous version of Polylang since v1.7.7
|
113 |
$this->options['version'] = POLYLANG_VERSION;
|
114 |
update_option( 'polylang', $this->options );
|
115 |
}
|
116 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
/**
|
118 |
* Upgrades if the previous version is < 2.0.8
|
119 |
* Changes the user meta 'user_lang' to 'locale' to match WP 4.7 choice
|
120 |
*
|
121 |
* @since 2.0.8
|
122 |
+
*
|
123 |
+
* @return void
|
124 |
*/
|
125 |
protected function upgrade_2_0_8() {
|
126 |
global $wpdb;
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
+
* Upgrades if the previous version is < 2.1.
|
132 |
+
* Moves strings translations from polylang_mo post_content to post meta _pll_strings_translations.
|
133 |
*
|
134 |
* @since 2.1
|
135 |
+
*
|
136 |
+
* @return void
|
137 |
*/
|
138 |
protected function upgrade_2_1() {
|
139 |
+
$posts = get_posts(
|
140 |
+
array(
|
141 |
+
'post_type' => 'polylang_mo',
|
142 |
+
'post_status' => 'any',
|
143 |
+
'numberposts' => -1,
|
144 |
+
'nopaging' => true,
|
145 |
+
)
|
146 |
+
);
|
147 |
+
|
148 |
+
if ( is_array( $posts ) ) {
|
149 |
+
foreach ( $posts as $post ) {
|
150 |
+
$meta = get_post_meta( $post->ID, '_pll_strings_translations', true );
|
151 |
|
152 |
+
if ( empty( $meta ) ) {
|
153 |
+
$strings = maybe_unserialize( $post->post_content );
|
154 |
+
if ( is_array( $strings ) ) {
|
155 |
+
update_post_meta( $post->ID, '_pll_strings_translations', $strings );
|
156 |
+
}
|
157 |
}
|
158 |
}
|
159 |
}
|
165 |
* Dismiss the wizard notice for existing sites
|
166 |
*
|
167 |
* @since 2.7
|
168 |
+
*
|
169 |
+
* @return void
|
170 |
*/
|
171 |
protected function upgrade_2_7() {
|
172 |
$strings = get_option( 'polylang_wpml_strings' );
|
196 |
* - bug of flags url returning html fixed in 2.8.1
|
197 |
*
|
198 |
* @since 2.8.1
|
199 |
+
*
|
200 |
+
* @return void
|
201 |
*/
|
202 |
protected function upgrade_2_8_1() {
|
203 |
delete_transient( 'pll_languages_list' );
|
integrations/cache/cache-compat.php
CHANGED
@@ -27,13 +27,18 @@ class PLL_Cache_Compat {
|
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
-
* Currently all tested cache plugins don't send cookies with cached pages
|
31 |
-
* This makes us impossible know the language of the last browsed page
|
32 |
-
* This functions allows to create the cookie in javascript as a workaround
|
33 |
*
|
34 |
* @since 2.3
|
35 |
*/
|
36 |
public function add_cookie_script() {
|
|
|
|
|
|
|
|
|
|
|
37 |
$domain = ( 2 === PLL()->options['force_lang'] ) ? wp_parse_url( PLL()->links_model->home, PHP_URL_HOST ) : COOKIE_DOMAIN;
|
38 |
$samesite = ( 3 === PLL()->options['force_lang'] ) ? 'None' : 'Lax';
|
39 |
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
+
* Currently all tested cache plugins don't send cookies with cached pages.
|
31 |
+
* This makes us impossible to know the language of the last browsed page.
|
32 |
+
* This functions allows to create the cookie in javascript as a workaround.
|
33 |
*
|
34 |
* @since 2.3
|
35 |
*/
|
36 |
public function add_cookie_script() {
|
37 |
+
// Embeds should not set the cookie.
|
38 |
+
if ( is_embed() ) {
|
39 |
+
return;
|
40 |
+
}
|
41 |
+
|
42 |
$domain = ( 2 === PLL()->options['force_lang'] ) ? wp_parse_url( PLL()->links_model->home, PHP_URL_HOST ) : COOKIE_DOMAIN;
|
43 |
$samesite = ( 3 === PLL()->options['force_lang'] ) ? 'None' : 'Lax';
|
44 |
|
integrations/custom-field-template/cft.php
CHANGED
@@ -23,8 +23,8 @@ class PLL_Cft {
|
|
23 |
*
|
24 |
* @since 1.0.2
|
25 |
*
|
26 |
-
* @param string
|
27 |
-
* @param
|
28 |
*/
|
29 |
public function cft_copy( $post_type, $post ) {
|
30 |
global $custom_field_template;
|
23 |
*
|
24 |
* @since 1.0.2
|
25 |
*
|
26 |
+
* @param string $post_type Unused.
|
27 |
+
* @param WP_Post $post Current post object.
|
28 |
*/
|
29 |
public function cft_copy( $post_type, $post ) {
|
30 |
global $custom_field_template;
|
integrations/wp-importer/wp-import.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_WP_Import extends WP_Import {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $post_translations = array();
|
13 |
|
14 |
/**
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_WP_Import extends WP_Import {
|
12 |
+
/**
|
13 |
+
* Stores post_translations terms.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
public $post_translations = array();
|
18 |
|
19 |
/**
|
integrations/wp-offload-media/as3cf.php
CHANGED
@@ -10,6 +10,11 @@
|
|
10 |
* @since 2.6
|
11 |
*/
|
12 |
class PLL_AS3CF {
|
|
|
|
|
|
|
|
|
|
|
13 |
private $is_media_translated;
|
14 |
|
15 |
/**
|
10 |
* @since 2.6
|
11 |
*/
|
12 |
class PLL_AS3CF {
|
13 |
+
/**
|
14 |
+
* Stores if a media is translated when it is deleted.
|
15 |
+
*
|
16 |
+
* @var bool[]
|
17 |
+
*/
|
18 |
private $is_media_translated;
|
19 |
|
20 |
/**
|
integrations/wpseo/wpseo.php
CHANGED
@@ -84,6 +84,7 @@ class PLL_WPSEO {
|
|
84 |
}
|
85 |
|
86 |
if ( ! empty( $keys ) ) {
|
|
|
87 |
new PLL_Translate_Option( 'wpseo_titles', array_fill_keys( $keys, 1 ), array( 'context' => 'wordpress-seo' ) );
|
88 |
}
|
89 |
}
|
@@ -195,11 +196,11 @@ class PLL_WPSEO {
|
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
* Add filters before the sitemap is evaluated and outputed
|
199 |
*
|
200 |
* @since 2.6
|
201 |
*
|
202 |
-
* @param
|
203 |
*/
|
204 |
public function before_sitemap( $query ) {
|
205 |
$type = $query->get( 'sitemap' );
|
84 |
}
|
85 |
|
86 |
if ( ! empty( $keys ) ) {
|
87 |
+
WPSEO_Options::clear_cache();
|
88 |
new PLL_Translate_Option( 'wpseo_titles', array_fill_keys( $keys, 1 ), array( 'context' => 'wordpress-seo' ) );
|
89 |
}
|
90 |
}
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* Add filters before the sitemap is evaluated and outputed.
|
200 |
*
|
201 |
* @since 2.6
|
202 |
*
|
203 |
+
* @param WP_Query $query Instance of WP_Query being filtered.
|
204 |
*/
|
205 |
public function before_sitemap( $query ) {
|
206 |
$type = $query->get( 'sitemap' );
|
js/admin.js
CHANGED
@@ -111,7 +111,13 @@ jQuery(
|
|
111 |
*/
|
112 |
|
113 |
// Selectmenu widget options
|
114 |
-
var selectmenuOptions = {
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
// Selectmenu widget callbacks
|
117 |
var selectmenuFlagListCallbacks = {};
|
@@ -306,7 +312,7 @@ jQuery(
|
|
306 |
function() {
|
307 |
var $this = $( this ),
|
308 |
$button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
|
309 |
-
btnText =
|
310 |
|
311 |
// Ensure plain text
|
312 |
$button.find( '.screen-reader-text' ).text( btnText );
|
111 |
*/
|
112 |
|
113 |
// Selectmenu widget options
|
114 |
+
var selectmenuOptions = {
|
115 |
+
width: defaultSelectmenuWidth,
|
116 |
+
classes: {
|
117 |
+
'ui-selectmenu-menu': 'pll-selectmenu-menu',
|
118 |
+
'ui-selectmenu-button': 'pll-selectmenu-button',
|
119 |
+
}
|
120 |
+
};
|
121 |
|
122 |
// Selectmenu widget callbacks
|
123 |
var selectmenuFlagListCallbacks = {};
|
312 |
function() {
|
313 |
var $this = $( this ),
|
314 |
$button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
|
315 |
+
btnText = pll_admin.dismiss_notice || '';
|
316 |
|
317 |
// Ensure plain text
|
318 |
$button.find( '.screen-reader-text' ).text( btnText );
|
js/admin.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery((function($){var transitionTimeout;$("table.languages").on({focusin:function(){clearTimeout(transitionTimeout);var focusedRowActions=$(this).find(".row-actions");$(".row-actions").not(this).removeClass("visible"),focusedRowActions.addClass("visible")},focusout:function(){transitionTimeout=setTimeout((function(){focusedRowActions.removeClass("visible")}),30)}},"tr");var isJqueryUImin112=$.ui.version>="1.12.0",flagListExist=$("#flag_list").length,langListExist=$("#lang_list").length,defaultSelectmenuWidth="95%",wizardSelectmenuWidth="100%",selectmenuRenderItem=function(ul,item){var li=$("<li>"),wrapper=$("<div>");return item.disabled&&this._addClass(li,null,"ui-state-disabled"),this._setText(wrapper,item.label),wrapper.prepend($(item.element).data("flag-html")),wrapper.children("img").addClass("ui-icon"),li.append(wrapper).appendTo(ul)},selectmenuRefreshButtonText=function(selectElement){var buttonText=$(selectElement).selectmenu("instance").buttonText;buttonText.prepend($(selectElement).children(":selected").data("flag-html")),buttonText.children("img").addClass("ui-icon")},selectmenuRenderButtonItem=function(selectElement){var buttonItem=$("<span>");return this._setText(buttonItem,selectElement.label),this._addClass(buttonItem,"ui-selectmenu-text"),buttonItem.prepend($(selectElement.element).data("flag-html")),buttonItem.children("img").addClass("ui-icon"),buttonItem};function initializeSelectmenuWidget(element,config){var selectmenuWidgetInstance=element.selectmenu(config).selectmenu("instance");return selectmenuWidgetInstance._renderItem=selectmenuRenderItem,isJqueryUImin112&&(selectmenuWidgetInstance._renderButtonItem=selectmenuRenderButtonItem,selectmenuWidgetInstance.refresh()),selectmenuWidgetInstance}var selectmenuOptions={width:"95%"},selectmenuFlagListCallbacks={},createSelectCallback=function(event,ui){selectmenuRefreshButtonText(event.target)},changeOpenCallback=function(event,ui){selectmenuRefreshButtonText($(event.target).selectmenu("refresh"))},changeOpenCallbackjQueryUI112=function(event,ui){$(event.target).selectmenu("refresh")};if(selectmenuFlagListCallbacks=isJqueryUImin112?{change:changeOpenCallbackjQueryUI112,open:changeOpenCallbackjQueryUI112}:{create:createSelectCallback,select:createSelectCallback,change:changeOpenCallback,open:changeOpenCallback},flagListExist){var selectmenuFlagList=initializeSelectmenuWidget($("#flag_list"),Object.assign({},selectmenuOptions,selectmenuFlagListCallbacks));$("#lang_list").on("languageChanged",(function(event,flag){selectmenuFlagList.element.val(flag),selectmenuFlagList._trigger("change")}))}function fillLanguageFields(language){$("#lang_slug").val(language.slug),$("#lang_locale").val(language.locale),$('input[name="rtl"]').val(language.rtl),$("#lang_name").val(language.name)}function parseSelectedLanguage(event){var selectedElement=$("option:selected",event.target),values=selectedElement.val().split(":");return{slug:values[0],locale:values[1],rtl:[values[2]],flag:values[3],name:selectedElement.text().split(" - ")[0]}}var changeCallback=function(event,ui){var language=parseSelectedLanguage(event);fillLanguageFields(language),$(event.target).trigger("languageChanged",language.flag)},selectmenuLangListCallbacks={};$("#lang_list").closest(".pll-wizard-content").length>0&&(selectmenuOptions=Object.assign(selectmenuOptions,{width:"100%"})),selectmenuLangListCallbacks=isJqueryUImin112?{change:changeCallback}:{create:createSelectCallback,select:createSelectCallback,change:changeCallback},langListExist&&initializeSelectmenuWidget($("#lang_list"),Object.assign({},selectmenuOptions,selectmenuLangListCallbacks)),$(".translation input").on("keydown",(function(event){"Enter"===event.key&&(event.preventDefault(),$("#submit").trigger("click"))})),$("#the-list").on("click",".configure>a",(function(){return $(".pll-configure").hide().prev().show(),$(this).closest("tr").hide().next().show(),!1})),$("#the-list").on("click",".cancel",(function(){$(this).closest("tr").hide().prev().show()})),$("#the-list").on("click",".save",(function(){var tr=$(this).closest("tr"),parts=tr.attr("id").split("-"),data={action:"pll_save_options",pll_ajax_settings:!0,module:parts[parts.length-1],_pll_nonce:$("#_pll_nonce").val()};data=tr.find(":input").serialize()+"&"+$.param(data),$.post(ajaxurl,data,(function(response){var res=wpAjax.parseAjaxResponse(response,"ajax-response");$.each(res.responses,(function(){switch(this.what){case"license-update":$("#pll-license-"+this.data).replaceWith(this.supplemental.html);break;case"success":tr.hide().prev().show();case"error":$(".settings-error").remove(),$("h1").after(this.data),$(".notice.is-dismissible").each((function(){var $this=$(this),$button=$('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),btnText=pll_dismiss_notice||"";$button.find(".screen-reader-text").text(btnText),$this.append($button),$button.on("click.wp-dismiss-notice",(function(event){event.preventDefault(),$this.fadeTo(100,0,(function(){$(this).slideUp(100,(function(){$(this).remove()}))}))}))}))}}))}))})),$(".pll-configure").on("keydown",(function(event){"Enter"===event.key&&(event.preventDefault(),$(this).find(".save").trigger("click")),"Escape"===event.key&&(event.preventDefault(),$(this).find(".cancel").trigger("click"))})),$("input[name='force_lang']").on("change",(function(){function pll_toggle(a,test){test?a.show():a.hide()}var value=$(this).val();pll_toggle($("#pll-domains-table"),3==value),pll_toggle($("#pll-hide-default"),3>value),pll_toggle($("#pll-rewrite"),2>value),pll_toggle($("#pll-redirect-lang"),2>value)})),$(".pll-deactivate-license").on("click",(function(){var data={action:"pll_deactivate_license",pll_ajax_settings:!0,id:$(this).attr("id"),_pll_nonce:$("#_pll_nonce").val()};$.post(ajaxurl,data,(function(response){$("#pll-license-"+response.id).replaceWith(response.html)}))})),$(".if-js-closed").removeClass("if-js-closed").addClass("closed"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(pagenow)}));
|
|
js/block-editor.js
CHANGED
@@ -2,6 +2,11 @@
|
|
2 |
* @package Polylang
|
3 |
*/
|
4 |
|
|
|
|
|
|
|
|
|
|
|
5 |
/**
|
6 |
* Filter REST API requests to add the language in the request
|
7 |
*
|
@@ -35,126 +40,170 @@ function getCurrentLanguage() {
|
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
-
*
|
|
|
|
|
|
|
|
|
|
|
39 |
*
|
40 |
* @since 2.5
|
|
|
|
|
|
|
|
|
41 |
*/
|
42 |
jQuery(
|
43 |
function( $ ) {
|
44 |
-
//
|
|
|
|
|
|
|
|
|
45 |
$( '.post_lang_choice' ).on(
|
46 |
'change',
|
47 |
-
function() {
|
48 |
const select = wp.data.select;
|
49 |
const dispatch = wp.data.dispatch;
|
50 |
const subscribe = wp.data.subscribe;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
const title =
|
76 |
-
const content =
|
77 |
-
const excerpt =
|
78 |
-
if ( '' === title && '' === content && '' === excerpt ) {
|
79 |
-
// Change the new_lang parameter with the new language value for reloading the page
|
80 |
-
// WPCS location.search is never written in the page, just used to relaoad page ( See line 94 ) with the right value of new_lang
|
81 |
-
// new_lang input is controlled server side in PHP. The value come from the dropdown list of language returned and escaped server side
|
82 |
-
if ( -1 != location.search.indexOf( 'new_lang' ) ) {
|
83 |
-
// use regexp non capturing group to replace new_lang parameter no matter where it is and capture other parameters which can be behind it
|
84 |
-
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
|
85 |
-
} else {
|
86 |
-
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
|
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 |
-
* Language select, autocomplete input field.
|
118 |
-
*
|
119 |
-
* @since 1.5
|
120 |
-
*/
|
121 |
-
jQuery(
|
122 |
-
function( $ ) {
|
123 |
-
// Ajax for changing the post's language in the languages metabox
|
124 |
-
$( '.post_lang_choice' ).on(
|
125 |
-
'change',
|
126 |
-
function() {
|
127 |
-
var data = {
|
128 |
-
action: 'post_lang_choice',
|
129 |
-
lang: $( this ).val(),
|
130 |
-
post_type: $( '#post_type' ).val(),
|
131 |
-
post_id: $( '#post_ID' ).val(),
|
132 |
-
_pll_nonce: $( '#_pll_nonce' ).val()
|
133 |
-
}
|
134 |
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
break;
|
153 |
-
}
|
154 |
-
}
|
155 |
-
);
|
156 |
-
}
|
157 |
-
);
|
158 |
}
|
159 |
);
|
160 |
|
2 |
* @package Polylang
|
3 |
*/
|
4 |
|
5 |
+
import {
|
6 |
+
initializeLanguageOldValue,
|
7 |
+
initializeConfimationModal
|
8 |
+
} from './lib/confirmation-modal';
|
9 |
+
|
10 |
/**
|
11 |
* Filter REST API requests to add the language in the request
|
12 |
*
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* Handles internals of the metabox:
|
44 |
+
* Language select, autocomplete input field.
|
45 |
+
*
|
46 |
+
* @since 1.5
|
47 |
+
*
|
48 |
+
* Save post after lang choice is done and redirect to the same page for refreshing all the data.
|
49 |
*
|
50 |
* @since 2.5
|
51 |
+
*
|
52 |
+
* Link post saving after refreshing the metabox.
|
53 |
+
*
|
54 |
+
* @since 3.0
|
55 |
*/
|
56 |
jQuery(
|
57 |
function( $ ) {
|
58 |
+
// Initialize current language to be able to compare if it changes.
|
59 |
+
initializeLanguageOldValue();
|
60 |
+
|
61 |
+
|
62 |
+
// Ajax for changing the post's language in the languages metabox
|
63 |
$( '.post_lang_choice' ).on(
|
64 |
'change',
|
65 |
+
function( event ) {
|
66 |
const select = wp.data.select;
|
67 |
const dispatch = wp.data.dispatch;
|
68 |
const subscribe = wp.data.subscribe;
|
69 |
+
const emptyPost = isEmptyPost();
|
70 |
+
|
71 |
+
// Initialize the confirmation dialog box.
|
72 |
+
const confirmationModal = initializeConfimationModal();
|
73 |
+
const { dialogContainer : dialog } = confirmationModal;
|
74 |
+
let { dialogResult } = confirmationModal;
|
75 |
+
// The selected option in the dropdown list.
|
76 |
+
const selectedOption = event.target;
|
77 |
+
|
78 |
+
// Specific case for empty posts.
|
79 |
+
// Place at the beginning because window.location changing triggers automatically page reloading.
|
80 |
+
if ( location.pathname.match( /post-new.php/gi ) && emptyPost ) {
|
81 |
+
reloadPageForEmptyPost( selectedOption.value );
|
82 |
+
}
|
83 |
|
84 |
+
// Otherwise send an ajax request to refresh the legacy metabox and set the post language with the new language.
|
85 |
+
// It needs a confirmation of the user before changing the language.
|
86 |
+
// Need to wait the ajax response before triggering the block editor post save action.
|
87 |
+
if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! emptyPost ) {
|
88 |
+
dialog.dialog( 'open' );
|
89 |
+
} else {
|
90 |
+
// Update the old language with the new one to be able to compare it in the next changing.
|
91 |
+
// Because the page isn't reloaded in this case.
|
92 |
+
initializeLanguageOldValue();
|
93 |
+
dialogResult = Promise.resolve();
|
94 |
+
}
|
95 |
+
|
96 |
+
dialogResult.then(
|
97 |
+
() => {
|
98 |
+
var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
99 |
+
action: 'post_lang_choice',
|
100 |
+
lang: selectedOption.value,
|
101 |
+
post_type: $( '#post_type' ).val(),
|
102 |
+
post_id: $( '#post_ID' ).val(),
|
103 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
104 |
+
}
|
105 |
+
|
106 |
+
$.post(
|
107 |
+
ajaxurl,
|
108 |
+
data,
|
109 |
+
function( response ) {
|
110 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
111 |
+
$.each(
|
112 |
+
res.responses,
|
113 |
+
function() {
|
114 |
+
switch ( this.what ) {
|
115 |
+
case 'translations': // Translations fields
|
116 |
+
// Data is built and come from server side and is well escaped when necessary
|
117 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
118 |
+
init_translations();
|
119 |
+
break;
|
120 |
+
case 'flag': // Flag in front of the select dropdown
|
121 |
+
// Data is built and come from server side and is well escaped when necessary
|
122 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
123 |
+
break;
|
124 |
+
}
|
125 |
}
|
126 |
+
);
|
127 |
+
blockEditorSavePostAndReloadPage();
|
128 |
}
|
129 |
);
|
130 |
+
},
|
131 |
+
() => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
|
132 |
);
|
133 |
|
134 |
+
function isEmptyPost() {
|
135 |
+
const editor = wp.data.select( 'core/editor' );
|
136 |
+
const title = editor.getEditedPostAttribute( 'title' ).trim();
|
137 |
+
const content = editor.getEditedPostAttribute( 'content' ).trim();
|
138 |
+
const excerpt = editor.getEditedPostAttribute( 'excerpt' ).trim();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
|
140 |
+
return ! title && ! content && ! excerpt;
|
141 |
+
}
|
142 |
|
143 |
+
/**
|
144 |
+
* Reload the block editor page for empty posts.
|
145 |
+
*
|
146 |
+
* @param {string} lang The target language code.
|
147 |
+
*/
|
148 |
+
function reloadPageForEmptyPost( lang ) {
|
149 |
+
// Change the new_lang parameter with the new language value for reloading the page
|
150 |
+
// WPCS location.search is never written in the page, just used to reload page with the right value of new_lang
|
151 |
+
// new_lang input is controlled server side in PHP. The value come from the dropdown list of language returned and escaped server side.
|
152 |
+
// Notice that window.location changing triggers automatically page reloading.
|
153 |
+
if ( -1 != location.search.indexOf( 'new_lang' ) ) {
|
154 |
+
// use regexp non capturing group to replace new_lang parameter no matter where it is and capture other parameters which can be behind it
|
155 |
+
window.location.search = window.location.search.replace( /(?:new_lang=[^&]*)(&)?(.*)/, 'new_lang=' + lang + '$1$2' ); // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
156 |
+
} else {
|
157 |
+
window.location.search = window.location.search + ( ( -1 != window.location.search.indexOf( '?' ) ) ? '&' : '?' ) + 'new_lang=' + lang; // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
158 |
}
|
159 |
+
};
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Triggers block editor post save and reload the block editor page when everything is ok.
|
163 |
+
*/
|
164 |
+
function blockEditorSavePostAndReloadPage() {
|
165 |
+
|
166 |
+
let unsubscribe = null;
|
167 |
+
|
168 |
+
// Listen if the savePost is completely done by subscribing to its events.
|
169 |
+
const savePostIsDone = new Promise(
|
170 |
+
function( resolve, reject ) {
|
171 |
+
unsubscribe = subscribe(
|
172 |
+
function() {
|
173 |
+
const isSavePostSucceeded = select( 'core/editor' ).didPostSaveRequestSucceed();
|
174 |
+
const isSavePostFailed = select( 'core/editor' ).didPostSaveRequestFail();
|
175 |
+
if ( isSavePostSucceeded || isSavePostFailed ) {
|
176 |
+
if ( isSavePostFailed ) {
|
177 |
+
reject();
|
178 |
+
} else {
|
179 |
+
resolve();
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
);
|
184 |
+
}
|
185 |
+
);
|
186 |
|
187 |
+
// Triggers the post save.
|
188 |
+
dispatch( 'core/editor' ).savePost();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
+
// Process
|
191 |
+
savePostIsDone.then(
|
192 |
+
function() {
|
193 |
+
// If the post is well saved, we can reload the page
|
194 |
+
window.location.reload();
|
195 |
+
},
|
196 |
+
function() {
|
197 |
+
// If the post save failed
|
198 |
+
unsubscribe();
|
199 |
+
}
|
200 |
+
).catch(
|
201 |
+
function() {
|
202 |
+
// If an exception is thrown
|
203 |
+
unsubscribe();
|
204 |
+
}
|
205 |
+
);
|
206 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
);
|
209 |
|
js/block-editor.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
function getCurrentLanguage(){return document.querySelector("[name=post_lang_choice]").value}wp.apiFetch.use((function(options,next){return void 0===options.url&&(void 0===options.data||null===options.data?options.path+=(options.path.indexOf("?")>=0?"&lang=":"?lang=")+getCurrentLanguage():options.data.lang=getCurrentLanguage()),next(options)})),jQuery((function($){$(".post_lang_choice").on("change",(function(){const select=wp.data.select,dispatch=wp.data.dispatch,subscribe=wp.data.subscribe;let unsubscribe=null;const savePostIsDone=new Promise((function(resolve,reject){unsubscribe=subscribe((function(){const isSavePostSucceeded=select("core/editor").didPostSaveRequestSucceed(),isSavePostFailed=select("core/editor").didPostSaveRequestFail();(isSavePostSucceeded||isSavePostFailed)&&(isSavePostFailed?reject():resolve())}))}));if(location.pathname.match(/post-new.php/gi)){const title=select("core/editor").getEditedPostAttribute("title"),content=select("core/editor").getEditedPostAttribute("content"),excerpt=select("core/editor").getEditedPostAttribute("excerpt");""===title&&""===content&&""===excerpt&&(-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)}dispatch("core/editor").savePost(),savePostIsDone.then((function(){unsubscribe(),window.location.reload()}),(function(){unsubscribe()})).catch((function(){unsubscribe()}))}))})),jQuery((function($){function init_translations(){$(".tr_lang").each((function(){var tr_lang=$(this).attr("id").substring(8),td=$(this).parent().parent().siblings(".pll-edit-column");$(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+$(".post_lang_choice").val()+"&translation_language="+tr_lang+"&post_type="+$("#post_type").val()+"&_pll_nonce="+$("#_pll_nonce").val(),select:function(event,ui){$("#htr_lang_"+tr_lang).val(ui.item.id),td.html(ui.item.link)}}),$(this).on("blur",(function(){$(this).val()||($("#htr_lang_"+tr_lang).val(0),td.html(td.siblings(".hidden").children().clone()))}))}))}$(".post_lang_choice").on("change",(function(){var data={action:"post_lang_choice",lang:$(this).val(),post_type:$("#post_type").val(),post_id:$("#post_ID").val(),_pll_nonce:$("#_pll_nonce").val()};$.post(ajaxurl,data,(function(response){var res=wpAjax.parseAjaxResponse(response,"ajax-response");$.each(res.responses,(function(){switch(this.what){case"translations":$(".translations").html(this.data),init_translations();break;case"flag":$(".pll-select-flag").html(this.data)}}))}))})),init_translations()}));
|
|
js/build/admin.js
ADDED
@@ -0,0 +1,416 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @package Polylang
|
3 |
+
*/
|
4 |
+
|
5 |
+
jQuery(
|
6 |
+
function( $ ) {
|
7 |
+
|
8 |
+
// languages list table
|
9 |
+
// accessibility to row actions on focus
|
10 |
+
// mainly copy paste of WP code from common.js
|
11 |
+
var transitionTimeout;
|
12 |
+
$( 'table.languages' ).on(
|
13 |
+
{ // restricted to languages list table
|
14 |
+
focusin: function() {
|
15 |
+
clearTimeout( transitionTimeout );
|
16 |
+
var focusedRowActions = $( this ).find( '.row-actions' );
|
17 |
+
// transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
|
18 |
+
$( '.row-actions' ).not( this ).removeClass( 'visible' );
|
19 |
+
focusedRowActions.addClass( 'visible' );
|
20 |
+
},
|
21 |
+
focusout: function() {
|
22 |
+
// Tabbing between post title and .row-actions links needs a brief pause, otherwise
|
23 |
+
// the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
|
24 |
+
transitionTimeout = setTimeout(
|
25 |
+
function() {
|
26 |
+
focusedRowActions.removeClass( 'visible' );
|
27 |
+
},
|
28 |
+
30
|
29 |
+
);
|
30 |
+
}
|
31 |
+
},
|
32 |
+
'tr'
|
33 |
+
); // acts on the whole tr instead of single td as we have actions links in several columns
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Common functions and variables for overriding languages and flags dropdown list by a jQuery UI selectmenu widget.
|
37 |
+
*/
|
38 |
+
|
39 |
+
// Add a boolean variable to be able to check jQuery UI >= 1.12 which is introduced in WP 5.6.
|
40 |
+
// Backward compatibility WP < 5.6
|
41 |
+
var isJqueryUImin112 = $.ui.version >= '1.12.0';
|
42 |
+
// Allow to check if a flag list dropdown is present. Not present in the Wizard steps or other settings page.
|
43 |
+
var flagListExist = $( "#flag_list" ).length;
|
44 |
+
// Allow to check if a language list dropdown is present. Not present in other settings page.
|
45 |
+
var langListExist = $( "#lang_list" ).length;
|
46 |
+
// jQuery UI selectmenu widget width option
|
47 |
+
var defaultSelectmenuWidth = '95%';
|
48 |
+
var wizardSelectmenuWidth = '100%';
|
49 |
+
|
50 |
+
// Inject flag image when jQuery UI selectmenu is created or an item is selected.
|
51 |
+
// jQuery UI 1.12 introduce a wrapper inside de li tag which is necessary to selectmenu widget to work correctly.
|
52 |
+
// Mainly copy from the orginal jQuery UI 1.12 selectmenu widget _renderItem method.
|
53 |
+
// Note this code works fine with jQuery UI 1.11.4 too.
|
54 |
+
var selectmenuRenderItem = function( ul, item ) {
|
55 |
+
var li = $( '<li>' );
|
56 |
+
var wrapper = $( '<div>');
|
57 |
+
|
58 |
+
if ( item.disabled ) {
|
59 |
+
this._addClass( li, null, "ui-state-disabled" );
|
60 |
+
}
|
61 |
+
this._setText( wrapper, item.label );
|
62 |
+
|
63 |
+
// Add the flag from the data attribute in the selected element.
|
64 |
+
wrapper.prepend( $( item.element ).data( 'flag-html' ) );
|
65 |
+
wrapper.children( 'img' ).addClass( 'ui-icon' );
|
66 |
+
|
67 |
+
return li.append( wrapper ).appendTo( ul );
|
68 |
+
};
|
69 |
+
// Override selected item to inject flag for jQuery UI less than 1.12.
|
70 |
+
var selectmenuRefreshButtonText = function( selectElement ) {
|
71 |
+
var buttonText = $( selectElement ).selectmenu( 'instance' ).buttonText;
|
72 |
+
buttonText.prepend( $( selectElement ).children( ':selected' ).data( 'flag-html' ) );
|
73 |
+
buttonText.children( 'img' ).addClass( 'ui-icon' );
|
74 |
+
};
|
75 |
+
// Override selected item since jQuery UI 1.12 which introduces extension point method _renderButtonItem.
|
76 |
+
// @see https://api.jqueryui.com/1.12/selectmenu/#method-_renderButtonItem _renderButtonItem documentation.
|
77 |
+
var selectmenuRenderButtonItem = function ( selectElement ) {
|
78 |
+
var buttonItem = $( '<span>' );
|
79 |
+
this._setText( buttonItem, selectElement.label );
|
80 |
+
this._addClass( buttonItem, "ui-selectmenu-text" );
|
81 |
+
|
82 |
+
// Add the flag from the data attribute in the selected element.
|
83 |
+
buttonItem.prepend( $( selectElement.element ).data( 'flag-html' ) );
|
84 |
+
buttonItem.children( 'img' ).addClass( 'ui-icon' );
|
85 |
+
|
86 |
+
return buttonItem;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Initialize a jQuery UI selectmenu widget on a DOM element
|
91 |
+
*
|
92 |
+
* @param {*} element - The jQuery object representing the DOM element to attach the widget with.
|
93 |
+
* @param {*} config - All the parameters - options and callbacks - necessary to configure the jQuery UI selectmenu widget.
|
94 |
+
* @return {Object} - The jQuery UI selectmenu widget object instance.
|
95 |
+
*/
|
96 |
+
function initializeSelectmenuWidget( element, config ) {
|
97 |
+
// Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
|
98 |
+
var selectmenuWidgetInstance = element.selectmenu( config ).selectmenu( 'instance' );
|
99 |
+
// Overrides each item in the jQuery UI selectmenu list by injecting flag image.
|
100 |
+
selectmenuWidgetInstance._renderItem = selectmenuRenderItem;
|
101 |
+
// Override the selected item rendering for jQuery UI 1.12
|
102 |
+
if ( isJqueryUImin112 ) {
|
103 |
+
selectmenuWidgetInstance._renderButtonItem = selectmenuRenderButtonItem;
|
104 |
+
// Need to refresh to take in account the new button item rendering method after the selectmenu widget instanciaion.
|
105 |
+
selectmenuWidgetInstance.refresh();
|
106 |
+
}
|
107 |
+
return selectmenuWidgetInstance
|
108 |
+
}
|
109 |
+
/**
|
110 |
+
* Selectmenu widget common parameters for its configuration: options and callbacks.
|
111 |
+
*/
|
112 |
+
|
113 |
+
// Selectmenu widget options
|
114 |
+
var selectmenuOptions = {
|
115 |
+
width: defaultSelectmenuWidth,
|
116 |
+
classes: {
|
117 |
+
'ui-selectmenu-menu': 'pll-selectmenu-menu',
|
118 |
+
'ui-selectmenu-button': 'pll-selectmenu-button',
|
119 |
+
}
|
120 |
+
};
|
121 |
+
|
122 |
+
// Selectmenu widget callbacks
|
123 |
+
var selectmenuFlagListCallbacks = {};
|
124 |
+
// Callbacks when Selectmenu widget create or select event is triggered.
|
125 |
+
var createSelectCallback = function( event, ui ) {
|
126 |
+
selectmenuRefreshButtonText( event.target );
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Overrides the flag dropdown list with our customized jquery ui selectmenu.
|
131 |
+
*/
|
132 |
+
|
133 |
+
// Callbacks when Selectmenu widget change or open event is triggered.
|
134 |
+
// Needed to correctly refresh the selected element in the list when editing an existing language or when the value change is triggered by the language choice.
|
135 |
+
// jQuery UI 1.11 callback version.
|
136 |
+
var changeOpenCallback = function( event, ui ){
|
137 |
+
selectmenuRefreshButtonText( $( event.target ).selectmenu( 'refresh' ) );
|
138 |
+
}
|
139 |
+
// jQueryUI 1.12 callback version.
|
140 |
+
var changeOpenCallbackjQueryUI112 = function( event, ui ){
|
141 |
+
// Just a refresh of the menu is needed with jQuery UI 1.12 because _renderButtonItem is triggered and then inject correctly the flag.
|
142 |
+
$( event.target ).selectmenu( 'refresh' );
|
143 |
+
}
|
144 |
+
// There is no need of create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method do the job.
|
145 |
+
if ( isJqueryUImin112 ) {
|
146 |
+
selectmenuFlagListCallbacks =
|
147 |
+
{
|
148 |
+
change: changeOpenCallbackjQueryUI112,
|
149 |
+
open: changeOpenCallbackjQueryUI112,
|
150 |
+
};
|
151 |
+
} else {
|
152 |
+
selectmenuFlagListCallbacks = {
|
153 |
+
create: createSelectCallback,
|
154 |
+
select: createSelectCallback,
|
155 |
+
change: changeOpenCallback,
|
156 |
+
open: changeOpenCallback,
|
157 |
+
};
|
158 |
+
}
|
159 |
+
|
160 |
+
// Create the selectmenu widget only if the field is present.
|
161 |
+
if ( flagListExist ) {
|
162 |
+
// Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
|
163 |
+
var selectmenuFlagList = initializeSelectmenuWidget( $( '#flag_list' ), Object.assign( {}, selectmenuOptions, selectmenuFlagListCallbacks ) );
|
164 |
+
$( '#lang_list' ).on(
|
165 |
+
'languageChanged',
|
166 |
+
function( event, flag ) {
|
167 |
+
// Refresh the flag field
|
168 |
+
selectmenuFlagList.element.val( flag );
|
169 |
+
selectmenuFlagList._trigger( 'change' );
|
170 |
+
}
|
171 |
+
);
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Language choice in predefined languages in Polylang Languages settings page and wizard.
|
176 |
+
* Overrides the predefined language dropdown list with our customized jQuery ui selectmenu widget.
|
177 |
+
*/
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Fill the other language form fields from the language element selected in the language list dropdown.
|
181 |
+
*
|
182 |
+
* @param {Object} language - language object of the selected element in the language list dropdown.
|
183 |
+
*/
|
184 |
+
function fillLanguageFields( language ) {
|
185 |
+
$( '#lang_slug' ).val( language.slug );
|
186 |
+
$( '#lang_locale' ).val( language.locale );
|
187 |
+
$( 'input[name="rtl"]' ).val( language.rtl );
|
188 |
+
$( '#lang_name' ).val( language.name );
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Parse selected language element in the language list dropdown.
|
193 |
+
*
|
194 |
+
* @param {object} event - jQuery triggered event.
|
195 |
+
* @return {object} The language object with its named properties.
|
196 |
+
*/
|
197 |
+
function parseSelectedLanguage( event ) {
|
198 |
+
var selectedElement = $('option:selected', event.target);
|
199 |
+
var values = selectedElement.val().split(':')
|
200 |
+
return {
|
201 |
+
slug: values[0],
|
202 |
+
locale: values[1],
|
203 |
+
rtl: [values[2]],
|
204 |
+
flag: values[3],
|
205 |
+
name: selectedElement.text().split(' - ')[0] // At the moment there is no need of the 2nd part because it corresponds on the locale which is already known by splitting the selected element value
|
206 |
+
};
|
207 |
+
}
|
208 |
+
|
209 |
+
// Callback when selectmenu widget change event is triggered.
|
210 |
+
var changeCallback = function( event, ui ) {
|
211 |
+
var language = parseSelectedLanguage( event );
|
212 |
+
|
213 |
+
fillLanguageFields( language );
|
214 |
+
|
215 |
+
$( event.target ).trigger( 'languageChanged', language.flag );
|
216 |
+
};
|
217 |
+
|
218 |
+
// Create the jQuery UI selectmenu widget languages list dropdown and return its instance.
|
219 |
+
var selectmenuLangListCallbacks = {};
|
220 |
+
// For the wizard we need a 100% width. So we override the previous defined value of selectmenuOptions.
|
221 |
+
if( $( '#lang_list' ).closest( '.pll-wizard-content' ).length > 0 ) {
|
222 |
+
selectmenuOptions = Object.assign( selectmenuOptions, { width: wizardSelectmenuWidth } );
|
223 |
+
}
|
224 |
+
|
225 |
+
// There is no need of create and select callbacks with jQuery UI 1.12 because overrinding _renderButtonItem method do the job.
|
226 |
+
if ( isJqueryUImin112 ) {
|
227 |
+
selectmenuLangListCallbacks = {
|
228 |
+
change: changeCallback,
|
229 |
+
};
|
230 |
+
} else {
|
231 |
+
selectmenuLangListCallbacks = {
|
232 |
+
create: createSelectCallback,
|
233 |
+
select: createSelectCallback,
|
234 |
+
change: changeCallback,
|
235 |
+
};
|
236 |
+
}
|
237 |
+
if ( langListExist ) {
|
238 |
+
initializeSelectmenuWidget( $( '#lang_list' ), Object.assign( {}, selectmenuOptions, selectmenuLangListCallbacks ) );
|
239 |
+
}
|
240 |
+
|
241 |
+
// strings translations
|
242 |
+
// save translations when pressing enter
|
243 |
+
$( '.translation input' ).on(
|
244 |
+
'keydown',
|
245 |
+
function( event ){
|
246 |
+
if ( 'Enter' === event.key ) {
|
247 |
+
event.preventDefault();
|
248 |
+
$( '#submit' ).trigger( 'click' );
|
249 |
+
}
|
250 |
+
}
|
251 |
+
);
|
252 |
+
|
253 |
+
// settings page
|
254 |
+
// click on configure link
|
255 |
+
$( '#the-list' ).on(
|
256 |
+
'click',
|
257 |
+
'.configure>a',
|
258 |
+
function(){
|
259 |
+
$( '.pll-configure' ).hide().prev().show();
|
260 |
+
$( this ).closest( 'tr' ).hide().next().show();
|
261 |
+
return false;
|
262 |
+
}
|
263 |
+
);
|
264 |
+
|
265 |
+
// cancel
|
266 |
+
$( '#the-list' ).on(
|
267 |
+
'click',
|
268 |
+
'.cancel',
|
269 |
+
function(){
|
270 |
+
$( this ).closest( 'tr' ).hide().prev().show();
|
271 |
+
}
|
272 |
+
);
|
273 |
+
|
274 |
+
// save settings
|
275 |
+
$( '#the-list' ).on(
|
276 |
+
'click',
|
277 |
+
'.save',
|
278 |
+
function(){
|
279 |
+
var tr = $( this ).closest( 'tr' );
|
280 |
+
var parts = tr.attr( 'id' ).split( '-' );
|
281 |
+
|
282 |
+
var data = {
|
283 |
+
action: 'pll_save_options',
|
284 |
+
pll_ajax_settings: true,
|
285 |
+
module: parts[parts.length - 1],
|
286 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
287 |
+
};
|
288 |
+
|
289 |
+
data = tr.find( ':input' ).serialize() + '&' + $.param( data );
|
290 |
+
|
291 |
+
$.post(
|
292 |
+
ajaxurl,
|
293 |
+
data,
|
294 |
+
function( response ) {
|
295 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
296 |
+
$.each(
|
297 |
+
res.responses,
|
298 |
+
function() {
|
299 |
+
switch ( this.what ) {
|
300 |
+
case 'license-update':
|
301 |
+
$( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
|
302 |
+
break;
|
303 |
+
case 'success':
|
304 |
+
tr.hide().prev().show(); // close only if there is no error
|
305 |
+
case 'error':
|
306 |
+
$( '.settings-error' ).remove(); // remove previous messages if any
|
307 |
+
$( 'h1' ).after( this.data );
|
308 |
+
|
309 |
+
// Make notices dismissible
|
310 |
+
// copy paste of common.js from WP 4.2.2
|
311 |
+
$( '.notice.is-dismissible' ).each(
|
312 |
+
function() {
|
313 |
+
var $this = $( this ),
|
314 |
+
$button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
|
315 |
+
btnText = pll_admin.dismiss_notice || '';
|
316 |
+
|
317 |
+
// Ensure plain text
|
318 |
+
$button.find( '.screen-reader-text' ).text( btnText );
|
319 |
+
|
320 |
+
// Whitelist because of how the button is built. See above
|
321 |
+
$this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
322 |
+
|
323 |
+
$button.on(
|
324 |
+
'click.wp-dismiss-notice',
|
325 |
+
function( event ) {
|
326 |
+
event.preventDefault();
|
327 |
+
$this.fadeTo(
|
328 |
+
100,
|
329 |
+
0,
|
330 |
+
function() {
|
331 |
+
$( this ).slideUp(
|
332 |
+
100,
|
333 |
+
function() {
|
334 |
+
$( this ).remove();
|
335 |
+
}
|
336 |
+
);
|
337 |
+
}
|
338 |
+
);
|
339 |
+
}
|
340 |
+
);
|
341 |
+
}
|
342 |
+
);
|
343 |
+
break;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
);
|
347 |
+
}
|
348 |
+
);
|
349 |
+
}
|
350 |
+
);
|
351 |
+
|
352 |
+
// act when pressing enter or esc in configurations
|
353 |
+
$( '.pll-configure' ).on(
|
354 |
+
'keydown',
|
355 |
+
function( event ){
|
356 |
+
if ( 'Enter' === event.key ) {
|
357 |
+
event.preventDefault();
|
358 |
+
$( this ).find( '.save' ).trigger( 'click' );
|
359 |
+
}
|
360 |
+
|
361 |
+
if ( 'Escape' === event.key ) {
|
362 |
+
event.preventDefault();
|
363 |
+
$( this ).find( '.cancel' ).trigger( 'click' );
|
364 |
+
}
|
365 |
+
}
|
366 |
+
);
|
367 |
+
|
368 |
+
// settings URL modifications
|
369 |
+
// manages visibility of fields
|
370 |
+
$( "input[name='force_lang']" ).on(
|
371 |
+
'change',
|
372 |
+
function() {
|
373 |
+
function pll_toggle( a, test ) {
|
374 |
+
test ? a.show() : a.hide();
|
375 |
+
}
|
376 |
+
|
377 |
+
var value = $( this ).val();
|
378 |
+
pll_toggle( $( '#pll-domains-table' ), 3 == value );
|
379 |
+
pll_toggle( $( "#pll-hide-default" ), 3 > value );
|
380 |
+
pll_toggle( $( "#pll-rewrite" ), 2 > value );
|
381 |
+
pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
|
382 |
+
}
|
383 |
+
);
|
384 |
+
|
385 |
+
// settings license
|
386 |
+
// deactivate button
|
387 |
+
$( '.pll-deactivate-license' ).on(
|
388 |
+
'click',
|
389 |
+
function() {
|
390 |
+
var data = {
|
391 |
+
action: 'pll_deactivate_license',
|
392 |
+
pll_ajax_settings: true,
|
393 |
+
id: $( this ).attr( 'id' ),
|
394 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
395 |
+
};
|
396 |
+
$.post(
|
397 |
+
ajaxurl,
|
398 |
+
data,
|
399 |
+
function( response ){
|
400 |
+
$( '#pll-license-' + response.id ).replaceWith( response.html );
|
401 |
+
}
|
402 |
+
);
|
403 |
+
}
|
404 |
+
);
|
405 |
+
|
406 |
+
// Manage closing the metabox.
|
407 |
+
// close postboxes that should be closed
|
408 |
+
$( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
|
409 |
+
// postboxes setup
|
410 |
+
if ( 'undefined' !== typeof postboxes ) {
|
411 |
+
postboxes.add_postbox_toggles( pagenow );
|
412 |
+
}
|
413 |
+
}
|
414 |
+
);
|
415 |
+
|
416 |
+
|
js/build/admin.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(e){var t;e("table.languages").on({focusin:function(){clearTimeout(t);var n=e(this).find(".row-actions");e(".row-actions").not(this).removeClass("visible"),n.addClass("visible")},focusout:function(){t=setTimeout((function(){focusedRowActions.removeClass("visible")}),30)}},"tr");var n=e.ui.version>="1.12.0",l=e("#flag_list").length,s=e("#lang_list").length,i=function(t,n){var l=e("<li>"),s=e("<div>");return n.disabled&&this._addClass(l,null,"ui-state-disabled"),this._setText(s,n.label),s.prepend(e(n.element).data("flag-html")),s.children("img").addClass("ui-icon"),l.append(s).appendTo(t)},a=function(t){var n=e(t).selectmenu("instance").buttonText;n.prepend(e(t).children(":selected").data("flag-html")),n.children("img").addClass("ui-icon")},c=function(t){var n=e("<span>");return this._setText(n,t.label),this._addClass(n,"ui-selectmenu-text"),n.prepend(e(t.element).data("flag-html")),n.children("img").addClass("ui-icon"),n};function o(e,t){var l=e.selectmenu(t).selectmenu("instance");return l._renderItem=i,n&&(l._renderButtonItem=c,l.refresh()),l}var r={width:"95%",classes:{"ui-selectmenu-menu":"pll-selectmenu-menu","ui-selectmenu-button":"pll-selectmenu-button"}},u={},d=function(e,t){a(e.target)},p=function(t,n){a(e(t.target).selectmenu("refresh"))},g=function(t,n){e(t.target).selectmenu("refresh")};if(u=n?{change:g,open:g}:{create:d,select:d,change:p,open:p},l){var h=o(e("#flag_list"),Object.assign({},r,u));e("#lang_list").on("languageChanged",(function(e,t){h.element.val(t),h._trigger("change")}))}var f=function(t,n){var l=function(t){var n=e("option:selected",t.target),l=n.val().split(":");return{slug:l[0],locale:l[1],rtl:[l[2]],flag:l[3],name:n.text().split(" - ")[0]}}(t);!function(t){e("#lang_slug").val(t.slug),e("#lang_locale").val(t.locale),e('input[name="rtl"]').val(t.rtl),e("#lang_name").val(t.name)}(l),e(t.target).trigger("languageChanged",l.flag)},v={};e("#lang_list").closest(".pll-wizard-content").length>0&&(r=Object.assign(r,{width:"100%"})),v=n?{change:f}:{create:d,select:d,change:f},s&&o(e("#lang_list"),Object.assign({},r,v)),e(".translation input").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e("#submit").trigger("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("-"),l={action:"pll_save_options",pll_ajax_settings:!0,module:n[n.length-1],_pll_nonce:e("#_pll_nonce").val()};l=t.find(":input").serialize()+"&"+e.param(l),e.post(ajaxurl,l,(function(n){var l=wpAjax.parseAjaxResponse(n,"ajax-response");e.each(l.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>'),l=pll_admin.dismiss_notice||"";n.find(".screen-reader-text").text(l),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").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e(this).find(".save").trigger("click")),"Escape"===t.key&&(t.preventDefault(),e(this).find(".cancel").trigger("click"))})),e("input[name='force_lang']").on("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/build/block-editor.js
ADDED
@@ -0,0 +1,350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/******/ "use strict";
|
2 |
+
|
3 |
+
;// CONCATENATED MODULE: ./js/lib/confirmation-modal.js
|
4 |
+
/**
|
5 |
+
* @package Polylang
|
6 |
+
*/
|
7 |
+
|
8 |
+
// We can't use underscore or lodash in this common code because it depends of the context classic or block editor.
|
9 |
+
// Classic editor underscore is loaded, Block editor lodash is loaded.
|
10 |
+
const { __ } = wp.i18n;
|
11 |
+
|
12 |
+
const languagesList = jQuery( '.post_lang_choice' );
|
13 |
+
|
14 |
+
// Dialog box for alerting the user about a risky changing.
|
15 |
+
const initializeConfimationModal = () => {
|
16 |
+
// Create dialog container.
|
17 |
+
const dialogContainer = jQuery(
|
18 |
+
'<div/>',
|
19 |
+
{
|
20 |
+
id: 'pll-dialog',
|
21 |
+
style: 'display:none;'
|
22 |
+
}
|
23 |
+
).text( __( 'Are you sure you want to change the language of the current content?', 'polylang' ) );
|
24 |
+
|
25 |
+
// Put it after languages list dropdown.
|
26 |
+
// PHPCS ignore dialogContainer is a new safe HTML code generated above.
|
27 |
+
languagesList.after( dialogContainer ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
|
28 |
+
|
29 |
+
const dialogResult = new Promise(
|
30 |
+
( confirm, cancel ) => {
|
31 |
+
const confirmDialog = ( what ) => { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
32 |
+
switch ( what ) { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
33 |
+
case 'yes':
|
34 |
+
// Confirm the new language.
|
35 |
+
languagesList.data( 'old-value', languagesList.children( ':selected' )[0].value );
|
36 |
+
confirm();
|
37 |
+
break;
|
38 |
+
case 'no':
|
39 |
+
// Revert to the old language.
|
40 |
+
languagesList.val( languagesList.data( 'old-value' ) );
|
41 |
+
cancel( 'Cancel' );
|
42 |
+
break;
|
43 |
+
}
|
44 |
+
dialogContainer.dialog( 'close' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
45 |
+
} // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
46 |
+
|
47 |
+
// Initialize dialog box in the case a language is selected but not added in the list.
|
48 |
+
dialogContainer.dialog(
|
49 |
+
{
|
50 |
+
autoOpen: false,
|
51 |
+
modal: true,
|
52 |
+
draggable: false,
|
53 |
+
resizable: false,
|
54 |
+
title: __( 'Change language', 'polylang' ),
|
55 |
+
minWidth: 600,
|
56 |
+
maxWidth: '100%',
|
57 |
+
classes: {
|
58 |
+
'ui-dialog': 'pll-confirmation-modal',
|
59 |
+
},
|
60 |
+
open: function( event, ui ) {
|
61 |
+
// Change dialog box position for rtl language
|
62 |
+
if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
|
63 |
+
jQuery( this ).parent().css(
|
64 |
+
{
|
65 |
+
right: jQuery( this ).parent().css( 'left' ),
|
66 |
+
left: 'auto'
|
67 |
+
}
|
68 |
+
);
|
69 |
+
}
|
70 |
+
},
|
71 |
+
close: function( event, ui ) {
|
72 |
+
// When we're closing the dialog box we need to cancel the language change as we click on Cancel button.
|
73 |
+
confirmDialog( 'no' );
|
74 |
+
},
|
75 |
+
buttons: [
|
76 |
+
{
|
77 |
+
text: __( 'OK', 'polylang' ),
|
78 |
+
click: function( event ) {
|
79 |
+
confirmDialog( 'yes' );
|
80 |
+
}
|
81 |
+
},
|
82 |
+
{
|
83 |
+
text: __( 'Cancel', 'polylang' ),
|
84 |
+
click: function( event ) {
|
85 |
+
confirmDialog( 'no' );
|
86 |
+
}
|
87 |
+
} ]
|
88 |
+
}
|
89 |
+
);
|
90 |
+
}
|
91 |
+
);
|
92 |
+
return { dialogContainer, dialogResult };
|
93 |
+
}
|
94 |
+
|
95 |
+
const initializeLanguageOldValue = () => {
|
96 |
+
// Keep the old language value to be able to compare to the new one and revert to it if necessary.
|
97 |
+
languagesList.attr( 'data-old-value', languagesList.children( ':selected' )[0].value );
|
98 |
+
};
|
99 |
+
|
100 |
+
;// CONCATENATED MODULE: ./js/block-editor.js
|
101 |
+
/**
|
102 |
+
* @package Polylang
|
103 |
+
*/
|
104 |
+
|
105 |
+
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Filter REST API requests to add the language in the request
|
109 |
+
*
|
110 |
+
* @since 2.5
|
111 |
+
*/
|
112 |
+
wp.apiFetch.use(
|
113 |
+
function( options, next ) {
|
114 |
+
// If options.url is defined, this is not a REST request but a direct call to post.php for legacy metaboxes.
|
115 |
+
if ( 'undefined' === typeof options.url ) {
|
116 |
+
if ( 'undefined' === typeof options.data || null === options.data ) {
|
117 |
+
// GET
|
118 |
+
options.path += ( ( options.path.indexOf( '?' ) >= 0 ) ? '&lang=' : '?lang=' ) + getCurrentLanguage();
|
119 |
+
} else {
|
120 |
+
// PUT, POST
|
121 |
+
options.data.lang = getCurrentLanguage();
|
122 |
+
}
|
123 |
+
}
|
124 |
+
return next( options );
|
125 |
+
}
|
126 |
+
);
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Get the language from the HTML form
|
130 |
+
*
|
131 |
+
* @since 2.5
|
132 |
+
*
|
133 |
+
* @return {Element.value}
|
134 |
+
*/
|
135 |
+
function getCurrentLanguage() {
|
136 |
+
return document.querySelector( '[name=post_lang_choice]' ).value;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Handles internals of the metabox:
|
141 |
+
* Language select, autocomplete input field.
|
142 |
+
*
|
143 |
+
* @since 1.5
|
144 |
+
*
|
145 |
+
* Save post after lang choice is done and redirect to the same page for refreshing all the data.
|
146 |
+
*
|
147 |
+
* @since 2.5
|
148 |
+
*
|
149 |
+
* Link post saving after refreshing the metabox.
|
150 |
+
*
|
151 |
+
* @since 3.0
|
152 |
+
*/
|
153 |
+
jQuery(
|
154 |
+
function( $ ) {
|
155 |
+
// Initialize current language to be able to compare if it changes.
|
156 |
+
initializeLanguageOldValue();
|
157 |
+
|
158 |
+
|
159 |
+
// Ajax for changing the post's language in the languages metabox
|
160 |
+
$( '.post_lang_choice' ).on(
|
161 |
+
'change',
|
162 |
+
function( event ) {
|
163 |
+
const select = wp.data.select;
|
164 |
+
const dispatch = wp.data.dispatch;
|
165 |
+
const subscribe = wp.data.subscribe;
|
166 |
+
const emptyPost = isEmptyPost();
|
167 |
+
|
168 |
+
// Initialize the confirmation dialog box.
|
169 |
+
const confirmationModal = initializeConfimationModal();
|
170 |
+
const { dialogContainer : dialog } = confirmationModal;
|
171 |
+
let { dialogResult } = confirmationModal;
|
172 |
+
// The selected option in the dropdown list.
|
173 |
+
const selectedOption = event.target;
|
174 |
+
|
175 |
+
// Specific case for empty posts.
|
176 |
+
// Place at the beginning because window.location changing triggers automatically page reloading.
|
177 |
+
if ( location.pathname.match( /post-new.php/gi ) && emptyPost ) {
|
178 |
+
reloadPageForEmptyPost( selectedOption.value );
|
179 |
+
}
|
180 |
+
|
181 |
+
// Otherwise send an ajax request to refresh the legacy metabox and set the post language with the new language.
|
182 |
+
// It needs a confirmation of the user before changing the language.
|
183 |
+
// Need to wait the ajax response before triggering the block editor post save action.
|
184 |
+
if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! emptyPost ) {
|
185 |
+
dialog.dialog( 'open' );
|
186 |
+
} else {
|
187 |
+
// Update the old language with the new one to be able to compare it in the next changing.
|
188 |
+
// Because the page isn't reloaded in this case.
|
189 |
+
initializeLanguageOldValue();
|
190 |
+
dialogResult = Promise.resolve();
|
191 |
+
}
|
192 |
+
|
193 |
+
dialogResult.then(
|
194 |
+
() => {
|
195 |
+
var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
196 |
+
action: 'post_lang_choice',
|
197 |
+
lang: selectedOption.value,
|
198 |
+
post_type: $( '#post_type' ).val(),
|
199 |
+
post_id: $( '#post_ID' ).val(),
|
200 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
201 |
+
}
|
202 |
+
|
203 |
+
$.post(
|
204 |
+
ajaxurl,
|
205 |
+
data,
|
206 |
+
function( response ) {
|
207 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
208 |
+
$.each(
|
209 |
+
res.responses,
|
210 |
+
function() {
|
211 |
+
switch ( this.what ) {
|
212 |
+
case 'translations': // Translations fields
|
213 |
+
// Data is built and come from server side and is well escaped when necessary
|
214 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
215 |
+
init_translations();
|
216 |
+
break;
|
217 |
+
case 'flag': // Flag in front of the select dropdown
|
218 |
+
// Data is built and come from server side and is well escaped when necessary
|
219 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
220 |
+
break;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
);
|
224 |
+
blockEditorSavePostAndReloadPage();
|
225 |
+
}
|
226 |
+
);
|
227 |
+
},
|
228 |
+
() => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
|
229 |
+
);
|
230 |
+
|
231 |
+
function isEmptyPost() {
|
232 |
+
const editor = wp.data.select( 'core/editor' );
|
233 |
+
const title = editor.getEditedPostAttribute( 'title' ).trim();
|
234 |
+
const content = editor.getEditedPostAttribute( 'content' ).trim();
|
235 |
+
const excerpt = editor.getEditedPostAttribute( 'excerpt' ).trim();
|
236 |
+
|
237 |
+
return ! title && ! content && ! excerpt;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Reload the block editor page for empty posts.
|
242 |
+
*
|
243 |
+
* @param {string} lang The target language code.
|
244 |
+
*/
|
245 |
+
function reloadPageForEmptyPost( lang ) {
|
246 |
+
// Change the new_lang parameter with the new language value for reloading the page
|
247 |
+
// WPCS location.search is never written in the page, just used to reload page with the right value of new_lang
|
248 |
+
// new_lang input is controlled server side in PHP. The value come from the dropdown list of language returned and escaped server side.
|
249 |
+
// Notice that window.location changing triggers automatically page reloading.
|
250 |
+
if ( -1 != location.search.indexOf( 'new_lang' ) ) {
|
251 |
+
// use regexp non capturing group to replace new_lang parameter no matter where it is and capture other parameters which can be behind it
|
252 |
+
window.location.search = window.location.search.replace( /(?:new_lang=[^&]*)(&)?(.*)/, 'new_lang=' + lang + '$1$2' ); // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
253 |
+
} else {
|
254 |
+
window.location.search = window.location.search + ( ( -1 != window.location.search.indexOf( '?' ) ) ? '&' : '?' ) + 'new_lang=' + lang; // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
|
255 |
+
}
|
256 |
+
};
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Triggers block editor post save and reload the block editor page when everything is ok.
|
260 |
+
*/
|
261 |
+
function blockEditorSavePostAndReloadPage() {
|
262 |
+
|
263 |
+
let unsubscribe = null;
|
264 |
+
|
265 |
+
// Listen if the savePost is completely done by subscribing to its events.
|
266 |
+
const savePostIsDone = new Promise(
|
267 |
+
function( resolve, reject ) {
|
268 |
+
unsubscribe = subscribe(
|
269 |
+
function() {
|
270 |
+
const isSavePostSucceeded = select( 'core/editor' ).didPostSaveRequestSucceed();
|
271 |
+
const isSavePostFailed = select( 'core/editor' ).didPostSaveRequestFail();
|
272 |
+
if ( isSavePostSucceeded || isSavePostFailed ) {
|
273 |
+
if ( isSavePostFailed ) {
|
274 |
+
reject();
|
275 |
+
} else {
|
276 |
+
resolve();
|
277 |
+
}
|
278 |
+
}
|
279 |
+
}
|
280 |
+
);
|
281 |
+
}
|
282 |
+
);
|
283 |
+
|
284 |
+
// Triggers the post save.
|
285 |
+
dispatch( 'core/editor' ).savePost();
|
286 |
+
|
287 |
+
// Process
|
288 |
+
savePostIsDone.then(
|
289 |
+
function() {
|
290 |
+
// If the post is well saved, we can reload the page
|
291 |
+
window.location.reload();
|
292 |
+
},
|
293 |
+
function() {
|
294 |
+
// If the post save failed
|
295 |
+
unsubscribe();
|
296 |
+
}
|
297 |
+
).catch(
|
298 |
+
function() {
|
299 |
+
// If an exception is thrown
|
300 |
+
unsubscribe();
|
301 |
+
}
|
302 |
+
);
|
303 |
+
};
|
304 |
+
}
|
305 |
+
);
|
306 |
+
|
307 |
+
// Translations autocomplete input box
|
308 |
+
function init_translations() {
|
309 |
+
$( '.tr_lang' ).each(
|
310 |
+
function(){
|
311 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
312 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
313 |
+
|
314 |
+
$( this ).autocomplete(
|
315 |
+
{
|
316 |
+
minLength: 0,
|
317 |
+
|
318 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
319 |
+
'&post_language=' + $( '.post_lang_choice' ).val() +
|
320 |
+
'&translation_language=' + tr_lang +
|
321 |
+
'&post_type=' + $( '#post_type' ).val() +
|
322 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
323 |
+
|
324 |
+
select: function( event, ui ) {
|
325 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
326 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
327 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
328 |
+
},
|
329 |
+
}
|
330 |
+
);
|
331 |
+
|
332 |
+
// When the input box is emptied
|
333 |
+
$( this ).on(
|
334 |
+
'blur',
|
335 |
+
function() {
|
336 |
+
if ( ! $( this ).val() ) {
|
337 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
338 |
+
// Value is retrieved from HTML already generated server side
|
339 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
340 |
+
}
|
341 |
+
}
|
342 |
+
);
|
343 |
+
}
|
344 |
+
);
|
345 |
+
}
|
346 |
+
|
347 |
+
init_translations();
|
348 |
+
}
|
349 |
+
);
|
350 |
+
|
js/build/block-editor.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";const{__}=wp.i18n,languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const t=jQuery("<div/>",{id:"pll-dialog",style:"display:none;"}).text(__("Are you sure you want to change the language of the current content?","polylang"));languagesList.after(t);const a=new Promise(((a,e)=>{const n=n=>{switch(n){case"yes":languagesList.data("old-value",languagesList.children(":selected")[0].value),a();break;case"no":languagesList.val(languagesList.data("old-value")),e("Cancel")}t.dialog("close")};t.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:__("Change language","polylang"),minWidth:600,maxWidth:"100%",classes:{"ui-dialog":"pll-confirmation-modal"},open:function(t,a){jQuery("body").hasClass("rtl")&&jQuery(this).parent().css({right:jQuery(this).parent().css("left"),left:"auto"})},close:function(t,a){n("no")},buttons:[{text:__("OK","polylang"),click:function(t){n("yes")}},{text:__("Cancel","polylang"),click:function(t){n("no")}}]})}));return{dialogContainer:t,dialogResult:a}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected")[0].value)};function getCurrentLanguage(){return document.querySelector("[name=post_lang_choice]").value}wp.apiFetch.use((function(t,a){return void 0===t.url&&(void 0===t.data||null===t.data?t.path+=(t.path.indexOf("?")>=0?"&lang=":"?lang=")+getCurrentLanguage():t.data.lang=getCurrentLanguage()),a(t)})),jQuery((function(t){function a(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=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,l){t("#htr_lang_"+a).val(l.item.id),e.html(l.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(e){const n=wp.data.select,l=wp.data.dispatch,i=wp.data.subscribe,o=function(){const t=wp.data.select("core/editor"),a=t.getEditedPostAttribute("title").trim(),e=t.getEditedPostAttribute("content").trim(),n=t.getEditedPostAttribute("excerpt").trim();return!a&&!e&&!n}(),s=initializeConfimationModal(),{dialogContainer:c}=s;let{dialogResult:u}=s;const r=e.target;var g;location.pathname.match(/post-new.php/gi)&&o&&(g=r.value,-1!=location.search.indexOf("new_lang")?window.location.search=window.location.search.replace(/(?:new_lang=[^&]*)(&)?(.*)/,"new_lang="+g+"$1$2"):window.location.search=window.location.search+(-1!=window.location.search.indexOf("?")?"&":"?")+"new_lang="+g),t(this).data("old-value")===r.value||o?(initializeLanguageOldValue(),u=Promise.resolve()):c.dialog("open"),u.then((()=>{var e={action:"post_lang_choice",lang:r.value,post_type:t("#post_type").val(),post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,e,(function(e){var o=wpAjax.parseAjaxResponse(e,"ajax-response");t.each(o.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),a();break;case"flag":t(".pll-select-flag").html(this.data)}})),function(){let t=null;const a=new Promise((function(a,e){t=i((function(){const t=n("core/editor").didPostSaveRequestSucceed(),l=n("core/editor").didPostSaveRequestFail();(t||l)&&(l?e():a())}))}));l("core/editor").savePost(),a.then((function(){window.location.reload()}),(function(){t()})).catch((function(){t()}))}()}))}),(()=>{}))})),a()}));
|
js/build/classic-editor.js
ADDED
@@ -0,0 +1,436 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/******/ "use strict";
|
2 |
+
|
3 |
+
;// CONCATENATED MODULE: ./js/lib/confirmation-modal.js
|
4 |
+
/**
|
5 |
+
* @package Polylang
|
6 |
+
*/
|
7 |
+
|
8 |
+
// We can't use underscore or lodash in this common code because it depends of the context classic or block editor.
|
9 |
+
// Classic editor underscore is loaded, Block editor lodash is loaded.
|
10 |
+
const { __ } = wp.i18n;
|
11 |
+
|
12 |
+
const languagesList = jQuery( '.post_lang_choice' );
|
13 |
+
|
14 |
+
// Dialog box for alerting the user about a risky changing.
|
15 |
+
const initializeConfimationModal = () => {
|
16 |
+
// Create dialog container.
|
17 |
+
const dialogContainer = jQuery(
|
18 |
+
'<div/>',
|
19 |
+
{
|
20 |
+
id: 'pll-dialog',
|
21 |
+
style: 'display:none;'
|
22 |
+
}
|
23 |
+
).text( __( 'Are you sure you want to change the language of the current content?', 'polylang' ) );
|
24 |
+
|
25 |
+
// Put it after languages list dropdown.
|
26 |
+
// PHPCS ignore dialogContainer is a new safe HTML code generated above.
|
27 |
+
languagesList.after( dialogContainer ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
|
28 |
+
|
29 |
+
const dialogResult = new Promise(
|
30 |
+
( confirm, cancel ) => {
|
31 |
+
const confirmDialog = ( what ) => { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
32 |
+
switch ( what ) { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
33 |
+
case 'yes':
|
34 |
+
// Confirm the new language.
|
35 |
+
languagesList.data( 'old-value', languagesList.children( ':selected' )[0].value );
|
36 |
+
confirm();
|
37 |
+
break;
|
38 |
+
case 'no':
|
39 |
+
// Revert to the old language.
|
40 |
+
languagesList.val( languagesList.data( 'old-value' ) );
|
41 |
+
cancel( 'Cancel' );
|
42 |
+
break;
|
43 |
+
}
|
44 |
+
dialogContainer.dialog( 'close' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
45 |
+
} // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
46 |
+
|
47 |
+
// Initialize dialog box in the case a language is selected but not added in the list.
|
48 |
+
dialogContainer.dialog(
|
49 |
+
{
|
50 |
+
autoOpen: false,
|
51 |
+
modal: true,
|
52 |
+
draggable: false,
|
53 |
+
resizable: false,
|
54 |
+
title: __( 'Change language', 'polylang' ),
|
55 |
+
minWidth: 600,
|
56 |
+
maxWidth: '100%',
|
57 |
+
classes: {
|
58 |
+
'ui-dialog': 'pll-confirmation-modal',
|
59 |
+
},
|
60 |
+
open: function( event, ui ) {
|
61 |
+
// Change dialog box position for rtl language
|
62 |
+
if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
|
63 |
+
jQuery( this ).parent().css(
|
64 |
+
{
|
65 |
+
right: jQuery( this ).parent().css( 'left' ),
|
66 |
+
left: 'auto'
|
67 |
+
}
|
68 |
+
);
|
69 |
+
}
|
70 |
+
},
|
71 |
+
close: function( event, ui ) {
|
72 |
+
// When we're closing the dialog box we need to cancel the language change as we click on Cancel button.
|
73 |
+
confirmDialog( 'no' );
|
74 |
+
},
|
75 |
+
buttons: [
|
76 |
+
{
|
77 |
+
text: __( 'OK', 'polylang' ),
|
78 |
+
click: function( event ) {
|
79 |
+
confirmDialog( 'yes' );
|
80 |
+
}
|
81 |
+
},
|
82 |
+
{
|
83 |
+
text: __( 'Cancel', 'polylang' ),
|
84 |
+
click: function( event ) {
|
85 |
+
confirmDialog( 'no' );
|
86 |
+
}
|
87 |
+
} ]
|
88 |
+
}
|
89 |
+
);
|
90 |
+
}
|
91 |
+
);
|
92 |
+
return { dialogContainer, dialogResult };
|
93 |
+
}
|
94 |
+
|
95 |
+
const initializeLanguageOldValue = () => {
|
96 |
+
// Keep the old language value to be able to compare to the new one and revert to it if necessary.
|
97 |
+
languagesList.attr( 'data-old-value', languagesList.children( ':selected' )[0].value );
|
98 |
+
};
|
99 |
+
|
100 |
+
;// CONCATENATED MODULE: ./js/classic-editor.js
|
101 |
+
/**
|
102 |
+
* @package Polylang
|
103 |
+
*/
|
104 |
+
|
105 |
+
|
106 |
+
|
107 |
+
// tag suggest in metabox
|
108 |
+
jQuery(
|
109 |
+
function( $ ) {
|
110 |
+
$.ajaxPrefilter(
|
111 |
+
function( options, originalOptions, jqXHR ) {
|
112 |
+
var lang = $( '.post_lang_choice' ).val();
|
113 |
+
if ( 'string' === typeof options.data && -1 !== options.url.indexOf( 'action=ajax-tag-search' ) && lang ) {
|
114 |
+
options.data = 'lang=' + lang + '&' + options.data;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
);
|
118 |
+
}
|
119 |
+
);
|
120 |
+
|
121 |
+
// overrides tagBox.get
|
122 |
+
jQuery(
|
123 |
+
function( $ ) {
|
124 |
+
// overrides function to add the language
|
125 |
+
tagBox.get = function( id ) {
|
126 |
+
var tax = id.substr( id.indexOf( '-' ) + 1 );
|
127 |
+
|
128 |
+
// add the language in the $_POST variable
|
129 |
+
var data = {
|
130 |
+
action: 'get-tagcloud',
|
131 |
+
lang: $( '.post_lang_choice' ).val(),
|
132 |
+
tax: tax
|
133 |
+
}
|
134 |
+
|
135 |
+
$.post(
|
136 |
+
ajaxurl,
|
137 |
+
data,
|
138 |
+
function( r, stat ) {
|
139 |
+
if ( 0 == r || 'success' != stat ) {
|
140 |
+
r = wpAjax.broken;
|
141 |
+
}
|
142 |
+
|
143 |
+
// @see code from WordPress core https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/js/tags-box.js#L291
|
144 |
+
// @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
|
145 |
+
r = $( '<div />' ).addClass( 'the-tagcloud' ).attr( 'id', 'tagcloud-' + tax ).html( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
146 |
+
$( 'a', r ).on(
|
147 |
+
'click',
|
148 |
+
function(){
|
149 |
+
tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
);
|
153 |
+
|
154 |
+
var tagCloud = $( '#tagcloud-' + tax );
|
155 |
+
// add an if else condition to allow modifying the tags outputed when switching the language
|
156 |
+
var v = tagCloud.css( 'display' );
|
157 |
+
if ( v ) {
|
158 |
+
// See the comment above when r variable is created.
|
159 |
+
$( '#tagcloud-' + tax ).replaceWith( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
160 |
+
$( '#tagcloud-' + tax ).css( 'display', v );
|
161 |
+
}
|
162 |
+
else {
|
163 |
+
// See the comment above when r variable is created.
|
164 |
+
$( '#' + id ).after( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
|
165 |
+
}
|
166 |
+
}
|
167 |
+
);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
);
|
171 |
+
|
172 |
+
jQuery(
|
173 |
+
function( $ ) {
|
174 |
+
// collect taxonomies - code partly copied from WordPress
|
175 |
+
var taxonomies = new Array();
|
176 |
+
$( '.categorydiv' ).each(
|
177 |
+
function(){
|
178 |
+
var this_id = $( this ).attr( 'id' ), taxonomyParts, taxonomy;
|
179 |
+
|
180 |
+
taxonomyParts = this_id.split( '-' );
|
181 |
+
taxonomyParts.shift();
|
182 |
+
taxonomy = taxonomyParts.join( '-' );
|
183 |
+
taxonomies.push( taxonomy ); // store the taxonomy for future use
|
184 |
+
|
185 |
+
// add our hidden field in the new category form - for each hierarchical taxonomy
|
186 |
+
// to set the language when creating a new category
|
187 |
+
// html code inserted come from html code itself.
|
188 |
+
$( '#' + taxonomy + '-add-submit' ).before( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.before
|
189 |
+
$( '<input />' ).attr( 'type', 'hidden' )
|
190 |
+
.attr( 'id', taxonomy + '-lang' )
|
191 |
+
.attr( 'name', 'term_lang_choice' )
|
192 |
+
.attr( 'value', $( '.post_lang_choice' ).val() )
|
193 |
+
);
|
194 |
+
}
|
195 |
+
);
|
196 |
+
|
197 |
+
// Initialize current language to be able to compare if it changes.
|
198 |
+
initializeLanguageOldValue();
|
199 |
+
|
200 |
+
// ajax for changing the post's language in the languages metabox
|
201 |
+
$( '.post_lang_choice' ).on(
|
202 |
+
'change',
|
203 |
+
function( event ) {
|
204 |
+
// Initialize the confirmation dialog box.
|
205 |
+
const confirmationModal = initializeConfimationModal();
|
206 |
+
const { dialogContainer: dialog } = confirmationModal;
|
207 |
+
let { dialogResult } = confirmationModal;
|
208 |
+
// The selected option in the dropdown list.
|
209 |
+
const selectedOption = event.target;
|
210 |
+
|
211 |
+
if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! isEmptyPost() ) {
|
212 |
+
dialog.dialog( 'open' );
|
213 |
+
} else {
|
214 |
+
dialogResult = Promise.resolve();
|
215 |
+
}
|
216 |
+
|
217 |
+
// phpcs:disable PEAR.Functions.FunctionCallSignature.EmptyLine
|
218 |
+
dialogResult.then(
|
219 |
+
() => {
|
220 |
+
var lang = selectedOption.options[selectedOption.options.selectedIndex].lang; // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
221 |
+
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
222 |
+
|
223 |
+
var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
224 |
+
action: 'post_lang_choice',
|
225 |
+
lang: selectedOption.value,
|
226 |
+
post_type: $( '#post_type' ).val(),
|
227 |
+
taxonomies: taxonomies,
|
228 |
+
post_id: $( '#post_ID' ).val(),
|
229 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
230 |
+
}
|
231 |
+
|
232 |
+
$.post(
|
233 |
+
ajaxurl,
|
234 |
+
data,
|
235 |
+
function( response ) {
|
236 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
237 |
+
$.each(
|
238 |
+
res.responses,
|
239 |
+
function() {
|
240 |
+
switch ( this.what ) {
|
241 |
+
case 'translations': // translations fields
|
242 |
+
// Data is built and come from server side and is well escaped when necessary
|
243 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
244 |
+
init_translations();
|
245 |
+
break;
|
246 |
+
case 'taxonomy': // categories metabox for posts
|
247 |
+
var tax = this.data;
|
248 |
+
// @see wp_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L175
|
249 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/class-walker-category-checklist.php#L89-L111
|
250 |
+
$( '#' + tax + 'checklist' ).html( this.supplemental.all ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
251 |
+
// @see wp_popular_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L236
|
252 |
+
$( '#' + tax + 'checklist-pop' ).html( this.supplemental.populars ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
253 |
+
// @see wp_dropdown_categories https://github.com/WordPress/WordPress/blob/5.5.1/wp-includes/category-template.php#L336
|
254 |
+
// which is called by PLL_Admin_Classic_Editor::post_lang_choice to generate supplemental.dropdown
|
255 |
+
$( '#new' + tax + '_parent' ).replaceWith( this.supplemental.dropdown ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
256 |
+
$( '#' + tax + '-lang' ).val( $( '.post_lang_choice' ).val() ); // hidden field
|
257 |
+
break;
|
258 |
+
case 'pages': // parent dropdown list for pages
|
259 |
+
// @see wp_dropdown_pages https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/post-template.php#L1186-L1208
|
260 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/class-walker-page-dropdown.php#L88
|
261 |
+
$( '#parent_id' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
262 |
+
break;
|
263 |
+
case 'flag': // flag in front of the select dropdown
|
264 |
+
// Data is built and come from server side and is well escaped when necessary
|
265 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
266 |
+
break;
|
267 |
+
case 'permalink': // Sample permalink
|
268 |
+
var div = $( '#edit-slug-box' );
|
269 |
+
if ( '-1' != this.data && div.children().length ) {
|
270 |
+
// @see get_sample_permalink_html https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/post.php#L1425-L1454
|
271 |
+
div.html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
272 |
+
}
|
273 |
+
break;
|
274 |
+
}
|
275 |
+
}
|
276 |
+
);
|
277 |
+
|
278 |
+
// Update the old language with the new one to be able to compare it in the next changing.
|
279 |
+
initializeLanguageOldValue();
|
280 |
+
// modifies the language in the tag cloud
|
281 |
+
$( '.tagcloud-link' ).each(
|
282 |
+
function() {
|
283 |
+
var id = $( this ).attr( 'id' );
|
284 |
+
tagBox.get( id );
|
285 |
+
}
|
286 |
+
);
|
287 |
+
|
288 |
+
// Modifies the text direction
|
289 |
+
$( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
|
290 |
+
$( '#content_ifr' ).contents().find( 'html' ).attr( 'lang', lang ).attr( 'dir', dir );
|
291 |
+
$( '#content_ifr' ).contents().find( 'body' ).attr( 'dir', dir );
|
292 |
+
|
293 |
+
pll.media.resetAllAttachmentsCollections();
|
294 |
+
}
|
295 |
+
)
|
296 |
+
},
|
297 |
+
() => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
|
298 |
+
);
|
299 |
+
// phpcs:enable PEAR.Functions.FunctionCallSignature.EmptyLine
|
300 |
+
|
301 |
+
function isEmptyPost() {
|
302 |
+
const title = $( 'input#title' ).val();
|
303 |
+
const content = $( 'textarea#content' ).val();
|
304 |
+
const excerpt = $( 'textarea#excerpt' ).val();
|
305 |
+
|
306 |
+
return ! title && ! content && ! excerpt;
|
307 |
+
}
|
308 |
+
}
|
309 |
+
);
|
310 |
+
|
311 |
+
// translations autocomplete input box
|
312 |
+
function init_translations() {
|
313 |
+
$( '.tr_lang' ).each(
|
314 |
+
function(){
|
315 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
316 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
317 |
+
|
318 |
+
$( this ).autocomplete(
|
319 |
+
{
|
320 |
+
minLength: 0,
|
321 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
322 |
+
'&post_language=' + $( '.post_lang_choice' ).val() +
|
323 |
+
'&translation_language=' + tr_lang +
|
324 |
+
'&post_type=' + $( '#post_type' ).val() +
|
325 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
326 |
+
select: function( event, ui ) {
|
327 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
328 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
329 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
330 |
+
},
|
331 |
+
}
|
332 |
+
);
|
333 |
+
|
334 |
+
// when the input box is emptied
|
335 |
+
$( this ).on(
|
336 |
+
'blur',
|
337 |
+
function() {
|
338 |
+
if ( ! $( this ).val() ) {
|
339 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
340 |
+
// Value is retrieved from HTML already generated server side
|
341 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
342 |
+
}
|
343 |
+
}
|
344 |
+
);
|
345 |
+
}
|
346 |
+
);
|
347 |
+
}
|
348 |
+
|
349 |
+
init_translations();
|
350 |
+
}
|
351 |
+
);
|
352 |
+
|
353 |
+
/**
|
354 |
+
* @since 3.0
|
355 |
+
*
|
356 |
+
* @namespace pll
|
357 |
+
*/
|
358 |
+
var pll = window.pll || {};
|
359 |
+
|
360 |
+
/**
|
361 |
+
* @since 3.0
|
362 |
+
*
|
363 |
+
* @namespace pll.media
|
364 |
+
*/
|
365 |
+
_.extend( pll, { media: {} } );
|
366 |
+
|
367 |
+
/**
|
368 |
+
* @since 3.0
|
369 |
+
*
|
370 |
+
* @alias pll.media
|
371 |
+
* @memberOf pll
|
372 |
+
* @namespace
|
373 |
+
*/
|
374 |
+
var media = _.extend(
|
375 |
+
pll.media, /** @lends pll.media.prototype */
|
376 |
+
{
|
377 |
+
/**
|
378 |
+
* TODO: Find a way to delete references to Attachments collections that are not used anywhere else.
|
379 |
+
*
|
380 |
+
* @type {wp.media.model.Attachments}
|
381 |
+
*/
|
382 |
+
attachmentsCollections : [],
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Imitates { @see wp.media.query } but log all Attachments collections created.
|
386 |
+
*
|
387 |
+
* @param {Object} [props]
|
388 |
+
* @return {wp.media.model.Attachments}
|
389 |
+
*/
|
390 |
+
query: function( props ) {
|
391 |
+
var attachments = pll.media.query.delegate();
|
392 |
+
|
393 |
+
pll.media.attachmentsCollections.push( attachments );
|
394 |
+
|
395 |
+
return attachments;
|
396 |
+
},
|
397 |
+
|
398 |
+
resetAllAttachmentsCollections: function() {
|
399 |
+
this.attachmentsCollections.forEach(
|
400 |
+
function( attachmentsCollection ) {
|
401 |
+
/**
|
402 |
+
* First reset the { @see wp.media.model.Attachments } collection.
|
403 |
+
* Then, if it is mirroring a { @see wp.media.model.Query } collection,
|
404 |
+
* refresh this one too, so it will fetch new data from the server,
|
405 |
+
* and then the wp.media.model.Attachments collection will syncrhonize with the new data.
|
406 |
+
*/
|
407 |
+
attachmentsCollection.reset();
|
408 |
+
if (attachmentsCollection.mirroring) {
|
409 |
+
attachmentsCollection.mirroring._hasMore = true;
|
410 |
+
attachmentsCollection.mirroring.reset();
|
411 |
+
}
|
412 |
+
}
|
413 |
+
);
|
414 |
+
}
|
415 |
+
}
|
416 |
+
);
|
417 |
+
|
418 |
+
/**
|
419 |
+
* @since 3.0
|
420 |
+
*
|
421 |
+
* @memberOf pll.media
|
422 |
+
*/
|
423 |
+
media.query = _.extend(
|
424 |
+
media.query, /** @lends pll.media.query prototype */
|
425 |
+
{
|
426 |
+
/**
|
427 |
+
* @type Function References WordPress { @see wp.media.query } constructor
|
428 |
+
*/
|
429 |
+
delegate: wp.media.query
|
430 |
+
}
|
431 |
+
)
|
432 |
+
|
433 |
+
// Substitute WordPress media query shortcut with our decorated function.
|
434 |
+
wp.media.query = media.query
|
435 |
+
|
436 |
+
|
js/build/classic-editor.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"use strict";const{__}=wp.i18n,languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const t=jQuery("<div/>",{id:"pll-dialog",style:"display:none;"}).text(__("Are you sure you want to change the language of the current content?","polylang"));languagesList.after(t);const a=new Promise(((a,e)=>{const l=l=>{switch(l){case"yes":languagesList.data("old-value",languagesList.children(":selected")[0].value),a();break;case"no":languagesList.val(languagesList.data("old-value")),e("Cancel")}t.dialog("close")};t.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:__("Change language","polylang"),minWidth:600,maxWidth:"100%",classes:{"ui-dialog":"pll-confirmation-modal"},open:function(t,a){jQuery("body").hasClass("rtl")&&jQuery(this).parent().css({right:jQuery(this).parent().css("left"),left:"auto"})},close:function(t,a){l("no")},buttons:[{text:__("OK","polylang"),click:function(t){l("yes")}},{text:__("Cancel","polylang"),click:function(t){l("no")}}]})}));return{dialogContainer:t,dialogResult:a}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected")[0].value)};jQuery((function(t){t.ajaxPrefilter((function(a,e,l){var n=t(".post_lang_choice").val();"string"==typeof a.data&&-1!==a.url.indexOf("action=ajax-tag-search")&&n&&(a.data="lang="+n+"&"+a.data)}))})),jQuery((function(t){tagBox.get=function(a){var e=a.substr(a.indexOf("-")+1),l={action:"get-tagcloud",lang:t(".post_lang_choice").val(),tax:e};t.post(ajaxurl,l,(function(l,n){0!=l&&"success"==n||(l=wpAjax.broken),l=t("<div />").addClass("the-tagcloud").attr("id","tagcloud-"+e).html(l),t("a",l).on("click",(function(){return tagBox.flushTags(t(this).closest(".inside").children(".tagsdiv"),this),!1}));var i=t("#tagcloud-"+e).css("display");i?(t("#tagcloud-"+e).replaceWith(l),t("#tagcloud-"+e).css("display",i)):t("#"+a).after(l)}))}})),jQuery((function(t){var a=new Array;function e(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=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(l,n){t("#htr_lang_"+a).val(n.item.id),e.html(n.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}t(".categorydiv").each((function(){var e,l;(e=t(this).attr("id").split("-")).shift(),l=e.join("-"),a.push(l),t("#"+l+"-add-submit").before(t("<input />").attr("type","hidden").attr("id",l+"-lang").attr("name","term_lang_choice").attr("value",t(".post_lang_choice").val()))})),initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(l){const n=initializeConfimationModal(),{dialogContainer:i}=n;let{dialogResult:s}=n;const o=l.target;t(this).data("old-value")===o.value||function(){const a=t("input#title").val(),e=t("textarea#content").val(),l=t("textarea#excerpt").val();return!a&&!e&&!l}()?s=Promise.resolve():i.dialog("open"),s.then((()=>{var l=o.options[o.options.selectedIndex].lang,n=t('.pll-translation-column > span[lang="'+l+'"]').attr("dir"),i={action:"post_lang_choice",lang:o.value,post_type:t("#post_type").val(),taxonomies:a,post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,i,(function(a){var i=wpAjax.parseAjaxResponse(a,"ajax-response");t.each(i.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),e();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 l=t("#edit-slug-box");"-1"!=this.data&&l.children().length&&l.html(this.data)}})),initializeLanguageOldValue(),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-"+n),t("#content_ifr").contents().find("html").attr("lang",l).attr("dir",n),t("#content_ifr").contents().find("body").attr("dir",n),pll.media.resetAllAttachmentsCollections()}))}),(()=>{}))})),e()}));var pll=window.pll||{};_.extend(pll,{media:{}});var media=_.extend(pll.media,{attachmentsCollections:[],query:function(t){var a=pll.media.query.delegate();return pll.media.attachmentsCollections.push(a),a},resetAllAttachmentsCollections:function(){this.attachmentsCollections.forEach((function(t){t.reset(),t.mirroring&&(t.mirroring._hasMore=!0,t.mirroring.reset())}))}});media.query=_.extend(media.query,{delegate:wp.media.query}),wp.media.query=media.query;
|
js/build/languages-step.js
ADDED
@@ -0,0 +1,303 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @package Polylang
|
3 |
+
*/
|
4 |
+
|
5 |
+
jQuery(
|
6 |
+
function( $ ) {
|
7 |
+
var addLanguageForm = $( '.languages-step' ); // Form element.
|
8 |
+
var languageFields = $( '#language-fields' ); // Element where to append hidden fields for creating language.
|
9 |
+
var languagesTable = $( '#languages' ); // Table element contains languages list to create.
|
10 |
+
var languagesListTable = $( '#languages tbody' ); // Table rows with languages list to create.
|
11 |
+
var definedLanguagesListTable = $( '#defined-languages tbody' ); // Table rows with already defined languages list.
|
12 |
+
var languagesList = $( '#lang_list' ); // Select form element with predefined languages without already created languages.
|
13 |
+
var nextStepButton = $( '[name="save_step"]' ); // The button for continuing to the next step.
|
14 |
+
var messagesContainer = $( '#messages' ); // Element where to display error messages.
|
15 |
+
var languagesMap = new Map(); // Languages map object for managing the languages to create.
|
16 |
+
var dialog = $( '#dialog' ); // Dialog box for alerting the language selected has not been added to the list.
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Add a language in the list to create it in Polylang settings
|
20 |
+
*
|
21 |
+
* @param {object} language The language object
|
22 |
+
*/
|
23 |
+
function addLanguage( language ) {
|
24 |
+
// language properties come from the select dropdown which is built server side and well escaped.
|
25 |
+
// see template view-wizard-step-languages.php.
|
26 |
+
var languageValueHtml = $( '<td />' ).text( language.text ).prepend( language.flagUrl ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
27 |
+
var languageTrashIconHtml = $( '<td />' )
|
28 |
+
.append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
29 |
+
$( '<span />' )
|
30 |
+
.addClass( 'dashicons dashicons-trash' )
|
31 |
+
.attr( 'data-language', language.locale )
|
32 |
+
.append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
33 |
+
$( '<span />' )
|
34 |
+
.addClass( 'screen-reader-text' )
|
35 |
+
.text( pll_wizard_params.i18n_remove_language_icon )
|
36 |
+
)
|
37 |
+
);
|
38 |
+
// see the comment and the harcoded code above. languageTrashIconHtml and languageValueHtml are safe.
|
39 |
+
var languageLineHtml = $( '<tr />' ).prepend( languageTrashIconHtml ).prepend( languageValueHtml ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
40 |
+
var languageFieldHtml = $( '<input />' ).attr(
|
41 |
+
{
|
42 |
+
type: 'hidden',
|
43 |
+
name: 'languages[]'
|
44 |
+
}
|
45 |
+
).val( language.locale );
|
46 |
+
|
47 |
+
languagesList.val( '' );
|
48 |
+
languagesList.selectmenu( 'refresh' ); // Refresh jQuery selectmenu widget after changing the value.
|
49 |
+
|
50 |
+
languagesMap.set( language.locale, language );
|
51 |
+
|
52 |
+
// see above how languageLineHtml is built.
|
53 |
+
languagesListTable.append( languageLineHtml ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
54 |
+
// Bind click event on trash icon.
|
55 |
+
languagesListTable.on(
|
56 |
+
'click',
|
57 |
+
'span[data-language=' + language.locale + ']',
|
58 |
+
function( event ) {
|
59 |
+
event.preventDefault();
|
60 |
+
// Remove line in languages table.
|
61 |
+
$( this ).parents( 'tr' ).remove();
|
62 |
+
// Remove input field.
|
63 |
+
var languageField = languageFields.children( 'input[value=' + $( this ).data( 'language' ) + ']' ).remove();
|
64 |
+
// If there is no more languages hide languages table.
|
65 |
+
if ( languagesListTable.children().length <= 0 ) {
|
66 |
+
languagesTable.hide();
|
67 |
+
}
|
68 |
+
// Remove language from the Map.
|
69 |
+
languagesMap.delete( $( this ).data( 'language' ) );
|
70 |
+
// Hide error message.
|
71 |
+
hideError();
|
72 |
+
}
|
73 |
+
);
|
74 |
+
// see above how languageFieldHtml is built.
|
75 |
+
// Add hidden input field for posting the form.
|
76 |
+
languageFields.append( languageFieldHtml ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Display an error message
|
82 |
+
*
|
83 |
+
* @param {string} message The message to display
|
84 |
+
*/
|
85 |
+
function showError( message ) {
|
86 |
+
messagesContainer.empty();
|
87 |
+
// html is harcoded and use of jQuery text method which is safe to add message value.
|
88 |
+
// In addition message is i18n value which is initialized server side in PLL_Wizard::add_step_languages and correctly escaped.
|
89 |
+
messagesContainer.prepend( $( '<p/>' ).addClass( 'error' ).text( message ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Hide all error messages and fields in error
|
94 |
+
*/
|
95 |
+
function hideError() {
|
96 |
+
messagesContainer.empty();
|
97 |
+
addLanguageForm.find( '.error' ).removeClass( 'error field-in-error' );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Style the field to indicate where the error is
|
102 |
+
*
|
103 |
+
* @param {object} field The jQuery element which is in error
|
104 |
+
*/
|
105 |
+
function showFieldInError( field ) {
|
106 |
+
field.addClass( 'error field-in-error' );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Focus on a specific element
|
111 |
+
*
|
112 |
+
* @param {object} field The jQuery element which will be focused
|
113 |
+
*/
|
114 |
+
function focusOnField( field ) {
|
115 |
+
field.trigger( 'focus' );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Disable a specific button
|
120 |
+
*
|
121 |
+
* @param {object} button
|
122 |
+
*/
|
123 |
+
function disableButton( button ){
|
124 |
+
button.prop( 'disabled', true );
|
125 |
+
// Because the button is disabled we need to add the value of the button to ensure it will pass in the request.
|
126 |
+
addLanguageForm.append( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
127 |
+
$( '<input />' ).prop(
|
128 |
+
{
|
129 |
+
type: 'hidden',
|
130 |
+
name: button.prop( 'name' ),
|
131 |
+
value: button.prop( 'value' )
|
132 |
+
}
|
133 |
+
)
|
134 |
+
);
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Remove error when a new selection is done in languages list.
|
139 |
+
*/
|
140 |
+
languagesList.on(
|
141 |
+
'selectmenuchange',
|
142 |
+
function() {
|
143 |
+
hideError();;
|
144 |
+
}
|
145 |
+
);
|
146 |
+
/**
|
147 |
+
* Bind click event on "Add language" button
|
148 |
+
*/
|
149 |
+
$( '#add-language' ).on(
|
150 |
+
'click',
|
151 |
+
function( event ) {
|
152 |
+
hideError();
|
153 |
+
var selectedOption = event.currentTarget.form.lang_list.options[event.currentTarget.form.lang_list.selectedIndex];
|
154 |
+
if ( '' !== selectedOption.value && ! languagesMap.has( selectedOption.value ) ) {
|
155 |
+
addLanguage(
|
156 |
+
{
|
157 |
+
locale: selectedOption.value,
|
158 |
+
text: selectedOption.innerText,
|
159 |
+
name: $( selectedOption ).data( 'language-name' ),
|
160 |
+
flagUrl: $( selectedOption ).data( 'flag-html' )
|
161 |
+
}
|
162 |
+
);
|
163 |
+
// Show table of languages.
|
164 |
+
languagesTable.show();
|
165 |
+
// Put back the focus on the select language field after clicking on "Add language button".
|
166 |
+
focusOnField( $( '#lang_list-button' ) );
|
167 |
+
} else {
|
168 |
+
var message = pll_wizard_params.i18n_no_language_selected;
|
169 |
+
if ( languagesMap.has( selectedOption.value ) ) {
|
170 |
+
message = pll_wizard_params.i18n_language_already_added;
|
171 |
+
}
|
172 |
+
showError( message );
|
173 |
+
showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
|
174 |
+
focusOnField( $( '#lang_list-button' ) );
|
175 |
+
|
176 |
+
}
|
177 |
+
}
|
178 |
+
);
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Bind submit event on "add_lang" form
|
182 |
+
*/
|
183 |
+
addLanguageForm.on(
|
184 |
+
'submit',
|
185 |
+
function( event ) {
|
186 |
+
// Verify if there is at least one language.
|
187 |
+
var isLanguagesAlreadyDefined = definedLanguagesListTable.children().length > 0;
|
188 |
+
var selectedLanguage = $( '#lang_list' ).val();
|
189 |
+
if ( languagesMap.size <= 0 && ! isLanguagesAlreadyDefined ) {
|
190 |
+
if ( '' === selectedLanguage ) {
|
191 |
+
showError( pll_wizard_params.i18n_no_language_added );
|
192 |
+
showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
|
193 |
+
focusOnField( $( '#lang_list-button' ) );
|
194 |
+
} else {
|
195 |
+
showError( pll_wizard_params.i18n_add_language_needed );
|
196 |
+
showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
|
197 |
+
focusOnField( $( '#add-language' ) ); // Put the focus on the "Add language" button.
|
198 |
+
}
|
199 |
+
return false;
|
200 |
+
}
|
201 |
+
// Verify if the language has been added in the list otherwise display a dialog box to confirm what to do.
|
202 |
+
if ( '' !== selectedLanguage ) {
|
203 |
+
// Verify we don't add a duplicate language before opening the dialog box otherwise display an error message.
|
204 |
+
if ( ! languagesMap.has( selectedLanguage ) ) {
|
205 |
+
dialog.dialog( 'open' );
|
206 |
+
} else {
|
207 |
+
showError( pll_wizard_params.i18n_language_already_added );
|
208 |
+
showFieldInError( languagesList.next( 'span.ui-selectmenu-button' ) );
|
209 |
+
focusOnField( $( '#lang_list-button' ) );
|
210 |
+
}
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
disableButton( nextStepButton );
|
214 |
+
}
|
215 |
+
);
|
216 |
+
|
217 |
+
// Is there an error return by PHP ?
|
218 |
+
var searchParams = new URLSearchParams( document.location.search );
|
219 |
+
if ( searchParams.has( 'activate_error' ) ) {
|
220 |
+
// If the error code exists, display it.
|
221 |
+
if ( undefined !== pll_wizard_params[ searchParams.get( 'activate_error' ) ] ) {
|
222 |
+
showError( pll_wizard_params[ searchParams.get( 'activate_error' ) ] );
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
function confirmDialog( what ) {
|
227 |
+
switch ( what ) {
|
228 |
+
case 'yes':
|
229 |
+
var selectedOption = $( '#lang_list' ).children( ':selected' );
|
230 |
+
addLanguage(
|
231 |
+
{
|
232 |
+
locale: selectedOption[0].value,
|
233 |
+
text: selectedOption[0].innerText,
|
234 |
+
name: $( selectedOption ).data( 'language-name' ),
|
235 |
+
flagUrl: $( selectedOption ).data( 'flag-html' )
|
236 |
+
}
|
237 |
+
);
|
238 |
+
break;
|
239 |
+
case 'no':
|
240 |
+
// Empty select form field and submit again the form.
|
241 |
+
languagesList.val( '' );
|
242 |
+
break;
|
243 |
+
case 'ignore':
|
244 |
+
}
|
245 |
+
dialog.dialog( 'close' );
|
246 |
+
if ( 'ignore' === what ) {
|
247 |
+
focusOnField( $( '#lang_list-button' ) );
|
248 |
+
} else {
|
249 |
+
addLanguageForm.submit();
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
// Initialize dialog box in the case a language is selected but not added in the list.
|
254 |
+
dialog.dialog(
|
255 |
+
{
|
256 |
+
autoOpen: false,
|
257 |
+
modal: true,
|
258 |
+
draggable: false,
|
259 |
+
resizable: false,
|
260 |
+
title: pll_wizard_params.i18n_dialog_title,
|
261 |
+
minWidth: 600,
|
262 |
+
maxWidth: '100%',
|
263 |
+
open: function( event, ui ) {
|
264 |
+
// Change dialog box position for rtl language
|
265 |
+
if ( $( 'body' ).hasClass( 'rtl' ) ) {
|
266 |
+
$( this ).parent().css(
|
267 |
+
{
|
268 |
+
right: $( this ).parent().css( 'left' ),
|
269 |
+
left: 'auto'
|
270 |
+
}
|
271 |
+
);
|
272 |
+
}
|
273 |
+
// Display language name and flag information in dialog box.
|
274 |
+
$( this ).find( '#dialog-language' ).text( $( '#lang_list' ).children( ':selected' )[0].innerText );
|
275 |
+
// language properties come from the select dropdown #lang_list which is built server side and well escaped.
|
276 |
+
// see template view-wizard-step-languages.php.
|
277 |
+
$( this ).find( '#dialog-language-flag' ).empty().prepend( $( '#lang_list' ).children( ':selected' ).data( 'flag-html' ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
278 |
+
},
|
279 |
+
buttons: [
|
280 |
+
{
|
281 |
+
text: pll_wizard_params.i18n_dialog_yes_button,
|
282 |
+
click: function( event ) {
|
283 |
+
confirmDialog( 'yes' );
|
284 |
+
}
|
285 |
+
},
|
286 |
+
{
|
287 |
+
text: pll_wizard_params.i18n_dialog_no_button,
|
288 |
+
click: function( event ) {
|
289 |
+
confirmDialog( 'no' );
|
290 |
+
}
|
291 |
+
},
|
292 |
+
{
|
293 |
+
text: pll_wizard_params.i18n_dialog_ignore_button,
|
294 |
+
click: function( event ) {
|
295 |
+
confirmDialog( 'ignore' );
|
296 |
+
}
|
297 |
+
}
|
298 |
+
]
|
299 |
+
}
|
300 |
+
)
|
301 |
+
}
|
302 |
+
);
|
303 |
+
|
js/build/languages-step.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(a){var e=a(".languages-step"),n=a("#language-fields"),t=a("#languages"),l=a("#languages tbody"),i=a("#defined-languages tbody"),r=a("#lang_list"),d=a('[name="save_step"]'),s=a("#messages"),o=new Map,g=a("#dialog");function u(e){var i=a("<td />").text(e.text).prepend(e.flagUrl),d=a("<td />").append(a("<span />").addClass("dashicons dashicons-trash").attr("data-language",e.locale).append(a("<span />").addClass("screen-reader-text").text(pll_wizard_params.i18n_remove_language_icon))),s=a("<tr />").prepend(d).prepend(i),g=a("<input />").attr({type:"hidden",name:"languages[]"}).val(e.locale);r.val(""),r.selectmenu("refresh"),o.set(e.locale,e),l.append(s),l.on("click","span[data-language="+e.locale+"]",(function(e){e.preventDefault(),a(this).parents("tr").remove();n.children("input[value="+a(this).data("language")+"]").remove();l.children().length<=0&&t.hide(),o.delete(a(this).data("language")),c()})),n.append(g)}function p(e){s.empty(),s.prepend(a("<p/>").addClass("error").text(e))}function c(){s.empty(),e.find(".error").removeClass("error field-in-error")}function _(a){a.addClass("error field-in-error")}function m(a){a.trigger("focus")}r.on("selectmenuchange",(function(){c()})),a("#add-language").on("click",(function(e){c();var n=e.currentTarget.form.lang_list.options[e.currentTarget.form.lang_list.selectedIndex];if(""===n.value||o.has(n.value)){var l=pll_wizard_params.i18n_no_language_selected;o.has(n.value)&&(l=pll_wizard_params.i18n_language_already_added),p(l),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))}else u({locale:n.value,text:n.innerText,name:a(n).data("language-name"),flagUrl:a(n).data("flag-html")}),t.show(),m(a("#lang_list-button"))})),e.on("submit",(function(n){var t,l=i.children().length>0,s=a("#lang_list").val();return o.size<=0&&!l?(""===s?(p(pll_wizard_params.i18n_no_language_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):(p(pll_wizard_params.i18n_add_language_needed),_(r.next("span.ui-selectmenu-button")),m(a("#add-language"))),!1):""!==s?(o.has(s)?(p(pll_wizard_params.i18n_language_already_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):g.dialog("open"),!1):((t=d).prop("disabled",!0),void e.append(a("<input />").prop({type:"hidden",name:t.prop("name"),value:t.prop("value")})))}));var h=new URLSearchParams(document.location.search);function f(n){switch(n){case"yes":var t=a("#lang_list").children(":selected");u({locale:t[0].value,text:t[0].innerText,name:a(t).data("language-name"),flagUrl:a(t).data("flag-html")});break;case"no":r.val("")}g.dialog("close"),"ignore"===n?m(a("#lang_list-button")):e.submit()}h.has("activate_error")&&void 0!==pll_wizard_params[h.get("activate_error")]&&p(pll_wizard_params[h.get("activate_error")]),g.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:pll_wizard_params.i18n_dialog_title,minWidth:600,maxWidth:"100%",open:function(e,n){a("body").hasClass("rtl")&&a(this).parent().css({right:a(this).parent().css("left"),left:"auto"}),a(this).find("#dialog-language").text(a("#lang_list").children(":selected")[0].innerText),a(this).find("#dialog-language-flag").empty().prepend(a("#lang_list").children(":selected").data("flag-html"))},buttons:[{text:pll_wizard_params.i18n_dialog_yes_button,click:function(a){f("yes")}},{text:pll_wizard_params.i18n_dialog_no_button,click:function(a){f("no")}},{text:pll_wizard_params.i18n_dialog_ignore_button,click:function(a){f("ignore")}}]})}));
|
js/build/nav-menu.js
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Handles the options in the language switcher nav menu metabox.
|
3 |
+
*
|
4 |
+
* @package Polylang
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(
|
8 |
+
function( $ ) {
|
9 |
+
$( '#update-nav-menu' ).on(
|
10 |
+
'click',
|
11 |
+
function( e ) {
|
12 |
+
if ( e.target && e.target.className && -1 != e.target.className.indexOf( 'item-edit' ) ) {
|
13 |
+
$( "input[value='#pll_switcher'][type=text]" ).parent().parent().parent().each(
|
14 |
+
function(){
|
15 |
+
var item = $( this ).attr( 'id' ).substring( 19 );
|
16 |
+
$( this ).children( 'p:not( .field-move )' ).remove(); // remove default fields we don't need
|
17 |
+
|
18 |
+
// item is a number part of id of parent menu item built by WordPress
|
19 |
+
// pll_data is built server side with i18n strings without HTML and data retrieved from post meta
|
20 |
+
// the usage of attr method is safe before append call.
|
21 |
+
h = $( '<input>' ).attr(
|
22 |
+
{
|
23 |
+
type: 'hidden',
|
24 |
+
id: 'edit-menu-item-title-' + item,
|
25 |
+
name: 'menu-item-title[' + item + ']',
|
26 |
+
value: pll_data.title
|
27 |
+
}
|
28 |
+
);
|
29 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
30 |
+
|
31 |
+
h = $( '<input>' ).attr(
|
32 |
+
{
|
33 |
+
type: 'hidden',
|
34 |
+
id: 'edit-menu-item-url-' + item,
|
35 |
+
name: 'menu-item-url[' + item + ']',
|
36 |
+
value: '#pll_switcher'
|
37 |
+
}
|
38 |
+
);
|
39 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
40 |
+
|
41 |
+
// a hidden field which exits only if our jQuery code has been executed
|
42 |
+
h = $( '<input>' ).attr(
|
43 |
+
{
|
44 |
+
type: 'hidden',
|
45 |
+
id: 'edit-menu-item-pll-detect-' + item,
|
46 |
+
name: 'menu-item-pll-detect[' + item + ']',
|
47 |
+
value: 1
|
48 |
+
}
|
49 |
+
);
|
50 |
+
$( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
51 |
+
|
52 |
+
ids = Array( 'hide_if_no_translation', 'hide_current', 'force_home', 'show_flags', 'show_names', 'dropdown' ); // reverse order
|
53 |
+
|
54 |
+
// add the fields
|
55 |
+
for ( var i = 0, idsLength = ids.length; i < idsLength; i++ ) {
|
56 |
+
p = $( '<p>' ).attr( 'class', 'description' );
|
57 |
+
// p is hardcoded just above by using attr method which is safe.
|
58 |
+
$( this ).prepend( p ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
59 |
+
// item is a number part of id of parent menu item built by WordPress
|
60 |
+
// pll_data is built server side with i18n strings without HTML
|
61 |
+
label = $( '<label>' ).attr( 'for', 'edit-menu-item-' + ids[ i ] + '-' + item ).text( ' ' + pll_data.strings[ ids[ i ] ] );
|
62 |
+
p.append( label ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
63 |
+
cb = $( '<input>' ).attr(
|
64 |
+
{
|
65 |
+
type: 'checkbox',
|
66 |
+
id: 'edit-menu-item-' + ids[ i ] + '-' + item,
|
67 |
+
name: 'menu-item-' + ids[ i ] + '[' + item + ']',
|
68 |
+
value: 1
|
69 |
+
}
|
70 |
+
);
|
71 |
+
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
|
72 |
+
cb.prop( 'checked', true );
|
73 |
+
}
|
74 |
+
// See reasons above. Checkbox are totaly hardcoded here with safe value
|
75 |
+
label.prepend( cb ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
76 |
+
}
|
77 |
+
}
|
78 |
+
);
|
79 |
+
|
80 |
+
// disallow unchecking both show names and show flags
|
81 |
+
$( '.menu-item-data-object-id' ).each(
|
82 |
+
function() {
|
83 |
+
var id = $( this ).val();
|
84 |
+
var options = ['names-', 'flags-'];
|
85 |
+
$.each(
|
86 |
+
options,
|
87 |
+
function( i, v ) {
|
88 |
+
$( '#edit-menu-item-show_' + v + id ).on(
|
89 |
+
'change',
|
90 |
+
function() {
|
91 |
+
if ( true != $( this ).prop( 'checked' ) ) {
|
92 |
+
$( '#edit-menu-item-show_' + options[ 1 - i ] + id ).prop( 'checked', true );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
);
|
96 |
+
}
|
97 |
+
);
|
98 |
+
}
|
99 |
+
);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
);
|
103 |
+
}
|
104 |
+
);
|
105 |
+
|
js/build/nav-menu.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(e){e("#update-nav-menu").on("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).on("change",(function(){1!=e(this).prop("checked")&&e("#edit-menu-item-show_"+i[1-a]+t).prop("checked",!0)}))}))})))}))}));
|
js/build/post.js
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @package Polylang
|
3 |
+
*/
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Tag suggest in quick edit
|
7 |
+
*/
|
8 |
+
jQuery(
|
9 |
+
function( $ ) {
|
10 |
+
$.ajaxPrefilter(
|
11 |
+
function( options, originalOptions, jqXHR ) {
|
12 |
+
if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=ajax-tag-search' ) && ( lang = $( ':input[name="inline_lang_choice"]' ).val() ) ) {
|
13 |
+
options.data = 'lang=' + lang + '&' + options.data;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
);
|
17 |
+
}
|
18 |
+
);
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Quick edit
|
22 |
+
*/
|
23 |
+
jQuery(
|
24 |
+
function( $ ) {
|
25 |
+
$( document ).on(
|
26 |
+
'DOMNodeInserted',
|
27 |
+
function( e ) {
|
28 |
+
var t = $( e.target );
|
29 |
+
|
30 |
+
// WP inserts the quick edit from
|
31 |
+
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
32 |
+
var post_id = t.prev().attr( 'id' ).replace( "post-", "" );
|
33 |
+
|
34 |
+
if ( post_id > 0 ) {
|
35 |
+
// language dropdown
|
36 |
+
var select = t.find( ':input[name="inline_lang_choice"]' );
|
37 |
+
var lang = $( '#lang_' + post_id ).html();
|
38 |
+
select.val( lang ); // populates the dropdown
|
39 |
+
|
40 |
+
filter_terms( lang ); // initial filter for category checklist
|
41 |
+
filter_pages( lang ); // initial filter for parent dropdown
|
42 |
+
|
43 |
+
// modify category checklist an parent dropdown on language change
|
44 |
+
select.on(
|
45 |
+
'change',
|
46 |
+
function() {
|
47 |
+
filter_terms( $( this ).val() );
|
48 |
+
filter_pages( $( this ).val() );
|
49 |
+
}
|
50 |
+
);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Filters the category checklist.
|
56 |
+
*/
|
57 |
+
function filter_terms( lang ) {
|
58 |
+
if ( "undefined" != typeof( pll_term_languages ) ) {
|
59 |
+
$.each(
|
60 |
+
pll_term_languages,
|
61 |
+
function( lg, term_tax ) {
|
62 |
+
$.each(
|
63 |
+
term_tax,
|
64 |
+
function( tax, terms ) {
|
65 |
+
$.each(
|
66 |
+
terms,
|
67 |
+
function( i ) {
|
68 |
+
id = '#' + tax + '-' + pll_term_languages[ lg ][ tax ][ i ];
|
69 |
+
lang == lg ? $( id ).show() : $( id ).hide();
|
70 |
+
}
|
71 |
+
);
|
72 |
+
}
|
73 |
+
);
|
74 |
+
}
|
75 |
+
);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Filters the parent page dropdown list.
|
81 |
+
*/
|
82 |
+
function filter_pages( lang ) {
|
83 |
+
if ( "undefined" != typeof( pll_page_languages ) ) {
|
84 |
+
$.each(
|
85 |
+
pll_page_languages,
|
86 |
+
function( lg, pages ) {
|
87 |
+
$.each(
|
88 |
+
pages,
|
89 |
+
function( i ) {
|
90 |
+
v = $( '#post_parent option[value="' + pll_page_languages[ lg ][ i ] + '"]' );
|
91 |
+
lang == lg ? v.show() : v.hide();
|
92 |
+
}
|
93 |
+
);
|
94 |
+
}
|
95 |
+
);
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
);
|
100 |
+
}
|
101 |
+
);
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Update rows of translated posts when the language is modified in quick edit
|
105 |
+
* Acts on ajaxSuccess event
|
106 |
+
*/
|
107 |
+
jQuery(
|
108 |
+
function( $ ) {
|
109 |
+
$( document ).ajaxSuccess(
|
110 |
+
function( event, xhr, settings ) {
|
111 |
+
function update_rows( post_id ) {
|
112 |
+
// collect old translations
|
113 |
+
var translations = new Array();
|
114 |
+
$( '.translation_' + post_id ).each(
|
115 |
+
function() {
|
116 |
+
translations.push( $( this ).parent().parent().attr( 'id' ).substring( 5 ) );
|
117 |
+
}
|
118 |
+
);
|
119 |
+
|
120 |
+
var data = {
|
121 |
+
action: 'pll_update_post_rows',
|
122 |
+
post_id: post_id,
|
123 |
+
translations: translations.join( ',' ),
|
124 |
+
post_type: $( "input[name='post_type']" ).val(),
|
125 |
+
screen: $( "input[name='screen']" ).val(),
|
126 |
+
_pll_nonce: $( "input[name='_inline_edit']" ).val() // reuse quick edit nonce
|
127 |
+
};
|
128 |
+
|
129 |
+
// get the modified rows in ajax and update them
|
130 |
+
$.post(
|
131 |
+
ajaxurl,
|
132 |
+
data,
|
133 |
+
function( response ) {
|
134 |
+
if ( response ) {
|
135 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
136 |
+
$.each(
|
137 |
+
res.responses,
|
138 |
+
function() {
|
139 |
+
if ( 'row' == this.what ) {
|
140 |
+
// data is built with a call to WP_Posts_List_Table::single_row method
|
141 |
+
// which uses internally other WordPress methods which escape correctly values.
|
142 |
+
// For Polylang language columns the HTML code is correctly escaped in PLL_Admin_Filters_Columns::post_column method.
|
143 |
+
$( "#post-" + this.supplemental.post_id ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
144 |
+
}
|
145 |
+
}
|
146 |
+
);
|
147 |
+
}
|
148 |
+
}
|
149 |
+
);
|
150 |
+
}
|
151 |
+
|
152 |
+
if ( 'string' == typeof( settings.data ) ) { // Need to check the type due to block editor sometime sending FormData objects
|
153 |
+
var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
|
154 |
+
if ( 'undefined' != typeof( data['action'] ) && 'inline-save' == data['action'] ) {
|
155 |
+
update_rows( data['post_ID'] );
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
);
|
160 |
+
}
|
161 |
+
);
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Media list table
|
165 |
+
* When clicking on attach link, filters find post list per media language
|
166 |
+
*/
|
167 |
+
jQuery(
|
168 |
+
function( $ ) {
|
169 |
+
$.ajaxPrefilter(
|
170 |
+
function ( options, originalOptions, jqXHR ) {
|
171 |
+
if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=find_posts' ) ) {
|
172 |
+
options.data = 'pll_post_id=' + $( '#affected' ).val() + '&' + options.data;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
);
|
176 |
+
}
|
177 |
+
);
|
178 |
+
|
js/build/post.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)}))})),jQuery((function(a){a(document).on("DOMNodeInserted",(function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),s(o),i.on("change",(function(){l(a(this).val()),s(a(this).val())}))}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,(function(t,e){a.each(e,(function(e,i){a.each(i,(function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()}))}))}))}function s(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,(function(t,e){a.each(e,(function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()}))}))}}))})),jQuery((function(a){a(document).ajaxSuccess((function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each((function(){t.push(a(this).parent().parent().attr("id").substring(5))}));var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,(function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(t.responses,(function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)}))}));
|
js/build/term.js
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @package Polylang
|
3 |
+
*/
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Quick edit
|
7 |
+
*/
|
8 |
+
jQuery(
|
9 |
+
function( $ ) {
|
10 |
+
$( document ).on(
|
11 |
+
'DOMNodeInserted',
|
12 |
+
function( e ) {
|
13 |
+
var t = $( e.target );
|
14 |
+
|
15 |
+
// WP inserts the quick edit from
|
16 |
+
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
17 |
+
var term_id = t.prev().attr( 'id' ).replace( "tag-", "" );
|
18 |
+
|
19 |
+
if ( term_id > 0 ) {
|
20 |
+
// language dropdown
|
21 |
+
var select = t.find( ':input[name="inline_lang_choice"]' );
|
22 |
+
var lang = $( '#lang_' + term_id ).html();
|
23 |
+
select.val( lang ); // populates the dropdown
|
24 |
+
|
25 |
+
// disable the language dropdown for default categories
|
26 |
+
var default_cat = $( '#default_cat_' + term_id ).html();
|
27 |
+
if ( term_id == default_cat ) {
|
28 |
+
select.prop( 'disabled', true );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
);
|
34 |
+
}
|
35 |
+
);
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit.
|
39 |
+
* Acts on ajaxSuccess event.
|
40 |
+
*/
|
41 |
+
jQuery(
|
42 |
+
function( $ ) {
|
43 |
+
$( document ).ajaxSuccess(
|
44 |
+
function( event, xhr, settings ) {
|
45 |
+
function update_rows( term_id ) {
|
46 |
+
// collect old translations
|
47 |
+
var translations = new Array();
|
48 |
+
$( '.translation_' + term_id ).each(
|
49 |
+
function() {
|
50 |
+
translations.push( $( this ).parent().parent().attr( 'id' ).substring( 4 ) );
|
51 |
+
}
|
52 |
+
);
|
53 |
+
|
54 |
+
var data = {
|
55 |
+
action: 'pll_update_term_rows',
|
56 |
+
term_id: term_id,
|
57 |
+
translations: translations.join( ',' ),
|
58 |
+
taxonomy: $( "input[name='taxonomy']" ).val(),
|
59 |
+
post_type: $( "input[name='post_type']" ).val(),
|
60 |
+
screen: $( "input[name='screen']" ).val(),
|
61 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
62 |
+
};
|
63 |
+
|
64 |
+
// get the modified rows in ajax and update them
|
65 |
+
$.post(
|
66 |
+
ajaxurl,
|
67 |
+
data,
|
68 |
+
function( response ) {
|
69 |
+
if ( response ) {
|
70 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
71 |
+
$.each(
|
72 |
+
res.responses,
|
73 |
+
function() {
|
74 |
+
if ( 'row' == this.what ) {
|
75 |
+
// data is built with a call to WP_Terms_List_Table::single_row method
|
76 |
+
// which uses internally other WordPress methods which escape correctly values.
|
77 |
+
// For Polylang language columns the HTML code is correctly escaped in PLL_Admin_Filters_Columns::term_column method.
|
78 |
+
$( "#tag-" + this.supplemental.term_id ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
79 |
+
}
|
80 |
+
}
|
81 |
+
);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
|
88 |
+
if ( 'undefined' != typeof( data['action'] ) ) {
|
89 |
+
switch ( data['action'] ) {
|
90 |
+
// when adding a term, the new term_id is in the ajax response
|
91 |
+
case 'add-tag':
|
92 |
+
res = wpAjax.parseAjaxResponse( xhr.responseXML, 'ajax-response' );
|
93 |
+
$.each(
|
94 |
+
res.responses,
|
95 |
+
function() {
|
96 |
+
if ( 'term' == this.what ) {
|
97 |
+
update_rows( this.supplemental.term_id );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
);
|
101 |
+
|
102 |
+
// and also reset translations hidden input fields
|
103 |
+
$( '.htr_lang' ).val( 0 );
|
104 |
+
break;
|
105 |
+
|
106 |
+
// when deleting a term
|
107 |
+
case 'delete-tag':
|
108 |
+
update_rows( data['tag_ID'] );
|
109 |
+
break;
|
110 |
+
|
111 |
+
// in case the language is modified in quick edit and breaks translations
|
112 |
+
case 'inline-save-tax':
|
113 |
+
update_rows( data['tax_ID'] );
|
114 |
+
break;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
);
|
119 |
+
}
|
120 |
+
);
|
121 |
+
|
122 |
+
jQuery(
|
123 |
+
function( $ ) {
|
124 |
+
// translations autocomplete input box
|
125 |
+
function init_translations() {
|
126 |
+
$( '.tr_lang' ).each(
|
127 |
+
function(){
|
128 |
+
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
129 |
+
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
130 |
+
|
131 |
+
$( this ).autocomplete(
|
132 |
+
{
|
133 |
+
minLength: 0,
|
134 |
+
source: ajaxurl + '?action=pll_terms_not_translated' +
|
135 |
+
'&term_language=' + $( '#term_lang_choice' ).val() +
|
136 |
+
'&term_id=' + $( "input[name='tag_ID']" ).val() +
|
137 |
+
'&taxonomy=' + $( "input[name='taxonomy']" ).val() +
|
138 |
+
'&translation_language=' + tr_lang +
|
139 |
+
'&post_type=' + typenow +
|
140 |
+
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
141 |
+
select: function( event, ui ) {
|
142 |
+
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
143 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
144 |
+
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
145 |
+
},
|
146 |
+
}
|
147 |
+
);
|
148 |
+
|
149 |
+
// when the input box is emptied
|
150 |
+
$( this ).on(
|
151 |
+
'blur',
|
152 |
+
function() {
|
153 |
+
if ( ! $( this ).val() ) {
|
154 |
+
$( '#htr_lang_' + tr_lang ).val( 0 );
|
155 |
+
// Value is retrieved from HTML already generated server side
|
156 |
+
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
157 |
+
}
|
158 |
+
}
|
159 |
+
);
|
160 |
+
}
|
161 |
+
);
|
162 |
+
}
|
163 |
+
|
164 |
+
init_translations();
|
165 |
+
|
166 |
+
// ajax for changing the term's language
|
167 |
+
$( '#term_lang_choice' ).on(
|
168 |
+
'change',
|
169 |
+
function() {
|
170 |
+
var value = $( this ).val();
|
171 |
+
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
172 |
+
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' );
|
173 |
+
|
174 |
+
var data = {
|
175 |
+
action: 'term_lang_choice',
|
176 |
+
lang: value,
|
177 |
+
from_tag: $( "input[name='from_tag']" ).val(),
|
178 |
+
term_id: $( "input[name='tag_ID']" ).val(),
|
179 |
+
taxonomy: $( "input[name='taxonomy']" ).val(),
|
180 |
+
post_type: typenow,
|
181 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
182 |
+
};
|
183 |
+
|
184 |
+
$.post(
|
185 |
+
ajaxurl,
|
186 |
+
data,
|
187 |
+
function( response ) {
|
188 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
189 |
+
$.each(
|
190 |
+
res.responses,
|
191 |
+
function() {
|
192 |
+
switch ( this.what ) {
|
193 |
+
case 'translations': // translations fields
|
194 |
+
// Data is built and come from server side and is well escaped when necessary
|
195 |
+
$( "#term-translations" ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
196 |
+
init_translations();
|
197 |
+
break;
|
198 |
+
case 'parent': // parent dropdown list for hierarchical taxonomies
|
199 |
+
// data correctly escaped in PLL_Admin_Filters_Term::term_lang_choice method which uses wp_dropdown_categories function.
|
200 |
+
$( '#parent' ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
201 |
+
break;
|
202 |
+
case 'tag_cloud': // popular items
|
203 |
+
// data correctly escaped in PLL_Admin_Filters_Term::term_lang_choice method which uses wp_tag_cloud and wp_generate_tag_cloud functions.
|
204 |
+
$( '.tagcloud' ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
205 |
+
break;
|
206 |
+
case 'flag': // flag in front of the select dropdown
|
207 |
+
// Data is built and come from server side and is well escaped when necessary
|
208 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
209 |
+
break;
|
210 |
+
}
|
211 |
+
}
|
212 |
+
);
|
213 |
+
|
214 |
+
// Modifies the text direction
|
215 |
+
$( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
|
216 |
+
}
|
217 |
+
);
|
218 |
+
}
|
219 |
+
);
|
220 |
+
}
|
221 |
+
);
|
222 |
+
|
js/build/term.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(a){a(document).on("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((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).on("blur",(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))}))}))}t(),a("#term_lang_choice").on("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/build/user.js
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Adds one biography input field per language in the user profile.
|
3 |
+
*
|
4 |
+
* @package Polylang
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(
|
8 |
+
function( $ ) {
|
9 |
+
// biography
|
10 |
+
// FIXME there is probably a more efficient way to do this
|
11 |
+
var td = $( '#description' ).parent();
|
12 |
+
var d = $( '#description' ).clone();
|
13 |
+
var span = td.children( '.description' ).clone();
|
14 |
+
td.children().remove();
|
15 |
+
|
16 |
+
$( '.biography' ).each(
|
17 |
+
function(){
|
18 |
+
lang = $( this ).attr( 'name' ).split( '___' );
|
19 |
+
desc = d.clone();
|
20 |
+
desc.attr( 'name', 'description_' + lang[0] );
|
21 |
+
desc.attr( 'id', 'description_' + lang[0] );
|
22 |
+
// Whitelist because description and lang value is already escaped by the side of PHP
|
23 |
+
desc.html( $( this ).val() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
24 |
+
td.append( $( '<div></div>' ).text( lang[1] ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
25 |
+
td.append( desc ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
26 |
+
}
|
27 |
+
);
|
28 |
+
|
29 |
+
td.append( '<br />' );
|
30 |
+
// Whitelist because description come from html code generated by WordPress
|
31 |
+
td.append( span ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
|
32 |
+
}
|
33 |
+
);
|
34 |
+
|
js/build/user.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(e){var n=e("#description").parent(),i=e("#description").clone(),t=n.children(".description").clone();n.children().remove(),e(".biography").each((function(){lang=e(this).attr("name").split("___"),desc=i.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(t)}));
|
js/build/widgets.js
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Adds a flag to the widgets filtered by a language.
|
3 |
+
*
|
4 |
+
* @package Polylang
|
5 |
+
*/
|
6 |
+
|
7 |
+
jQuery(
|
8 |
+
function( $ ) {
|
9 |
+
var widgets_container, widgets_selector, flags;
|
10 |
+
|
11 |
+
if ( 'undefined' !== typeof pll_widgets && pll_widgets.hasOwnProperty( 'flags' ) ) {
|
12 |
+
flags = pll_widgets.flags;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Prepend widget titles with a flag once a language is selected.
|
17 |
+
*
|
18 |
+
* @param {object} widget The widget element.
|
19 |
+
* @return {void} Nothing.
|
20 |
+
*/
|
21 |
+
function add_flag( widget ) {
|
22 |
+
if ( ! flags ) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
+
widget = $( widget );
|
26 |
+
var title = $( '.widget-top .widget-title h3', widget ),
|
27 |
+
locale = $( '.pll-lang-choice option:selected', widget ).val(),
|
28 |
+
// Icon is HTML built and come from server side and is well escaped when necessary
|
29 |
+
icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
|
30 |
+
|
31 |
+
if ( icon ) {
|
32 |
+
icon += ' ';
|
33 |
+
var current = $( '.pll-lang', title );
|
34 |
+
if ( current.length ) {
|
35 |
+
current.html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
36 |
+
} else {
|
37 |
+
flag = $( '<span />' ).addClass( 'pll-lang' ).html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
38 |
+
// See the comment above about the icon which is safe. So it is also safe to prepend flag which uses icon.
|
39 |
+
title.prepend( flag ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
|
40 |
+
}
|
41 |
+
} else {
|
42 |
+
$( '.pll-lang', title ).remove();
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
if ( 'undefined' !== typeof wp.customize ) {
|
47 |
+
|
48 |
+
widgets_container = $( '#customize-controls' );
|
49 |
+
widgets_selector = '.customize-control .widget';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* WP Customizer add control listener.
|
53 |
+
*
|
54 |
+
* @link https://wordpress.stackexchange.com/questions/256536/callback-after-wordpress-customizer-complete-loading
|
55 |
+
*
|
56 |
+
* @param {object} control The control type.
|
57 |
+
* @return {void} Nothing.
|
58 |
+
*/
|
59 |
+
function customize_add_flag( control ) {
|
60 |
+
if ( ! control.extended( wp.customize.Widgets.WidgetControl ) ) {
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
|
64 |
+
/*
|
65 |
+
* Make sure the widget's contents are embedded; normally this is done
|
66 |
+
* when the control is expanded, for DOM performance reasons.
|
67 |
+
*/
|
68 |
+
control.embedWidgetContent();
|
69 |
+
|
70 |
+
// Now we know for sure the widget is fully embedded.
|
71 |
+
add_flag( control.container.find( '.widget' ) );
|
72 |
+
}
|
73 |
+
wp.customize.control.each( customize_add_flag );
|
74 |
+
wp.customize.control.bind( 'add', customize_add_flag );
|
75 |
+
|
76 |
+
} else {
|
77 |
+
|
78 |
+
widgets_container = $( '#widgets-right' );
|
79 |
+
widgets_selector = '.widget';
|
80 |
+
|
81 |
+
}
|
82 |
+
|
83 |
+
// Add flags on load.
|
84 |
+
$( widgets_selector, widgets_container ).each(
|
85 |
+
function() {
|
86 |
+
add_flag( this );
|
87 |
+
}
|
88 |
+
);
|
89 |
+
|
90 |
+
// Update flags.
|
91 |
+
widgets_container.on(
|
92 |
+
'change',
|
93 |
+
'.pll-lang-choice',
|
94 |
+
function() {
|
95 |
+
add_flag( $( this ).parents( '.widget' ) );
|
96 |
+
}
|
97 |
+
);
|
98 |
+
|
99 |
+
function pll_toggle( a, test ) {
|
100 |
+
test ? a.show() : a.hide();
|
101 |
+
}
|
102 |
+
|
103 |
+
// Remove all options if dropdown is checked.
|
104 |
+
$( '.widgets-sortables,.control-section-sidebar' ).on(
|
105 |
+
'change',
|
106 |
+
'.pll-dropdown',
|
107 |
+
function() {
|
108 |
+
var this_id = $( this ).parent().parent().parent().children( '.widget-id' ).attr( 'value' );
|
109 |
+
pll_toggle( $( '.no-dropdown-' + this_id ), true != $( this ).prop( 'checked' ) );
|
110 |
+
}
|
111 |
+
);
|
112 |
+
|
113 |
+
// Disallow unchecking both show names and show flags.
|
114 |
+
var options = ['-show_flags', '-show_names'];
|
115 |
+
$.each(
|
116 |
+
options,
|
117 |
+
function( i, v ) {
|
118 |
+
$( '.widgets-sortables,.control-section-sidebar' ).on(
|
119 |
+
'change',
|
120 |
+
'.pll' + v,
|
121 |
+
function() {
|
122 |
+
var this_id = $( this ).parent().parent().parent().children( '.widget-id' ).attr( 'value' );
|
123 |
+
if ( true != $( this ).prop( 'checked' ) ) {
|
124 |
+
$( '#widget-' + this_id + options[ 1 - i ] ).prop( 'checked', true );
|
125 |
+
}
|
126 |
+
}
|
127 |
+
);
|
128 |
+
}
|
129 |
+
);
|
130 |
+
|
131 |
+
}
|
132 |
+
);
|
133 |
+
|
js/build/widgets.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
jQuery((function(e){var t,n,i;function o(t){if(i){t=e(t);var n=e(".widget-top .widget-title h3",t),o=e(".pll-lang-choice option:selected",t).val(),l=o&&i.hasOwnProperty(o)?i[o]:null;if(l){l+=" ";var a=e(".pll-lang",n);a.length?a.html(l):(flag=e("<span />").addClass("pll-lang").html(l),n.prepend(flag))}else e(".pll-lang",n).remove()}}if("undefined"!=typeof pll_widgets&&pll_widgets.hasOwnProperty("flags")&&(i=pll_widgets.flags),void 0!==wp.customize){function l(e){e.extended(wp.customize.Widgets.WidgetControl)&&(e.embedWidgetContent(),o(e.container.find(".widget")))}t=e("#customize-controls"),n=".customize-control .widget",wp.customize.control.each(l),wp.customize.control.bind("add",l)}else t=e("#widgets-right"),n=".widget";e(n,t).each((function(){o(this)})),t.on("change",".pll-lang-choice",(function(){o(e(this).parents(".widget"))})),e(".widgets-sortables,.control-section-sidebar").on("change",".pll-dropdown",(function(){var t,n=e(this).parent().parent().parent().children(".widget-id").attr("value");t=e(".no-dropdown-"+n),1!=e(this).prop("checked")?t.show():t.hide()}));var a=["-show_flags","-show_names"];e.each(a,(function(t,n){e(".widgets-sortables,.control-section-sidebar").on("change",".pll"+n,(function(){var n=e(this).parent().parent().parent().children(".widget-id").attr("value");1!=e(this).prop("checked")&&e("#widget-"+n+a[1-t]).prop("checked",!0)}))}))}));
|
js/classic-editor.js
CHANGED
@@ -2,6 +2,11 @@
|
|
2 |
* @package Polylang
|
3 |
*/
|
4 |
|
|
|
|
|
|
|
|
|
|
|
5 |
// tag suggest in metabox
|
6 |
jQuery(
|
7 |
function( $ ) {
|
@@ -41,7 +46,8 @@ jQuery(
|
|
41 |
// @see code from WordPress core https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/js/tags-box.js#L291
|
42 |
// @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
|
43 |
r = $( '<div />' ).addClass( 'the-tagcloud' ).attr( 'id', 'tagcloud-' + tax ).html( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
44 |
-
$( 'a', r ).
|
|
|
45 |
function(){
|
46 |
tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
|
47 |
return false;
|
@@ -67,7 +73,7 @@ jQuery(
|
|
67 |
);
|
68 |
|
69 |
jQuery(
|
70 |
-
function
|
71 |
// collect taxonomies - code partly copied from WordPress
|
72 |
var taxonomies = new Array();
|
73 |
$( '.categorydiv' ).each(
|
@@ -91,82 +97,117 @@ jQuery(
|
|
91 |
}
|
92 |
);
|
93 |
|
|
|
|
|
|
|
94 |
// ajax for changing the post's language in the languages metabox
|
95 |
-
$( '.post_lang_choice' ).
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
}
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
var
|
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 |
-
);
|
155 |
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
|
|
163 |
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
|
|
|
|
|
|
|
|
|
|
169 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
}
|
171 |
);
|
172 |
|
@@ -211,3 +252,87 @@ jQuery(
|
|
211 |
init_translations();
|
212 |
}
|
213 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
* @package Polylang
|
3 |
*/
|
4 |
|
5 |
+
import {
|
6 |
+
initializeLanguageOldValue,
|
7 |
+
initializeConfimationModal
|
8 |
+
} from './lib/confirmation-modal';
|
9 |
+
|
10 |
// tag suggest in metabox
|
11 |
jQuery(
|
12 |
function( $ ) {
|
46 |
// @see code from WordPress core https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/js/tags-box.js#L291
|
47 |
// @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
|
48 |
r = $( '<div />' ).addClass( 'the-tagcloud' ).attr( 'id', 'tagcloud-' + tax ).html( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
49 |
+
$( 'a', r ).on(
|
50 |
+
'click',
|
51 |
function(){
|
52 |
tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
|
53 |
return false;
|
73 |
);
|
74 |
|
75 |
jQuery(
|
76 |
+
function( $ ) {
|
77 |
// collect taxonomies - code partly copied from WordPress
|
78 |
var taxonomies = new Array();
|
79 |
$( '.categorydiv' ).each(
|
97 |
}
|
98 |
);
|
99 |
|
100 |
+
// Initialize current language to be able to compare if it changes.
|
101 |
+
initializeLanguageOldValue();
|
102 |
+
|
103 |
// ajax for changing the post's language in the languages metabox
|
104 |
+
$( '.post_lang_choice' ).on(
|
105 |
+
'change',
|
106 |
+
function( event ) {
|
107 |
+
// Initialize the confirmation dialog box.
|
108 |
+
const confirmationModal = initializeConfimationModal();
|
109 |
+
const { dialogContainer: dialog } = confirmationModal;
|
110 |
+
let { dialogResult } = confirmationModal;
|
111 |
+
// The selected option in the dropdown list.
|
112 |
+
const selectedOption = event.target;
|
113 |
+
|
114 |
+
if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! isEmptyPost() ) {
|
115 |
+
dialog.dialog( 'open' );
|
116 |
+
} else {
|
117 |
+
dialogResult = Promise.resolve();
|
118 |
}
|
119 |
|
120 |
+
// phpcs:disable PEAR.Functions.FunctionCallSignature.EmptyLine
|
121 |
+
dialogResult.then(
|
122 |
+
() => {
|
123 |
+
var lang = selectedOption.options[selectedOption.options.selectedIndex].lang; // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
124 |
+
var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
125 |
+
|
126 |
+
var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
127 |
+
action: 'post_lang_choice',
|
128 |
+
lang: selectedOption.value,
|
129 |
+
post_type: $( '#post_type' ).val(),
|
130 |
+
taxonomies: taxonomies,
|
131 |
+
post_id: $( '#post_ID' ).val(),
|
132 |
+
_pll_nonce: $( '#_pll_nonce' ).val()
|
133 |
+
}
|
134 |
+
|
135 |
+
$.post(
|
136 |
+
ajaxurl,
|
137 |
+
data,
|
138 |
+
function( response ) {
|
139 |
+
var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
|
140 |
+
$.each(
|
141 |
+
res.responses,
|
142 |
+
function() {
|
143 |
+
switch ( this.what ) {
|
144 |
+
case 'translations': // translations fields
|
145 |
+
// Data is built and come from server side and is well escaped when necessary
|
146 |
+
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
147 |
+
init_translations();
|
148 |
+
break;
|
149 |
+
case 'taxonomy': // categories metabox for posts
|
150 |
+
var tax = this.data;
|
151 |
+
// @see wp_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L175
|
152 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/class-walker-category-checklist.php#L89-L111
|
153 |
+
$( '#' + tax + 'checklist' ).html( this.supplemental.all ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
154 |
+
// @see wp_popular_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L236
|
155 |
+
$( '#' + tax + 'checklist-pop' ).html( this.supplemental.populars ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
156 |
+
// @see wp_dropdown_categories https://github.com/WordPress/WordPress/blob/5.5.1/wp-includes/category-template.php#L336
|
157 |
+
// which is called by PLL_Admin_Classic_Editor::post_lang_choice to generate supplemental.dropdown
|
158 |
+
$( '#new' + tax + '_parent' ).replaceWith( this.supplemental.dropdown ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
|
159 |
+
$( '#' + tax + '-lang' ).val( $( '.post_lang_choice' ).val() ); // hidden field
|
160 |
+
break;
|
161 |
+
case 'pages': // parent dropdown list for pages
|
162 |
+
// @see wp_dropdown_pages https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/post-template.php#L1186-L1208
|
163 |
+
// @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/class-walker-page-dropdown.php#L88
|
164 |
+
$( '#parent_id' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
165 |
+
break;
|
166 |
+
case 'flag': // flag in front of the select dropdown
|
167 |
+
// Data is built and come from server side and is well escaped when necessary
|
168 |
+
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
169 |
+
break;
|
170 |
+
case 'permalink': // Sample permalink
|
171 |
+
var div = $( '#edit-slug-box' );
|
172 |
+
if ( '-1' != this.data && div.children().length ) {
|
173 |
+
// @see get_sample_permalink_html https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/post.php#L1425-L1454
|
174 |
+
div.html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
175 |
+
}
|
176 |
+
break;
|
177 |
}
|
178 |
+
}
|
179 |
+
);
|
|
|
|
|
180 |
|
181 |
+
// Update the old language with the new one to be able to compare it in the next changing.
|
182 |
+
initializeLanguageOldValue();
|
183 |
+
// modifies the language in the tag cloud
|
184 |
+
$( '.tagcloud-link' ).each(
|
185 |
+
function() {
|
186 |
+
var id = $( this ).attr( 'id' );
|
187 |
+
tagBox.get( id );
|
188 |
+
}
|
189 |
+
);
|
190 |
|
191 |
+
// Modifies the text direction
|
192 |
+
$( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
|
193 |
+
$( '#content_ifr' ).contents().find( 'html' ).attr( 'lang', lang ).attr( 'dir', dir );
|
194 |
+
$( '#content_ifr' ).contents().find( 'body' ).attr( 'dir', dir );
|
195 |
+
|
196 |
+
pll.media.resetAllAttachmentsCollections();
|
197 |
+
}
|
198 |
+
)
|
199 |
+
},
|
200 |
+
() => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
|
201 |
);
|
202 |
+
// phpcs:enable PEAR.Functions.FunctionCallSignature.EmptyLine
|
203 |
+
|
204 |
+
function isEmptyPost() {
|
205 |
+
const title = $( 'input#title' ).val();
|
206 |
+
const content = $( 'textarea#content' ).val();
|
207 |
+
const excerpt = $( 'textarea#excerpt' ).val();
|
208 |
+
|
209 |
+
return ! title && ! content && ! excerpt;
|
210 |
+
}
|
211 |
}
|
212 |
);
|
213 |
|
252 |
init_translations();
|
253 |
}
|
254 |
);
|
255 |
+
|
256 |
+
/**
|
257 |
+
* @since 3.0
|
258 |
+
*
|
259 |
+
* @namespace pll
|
260 |
+
*/
|
261 |
+
var pll = window.pll || {};
|
262 |
+
|
263 |
+
/**
|
264 |
+
* @since 3.0
|
265 |
+
*
|
266 |
+
* @namespace pll.media
|
267 |
+
*/
|
268 |
+
_.extend( pll, { media: {} } );
|
269 |
+
|
270 |
+
/**
|
271 |
+
* @since 3.0
|
272 |
+
*
|
273 |
+
* @alias pll.media
|
274 |
+
* @memberOf pll
|
275 |
+
* @namespace
|
276 |
+
*/
|
277 |
+
var media = _.extend(
|
278 |
+
pll.media, /** @lends pll.media.prototype */
|
279 |
+
{
|
280 |
+
/**
|
281 |
+
* TODO: Find a way to delete references to Attachments collections that are not used anywhere else.
|
282 |
+
*
|
283 |
+
* @type {wp.media.model.Attachments}
|
284 |
+
*/
|
285 |
+
attachmentsCollections : [],
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Imitates { @see wp.media.query } but log all Attachments collections created.
|
289 |
+
*
|
290 |
+
* @param {Object} [props]
|
291 |
+
* @return {wp.media.model.Attachments}
|
292 |
+
*/
|
293 |
+
query: function( props ) {
|
294 |
+
var attachments = pll.media.query.delegate();
|
295 |
+
|
296 |
+
pll.media.attachmentsCollections.push( attachments );
|
297 |
+
|
298 |
+
return attachments;
|
299 |
+
},
|
300 |
+
|
301 |
+
resetAllAttachmentsCollections: function() {
|
302 |
+
this.attachmentsCollections.forEach(
|
303 |
+
function( attachmentsCollection ) {
|
304 |
+
/**
|
305 |
+
* First reset the { @see wp.media.model.Attachments } collection.
|
306 |
+
* Then, if it is mirroring a { @see wp.media.model.Query } collection,
|
307 |
+
* refresh this one too, so it will fetch new data from the server,
|
308 |
+
* and then the wp.media.model.Attachments collection will syncrhonize with the new data.
|
309 |
+
*/
|
310 |
+
attachmentsCollection.reset();
|
311 |
+
if (attachmentsCollection.mirroring) {
|
312 |
+
attachmentsCollection.mirroring._hasMore = true;
|
313 |
+
attachmentsCollection.mirroring.reset();
|
314 |
+
}
|
315 |
+
}
|
316 |
+
);
|
317 |
+
}
|
318 |
+
}
|
319 |
+
);
|
320 |
+
|
321 |
+
/**
|
322 |
+
* @since 3.0
|
323 |
+
*
|
324 |
+
* @memberOf pll.media
|
325 |
+
*/
|
326 |
+
media.query = _.extend(
|
327 |
+
media.query, /** @lends pll.media.query prototype */
|
328 |
+
{
|
329 |
+
/**
|
330 |
+
* @type Function References WordPress { @see wp.media.query } constructor
|
331 |
+
*/
|
332 |
+
delegate: wp.media.query
|
333 |
+
}
|
334 |
+
)
|
335 |
+
|
336 |
+
// Substitute WordPress media query shortcut with our decorated function.
|
337 |
+
wp.media.query = media.query
|
338 |
+
|
js/classic-editor.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery(function(t){t.ajaxPrefilter(function(a,l,n){var e=t(".post_lang_choice").val();"string"==typeof a.data&&-1!==a.url.indexOf("action=ajax-tag-search")&&e&&(a.data="lang="+e+"&"+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});var i=t("#tagcloud-"+l).css("display");i?(t("#tagcloud-"+l).replaceWith(n),t("#tagcloud-"+l).css("display",i)):t("#"+a).after(n)})}}),jQuery(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).on("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()});
|
|
js/lib/confirmation-modal.js
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @package Polylang
|
3 |
+
*/
|
4 |
+
|
5 |
+
// We can't use underscore or lodash in this common code because it depends of the context classic or block editor.
|
6 |
+
// Classic editor underscore is loaded, Block editor lodash is loaded.
|
7 |
+
const { __ } = wp.i18n;
|
8 |
+
|
9 |
+
const languagesList = jQuery( '.post_lang_choice' );
|
10 |
+
|
11 |
+
// Dialog box for alerting the user about a risky changing.
|
12 |
+
export const initializeConfimationModal = () => {
|
13 |
+
// Create dialog container.
|
14 |
+
const dialogContainer = jQuery(
|
15 |
+
'<div/>',
|
16 |
+
{
|
17 |
+
id: 'pll-dialog',
|
18 |
+
style: 'display:none;'
|
19 |
+
}
|
20 |
+
).text( __( 'Are you sure you want to change the language of the current content?', 'polylang' ) );
|
21 |
+
|
22 |
+
// Put it after languages list dropdown.
|
23 |
+
// PHPCS ignore dialogContainer is a new safe HTML code generated above.
|
24 |
+
languagesList.after( dialogContainer ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
|
25 |
+
|
26 |
+
const dialogResult = new Promise(
|
27 |
+
( confirm, cancel ) => {
|
28 |
+
const confirmDialog = ( what ) => { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
29 |
+
switch ( what ) { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
30 |
+
case 'yes':
|
31 |
+
// Confirm the new language.
|
32 |
+
languagesList.data( 'old-value', languagesList.children( ':selected' )[0].value );
|
33 |
+
confirm();
|
34 |
+
break;
|
35 |
+
case 'no':
|
36 |
+
// Revert to the old language.
|
37 |
+
languagesList.val( languagesList.data( 'old-value' ) );
|
38 |
+
cancel( 'Cancel' );
|
39 |
+
break;
|
40 |
+
}
|
41 |
+
dialogContainer.dialog( 'close' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
42 |
+
} // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
43 |
+
|
44 |
+
// Initialize dialog box in the case a language is selected but not added in the list.
|
45 |
+
dialogContainer.dialog(
|
46 |
+
{
|
47 |
+
autoOpen: false,
|
48 |
+
modal: true,
|
49 |
+
draggable: false,
|
50 |
+
resizable: false,
|
51 |
+
title: __( 'Change language', 'polylang' ),
|
52 |
+
minWidth: 600,
|
53 |
+
maxWidth: '100%',
|
54 |
+
classes: {
|
55 |
+
'ui-dialog': 'pll-confirmation-modal',
|
56 |
+
},
|
57 |
+
open: function( event, ui ) {
|
58 |
+
// Change dialog box position for rtl language
|
59 |
+
if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
|
60 |
+
jQuery( this ).parent().css(
|
61 |
+
{
|
62 |
+
right: jQuery( this ).parent().css( 'left' ),
|
63 |
+
left: 'auto'
|
64 |
+
}
|
65 |
+
);
|
66 |
+
}
|
67 |
+
},
|
68 |
+
close: function( event, ui ) {
|
69 |
+
// When we're closing the dialog box we need to cancel the language change as we click on Cancel button.
|
70 |
+
confirmDialog( 'no' );
|
71 |
+
},
|
72 |
+
buttons: [
|
73 |
+
{
|
74 |
+
text: __( 'OK', 'polylang' ),
|
75 |
+
click: function( event ) {
|
76 |
+
confirmDialog( 'yes' );
|
77 |
+
}
|
78 |
+
},
|
79 |
+
{
|
80 |
+
text: __( 'Cancel', 'polylang' ),
|
81 |
+
click: function( event ) {
|
82 |
+
confirmDialog( 'no' );
|
83 |
+
}
|
84 |
+
} ]
|
85 |
+
}
|
86 |
+
);
|
87 |
+
}
|
88 |
+
);
|
89 |
+
return { dialogContainer, dialogResult };
|
90 |
+
}
|
91 |
+
|
92 |
+
export const initializeLanguageOldValue = () => {
|
93 |
+
// Keep the old language value to be able to compare to the new one and revert to it if necessary.
|
94 |
+
languagesList.attr( 'data-old-value', languagesList.children( ':selected' )[0].value );
|
95 |
+
};
|
js/nav-menu.js
CHANGED
@@ -4,9 +4,9 @@
|
|
4 |
* @package Polylang
|
5 |
*/
|
6 |
|
7 |
-
jQuery(
|
8 |
function( $ ) {
|
9 |
-
$( '#update-nav-menu' ).
|
10 |
'click',
|
11 |
function( e ) {
|
12 |
if ( e.target && e.target.className && -1 != e.target.className.indexOf( 'item-edit' ) ) {
|
@@ -85,7 +85,8 @@ jQuery( document ).ready(
|
|
85 |
$.each(
|
86 |
options,
|
87 |
function( i, v ) {
|
88 |
-
$( '#edit-menu-item-show_' + v + id ).
|
|
|
89 |
function() {
|
90 |
if ( true != $( this ).prop( 'checked' ) ) {
|
91 |
$( '#edit-menu-item-show_' + options[ 1 - i ] + id ).prop( 'checked', true );
|
4 |
* @package Polylang
|
5 |
*/
|
6 |
|
7 |
+
jQuery(
|
8 |
function( $ ) {
|
9 |
+
$( '#update-nav-menu' ).on(
|
10 |
'click',
|
11 |
function( e ) {
|
12 |
if ( e.target && e.target.className && -1 != e.target.className.indexOf( 'item-edit' ) ) {
|
85 |
$.each(
|
86 |
options,
|
87 |
function( i, v ) {
|
88 |
+
$( '#edit-menu-item-show_' + v + id ).on(
|
89 |
+
'change',
|
90 |
function() {
|
91 |
if ( true != $( this ).prop( 'checked' ) ) {
|
92 |
$( '#edit-menu-item-show_' + options[ 1 - i ] + id ).prop( 'checked', true );
|
js/nav-menu.min.js
DELETED
@@ -1 +0,0 @@
|
|
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(){1!=e(this).prop("checked")&&e("#edit-menu-item-show_"+i[1-a]+t).prop("checked",!0)})})}))})});
|
|
js/post.js
CHANGED
@@ -41,7 +41,8 @@ jQuery(
|
|
41 |
filter_pages( lang ); // initial filter for parent dropdown
|
42 |
|
43 |
// modify category checklist an parent dropdown on language change
|
44 |
-
select.
|
|
|
45 |
function() {
|
46 |
filter_terms( $( this ).val() );
|
47 |
filter_pages( $( this ).val() );
|
41 |
filter_pages( lang ); // initial filter for parent dropdown
|
42 |
|
43 |
// modify category checklist an parent dropdown on language change
|
44 |
+
select.on(
|
45 |
+
'change',
|
46 |
function() {
|
47 |
filter_terms( $( this ).val() );
|
48 |
filter_pages( $( this ).val() );
|
js/post.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery(function(a){a.ajaxPrefilter(function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)})}),jQuery(function(a){a(document).on("DOMNodeInserted",function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),s(o),i.change(function(){l(a(this).val()),s(a(this).val())})}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,function(t,e){a.each(e,function(e,i){a.each(i,function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()})})})}function s(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,function(t,e){a.each(e,function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()})})}})}),jQuery(function(a){a(document).ajaxSuccess(function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each(function(){t.push(a(this).parent().parent().attr("id").substring(5))});var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(t.responses,function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)})}})}(i.post_ID)}})}),jQuery(function(a){a.ajaxPrefilter(function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)})});
|
|
js/term.js
CHANGED
@@ -164,7 +164,8 @@ jQuery(
|
|
164 |
init_translations();
|
165 |
|
166 |
// ajax for changing the term's language
|
167 |
-
$( '#term_lang_choice' ).
|
|
|
168 |
function() {
|
169 |
var value = $( this ).val();
|
170 |
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
164 |
init_translations();
|
165 |
|
166 |
// ajax for changing the term's language
|
167 |
+
$( '#term_lang_choice' ).on(
|
168 |
+
'change',
|
169 |
function() {
|
170 |
var value = $( this ).val();
|
171 |
var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
|
js/term.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery(function(a){a(document).on("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(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).on("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
@@ -4,7 +4,7 @@
|
|
4 |
* @package Polylang
|
5 |
*/
|
6 |
|
7 |
-
jQuery(
|
8 |
function( $ ) {
|
9 |
// biography
|
10 |
// FIXME there is probably a more efficient way to do this
|
4 |
* @package Polylang
|
5 |
*/
|
6 |
|
7 |
+
jQuery(
|
8 |
function( $ ) {
|
9 |
// biography
|
10 |
// FIXME there is probably a more efficient way to do this
|
js/user.min.js
DELETED
@@ -1 +0,0 @@
|
|
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.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery(function(e){var t,n,i;function o(t){if(i){t=e(t);var n=e(".widget-top .widget-title h3",t),o=e(".pll-lang-choice option:selected",t).val(),l=o&&i.hasOwnProperty(o)?i[o]:null;if(l){l+=" ";var a=e(".pll-lang",n);a.length?a.html(l):(flag=e("<span />").addClass("pll-lang").html(l),n.prepend(flag))}else e(".pll-lang",n).remove()}}if("undefined"!=typeof pll_widgets&&pll_widgets.hasOwnProperty("flags")&&(i=pll_widgets.flags),void 0!==wp.customize){function l(e){e.extended(wp.customize.Widgets.WidgetControl)&&(e.embedWidgetContent(),o(e.container.find(".widget")))}t=e("#customize-controls"),n=".customize-control .widget",wp.customize.control.each(l),wp.customize.control.bind("add",l)}else t=e("#widgets-right"),n=".widget";e(n,t).each(function(){o(this)}),t.on("change",".pll-lang-choice",function(){o(e(this).parents(".widget"))}),e(".widgets-sortables,.control-section-sidebar").on("change",".pll-dropdown",function(){var t,n=e(this).parent().parent().parent().children(".widget-id").attr("value");t=e(".no-dropdown-"+n),1!=e(this).prop("checked")?t.show():t.hide()});var a=["-show_flags","-show_names"];e.each(a,function(t,n){e(".widgets-sortables,.control-section-sidebar").on("change",".pll"+n,function(){var n=e(this).parent().parent().parent().children(".widget-id").attr("value");1!=e(this).prop("checked")&&e("#widget-"+n+a[1-t]).prop("checked",!0)})})});
|
|
modules/lingotek/lingotek.php
CHANGED
@@ -15,6 +15,8 @@ class PLL_Lingotek {
|
|
15 |
* Init
|
16 |
*
|
17 |
* @since 1.7.7
|
|
|
|
|
18 |
*/
|
19 |
public function init() {
|
20 |
// The Lingotek tab
|
@@ -71,6 +73,8 @@ class PLL_Lingotek {
|
|
71 |
* Displays the content in the Lingotek tab
|
72 |
*
|
73 |
* @since 1.7.7
|
|
|
|
|
74 |
*/
|
75 |
public function display_tab() {
|
76 |
PLL_Admin_Notices::dismiss( 'lingotek' );
|
@@ -154,6 +158,8 @@ class PLL_Lingotek {
|
|
154 |
* Styles the content of the Lingotek tab
|
155 |
*
|
156 |
* @since 1.7.7
|
|
|
|
|
157 |
*/
|
158 |
public function print_css() {
|
159 |
?>
|
@@ -233,6 +239,7 @@ class PLL_Lingotek {
|
|
233 |
* @param array $list
|
234 |
* @param array $links
|
235 |
* @param string $img
|
|
|
236 |
*/
|
237 |
protected function box( $title, $desc, $list, $links, $img ) {
|
238 |
?>
|
15 |
* Init
|
16 |
*
|
17 |
* @since 1.7.7
|
18 |
+
*
|
19 |
+
* @return void
|
20 |
*/
|
21 |
public function init() {
|
22 |
// The Lingotek tab
|
73 |
* Displays the content in the Lingotek tab
|
74 |
*
|
75 |
* @since 1.7.7
|
76 |
+
*
|
77 |
+
* @return void
|
78 |
*/
|
79 |
public function display_tab() {
|
80 |
PLL_Admin_Notices::dismiss( 'lingotek' );
|
158 |
* Styles the content of the Lingotek tab
|
159 |
*
|
160 |
* @since 1.7.7
|
161 |
+
*
|
162 |
+
* @return void
|
163 |
*/
|
164 |
public function print_css() {
|
165 |
?>
|
239 |
* @param array $list
|
240 |
* @param array $links
|
241 |
* @param string $img
|
242 |
+
* @return void
|
243 |
*/
|
244 |
protected function box( $title, $desc, $list, $links, $img ) {
|
245 |
?>
|
modules/share-slug/settings-share-slug.php
CHANGED
@@ -65,6 +65,8 @@ class PLL_Settings_Share_Slug extends PLL_Settings_Module {
|
|
65 |
* as sharing slugs is not possible when the language is set from the content
|
66 |
*
|
67 |
* @since 1.9
|
|
|
|
|
68 |
*/
|
69 |
public function print_js() {
|
70 |
wp_enqueue_script( 'jquery' );
|
65 |
* as sharing slugs is not possible when the language is set from the content
|
66 |
*
|
67 |
* @since 1.9
|
68 |
+
*
|
69 |
+
* @return void
|
70 |
*/
|
71 |
public function print_js() {
|
72 |
wp_enqueue_script( 'jquery' );
|
modules/site-health/admin-site-health.php
CHANGED
@@ -53,7 +53,7 @@ class PLL_Admin_Site_Health {
|
|
53 |
*
|
54 |
* @since 2.8
|
55 |
*
|
56 |
-
* @return
|
57 |
*/
|
58 |
protected function exclude_options_keys() {
|
59 |
return array(
|
@@ -67,7 +67,7 @@ class PLL_Admin_Site_Health {
|
|
67 |
*
|
68 |
* @since 2.8
|
69 |
*
|
70 |
-
* @return
|
71 |
*/
|
72 |
protected function exclude_language_keys() {
|
73 |
return array(
|
@@ -218,7 +218,7 @@ class PLL_Admin_Site_Health {
|
|
218 |
*
|
219 |
* @since 2.8
|
220 |
*
|
221 |
-
* @param
|
222 |
* @return string
|
223 |
*/
|
224 |
protected function get_flag( $language ) {
|
53 |
*
|
54 |
* @since 2.8
|
55 |
*
|
56 |
+
* @return string[] List of option keys to ignore.
|
57 |
*/
|
58 |
protected function exclude_options_keys() {
|
59 |
return array(
|
67 |
*
|
68 |
* @since 2.8
|
69 |
*
|
70 |
+
* @return string[] List of language keys to ignore.
|
71 |
*/
|
72 |
protected function exclude_language_keys() {
|
73 |
return array(
|
218 |
*
|
219 |
* @since 2.8
|
220 |
*
|
221 |
+
* @param PLL_Language $language Language object.
|
222 |
* @return string
|
223 |
*/
|
224 |
protected function get_flag( $language ) {
|
modules/sitemaps/abstract-sitemaps.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Common class for handling the core sitemaps.
|
8 |
+
*
|
9 |
+
* The child classes must called the init() method.
|
10 |
+
*
|
11 |
+
* @since 3.0
|
12 |
+
*/
|
13 |
+
abstract class PLL_Abstract_Sitemaps {
|
14 |
+
/**
|
15 |
+
* Setups actions and filters.
|
16 |
+
*
|
17 |
+
* @since 2.8
|
18 |
+
*
|
19 |
+
* @return void
|
20 |
+
*/
|
21 |
+
public function init() {
|
22 |
+
add_filter( 'pll_home_url_white_list', array( $this, 'home_url_white_list' ) );
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Whitelists the home url filter for the sitemaps.
|
27 |
+
*
|
28 |
+
* @since 2.8
|
29 |
+
*
|
30 |
+
* @param array $whitelist White list.
|
31 |
+
* @return array;
|
32 |
+
*/
|
33 |
+
public function home_url_white_list( $whitelist ) {
|
34 |
+
$whitelist[] = array( 'file' => 'class-wp-sitemaps-posts' );
|
35 |
+
return $whitelist;
|
36 |
+
}
|
37 |
+
}
|
modules/sitemaps/load.php
CHANGED
@@ -8,6 +8,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
8 |
};
|
9 |
|
10 |
if ( $polylang->model->get_languages_list() ) {
|
11 |
-
$polylang->
|
|
|
|
|
|
|
|
|
12 |
$polylang->sitemaps->init();
|
13 |
}
|
8 |
};
|
9 |
|
10 |
if ( $polylang->model->get_languages_list() ) {
|
11 |
+
if ( $polylang->links_model instanceof PLL_Links_Abstract_Domain ) {
|
12 |
+
$polylang->sitemaps = new PLL_Sitemaps_Domain( $polylang );
|
13 |
+
} else {
|
14 |
+
$polylang->sitemaps = new PLL_Sitemaps( $polylang );
|
15 |
+
}
|
16 |
$polylang->sitemaps->init();
|
17 |
}
|
modules/sitemaps/multilingual-sitemaps-provider.php
CHANGED
@@ -187,9 +187,12 @@ class PLL_Multilingual_Sitemaps_Provider extends WP_Sitemaps_Provider {
|
|
187 |
$pattern = '#(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')$#';
|
188 |
if ( preg_match( $pattern, $name, $matches ) ) {
|
189 |
$lang = $this->model->get_language( $matches[1] );
|
190 |
-
|
191 |
-
|
192 |
-
|
|
|
|
|
|
|
193 |
}
|
194 |
|
195 |
// If no language is present in $name, we may attempt to get the current sitemap url (e.g. in redirect_canonical() ).
|
187 |
$pattern = '#(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')$#';
|
188 |
if ( preg_match( $pattern, $name, $matches ) ) {
|
189 |
$lang = $this->model->get_language( $matches[1] );
|
190 |
+
|
191 |
+
if ( ! empty( $lang ) ) {
|
192 |
+
$name = preg_replace( '#(-?' . $lang->slug . ')$#', '', $name );
|
193 |
+
$url = $this->provider->get_sitemap_url( $name, $page );
|
194 |
+
return $this->links_model->add_language_to_link( $url, $lang );
|
195 |
+
}
|
196 |
}
|
197 |
|
198 |
// If no language is present in $name, we may attempt to get the current sitemap url (e.g. in redirect_canonical() ).
|
modules/sitemaps/sitemaps-domain.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Handles the core sitemaps for subdomains and multiple domains.
|
8 |
+
*
|
9 |
+
* @since 3.0
|
10 |
+
*/
|
11 |
+
class PLL_Sitemaps_Domain extends PLL_Abstract_Sitemaps {
|
12 |
+
/**
|
13 |
+
* @var PLL_Links_Abstract_Domain
|
14 |
+
*/
|
15 |
+
protected $links_model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Constructor.
|
19 |
+
*
|
20 |
+
* @since 3.0
|
21 |
+
*
|
22 |
+
* @param object $polylang Main Polylang object.
|
23 |
+
*/
|
24 |
+
public function __construct( &$polylang ) {
|
25 |
+
$this->links_model = &$polylang->links_model;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Setups actions and filters.
|
30 |
+
*
|
31 |
+
* @since 3.0
|
32 |
+
*
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function init() {
|
36 |
+
parent::init();
|
37 |
+
|
38 |
+
add_filter( 'wp_sitemaps_index_entry', array( $this, 'index_entry' ) );
|
39 |
+
add_filter( 'wp_sitemaps_stylesheet_url', array( $this->links_model, 'site_url' ) );
|
40 |
+
add_filter( 'wp_sitemaps_stylesheet_index_url', array( $this->links_model, 'site_url' ) );
|
41 |
+
add_filter( 'home_url', array( $this, 'sitemap_url' ) );
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Filters the sitemap index entries for subdomains and multiple domains.
|
46 |
+
*
|
47 |
+
* @since 2.8
|
48 |
+
*
|
49 |
+
* @param array $sitemap_entry Sitemap entry for the post.
|
50 |
+
* @return array
|
51 |
+
*/
|
52 |
+
public function index_entry( $sitemap_entry ) {
|
53 |
+
$sitemap_entry['loc'] = $this->links_model->site_url( $sitemap_entry['loc'] );
|
54 |
+
return $sitemap_entry;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Makes sure that the sitemap urls are always evaluated on the current domain.
|
59 |
+
*
|
60 |
+
* @since 2.8.4
|
61 |
+
*
|
62 |
+
* @param string $url A sitemap url.
|
63 |
+
* @return string
|
64 |
+
*/
|
65 |
+
public function sitemap_url( $url ) {
|
66 |
+
if ( false !== strpos( $url, '/wp-sitemap' ) ) {
|
67 |
+
$url = $this->links_model->site_url( $url );
|
68 |
+
}
|
69 |
+
return $url;
|
70 |
+
}
|
71 |
+
}
|
modules/sitemaps/sitemaps.php
CHANGED
@@ -4,34 +4,17 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Handles the core sitemaps.
|
8 |
*
|
9 |
* @since 2.8
|
10 |
*/
|
11 |
-
class PLL_Sitemaps {
|
12 |
/**
|
13 |
-
* A reference to the current language.
|
14 |
-
*
|
15 |
-
* @since 2.8
|
16 |
-
*
|
17 |
-
* @var PLL_Language
|
18 |
-
*/
|
19 |
-
protected $curlang;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* A reference to the PLL_Links_Model instance.
|
23 |
-
*
|
24 |
-
* @since 2.8
|
25 |
-
*
|
26 |
* @var PLL_Links_Model
|
27 |
*/
|
28 |
protected $links_model;
|
29 |
|
30 |
/**
|
31 |
-
* A reference to the PLL_Model instance.
|
32 |
-
*
|
33 |
-
* @since 2.8
|
34 |
-
*
|
35 |
* @var PLL_Model
|
36 |
*/
|
37 |
protected $model;
|
@@ -51,7 +34,6 @@ class PLL_Sitemaps {
|
|
51 |
* @param object $polylang Main Polylang object.
|
52 |
*/
|
53 |
public function __construct( &$polylang ) {
|
54 |
-
$this->curlang = &$polylang->curlang;
|
55 |
$this->links_model = &$polylang->links_model;
|
56 |
$this->model = &$polylang->model;
|
57 |
$this->options = &$polylang->options;
|
@@ -61,20 +43,15 @@ class PLL_Sitemaps {
|
|
61 |
* Setups actions and filters.
|
62 |
*
|
63 |
* @since 2.8
|
|
|
|
|
64 |
*/
|
65 |
public function init() {
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
add_filter( 'wp_sitemaps_add_provider', array( $this, 'replace_provider' ) );
|
72 |
-
} elseif ( method_exists( $this->links_model, 'site_url' ) ) {
|
73 |
-
add_filter( 'wp_sitemaps_index_entry', array( $this, 'index_entry' ) );
|
74 |
-
add_filter( 'wp_sitemaps_stylesheet_url', array( $this->links_model, 'site_url' ) );
|
75 |
-
add_filter( 'wp_sitemaps_stylesheet_index_url', array( $this->links_model, 'site_url' ) );
|
76 |
-
add_filter( 'home_url', array( $this, 'sitemap_url' ) );
|
77 |
-
}
|
78 |
}
|
79 |
|
80 |
/**
|
@@ -84,7 +61,7 @@ class PLL_Sitemaps {
|
|
84 |
* @since 2.8
|
85 |
*
|
86 |
* @param string|bool $lang Current language code, false if not set yet.
|
87 |
-
* @param
|
88 |
* @return string|bool
|
89 |
*/
|
90 |
public function set_language_from_query( $lang, $query ) {
|
@@ -100,7 +77,7 @@ class PLL_Sitemaps {
|
|
100 |
* @since 2.8
|
101 |
*
|
102 |
* @param array $whitelist White list.
|
103 |
-
* @return array
|
104 |
*/
|
105 |
public function home_url_white_list( $whitelist ) {
|
106 |
$whitelist[] = array( 'file' => 'class-wp-sitemaps-posts' );
|
@@ -112,8 +89,8 @@ class PLL_Sitemaps {
|
|
112 |
*
|
113 |
* @since 2.8
|
114 |
*
|
115 |
-
* @param
|
116 |
-
* @return
|
117 |
*/
|
118 |
public function rewrite_rules( $rules ) {
|
119 |
global $wp_rewrite;
|
@@ -133,7 +110,7 @@ class PLL_Sitemaps {
|
|
133 |
$newrules = array();
|
134 |
|
135 |
foreach ( $rules as $key => $rule ) {
|
136 |
-
if (
|
137 |
$newrules[ str_replace( '^wp-sitemap', $slug . 'wp-sitemap', $key ) ] = str_replace(
|
138 |
array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
|
139 |
array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
|
@@ -160,32 +137,4 @@ class PLL_Sitemaps {
|
|
160 |
}
|
161 |
return $provider;
|
162 |
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* Filters the sitemap index entries for subdomains and multiple domains.
|
166 |
-
*
|
167 |
-
* @since 2.8
|
168 |
-
*
|
169 |
-
* @param array $sitemap_entry Sitemap entry for the post.
|
170 |
-
* return array
|
171 |
-
*/
|
172 |
-
public function index_entry( $sitemap_entry ) {
|
173 |
-
$sitemap_entry['loc'] = $this->links_model->site_url( $sitemap_entry['loc'] );
|
174 |
-
return $sitemap_entry;
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Makes sure that the sitemap urls are always evaluated on the current domain.
|
179 |
-
*
|
180 |
-
* @since 2.8.4
|
181 |
-
*
|
182 |
-
* @param string $url A sitemap url.
|
183 |
-
* @return string
|
184 |
-
*/
|
185 |
-
public function sitemap_url( $url ) {
|
186 |
-
if ( false !== strpos( $url, '/wp-sitemap' ) ) {
|
187 |
-
$url = $this->links_model->site_url( $url );
|
188 |
-
}
|
189 |
-
return $url;
|
190 |
-
}
|
191 |
}
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Handles the core sitemaps for sites using a single domain.
|
8 |
*
|
9 |
* @since 2.8
|
10 |
*/
|
11 |
+
class PLL_Sitemaps extends PLL_Abstract_Sitemaps {
|
12 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
* @var PLL_Links_Model
|
14 |
*/
|
15 |
protected $links_model;
|
16 |
|
17 |
/**
|
|
|
|
|
|
|
|
|
18 |
* @var PLL_Model
|
19 |
*/
|
20 |
protected $model;
|
34 |
* @param object $polylang Main Polylang object.
|
35 |
*/
|
36 |
public function __construct( &$polylang ) {
|
|
|
37 |
$this->links_model = &$polylang->links_model;
|
38 |
$this->model = &$polylang->model;
|
39 |
$this->options = &$polylang->options;
|
43 |
* Setups actions and filters.
|
44 |
*
|
45 |
* @since 2.8
|
46 |
+
*
|
47 |
+
* @return void
|
48 |
*/
|
49 |
public function init() {
|
50 |
+
parent::init();
|
51 |
+
|
52 |
+
add_filter( 'pll_set_language_from_query', array( $this, 'set_language_from_query' ), 10, 2 );
|
53 |
+
add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) );
|
54 |
+
add_filter( 'wp_sitemaps_add_provider', array( $this, 'replace_provider' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
}
|
56 |
|
57 |
/**
|
61 |
* @since 2.8
|
62 |
*
|
63 |
* @param string|bool $lang Current language code, false if not set yet.
|
64 |
+
* @param WP_Query $query Main WP query object.
|
65 |
* @return string|bool
|
66 |
*/
|
67 |
public function set_language_from_query( $lang, $query ) {
|
77 |
* @since 2.8
|
78 |
*
|
79 |
* @param array $whitelist White list.
|
80 |
+
* @return array
|
81 |
*/
|
82 |
public function home_url_white_list( $whitelist ) {
|
83 |
$whitelist[] = array( 'file' => 'class-wp-sitemaps-posts' );
|
89 |
*
|
90 |
* @since 2.8
|
91 |
*
|
92 |
+
* @param string[] $rules Rewrite rules.
|
93 |
+
* @return string[] Modified rewrite rules.
|
94 |
*/
|
95 |
public function rewrite_rules( $rules ) {
|
96 |
global $wp_rewrite;
|
110 |
$newrules = array();
|
111 |
|
112 |
foreach ( $rules as $key => $rule ) {
|
113 |
+
if ( false !== strpos( $rule, 'sitemap=$matches[1]' ) ) {
|
114 |
$newrules[ str_replace( '^wp-sitemap', $slug . 'wp-sitemap', $key ) ] = str_replace(
|
115 |
array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
|
116 |
array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
|
137 |
}
|
138 |
return $provider;
|
139 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
modules/sync/admin-sync.php
CHANGED
@@ -62,14 +62,16 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
62 |
$from_post_id = (int) $_GET['from_post'];
|
63 |
$from_post = get_post( $from_post_id );
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
$
|
72 |
-
|
|
|
|
|
73 |
}
|
74 |
}
|
75 |
|
@@ -80,6 +82,8 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
80 |
* Copy post metas, and taxonomies when using "Add new" ( translation )
|
81 |
*
|
82 |
* @since 2.5
|
|
|
|
|
83 |
*/
|
84 |
public function new_post_translation() {
|
85 |
global $post;
|
@@ -108,12 +112,12 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
-
* Get post fields to synchronize
|
112 |
*
|
113 |
* @since 2.4
|
114 |
*
|
115 |
-
* @param
|
116 |
-
* @return array
|
117 |
*/
|
118 |
protected function get_fields_to_sync( $post ) {
|
119 |
global $wpdb;
|
@@ -128,14 +132,17 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
128 |
unset( $postarr['post_date_gmt'] );
|
129 |
|
130 |
$original = get_post( (int) $_GET['from_post'] );
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
139 |
}
|
140 |
|
141 |
if ( isset( $GLOBALS['post_type'] ) ) {
|
@@ -153,13 +160,13 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
-
* Synchronizes post fields in translations
|
157 |
*
|
158 |
* @since 1.2
|
159 |
*
|
160 |
-
* @param int
|
161 |
-
* @param
|
162 |
-
* @param
|
163 |
*/
|
164 |
public function pll_save_post( $post_id, $post, $translations ) {
|
165 |
parent::pll_save_post( $post_id, $post, $translations );
|
@@ -186,6 +193,7 @@ class PLL_Admin_Sync extends PLL_Sync {
|
|
186 |
*
|
187 |
* @param string $func Function name
|
188 |
* @param array $args Function arguments
|
|
|
189 |
*/
|
190 |
public function __call( $func, $args ) {
|
191 |
$obj = substr( $func, 5 );
|
62 |
$from_post_id = (int) $_GET['from_post'];
|
63 |
$from_post = get_post( $from_post_id );
|
64 |
|
65 |
+
if ( $from_post instanceof WP_Post ) {
|
66 |
+
foreach ( array( 'menu_order', 'comment_status', 'ping_status' ) as $property ) {
|
67 |
+
$data[ $property ] = $from_post->$property;
|
68 |
+
}
|
69 |
+
|
70 |
+
// Copy the date only if the synchronization is activated
|
71 |
+
if ( in_array( 'post_date', $this->options['sync'] ) ) {
|
72 |
+
$data['post_date'] = $from_post->post_date;
|
73 |
+
$data['post_date_gmt'] = $from_post->post_date_gmt;
|
74 |
+
}
|
75 |
}
|
76 |
}
|
77 |
|
82 |
* Copy post metas, and taxonomies when using "Add new" ( translation )
|
83 |
*
|
84 |
* @since 2.5
|
85 |
+
*
|
86 |
+
* @return void
|
87 |
*/
|
88 |
public function new_post_translation() {
|
89 |
global $post;
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* Get post fields to synchronize.
|
116 |
*
|
117 |
* @since 2.4
|
118 |
*
|
119 |
+
* @param WP_Post $post Post object.
|
120 |
+
* @return array Fields to synchronize.
|
121 |
*/
|
122 |
protected function get_fields_to_sync( $post ) {
|
123 |
global $wpdb;
|
132 |
unset( $postarr['post_date_gmt'] );
|
133 |
|
134 |
$original = get_post( (int) $_GET['from_post'] );
|
135 |
+
|
136 |
+
if ( $original instanceof WP_Post ) {
|
137 |
+
$wpdb->update(
|
138 |
+
$wpdb->posts,
|
139 |
+
array(
|
140 |
+
'post_date' => $original->post_date,
|
141 |
+
'post_date_gmt' => $original->post_date_gmt,
|
142 |
+
),
|
143 |
+
array( 'ID' => $post->ID )
|
144 |
+
);
|
145 |
+
}
|
146 |
}
|
147 |
|
148 |
if ( isset( $GLOBALS['post_type'] ) ) {
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
+
* Synchronizes post fields in translations.
|
164 |
*
|
165 |
* @since 1.2
|
166 |
*
|
167 |
+
* @param int $post_id Post id.
|
168 |
+
* @param WP_Post $post Post object.
|
169 |
+
* @param int[] $translations Post translations.
|
170 |
*/
|
171 |
public function pll_save_post( $post_id, $post, $translations ) {
|
172 |
parent::pll_save_post( $post_id, $post, $translations );
|
193 |
*
|
194 |
* @param string $func Function name
|
195 |
* @param array $args Function arguments
|
196 |
+
* @return mixed|void
|
197 |
*/
|
198 |
public function __call( $func, $args ) {
|
199 |
$obj = substr( $func, 5 );
|
modules/sync/settings-sync.php
CHANGED
@@ -79,22 +79,22 @@ class PLL_Settings_Sync extends PLL_Settings_Module {
|
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
-
* Get the row actions
|
83 |
*
|
84 |
* @since 1.8
|
85 |
*
|
86 |
-
* @return
|
87 |
*/
|
88 |
protected function get_actions() {
|
89 |
return empty( $this->options['sync'] ) ? array( 'configure' ) : array( 'configure', 'deactivate' );
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
-
*
|
94 |
*
|
95 |
* @since 1.0
|
96 |
*
|
97 |
-
* @return
|
98 |
*/
|
99 |
public static function list_metas_to_sync() {
|
100 |
return array(
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* Get the row actions.
|
83 |
*
|
84 |
* @since 1.8
|
85 |
*
|
86 |
+
* @return string[] Row actions.
|
87 |
*/
|
88 |
protected function get_actions() {
|
89 |
return empty( $this->options['sync'] ) ? array( 'configure' ) : array( 'configure', 'deactivate' );
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
+
* Get the list of synchronization settings.
|
94 |
*
|
95 |
* @since 1.0
|
96 |
*
|
97 |
+
* @return string[] Array synchronization options.
|
98 |
*/
|
99 |
public static function list_metas_to_sync() {
|
100 |
return array(
|
modules/sync/sync-metas.php
CHANGED
@@ -9,8 +9,31 @@
|
|
9 |
* @since 2.3
|
10 |
*/
|
11 |
abstract class PLL_Sync_Metas {
|
|
|
|
|
|
|
12 |
public $model;
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* Constructor
|
@@ -35,6 +58,8 @@ abstract class PLL_Sync_Metas {
|
|
35 |
* Removes "added_{$this->meta_type}_meta" action
|
36 |
*
|
37 |
* @since 2.3
|
|
|
|
|
38 |
*/
|
39 |
protected function remove_add_meta_action() {
|
40 |
remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
|
@@ -44,6 +69,8 @@ abstract class PLL_Sync_Metas {
|
|
44 |
* Removes all meta synchronization actions and filters
|
45 |
*
|
46 |
* @since 2.3
|
|
|
|
|
47 |
*/
|
48 |
protected function remove_all_meta_actions() {
|
49 |
$this->remove_add_meta_action();
|
@@ -59,6 +86,8 @@ abstract class PLL_Sync_Metas {
|
|
59 |
* Adds "added_{$this->meta_type}_meta" action
|
60 |
*
|
61 |
* @since 2.3
|
|
|
|
|
62 |
*/
|
63 |
protected function restore_add_meta_action() {
|
64 |
add_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
|
@@ -68,6 +97,8 @@ abstract class PLL_Sync_Metas {
|
|
68 |
* Adds meta synchronization actions and filters
|
69 |
*
|
70 |
* @since 2.3
|
|
|
|
|
71 |
*/
|
72 |
protected function add_all_meta_actions() {
|
73 |
$this->restore_add_meta_action();
|
@@ -107,28 +138,28 @@ abstract class PLL_Sync_Metas {
|
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
-
* Get the custom fields to copy or synchronize
|
111 |
*
|
112 |
* @since 2.3
|
113 |
*
|
114 |
-
* @param int $from Id of the post from which we copy informations
|
115 |
-
* @param int $to Id of the post to which we paste informations
|
116 |
-
* @param string $lang Language slug
|
117 |
-
* @param bool $sync True if it is synchronization, false if it is a copy
|
118 |
-
* @return
|
119 |
*/
|
120 |
protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
|
121 |
/**
|
122 |
-
*
|
123 |
*
|
124 |
* @since 0.6
|
125 |
* @since 1.9.2 The `$from`, `$to`, `$lang` parameters were added.
|
126 |
*
|
127 |
-
* @param
|
128 |
-
* @param bool
|
129 |
-
* @param int
|
130 |
-
* @param int
|
131 |
-
* @param string
|
132 |
*/
|
133 |
return array_unique( apply_filters( "pll_copy_{$this->meta_type}_metas", array(), $sync, $from, $to, $lang ) );
|
134 |
}
|
@@ -168,6 +199,7 @@ abstract class PLL_Sync_Metas {
|
|
168 |
* @param int $id Object ID.
|
169 |
* @param string $meta_key Meta key.
|
170 |
* @param mixed $meta_value Meta value. Must be serializable if non-scalar.
|
|
|
171 |
*/
|
172 |
public function add_meta( $mid, $id, $meta_key, $meta_value ) {
|
173 |
static $avoid_recursion = false;
|
@@ -219,6 +251,7 @@ abstract class PLL_Sync_Metas {
|
|
219 |
* @param int $id Object ID.
|
220 |
* @param string $meta_key Meta key.
|
221 |
* @param mixed $meta_value Meta value. Must be serializable if non-scalar.
|
|
|
222 |
*/
|
223 |
public function update_meta( $mid, $id, $meta_key, $meta_value ) {
|
224 |
static $avoid_recursion = false;
|
@@ -251,12 +284,13 @@ abstract class PLL_Sync_Metas {
|
|
251 |
}
|
252 |
|
253 |
/**
|
254 |
-
* Store metas to synchronize before deleting them
|
255 |
*
|
256 |
* @since 2.3
|
257 |
*
|
258 |
-
* @param
|
259 |
* @param int $id Object ID.
|
|
|
260 |
*/
|
261 |
public function store_metas_to_sync( $mids, $id ) {
|
262 |
$tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
|
@@ -267,14 +301,15 @@ abstract class PLL_Sync_Metas {
|
|
267 |
}
|
268 |
|
269 |
/**
|
270 |
-
*
|
271 |
*
|
272 |
* @since 2.3
|
273 |
*
|
274 |
-
* @param
|
275 |
* @param int $id Object ID.
|
276 |
* @param string $key Meta key.
|
277 |
* @param mixed $value Meta value.
|
|
|
278 |
*/
|
279 |
public function delete_meta( $mids, $id, $key, $value ) {
|
280 |
static $avoid_recursion = false;
|
@@ -308,6 +343,7 @@ abstract class PLL_Sync_Metas {
|
|
308 |
* @param int $to Id of the target object
|
309 |
* @param string $lang Language code of the target object
|
310 |
* @param bool $sync Optional, defaults to true. True if it is synchronization, false if it is a copy
|
|
|
311 |
*/
|
312 |
public function copy( $from, $to, $lang, $sync = false ) {
|
313 |
$this->remove_all_meta_actions();
|
@@ -357,9 +393,10 @@ abstract class PLL_Sync_Metas {
|
|
357 |
*
|
358 |
* @since 2.3
|
359 |
*
|
360 |
-
* @param int $object_id Id of the object being
|
361 |
-
* @param object $obj Not used
|
362 |
-
* @param
|
|
|
363 |
*/
|
364 |
public function save_object( $object_id, $obj, $translations ) {
|
365 |
foreach ( $translations as $tr_lang => $tr_id ) {
|
9 |
* @since 2.3
|
10 |
*/
|
11 |
abstract class PLL_Sync_Metas {
|
12 |
+
/**
|
13 |
+
* @var PLL_Model
|
14 |
+
*/
|
15 |
public $model;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Meta type. Typically 'post' or 'term'.
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $meta_type;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Stores the previous values when updating a meta.
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $prev_value;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Stores the metas to synchronize before deleting them.
|
33 |
+
*
|
34 |
+
* @var array
|
35 |
+
*/
|
36 |
+
protected $to_copy;
|
37 |
|
38 |
/**
|
39 |
* Constructor
|
58 |
* Removes "added_{$this->meta_type}_meta" action
|
59 |
*
|
60 |
* @since 2.3
|
61 |
+
*
|
62 |
+
* @return void
|
63 |
*/
|
64 |
protected function remove_add_meta_action() {
|
65 |
remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
|
69 |
* Removes all meta synchronization actions and filters
|
70 |
*
|
71 |
* @since 2.3
|
72 |
+
*
|
73 |
+
* @return void
|
74 |
*/
|
75 |
protected function remove_all_meta_actions() {
|
76 |
$this->remove_add_meta_action();
|
86 |
* Adds "added_{$this->meta_type}_meta" action
|
87 |
*
|
88 |
* @since 2.3
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
*/
|
92 |
protected function restore_add_meta_action() {
|
93 |
add_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ), 10, 4 );
|
97 |
* Adds meta synchronization actions and filters
|
98 |
*
|
99 |
* @since 2.3
|
100 |
+
*
|
101 |
+
* @return void
|
102 |
*/
|
103 |
protected function add_all_meta_actions() {
|
104 |
$this->restore_add_meta_action();
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* Get the custom fields to copy or synchronize.
|
142 |
*
|
143 |
* @since 2.3
|
144 |
*
|
145 |
+
* @param int $from Id of the post from which we copy informations.
|
146 |
+
* @param int $to Id of the post to which we paste informations.
|
147 |
+
* @param string $lang Language slug.
|
148 |
+
* @param bool $sync True if it is synchronization, false if it is a copy.
|
149 |
+
* @return string[] List of meta keys.
|
150 |
*/
|
151 |
protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
|
152 |
/**
|
153 |
+
* Filters the custom fields to copy or synchronize.
|
154 |
*
|
155 |
* @since 0.6
|
156 |
* @since 1.9.2 The `$from`, `$to`, `$lang` parameters were added.
|
157 |
*
|
158 |
+
* @param string[] $keys List of custom fields names.
|
159 |
+
* @param bool $sync True if it is synchronization, false if it is a copy.
|
160 |
+
* @param int $from Id of the post from which we copy informations.
|
161 |
+
* @param int $to Id of the post to which we paste informations.
|
162 |
+
* @param string $lang Language slug.
|
163 |
*/
|
164 |
return array_unique( apply_filters( "pll_copy_{$this->meta_type}_metas", array(), $sync, $from, $to, $lang ) );
|
165 |
}
|
199 |
* @param int $id Object ID.
|
200 |
* @param string $meta_key Meta key.
|
201 |
* @param mixed $meta_value Meta value. Must be serializable if non-scalar.
|
202 |
+
* @return void
|
203 |
*/
|
204 |
public function add_meta( $mid, $id, $meta_key, $meta_value ) {
|
205 |
static $avoid_recursion = false;
|
251 |
* @param int $id Object ID.
|
252 |
* @param string $meta_key Meta key.
|
253 |
* @param mixed $meta_value Meta value. Must be serializable if non-scalar.
|
254 |
+
* @return void
|
255 |
*/
|
256 |
public function update_meta( $mid, $id, $meta_key, $meta_value ) {
|
257 |
static $avoid_recursion = false;
|
284 |
}
|
285 |
|
286 |
/**
|
287 |
+
* Store metas to synchronize before deleting them.
|
288 |
*
|
289 |
* @since 2.3
|
290 |
*
|
291 |
+
* @param int[] $mids Not used.
|
292 |
* @param int $id Object ID.
|
293 |
+
* @return void
|
294 |
*/
|
295 |
public function store_metas_to_sync( $mids, $id ) {
|
296 |
$tr_ids = $this->model->{$this->meta_type}->get_translations( $id );
|
301 |
}
|
302 |
|
303 |
/**
|
304 |
+
* Synchronizes deleted meta across translations.
|
305 |
*
|
306 |
* @since 2.3
|
307 |
*
|
308 |
+
* @param int[] $mids Not used.
|
309 |
* @param int $id Object ID.
|
310 |
* @param string $key Meta key.
|
311 |
* @param mixed $value Meta value.
|
312 |
+
* @return void
|
313 |
*/
|
314 |
public function delete_meta( $mids, $id, $key, $value ) {
|
315 |
static $avoid_recursion = false;
|
343 |
* @param int $to Id of the target object
|
344 |
* @param string $lang Language code of the target object
|
345 |
* @param bool $sync Optional, defaults to true. True if it is synchronization, false if it is a copy
|
346 |
+
* @return void
|
347 |
*/
|
348 |
public function copy( $from, $to, $lang, $sync = false ) {
|
349 |
$this->remove_all_meta_actions();
|
393 |
*
|
394 |
* @since 2.3
|
395 |
*
|
396 |
+
* @param int $object_id Id of the object being saved.
|
397 |
+
* @param object $obj Not used.
|
398 |
+
* @param int[] $translations The list of translations object ids.
|
399 |
+
* @return void
|
400 |
*/
|
401 |
public function save_object( $object_id, $obj, $translations ) {
|
402 |
foreach ( $translations as $tr_lang => $tr_id ) {
|
modules/sync/sync-post-metas.php
CHANGED
@@ -9,6 +9,11 @@
|
|
9 |
* @since 2.3
|
10 |
*/
|
11 |
class PLL_Sync_Post_Metas extends PLL_Sync_Metas {
|
|
|
|
|
|
|
|
|
|
|
12 |
public $options;
|
13 |
|
14 |
/**
|
@@ -29,15 +34,15 @@ class PLL_Sync_Post_Metas extends PLL_Sync_Metas {
|
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
* Get the custom fields to copy or synchronize
|
33 |
*
|
34 |
* @since 2.3
|
35 |
*
|
36 |
-
* @param int $from Id of the post from which we copy informations
|
37 |
-
* @param int $to Id of the post to which we paste informations
|
38 |
-
* @param string $lang Language slug
|
39 |
-
* @param bool $sync True if it is synchronization, false if it is a copy
|
40 |
-
* @return
|
41 |
*/
|
42 |
protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
|
43 |
// Copy or synchronize post metas and allow plugins to do the same
|
9 |
* @since 2.3
|
10 |
*/
|
11 |
class PLL_Sync_Post_Metas extends PLL_Sync_Metas {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
public $options;
|
18 |
|
19 |
/**
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
* Get the custom fields to copy or synchronize.
|
38 |
*
|
39 |
* @since 2.3
|
40 |
*
|
41 |
+
* @param int $from Id of the post from which we copy informations.
|
42 |
+
* @param int $to Id of the post to which we paste informations.
|
43 |
+
* @param string $lang Language slug.
|
44 |
+
* @param bool $sync True if it is synchronization, false if it is a copy.
|
45 |
+
* @return string[] List of meta keys.
|
46 |
*/
|
47 |
protected function get_metas_to_copy( $from, $to, $lang, $sync = false ) {
|
48 |
// Copy or synchronize post metas and allow plugins to do the same
|
modules/sync/sync-tax.php
CHANGED
@@ -10,6 +10,18 @@
|
|
10 |
*/
|
11 |
class PLL_Sync_Tax {
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* Constructor
|
15 |
*
|
@@ -18,7 +30,7 @@ class PLL_Sync_Tax {
|
|
18 |
* @param object $polylang
|
19 |
*/
|
20 |
public function __construct( &$polylang ) {
|
21 |
-
$this->model
|
22 |
$this->options = &$polylang->options;
|
23 |
|
24 |
add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
@@ -28,16 +40,16 @@ class PLL_Sync_Tax {
|
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
* Get the list of taxonomies to copy or to synchronize
|
32 |
*
|
33 |
* @since 1.7
|
34 |
* @since 2.1 The `$from`, `$to`, `$lang` parameters were added.
|
35 |
*
|
36 |
-
* @param bool $sync True if it is synchronization, false if it is a copy
|
37 |
-
* @param int $from Id of the post from which we copy informations, optional, defaults to null
|
38 |
-
* @param int $to Id of the post to which we paste informations, optional, defaults to null
|
39 |
-
* @param string $lang Language slug, optional, defaults to null
|
40 |
-
* @return
|
41 |
*/
|
42 |
protected function get_taxonomies_to_copy( $sync, $from = null, $to = null, $lang = null ) {
|
43 |
$taxonomies = ! $sync || in_array( 'taxonomies', $this->options['sync'] ) ? $this->model->get_translated_taxonomies() : array();
|
@@ -46,16 +58,16 @@ class PLL_Sync_Tax {
|
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
-
*
|
50 |
*
|
51 |
* @since 1.7
|
52 |
* @since 2.1 The `$from`, `$to`, `$lang` parameters were added.
|
53 |
*
|
54 |
-
* @param
|
55 |
-
* @param bool
|
56 |
-
* @param int
|
57 |
-
* @param int
|
58 |
-
* @param string
|
59 |
*/
|
60 |
return array_unique( apply_filters( 'pll_copy_taxonomies', $taxonomies, $sync, $from, $to, $lang ) );
|
61 |
}
|
@@ -65,11 +77,11 @@ class PLL_Sync_Tax {
|
|
65 |
*
|
66 |
* @since 2.3
|
67 |
*
|
68 |
-
* @param
|
69 |
-
* @param
|
70 |
-
* @param string $taxonomy Taxonomy name
|
71 |
-
* @param string $lang Language slug
|
72 |
-
* @return
|
73 |
*/
|
74 |
protected function maybe_translate_terms( $object_id, $terms, $taxonomy, $lang ) {
|
75 |
if ( is_array( $terms ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
@@ -104,7 +116,7 @@ class PLL_Sync_Tax {
|
|
104 |
}
|
105 |
|
106 |
/**
|
107 |
-
* Maybe copy taxonomy terms from one post to the other
|
108 |
*
|
109 |
* @since 2.6
|
110 |
*
|
@@ -114,6 +126,7 @@ class PLL_Sync_Tax {
|
|
114 |
* @param array $terms An array of object terms.
|
115 |
* @param string $taxonomy Taxonomy slug.
|
116 |
* @param bool $append Whether to append new terms to the old terms.
|
|
|
117 |
*/
|
118 |
protected function copy_object_terms( $object_id, $tr_id, $lang, $terms, $taxonomy, $append ) {
|
119 |
$to_copy = $this->get_taxonomies_to_copy( true, $object_id, $tr_id, $lang );
|
@@ -139,22 +152,23 @@ class PLL_Sync_Tax {
|
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
-
* When assigning terms to a post, assign translated terms to the translated posts (synchronisation)
|
143 |
*
|
144 |
* @since 2.3
|
145 |
*
|
146 |
* @param int $object_id Object ID.
|
147 |
* @param array $terms An array of object terms.
|
148 |
-
* @param
|
149 |
* @param string $taxonomy Taxonomy slug.
|
150 |
* @param bool $append Whether to append new terms to the old terms.
|
|
|
151 |
*/
|
152 |
public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append ) {
|
153 |
static $avoid_recursion = false;
|
154 |
$taxonomy_object = get_taxonomy( $taxonomy );
|
155 |
|
156 |
// Make sure that the taxonomy is registered for a post type
|
157 |
-
if ( ! $avoid_recursion && array_filter( $taxonomy_object->object_type, 'post_type_exists' ) ) {
|
158 |
$avoid_recursion = true;
|
159 |
|
160 |
$tr_ids = $this->model->post->get_translations( $object_id );
|
@@ -193,6 +207,7 @@ class PLL_Sync_Tax {
|
|
193 |
* @param int $from Id of the source post
|
194 |
* @param int $to Id of the target post
|
195 |
* @param string $lang Language slug
|
|
|
196 |
*/
|
197 |
public function copy( $from, $to, $lang ) {
|
198 |
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 6 );
|
@@ -201,7 +216,7 @@ class PLL_Sync_Tax {
|
|
201 |
$taxonomies = array_intersect( get_post_taxonomies( $from ), $this->get_taxonomies_to_copy( false, $from, $to, $lang ) );
|
202 |
|
203 |
// Update the term cache to reduce the number of queries in the loop
|
204 |
-
update_object_term_cache( $from, get_post_type( $from ) );
|
205 |
|
206 |
// Copy
|
207 |
foreach ( $taxonomies as $tax ) {
|
@@ -219,13 +234,14 @@ class PLL_Sync_Tax {
|
|
219 |
}
|
220 |
|
221 |
/**
|
222 |
-
* When creating a new term, associate it to posts having translations associated to the translated terms
|
223 |
*
|
224 |
* @since 2.3
|
225 |
*
|
226 |
-
* @param int $term_id Id of the created term
|
227 |
-
* @param string $taxonomy Taxonomy
|
228 |
-
* @param
|
|
|
229 |
*/
|
230 |
public function create_term( $term_id, $taxonomy, $translations ) {
|
231 |
if ( doing_action( 'create_term' ) && in_array( $taxonomy, $this->get_taxonomies_to_copy( true ) ) ) {
|
@@ -274,6 +290,8 @@ class PLL_Sync_Tax {
|
|
274 |
* to avoid translated terms to be removed from translated posts
|
275 |
*
|
276 |
* @since 2.3.2
|
|
|
|
|
277 |
*/
|
278 |
public function pre_delete_term() {
|
279 |
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
@@ -283,6 +301,8 @@ class PLL_Sync_Tax {
|
|
283 |
* Re-activate the synchronization of terms after a term is deleted
|
284 |
*
|
285 |
* @since 2.3.2
|
|
|
|
|
286 |
*/
|
287 |
public function delete_term() {
|
288 |
add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
10 |
*/
|
11 |
class PLL_Sync_Tax {
|
12 |
|
13 |
+
/**
|
14 |
+
* Stores the plugin options.
|
15 |
+
*
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
protected $options;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var PLL_Model
|
22 |
+
*/
|
23 |
+
protected $model;
|
24 |
+
|
25 |
/**
|
26 |
* Constructor
|
27 |
*
|
30 |
* @param object $polylang
|
31 |
*/
|
32 |
public function __construct( &$polylang ) {
|
33 |
+
$this->model = &$polylang->model;
|
34 |
$this->options = &$polylang->options;
|
35 |
|
36 |
add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
40 |
}
|
41 |
|
42 |
/**
|
43 |
+
* Get the list of taxonomies to copy or to synchronize.
|
44 |
*
|
45 |
* @since 1.7
|
46 |
* @since 2.1 The `$from`, `$to`, `$lang` parameters were added.
|
47 |
*
|
48 |
+
* @param bool $sync True if it is synchronization, false if it is a copy.
|
49 |
+
* @param int $from Id of the post from which we copy informations, optional, defaults to null.
|
50 |
+
* @param int $to Id of the post to which we paste informations, optional, defaults to null.
|
51 |
+
* @param string $lang Language slug, optional, defaults to null.
|
52 |
+
* @return string[] List of taxonomy names.
|
53 |
*/
|
54 |
protected function get_taxonomies_to_copy( $sync, $from = null, $to = null, $lang = null ) {
|
55 |
$taxonomies = ! $sync || in_array( 'taxonomies', $this->options['sync'] ) ? $this->model->get_translated_taxonomies() : array();
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
+
* Filters the taxonomies to copy or synchronize.
|
62 |
*
|
63 |
* @since 1.7
|
64 |
* @since 2.1 The `$from`, `$to`, `$lang` parameters were added.
|
65 |
*
|
66 |
+
* @param string[] $taxonomies List of taxonomy names.
|
67 |
+
* @param bool $sync True if it is synchronization, false if it is a copy.
|
68 |
+
* @param int $from Id of the post from which we copy informations.
|
69 |
+
* @param int $to Id of the post to which we paste informations.
|
70 |
+
* @param string $lang Language slug.
|
71 |
*/
|
72 |
return array_unique( apply_filters( 'pll_copy_taxonomies', $taxonomies, $sync, $from, $to, $lang ) );
|
73 |
}
|
77 |
*
|
78 |
* @since 2.3
|
79 |
*
|
80 |
+
* @param int $object_id Object ID.
|
81 |
+
* @param int[] $terms List of terms ids assigned to the source post.
|
82 |
+
* @param string $taxonomy Taxonomy name.
|
83 |
+
* @param string $lang Language slug.
|
84 |
+
* @return int[] List of terms ids to assign to the target post.
|
85 |
*/
|
86 |
protected function maybe_translate_terms( $object_id, $terms, $taxonomy, $lang ) {
|
87 |
if ( is_array( $terms ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
116 |
}
|
117 |
|
118 |
/**
|
119 |
+
* Maybe copy taxonomy terms from one post to the other.
|
120 |
*
|
121 |
* @since 2.6
|
122 |
*
|
126 |
* @param array $terms An array of object terms.
|
127 |
* @param string $taxonomy Taxonomy slug.
|
128 |
* @param bool $append Whether to append new terms to the old terms.
|
129 |
+
* @return void
|
130 |
*/
|
131 |
protected function copy_object_terms( $object_id, $tr_id, $lang, $terms, $taxonomy, $append ) {
|
132 |
$to_copy = $this->get_taxonomies_to_copy( true, $object_id, $tr_id, $lang );
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
+
* When assigning terms to a post, assign translated terms to the translated posts (synchronisation).
|
156 |
*
|
157 |
* @since 2.3
|
158 |
*
|
159 |
* @param int $object_id Object ID.
|
160 |
* @param array $terms An array of object terms.
|
161 |
+
* @param int[] $tt_ids An array of term taxonomy IDs.
|
162 |
* @param string $taxonomy Taxonomy slug.
|
163 |
* @param bool $append Whether to append new terms to the old terms.
|
164 |
+
* @return void
|
165 |
*/
|
166 |
public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy, $append ) {
|
167 |
static $avoid_recursion = false;
|
168 |
$taxonomy_object = get_taxonomy( $taxonomy );
|
169 |
|
170 |
// Make sure that the taxonomy is registered for a post type
|
171 |
+
if ( ! $avoid_recursion && ! empty( $taxonomy_object ) && array_filter( $taxonomy_object->object_type, 'post_type_exists' ) ) {
|
172 |
$avoid_recursion = true;
|
173 |
|
174 |
$tr_ids = $this->model->post->get_translations( $object_id );
|
207 |
* @param int $from Id of the source post
|
208 |
* @param int $to Id of the target post
|
209 |
* @param string $lang Language slug
|
210 |
+
* @return void
|
211 |
*/
|
212 |
public function copy( $from, $to, $lang ) {
|
213 |
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 6 );
|
216 |
$taxonomies = array_intersect( get_post_taxonomies( $from ), $this->get_taxonomies_to_copy( false, $from, $to, $lang ) );
|
217 |
|
218 |
// Update the term cache to reduce the number of queries in the loop
|
219 |
+
update_object_term_cache( array( $from ), get_post_type( $from ) );
|
220 |
|
221 |
// Copy
|
222 |
foreach ( $taxonomies as $tax ) {
|
234 |
}
|
235 |
|
236 |
/**
|
237 |
+
* When creating a new term, associate it to posts having translations associated to the translated terms.
|
238 |
*
|
239 |
* @since 2.3
|
240 |
*
|
241 |
+
* @param int $term_id Id of the created term.
|
242 |
+
* @param string $taxonomy Taxonomy.
|
243 |
+
* @param int[] $translations Ids of the translations of the created term.
|
244 |
+
* @return void
|
245 |
*/
|
246 |
public function create_term( $term_id, $taxonomy, $translations ) {
|
247 |
if ( doing_action( 'create_term' ) && in_array( $taxonomy, $this->get_taxonomies_to_copy( true ) ) ) {
|
290 |
* to avoid translated terms to be removed from translated posts
|
291 |
*
|
292 |
* @since 2.3.2
|
293 |
+
*
|
294 |
+
* @return void
|
295 |
*/
|
296 |
public function pre_delete_term() {
|
297 |
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
301 |
* Re-activate the synchronization of terms after a term is deleted
|
302 |
*
|
303 |
* @since 2.3.2
|
304 |
+
*
|
305 |
+
* @return void
|
306 |
*/
|
307 |
public function delete_term() {
|
308 |
add_action( 'set_object_terms', array( $this, 'set_object_terms' ), 10, 5 );
|
modules/sync/sync.php
CHANGED
@@ -9,7 +9,32 @@
|
|
9 |
* @since 2.4
|
10 |
*/
|
11 |
class PLL_Sync {
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
/**
|
15 |
* Constructor
|
@@ -45,11 +70,11 @@ class PLL_Sync {
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
-
* Get post fields to
|
49 |
*
|
50 |
* @since 2.4
|
51 |
*
|
52 |
-
* @param
|
53 |
* @return array
|
54 |
*/
|
55 |
protected function get_fields_to_sync( $post ) {
|
@@ -119,13 +144,14 @@ class PLL_Sync {
|
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
-
* Synchronizes post fields in translations
|
123 |
*
|
124 |
* @since 2.4
|
125 |
*
|
126 |
-
* @param int
|
127 |
-
* @param
|
128 |
-
* @param
|
|
|
129 |
*/
|
130 |
public function pll_save_post( $post_id, $post, $translations ) {
|
131 |
global $wpdb;
|
@@ -170,24 +196,32 @@ class PLL_Sync {
|
|
170 |
* @param int $term_id Term id.
|
171 |
* @param int $tt_id Term taxonomy id, not used.
|
172 |
* @param string $taxonomy Taxonomy name.
|
|
|
173 |
*/
|
174 |
public function sync_term_parent( $term_id, $tt_id, $taxonomy ) {
|
175 |
global $wpdb;
|
176 |
|
177 |
if ( is_taxonomy_hierarchical( $taxonomy ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
178 |
$term = get_term( $term_id );
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
$
|
185 |
-
$
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
}
|
192 |
}
|
193 |
}
|
@@ -199,19 +233,20 @@ class PLL_Sync {
|
|
199 |
* @since 1.8
|
200 |
*
|
201 |
* @param int $post_id post id
|
|
|
202 |
*/
|
203 |
public function edit_attachment( $post_id ) {
|
204 |
$this->pll_save_post( $post_id, get_post( $post_id ), $this->model->post->get_translations( $post_id ) );
|
205 |
}
|
206 |
|
207 |
/**
|
208 |
-
* Synchronize sticky posts
|
209 |
*
|
210 |
* @since 2.3
|
211 |
*
|
212 |
-
* @param
|
213 |
-
* @param
|
214 |
-
* @return
|
215 |
*/
|
216 |
public function sync_sticky_posts( $value, $old_value ) {
|
217 |
if ( in_array( 'sticky_posts', $this->options['sync'] ) ) {
|
9 |
* @since 2.4
|
10 |
*/
|
11 |
class PLL_Sync {
|
12 |
+
/**
|
13 |
+
* @var PLL_Sync_Tax
|
14 |
+
*/
|
15 |
+
public $taxonomies;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var PLL_Sync_Post_Metas
|
19 |
+
*/
|
20 |
+
public $post_metas;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var PLL_Sync_Term_Metas
|
24 |
+
*/
|
25 |
+
public $term_metas;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Stores the plugin options.
|
29 |
+
*
|
30 |
+
* @var array
|
31 |
+
*/
|
32 |
+
protected $options;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var PLL_Model
|
36 |
+
*/
|
37 |
+
protected $model;
|
38 |
|
39 |
/**
|
40 |
* Constructor
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
+
* Get post fields to synchronize.
|
74 |
*
|
75 |
* @since 2.4
|
76 |
*
|
77 |
+
* @param WP_Post $post Post object.
|
78 |
* @return array
|
79 |
*/
|
80 |
protected function get_fields_to_sync( $post ) {
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* Synchronizes post fields in translations.
|
148 |
*
|
149 |
* @since 2.4
|
150 |
*
|
151 |
+
* @param int $post_id Post id.
|
152 |
+
* @param WP_Post $post Post object.
|
153 |
+
* @param int[] $translations Post translations.
|
154 |
+
* @return void
|
155 |
*/
|
156 |
public function pll_save_post( $post_id, $post, $translations ) {
|
157 |
global $wpdb;
|
196 |
* @param int $term_id Term id.
|
197 |
* @param int $tt_id Term taxonomy id, not used.
|
198 |
* @param string $taxonomy Taxonomy name.
|
199 |
+
* @return void
|
200 |
*/
|
201 |
public function sync_term_parent( $term_id, $tt_id, $taxonomy ) {
|
202 |
global $wpdb;
|
203 |
|
204 |
if ( is_taxonomy_hierarchical( $taxonomy ) && $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
205 |
$term = get_term( $term_id );
|
206 |
+
|
207 |
+
if ( $term instanceof WP_Term ) {
|
208 |
+
$translations = $this->model->term->get_translations( $term_id );
|
209 |
+
|
210 |
+
foreach ( $translations as $lang => $tr_id ) {
|
211 |
+
if ( ! empty( $tr_id ) && $tr_id !== $term_id ) {
|
212 |
+
$tr_parent = $this->model->term->get_translation( $term->parent, $lang );
|
213 |
+
$tr_term = get_term( (int) $tr_id, $taxonomy );
|
214 |
+
|
215 |
+
if ( $tr_term instanceof WP_Term ) {
|
216 |
+
$wpdb->update(
|
217 |
+
$wpdb->term_taxonomy,
|
218 |
+
array( 'parent' => $tr_parent ? $tr_parent : 0 ),
|
219 |
+
array( 'term_taxonomy_id' => $tr_term->term_taxonomy_id )
|
220 |
+
);
|
221 |
+
|
222 |
+
clean_term_cache( $tr_id, $taxonomy ); // OK since WP 3.9.
|
223 |
+
}
|
224 |
+
}
|
225 |
}
|
226 |
}
|
227 |
}
|
233 |
* @since 1.8
|
234 |
*
|
235 |
* @param int $post_id post id
|
236 |
+
* @return void
|
237 |
*/
|
238 |
public function edit_attachment( $post_id ) {
|
239 |
$this->pll_save_post( $post_id, get_post( $post_id ), $this->model->post->get_translations( $post_id ) );
|
240 |
}
|
241 |
|
242 |
/**
|
243 |
+
* Synchronize sticky posts.
|
244 |
*
|
245 |
* @since 2.3
|
246 |
*
|
247 |
+
* @param int[] $value New option value.
|
248 |
+
* @param int[] $old_value Old option value.
|
249 |
+
* @return int[]
|
250 |
*/
|
251 |
public function sync_sticky_posts( $value, $old_value ) {
|
252 |
if ( in_array( 'sticky_posts', $this->options['sync'] ) ) {
|
modules/wizard/css/wizard.css
CHANGED
@@ -3,7 +3,8 @@ body {
|
|
3 |
margin: 65px auto 24px;
|
4 |
box-shadow: none;
|
5 |
background: #f1f1f1;
|
6 |
-
padding: 0
|
|
|
7 |
}
|
8 |
|
9 |
#pll-logo {
|
3 |
margin: 65px auto 24px;
|
4 |
box-shadow: none;
|
5 |
background: #f1f1f1;
|
6 |
+
padding: 0;
|
7 |
+
border: 0; /* fix-pro #856 override WP install.css */
|
8 |
}
|
9 |
|
10 |
#pll-logo {
|
modules/wizard/css/wizard.min.css
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
@charset "UTF-8";body{margin:65px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#pll-logo{border:0;margin:0 0 24px;padding:0;text-align:center;font-family:sans-serif;font-size:64px;text-transform:uppercase;color:#000;line-height:normal}#pll-logo a{display:flex;justify-content:center;color:#000;text-decoration:none}#pll-logo img{max-width:100%;margin-right:16px}.rtl #pll-logo img{margin-right:0;margin-left:16px}.pll-wizard-footer{text-align:center}.pll-wizard .select2-container{text-align:left;width:auto}.pll-wizard .hidden{display:none}.pll-wizard-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:2em;margin:0 0 20px;background:#fff;overflow:hidden;zoom:1;text-align:left}.rtl .pll-wizard-content{text-align:right}.pll-wizard-content h1,.pll-wizard-content h2,.pll-wizard-content h3,.pll-wizard-content table{margin:0 0 20px;border:0;padding:0;color:#666;clear:none;font-weight:500}.pll-wizard-content p{margin:20px 0;font-size:1em;line-height:1.75em;color:#666}.pll-wizard-content table{font-size:1em;line-height:1.75em;color:#666;width:100%;margin-top:20px}.pll-wizard-content table td span{display:inline-block}.pll-wizard-content table caption{caption-side:bottom;font-style:italic;text-align:right}.rtl .pll-wizard-content table caption{text-align:left}.pll-wizard-content table caption .icon-default-lang{font-style:normal}.pll-wizard-content a{color:#a03f3f}.pll-wizard-content a:focus,.pll-wizard-content a:hover,.pll-wizard-footer-links:hover{color:#dd5454}.pll-wizard-content .pll-wizard-next-steps{overflow:hidden;margin:0 0 24px;padding-bottom:2px}.pll-wizard-content .pll-wizard-next-steps h2{margin-bottom:12px}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first{float:left;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last{float:right;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps ul{padding:0 2em 0 0;list-style:none outside;margin:0}.pll-wizard-content .pll-wizard-next-steps ul li a{display:block;padding:0 0 .75em}.pll-wizard-content .pll-wizard-next-steps ul li a::before{color:#82878c;font:normal 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;text-decoration:none!important;vertical-align:top}.pll-wizard-steps{padding:0 0 24px;margin:0;list-style:none outside;overflow:hidden;color:#ccc;width:100%;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex}.pll-wizard-steps li{width:100%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.pll-wizard-steps li a{color:#a03f3f;text-decoration:none;padding:1.5em;margin:-1.5em;position:relative;z-index:1}.pll-wizard-steps li a:focus,.pll-wizard-steps li a:hover{color:#dd5454;text-decoration:underline}.pll-wizard-steps li::before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.pll-wizard-steps li.active{border-color:#a03f3f;color:#a03f3f;font-weight:700}.pll-wizard-steps li.active::before{border-color:#a03f3f}.pll-wizard-steps li.done{border-color:#a03f3f;color:#a03f3f}.pll-wizard-steps li.done::before{border-color:#a03f3f;background:#a03f3f}.pll-wizard .pll-wizard-actions{overflow:hidden;margin:20px 0 0;position:relative}.pll-wizard .pll-wizard-actions .button{font-size:16px;font-weight:300;padding:1em 2em;line-height:1em;margin-right:.5em;margin-bottom:2px;margin-top:10px;height:auto;border-radius:4px;box-shadow:none;min-width:auto;border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-content .button{border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-actions .button-primary,.pll-wizard .pll-wizard-content .button-primary{background-color:#a03f3f;border-color:#a03f3f;color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #a03f3f;text-shadow:0 -1px 1px #a03f3f,1px 0 1px #a03f3f,0 1px 1px #a03f3f,-1px 0 1px #a03f3f;margin:0;opacity:1}.pll-wizard .pll-wizard-content .button-small .dashicons{font-size:15px;height:auto;vertical-align:middle}.pll-wizard .button-primary:active,.pll-wizard .button-primary:focus,.pll-wizard .button-primary:hover,.pll-wizard input[type=checkbox]:focus+label.button-primary{background:#dd5454;border-color:#dd5454;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #dd5454}.pll-wizard .pll-wizard-actions .button-primary.disabled,.pll-wizard .pll-wizard-actions .button-primary:disabled,.pll-wizard .pll-wizard-actions .button-primary[disabled]{cursor:wait;background-color:#bb5454!important;border-color:#bb5454!important;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #bb5454!important;text-shadow:0 -1px 1px #bb5454,1px 0 1px #bb5454,0 1px 1px #bb5454,-1px 0 1px #bb5454!important;color:#ffa3a3!important}.pll-wizard-content p:last-child{margin-bottom:0}.pll-wizard-footer-links{font-size:.85em;color:#7b7b7b;margin:1.18em auto;display:inline-block;text-align:center}.pll-wizard-services{border:1px solid #eee;padding:0;margin:0 0 1em;list-style:none outside;border-radius:4px;overflow:hidden}.pll-wizard-services p{margin:0 0 1em 0;padding:0;font-size:1em;line-height:1.5em}.pll-wizard-service-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;padding:0;border-bottom:1px solid #eee;color:#666;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.media-step .pll-wizard-service-item{border:0}.media-step .pll-wizard-service-item:last-child{display:block}.media-step .pll-wizard-service-item .pll-wizard-service-enable{padding-bottom:0}.pll-wizard-service-item:last-child{border-bottom:0}.pll-wizard-service-item .pll-wizard-service-name{-webkit-flex-basis:0;flex-basis:0;min-width:160px;text-align:center;font-weight:700;padding:2em 0;-webkit-align-self:stretch;align-self:stretch;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:baseline;-webkit-align-items:baseline;align-items:baseline}.pll-wizard-service-item .pll-wizard-service-name img{max-width:75px}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;padding:20px}.pll-wizard-service-item .pll-wizard-service-example{padding:0 20px 20px}.pll-wizard-service-item .pll-wizard-service-example p{text-align:right}.rtl .pll-wizard-service-item .pll-wizard-service-example p{text-align:left}.pll-wizard-service-item .pll-wizard-service-description p{margin-bottom:1em}.pll-wizard-service-item .pll-wizard-service-description p:last-child{margin-bottom:0}.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description{display:block;font-style:italic;color:#999}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-flex-basis:0;flex-basis:0;min-width:75px;text-align:center;cursor:pointer;padding:2em 0;position:relative;max-height:1.5em;-webkit-align-self:flex-start;align-self:flex-start;-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-toggle{position:relative}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]{position:absolute;opacity:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label{position:relative;display:inline-block;width:44px;height:20px;border-radius:10em;cursor:pointer;text-indent:-9999px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus+label{border:1px dashed #777}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::after,.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::before{content:'';position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::before{left:0;top:0;width:44px;height:20px;background:#ddd;border-radius:10em;transition:background-color .2s}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label::after{width:16px;height:16px;transition:all .2s;border-radius:50%;background:#fff;margin:2px;top:0;left:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label::before{background:#a03f3f}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label::after{right:0;left:auto}.pll-wizard-service-item .pll-wizard-service-settings{display:none;margin-top:.75em;margin-bottom:0;cursor:default}.pll-wizard-service-item .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.checked .pll-wizard-service-settings{display:inline-block}.pll-wizard-service-item.checked .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.closed{border-bottom:0}.step{text-align:center}.pll-wizard .button .dashicons{vertical-align:middle}.rtl .dashicons-arrow-right-alt2:before{content:"\f341"}.pll-wizard .pll-wizard-actions .button:active,.pll-wizard .pll-wizard-actions .button:focus,.pll-wizard .pll-wizard-actions .button:hover{box-shadow:none}.pll-wizard-next-steps{border:1px solid #eee;border-radius:4px;list-style:none;padding:0}.pll-wizard-next-steps li{padding:0}.pll-wizard-next-steps .pll-wizard-next-step-item{display:-webkit-box;display:-webkit-flex;display:flex;border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,.pll-wizard-next-steps .pll-wizard-next-step-item:first-child{border-top:0}.pll-wizard-next-steps .pll-wizard-next-step-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;margin:1.5em}.pll-wizard-next-steps .pll-wizard-next-step-action{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.pll-wizard-next-steps .pll-wizard-next-step-action .button{margin:1em 1.5em}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description{margin-top:0}.pll-wizard-next-steps p.next-step-heading{margin:0;font-size:.95em;font-weight:400;font-variant:all-petite-caps}.pll-wizard-next-steps p.next-step-extra-info{margin:0}.pll-wizard-next-steps h3.next-step-description{margin:0;font-size:16px;font-weight:600}.pll-wizard-next-steps .pll-wizard-additional-steps{border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions{margin:0 0 1.5em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{font-size:15px;margin:1em 0 1em 1.5em}.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{margin:1em 1.5em 1em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child{margin-right:1.5em}.pll-wizard-content img{max-width:100%;margin-right:.5em}.rtl .pll-wizard-content img{margin-left:.5em}.pll-wizard-content .form-field label{margin-bottom:5px;display:block}.pll-wizard-content .form-field select{padding:3px}.pll-wizard-content .languages-step select,.pll-wizard-content .untranslated-contents-step select{width:100%}.languages-step .form-field .button{margin-left:15px}.languages-step .form-field .button>span{margin-right:.3em}.rtl .languages-step .form-field .button{margin-left:0;margin-right:15px}.rtl .languages-step .form-field .button>span{margin-left:.3em;margin-right:0}.pll-wizard-content .languages-step .select-language-field{display:flex}.pll-wizard-content #languages{display:none}.pll-wizard-content #languages tr th:first-child{width:80%}.pll-wizard-content #languages .dashicons{color:#a03f3f}.pll-wizard-content #languages img{margin-right:5px}.pll-wizard-content .error{color:#a03f3f;font-weight:700}.pll-wizard-content #messages .error{background:#fccfcf;padding:.5rem;border:1px solid #a03f3f;margin-bottom:.5rem}.pll-wizard-content #slide-toggle{position:absolute;opacity:0}.pll-wizard-content #slide-toggle+label{position:relative}.pll-wizard-content #slide-toggle+label+span{display:block}.pll-wizard-content #slide-toggle+label .dashicons{margin-right:.3em}.rtl .pll-wizard-content #slide-toggle+label .dashicons{margin-left:.3em;margin-right:0}.pll-wizard-content #slide-toggle~#screenshot>img{max-height:500px;margin-top:10px;-webkit-transition:all .5s cubic-bezier(0,1,.5,1);transition:all .5s cubic-bezier(0,1,.5,1)}.pll-wizard-content #slide-toggle:checked~#screenshot>img{max-height:0}.hide{display:none}.field-in-error,input[type=checkbox].field-in-error,input[type=color].field-in-error,input[type=date].field-in-error,input[type=datetime-local].field-in-error,input[type=datetime].field-in-error,input[type=email].field-in-error,input[type=month].field-in-error,input[type=number].field-in-error,input[type=password].field-in-error,input[type=radio].field-in-error,input[type=search].field-in-error,input[type=tel].field-in-error,input[type=text].field-in-error,input[type=time].field-in-error,input[type=url].field-in-error,input[type=week].field-in-error,select.field-in-error,span.field-in-error,textarea.field-in-error{border-color:#a03f3f}.field-in-error:focus,input[type=checkbox].field-in-error:focus,input[type=color].field-in-error:focus,input[type=date].field-in-error:focus,input[type=datetime-local].field-in-error:focus,input[type=datetime].field-in-error:focus,input[type=email].field-in-error:focus,input[type=month].field-in-error:focus,input[type=number].field-in-error:focus,input[type=password].field-in-error:focus,input[type=radio].field-in-error:focus,input[type=search].field-in-error:focus,input[type=tel].field-in-error:focus,input[type=text].field-in-error:focus,input[type=time].field-in-error:focus,input[type=url].field-in-error:focus,input[type=week].field-in-error:focus,select.field-in-error:focus,span.field-in-error:focus,textarea.field-in-error:focus{border:1px solid #a03f3f;box-shadow:0 0 2px rgba(160,63,63,.8);outline-color:#a03f3f;outline-style:auto;outline-width:thin}.form-table input.regular-text{width:25em}.form-table input.field-in-error{border-color:#a03f3f}#pll-licenses-table td{padding:10px 9px}#pll-licenses-table .license-valid td p{min-width:35em}#pll-licenses-table .pll-deactivate-license{margin:0 0 0 20px}.rtl #pll-licenses-table .pll-deactivate-license{margin:0 10px 0 0}.pll-wizard-content .documentation{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.pll-wizard-content .documentation p{padding:0;margin:0 0 12px}.documentation-container{display:-webkit-box;display:-webkit-flex;display:flex;justify-content:flex-end}.documentation-container .documentation-button-container{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}.wc-setup .wc-setup-actions .button.documentation-button{height:42px;padding:0 1em;margin:0}#dialog{display:none}.pll-wizard .ui-dialog.ui-widget-content{max-height:none}.pll-wizard .ui-dialog-title::before{content:"\f534";font-family:dashicons;display:inline-block;line-height:1;font-weight:400;font-style:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:20px;height:20px;font-size:20px;vertical-align:middle;text-align:center;margin:0 5px 5px 0;transition:color .1s ease-in}.rtl.pll-wizard .ui-dialog-title::before{margin-right:0;margin-left:5px}.pll-wizard .ui-dialog ul{list-style:disc;padding-left:20px}.rtl.pll-wizard .ui-dialog ul{padding-left:0;padding-right:20px}.pll-wizard li{margin-bottom:0}#translations{border-collapse:collapse}#translations tbody:nth-child(odd){background-color:#f9f9f9}#translations.striped>tbody>:nth-child(odd){background-color:transparent}.pll-wizard-content mark{background:transparent none}.pll-wizard-content mark{color:#7ad03a}@media screen and (max-width:782px){.languages-step .form-field .button{font-size:13px;line-height:26px;height:28px;padding:0 10px 1px;vertical-align:top}#pll-licenses-table .pll-deactivate-license{margin:10px 0 5px}}@media only screen and (max-width:620px){.ui-dialog{width:100%!important}}@media only screen and (max-width:500px){#pll-logo a,.select-language-field{flex-direction:column}.select-language-field .action-buttons{display:flex;justify-content:flex-end}.languages-step .form-field .button{margin:5px 0 0}}@media only screen and (max-width:400px){#pll-logo{font-size:56px}.pll-wizard-steps{display:none}.pll-wizard-service-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:3;-webkit-order:2;order:2;padding:20px 0 0}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-name{padding:20px 20px 0;text-align:left;-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;justify-content:space-between!important}.pll-wizard-service-item .pll-wizard-service-name img{margin:0}.pll-wizard-next-steps .pll-wizard-next-step-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p{margin:0}}@media only screen and (max-width:360px){#pll-logo{font-size:48px}}
|
|
modules/wizard/js/languages-step.min.js
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
jQuery(function(a){var e=a(".languages-step"),n=a("#language-fields"),t=a("#languages"),l=a("#languages tbody"),i=a("#defined-languages tbody"),r=a("#lang_list"),d=a('[name="save_step"]'),s=a("#messages"),o=new Map,g=a("#dialog");function u(e){var i=a("<td />").text(e.text).prepend(e.flagUrl),d=a("<td />").append(a("<span />").addClass("dashicons dashicons-trash").attr("data-language",e.locale).append(a("<span />").addClass("screen-reader-text").text(pll_wizard_params.i18n_remove_language_icon))),s=a("<tr />").prepend(d).prepend(i),g=a("<input />").attr({type:"hidden",name:"languages[]"}).val(e.locale);r.val(""),r.selectmenu("refresh"),o.set(e.locale,e),l.append(s),l.on("click","span[data-language="+e.locale+"]",function(e){e.preventDefault(),a(this).parents("tr").remove();n.children("input[value="+a(this).data("language")+"]").remove();l.children().length<=0&&t.hide(),o.delete(a(this).data("language")),c()}),n.append(g)}function p(e){s.empty(),s.prepend(a("<p/>").addClass("error").text(e))}function c(){s.empty(),e.find(".error").removeClass("error field-in-error")}function _(a){a.addClass("error field-in-error")}function m(a){a.trigger("focus")}r.on("selectmenuchange",function(){c()}),a("#add-language").on("click",function(e){c();var n=e.currentTarget.form.lang_list.options[e.currentTarget.form.lang_list.selectedIndex];if(""===n.value||o.has(n.value)){var l=pll_wizard_params.i18n_no_language_selected;o.has(n.value)&&(l=pll_wizard_params.i18n_language_already_added),p(l),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))}else u({locale:n.value,text:n.innerText,name:a(n).data("language-name"),flagUrl:a(n).data("flag-html")}),t.show(),m(a("#lang_list-button"))}),e.on("submit",function(n){var t,l=i.children().length>0,s=a("#lang_list").val();return o.size<=0&&!l?(""===s?(p(pll_wizard_params.i18n_no_language_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):(p(pll_wizard_params.i18n_add_language_needed),_(r.next("span.ui-selectmenu-button")),m(a("#add-language"))),!1):""!==s?(o.has(s)?(p(pll_wizard_params.i18n_language_already_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):g.dialog("open"),!1):((t=d).prop("disabled",!0),void e.append(a("<input />").prop({type:"hidden",name:t.prop("name"),value:t.prop("value")})))});var h=new URLSearchParams(document.location.search);function f(n){switch(n){case"yes":var t=a("#lang_list").children(":selected");u({locale:t[0].value,text:t[0].innerText,name:a(t).data("language-name"),flagUrl:a(t).data("flag-html")});break;case"no":r.val("")}g.dialog("close"),"ignore"===n?m(a("#lang_list-button")):e.submit()}h.has("activate_error")&&void 0!==pll_wizard_params[h.get("activate_error")]&&p(pll_wizard_params[h.get("activate_error")]),g.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:pll_wizard_params.i18n_dialog_title,minWidth:600,maxWidth:"100%",open:function(e,n){a("body").hasClass("rtl")&&a(this).parent().css({right:a(this).parent().css("left"),left:"auto"}),a(this).find("#dialog-language").text(a("#lang_list").children(":selected")[0].innerText),a(this).find("#dialog-language-flag").empty().prepend(a("#lang_list").children(":selected").data("flag-html"))},buttons:[{text:pll_wizard_params.i18n_dialog_yes_button,click:function(a){f("yes")}},{text:pll_wizard_params.i18n_dialog_no_button,click:function(a){f("no")}},{text:pll_wizard_params.i18n_dialog_ignore_button,click:function(a){f("ignore")}}]})});
|
|
modules/wizard/wizard.php
CHANGED
@@ -10,36 +10,43 @@
|
|
10 |
*/
|
11 |
class PLL_Wizard {
|
12 |
/**
|
13 |
-
* Reference to
|
14 |
*
|
15 |
-
* @var
|
16 |
*/
|
17 |
protected $model;
|
18 |
|
19 |
/**
|
20 |
-
* Reference to Polylang options array
|
21 |
*
|
22 |
-
* @var array
|
23 |
*/
|
24 |
protected $options;
|
25 |
|
26 |
/**
|
27 |
-
* List of steps
|
28 |
*
|
29 |
* @var array $steps {
|
30 |
-
* @type string
|
31 |
* @type callable $view The callback function use to display the step content.
|
32 |
* @type callable $handler The callback function use to process the step after it is submitted.
|
33 |
-
* @type array
|
34 |
-
* @type array
|
35 |
* }
|
36 |
*/
|
37 |
protected $steps = array();
|
38 |
|
39 |
/**
|
40 |
-
*
|
41 |
*
|
42 |
-
* @var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
*/
|
44 |
protected $styles = array();
|
45 |
|
@@ -73,8 +80,10 @@ class PLL_Wizard {
|
|
73 |
/**
|
74 |
* Save an activation transient when Polylang is activating to redirect to the wizard
|
75 |
*
|
76 |
-
* @param bool $network_wide if activated for all sites in the network.
|
77 |
* @since 2.7
|
|
|
|
|
|
|
78 |
*/
|
79 |
public static function start_wizard( $network_wide ) {
|
80 |
$options = get_option( 'polylang' );
|
@@ -89,6 +98,8 @@ class PLL_Wizard {
|
|
89 |
* Redirect to the wizard depending on the context
|
90 |
*
|
91 |
* @since 2.7
|
|
|
|
|
92 |
*/
|
93 |
public function redirect_to_wizard() {
|
94 |
if ( get_transient( 'pll_activation_redirect' ) ) {
|
@@ -117,9 +128,10 @@ class PLL_Wizard {
|
|
117 |
/**
|
118 |
* Add an admin Polylang submenu to access the wizard
|
119 |
*
|
120 |
-
* @param array $tabs Submenus list.
|
121 |
-
* @return array Submenus list updated.
|
122 |
* @since 2.7
|
|
|
|
|
|
|
123 |
*/
|
124 |
public function settings_tabs( $tabs ) {
|
125 |
$tabs['wizard'] = esc_html__( 'Setup', 'polylang' );
|
@@ -127,11 +139,12 @@ class PLL_Wizard {
|
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
-
*
|
131 |
*
|
132 |
-
* @param array $languages List of language objects.
|
133 |
-
* @return bool
|
134 |
* @since 2.7
|
|
|
|
|
|
|
135 |
*/
|
136 |
public function is_media_step_displayable( $languages ) {
|
137 |
$media = array();
|
@@ -154,8 +167,9 @@ class PLL_Wizard {
|
|
154 |
/**
|
155 |
* Check if the licenses step is displayable
|
156 |
*
|
157 |
-
* @return bool
|
158 |
* @since 2.7
|
|
|
|
|
159 |
*/
|
160 |
public function is_licenses_step_displayable() {
|
161 |
$licenses = apply_filters( 'pll_settings_licenses', array() );
|
@@ -166,6 +180,8 @@ class PLL_Wizard {
|
|
166 |
* Setup the wizard page
|
167 |
*
|
168 |
* @since 2.7
|
|
|
|
|
169 |
*/
|
170 |
public function setup_wizard_page() {
|
171 |
|
@@ -213,15 +229,16 @@ class PLL_Wizard {
|
|
213 |
/**
|
214 |
* Adds some admin screens where to display the wizard notice
|
215 |
*
|
|
|
|
|
216 |
* @param bool $can_display_notice Whether the notice can be displayed.
|
217 |
* @param string $notice The notice name.
|
218 |
* @return bool
|
219 |
-
* @since 2.7
|
220 |
*/
|
221 |
public function can_display_notice( $can_display_notice, $notice ) {
|
222 |
if ( ! $can_display_notice && 'wizard' === $notice ) {
|
223 |
$screen = get_current_screen();
|
224 |
-
$can_display_notice = in_array(
|
225 |
$screen->base,
|
226 |
array(
|
227 |
'edit',
|
@@ -237,6 +254,8 @@ class PLL_Wizard {
|
|
237 |
* Return html code of the wizard notice
|
238 |
*
|
239 |
* @since 2.7
|
|
|
|
|
240 |
*/
|
241 |
public function wizard_notice() {
|
242 |
ob_start();
|
@@ -248,6 +267,8 @@ class PLL_Wizard {
|
|
248 |
* Display the wizard page
|
249 |
*
|
250 |
* @since 2.7
|
|
|
|
|
251 |
*/
|
252 |
public function display_wizard_page() {
|
253 |
set_current_screen();
|
@@ -258,10 +279,12 @@ class PLL_Wizard {
|
|
258 |
* Enqueue scripts and styles for the wizard
|
259 |
*
|
260 |
* @since 2.7
|
|
|
|
|
261 |
*/
|
262 |
public function enqueue_scripts() {
|
263 |
-
wp_enqueue_style( 'polylang_admin', plugins_url( '/css/admin' . $this->get_suffix() . '.css',
|
264 |
-
wp_enqueue_style( 'pll-wizard', plugins_url( '/
|
265 |
|
266 |
$this->styles = array( 'polylang_admin', 'pll-wizard' );
|
267 |
}
|
@@ -269,9 +292,10 @@ class PLL_Wizard {
|
|
269 |
/**
|
270 |
* Get the suffix to enqueue non minified files in a Debug context
|
271 |
*
|
|
|
|
|
272 |
* @return string Empty when SCRIPT_DEBUG equal to true
|
273 |
* otherwise .min
|
274 |
-
* @since 2.7
|
275 |
*/
|
276 |
public function get_suffix() {
|
277 |
return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
@@ -280,10 +304,11 @@ class PLL_Wizard {
|
|
280 |
/**
|
281 |
* Get the URL for the step's screen.
|
282 |
*
|
|
|
|
|
283 |
* @param string $step slug (default: current step).
|
284 |
* @return string URL for the step if it exists.
|
285 |
* Empty string on failure.
|
286 |
-
* @since 2.7
|
287 |
*/
|
288 |
public function get_step_link( $step = '' ) {
|
289 |
if ( ! $step ) {
|
@@ -303,11 +328,12 @@ class PLL_Wizard {
|
|
303 |
/**
|
304 |
* Get the URL for the next step's screen.
|
305 |
*
|
|
|
|
|
306 |
* @param string $step slug (default: current step).
|
307 |
* @return string URL for next step if a next step exists.
|
308 |
* Admin URL if it's the last step.
|
309 |
* Empty string on failure.
|
310 |
-
* @since 2.7
|
311 |
*/
|
312 |
public function get_next_step_link( $step = '' ) {
|
313 |
if ( ! $step ) {
|
@@ -330,16 +356,20 @@ class PLL_Wizard {
|
|
330 |
/**
|
331 |
* Add licenses step to the wizard
|
332 |
*
|
|
|
|
|
333 |
* @param array $steps List of steps.
|
334 |
* @return array List of steps updated.
|
335 |
-
* @since 2.7
|
336 |
*/
|
337 |
public function add_step_licenses( $steps ) {
|
338 |
// Add ajax action on deactivate button in licenses step.
|
339 |
add_action( 'wp_ajax_pll_deactivate_license', array( $this, 'deactivate_license' ) );
|
340 |
|
341 |
-
|
342 |
-
|
|
|
|
|
|
|
343 |
if ( $this->is_licenses_step_displayable() ) {
|
344 |
$steps['licenses'] = array(
|
345 |
'name' => esc_html__( 'Licenses', 'polylang' ),
|
@@ -356,6 +386,8 @@ class PLL_Wizard {
|
|
356 |
* Display the languages step form
|
357 |
*
|
358 |
* @since 2.7
|
|
|
|
|
359 |
*/
|
360 |
public function display_step_licenses() {
|
361 |
include __DIR__ . '/view-wizard-step-licenses.php';
|
@@ -365,6 +397,8 @@ class PLL_Wizard {
|
|
365 |
* Execute the languages step
|
366 |
*
|
367 |
* @since 2.7
|
|
|
|
|
368 |
*/
|
369 |
public function save_step_licenses() {
|
370 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -395,6 +429,8 @@ class PLL_Wizard {
|
|
395 |
* Ajax method to deactivate a license
|
396 |
*
|
397 |
* @since 2.7
|
|
|
|
|
398 |
*/
|
399 |
public function deactivate_license() {
|
400 |
check_ajax_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -423,14 +459,18 @@ class PLL_Wizard {
|
|
423 |
/**
|
424 |
* Add languages step to the wizard
|
425 |
*
|
|
|
|
|
426 |
* @param array $steps List of steps.
|
427 |
* @return array List of steps updated.
|
428 |
-
* @since 2.7
|
429 |
*/
|
430 |
public function add_step_languages( $steps ) {
|
431 |
-
|
432 |
-
|
433 |
-
|
|
|
|
|
|
|
434 |
wp_localize_script(
|
435 |
'pll-wizard-languages',
|
436 |
'pll_wizard_params',
|
@@ -453,12 +493,12 @@ class PLL_Wizard {
|
|
453 |
)
|
454 |
);
|
455 |
wp_enqueue_script( 'pll-wizard-languages' );
|
456 |
-
wp_enqueue_style( 'pll-wizard-selectmenu', plugins_url( '/css/selectmenu' . $this->get_suffix() . '.css',
|
457 |
$steps['languages'] = array(
|
458 |
'name' => esc_html__( 'Languages', 'polylang' ),
|
459 |
'view' => array( $this, 'display_step_languages' ),
|
460 |
'handler' => array( $this, 'save_step_languages' ),
|
461 |
-
'scripts' => array( 'pll-wizard-languages', '
|
462 |
'styles' => array( 'pll-wizard-selectmenu' ),
|
463 |
);
|
464 |
return $steps;
|
@@ -468,6 +508,8 @@ class PLL_Wizard {
|
|
468 |
* Display the languages step form
|
469 |
*
|
470 |
* @since 2.7
|
|
|
|
|
471 |
*/
|
472 |
public function display_step_languages() {
|
473 |
include __DIR__ . '/view-wizard-step-languages.php';
|
@@ -477,6 +519,8 @@ class PLL_Wizard {
|
|
477 |
* Execute the languages step
|
478 |
*
|
479 |
* @since 2.7
|
|
|
|
|
480 |
*/
|
481 |
public function save_step_languages() {
|
482 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -484,7 +528,7 @@ class PLL_Wizard {
|
|
484 |
$existing_languages = $this->model->get_languages_list();
|
485 |
|
486 |
$all_languages = include POLYLANG_DIR . '/settings/languages.php';
|
487 |
-
$languages = isset( $_POST['languages'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['languages'] ) ) : false;
|
488 |
$saved_languages = array();
|
489 |
|
490 |
// If there is no language added or defined.
|
@@ -550,12 +594,12 @@ class PLL_Wizard {
|
|
550 |
}
|
551 |
|
552 |
/**
|
553 |
-
* Add media step to the wizard
|
554 |
-
*
|
|
|
555 |
*
|
556 |
* @param array $steps List of steps.
|
557 |
* @return array List of steps updated.
|
558 |
-
* @since 2.7
|
559 |
*/
|
560 |
public function add_step_media( $steps ) {
|
561 |
$languages = $this->model->get_languages_list();
|
@@ -576,6 +620,8 @@ class PLL_Wizard {
|
|
576 |
* Display the media step form
|
577 |
*
|
578 |
* @since 2.7
|
|
|
|
|
579 |
*/
|
580 |
public function display_step_media() {
|
581 |
include __DIR__ . '/view-wizard-step-media.php';
|
@@ -585,6 +631,8 @@ class PLL_Wizard {
|
|
585 |
* Execute the media step
|
586 |
*
|
587 |
* @since 2.7
|
|
|
|
|
588 |
*/
|
589 |
public function save_step_media() {
|
590 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -602,20 +650,23 @@ class PLL_Wizard {
|
|
602 |
/**
|
603 |
* Add untranslated contents step to the wizard
|
604 |
*
|
|
|
|
|
605 |
* @param array $steps List of steps.
|
606 |
* @return array List of steps updated.
|
607 |
-
* @since 2.7
|
608 |
*/
|
609 |
public function add_step_untranslated_contents( $steps ) {
|
610 |
if ( ! $this->model->get_languages_list() || $this->model->get_objects_with_no_lang( 1 ) ) {
|
611 |
-
|
612 |
-
|
613 |
-
|
|
|
|
|
614 |
$steps['untranslated-contents'] = array(
|
615 |
'name' => esc_html__( 'Content', 'polylang' ),
|
616 |
'view' => array( $this, 'display_step_untranslated_contents' ),
|
617 |
'handler' => array( $this, 'save_step_untranslated_contents' ),
|
618 |
-
'scripts' => array( '
|
619 |
'styles' => array( 'pll-wizard-selectmenu' ),
|
620 |
);
|
621 |
}
|
@@ -626,6 +677,8 @@ class PLL_Wizard {
|
|
626 |
* Display the untranslated contents step form
|
627 |
*
|
628 |
* @since 2.7
|
|
|
|
|
629 |
*/
|
630 |
public function display_step_untranslated_contents() {
|
631 |
include __DIR__ . '/view-wizard-step-untranslated-contents.php';
|
@@ -635,6 +688,8 @@ class PLL_Wizard {
|
|
635 |
* Execute the untranslated contents step
|
636 |
*
|
637 |
* @since 2.7
|
|
|
|
|
638 |
*/
|
639 |
public function save_step_untranslated_contents() {
|
640 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -663,9 +718,10 @@ class PLL_Wizard {
|
|
663 |
/**
|
664 |
* Add home page step to the wizard
|
665 |
*
|
|
|
|
|
666 |
* @param array $steps List of steps.
|
667 |
* @return array List of steps updated.
|
668 |
-
* @since 2.7
|
669 |
*/
|
670 |
public function add_step_home_page( $steps ) {
|
671 |
$languages = $this->model->get_languages_list();
|
@@ -689,6 +745,8 @@ class PLL_Wizard {
|
|
689 |
* Display the home page step form
|
690 |
*
|
691 |
* @since 2.7
|
|
|
|
|
692 |
*/
|
693 |
public function display_step_home_page() {
|
694 |
include __DIR__ . '/view-wizard-step-home-page.php';
|
@@ -698,6 +756,8 @@ class PLL_Wizard {
|
|
698 |
* Execute the home page step
|
699 |
*
|
700 |
* @since 2.7
|
|
|
|
|
701 |
*/
|
702 |
public function save_step_home_page() {
|
703 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
@@ -731,11 +791,12 @@ class PLL_Wizard {
|
|
731 |
*
|
732 |
* @since 2.7
|
733 |
*
|
734 |
-
* @param string
|
735 |
-
* @param int
|
736 |
-
* @param string
|
737 |
-
* @param string
|
738 |
-
* @param
|
|
|
739 |
*/
|
740 |
public function create_home_page_translations( $default_language, $home_page, $home_page_title, $home_page_language, $untranslated_languages ) {
|
741 |
$translations = $this->model->post->get_translations( $home_page );
|
@@ -758,9 +819,10 @@ class PLL_Wizard {
|
|
758 |
/**
|
759 |
* Add last step to the wizard
|
760 |
*
|
|
|
|
|
761 |
* @param array $steps List of steps.
|
762 |
* @return array List of steps updated.
|
763 |
-
* @since 2.7
|
764 |
*/
|
765 |
public function add_step_last( $steps ) {
|
766 |
$steps['last'] = array(
|
@@ -777,6 +839,8 @@ class PLL_Wizard {
|
|
777 |
* Display the last step form
|
778 |
*
|
779 |
* @since 2.7
|
|
|
|
|
780 |
*/
|
781 |
public function display_step_last() {
|
782 |
// We ran the wizard once. So we can dismiss its notice.
|
@@ -788,6 +852,8 @@ class PLL_Wizard {
|
|
788 |
* Execute the last step
|
789 |
*
|
790 |
* @since 2.7
|
|
|
|
|
791 |
*/
|
792 |
public function save_step_last() {
|
793 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
10 |
*/
|
11 |
class PLL_Wizard {
|
12 |
/**
|
13 |
+
* Reference to the model object
|
14 |
*
|
15 |
+
* @var PLL_Admin_Model
|
16 |
*/
|
17 |
protected $model;
|
18 |
|
19 |
/**
|
20 |
+
* Reference to the Polylang options array.
|
21 |
*
|
22 |
+
* @var array
|
23 |
*/
|
24 |
protected $options;
|
25 |
|
26 |
/**
|
27 |
+
* List of steps.
|
28 |
*
|
29 |
* @var array $steps {
|
30 |
+
* @type string $name I18n string which names the step.
|
31 |
* @type callable $view The callback function use to display the step content.
|
32 |
* @type callable $handler The callback function use to process the step after it is submitted.
|
33 |
+
* @type array $scripts List of scripts handle needed by the step.
|
34 |
+
* @type array $styles The list of styles handle needed by the step.
|
35 |
* }
|
36 |
*/
|
37 |
protected $steps = array();
|
38 |
|
39 |
/**
|
40 |
+
* The current step.
|
41 |
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
protected $step;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* List of WordPress CSS file handles.
|
48 |
+
*
|
49 |
+
* @var string[]
|
50 |
*/
|
51 |
protected $styles = array();
|
52 |
|
80 |
/**
|
81 |
* Save an activation transient when Polylang is activating to redirect to the wizard
|
82 |
*
|
|
|
83 |
* @since 2.7
|
84 |
+
*
|
85 |
+
* @param bool $network_wide if activated for all sites in the network.
|
86 |
+
* @return void
|
87 |
*/
|
88 |
public static function start_wizard( $network_wide ) {
|
89 |
$options = get_option( 'polylang' );
|
98 |
* Redirect to the wizard depending on the context
|
99 |
*
|
100 |
* @since 2.7
|
101 |
+
*
|
102 |
+
* @return void
|
103 |
*/
|
104 |
public function redirect_to_wizard() {
|
105 |
if ( get_transient( 'pll_activation_redirect' ) ) {
|
128 |
/**
|
129 |
* Add an admin Polylang submenu to access the wizard
|
130 |
*
|
|
|
|
|
131 |
* @since 2.7
|
132 |
+
*
|
133 |
+
* @param string[] $tabs Submenus list.
|
134 |
+
* @return string[] Submenus list updated.
|
135 |
*/
|
136 |
public function settings_tabs( $tabs ) {
|
137 |
$tabs['wizard'] = esc_html__( 'Setup', 'polylang' );
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
+
* Returns true if the media step is displayable, false otherwise.
|
143 |
*
|
|
|
|
|
144 |
* @since 2.7
|
145 |
+
*
|
146 |
+
* @param PLL_Language[] $languages List of language objects.
|
147 |
+
* @return bool
|
148 |
*/
|
149 |
public function is_media_step_displayable( $languages ) {
|
150 |
$media = array();
|
167 |
/**
|
168 |
* Check if the licenses step is displayable
|
169 |
*
|
|
|
170 |
* @since 2.7
|
171 |
+
*
|
172 |
+
* @return bool
|
173 |
*/
|
174 |
public function is_licenses_step_displayable() {
|
175 |
$licenses = apply_filters( 'pll_settings_licenses', array() );
|
180 |
* Setup the wizard page
|
181 |
*
|
182 |
* @since 2.7
|
183 |
+
*
|
184 |
+
* @return void
|
185 |
*/
|
186 |
public function setup_wizard_page() {
|
187 |
|
229 |
/**
|
230 |
* Adds some admin screens where to display the wizard notice
|
231 |
*
|
232 |
+
* @since 2.7
|
233 |
+
*
|
234 |
* @param bool $can_display_notice Whether the notice can be displayed.
|
235 |
* @param string $notice The notice name.
|
236 |
* @return bool
|
|
|
237 |
*/
|
238 |
public function can_display_notice( $can_display_notice, $notice ) {
|
239 |
if ( ! $can_display_notice && 'wizard' === $notice ) {
|
240 |
$screen = get_current_screen();
|
241 |
+
$can_display_notice = ! empty( $screen ) && in_array(
|
242 |
$screen->base,
|
243 |
array(
|
244 |
'edit',
|
254 |
* Return html code of the wizard notice
|
255 |
*
|
256 |
* @since 2.7
|
257 |
+
*
|
258 |
+
* @return string
|
259 |
*/
|
260 |
public function wizard_notice() {
|
261 |
ob_start();
|
267 |
* Display the wizard page
|
268 |
*
|
269 |
* @since 2.7
|
270 |
+
*
|
271 |
+
* @return void
|
272 |
*/
|
273 |
public function display_wizard_page() {
|
274 |
set_current_screen();
|
279 |
* Enqueue scripts and styles for the wizard
|
280 |
*
|
281 |
* @since 2.7
|
282 |
+
*
|
283 |
+
* @return void
|
284 |
*/
|
285 |
public function enqueue_scripts() {
|
286 |
+
wp_enqueue_style( 'polylang_admin', plugins_url( '/css/build/admin' . $this->get_suffix() . '.css', POLYLANG_BASENAME ), array(), POLYLANG_VERSION );
|
287 |
+
wp_enqueue_style( 'pll-wizard', plugins_url( '/css/build/wizard' . $this->get_suffix() . '.css', POLYLANG_BASENAME ), array( 'dashicons', 'install', 'common', 'forms' ), POLYLANG_VERSION );
|
288 |
|
289 |
$this->styles = array( 'polylang_admin', 'pll-wizard' );
|
290 |
}
|
292 |
/**
|
293 |
* Get the suffix to enqueue non minified files in a Debug context
|
294 |
*
|
295 |
+
* @since 2.7
|
296 |
+
*
|
297 |
* @return string Empty when SCRIPT_DEBUG equal to true
|
298 |
* otherwise .min
|
|
|
299 |
*/
|
300 |
public function get_suffix() {
|
301 |
return defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
304 |
/**
|
305 |
* Get the URL for the step's screen.
|
306 |
*
|
307 |
+
* @since 2.7
|
308 |
+
*
|
309 |
* @param string $step slug (default: current step).
|
310 |
* @return string URL for the step if it exists.
|
311 |
* Empty string on failure.
|
|
|
312 |
*/
|
313 |
public function get_step_link( $step = '' ) {
|
314 |
if ( ! $step ) {
|
328 |
/**
|
329 |
* Get the URL for the next step's screen.
|
330 |
*
|
331 |
+
* @since 2.7
|
332 |
+
*
|
333 |
* @param string $step slug (default: current step).
|
334 |
* @return string URL for next step if a next step exists.
|
335 |
* Admin URL if it's the last step.
|
336 |
* Empty string on failure.
|
|
|
337 |
*/
|
338 |
public function get_next_step_link( $step = '' ) {
|
339 |
if ( ! $step ) {
|
356 |
/**
|
357 |
* Add licenses step to the wizard
|
358 |
*
|
359 |
+
* @since 2.7
|
360 |
+
*
|
361 |
* @param array $steps List of steps.
|
362 |
* @return array List of steps updated.
|
|
|
363 |
*/
|
364 |
public function add_step_licenses( $steps ) {
|
365 |
// Add ajax action on deactivate button in licenses step.
|
366 |
add_action( 'wp_ajax_pll_deactivate_license', array( $this, 'deactivate_license' ) );
|
367 |
|
368 |
+
// Be careful pll_admin script is enqueued here without depedency except jquery because only code useful for deactivate license button is needed.
|
369 |
+
// To be really loaded the script need to be passed to the $steps['licenses']['scripts'] array below with the same handle than in wp_enqueue_script().
|
370 |
+
wp_enqueue_script( 'pll_admin', plugins_url( '/js/build/admin' . $this->get_suffix() . '.js', POLYLANG_BASENAME ), array( 'jquery' ), POLYLANG_VERSION, true );
|
371 |
+
wp_localize_script( 'pll_admin', 'pll_admin', array( 'dismiss_notice' => esc_html__( 'Dismiss this notice.', 'polylang' ) ) );
|
372 |
+
|
373 |
if ( $this->is_licenses_step_displayable() ) {
|
374 |
$steps['licenses'] = array(
|
375 |
'name' => esc_html__( 'Licenses', 'polylang' ),
|
386 |
* Display the languages step form
|
387 |
*
|
388 |
* @since 2.7
|
389 |
+
*
|
390 |
+
* @return void
|
391 |
*/
|
392 |
public function display_step_licenses() {
|
393 |
include __DIR__ . '/view-wizard-step-licenses.php';
|
397 |
* Execute the languages step
|
398 |
*
|
399 |
* @since 2.7
|
400 |
+
*
|
401 |
+
* @return void
|
402 |
*/
|
403 |
public function save_step_licenses() {
|
404 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
429 |
* Ajax method to deactivate a license
|
430 |
*
|
431 |
* @since 2.7
|
432 |
+
*
|
433 |
+
* @return void
|
434 |
*/
|
435 |
public function deactivate_license() {
|
436 |
check_ajax_referer( 'pll-wizard', '_pll_nonce' );
|
459 |
/**
|
460 |
* Add languages step to the wizard
|
461 |
*
|
462 |
+
* @since 2.7
|
463 |
+
*
|
464 |
* @param array $steps List of steps.
|
465 |
* @return array List of steps updated.
|
|
|
466 |
*/
|
467 |
public function add_step_languages( $steps ) {
|
468 |
+
wp_deregister_script( 'pll_admin' ); // Deregister after the licenses step enqueue to update jquery-ui-selectmenu dependency.
|
469 |
+
// The wp-ajax-response and postbox dependencies is useless in wizard steps espacially postbox which triggers a javascript error otherwise.
|
470 |
+
// To be really loaded the script need to be passed to the $steps['languages']['scripts'] array below with the same handle than in wp_enqueue_script().
|
471 |
+
wp_enqueue_script( 'pll_admin', plugins_url( '/js/build/admin' . $this->get_suffix() . '.js', POLYLANG_BASENAME ), array( 'jquery', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
|
472 |
+
wp_localize_script( 'pll_admin', 'pll_admin', array( 'dismiss_notice' => esc_html__( 'Dismiss this notice.', 'polylang' ) ) );
|
473 |
+
wp_register_script( 'pll-wizard-languages', plugins_url( '/js/build/languages-step' . $this->get_suffix() . '.js', POLYLANG_BASENAME ), array( 'jquery', 'jquery-ui-dialog' ), POLYLANG_VERSION, true );
|
474 |
wp_localize_script(
|
475 |
'pll-wizard-languages',
|
476 |
'pll_wizard_params',
|
493 |
)
|
494 |
);
|
495 |
wp_enqueue_script( 'pll-wizard-languages' );
|
496 |
+
wp_enqueue_style( 'pll-wizard-selectmenu', plugins_url( '/css/build/selectmenu' . $this->get_suffix() . '.css', POLYLANG_BASENAME ), array( 'dashicons', 'install', 'common', 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
|
497 |
$steps['languages'] = array(
|
498 |
'name' => esc_html__( 'Languages', 'polylang' ),
|
499 |
'view' => array( $this, 'display_step_languages' ),
|
500 |
'handler' => array( $this, 'save_step_languages' ),
|
501 |
+
'scripts' => array( 'pll-wizard-languages', 'pll_admin' ),
|
502 |
'styles' => array( 'pll-wizard-selectmenu' ),
|
503 |
);
|
504 |
return $steps;
|
508 |
* Display the languages step form
|
509 |
*
|
510 |
* @since 2.7
|
511 |
+
*
|
512 |
+
* @return void
|
513 |
*/
|
514 |
public function display_step_languages() {
|
515 |
include __DIR__ . '/view-wizard-step-languages.php';
|
519 |
* Execute the languages step
|
520 |
*
|
521 |
* @since 2.7
|
522 |
+
*
|
523 |
+
* @return void
|
524 |
*/
|
525 |
public function save_step_languages() {
|
526 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
528 |
$existing_languages = $this->model->get_languages_list();
|
529 |
|
530 |
$all_languages = include POLYLANG_DIR . '/settings/languages.php';
|
531 |
+
$languages = isset( $_POST['languages'] ) && is_array( $_POST['languages'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['languages'] ) ) : false;
|
532 |
$saved_languages = array();
|
533 |
|
534 |
// If there is no language added or defined.
|
594 |
}
|
595 |
|
596 |
/**
|
597 |
+
* Add the media step to the wizard.
|
598 |
+
*
|
599 |
+
* @since 2.7
|
600 |
*
|
601 |
* @param array $steps List of steps.
|
602 |
* @return array List of steps updated.
|
|
|
603 |
*/
|
604 |
public function add_step_media( $steps ) {
|
605 |
$languages = $this->model->get_languages_list();
|
620 |
* Display the media step form
|
621 |
*
|
622 |
* @since 2.7
|
623 |
+
*
|
624 |
+
* @return void
|
625 |
*/
|
626 |
public function display_step_media() {
|
627 |
include __DIR__ . '/view-wizard-step-media.php';
|
631 |
* Execute the media step
|
632 |
*
|
633 |
* @since 2.7
|
634 |
+
*
|
635 |
+
* @return void
|
636 |
*/
|
637 |
public function save_step_media() {
|
638 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
650 |
/**
|
651 |
* Add untranslated contents step to the wizard
|
652 |
*
|
653 |
+
* @since 2.7
|
654 |
+
*
|
655 |
* @param array $steps List of steps.
|
656 |
* @return array List of steps updated.
|
|
|
657 |
*/
|
658 |
public function add_step_untranslated_contents( $steps ) {
|
659 |
if ( ! $this->model->get_languages_list() || $this->model->get_objects_with_no_lang( 1 ) ) {
|
660 |
+
// Even if pll_admin is already enqueued with the same dependencies by the languages step, it is interesting to keep that it's also useful for the untranslated-contents step.
|
661 |
+
// To be really loaded the script need to be passed to the $steps['untranslated-contents']['scripts'] array below with the same handle than in wp_enqueue_script().
|
662 |
+
wp_enqueue_script( 'pll_admin', plugins_url( '/js/build/admin' . $this->get_suffix() . '.js', POLYLANG_BASENAME ), array( 'jquery', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
|
663 |
+
wp_localize_script( 'pll_admin', 'pll_admin', array( 'dismiss_notice' => esc_html__( 'Dismiss this notice.', 'polylang' ) ) );
|
664 |
+
wp_enqueue_style( 'pll-wizard-selectmenu', plugins_url( '/css/build/selectmenu' . $this->get_suffix() . '.css', POLYLANG_BASENAME ), array( 'dashicons', 'install', 'common' ), POLYLANG_VERSION );
|
665 |
$steps['untranslated-contents'] = array(
|
666 |
'name' => esc_html__( 'Content', 'polylang' ),
|
667 |
'view' => array( $this, 'display_step_untranslated_contents' ),
|
668 |
'handler' => array( $this, 'save_step_untranslated_contents' ),
|
669 |
+
'scripts' => array( 'pll_admin' ),
|
670 |
'styles' => array( 'pll-wizard-selectmenu' ),
|
671 |
);
|
672 |
}
|
677 |
* Display the untranslated contents step form
|
678 |
*
|
679 |
* @since 2.7
|
680 |
+
*
|
681 |
+
* @return void
|
682 |
*/
|
683 |
public function display_step_untranslated_contents() {
|
684 |
include __DIR__ . '/view-wizard-step-untranslated-contents.php';
|
688 |
* Execute the untranslated contents step
|
689 |
*
|
690 |
* @since 2.7
|
691 |
+
*
|
692 |
+
* @return void
|
693 |
*/
|
694 |
public function save_step_untranslated_contents() {
|
695 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
718 |
/**
|
719 |
* Add home page step to the wizard
|
720 |
*
|
721 |
+
* @since 2.7
|
722 |
+
*
|
723 |
* @param array $steps List of steps.
|
724 |
* @return array List of steps updated.
|
|
|
725 |
*/
|
726 |
public function add_step_home_page( $steps ) {
|
727 |
$languages = $this->model->get_languages_list();
|
745 |
* Display the home page step form
|
746 |
*
|
747 |
* @since 2.7
|
748 |
+
*
|
749 |
+
* @return void
|
750 |
*/
|
751 |
public function display_step_home_page() {
|
752 |
include __DIR__ . '/view-wizard-step-home-page.php';
|
756 |
* Execute the home page step
|
757 |
*
|
758 |
* @since 2.7
|
759 |
+
*
|
760 |
+
* @return void
|
761 |
*/
|
762 |
public function save_step_home_page() {
|
763 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
791 |
*
|
792 |
* @since 2.7
|
793 |
*
|
794 |
+
* @param string $default_language Slug of the default language; null if no default language is defined.
|
795 |
+
* @param int $home_page Post ID of the home page if it's defined, false otherwise.
|
796 |
+
* @param string $home_page_title Home page title if it's defined, 'Homepage' otherwise.
|
797 |
+
* @param string $home_page_language Slug of the home page if it's defined, false otherwise.
|
798 |
+
* @param string[] $untranslated_languages Array of languages which needs to have a home page translated.
|
799 |
+
* @return void
|
800 |
*/
|
801 |
public function create_home_page_translations( $default_language, $home_page, $home_page_title, $home_page_language, $untranslated_languages ) {
|
802 |
$translations = $this->model->post->get_translations( $home_page );
|
819 |
/**
|
820 |
* Add last step to the wizard
|
821 |
*
|
822 |
+
* @since 2.7
|
823 |
+
*
|
824 |
* @param array $steps List of steps.
|
825 |
* @return array List of steps updated.
|
|
|
826 |
*/
|
827 |
public function add_step_last( $steps ) {
|
828 |
$steps['last'] = array(
|
839 |
* Display the last step form
|
840 |
*
|
841 |
* @since 2.7
|
842 |
+
*
|
843 |
+
* @return void
|
844 |
*/
|
845 |
public function display_step_last() {
|
846 |
// We ran the wizard once. So we can dismiss its notice.
|
852 |
* Execute the last step
|
853 |
*
|
854 |
* @since 2.7
|
855 |
+
*
|
856 |
+
* @return void
|
857 |
*/
|
858 |
public function save_step_last() {
|
859 |
check_admin_referer( 'pll-wizard', '_pll_nonce' );
|
modules/wpml/wpml-api.php
CHANGED
@@ -12,6 +12,11 @@
|
|
12 |
* @since 2.0
|
13 |
*/
|
14 |
class PLL_WPML_API {
|
|
|
|
|
|
|
|
|
|
|
15 |
private static $original_language = null;
|
16 |
|
17 |
/**
|
@@ -143,6 +148,8 @@ class PLL_WPML_API {
|
|
143 |
* Returns an HTML hidden input field with name=”lang” and as value the current language
|
144 |
*
|
145 |
* @since 2.0
|
|
|
|
|
146 |
*/
|
147 |
public function wpml_add_language_form_field() {
|
148 |
$lang = pll_current_language();
|
@@ -184,6 +191,7 @@ class PLL_WPML_API {
|
|
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 ) {
|
@@ -218,8 +226,11 @@ class PLL_WPML_API {
|
|
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
|
222 |
-
$
|
|
|
|
|
|
|
223 |
}
|
224 |
return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code;
|
225 |
}
|
12 |
* @since 2.0
|
13 |
*/
|
14 |
class PLL_WPML_API {
|
15 |
+
/**
|
16 |
+
* Stores the original language when the language is switched.
|
17 |
+
*
|
18 |
+
* @var PLL_Language
|
19 |
+
*/
|
20 |
private static $original_language = null;
|
21 |
|
22 |
/**
|
148 |
* Returns an HTML hidden input field with name=”lang” and as value the current language
|
149 |
*
|
150 |
* @since 2.0
|
151 |
+
*
|
152 |
+
* @return void
|
153 |
*/
|
154 |
public function wpml_add_language_form_field() {
|
155 |
$lang = pll_current_language();
|
191 |
*
|
192 |
* @param null|string $lang Language code to switch into, restores the original language if null.
|
193 |
* @param bool|string $cookie Optionally also switches the cookie.
|
194 |
+
* @return void
|
195 |
*/
|
196 |
public static function wpml_switch_language( $lang = null, $cookie = false ) {
|
197 |
if ( null === self::$original_language ) {
|
226 |
$type = $args['element_type'];
|
227 |
$id = $args['element_id'];
|
228 |
$pll_type = ( 'post' == $type || pll_is_translated_post_type( $type ) ) ? 'post' : ( 'term' == $type || pll_is_translated_taxonomy( $type ) ? 'term' : false );
|
229 |
+
if ( 'term' === $pll_type ) {
|
230 |
+
$term = get_term_by( 'term_taxonomy_id', $id );
|
231 |
+
if ( $term instanceof WP_Term ) {
|
232 |
+
$id = $term->term_id;
|
233 |
+
}
|
234 |
}
|
235 |
return $pll_type ? call_user_func( "pll_get_{$pll_type}_language", $id ) : $language_code;
|
236 |
}
|
modules/wpml/wpml-compat.php
CHANGED
@@ -11,8 +11,23 @@
|
|
11 |
* @since 1.0.2
|
12 |
*/
|
13 |
class PLL_WPML_Compat {
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
public $api;
|
17 |
|
18 |
/**
|
@@ -37,7 +52,7 @@ class PLL_WPML_Compat {
|
|
37 |
*
|
38 |
* @since 1.7
|
39 |
*
|
40 |
-
* @return
|
41 |
*/
|
42 |
public static function instance() {
|
43 |
if ( empty( self::$instance ) ) {
|
@@ -52,6 +67,8 @@ class PLL_WPML_Compat {
|
|
52 |
* in 'setup_theme' by Polylang ( based on user info ) and 'plugins_loaded' by WPML ( based on cookie )
|
53 |
*
|
54 |
* @since 0.9.5
|
|
|
|
|
55 |
*/
|
56 |
public function define_constants() {
|
57 |
if ( ! empty( PLL()->curlang ) ) {
|
@@ -83,6 +100,7 @@ class PLL_WPML_Compat {
|
|
83 |
* @param string $context The group in which the string is registered.
|
84 |
* @param string $name A unique name for the string.
|
85 |
* @param string $string The string to register.
|
|
|
86 |
*/
|
87 |
public function register_string( $context, $name, $string ) {
|
88 |
// If a string has already been registered with the same name and context, let's replace it.
|
@@ -118,6 +136,7 @@ class PLL_WPML_Compat {
|
|
118 |
*
|
119 |
* @param string $context The group in which the string is registered.
|
120 |
* @param string $name A unique name for the string.
|
|
|
121 |
*/
|
122 |
public function unregister_string( $context, $name ) {
|
123 |
$key = md5( "$context | $name" );
|
11 |
* @since 1.0.2
|
12 |
*/
|
13 |
class PLL_WPML_Compat {
|
14 |
+
/**
|
15 |
+
* Singleton instance
|
16 |
+
*
|
17 |
+
* @var PLL_WPML_Compat
|
18 |
+
*/
|
19 |
+
protected static $instance;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Stores the strings registered with the WPML API.
|
23 |
+
*
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
protected static $strings;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var PLL_WPML_API
|
30 |
+
*/
|
31 |
public $api;
|
32 |
|
33 |
/**
|
52 |
*
|
53 |
* @since 1.7
|
54 |
*
|
55 |
+
* @return PLL_WPML_Compat
|
56 |
*/
|
57 |
public static function instance() {
|
58 |
if ( empty( self::$instance ) ) {
|
67 |
* in 'setup_theme' by Polylang ( based on user info ) and 'plugins_loaded' by WPML ( based on cookie )
|
68 |
*
|
69 |
* @since 0.9.5
|
70 |
+
*
|
71 |
+
* @return void
|
72 |
*/
|
73 |
public function define_constants() {
|
74 |
if ( ! empty( PLL()->curlang ) ) {
|
100 |
* @param string $context The group in which the string is registered.
|
101 |
* @param string $name A unique name for the string.
|
102 |
* @param string $string The string to register.
|
103 |
+
* @return void
|
104 |
*/
|
105 |
public function register_string( $context, $name, $string ) {
|
106 |
// If a string has already been registered with the same name and context, let's replace it.
|
136 |
*
|
137 |
* @param string $context The group in which the string is registered.
|
138 |
* @param string $name A unique name for the string.
|
139 |
+
* @return void
|
140 |
*/
|
141 |
public function unregister_string( $context, $name ) {
|
142 |
$key = md5( "$context | $name" );
|
modules/wpml/wpml-config.php
CHANGED
@@ -11,8 +11,19 @@
|
|
11 |
* @since 1.0
|
12 |
*/
|
13 |
class PLL_WPML_Config {
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
/**
|
18 |
* Constructor
|
@@ -43,6 +54,8 @@ class PLL_WPML_Config {
|
|
43 |
* Finds the wpml-config.xml files to parse and setup filters
|
44 |
*
|
45 |
* @since 1.0
|
|
|
|
|
46 |
*/
|
47 |
public function init() {
|
48 |
$this->xmls = array();
|
@@ -80,19 +93,24 @@ class PLL_WPML_Config {
|
|
80 |
add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
|
81 |
|
82 |
foreach ( $this->xmls as $context => $xml ) {
|
83 |
-
|
84 |
-
|
85 |
-
$
|
|
|
|
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
|
91 |
-
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
-
} else {
|
95 |
-
$this->register_or_translate_option( $context, $name, $key );
|
96 |
}
|
97 |
}
|
98 |
}
|
@@ -100,22 +118,25 @@ class PLL_WPML_Config {
|
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
-
* Adds custom fields to the list of metas to copy when creating a new translation
|
104 |
*
|
105 |
* @since 1.0
|
106 |
*
|
107 |
-
* @param
|
108 |
-
* @param bool
|
109 |
-
* @return
|
110 |
*/
|
111 |
public function copy_post_metas( $metas, $sync ) {
|
112 |
foreach ( $this->xmls as $xml ) {
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
$
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
119 |
}
|
120 |
}
|
121 |
}
|
@@ -123,22 +144,25 @@ class PLL_WPML_Config {
|
|
123 |
}
|
124 |
|
125 |
/**
|
126 |
-
* Adds term metas to the list of metas to copy when creating a new translation
|
127 |
*
|
128 |
* @since 2.6
|
129 |
*
|
130 |
-
* @param
|
131 |
-
* @param bool
|
132 |
-
* @return
|
133 |
*/
|
134 |
public function copy_term_metas( $metas, $sync ) {
|
135 |
foreach ( $this->xmls as $xml ) {
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
$
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
142 |
}
|
143 |
}
|
144 |
}
|
@@ -146,22 +170,25 @@ class PLL_WPML_Config {
|
|
146 |
}
|
147 |
|
148 |
/**
|
149 |
-
* Language and translation management for custom post types
|
150 |
*
|
151 |
* @since 1.0
|
152 |
*
|
153 |
-
* @param
|
154 |
-
* @param bool
|
155 |
-
* @return
|
156 |
*/
|
157 |
public function translate_types( $types, $hide ) {
|
158 |
foreach ( $this->xmls as $xml ) {
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
$
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
165 |
}
|
166 |
}
|
167 |
}
|
@@ -169,22 +196,25 @@ class PLL_WPML_Config {
|
|
169 |
}
|
170 |
|
171 |
/**
|
172 |
-
* Language and translation management for custom taxonomies
|
173 |
*
|
174 |
* @since 1.0
|
175 |
*
|
176 |
-
* @param
|
177 |
-
* @param bool
|
178 |
-
* @return
|
179 |
*/
|
180 |
public function translate_taxonomies( $taxonomies, $hide ) {
|
181 |
foreach ( $this->xmls as $xml ) {
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
$
|
186 |
-
|
187 |
-
|
|
|
|
|
|
|
188 |
}
|
189 |
}
|
190 |
}
|
@@ -199,6 +229,7 @@ class PLL_WPML_Config {
|
|
199 |
* @param string $context The group in which the strings will be registered.
|
200 |
* @param string $name Option name.
|
201 |
* @param object $key XML node.
|
|
|
202 |
*/
|
203 |
protected function register_or_translate_option( $context, $name, $key ) {
|
204 |
$option_keys = $this->xml_to_array( $key );
|
11 |
* @since 1.0
|
12 |
*/
|
13 |
class PLL_WPML_Config {
|
14 |
+
/**
|
15 |
+
* Singleton instance
|
16 |
+
*
|
17 |
+
* @var PLL_WPML_Config
|
18 |
+
*/
|
19 |
+
protected static $instance;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* The content of all read xml files.
|
23 |
+
*
|
24 |
+
* @var SimpleXMLElement[]
|
25 |
+
*/
|
26 |
+
protected $xmls;
|
27 |
|
28 |
/**
|
29 |
* Constructor
|
54 |
* Finds the wpml-config.xml files to parse and setup filters
|
55 |
*
|
56 |
* @since 1.0
|
57 |
+
*
|
58 |
+
* @return void
|
59 |
*/
|
60 |
public function init() {
|
61 |
$this->xmls = array();
|
93 |
add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
|
94 |
|
95 |
foreach ( $this->xmls as $context => $xml ) {
|
96 |
+
$keys = $xml->xpath( 'admin-texts/key' );
|
97 |
+
if ( is_array( $keys ) ) {
|
98 |
+
foreach ( $keys as $key ) {
|
99 |
+
$attributes = $key->attributes();
|
100 |
+
$name = (string) $attributes['name'];
|
101 |
|
102 |
+
if ( false !== strpos( $name, '*' ) ) {
|
103 |
+
$pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
|
104 |
+
$names = preg_grep( $pattern, array_keys( wp_load_alloptions() ) );
|
105 |
|
106 |
+
if ( is_array( $names ) ) {
|
107 |
+
foreach ( $names as $_name ) {
|
108 |
+
$this->register_or_translate_option( $context, $_name, $key );
|
109 |
+
}
|
110 |
+
}
|
111 |
+
} else {
|
112 |
+
$this->register_or_translate_option( $context, $name, $key );
|
113 |
}
|
|
|
|
|
114 |
}
|
115 |
}
|
116 |
}
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
+
* Adds custom fields to the list of metas to copy when creating a new translation.
|
122 |
*
|
123 |
* @since 1.0
|
124 |
*
|
125 |
+
* @param string[] $metas The list of custom fields to copy or synchronize.
|
126 |
+
* @param bool $sync True for sync, false for copy.
|
127 |
+
* @return string[] The list of custom fields to copy or synchronize.
|
128 |
*/
|
129 |
public function copy_post_metas( $metas, $sync ) {
|
130 |
foreach ( $this->xmls as $xml ) {
|
131 |
+
$cfs = $xml->xpath( 'custom-fields/custom-field' );
|
132 |
+
if ( is_array( $cfs ) ) {
|
133 |
+
foreach ( $cfs as $cf ) {
|
134 |
+
$attributes = $cf->attributes();
|
135 |
+
if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
|
136 |
+
$metas[] = (string) $cf;
|
137 |
+
} else {
|
138 |
+
$metas = array_diff( $metas, array( (string) $cf ) );
|
139 |
+
}
|
140 |
}
|
141 |
}
|
142 |
}
|
144 |
}
|
145 |
|
146 |
/**
|
147 |
+
* Adds term metas to the list of metas to copy when creating a new translation.
|
148 |
*
|
149 |
* @since 2.6
|
150 |
*
|
151 |
+
* @param string[] $metas The list of term metas to copy or synchronize.
|
152 |
+
* @param bool $sync True for sync, false for copy.
|
153 |
+
* @return string[] The list of term metas to copy or synchronize.
|
154 |
*/
|
155 |
public function copy_term_metas( $metas, $sync ) {
|
156 |
foreach ( $this->xmls as $xml ) {
|
157 |
+
$cfs = $xml->xpath( 'custom-term-fields/custom-term-field' );
|
158 |
+
if ( is_array( $cfs ) ) {
|
159 |
+
foreach ( $cfs as $cf ) {
|
160 |
+
$attributes = $cf->attributes();
|
161 |
+
if ( 'copy' == $attributes['action'] || ( ! $sync && in_array( $attributes['action'], array( 'translate', 'copy-once' ) ) ) ) {
|
162 |
+
$metas[] = (string) $cf;
|
163 |
+
} else {
|
164 |
+
$metas = array_diff( $metas, array( (string) $cf ) );
|
165 |
+
}
|
166 |
}
|
167 |
}
|
168 |
}
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
+
* Language and translation management for custom post types.
|
174 |
*
|
175 |
* @since 1.0
|
176 |
*
|
177 |
+
* @param string[] $types The list of post type names for which Polylang manages language and translations.
|
178 |
+
* @param bool $hide True when displaying the list in Polylang settings.
|
179 |
+
* @return string[] The list of post type names for which Polylang manages language and translations.
|
180 |
*/
|
181 |
public function translate_types( $types, $hide ) {
|
182 |
foreach ( $this->xmls as $xml ) {
|
183 |
+
$pts = $xml->xpath( 'custom-types/custom-type' );
|
184 |
+
if ( is_array( $pts ) ) {
|
185 |
+
foreach ( $pts as $pt ) {
|
186 |
+
$attributes = $pt->attributes();
|
187 |
+
if ( 1 == $attributes['translate'] && ! $hide ) {
|
188 |
+
$types[ (string) $pt ] = (string) $pt;
|
189 |
+
} else {
|
190 |
+
unset( $types[ (string) $pt ] ); // The theme/plugin author decided what to do with the post type so don't allow the user to change this
|
191 |
+
}
|
192 |
}
|
193 |
}
|
194 |
}
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* Language and translation management for custom taxonomies.
|
200 |
*
|
201 |
* @since 1.0
|
202 |
*
|
203 |
+
* @param string[] $taxonomies The list of taxonomy names for which Polylang manages language and translations.
|
204 |
+
* @param bool $hide True when displaying the list in Polylang settings.
|
205 |
+
* @return string[] The list of taxonomy names for which Polylang manages language and translations.
|
206 |
*/
|
207 |
public function translate_taxonomies( $taxonomies, $hide ) {
|
208 |
foreach ( $this->xmls as $xml ) {
|
209 |
+
$taxos = $xml->xpath( 'taxonomies/taxonomy' );
|
210 |
+
if ( is_array( $taxos ) ) {
|
211 |
+
foreach ( $taxos as $tax ) {
|
212 |
+
$attributes = $tax->attributes();
|
213 |
+
if ( 1 == $attributes['translate'] && ! $hide ) {
|
214 |
+
$taxonomies[ (string) $tax ] = (string) $tax;
|
215 |
+
} else {
|
216 |
+
unset( $taxonomies[ (string) $tax ] ); // the theme/plugin author decided what to do with the taxonomy so don't allow the user to change this
|
217 |
+
}
|
218 |
}
|
219 |
}
|
220 |
}
|
229 |
* @param string $context The group in which the strings will be registered.
|
230 |
* @param string $name Option name.
|
231 |
* @param object $key XML node.
|
232 |
+
* @return void
|
233 |
*/
|
234 |
protected function register_or_translate_option( $context, $name, $key ) {
|
235 |
$option_keys = $this->xml_to_array( $key );
|
modules/wpml/wpml-legacy-api.php
CHANGED
@@ -128,7 +128,7 @@ if ( ! function_exists( 'icl_link_to_element' ) ) {
|
|
128 |
}
|
129 |
} elseif ( taxonomy_exists( $type ) ) {
|
130 |
$link = get_term_link( $id, $type );
|
131 |
-
if ( empty( $text ) && ( $term = get_term( $id, $type ) ) &&
|
132 |
$text = $term->name;
|
133 |
}
|
134 |
}
|
@@ -167,7 +167,7 @@ if ( ! function_exists( 'icl_object_id' ) ) {
|
|
167 |
* @param string $lang Optional, language code, defaults to current language
|
168 |
* @return int|null The object id of the translation, null if the translation is missing and $return_original_if_missing set to false
|
169 |
*/
|
170 |
-
function icl_object_id( $id, $type = 'post', $return_original_if_missing = false, $lang =
|
171 |
$lang = $lang ? $lang : pll_current_language();
|
172 |
|
173 |
if ( 'nav_menu' === $type ) {
|
@@ -246,6 +246,7 @@ if ( ! function_exists( 'icl_register_string' ) ) {
|
|
246 |
* @param string $context the group in which the string is registered, defaults to 'polylang'
|
247 |
* @param string $name a unique name for the string
|
248 |
* @param string $string the string to register
|
|
|
249 |
*/
|
250 |
function icl_register_string( $context, $name, $string ) {
|
251 |
PLL_WPML_Compat::instance()->register_string( $context, $name, $string );
|
@@ -260,6 +261,7 @@ if ( ! function_exists( 'icl_unregister_string' ) ) {
|
|
260 |
*
|
261 |
* @param string $context the group in which the string is registered, defaults to 'polylang'
|
262 |
* @param string $name a unique name for the string
|
|
|
263 |
*/
|
264 |
function icl_unregister_string( $context, $name ) {
|
265 |
PLL_WPML_Compat::instance()->unregister_string( $context, $name );
|
@@ -282,7 +284,7 @@ if ( ! function_exists( 'icl_t' ) ) {
|
|
282 |
* @param string|null $lang optional, return the translation in this language, defaults to current language
|
283 |
* @return string the translated string
|
284 |
*/
|
285 |
-
function icl_t( $context, $name, $string =
|
286 |
return icl_translate( $context, $name, $string, false, $has_translation, $lang );
|
287 |
}
|
288 |
}
|
@@ -303,7 +305,7 @@ if ( ! function_exists( 'icl_translate' ) ) {
|
|
303 |
* @param string|null $lang optional, return the translation in this language, defaults to current language
|
304 |
* @return string the translated string
|
305 |
*/
|
306 |
-
function icl_translate( $context, $name, $string =
|
307 |
// FIXME WPML can automatically registers the string based on an option
|
308 |
if ( empty( $string ) ) {
|
309 |
$string = PLL_WPML_Compat::instance()->get_string_by_context_and_name( $context, $name );
|
128 |
}
|
129 |
} elseif ( taxonomy_exists( $type ) ) {
|
130 |
$link = get_term_link( $id, $type );
|
131 |
+
if ( empty( $text ) && ( $term = get_term( $id, $type ) ) && $term instanceof WP_Term ) {
|
132 |
$text = $term->name;
|
133 |
}
|
134 |
}
|
167 |
* @param string $lang Optional, language code, defaults to current language
|
168 |
* @return int|null The object id of the translation, null if the translation is missing and $return_original_if_missing set to false
|
169 |
*/
|
170 |
+
function icl_object_id( $id, $type = 'post', $return_original_if_missing = false, $lang = '' ) {
|
171 |
$lang = $lang ? $lang : pll_current_language();
|
172 |
|
173 |
if ( 'nav_menu' === $type ) {
|
246 |
* @param string $context the group in which the string is registered, defaults to 'polylang'
|
247 |
* @param string $name a unique name for the string
|
248 |
* @param string $string the string to register
|
249 |
+
* @return void
|
250 |
*/
|
251 |
function icl_register_string( $context, $name, $string ) {
|
252 |
PLL_WPML_Compat::instance()->register_string( $context, $name, $string );
|
261 |
*
|
262 |
* @param string $context the group in which the string is registered, defaults to 'polylang'
|
263 |
* @param string $name a unique name for the string
|
264 |
+
* @return void
|
265 |
*/
|
266 |
function icl_unregister_string( $context, $name ) {
|
267 |
PLL_WPML_Compat::instance()->unregister_string( $context, $name );
|
284 |
* @param string|null $lang optional, return the translation in this language, defaults to current language
|
285 |
* @return string the translated string
|
286 |
*/
|
287 |
+
function icl_t( $context, $name, $string = '', &$has_translation = null, $bool = false, $lang = null ) {
|
288 |
return icl_translate( $context, $name, $string, false, $has_translation, $lang );
|
289 |
}
|
290 |
}
|
305 |
* @param string|null $lang optional, return the translation in this language, defaults to current language
|
306 |
* @return string the translated string
|
307 |
*/
|
308 |
+
function icl_translate( $context, $name, $string = '', $bool = false, &$has_translation = null, $lang = null ) {
|
309 |
// FIXME WPML can automatically registers the string based on an option
|
310 |
if ( empty( $string ) ) {
|
311 |
$string = PLL_WPML_Compat::instance()->get_string_by_context_and_name( $context, $name );
|
polylang.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
* Plugin Name: Polylang
|
11 |
* Plugin URI: https://polylang.pro
|
12 |
* Description: Adds multilingual capability to WordPress
|
13 |
-
* Version:
|
14 |
* Requires at least: 5.1
|
15 |
* Requires PHP: 5.6
|
16 |
* Author: WP SYNTEX
|
@@ -53,7 +53,7 @@ if ( defined( 'POLYLANG_VERSION' ) ) {
|
|
53 |
}
|
54 |
} else {
|
55 |
// Go on loading the plugin
|
56 |
-
define( 'POLYLANG_VERSION', '
|
57 |
define( 'PLL_MIN_WP_VERSION', '5.1' );
|
58 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
59 |
|
10 |
* Plugin Name: Polylang
|
11 |
* Plugin URI: https://polylang.pro
|
12 |
* Description: Adds multilingual capability to WordPress
|
13 |
+
* Version: 3.0
|
14 |
* Requires at least: 5.1
|
15 |
* Requires PHP: 5.6
|
16 |
* Author: WP SYNTEX
|
53 |
}
|
54 |
} else {
|
55 |
// Go on loading the plugin
|
56 |
+
define( 'POLYLANG_VERSION', '3.0' );
|
57 |
define( 'PLL_MIN_WP_VERSION', '5.1' );
|
58 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
59 |
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: Chouby, manooweb, raaaahman, marianne38, sebastienserre
|
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
Requires at least: 5.1
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag:
|
9 |
License: GPLv3 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -78,6 +78,34 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
|
|
78 |
|
79 |
== Changelog ==
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
= 2.9.2 (2021-02-02) =
|
82 |
|
83 |
* Pro: Fix translation of CPTUI plural label and description not working
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
Requires at least: 5.1
|
6 |
+
Tested up to: 5.7
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 3.0
|
9 |
License: GPLv3 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
78 |
|
79 |
== Changelog ==
|
80 |
|
81 |
+
= 3.0 (2021-03-08) =
|
82 |
+
|
83 |
+
* Add compatibility with WordPress 5.7
|
84 |
+
* Remove upgrades from Polylang older than 1.8
|
85 |
+
* Remove deprecated class PLL_Pointer
|
86 |
+
* Pro: Hide the license keys
|
87 |
+
* Pro: Fix redirect to the home page of a deactivated language
|
88 |
+
* Pro: Fix synchronization of post status not working
|
89 |
+
* Pro: Fix language switcher block not working in a post retrieved in REST API
|
90 |
+
* Pro: Fix PO export of strings with line breaks
|
91 |
+
* Pro: Fix file block title customization lost
|
92 |
+
* Add a dialog box to ask a confirmation about a language change in classic and block editors
|
93 |
+
* Improve browser language detection #591
|
94 |
+
* Improve robustness and documentation of code
|
95 |
+
* Fix media library after the language has been chnaged in the editor metabox
|
96 |
+
* Fix duplicated title attribute on flag link in posts list
|
97 |
+
* Fix legacy block editor language metabox compatibility with WordPress 5.6
|
98 |
+
* Fix uploaded theme and plugin files in media library
|
99 |
+
* Fix site title not translated in email change confirmation email
|
100 |
+
* Fix remaining deprecated jQuery notices #741
|
101 |
+
* Fix compatibility with GN publisher
|
102 |
+
* Fix compatibility with Woodmart theme search form
|
103 |
+
* Fix compatibility issue with 3rd party ajax requests since jQuery 3.3 #744
|
104 |
+
* Fix CSS conflict with WooCommerce Bookings
|
105 |
+
* Fix browser error when displaying an embed and using a cache plugin #757
|
106 |
+
* Fix post type archive title and metadesc not translated in Yoast SEO
|
107 |
+
* Fix PHP notice in REST API
|
108 |
+
|
109 |
= 2.9.2 (2021-02-02) =
|
110 |
|
111 |
* Pro: Fix translation of CPTUI plural label and description not working
|
settings/settings-browser.php
CHANGED
@@ -67,6 +67,8 @@ class PLL_Settings_Browser extends PLL_Settings_Module {
|
|
67 |
* as the preferred browser language is not used when the language is set from different domains
|
68 |
*
|
69 |
* @since 1.8
|
|
|
|
|
70 |
*/
|
71 |
public function print_js() {
|
72 |
wp_enqueue_script( 'jquery' );
|
67 |
* as the preferred browser language is not used when the language is set from different domains
|
68 |
*
|
69 |
* @since 1.8
|
70 |
+
*
|
71 |
+
* @return void
|
72 |
*/
|
73 |
public function print_js() {
|
74 |
wp_enqueue_script( 'jquery' );
|
settings/settings-cpt.php
CHANGED
@@ -19,28 +19,28 @@ class PLL_Settings_CPT extends PLL_Settings_Module {
|
|
19 |
/**
|
20 |
* The list of post types to show in the form.
|
21 |
*
|
22 |
-
* @var
|
23 |
*/
|
24 |
private $post_types;
|
25 |
|
26 |
/**
|
27 |
* The list of post types to disable in the form.
|
28 |
*
|
29 |
-
* @var
|
30 |
*/
|
31 |
private $disabled_post_types;
|
32 |
|
33 |
/**
|
34 |
* The list of taxonomies to show in the form.
|
35 |
*
|
36 |
-
* @var
|
37 |
*/
|
38 |
private $taxonomies;
|
39 |
|
40 |
/**
|
41 |
* The list of taxonomies to disable in the form.
|
42 |
*
|
43 |
-
* @var
|
44 |
*/
|
45 |
private $disabled_taxonomies;
|
46 |
|
19 |
/**
|
20 |
* The list of post types to show in the form.
|
21 |
*
|
22 |
+
* @var string[]
|
23 |
*/
|
24 |
private $post_types;
|
25 |
|
26 |
/**
|
27 |
* The list of post types to disable in the form.
|
28 |
*
|
29 |
+
* @var string[]
|
30 |
*/
|
31 |
private $disabled_post_types;
|
32 |
|
33 |
/**
|
34 |
* The list of taxonomies to show in the form.
|
35 |
*
|
36 |
+
* @var string[]
|
37 |
*/
|
38 |
private $taxonomies;
|
39 |
|
40 |
/**
|
41 |
* The list of taxonomies to disable in the form.
|
42 |
*
|
43 |
+
* @var string[]
|
44 |
*/
|
45 |
private $disabled_taxonomies;
|
46 |
|
settings/settings-licenses.php
CHANGED
@@ -17,9 +17,9 @@ class PLL_Settings_Licenses extends PLL_Settings_Module {
|
|
17 |
public $priority = 100;
|
18 |
|
19 |
/**
|
20 |
-
* Stores an array of
|
21 |
*
|
22 |
-
* @var
|
23 |
*/
|
24 |
protected $items;
|
25 |
|
@@ -77,11 +77,11 @@ class PLL_Settings_Licenses extends PLL_Settings_Module {
|
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
-
* Get the html for a row (one per license key) for display
|
81 |
*
|
82 |
* @since 1.9
|
83 |
*
|
84 |
-
* @param
|
85 |
* @return string
|
86 |
*/
|
87 |
protected function get_row( $item ) {
|
@@ -122,6 +122,8 @@ class PLL_Settings_Licenses extends PLL_Settings_Module {
|
|
122 |
* Ajax method to deactivate a license
|
123 |
*
|
124 |
* @since 1.9
|
|
|
|
|
125 |
*/
|
126 |
public function deactivate_license() {
|
127 |
check_ajax_referer( 'pll_options', '_pll_nonce' );
|
17 |
public $priority = 100;
|
18 |
|
19 |
/**
|
20 |
+
* Stores an array of objects allowing to manage a license.
|
21 |
*
|
22 |
+
* @var PLL_License[]
|
23 |
*/
|
24 |
protected $items;
|
25 |
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
+
* Get the html for a row (one per license key) for display.
|
81 |
*
|
82 |
* @since 1.9
|
83 |
*
|
84 |
+
* @param PLL_License $item Object allowing to manage a license.
|
85 |
* @return string
|
86 |
*/
|
87 |
protected function get_row( $item ) {
|
122 |
* Ajax method to deactivate a license
|
123 |
*
|
124 |
* @since 1.9
|
125 |
+
*
|
126 |
+
* @return void
|
127 |
*/
|
128 |
public function deactivate_license() {
|
129 |
check_ajax_referer( 'pll_options', '_pll_nonce' );
|
settings/settings-module.php
CHANGED
@@ -17,8 +17,6 @@ class PLL_Settings_Module {
|
|
17 |
public $options;
|
18 |
|
19 |
/**
|
20 |
-
* Instance of PLL_Model.
|
21 |
-
*
|
22 |
* @var PLL_Model
|
23 |
*/
|
24 |
public $model;
|
@@ -161,6 +159,8 @@ class PLL_Settings_Module {
|
|
161 |
* Activates the module
|
162 |
*
|
163 |
* @since 1.8
|
|
|
|
|
164 |
*/
|
165 |
public function activate() {
|
166 |
if ( ! empty( $this->active_option ) ) {
|
@@ -173,6 +173,8 @@ class PLL_Settings_Module {
|
|
173 |
* Deactivates the module
|
174 |
*
|
175 |
* @since 1.8
|
|
|
|
|
176 |
*/
|
177 |
public function deactivate() {
|
178 |
if ( ! empty( $this->active_option ) ) {
|
@@ -185,6 +187,8 @@ class PLL_Settings_Module {
|
|
185 |
* Protected method to display a configuration form
|
186 |
*
|
187 |
* @since 1.8
|
|
|
|
|
188 |
*/
|
189 |
protected function form() {
|
190 |
// Child classes can provide a form
|
@@ -224,6 +228,8 @@ class PLL_Settings_Module {
|
|
224 |
* Ajax method to save the options
|
225 |
*
|
226 |
* @since 1.8
|
|
|
|
|
227 |
*/
|
228 |
public function save_options() {
|
229 |
check_ajax_referer( 'pll_options', '_pll_nonce' );
|
@@ -263,11 +269,11 @@ class PLL_Settings_Module {
|
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
-
* Get the row actions
|
267 |
*
|
268 |
* @since 1.8
|
269 |
*
|
270 |
-
* @return
|
271 |
*/
|
272 |
protected function get_actions() {
|
273 |
$actions = array();
|
@@ -288,11 +294,11 @@ class PLL_Settings_Module {
|
|
288 |
}
|
289 |
|
290 |
/**
|
291 |
-
* Get the actions links
|
292 |
*
|
293 |
* @since 1.8
|
294 |
*
|
295 |
-
* @return
|
296 |
*/
|
297 |
public function get_action_links() {
|
298 |
return array_intersect_key( $this->action_links, array_flip( $this->get_actions() ) );
|
@@ -326,11 +332,11 @@ class PLL_Settings_Module {
|
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
-
* Get the buttons
|
330 |
*
|
331 |
* @since 1.9
|
332 |
*
|
333 |
-
* @return array
|
334 |
*/
|
335 |
public function get_buttons() {
|
336 |
return $this->buttons;
|
17 |
public $options;
|
18 |
|
19 |
/**
|
|
|
|
|
20 |
* @var PLL_Model
|
21 |
*/
|
22 |
public $model;
|
159 |
* Activates the module
|
160 |
*
|
161 |
* @since 1.8
|
162 |
+
*
|
163 |
+
* @return void
|
164 |
*/
|
165 |
public function activate() {
|
166 |
if ( ! empty( $this->active_option ) ) {
|
173 |
* Deactivates the module
|
174 |
*
|
175 |
* @since 1.8
|
176 |
+
*
|
177 |
+
* @return void
|
178 |
*/
|
179 |
public function deactivate() {
|
180 |
if ( ! empty( $this->active_option ) ) {
|
187 |
* Protected method to display a configuration form
|
188 |
*
|
189 |
* @since 1.8
|
190 |
+
*
|
191 |
+
* @return void
|
192 |
*/
|
193 |
protected function form() {
|
194 |
// Child classes can provide a form
|
228 |
* Ajax method to save the options
|
229 |
*
|
230 |
* @since 1.8
|
231 |
+
*
|
232 |
+
* @return void
|
233 |
*/
|
234 |
public function save_options() {
|
235 |
check_ajax_referer( 'pll_options', '_pll_nonce' );
|
269 |
}
|
270 |
|
271 |
/**
|
272 |
+
* Get the row actions.
|
273 |
*
|
274 |
* @since 1.8
|
275 |
*
|
276 |
+
* @return string[]
|
277 |
*/
|
278 |
protected function get_actions() {
|
279 |
$actions = array();
|
294 |
}
|
295 |
|
296 |
/**
|
297 |
+
* Get the actions links.
|
298 |
*
|
299 |
* @since 1.8
|
300 |
*
|
301 |
+
* @return string[] Action links.
|
302 |
*/
|
303 |
public function get_action_links() {
|
304 |
return array_intersect_key( $this->action_links, array_flip( $this->get_actions() ) );
|
332 |
}
|
333 |
|
334 |
/**
|
335 |
+
* Get the buttons.
|
336 |
*
|
337 |
* @since 1.9
|
338 |
*
|
339 |
+
* @return string[] An array of html fragment for the buttons.
|
340 |
*/
|
341 |
public function get_buttons() {
|
342 |
return $this->buttons;
|
settings/settings-url.php
CHANGED
@@ -16,6 +16,13 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
16 |
*/
|
17 |
public $priority = 10;
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
/**
|
20 |
* Constructor
|
21 |
*
|
@@ -34,7 +41,6 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
34 |
)
|
35 |
);
|
36 |
|
37 |
-
$this->links_model = &$polylang->links_model;
|
38 |
$this->page_on_front = &$polylang->static_pages->page_on_front;
|
39 |
}
|
40 |
|
@@ -42,6 +48,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
42 |
* Displays the fieldset to choose how the language is set
|
43 |
*
|
44 |
* @since 1.8
|
|
|
|
|
45 |
*/
|
46 |
protected function force_lang() {
|
47 |
?>
|
@@ -107,6 +115,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
107 |
* Displays the fieldset to choose to hide the default language information in url
|
108 |
*
|
109 |
* @since 1.8
|
|
|
|
|
110 |
*/
|
111 |
protected function hide_default() {
|
112 |
?>
|
@@ -126,6 +136,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
126 |
* Displays the fieldset to choose to hide /language/ in url
|
127 |
*
|
128 |
* @since 1.8
|
|
|
|
|
129 |
*/
|
130 |
protected function rewrite() {
|
131 |
?>
|
@@ -158,6 +170,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
158 |
* Displays the fieldset to choose to redirect the home page to language page
|
159 |
*
|
160 |
* @since 1.8
|
|
|
|
|
161 |
*/
|
162 |
protected function redirect_lang() {
|
163 |
?>
|
@@ -190,6 +204,8 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
190 |
* Displays the settings
|
191 |
*
|
192 |
* @since 1.8
|
|
|
|
|
193 |
*/
|
194 |
public function form() {
|
195 |
?>
|
@@ -230,6 +246,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
230 |
* @since 1.8
|
231 |
*
|
232 |
* @param array $options
|
|
|
233 |
*/
|
234 |
protected function update( $options ) {
|
235 |
$newoptions = array();
|
@@ -285,6 +302,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
285 |
* @since 1.8
|
286 |
*
|
287 |
* @param array $options new set of options to test
|
|
|
288 |
*/
|
289 |
protected function check_domains( $options ) {
|
290 |
$options = array_merge( $this->options, $options );
|
16 |
*/
|
17 |
public $priority = 10;
|
18 |
|
19 |
+
/**
|
20 |
+
* The page id of the static front page.
|
21 |
+
*
|
22 |
+
* @var int
|
23 |
+
*/
|
24 |
+
protected $page_on_front;
|
25 |
+
|
26 |
/**
|
27 |
* Constructor
|
28 |
*
|
41 |
)
|
42 |
);
|
43 |
|
|
|
44 |
$this->page_on_front = &$polylang->static_pages->page_on_front;
|
45 |
}
|
46 |
|
48 |
* Displays the fieldset to choose how the language is set
|
49 |
*
|
50 |
* @since 1.8
|
51 |
+
*
|
52 |
+
* @return void
|
53 |
*/
|
54 |
protected function force_lang() {
|
55 |
?>
|
115 |
* Displays the fieldset to choose to hide the default language information in url
|
116 |
*
|
117 |
* @since 1.8
|
118 |
+
*
|
119 |
+
* @return void
|
120 |
*/
|
121 |
protected function hide_default() {
|
122 |
?>
|
136 |
* Displays the fieldset to choose to hide /language/ in url
|
137 |
*
|
138 |
* @since 1.8
|
139 |
+
*
|
140 |
+
* @return void
|
141 |
*/
|
142 |
protected function rewrite() {
|
143 |
?>
|
170 |
* Displays the fieldset to choose to redirect the home page to language page
|
171 |
*
|
172 |
* @since 1.8
|
173 |
+
*
|
174 |
+
* @return void
|
175 |
*/
|
176 |
protected function redirect_lang() {
|
177 |
?>
|
204 |
* Displays the settings
|
205 |
*
|
206 |
* @since 1.8
|
207 |
+
*
|
208 |
+
* @return void
|
209 |
*/
|
210 |
public function form() {
|
211 |
?>
|
246 |
* @since 1.8
|
247 |
*
|
248 |
* @param array $options
|
249 |
+
* @return array
|
250 |
*/
|
251 |
protected function update( $options ) {
|
252 |
$newoptions = array();
|
302 |
* @since 1.8
|
303 |
*
|
304 |
* @param array $options new set of options to test
|
305 |
+
* @return void
|
306 |
*/
|
307 |
protected function check_domains( $options ) {
|
308 |
$options = array_merge( $this->options, $options );
|
settings/settings.php
CHANGED
@@ -4,34 +4,28 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* A class for the Polylang settings pages
|
8 |
-
* accessible in $polylang global object
|
9 |
-
*
|
10 |
-
* Properties:
|
11 |
-
* options => inherited, reference to Polylang options array
|
12 |
-
* model => inherited, reference to PLL_Model object
|
13 |
-
* links_model => inherited, reference to PLL_Links_Model object
|
14 |
-
* links => inherited, reference to PLL_Admin_Links object
|
15 |
-
* static_pages => inherited, reference to PLL_Admin_Static_Pages object
|
16 |
-
* filters_links => inherited, reference to PLL_Filters_Links object
|
17 |
-
* curlang => inherited, optional, current language used to filter admin content
|
18 |
-
* pref_lang => inherited, preferred language used as default when saving posts or terms
|
19 |
*
|
20 |
* @since 1.2
|
21 |
*/
|
22 |
class PLL_Settings extends PLL_Admin_Base {
|
23 |
|
24 |
/**
|
25 |
-
*
|
|
|
|
|
|
|
|
|
|
|
26 |
*
|
27 |
-
* @var string
|
28 |
*/
|
29 |
protected $active_tab;
|
30 |
|
31 |
/**
|
32 |
-
* Array of modules classes
|
33 |
*
|
34 |
-
* @var
|
35 |
*/
|
36 |
protected $modules;
|
37 |
|
@@ -40,7 +34,7 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
40 |
*
|
41 |
* @since 1.2
|
42 |
*
|
43 |
-
* @param
|
44 |
*/
|
45 |
public function __construct( &$links_model ) {
|
46 |
parent::__construct( $links_model );
|
@@ -65,6 +59,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
65 |
* Initializes the modules
|
66 |
*
|
67 |
* @since 1.8
|
|
|
|
|
68 |
*/
|
69 |
public function register_settings_modules() {
|
70 |
$modules = array();
|
@@ -99,6 +95,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
99 |
* Loads the about metabox
|
100 |
*
|
101 |
* @since 0.8
|
|
|
|
|
102 |
*/
|
103 |
public function metabox_about() {
|
104 |
include __DIR__ . '/view-about.php';
|
@@ -108,6 +106,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
108 |
* Adds screen options and the about box in the languages admin panel
|
109 |
*
|
110 |
* @since 0.9.5
|
|
|
|
|
111 |
*/
|
112 |
public function load_page() {
|
113 |
if ( ! defined( 'PLL_DISPLAY_ABOUT' ) || PLL_DISPLAY_ABOUT ) {
|
@@ -136,6 +136,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
136 |
* Adds screen options in the strings translations admin panel
|
137 |
*
|
138 |
* @since 2.1
|
|
|
|
|
139 |
*/
|
140 |
public function load_page_strings() {
|
141 |
add_screen_option(
|
@@ -169,6 +171,7 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
169 |
* @since 1.9
|
170 |
*
|
171 |
* @param string $action
|
|
|
172 |
*/
|
173 |
public function handle_actions( $action ) {
|
174 |
switch ( $action ) {
|
@@ -287,6 +290,8 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
287 |
* Also manages user input for these pages
|
288 |
*
|
289 |
* @since 0.1
|
|
|
|
|
290 |
*/
|
291 |
public function languages_page() {
|
292 |
switch ( $this->active_tab ) {
|
@@ -317,23 +322,26 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
317 |
|
318 |
/**
|
319 |
* Enqueues scripts and styles
|
|
|
|
|
320 |
*/
|
321 |
public function admin_enqueue_scripts() {
|
322 |
parent::admin_enqueue_scripts();
|
323 |
|
324 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
325 |
|
326 |
-
wp_enqueue_script( 'pll_admin', plugins_url( '/js/admin' . $suffix . '.js',
|
327 |
-
wp_localize_script( 'pll_admin', '
|
328 |
-
wp_localize_script( 'pll_admin', 'pll_dismiss_notice', esc_html__( 'Dismiss this notice.', 'polylang' ) );
|
329 |
|
330 |
-
wp_enqueue_style( 'pll_selectmenu', plugins_url( '/css/selectmenu' . $suffix . '.css',
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
* Displays a notice when there are objects with no language assigned
|
335 |
*
|
336 |
* @since 1.8
|
|
|
|
|
337 |
*/
|
338 |
public function notice_objects_with_no_lang() {
|
339 |
if ( ! empty( $this->options['default_lang'] ) && $this->model->get_objects_with_no_lang( 1 ) ) {
|
@@ -353,6 +361,7 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
353 |
* @since 1.5
|
354 |
*
|
355 |
* @param array $args query arguments to add to the url
|
|
|
356 |
*/
|
357 |
public static function redirect( $args = array() ) {
|
358 |
if ( $errors = get_settings_errors() ) {
|
@@ -368,6 +377,16 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
368 |
* Get the list of predefined languages
|
369 |
*
|
370 |
* @since 2.3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
*/
|
372 |
public static function get_predefined_languages() {
|
373 |
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* A class for the Polylang settings pages, accessible from @see PLL().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Settings extends PLL_Admin_Base {
|
12 |
|
13 |
/**
|
14 |
+
* @var PLL_Admin_Model
|
15 |
+
*/
|
16 |
+
public $model;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Name of the active module.
|
20 |
*
|
21 |
+
* @var string
|
22 |
*/
|
23 |
protected $active_tab;
|
24 |
|
25 |
/**
|
26 |
+
* Array of modules classes.
|
27 |
*
|
28 |
+
* @var PLL_Settings_Module[]
|
29 |
*/
|
30 |
protected $modules;
|
31 |
|
34 |
*
|
35 |
* @since 1.2
|
36 |
*
|
37 |
+
* @param PLL_Links_Model $links_model Reference to the links model.
|
38 |
*/
|
39 |
public function __construct( &$links_model ) {
|
40 |
parent::__construct( $links_model );
|
59 |
* Initializes the modules
|
60 |
*
|
61 |
* @since 1.8
|
62 |
+
*
|
63 |
+
* @return void
|
64 |
*/
|
65 |
public function register_settings_modules() {
|
66 |
$modules = array();
|
95 |
* Loads the about metabox
|
96 |
*
|
97 |
* @since 0.8
|
98 |
+
*
|
99 |
+
* @return void
|
100 |
*/
|
101 |
public function metabox_about() {
|
102 |
include __DIR__ . '/view-about.php';
|
106 |
* Adds screen options and the about box in the languages admin panel
|
107 |
*
|
108 |
* @since 0.9.5
|
109 |
+
*
|
110 |
+
* @return void
|
111 |
*/
|
112 |
public function load_page() {
|
113 |
if ( ! defined( 'PLL_DISPLAY_ABOUT' ) || PLL_DISPLAY_ABOUT ) {
|
136 |
* Adds screen options in the strings translations admin panel
|
137 |
*
|
138 |
* @since 2.1
|
139 |
+
*
|
140 |
+
* @return void
|
141 |
*/
|
142 |
public function load_page_strings() {
|
143 |
add_screen_option(
|
171 |
* @since 1.9
|
172 |
*
|
173 |
* @param string $action
|
174 |
+
* @return void
|
175 |
*/
|
176 |
public function handle_actions( $action ) {
|
177 |
switch ( $action ) {
|
290 |
* Also manages user input for these pages
|
291 |
*
|
292 |
* @since 0.1
|
293 |
+
*
|
294 |
+
* @return void
|
295 |
*/
|
296 |
public function languages_page() {
|
297 |
switch ( $this->active_tab ) {
|
322 |
|
323 |
/**
|
324 |
* Enqueues scripts and styles
|
325 |
+
*
|
326 |
+
* @return void
|
327 |
*/
|
328 |
public function admin_enqueue_scripts() {
|
329 |
parent::admin_enqueue_scripts();
|
330 |
|
331 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
332 |
|
333 |
+
wp_enqueue_script( 'pll_admin', plugins_url( '/js/build/admin' . $suffix . '.js', POLYLANG_BASENAME ), array( 'jquery', 'wp-ajax-response', 'postbox', 'jquery-ui-selectmenu' ), POLYLANG_VERSION, true );
|
334 |
+
wp_localize_script( 'pll_admin', 'pll_admin', array( 'dismiss_notice' => esc_html__( 'Dismiss this notice.', 'polylang' ) ) );
|
|
|
335 |
|
336 |
+
wp_enqueue_style( 'pll_selectmenu', plugins_url( '/css/build/selectmenu' . $suffix . '.css', POLYLANG_BASENAME ), array(), POLYLANG_VERSION );
|
337 |
}
|
338 |
|
339 |
/**
|
340 |
* Displays a notice when there are objects with no language assigned
|
341 |
*
|
342 |
* @since 1.8
|
343 |
+
*
|
344 |
+
* @return void
|
345 |
*/
|
346 |
public function notice_objects_with_no_lang() {
|
347 |
if ( ! empty( $this->options['default_lang'] ) && $this->model->get_objects_with_no_lang( 1 ) ) {
|
361 |
* @since 1.5
|
362 |
*
|
363 |
* @param array $args query arguments to add to the url
|
364 |
+
* @return void
|
365 |
*/
|
366 |
public static function redirect( $args = array() ) {
|
367 |
if ( $errors = get_settings_errors() ) {
|
377 |
* Get the list of predefined languages
|
378 |
*
|
379 |
* @since 2.3
|
380 |
+
*
|
381 |
+
* @return string[] {
|
382 |
+
* @type string $code ISO 639-1 language code.
|
383 |
+
* @type string $locale WordPress locale.
|
384 |
+
* @type string $name Native language name.
|
385 |
+
* @type string $dir Text direction: 'ltr' or 'rtl'.
|
386 |
+
* @type string $flag Flag code, generally the country code.
|
387 |
+
* @type string $w3c W3C locale.
|
388 |
+
* @type string $facebook Facebook locale.
|
389 |
+
* }
|
390 |
*/
|
391 |
public static function get_predefined_languages() {
|
392 |
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
|
settings/table-languages.php
CHANGED
@@ -30,11 +30,12 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
-
* Generates content for a single row of the table
|
34 |
*
|
35 |
* @since 1.8
|
36 |
*
|
37 |
-
* @param
|
|
|
38 |
*/
|
39 |
public function single_row( $item ) {
|
40 |
/**
|
@@ -42,8 +43,8 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
42 |
*
|
43 |
* @since 1.8
|
44 |
*
|
45 |
-
* @param array
|
46 |
-
* @param
|
47 |
*/
|
48 |
$classes = apply_filters( 'pll_languages_row_classes', array(), $item );
|
49 |
echo '<tr' . ( empty( $classes ) ? '>' : ' class="' . esc_attr( implode( ' ', $classes ) ) . '">' );
|
@@ -52,13 +53,13 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
-
* Displays the item information in a column ( default case )
|
56 |
*
|
57 |
* @since 0.1
|
58 |
*
|
59 |
-
* @param
|
60 |
-
* @param string
|
61 |
-
* @return string
|
62 |
*/
|
63 |
public function column_default( $item, $column_name ) {
|
64 |
switch ( $column_name ) {
|
@@ -71,7 +72,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
71 |
return (int) $item->$column_name;
|
72 |
|
73 |
default:
|
74 |
-
return $item->$column_name; //
|
75 |
}
|
76 |
}
|
77 |
|
@@ -81,7 +82,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
81 |
*
|
82 |
* @since 0.1
|
83 |
*
|
84 |
-
* @param
|
85 |
* @return string
|
86 |
*/
|
87 |
public function column_name( $item ) {
|
@@ -99,7 +100,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
99 |
*
|
100 |
* @since 1.8
|
101 |
*
|
102 |
-
* @param
|
103 |
* @return string
|
104 |
*/
|
105 |
public function column_default_lang( $item ) {
|
@@ -117,12 +118,12 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
117 |
);
|
118 |
|
119 |
/**
|
120 |
-
*
|
121 |
*
|
122 |
* @since 1.8
|
123 |
*
|
124 |
-
* @param string
|
125 |
-
* @param
|
126 |
*/
|
127 |
$s = apply_filters( 'pll_default_lang_row_action', $s, $item );
|
128 |
} else {
|
@@ -141,7 +142,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
141 |
*
|
142 |
* @since 0.1
|
143 |
*
|
144 |
-
* @return
|
145 |
*/
|
146 |
public function get_columns() {
|
147 |
return array(
|
@@ -188,9 +189,9 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
188 |
*
|
189 |
* @since 1.8
|
190 |
*
|
191 |
-
* @param
|
192 |
-
* @param string
|
193 |
-
* @param string
|
194 |
* @return string The row actions output.
|
195 |
*/
|
196 |
protected function handle_row_actions( $item, $column_name, $primary ) {
|
@@ -215,12 +216,12 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
215 |
);
|
216 |
|
217 |
/**
|
218 |
-
*
|
219 |
*
|
220 |
* @since 1.8
|
221 |
*
|
222 |
-
* @param array
|
223 |
-
* @param
|
224 |
*/
|
225 |
$actions = apply_filters( 'pll_languages_row_actions', $actions, $item );
|
226 |
|
@@ -254,6 +255,7 @@ class PLL_Table_Languages extends WP_List_Table {
|
|
254 |
* @since 0.1
|
255 |
*
|
256 |
* @param array $data
|
|
|
257 |
*/
|
258 |
public function prepare_items( $data = array() ) {
|
259 |
$per_page = $this->get_items_per_page( 'pll_lang_per_page' );
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
+
* Generates content for a single row of the table.
|
34 |
*
|
35 |
* @since 1.8
|
36 |
*
|
37 |
+
* @param PLL_Language $item The language item.
|
38 |
+
* @return void
|
39 |
*/
|
40 |
public function single_row( $item ) {
|
41 |
/**
|
43 |
*
|
44 |
* @since 1.8
|
45 |
*
|
46 |
+
* @param array $classes The list of class names.
|
47 |
+
* @param PLL_Language $item The language item.
|
48 |
*/
|
49 |
$classes = apply_filters( 'pll_languages_row_classes', array(), $item );
|
50 |
echo '<tr' . ( empty( $classes ) ? '>' : ' class="' . esc_attr( implode( ' ', $classes ) ) . '">' );
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
+
* Displays the item information in a column ( default case ).
|
57 |
*
|
58 |
* @since 0.1
|
59 |
*
|
60 |
+
* @param PLL_Language $item The language item.
|
61 |
+
* @param string $column_name The column name.
|
62 |
+
* @return string|int
|
63 |
*/
|
64 |
public function column_default( $item, $column_name ) {
|
65 |
switch ( $column_name ) {
|
72 |
return (int) $item->$column_name;
|
73 |
|
74 |
default:
|
75 |
+
return $item->$column_name; // Flag.
|
76 |
}
|
77 |
}
|
78 |
|
82 |
*
|
83 |
* @since 0.1
|
84 |
*
|
85 |
+
* @param PLL_Language $item The language item.
|
86 |
* @return string
|
87 |
*/
|
88 |
public function column_name( $item ) {
|
100 |
*
|
101 |
* @since 1.8
|
102 |
*
|
103 |
+
* @param PLL_Language $item The language item.
|
104 |
* @return string
|
105 |
*/
|
106 |
public function column_default_lang( $item ) {
|
118 |
);
|
119 |
|
120 |
/**
|
121 |
+
* Filters the default language row action in the languages list table.
|
122 |
*
|
123 |
* @since 1.8
|
124 |
*
|
125 |
+
* @param string $s The html markup of the action.
|
126 |
+
* @param PLL_Language $item The language item.
|
127 |
*/
|
128 |
$s = apply_filters( 'pll_default_lang_row_action', $s, $item );
|
129 |
} else {
|
142 |
*
|
143 |
* @since 0.1
|
144 |
*
|
145 |
+
* @return string[] The list of column titles.
|
146 |
*/
|
147 |
public function get_columns() {
|
148 |
return array(
|
189 |
*
|
190 |
* @since 1.8
|
191 |
*
|
192 |
+
* @param PLL_Language $item The language item being acted upon.
|
193 |
+
* @param string $column_name Current column name.
|
194 |
+
* @param string $primary Primary column name.
|
195 |
* @return string The row actions output.
|
196 |
*/
|
197 |
protected function handle_row_actions( $item, $column_name, $primary ) {
|
216 |
);
|
217 |
|
218 |
/**
|
219 |
+
* Filters the list of row actions in the languages list table.
|
220 |
*
|
221 |
* @since 1.8
|
222 |
*
|
223 |
+
* @param array $actions A list of html markup actions.
|
224 |
+
* @param PLL_Language $item The language item.
|
225 |
*/
|
226 |
$actions = apply_filters( 'pll_languages_row_actions', $actions, $item );
|
227 |
|
255 |
* @since 0.1
|
256 |
*
|
257 |
* @param array $data
|
258 |
+
* @return void
|
259 |
*/
|
260 |
public function prepare_items( $data = array() ) {
|
261 |
$per_page = $this->get_items_per_page( 'pll_lang_per_page' );
|
settings/table-settings.php
CHANGED
@@ -38,11 +38,12 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* Displays a single row
|
42 |
*
|
43 |
* @since 1.8
|
44 |
*
|
45 |
-
* @param
|
|
|
46 |
*/
|
47 |
public function single_row( $item ) {
|
48 |
// Classes to reuse css from the plugins list table
|
@@ -88,11 +89,12 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
-
* Generates the columns for a single row of the table
|
92 |
*
|
93 |
* @since 1.8
|
94 |
*
|
95 |
-
* @param
|
|
|
96 |
*/
|
97 |
protected function single_row_columns( $item ) {
|
98 |
$column_info = $this->get_column_info();
|
@@ -118,13 +120,13 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
-
* Displays the item information in a column (
|
122 |
*
|
123 |
* @since 1.8
|
124 |
*
|
125 |
-
* @param
|
126 |
-
* @param string
|
127 |
-
* @return string
|
128 |
*/
|
129 |
protected function column_default( $item, $column_name ) {
|
130 |
if ( 'plugin-title' == $column_name ) {
|
@@ -134,11 +136,11 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
134 |
}
|
135 |
|
136 |
/**
|
137 |
-
* Gets the list of columns
|
138 |
*
|
139 |
* @since 1.8
|
140 |
*
|
141 |
-
* @return
|
142 |
*/
|
143 |
public function get_columns() {
|
144 |
return array(
|
@@ -164,7 +166,8 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
164 |
*
|
165 |
* @since 1.8
|
166 |
*
|
167 |
-
* @param
|
|
|
168 |
*/
|
169 |
public function prepare_items( $items = array() ) {
|
170 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns(), $this->get_primary_column_name() );
|
@@ -185,6 +188,7 @@ class PLL_Table_Settings extends WP_List_Table {
|
|
185 |
* @since 2.1
|
186 |
*
|
187 |
* @param string $which 'top' or 'bottom'
|
|
|
188 |
*/
|
189 |
protected function display_tablenav( $which ) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
190 |
}
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* Displays a single row.
|
42 |
*
|
43 |
* @since 1.8
|
44 |
*
|
45 |
+
* @param PLL_Settings_Module $item Settings module item.
|
46 |
+
* @return void
|
47 |
*/
|
48 |
public function single_row( $item ) {
|
49 |
// Classes to reuse css from the plugins list table
|
89 |
}
|
90 |
|
91 |
/**
|
92 |
+
* Generates the columns for a single row of the table.
|
93 |
*
|
94 |
* @since 1.8
|
95 |
*
|
96 |
+
* @param PLL_Settings_Module $item Settings module item.
|
97 |
+
* @return void
|
98 |
*/
|
99 |
protected function single_row_columns( $item ) {
|
100 |
$column_info = $this->get_column_info();
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Displays the item information in a column (default case).
|
124 |
*
|
125 |
* @since 1.8
|
126 |
*
|
127 |
+
* @param PLL_Settings_Module $item Settings module item.
|
128 |
+
* @param string $column_name Column name.
|
129 |
+
* @return string The column name.
|
130 |
*/
|
131 |
protected function column_default( $item, $column_name ) {
|
132 |
if ( 'plugin-title' == $column_name ) {
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
+
* Gets the list of columns.
|
140 |
*
|
141 |
* @since 1.8
|
142 |
*
|
143 |
+
* @return string[] The list of column titles.
|
144 |
*/
|
145 |
public function get_columns() {
|
146 |
return array(
|
166 |
*
|
167 |
* @since 1.8
|
168 |
*
|
169 |
+
* @param PLL_Settings_Module[] $items Array of settings module items.
|
170 |
+
* @return void
|
171 |
*/
|
172 |
public function prepare_items( $items = array() ) {
|
173 |
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns(), $this->get_primary_column_name() );
|
188 |
* @since 2.1
|
189 |
*
|
190 |
* @param string $which 'top' or 'bottom'
|
191 |
+
* @return void
|
192 |
*/
|
193 |
protected function display_tablenav( $which ) {} // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
194 |
}
|
settings/table-string.php
CHANGED
@@ -14,14 +14,40 @@ if ( ! class_exists( 'WP_List_Table' ) ) {
|
|
14 |
* @since 0.6
|
15 |
*/
|
16 |
class PLL_Table_String extends WP_List_Table {
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
/**
|
20 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
*
|
22 |
* @since 0.6
|
23 |
*
|
24 |
-
* @param
|
25 |
*/
|
26 |
public function __construct( $languages ) {
|
27 |
parent::__construct(
|
@@ -119,15 +145,15 @@ class PLL_Table_String extends WP_List_Table {
|
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
-
* Gets the list of columns
|
123 |
*
|
124 |
* @since 0.6
|
125 |
*
|
126 |
-
* @return
|
127 |
*/
|
128 |
public function get_columns() {
|
129 |
return array(
|
130 |
-
'cb' => '<input type="checkbox" />', // Checkbox
|
131 |
'string' => esc_html__( 'String', 'polylang' ),
|
132 |
'name' => esc_html__( 'Name', 'polylang' ),
|
133 |
'context' => esc_html__( 'Group', 'polylang' ),
|
@@ -166,9 +192,9 @@ class PLL_Table_String extends WP_List_Table {
|
|
166 |
*
|
167 |
* @since 2.6
|
168 |
*
|
169 |
-
* @param
|
170 |
-
* @param string
|
171 |
-
* @return
|
172 |
*/
|
173 |
protected function search_in_translations( $mos, $s ) {
|
174 |
$founds = array();
|
@@ -209,6 +235,8 @@ class PLL_Table_String extends WP_List_Table {
|
|
209 |
* Prepares the list of items for displaying
|
210 |
*
|
211 |
* @since 0.6
|
|
|
|
|
212 |
*/
|
213 |
public function prepare_items() {
|
214 |
// Is admin language filter active?
|
@@ -275,11 +303,11 @@ class PLL_Table_String extends WP_List_Table {
|
|
275 |
}
|
276 |
|
277 |
/**
|
278 |
-
* Get the list of possible bulk actions
|
279 |
*
|
280 |
* @since 1.1
|
281 |
*
|
282 |
-
* @return
|
283 |
*/
|
284 |
public function get_bulk_actions() {
|
285 |
return array( 'delete' => __( 'Delete', 'polylang' ) );
|
@@ -303,6 +331,7 @@ class PLL_Table_String extends WP_List_Table {
|
|
303 |
* @since 1.1
|
304 |
*
|
305 |
* @param string $which only 'top' is supported
|
|
|
306 |
*/
|
307 |
public function extra_tablenav( $which ) {
|
308 |
if ( 'top' !== $which ) {
|
@@ -318,7 +347,7 @@ class PLL_Table_String extends WP_List_Table {
|
|
318 |
echo '<select id="select-group" name="group">' . "\n";
|
319 |
printf(
|
320 |
'<option value="-1"%s>%s</option>' . "\n",
|
321 |
-
selected( $this->
|
322 |
esc_html__( 'View all groups', 'polylang' )
|
323 |
);
|
324 |
|
@@ -341,13 +370,15 @@ class PLL_Table_String extends WP_List_Table {
|
|
341 |
* Optionaly clean the DB
|
342 |
*
|
343 |
* @since 1.9
|
|
|
|
|
344 |
*/
|
345 |
public function save_translations() {
|
346 |
check_admin_referer( 'string-translation', '_wpnonce_string-translation' );
|
347 |
|
348 |
if ( ! empty( $_POST['submit'] ) ) {
|
349 |
foreach ( $this->languages as $language ) {
|
350 |
-
if ( empty( $_POST['translation'][ $language->slug ] ) ) { // In case the language filter is active ( thanks to John P. Bloch )
|
351 |
continue;
|
352 |
}
|
353 |
|
14 |
* @since 0.6
|
15 |
*/
|
16 |
class PLL_Table_String extends WP_List_Table {
|
17 |
+
/**
|
18 |
+
* The list of languages.
|
19 |
+
*
|
20 |
+
* @var PLL_Language[]
|
21 |
+
*/
|
22 |
+
protected $languages;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Registered strings.
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $strings;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* The string groups.
|
33 |
+
*
|
34 |
+
* @var string[]
|
35 |
+
*/
|
36 |
+
protected $groups;
|
37 |
|
38 |
/**
|
39 |
+
* The selected string group or -1 if none is selected.
|
40 |
+
*
|
41 |
+
* @var string|int
|
42 |
+
*/
|
43 |
+
protected $selected_group;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Constructor.
|
47 |
*
|
48 |
* @since 0.6
|
49 |
*
|
50 |
+
* @param PLL_Language[] $languages List of languages.
|
51 |
*/
|
52 |
public function __construct( $languages ) {
|
53 |
parent::__construct(
|
145 |
}
|
146 |
|
147 |
/**
|
148 |
+
* Gets the list of columns.
|
149 |
*
|
150 |
* @since 0.6
|
151 |
*
|
152 |
+
* @return string[] The list of column titles.
|
153 |
*/
|
154 |
public function get_columns() {
|
155 |
return array(
|
156 |
+
'cb' => '<input type="checkbox" />', // Checkbox.
|
157 |
'string' => esc_html__( 'String', 'polylang' ),
|
158 |
'name' => esc_html__( 'Name', 'polylang' ),
|
159 |
'context' => esc_html__( 'Group', 'polylang' ),
|
192 |
*
|
193 |
* @since 2.6
|
194 |
*
|
195 |
+
* @param PLL_MO[] $mos An array of PLL_MO objects.
|
196 |
+
* @param string $s Searched string.
|
197 |
+
* @return string[] Found strings.
|
198 |
*/
|
199 |
protected function search_in_translations( $mos, $s ) {
|
200 |
$founds = array();
|
235 |
* Prepares the list of items for displaying
|
236 |
*
|
237 |
* @since 0.6
|
238 |
+
*
|
239 |
+
* @return void
|
240 |
*/
|
241 |
public function prepare_items() {
|
242 |
// Is admin language filter active?
|
303 |
}
|
304 |
|
305 |
/**
|
306 |
+
* Get the list of possible bulk actions.
|
307 |
*
|
308 |
* @since 1.1
|
309 |
*
|
310 |
+
* @return string[] Array of bulk actions.
|
311 |
*/
|
312 |
public function get_bulk_actions() {
|
313 |
return array( 'delete' => __( 'Delete', 'polylang' ) );
|
331 |
* @since 1.1
|
332 |
*
|
333 |
* @param string $which only 'top' is supported
|
334 |
+
* @return void
|
335 |
*/
|
336 |
public function extra_tablenav( $which ) {
|
337 |
if ( 'top' !== $which ) {
|
347 |
echo '<select id="select-group" name="group">' . "\n";
|
348 |
printf(
|
349 |
'<option value="-1"%s>%s</option>' . "\n",
|
350 |
+
selected( $this->selected_group, -1, false ),
|
351 |
esc_html__( 'View all groups', 'polylang' )
|
352 |
);
|
353 |
|
370 |
* Optionaly clean the DB
|
371 |
*
|
372 |
* @since 1.9
|
373 |
+
*
|
374 |
+
* @return void
|
375 |
*/
|
376 |
public function save_translations() {
|
377 |
check_admin_referer( 'string-translation', '_wpnonce_string-translation' );
|
378 |
|
379 |
if ( ! empty( $_POST['submit'] ) ) {
|
380 |
foreach ( $this->languages as $language ) {
|
381 |
+
if ( empty( $_POST['translation'][ $language->slug ] ) || ! is_array( $_POST['translation'][ $language->slug ] ) ) { // In case the language filter is active ( thanks to John P. Bloch )
|
382 |
continue;
|
383 |
}
|
384 |
|
settings/view-tab-lang.php
CHANGED
@@ -160,7 +160,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
160 |
*
|
161 |
* @since 1.7.10
|
162 |
*
|
163 |
-
* @param
|
164 |
*/
|
165 |
do_action( 'pll_language_edit_form_fields', $edit_lang );
|
166 |
} else {
|
160 |
*
|
161 |
* @since 1.7.10
|
162 |
*
|
163 |
+
* @param PLL_Language $lang language being edited.
|
164 |
*/
|
165 |
do_action( 'pll_language_edit_form_fields', $edit_lang );
|
166 |
} else {
|
uninstall.php
CHANGED
@@ -52,18 +52,6 @@ class PLL_Uninstall {
|
|
52 |
|
53 |
do_action( 'pll_uninstall' );
|
54 |
|
55 |
-
// Suppress data of the old model < 1.2
|
56 |
-
// FIXME: to remove when support for v1.1.6 will be dropped
|
57 |
-
$wpdb->termmeta = $wpdb->prefix . 'termmeta'; // registers the termmeta table in wpdb
|
58 |
-
|
59 |
-
// Do nothing if the termmeta table does not exists
|
60 |
-
if ( count( $wpdb->get_results( "SHOW TABLES LIKE '$wpdb->termmeta'" ) ) ) {
|
61 |
-
$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE meta_key = '_translations'" );
|
62 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_language'" );
|
63 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_rtl'" );
|
64 |
-
$wpdb->query( "DELETE FROM $wpdb->termmeta WHERE meta_key = '_translations'" );
|
65 |
-
}
|
66 |
-
|
67 |
// Need to register the taxonomies
|
68 |
$pll_taxonomies = array( 'language', 'term_language', 'post_translations', 'term_translations' );
|
69 |
foreach ( $pll_taxonomies as $taxonomy ) {
|
@@ -96,13 +84,7 @@ class PLL_Uninstall {
|
|
96 |
wp_delete_post( $id, true );
|
97 |
}
|
98 |
|
99 |
-
// Delete the strings translations
|
100 |
-
// FIXME: to remove when support for v1.1.6 will be dropped
|
101 |
-
foreach ( $languages as $lang ) {
|
102 |
-
delete_option( 'polylang_mo' . $lang->term_id );
|
103 |
-
}
|
104 |
-
|
105 |
-
// Delete the strings translations 1.2+
|
106 |
register_post_type( 'polylang_mo', array( 'rewrite' => false, 'query_var' => false ) );
|
107 |
$ids = get_posts(
|
108 |
array(
|
@@ -146,7 +128,6 @@ class PLL_Uninstall {
|
|
146 |
|
147 |
// Delete transients
|
148 |
delete_transient( 'pll_languages_list' );
|
149 |
-
delete_transient( 'pll_upgrade_1_4' );
|
150 |
}
|
151 |
}
|
152 |
|
52 |
|
53 |
do_action( 'pll_uninstall' );
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
// Need to register the taxonomies
|
56 |
$pll_taxonomies = array( 'language', 'term_language', 'post_translations', 'term_translations' );
|
57 |
foreach ( $pll_taxonomies as $taxonomy ) {
|
84 |
wp_delete_post( $id, true );
|
85 |
}
|
86 |
|
87 |
+
// Delete the strings translations.
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
register_post_type( 'polylang_mo', array( 'rewrite' => false, 'query_var' => false ) );
|
89 |
$ids = get_posts(
|
90 |
array(
|
128 |
|
129 |
// Delete transients
|
130 |
delete_transient( 'pll_languages_list' );
|
|
|
131 |
}
|
132 |
}
|
133 |
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit526218cdfc05347def14cd0ba4a67216::getLoader();
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -7,6 +7,9 @@ $baseDir = dirname($vendorDir);
|
|
7 |
|
8 |
return array(
|
9 |
'PLL_AS3CF' => $baseDir . '/integrations/wp-offload-media/as3cf.php',
|
|
|
|
|
|
|
10 |
'PLL_Admin' => $baseDir . '/admin/admin.php',
|
11 |
'PLL_Admin_Base' => $baseDir . '/admin/admin-base.php',
|
12 |
'PLL_Admin_Block_Editor' => $baseDir . '/admin/admin-block-editor.php',
|
@@ -17,6 +20,7 @@ return array(
|
|
17 |
'PLL_Admin_Filters_Post' => $baseDir . '/admin/admin-filters-post.php',
|
18 |
'PLL_Admin_Filters_Post_Base' => $baseDir . '/admin/admin-filters-post-base.php',
|
19 |
'PLL_Admin_Filters_Term' => $baseDir . '/admin/admin-filters-term.php',
|
|
|
20 |
'PLL_Admin_Links' => $baseDir . '/admin/admin-links.php',
|
21 |
'PLL_Admin_Model' => $baseDir . '/admin/admin-model.php',
|
22 |
'PLL_Admin_Nav_Menu' => $baseDir . '/admin/admin-nav-menu.php',
|
@@ -43,6 +47,7 @@ return array(
|
|
43 |
'PLL_Filters' => $baseDir . '/include/filters.php',
|
44 |
'PLL_Filters_Links' => $baseDir . '/include/filters-links.php',
|
45 |
'PLL_Filters_Sanitization' => $baseDir . '/include/filters-sanitization.php',
|
|
|
46 |
'PLL_Frontend' => $baseDir . '/frontend/frontend.php',
|
47 |
'PLL_Frontend_Auto_Translate' => $baseDir . '/frontend/frontend-auto-translate.php',
|
48 |
'PLL_Frontend_Filters' => $baseDir . '/frontend/frontend-filters.php',
|
@@ -73,7 +78,6 @@ return array(
|
|
73 |
'PLL_No_Category_Base' => $baseDir . '/integrations/no-category-base/no-category-base.php',
|
74 |
'PLL_OLT_Manager' => $baseDir . '/include/olt-manager.php',
|
75 |
'PLL_Plugin_Updater' => $baseDir . '/install/plugin-updater.php',
|
76 |
-
'PLL_Pointer' => $baseDir . '/include/pointer.php',
|
77 |
'PLL_Query' => $baseDir . '/include/query.php',
|
78 |
'PLL_REST_Request' => $baseDir . '/include/rest-request.php',
|
79 |
'PLL_Settings' => $baseDir . '/settings/settings.php',
|
@@ -88,6 +92,7 @@ return array(
|
|
88 |
'PLL_Settings_Url' => $baseDir . '/settings/settings-url.php',
|
89 |
'PLL_Settings_WPML' => $baseDir . '/modules/wpml/settings-wpml.php',
|
90 |
'PLL_Sitemaps' => $baseDir . '/modules/sitemaps/sitemaps.php',
|
|
|
91 |
'PLL_Static_Pages' => $baseDir . '/include/static-pages.php',
|
92 |
'PLL_Switcher' => $baseDir . '/include/switcher.php',
|
93 |
'PLL_Sync' => $baseDir . '/modules/sync/sync.php',
|
7 |
|
8 |
return array(
|
9 |
'PLL_AS3CF' => $baseDir . '/integrations/wp-offload-media/as3cf.php',
|
10 |
+
'PLL_Abstract_Sitemaps' => $baseDir . '/modules/sitemaps/abstract-sitemaps.php',
|
11 |
+
'PLL_Accept_Language' => $baseDir . '/frontend/accept-language.php',
|
12 |
+
'PLL_Accept_Languages_Collection' => $baseDir . '/frontend/accept-languages-collection.php',
|
13 |
'PLL_Admin' => $baseDir . '/admin/admin.php',
|
14 |
'PLL_Admin_Base' => $baseDir . '/admin/admin-base.php',
|
15 |
'PLL_Admin_Block_Editor' => $baseDir . '/admin/admin-block-editor.php',
|
20 |
'PLL_Admin_Filters_Post' => $baseDir . '/admin/admin-filters-post.php',
|
21 |
'PLL_Admin_Filters_Post_Base' => $baseDir . '/admin/admin-filters-post-base.php',
|
22 |
'PLL_Admin_Filters_Term' => $baseDir . '/admin/admin-filters-term.php',
|
23 |
+
'PLL_Admin_Filters_Widgets_Options' => $baseDir . '/admin/admin-filters-widgets-options.php',
|
24 |
'PLL_Admin_Links' => $baseDir . '/admin/admin-links.php',
|
25 |
'PLL_Admin_Model' => $baseDir . '/admin/admin-model.php',
|
26 |
'PLL_Admin_Nav_Menu' => $baseDir . '/admin/admin-nav-menu.php',
|
47 |
'PLL_Filters' => $baseDir . '/include/filters.php',
|
48 |
'PLL_Filters_Links' => $baseDir . '/include/filters-links.php',
|
49 |
'PLL_Filters_Sanitization' => $baseDir . '/include/filters-sanitization.php',
|
50 |
+
'PLL_Filters_Widgets_Options' => $baseDir . '/include/filters-widgets-options.php',
|
51 |
'PLL_Frontend' => $baseDir . '/frontend/frontend.php',
|
52 |
'PLL_Frontend_Auto_Translate' => $baseDir . '/frontend/frontend-auto-translate.php',
|
53 |
'PLL_Frontend_Filters' => $baseDir . '/frontend/frontend-filters.php',
|
78 |
'PLL_No_Category_Base' => $baseDir . '/integrations/no-category-base/no-category-base.php',
|
79 |
'PLL_OLT_Manager' => $baseDir . '/include/olt-manager.php',
|
80 |
'PLL_Plugin_Updater' => $baseDir . '/install/plugin-updater.php',
|
|
|
81 |
'PLL_Query' => $baseDir . '/include/query.php',
|
82 |
'PLL_REST_Request' => $baseDir . '/include/rest-request.php',
|
83 |
'PLL_Settings' => $baseDir . '/settings/settings.php',
|
92 |
'PLL_Settings_Url' => $baseDir . '/settings/settings-url.php',
|
93 |
'PLL_Settings_WPML' => $baseDir . '/modules/wpml/settings-wpml.php',
|
94 |
'PLL_Sitemaps' => $baseDir . '/modules/sitemaps/sitemaps.php',
|
95 |
+
'PLL_Sitemaps_Domain' => $baseDir . '/modules/sitemaps/sitemaps-domain.php',
|
96 |
'PLL_Static_Pages' => $baseDir . '/include/static-pages.php',
|
97 |
'PLL_Switcher' => $baseDir . '/include/switcher.php',
|
98 |
'PLL_Sync' => $baseDir . '/modules/sync/sync.php',
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -22,15 +22,15 @@ class ComposerAutoloaderInitb2e9581550b70057025a8e7128ef798f
|
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
-
spl_autoload_register(array('
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
-
spl_autoload_unregister(array('
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
-
call_user_func(\Composer\Autoload\
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit526218cdfc05347def14cd0ba4a67216
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
22 |
return self::$loader;
|
23 |
}
|
24 |
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit526218cdfc05347def14cd0ba4a67216', 'loadClassLoader'), true, true);
|
26 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit526218cdfc05347def14cd0ba4a67216', 'loadClassLoader'));
|
28 |
|
29 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
if ($useStaticLoader) {
|
31 |
require_once __DIR__ . '/autoload_static.php';
|
32 |
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit526218cdfc05347def14cd0ba4a67216::getInitializer($loader));
|
34 |
} else {
|
35 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
foreach ($map as $namespace => $path) {
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,10 +4,13 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $classMap = array (
|
10 |
'PLL_AS3CF' => __DIR__ . '/../..' . '/integrations/wp-offload-media/as3cf.php',
|
|
|
|
|
|
|
11 |
'PLL_Admin' => __DIR__ . '/../..' . '/admin/admin.php',
|
12 |
'PLL_Admin_Base' => __DIR__ . '/../..' . '/admin/admin-base.php',
|
13 |
'PLL_Admin_Block_Editor' => __DIR__ . '/../..' . '/admin/admin-block-editor.php',
|
@@ -18,6 +21,7 @@ class ComposerStaticInitb2e9581550b70057025a8e7128ef798f
|
|
18 |
'PLL_Admin_Filters_Post' => __DIR__ . '/../..' . '/admin/admin-filters-post.php',
|
19 |
'PLL_Admin_Filters_Post_Base' => __DIR__ . '/../..' . '/admin/admin-filters-post-base.php',
|
20 |
'PLL_Admin_Filters_Term' => __DIR__ . '/../..' . '/admin/admin-filters-term.php',
|
|
|
21 |
'PLL_Admin_Links' => __DIR__ . '/../..' . '/admin/admin-links.php',
|
22 |
'PLL_Admin_Model' => __DIR__ . '/../..' . '/admin/admin-model.php',
|
23 |
'PLL_Admin_Nav_Menu' => __DIR__ . '/../..' . '/admin/admin-nav-menu.php',
|
@@ -44,6 +48,7 @@ class ComposerStaticInitb2e9581550b70057025a8e7128ef798f
|
|
44 |
'PLL_Filters' => __DIR__ . '/../..' . '/include/filters.php',
|
45 |
'PLL_Filters_Links' => __DIR__ . '/../..' . '/include/filters-links.php',
|
46 |
'PLL_Filters_Sanitization' => __DIR__ . '/../..' . '/include/filters-sanitization.php',
|
|
|
47 |
'PLL_Frontend' => __DIR__ . '/../..' . '/frontend/frontend.php',
|
48 |
'PLL_Frontend_Auto_Translate' => __DIR__ . '/../..' . '/frontend/frontend-auto-translate.php',
|
49 |
'PLL_Frontend_Filters' => __DIR__ . '/../..' . '/frontend/frontend-filters.php',
|
@@ -74,7 +79,6 @@ class ComposerStaticInitb2e9581550b70057025a8e7128ef798f
|
|
74 |
'PLL_No_Category_Base' => __DIR__ . '/../..' . '/integrations/no-category-base/no-category-base.php',
|
75 |
'PLL_OLT_Manager' => __DIR__ . '/../..' . '/include/olt-manager.php',
|
76 |
'PLL_Plugin_Updater' => __DIR__ . '/../..' . '/install/plugin-updater.php',
|
77 |
-
'PLL_Pointer' => __DIR__ . '/../..' . '/include/pointer.php',
|
78 |
'PLL_Query' => __DIR__ . '/../..' . '/include/query.php',
|
79 |
'PLL_REST_Request' => __DIR__ . '/../..' . '/include/rest-request.php',
|
80 |
'PLL_Settings' => __DIR__ . '/../..' . '/settings/settings.php',
|
@@ -89,6 +93,7 @@ class ComposerStaticInitb2e9581550b70057025a8e7128ef798f
|
|
89 |
'PLL_Settings_Url' => __DIR__ . '/../..' . '/settings/settings-url.php',
|
90 |
'PLL_Settings_WPML' => __DIR__ . '/../..' . '/modules/wpml/settings-wpml.php',
|
91 |
'PLL_Sitemaps' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps.php',
|
|
|
92 |
'PLL_Static_Pages' => __DIR__ . '/../..' . '/include/static-pages.php',
|
93 |
'PLL_Switcher' => __DIR__ . '/../..' . '/include/switcher.php',
|
94 |
'PLL_Sync' => __DIR__ . '/../..' . '/modules/sync/sync.php',
|
@@ -126,7 +131,7 @@ class ComposerStaticInitb2e9581550b70057025a8e7128ef798f
|
|
126 |
public static function getInitializer(ClassLoader $loader)
|
127 |
{
|
128 |
return \Closure::bind(function () use ($loader) {
|
129 |
-
$loader->classMap =
|
130 |
|
131 |
}, null, ClassLoader::class);
|
132 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInit526218cdfc05347def14cd0ba4a67216
|
8 |
{
|
9 |
public static $classMap = array (
|
10 |
'PLL_AS3CF' => __DIR__ . '/../..' . '/integrations/wp-offload-media/as3cf.php',
|
11 |
+
'PLL_Abstract_Sitemaps' => __DIR__ . '/../..' . '/modules/sitemaps/abstract-sitemaps.php',
|
12 |
+
'PLL_Accept_Language' => __DIR__ . '/../..' . '/frontend/accept-language.php',
|
13 |
+
'PLL_Accept_Languages_Collection' => __DIR__ . '/../..' . '/frontend/accept-languages-collection.php',
|
14 |
'PLL_Admin' => __DIR__ . '/../..' . '/admin/admin.php',
|
15 |
'PLL_Admin_Base' => __DIR__ . '/../..' . '/admin/admin-base.php',
|
16 |
'PLL_Admin_Block_Editor' => __DIR__ . '/../..' . '/admin/admin-block-editor.php',
|
21 |
'PLL_Admin_Filters_Post' => __DIR__ . '/../..' . '/admin/admin-filters-post.php',
|
22 |
'PLL_Admin_Filters_Post_Base' => __DIR__ . '/../..' . '/admin/admin-filters-post-base.php',
|
23 |
'PLL_Admin_Filters_Term' => __DIR__ . '/../..' . '/admin/admin-filters-term.php',
|
24 |
+
'PLL_Admin_Filters_Widgets_Options' => __DIR__ . '/../..' . '/admin/admin-filters-widgets-options.php',
|
25 |
'PLL_Admin_Links' => __DIR__ . '/../..' . '/admin/admin-links.php',
|
26 |
'PLL_Admin_Model' => __DIR__ . '/../..' . '/admin/admin-model.php',
|
27 |
'PLL_Admin_Nav_Menu' => __DIR__ . '/../..' . '/admin/admin-nav-menu.php',
|
48 |
'PLL_Filters' => __DIR__ . '/../..' . '/include/filters.php',
|
49 |
'PLL_Filters_Links' => __DIR__ . '/../..' . '/include/filters-links.php',
|
50 |
'PLL_Filters_Sanitization' => __DIR__ . '/../..' . '/include/filters-sanitization.php',
|
51 |
+
'PLL_Filters_Widgets_Options' => __DIR__ . '/../..' . '/include/filters-widgets-options.php',
|
52 |
'PLL_Frontend' => __DIR__ . '/../..' . '/frontend/frontend.php',
|
53 |
'PLL_Frontend_Auto_Translate' => __DIR__ . '/../..' . '/frontend/frontend-auto-translate.php',
|
54 |
'PLL_Frontend_Filters' => __DIR__ . '/../..' . '/frontend/frontend-filters.php',
|
79 |
'PLL_No_Category_Base' => __DIR__ . '/../..' . '/integrations/no-category-base/no-category-base.php',
|
80 |
'PLL_OLT_Manager' => __DIR__ . '/../..' . '/include/olt-manager.php',
|
81 |
'PLL_Plugin_Updater' => __DIR__ . '/../..' . '/install/plugin-updater.php',
|
|
|
82 |
'PLL_Query' => __DIR__ . '/../..' . '/include/query.php',
|
83 |
'PLL_REST_Request' => __DIR__ . '/../..' . '/include/rest-request.php',
|
84 |
'PLL_Settings' => __DIR__ . '/../..' . '/settings/settings.php',
|
93 |
'PLL_Settings_Url' => __DIR__ . '/../..' . '/settings/settings-url.php',
|
94 |
'PLL_Settings_WPML' => __DIR__ . '/../..' . '/modules/wpml/settings-wpml.php',
|
95 |
'PLL_Sitemaps' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps.php',
|
96 |
+
'PLL_Sitemaps_Domain' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps-domain.php',
|
97 |
'PLL_Static_Pages' => __DIR__ . '/../..' . '/include/static-pages.php',
|
98 |
'PLL_Switcher' => __DIR__ . '/../..' . '/include/switcher.php',
|
99 |
'PLL_Sync' => __DIR__ . '/../..' . '/modules/sync/sync.php',
|
131 |
public static function getInitializer(ClassLoader $loader)
|
132 |
{
|
133 |
return \Closure::bind(function () use ($loader) {
|
134 |
+
$loader->classMap = ComposerStaticInit526218cdfc05347def14cd0ba4a67216::$classMap;
|
135 |
|
136 |
}, null, ClassLoader::class);
|
137 |
}
|