Version Description
(2022-11-28) =
- Requires WP 5.7 as minimum version
- Pro: Allow to export and import XLIFF files for posts
- Pro: Honor the provided context for the navigation language switcher block.
- Pro: Remove the parent hyperlink in the navigation language switcher block.
- Pro: Add spacing between flag and name in the navigation language switcher block.
- Pro: Disallow some special characters in translated slugs to avoid 404 errors.
- Pro: Fix string translation not imported when the original is registered but has never been saved in database.
- Pro: Fix string translation not imported when it includes an html entity.
- Pro: Fix navigation language switcher block rendering in block editor.
- Pro: Fix navigation language switcher may be displayed wrong color.
- Translate the post pages in get_post_type_archive_link() on admin side too. #1000
- Enable the block editor in page for posts translations to match the WordPress behavior since version 5.8 #1002
- Improve the site health report #1062 #1076
- Set the current language when saving a post #1065
- The search block is now filtered by language #1081
- Display slug of CPT and taxonomies in Custom post types and Taxonomies settings. Props @nicomollet #1112
- Add support for wpml-config.xml to MU plugins #1140 Props Jeremy Simkins
- Fix some deprecated notices fired by PHP 8.1 #975
- Fix some missing canonical redirect taxonomies #1074
- Fix redirect when permalink structure has no trailing slash #1080
- Fix language switcher in legacy navigation menu widget not rendered in widgets block editor #1083
- Fix language in tax query when an OR relation is used #1098
- Fix parent of translated category removed when assigning an untranslated parent #1105
- Fix is_front_page() when a static front page is not translated #1123
- Yoast SEO: Fix posts without language displayed in the sitemap #1103
- Yoast SEO: Avoid syncing robots meta. #1118
Download this release
Release Info
Developer | Chouby |
Plugin | Polylang |
Version | 3.3 |
Comparing to | |
See all releases |
Code changes from version 3.2.8 to 3.3
- admin/admin-base.php +48 -20
- admin/admin-block-editor.php +1 -1
- admin/admin-classic-editor.php +3 -3
- admin/admin-default-term.php +1 -1
- admin/admin-filters-columns.php +2 -2
- admin/admin-filters-media.php +1 -1
- admin/admin-filters-post-base.php +9 -2
- admin/admin-filters-post.php +2 -2
- admin/admin-filters-term.php +92 -72
- admin/admin-model.php +8 -8
- admin/admin-static-pages.php +1 -47
- admin/admin-strings.php +1 -1
- admin/admin.php +10 -10
- frontend/canonical.php +266 -0
- frontend/choose-lang.php +23 -14
- frontend/frontend-auto-translate.php +6 -3
- frontend/frontend-filters-links.php +30 -261
- frontend/frontend-filters-search.php +23 -11
- frontend/frontend-filters-widgets.php +1 -1
- frontend/frontend-filters.php +9 -1
- frontend/frontend-links.php +5 -9
- frontend/frontend-nav-menu.php +5 -1
- frontend/frontend-static-pages.php +7 -28
- frontend/frontend.php +18 -10
- include/base.php +3 -2
- include/cache.php +1 -1
- include/class-polylang.php +4 -4
- include/crud-posts.php +10 -8
- include/crud-terms.php +89 -7
- include/db-tools.php +6 -5
- include/filters-links.php +7 -7
- include/filters.php +5 -5
- include/language.php +23 -14
- include/license.php +1 -1
- include/links-abstract-domain.php +11 -12
- include/links-default.php +20 -25
- include/links-directory.php +40 -44
- include/links-domain.php +14 -18
- include/links-model.php +19 -22
- include/links-permalinks.php +22 -22
- include/links-subdomain.php +11 -13
- include/links.php +7 -0
- include/model.php +39 -10
- include/olt-manager.php +5 -5
- include/query.php +49 -7
- include/rest-request.php +32 -15
- include/static-pages.php +40 -10
- include/switcher.php +1 -1
- include/translate-option.php +1 -1
- include/translated-object.php +33 -23
- include/translated-term.php +0 -20
- include/walker-dropdown.php +1 -1
- include/walker-list.php +1 -1
- include/widget-languages.php +4 -1
- install/t15s.php +2 -2
- install/upgrade.php +4 -1
- integrations/integrations.php +2 -1
- integrations/wp-importer/wp-import.php +1 -1
- integrations/wp-offload-media/as3cf.php +1 -1
- integrations/wpseo/wpseo.php +58 -29
- js/build/block-editor.js +58 -63
- js/build/block-editor.min.js +1 -1
- js/build/classic-editor.js +47 -40
- js/build/classic-editor.min.js +1 -1
- js/build/post.js +67 -64
- js/build/post.min.js +1 -1
- js/build/term.js +22 -16
- js/build/term.min.js +1 -1
- modules/site-health/admin-site-health.php +121 -45
- modules/sitemaps/sitemaps.php +0 -13
- modules/sync/sync-metas.php +8 -7
- modules/sync/sync-tax.php +2 -2
- modules/sync/sync.php +1 -1
- modules/wizard/wizard.php +1 -1
- modules/wpml/wpml-api.php +1 -1
- modules/wpml/wpml-compat.php +1 -1
- modules/wpml/wpml-config.php +529 -113
- modules/wpml/wpml-legacy-api.php +7 -4
- polylang.php +4 -4
- readme.txt +32 -3
- settings/settings-browser.php +2 -0
- settings/settings-cpt.php +18 -4
- settings/settings-module.php +1 -1
- settings/settings-url.php +2 -2
- settings/settings.php +2 -2
- settings/table-string.php +7 -3
- uninstall.php +2 -2
- vendor/composer/InstalledVersions.php +352 -0
- vendor/composer/autoload_classmap.php +1 -0
- vendor/composer/autoload_static.php +1 -0
- vendor/composer/installed.php +23 -0
- vendor/composer/platform_check.php +26 -0
admin/admin-base.php
CHANGED
@@ -12,46 +12,46 @@ 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 |
-
* @var PLL_Admin_Default_Term
|
55 |
*/
|
56 |
public $default_term;
|
57 |
|
@@ -123,7 +123,7 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
123 |
|
124 |
// Only if at least one language has been created
|
125 |
if ( $this->model->get_languages_list() ) {
|
126 |
-
$tabs['strings'] = __( '
|
127 |
}
|
128 |
|
129 |
$tabs['settings'] = __( 'Settings', 'polylang' );
|
@@ -178,6 +178,8 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
178 |
'widgets' => array( array( 'widgets' ), array( 'jquery' ), 0, 0 ),
|
179 |
);
|
180 |
|
|
|
|
|
181 |
if ( ! empty( $screen->post_type ) && $this->model->is_translated_post_type( $screen->post_type ) ) {
|
182 |
$scripts['post'] = array( array( 'edit', 'upload' ), array( 'jquery', 'wp-ajax-response' ), 0, 1 );
|
183 |
|
@@ -187,9 +189,11 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
187 |
}
|
188 |
|
189 |
// Block editor with legacy metabox in WP 5.0+.
|
190 |
-
|
191 |
-
|
192 |
-
|
|
|
|
|
193 |
}
|
194 |
|
195 |
if ( ! empty( $screen->taxonomy ) && $this->model->is_translated_taxonomy( $screen->taxonomy ) ) {
|
@@ -208,7 +212,20 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
208 |
wp_register_style( 'polylang_admin', plugins_url( '/css/build/admin' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
|
209 |
wp_enqueue_style( 'polylang_dialog', plugins_url( '/css/build/dialog' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'polylang_admin' ), POLYLANG_VERSION );
|
210 |
|
211 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
213 |
|
214 |
/**
|
@@ -222,18 +239,27 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
222 |
if ( $this->model->get_languages_list() ) {
|
223 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
224 |
wp_enqueue_script( 'pll_widgets', plugins_url( '/js/build/widgets' . $suffix . '.js', POLYLANG_ROOT_FILE ), array( 'jquery' ), POLYLANG_VERSION, true );
|
225 |
-
$this->
|
226 |
}
|
227 |
}
|
228 |
|
229 |
/**
|
230 |
-
*
|
|
|
231 |
*
|
232 |
-
* @since
|
233 |
*
|
234 |
* @return void
|
235 |
*/
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
if ( wp_script_is( 'pll_widgets', 'enqueued' ) ) {
|
238 |
wp_localize_script(
|
239 |
'pll_widgets',
|
@@ -345,7 +371,9 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
345 |
// Edit Post
|
346 |
if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
347 |
$this->curlang = $lang;
|
348 |
-
} elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && $this->model->is_translated_post_type( get_post_type( (int) $_GET['post'] ) ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
|
|
|
|
349 |
$this->curlang = $lang;
|
350 |
} elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( sanitize_key( $_GET['post_type'] ) ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
351 |
$this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -354,8 +382,8 @@ abstract class PLL_Admin_Base extends PLL_Base {
|
|
354 |
// Edit Term
|
355 |
elseif ( isset( $_REQUEST['pll_term_id'] ) && $lang = $this->model->term->get_language( (int) $_REQUEST['pll_term_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
356 |
$this->curlang = $lang;
|
357 |
-
} elseif ( in_array( $GLOBALS['pagenow'], array( 'edit-tags.php', 'term.php' ) ) && isset( $
|
358 |
-
if ( isset( $
|
359 |
$this->curlang = $lang;
|
360 |
} elseif ( ! empty( $_GET['new_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
361 |
$this->curlang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
12 |
/**
|
13 |
* Current language (used to filter the content).
|
14 |
*
|
15 |
+
* @var PLL_Language|null
|
16 |
*/
|
17 |
public $curlang;
|
18 |
|
19 |
/**
|
20 |
* Language selected in the admin language filter.
|
21 |
*
|
22 |
+
* @var PLL_Language|null
|
23 |
*/
|
24 |
public $filter_lang;
|
25 |
|
26 |
/**
|
27 |
* Preferred language to assign to new contents.
|
28 |
*
|
29 |
+
* @var PLL_Language|null
|
30 |
*/
|
31 |
public $pref_lang;
|
32 |
|
33 |
/**
|
34 |
+
* @var PLL_Filters_Links|null
|
35 |
*/
|
36 |
public $filters_links;
|
37 |
|
38 |
/**
|
39 |
+
* @var PLL_Admin_Links|null
|
40 |
*/
|
41 |
public $links;
|
42 |
|
43 |
/**
|
44 |
+
* @var PLL_Admin_Notices|null
|
45 |
*/
|
46 |
public $notices;
|
47 |
|
48 |
/**
|
49 |
+
* @var PLL_Admin_Static_Pages|null
|
50 |
*/
|
51 |
public $static_pages;
|
52 |
|
53 |
/**
|
54 |
+
* @var PLL_Admin_Default_Term|null
|
55 |
*/
|
56 |
public $default_term;
|
57 |
|
123 |
|
124 |
// Only if at least one language has been created
|
125 |
if ( $this->model->get_languages_list() ) {
|
126 |
+
$tabs['strings'] = __( 'Translations', 'polylang' );
|
127 |
}
|
128 |
|
129 |
$tabs['settings'] = __( 'Settings', 'polylang' );
|
178 |
'widgets' => array( array( 'widgets' ), array( 'jquery' ), 0, 0 ),
|
179 |
);
|
180 |
|
181 |
+
$block_screens = array( 'widgets', 'site-editor' );
|
182 |
+
|
183 |
if ( ! empty( $screen->post_type ) && $this->model->is_translated_post_type( $screen->post_type ) ) {
|
184 |
$scripts['post'] = array( array( 'edit', 'upload' ), array( 'jquery', 'wp-ajax-response' ), 0, 1 );
|
185 |
|
189 |
}
|
190 |
|
191 |
// Block editor with legacy metabox in WP 5.0+.
|
192 |
+
$block_screens[] = 'post';
|
193 |
+
}
|
194 |
+
|
195 |
+
if ( $this->is_block_editor( $screen ) ) {
|
196 |
+
$scripts['block-editor'] = array( $block_screens, array( 'jquery', 'wp-ajax-response', 'wp-api-fetch', 'jquery-ui-dialog', 'wp-i18n' ), 0, 1 );
|
197 |
}
|
198 |
|
199 |
if ( ! empty( $screen->taxonomy ) && $this->model->is_translated_taxonomy( $screen->taxonomy ) ) {
|
212 |
wp_register_style( 'polylang_admin', plugins_url( '/css/build/admin' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'wp-jquery-ui-dialog' ), POLYLANG_VERSION );
|
213 |
wp_enqueue_style( 'polylang_dialog', plugins_url( '/css/build/dialog' . $suffix . '.css', POLYLANG_ROOT_FILE ), array( 'polylang_admin' ), POLYLANG_VERSION );
|
214 |
|
215 |
+
$this->add_inline_scripts();
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Tells whether or not the given screen is block editor kind.
|
220 |
+
* e.g. widget, site or post editor.
|
221 |
+
*
|
222 |
+
* @since 3.3
|
223 |
+
*
|
224 |
+
* @param WP_Screen $screen Screen object.
|
225 |
+
* @return bool True if the screen is a block editor, false otherwise.
|
226 |
+
*/
|
227 |
+
protected function is_block_editor( $screen ) {
|
228 |
+
return method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() && ! pll_use_block_editor_plugin();
|
229 |
}
|
230 |
|
231 |
/**
|
239 |
if ( $this->model->get_languages_list() ) {
|
240 |
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
241 |
wp_enqueue_script( 'pll_widgets', plugins_url( '/js/build/widgets' . $suffix . '.js', POLYLANG_ROOT_FILE ), array( 'jquery' ), POLYLANG_VERSION, true );
|
242 |
+
$this->add_inline_scripts();
|
243 |
}
|
244 |
}
|
245 |
|
246 |
/**
|
247 |
+
* Adds inline scripts to set the default language in JS
|
248 |
+
* and localizes scripts.
|
249 |
*
|
250 |
+
* @since 3.3
|
251 |
*
|
252 |
* @return void
|
253 |
*/
|
254 |
+
private function add_inline_scripts() {
|
255 |
+
if ( wp_script_is( 'pll_block-editor', 'enqueued' ) ) {
|
256 |
+
$default_lang_script = 'const pllDefaultLanguage = "' . $this->options['default_lang'] . '";';
|
257 |
+
wp_add_inline_script(
|
258 |
+
'pll_block-editor',
|
259 |
+
$default_lang_script,
|
260 |
+
'before'
|
261 |
+
);
|
262 |
+
}
|
263 |
if ( wp_script_is( 'pll_widgets', 'enqueued' ) ) {
|
264 |
wp_localize_script(
|
265 |
'pll_widgets',
|
371 |
// Edit Post
|
372 |
if ( isset( $_REQUEST['pll_post_id'] ) && $lang = $this->model->post->get_language( (int) $_REQUEST['pll_post_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
373 |
$this->curlang = $lang;
|
374 |
+
} elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_GET['post'] ) && false !== get_post_type( (int) $_GET['post'] ) && $this->model->is_translated_post_type( get_post_type( (int) $_GET['post'] ) ) && $lang = $this->model->post->get_language( (int) $_GET['post'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
375 |
+
$this->curlang = $lang;
|
376 |
+
} elseif ( 'post.php' === $GLOBALS['pagenow'] && isset( $_POST['post_ID'] ) && false !== get_post_type( (int) $_POST['post_ID'] ) && $this->model->is_translated_post_type( get_post_type( (int) $_POST['post_ID'] ) ) && $lang = $this->model->post->get_language( (int) $_POST['post_ID'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
377 |
$this->curlang = $lang;
|
378 |
} elseif ( 'post-new.php' === $GLOBALS['pagenow'] && ( empty( $_GET['post_type'] ) || $this->model->is_translated_post_type( sanitize_key( $_GET['post_type'] ) ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
379 |
$this->curlang = empty( $_GET['new_lang'] ) ? $this->pref_lang : $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
382 |
// Edit Term
|
383 |
elseif ( isset( $_REQUEST['pll_term_id'] ) && $lang = $this->model->term->get_language( (int) $_REQUEST['pll_term_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
384 |
$this->curlang = $lang;
|
385 |
+
} elseif ( in_array( $GLOBALS['pagenow'], array( 'edit-tags.php', 'term.php' ) ) && isset( $_REQUEST['taxonomy'] ) && $this->model->is_translated_taxonomy( sanitize_key( $_REQUEST['taxonomy'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
386 |
+
if ( isset( $_REQUEST['tag_ID'] ) && $lang = $this->model->term->get_language( (int) $_REQUEST['tag_ID'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
387 |
$this->curlang = $lang;
|
388 |
} elseif ( ! empty( $_GET['new_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
389 |
$this->curlang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
admin/admin-block-editor.php
CHANGED
@@ -17,7 +17,7 @@ class PLL_Admin_Block_Editor {
|
|
17 |
/**
|
18 |
* Preferred language to assign to a new post.
|
19 |
*
|
20 |
-
* @var PLL_Language
|
21 |
*/
|
22 |
protected $pref_lang;
|
23 |
|
17 |
/**
|
18 |
* Preferred language to assign to a new post.
|
19 |
*
|
20 |
+
* @var PLL_Language|null
|
21 |
*/
|
22 |
protected $pref_lang;
|
23 |
|
admin/admin-classic-editor.php
CHANGED
@@ -15,21 +15,21 @@ class PLL_Admin_Classic_Editor {
|
|
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 |
|
15 |
public $model;
|
16 |
|
17 |
/**
|
18 |
+
* @var PLL_Admin_Links|null
|
19 |
*/
|
20 |
public $links;
|
21 |
|
22 |
/**
|
23 |
* Current language (used to filter the content).
|
24 |
*
|
25 |
+
* @var PLL_Language|null
|
26 |
*/
|
27 |
public $curlang;
|
28 |
|
29 |
/**
|
30 |
* Preferred language to assign to new contents.
|
31 |
*
|
32 |
+
* @var PLL_Language|null
|
33 |
*/
|
34 |
public $pref_lang;
|
35 |
|
admin/admin-default-term.php
CHANGED
@@ -20,7 +20,7 @@ class PLL_Admin_Default_Term {
|
|
20 |
/**
|
21 |
* Preferred language to assign to new contents.
|
22 |
*
|
23 |
-
* @var PLL_Language
|
24 |
*/
|
25 |
protected $pref_lang;
|
26 |
|
20 |
/**
|
21 |
* Preferred language to assign to new contents.
|
22 |
*
|
23 |
+
* @var PLL_Language|null
|
24 |
*/
|
25 |
protected $pref_lang;
|
26 |
|
admin/admin-filters-columns.php
CHANGED
@@ -16,14 +16,14 @@ class PLL_Admin_Filters_Columns {
|
|
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 |
|
16 |
public $model;
|
17 |
|
18 |
/**
|
19 |
+
* @var PLL_Admin_Links|null
|
20 |
*/
|
21 |
public $links;
|
22 |
|
23 |
/**
|
24 |
* Language selected in the admin language filter.
|
25 |
*
|
26 |
+
* @var PLL_Language|null
|
27 |
*/
|
28 |
public $filter_lang;
|
29 |
|
admin/admin-filters-media.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
13 |
/**
|
14 |
-
* @var PLL_CRUD_Posts
|
15 |
*/
|
16 |
public $posts;
|
17 |
|
11 |
*/
|
12 |
class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
|
13 |
/**
|
14 |
+
* @var PLL_CRUD_Posts|null
|
15 |
*/
|
16 |
public $posts;
|
17 |
|
admin/admin-filters-post-base.php
CHANGED
@@ -15,17 +15,24 @@ abstract class PLL_Admin_Filters_Post_Base {
|
|
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
|
31 |
*
|
15 |
public $model;
|
16 |
|
17 |
/**
|
18 |
+
* @var PLL_Links|null
|
19 |
*/
|
20 |
public $links;
|
21 |
|
22 |
/**
|
23 |
* Language selected in the admin language filter.
|
24 |
*
|
25 |
+
* @var PLL_Language|null
|
26 |
*/
|
27 |
public $filter_lang;
|
28 |
|
29 |
+
/**
|
30 |
+
* Preferred language to assign to new contents.
|
31 |
+
*
|
32 |
+
* @var PLL_Language|null
|
33 |
+
*/
|
34 |
+
public $pref_lang;
|
35 |
+
|
36 |
/**
|
37 |
* Constructor: setups filters and actions
|
38 |
*
|
admin/admin-filters-post.php
CHANGED
@@ -12,7 +12,7 @@ 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 |
|
@@ -69,7 +69,7 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
|
|
69 |
}
|
70 |
|
71 |
if ( ! empty( $hierarchical_taxonomies ) ) {
|
72 |
-
$terms = get_terms( $hierarchical_taxonomies,
|
73 |
$term_languages = array();
|
74 |
|
75 |
if ( is_array( $terms ) ) {
|
12 |
/**
|
13 |
* Current language (used to filter the content).
|
14 |
*
|
15 |
+
* @var PLL_Language|null
|
16 |
*/
|
17 |
public $curlang;
|
18 |
|
69 |
}
|
70 |
|
71 |
if ( ! empty( $hierarchical_taxonomies ) ) {
|
72 |
+
$terms = get_terms( array( 'taxonomy' => $hierarchical_taxonomies, 'get' => 'all' ) );
|
73 |
$term_languages = array();
|
74 |
|
75 |
if ( is_array( $terms ) ) {
|
admin/admin-filters-term.php
CHANGED
@@ -22,35 +22,28 @@ class PLL_Admin_Filters_Term {
|
|
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 |
|
@@ -59,7 +52,7 @@ class PLL_Admin_Filters_Term {
|
|
59 |
*
|
60 |
* @since 2.8
|
61 |
*
|
62 |
-
* @var PLL_Admin_Default_Term
|
63 |
*/
|
64 |
protected $default_term;
|
65 |
|
@@ -69,10 +62,10 @@ class PLL_Admin_Filters_Term {
|
|
69 |
* @param object $polylang
|
70 |
*/
|
71 |
public function __construct( &$polylang ) {
|
72 |
-
$this->links
|
73 |
-
$this->model
|
74 |
-
$this->options
|
75 |
-
$this->pref_lang
|
76 |
$this->default_term = &$polylang->default_term;
|
77 |
|
78 |
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
@@ -88,8 +81,8 @@ class PLL_Admin_Filters_Term {
|
|
88 |
add_action( 'create_term', array( $this, 'save_term' ), 900, 3 );
|
89 |
add_action( 'edit_term', array( $this, 'save_term' ), 900, 3 ); // Late as it may conflict with other plugins, see http://wordpress.org/support/topic/polylang-and-wordpress-seo-by-yoast
|
90 |
add_action( 'pre_post_update', array( $this, 'pre_post_update' ) );
|
91 |
-
add_filter( '
|
92 |
-
add_filter( '
|
93 |
|
94 |
// Ajax response for edit term form
|
95 |
add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
|
@@ -258,7 +251,7 @@ class PLL_Admin_Filters_Term {
|
|
258 |
}
|
259 |
|
260 |
/**
|
261 |
-
* Stores the current post_id when bulk editing posts for use in save_language and
|
262 |
*
|
263 |
* @since 1.7
|
264 |
*
|
@@ -421,58 +414,6 @@ class PLL_Admin_Filters_Term {
|
|
421 |
}
|
422 |
}
|
423 |
|
424 |
-
/**
|
425 |
-
* Stores the term name for use in pre_term_slug
|
426 |
-
*
|
427 |
-
* @since 0.9.5
|
428 |
-
*
|
429 |
-
* @param string $name term name
|
430 |
-
* @return string unmodified term name
|
431 |
-
*/
|
432 |
-
public function pre_term_name( $name ) {
|
433 |
-
return $this->pre_term_name = $name;
|
434 |
-
}
|
435 |
-
|
436 |
-
/**
|
437 |
-
* Creates the term slug in case the term already exists in another language
|
438 |
-
*
|
439 |
-
* @since 0.9.5
|
440 |
-
*
|
441 |
-
* @param string $slug
|
442 |
-
* @param string $taxonomy
|
443 |
-
* @return string
|
444 |
-
*/
|
445 |
-
public function pre_term_slug( $slug, $taxonomy ) {
|
446 |
-
$name = sanitize_title( $this->pre_term_name );
|
447 |
-
|
448 |
-
// If the term already exists in another language
|
449 |
-
if ( ! $slug && $this->model->is_translated_taxonomy( $taxonomy ) && term_exists( $name, $taxonomy ) ) {
|
450 |
-
if ( isset( $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
451 |
-
$lang = $this->model->get_language( sanitize_key( $_POST['term_lang_choice'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
452 |
-
}
|
453 |
-
|
454 |
-
elseif ( isset( $_POST['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
455 |
-
$lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
456 |
-
}
|
457 |
-
|
458 |
-
// *Post* bulk edit, in case a new term is created
|
459 |
-
elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
460 |
-
// Bulk edit does not modify the language
|
461 |
-
if ( -1 == $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
462 |
-
$lang = $this->model->post->get_language( $this->post_id );
|
463 |
-
} else {
|
464 |
-
$lang = $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
465 |
-
}
|
466 |
-
}
|
467 |
-
|
468 |
-
if ( ! empty( $lang ) && ! $this->model->term_exists_by_slug( $name, $lang, $taxonomy ) ) {
|
469 |
-
$slug = $name . '-' . $lang->slug;
|
470 |
-
}
|
471 |
-
}
|
472 |
-
|
473 |
-
return $slug;
|
474 |
-
}
|
475 |
-
|
476 |
/**
|
477 |
* Ajax response for edit term form
|
478 |
*
|
@@ -576,7 +517,7 @@ class PLL_Admin_Filters_Term {
|
|
576 |
}
|
577 |
|
578 |
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
579 |
-
$all_terms = get_terms( $taxonomy, 'hide_empty
|
580 |
if ( is_array( $all_terms ) ) {
|
581 |
foreach ( $all_terms as $term ) {
|
582 |
$lang = $this->model->term->get_language( $term->term_id );
|
@@ -661,4 +602,83 @@ class PLL_Admin_Filters_Term {
|
|
661 |
$this->model->term->save_translations( $new_term_id, $translations );
|
662 |
$avoid_recursion = false;
|
663 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
664 |
}
|
22 |
public $model;
|
23 |
|
24 |
/**
|
25 |
+
* @var PLL_Admin_Links|null
|
26 |
*/
|
27 |
public $links;
|
28 |
|
29 |
/**
|
30 |
* Language selected in the admin language filter.
|
31 |
*
|
32 |
+
* @var PLL_Language|null
|
33 |
*/
|
34 |
public $filter_lang;
|
35 |
|
36 |
/**
|
37 |
* Preferred language to assign to the new terms.
|
38 |
*
|
39 |
+
* @var PLL_Language|null
|
40 |
*/
|
41 |
public $pref_lang;
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* Stores the current post_id when bulk editing posts.
|
45 |
*
|
46 |
+
* @var int|null
|
47 |
*/
|
48 |
protected $post_id;
|
49 |
|
52 |
*
|
53 |
* @since 2.8
|
54 |
*
|
55 |
+
* @var PLL_Admin_Default_Term|null
|
56 |
*/
|
57 |
protected $default_term;
|
58 |
|
62 |
* @param object $polylang
|
63 |
*/
|
64 |
public function __construct( &$polylang ) {
|
65 |
+
$this->links = &$polylang->links;
|
66 |
+
$this->model = &$polylang->model;
|
67 |
+
$this->options = &$polylang->options;
|
68 |
+
$this->pref_lang = &$polylang->pref_lang;
|
69 |
$this->default_term = &$polylang->default_term;
|
70 |
|
71 |
foreach ( $this->model->get_translated_taxonomies() as $tax ) {
|
81 |
add_action( 'create_term', array( $this, 'save_term' ), 900, 3 );
|
82 |
add_action( 'edit_term', array( $this, 'save_term' ), 900, 3 ); // Late as it may conflict with other plugins, see http://wordpress.org/support/topic/polylang-and-wordpress-seo-by-yoast
|
83 |
add_action( 'pre_post_update', array( $this, 'pre_post_update' ) );
|
84 |
+
add_filter( 'pll_inserted_term_language', array( $this, 'get_inserted_term_language' ) );
|
85 |
+
add_filter( 'pll_inserted_term_parent', array( $this, 'get_inserted_term_parent' ), 10, 2 );
|
86 |
|
87 |
// Ajax response for edit term form
|
88 |
add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
|
251 |
}
|
252 |
|
253 |
/**
|
254 |
+
* Stores the current post_id when bulk editing posts for use in save_language and get_inserted_term_language.
|
255 |
*
|
256 |
* @since 1.7
|
257 |
*
|
414 |
}
|
415 |
}
|
416 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
/**
|
418 |
* Ajax response for edit term form
|
419 |
*
|
517 |
}
|
518 |
|
519 |
// It is more efficient to use one common query for all languages as soon as there are more than 2.
|
520 |
+
$all_terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false, 'lang' => '', 'name__like' => $s ) );
|
521 |
if ( is_array( $all_terms ) ) {
|
522 |
foreach ( $all_terms as $term ) {
|
523 |
$lang = $this->model->term->get_language( $term->term_id );
|
602 |
$this->model->term->save_translations( $new_term_id, $translations );
|
603 |
$avoid_recursion = false;
|
604 |
}
|
605 |
+
|
606 |
+
/**
|
607 |
+
* Returns the language for subsequently inserted term in admin.
|
608 |
+
*
|
609 |
+
* @since 3.3
|
610 |
+
*
|
611 |
+
* @param PLL_Language|null $lang Term language object if found, null otherwise.
|
612 |
+
* @return PLL_Language|null Language object, null if none found.
|
613 |
+
*/
|
614 |
+
public function get_inserted_term_language( $lang ) {
|
615 |
+
if ( $lang instanceof PLL_Language ) {
|
616 |
+
return $lang;
|
617 |
+
}
|
618 |
+
|
619 |
+
if ( ! empty( $_POST['term_lang_choice'] ) && is_string( $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
620 |
+
$lang_slug = sanitize_key( $_POST['term_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
621 |
+
if ( ! empty( $lang_slug ) ) {
|
622 |
+
$lang = $this->model->get_language( $lang_slug );
|
623 |
+
}
|
624 |
+
}
|
625 |
+
|
626 |
+
elseif ( ! empty( $_POST['inline_lang_choice'] ) && is_string( $_POST['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
627 |
+
$lang_slug = sanitize_key( $_POST['inline_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
628 |
+
if ( ! empty( $lang_slug ) ) {
|
629 |
+
$lang = $this->model->get_language( $lang_slug );
|
630 |
+
}
|
631 |
+
}
|
632 |
+
|
633 |
+
// *Post* bulk edit, in case a new term is created
|
634 |
+
elseif ( isset( $_GET['bulk_edit'], $_GET['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
635 |
+
// Bulk edit does not modify the language
|
636 |
+
if ( -1 === (int) $_GET['inline_lang_choice'] ) { // phpcs:ignore WordPress.Security.NonceVerification
|
637 |
+
$lang = $this->model->post->get_language( $this->post_id );
|
638 |
+
} elseif ( is_string( $_GET['inline_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
639 |
+
$lang_slug = sanitize_key( $_GET['inline_lang_choice'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
640 |
+
if ( ! empty( $lang_slug ) ) {
|
641 |
+
$lang = $this->model->get_language( $lang_slug );
|
642 |
+
}
|
643 |
+
}
|
644 |
+
}
|
645 |
+
|
646 |
+
// Special cases for default categories as the select is disabled.
|
647 |
+
elseif ( ! empty( $_POST['tag_ID'] ) && in_array( intval( get_option( 'default_category' ) ), $this->model->term->get_translations( (int) $_POST['tag_ID'] ), true ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
648 |
+
$lang = $this->model->term->get_language( (int) $_POST['tag_ID'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
649 |
+
}
|
650 |
+
|
651 |
+
elseif ( ! empty( $_POST['tax_ID'] ) && in_array( intval( get_option( 'default_category' ) ), $this->model->term->get_translations( (int) $_POST['tax_ID'] ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
652 |
+
$lang = $this->model->term->get_language( (int) $_POST['tax_ID'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
653 |
+
}
|
654 |
+
|
655 |
+
if ( $lang instanceof PLL_Language ) {
|
656 |
+
return $lang;
|
657 |
+
}
|
658 |
+
|
659 |
+
return null;
|
660 |
+
}
|
661 |
+
|
662 |
+
/**
|
663 |
+
* Filters the subsequently inserted term parent in admin.
|
664 |
+
*
|
665 |
+
* @since 3.3
|
666 |
+
*
|
667 |
+
* @param int $parent Parent term ID, 0 if none found.
|
668 |
+
* @param string $taxonomy Term taxonomy.
|
669 |
+
* @return int Parent term ID if found, 0 otherwise.
|
670 |
+
*/
|
671 |
+
public function get_inserted_term_parent( $parent, $taxonomy ) {
|
672 |
+
if ( $parent ) {
|
673 |
+
return $parent;
|
674 |
+
}
|
675 |
+
|
676 |
+
if ( isset( $_POST['parent'], $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
677 |
+
$parent = intval( $_POST['parent'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
678 |
+
} elseif ( isset( $_POST[ "new{$taxonomy}_parent" ], $_POST['term_lang_choice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
679 |
+
$parent = intval( $_POST[ "new{$taxonomy}_parent" ] ); // phpcs:ignore WordPress.Security.NonceVerification
|
680 |
+
}
|
681 |
+
|
682 |
+
return $parent;
|
683 |
+
}
|
684 |
}
|
admin/admin-model.php
CHANGED
@@ -243,7 +243,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
243 |
* @since 1.9
|
244 |
* @since 3.2 Added $lang parameter.
|
245 |
*
|
246 |
-
* @param array
|
247 |
* Arguments used to modify the language. @see PLL_Admin_Model::update_language().
|
248 |
*
|
249 |
* @type string $name Language name (used only for display).
|
@@ -416,7 +416,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
416 |
}
|
417 |
|
418 |
// Get all terms with term_taxonomy_id
|
419 |
-
$terms = get_terms( $taxonomy,
|
420 |
$trs = array();
|
421 |
|
422 |
// Prepare objects relationships.
|
@@ -456,7 +456,7 @@ class PLL_Admin_Model extends PLL_Model {
|
|
456 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
457 |
global $wpdb;
|
458 |
|
459 |
-
$terms = get_terms( array( 'post_translations', 'term_translations' ) );
|
460 |
$term_ids = array();
|
461 |
$dr = array();
|
462 |
$dt = array();
|
@@ -473,15 +473,15 @@ class PLL_Admin_Model extends PLL_Model {
|
|
473 |
*
|
474 |
* @since 3.2
|
475 |
*
|
476 |
-
* @param
|
477 |
* List of translations with lang codes as array keys and IDs as array values.
|
478 |
* Also in this array:
|
479 |
*
|
480 |
-
* @type
|
481 |
* }
|
482 |
-
* @param string
|
483 |
-
* @param string
|
484 |
-
* @param WP_Term
|
485 |
*/
|
486 |
$tr = apply_filters( 'update_translation_group', $tr, $old_slug, $new_slug, $term );
|
487 |
|
243 |
* @since 1.9
|
244 |
* @since 3.2 Added $lang parameter.
|
245 |
*
|
246 |
+
* @param array $args {
|
247 |
* Arguments used to modify the language. @see PLL_Admin_Model::update_language().
|
248 |
*
|
249 |
* @type string $name Language name (used only for display).
|
416 |
}
|
417 |
|
418 |
// Get all terms with term_taxonomy_id
|
419 |
+
$terms = get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false ) );
|
420 |
$trs = array();
|
421 |
|
422 |
// Prepare objects relationships.
|
456 |
public function update_translations( $old_slug, $new_slug = '' ) {
|
457 |
global $wpdb;
|
458 |
|
459 |
+
$terms = get_terms( array( 'taxonomy' => array( 'post_translations', 'term_translations' ) ) );
|
460 |
$term_ids = array();
|
461 |
$dr = array();
|
462 |
$dt = array();
|
473 |
*
|
474 |
* @since 3.2
|
475 |
*
|
476 |
+
* @param (int|string[])[] $tr {
|
477 |
* List of translations with lang codes as array keys and IDs as array values.
|
478 |
* Also in this array:
|
479 |
*
|
480 |
+
* @type string[] $sync List of synchronized translations with lang codes as array keys and array values.
|
481 |
* }
|
482 |
+
* @param string $old_slug The old language slug.
|
483 |
+
* @param string $new_slug The new language slug.
|
484 |
+
* @param WP_Term $term The term containing the post or term translation group.
|
485 |
*/
|
486 |
$tr = apply_filters( 'update_translation_group', $tr, $old_slug, $new_slug, $term );
|
487 |
|
admin/admin-static-pages.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
*/
|
11 |
class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
12 |
/**
|
13 |
-
* @var PLL_Admin_Links
|
14 |
*/
|
15 |
protected $links;
|
16 |
|
@@ -26,10 +26,6 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
26 |
|
27 |
$this->links = &$polylang->links;
|
28 |
|
29 |
-
// Removes the editor and the template select dropdown for pages for posts
|
30 |
-
add_filter( 'use_block_editor_for_post', array( $this, 'use_block_editor_for_post' ), 10, 2 ); // Since WP 5.0
|
31 |
-
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 );
|
32 |
-
|
33 |
// Add post state for translations of the front page and posts page
|
34 |
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
35 |
|
@@ -42,48 +38,6 @@ class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
|
42 |
add_action( 'admin_notices', array( $this, 'notice_must_translate' ) );
|
43 |
}
|
44 |
|
45 |
-
/**
|
46 |
-
* Don't use the block editor for the translations of the pages for posts
|
47 |
-
*
|
48 |
-
* @since 2.5
|
49 |
-
*
|
50 |
-
* @param bool $use_block_editor Whether the post can be edited or not.
|
51 |
-
* @param WP_Post $post The post being checked.
|
52 |
-
* @return bool
|
53 |
-
*/
|
54 |
-
public function use_block_editor_for_post( $use_block_editor, $post ) {
|
55 |
-
if ( 'page' === $post->post_type ) {
|
56 |
-
add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
|
57 |
-
|
58 |
-
if ( ( get_option( 'page_for_posts' ) == $post->ID ) && empty( $post->post_content ) ) {
|
59 |
-
return false;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
return $use_block_editor;
|
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 ) {
|
78 |
-
add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
|
79 |
-
|
80 |
-
if ( ( get_option( 'page_for_posts' ) == $post->ID ) && empty( $post->post_content ) ) {
|
81 |
-
add_action( 'edit_form_after_title', '_wp_posts_page_notice' );
|
82 |
-
remove_post_type_support( $post_type, 'editor' );
|
83 |
-
}
|
84 |
-
}
|
85 |
-
}
|
86 |
-
|
87 |
/**
|
88 |
* Adds post state for translations of the front page and posts page.
|
89 |
*
|
10 |
*/
|
11 |
class PLL_Admin_Static_Pages extends PLL_Static_Pages {
|
12 |
/**
|
13 |
+
* @var PLL_Admin_Links|null
|
14 |
*/
|
15 |
protected $links;
|
16 |
|
26 |
|
27 |
$this->links = &$polylang->links;
|
28 |
|
|
|
|
|
|
|
|
|
29 |
// Add post state for translations of the front page and posts page
|
30 |
add_filter( 'display_post_states', array( $this, 'display_post_states' ), 10, 2 );
|
31 |
|
38 |
add_action( 'admin_notices', array( $this, 'notice_must_translate' ) );
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
/**
|
42 |
* Adds post state for translations of the front page and posts page.
|
43 |
*
|
admin/admin-strings.php
CHANGED
@@ -24,7 +24,7 @@ class PLL_Admin_Strings {
|
|
24 |
/**
|
25 |
* The strings to register by default.
|
26 |
*
|
27 |
-
* @var string[]
|
28 |
*/
|
29 |
protected static $default_strings;
|
30 |
|
24 |
/**
|
25 |
* The strings to register by default.
|
26 |
*
|
27 |
+
* @var string[]|null
|
28 |
*/
|
29 |
protected static $default_strings;
|
30 |
|
admin/admin.php
CHANGED
@@ -10,54 +10,54 @@
|
|
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
|
41 |
*/
|
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_options;
|
63 |
|
10 |
*/
|
11 |
class PLL_Admin extends PLL_Admin_Base {
|
12 |
/**
|
13 |
+
* @var PLL_Admin_Filters|null
|
14 |
*/
|
15 |
public $filters;
|
16 |
|
17 |
/**
|
18 |
+
* @var PLL_Admin_Filters_Columns|null
|
19 |
*/
|
20 |
public $filters_columns;
|
21 |
|
22 |
/**
|
23 |
+
* @var PLL_Admin_Filters_Post|null
|
24 |
*/
|
25 |
public $filters_post;
|
26 |
|
27 |
/**
|
28 |
+
* @var PLL_Admin_Filters_Term|null
|
29 |
*/
|
30 |
public $filters_term;
|
31 |
|
32 |
/**
|
33 |
+
* @var PLL_Admin_Filters_Media|null
|
34 |
*/
|
35 |
public $filters_media;
|
36 |
|
37 |
/**
|
38 |
* @since 2.9
|
39 |
*
|
40 |
+
* @var PLL_Filters_Sanitization|null
|
41 |
*/
|
42 |
public $filters_sanitization;
|
43 |
|
44 |
/**
|
45 |
+
* @var PLL_Admin_Block_Editor|null
|
46 |
*/
|
47 |
public $block_editor;
|
48 |
|
49 |
/**
|
50 |
+
* @var PLL_Admin_Classic_Editor|null
|
51 |
*/
|
52 |
public $classic_editor;
|
53 |
|
54 |
/**
|
55 |
+
* @var PLL_Admin_Nav_Menu|null
|
56 |
*/
|
57 |
public $nav_menu;
|
58 |
|
59 |
/**
|
60 |
+
* @var PLL_Admin_Filters_Widgets_Options|null
|
61 |
*/
|
62 |
public $filters_widgets_options;
|
63 |
|
frontend/canonical.php
ADDED
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package Polylang
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Manages canonical redirect on frontend.
|
8 |
+
*
|
9 |
+
* @since 3.3
|
10 |
+
*/
|
11 |
+
class PLL_Canonical {
|
12 |
+
/**
|
13 |
+
* Stores the plugin options.
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected $options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var PLL_Model
|
21 |
+
*/
|
22 |
+
protected $model;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Instance of a child class of PLL_Links_Model.
|
26 |
+
*
|
27 |
+
* @var PLL_Links_Model
|
28 |
+
*/
|
29 |
+
protected $links_model;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Current language.
|
33 |
+
*
|
34 |
+
* @var PLL_Language
|
35 |
+
*/
|
36 |
+
protected $curlang;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Constructor.
|
40 |
+
*
|
41 |
+
* @since 3.3
|
42 |
+
*
|
43 |
+
* @param object $polylang Main Polylang object.
|
44 |
+
*/
|
45 |
+
public function __construct( &$polylang ) {
|
46 |
+
$this->links_model = &$polylang->links_model;
|
47 |
+
$this->model = &$polylang->model;
|
48 |
+
$this->options = &$polylang->options;
|
49 |
+
$this->curlang = &$polylang->curlang;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* If the language code is not in agreement with the language of the content,
|
54 |
+
* redirects incoming links to the proper URL to avoid duplicate content.
|
55 |
+
*
|
56 |
+
* @since 0.9.6
|
57 |
+
*
|
58 |
+
* @global WP_Query $wp_query WordPress Query object.
|
59 |
+
* @global bool $is_IIS
|
60 |
+
*
|
61 |
+
* @param string $requested_url Optional, defaults to requested url.
|
62 |
+
* @param bool $do_redirect Optional, whether to perform the redirect or not.
|
63 |
+
* @return string|void Returns if redirect is not performed.
|
64 |
+
*/
|
65 |
+
public function check_canonical_url( $requested_url = '', $do_redirect = true ) {
|
66 |
+
global $wp_query;
|
67 |
+
|
68 |
+
// Don't redirect in same cases as WP.
|
69 |
+
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $GLOBALS['is_IIS'] && ! iis7_supports_permalinks() ) ) {
|
70 |
+
return;
|
71 |
+
}
|
72 |
+
|
73 |
+
// Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id=.
|
74 |
+
if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
75 |
+
return;
|
76 |
+
}
|
77 |
+
|
78 |
+
/*
|
79 |
+
* If the default language code is not hidden and the static front page url contains the page name,
|
80 |
+
* the customizer lands here and the code below would redirect to the list of posts.
|
81 |
+
*/
|
82 |
+
if ( is_customize_preview() ) {
|
83 |
+
return;
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( empty( $requested_url ) ) {
|
87 |
+
$requested_url = pll_get_requested_url();
|
88 |
+
}
|
89 |
+
|
90 |
+
if ( ( is_single() || is_page() ) && ! is_front_page() ) {
|
91 |
+
$post = get_post();
|
92 |
+
if ( $post instanceof WP_Post && $this->model->is_translated_post_type( $post->post_type ) ) {
|
93 |
+
$language = $this->model->post->get_language( (int) $post->ID );
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
if ( ! empty( $wp_query->tax_query ) ) {
|
98 |
+
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $wp_query->tax_query ) ) ) {
|
99 |
+
$term_id = $this->get_queried_term_id( $wp_query->tax_query );
|
100 |
+
if ( $term_id ) {
|
101 |
+
$language = $this->model->term->get_language( $term_id );
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
if ( $wp_query->is_posts_page ) {
|
107 |
+
$page_id = get_query_var( 'page_id' );
|
108 |
+
if ( ! $page_id ) {
|
109 |
+
$page_id = get_queried_object_id();
|
110 |
+
}
|
111 |
+
if ( $page_id && is_numeric( $page_id ) ) {
|
112 |
+
$language = $this->model->post->get_language( (int) $page_id );
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
if ( 3 === $this->options['force_lang'] ) {
|
117 |
+
$requested_host = wp_parse_url( $requested_url, PHP_URL_HOST );
|
118 |
+
foreach ( $this->options['domains'] as $lang => $domain ) {
|
119 |
+
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
120 |
+
if ( $requested_host && $host && ltrim( $requested_host, 'w.' ) === ltrim( $host, 'w.' ) ) {
|
121 |
+
$language = $this->model->get_language( $lang );
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( empty( $language ) ) {
|
127 |
+
$language = $this->curlang;
|
128 |
+
$redirect_url = $requested_url;
|
129 |
+
} else {
|
130 |
+
$redirect_url = $this->redirect_canonical( $requested_url, $language );
|
131 |
+
$redirect_url = $this->options['force_lang'] ?
|
132 |
+
$this->links_model->switch_language_in_link( $redirect_url, $language ) :
|
133 |
+
$this->links_model->remove_language_from_link( $redirect_url ); // Works only for default permalinks.
|
134 |
+
}
|
135 |
+
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Filters the canonical url detected by Polylang.
|
139 |
+
*
|
140 |
+
* @since 1.6
|
141 |
+
*
|
142 |
+
* @param string|false $redirect_url False or the url to redirect to.
|
143 |
+
* @param PLL_Language $language The language detected.
|
144 |
+
*/
|
145 |
+
$redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language );
|
146 |
+
|
147 |
+
if ( ! $redirect_url || $requested_url === $redirect_url ) {
|
148 |
+
return $requested_url;
|
149 |
+
}
|
150 |
+
|
151 |
+
if ( ! $do_redirect ) {
|
152 |
+
return $redirect_url;
|
153 |
+
}
|
154 |
+
|
155 |
+
// Protect against chained redirects.
|
156 |
+
if ( $redirect_url === $this->check_canonical_url( $redirect_url, false ) && wp_validate_redirect( $redirect_url ) ) {
|
157 |
+
wp_safe_redirect( $redirect_url, 301, POLYLANG );
|
158 |
+
exit;
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Returns the term_id of the requested term.
|
164 |
+
*
|
165 |
+
* @since 2.9
|
166 |
+
*
|
167 |
+
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
168 |
+
* @return int
|
169 |
+
*/
|
170 |
+
protected function get_queried_term_id( $tax_query ) {
|
171 |
+
$queried_terms = $tax_query->queried_terms;
|
172 |
+
$taxonomy = $this->get_queried_taxonomy( $tax_query );
|
173 |
+
|
174 |
+
if ( ! is_array( $queried_terms[ $taxonomy ]['terms'] ) ) {
|
175 |
+
return 0;
|
176 |
+
}
|
177 |
+
$field = $queried_terms[ $taxonomy ]['field'];
|
178 |
+
$term = reset( $queried_terms[ $taxonomy ]['terms'] );
|
179 |
+
$lang = isset( $queried_terms['language']['terms'] ) ? reset( $queried_terms['language']['terms'] ) : '';
|
180 |
+
|
181 |
+
// We can get a term_id when requesting a plain permalink, eg /?cat=1.
|
182 |
+
if ( 'term_id' === $field ) {
|
183 |
+
return $term;
|
184 |
+
}
|
185 |
+
|
186 |
+
// We get a slug when requesting a pretty permalink. Let's query all corresponding terms.
|
187 |
+
$args = array(
|
188 |
+
'lang' => '',
|
189 |
+
'taxonomy' => $taxonomy,
|
190 |
+
$field => $term,
|
191 |
+
'hide_empty' => false,
|
192 |
+
'fields' => 'ids',
|
193 |
+
);
|
194 |
+
$term_ids = get_terms( $args );
|
195 |
+
|
196 |
+
if ( ! is_array( $term_ids ) || empty( $term_ids ) ) {
|
197 |
+
return 0;
|
198 |
+
}
|
199 |
+
|
200 |
+
$term_ids = array_filter( $term_ids, 'is_numeric' );
|
201 |
+
|
202 |
+
$filtered_terms_by_lang = array_filter(
|
203 |
+
$term_ids,
|
204 |
+
function ( $term_id ) use ( $lang ) {
|
205 |
+
$term_lang = $this->model->term->get_language( (int) $term_id );
|
206 |
+
|
207 |
+
return ! empty( $term_lang ) && $term_lang->slug === $lang;
|
208 |
+
}
|
209 |
+
);
|
210 |
+
|
211 |
+
$tr_term = (int) reset( $filtered_terms_by_lang );
|
212 |
+
|
213 |
+
if ( ! empty( $tr_term ) ) {
|
214 |
+
// The queried term exists in the desired language.
|
215 |
+
return $tr_term;
|
216 |
+
}
|
217 |
+
|
218 |
+
// The queried term doesn't exist in the desired language, let's return the first one retrieved.
|
219 |
+
return (int) reset( $term_ids );
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Find the taxonomy being queried.
|
224 |
+
*
|
225 |
+
* @since 2.9
|
226 |
+
*
|
227 |
+
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
228 |
+
* @return string A taxonomy slug
|
229 |
+
*/
|
230 |
+
protected function get_queried_taxonomy( $tax_query ) {
|
231 |
+
$queried_terms = $tax_query->queried_terms;
|
232 |
+
unset( $queried_terms['language'] );
|
233 |
+
|
234 |
+
return (string) key( $queried_terms );
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Evaluates the canonical redirect url through the deidcated WP function.
|
239 |
+
*
|
240 |
+
* @since 3.3
|
241 |
+
*
|
242 |
+
* @global WP_Query $wp_query WordPress Query object.
|
243 |
+
*
|
244 |
+
* @param string $url Requested url.
|
245 |
+
* @param PLL_Language $language Language of the queried object.
|
246 |
+
* @return string
|
247 |
+
*/
|
248 |
+
protected function redirect_canonical( $url, $language ) {
|
249 |
+
global $wp_query;
|
250 |
+
|
251 |
+
$this->curlang = $language; // Hack to filter the `page_for_posts` option in the correct language.
|
252 |
+
|
253 |
+
$backup_wp_query = $wp_query;
|
254 |
+
|
255 |
+
if ( isset( $wp_query->tax_query ) ) {
|
256 |
+
unset( $wp_query->tax_query->queried_terms['language'] );
|
257 |
+
unset( $wp_query->query['lang'] );
|
258 |
+
}
|
259 |
+
|
260 |
+
$redirect_url = redirect_canonical( $url, false );
|
261 |
+
|
262 |
+
$wp_query = $backup_wp_query;
|
263 |
+
|
264 |
+
return $redirect_url ? $redirect_url : $url;
|
265 |
+
}
|
266 |
+
}
|
frontend/choose-lang.php
CHANGED
@@ -31,17 +31,9 @@ abstract class PLL_Choose_Lang {
|
|
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
|
@@ -306,15 +298,30 @@ abstract class PLL_Choose_Lang {
|
|
306 |
$this->set_language( $lang );
|
307 |
$this->set_curlang_in_query( $query );
|
308 |
} elseif ( ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) ) && $lang = get_query_var( 'lang' ) ) {
|
309 |
-
// Set is_home on translated home page when it displays posts. It must be true on page 2, 3... too.
|
310 |
$lang = $this->model->get_language( $lang );
|
311 |
$this->set_language( $lang ); // Set the language now otherwise it will be too late to filter sticky posts!
|
312 |
-
|
313 |
-
|
|
|
|
|
314 |
$query->is_archive = false;
|
|
|
|
|
|
|
315 |
}
|
316 |
}
|
317 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
/**
|
319 |
* Sets the current language in the query.
|
320 |
*
|
@@ -324,7 +331,9 @@ abstract class PLL_Choose_Lang {
|
|
324 |
* @return void
|
325 |
*/
|
326 |
protected function set_curlang_in_query( &$query ) {
|
327 |
-
|
328 |
-
|
|
|
|
|
329 |
}
|
330 |
}
|
31 |
/**
|
32 |
* Current language.
|
33 |
*
|
34 |
+
* @var PLL_Language|null
|
35 |
*/
|
36 |
public $curlang;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
/**
|
39 |
* Constructor
|
298 |
$this->set_language( $lang );
|
299 |
$this->set_curlang_in_query( $query );
|
300 |
} elseif ( ( count( $query->query ) == 1 || ( is_paged() && count( $query->query ) == 2 ) ) && $lang = get_query_var( 'lang' ) ) {
|
|
|
301 |
$lang = $this->model->get_language( $lang );
|
302 |
$this->set_language( $lang ); // Set the language now otherwise it will be too late to filter sticky posts!
|
303 |
+
|
304 |
+
// Set is_home on translated home page when it displays posts. It must be true on page 2, 3... too.
|
305 |
+
$query->is_home = true;
|
306 |
+
$query->is_tax = false;
|
307 |
$query->is_archive = false;
|
308 |
+
|
309 |
+
// Filters is_front_page() in case a static front page is not translated in this language.
|
310 |
+
add_filter( 'option_show_on_front', array( $this, 'filter_option_show_on_front' ) );
|
311 |
}
|
312 |
}
|
313 |
|
314 |
+
/**
|
315 |
+
* Filters the option show_on_front when the current front page displays posts.
|
316 |
+
*
|
317 |
+
* This is useful when a static front page is not translated in all languages.
|
318 |
+
*
|
319 |
+
* @return string
|
320 |
+
*/
|
321 |
+
public function filter_option_show_on_front() {
|
322 |
+
return 'posts';
|
323 |
+
}
|
324 |
+
|
325 |
/**
|
326 |
* Sets the current language in the query.
|
327 |
*
|
331 |
* @return void
|
332 |
*/
|
333 |
protected function set_curlang_in_query( &$query ) {
|
334 |
+
if ( ! empty( $this->curlang ) ) {
|
335 |
+
$pll_query = new PLL_Query( $query, $this->model );
|
336 |
+
$pll_query->set_language( $this->curlang );
|
337 |
+
}
|
338 |
}
|
339 |
}
|
frontend/frontend-auto-translate.php
CHANGED
@@ -18,7 +18,7 @@ class PLL_Frontend_Auto_Translate {
|
|
18 |
/**
|
19 |
* Current language.
|
20 |
*
|
21 |
-
* @var PLL_Language
|
22 |
*/
|
23 |
public $curlang;
|
24 |
|
@@ -275,10 +275,13 @@ class PLL_Frontend_Auto_Translate {
|
|
275 |
return $tr_id;
|
276 |
}
|
277 |
} else {
|
278 |
-
$terms = get_terms( $taxonomy,
|
279 |
|
280 |
-
if ( ! empty( $terms ) &&
|
281 |
$t = reset( $terms );
|
|
|
|
|
|
|
282 |
$tr_id = $this->get_term( $t->term_id );
|
283 |
|
284 |
if ( ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) {
|
18 |
/**
|
19 |
* Current language.
|
20 |
*
|
21 |
+
* @var PLL_Language|null
|
22 |
*/
|
23 |
public $curlang;
|
24 |
|
275 |
return $tr_id;
|
276 |
}
|
277 |
} else {
|
278 |
+
$terms = get_terms( array( 'taxonomy' => $taxonomy, $field => $term, 'lang' => '' ) );
|
279 |
|
280 |
+
if ( ! empty( $terms ) && is_array( $terms ) ) {
|
281 |
$t = reset( $terms );
|
282 |
+
if ( ! $t instanceof WP_Term ) {
|
283 |
+
return $term;
|
284 |
+
}
|
285 |
$tr_id = $this->get_term( $t->term_id );
|
286 |
|
287 |
if ( ! is_wp_error( $tr = get_term( $tr_id, $taxonomy ) ) ) {
|
frontend/frontend-filters-links.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
12 |
|
13 |
/**
|
14 |
-
* @var PLL_Frontend_Links
|
15 |
*/
|
16 |
public $links;
|
17 |
|
@@ -73,10 +73,6 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
73 |
// Rewrites ajax url
|
74 |
add_filter( 'admin_url', array( $this, 'admin_url' ), 10, 2 );
|
75 |
}
|
76 |
-
|
77 |
-
// Redirects to canonical url before WordPress redirect_canonical
|
78 |
-
// but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!! and restores it in 'template_redirect' with priority 1
|
79 |
-
add_action( 'template_redirect', array( $this, 'check_canonical_url' ), 4 );
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -274,48 +270,47 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
274 |
$theme_root = get_theme_root();
|
275 |
$theme_root = ( false === strpos( $theme_root, '\\' ) ) ? $theme_root : str_replace( '/', '\\', $theme_root );
|
276 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
/**
|
278 |
-
*
|
279 |
-
* The $args contains an array of arrays each of them having
|
280 |
-
* a 'file' key and/or a 'function' key to decide which functions in
|
281 |
-
* which files using home_url() calls must be filtered
|
282 |
*
|
283 |
* @since 1.1.2
|
284 |
*
|
285 |
-
* @param array
|
|
|
|
|
286 |
*/
|
287 |
-
$this->white_list = apply_filters(
|
288 |
-
'pll_home_url_white_list',
|
289 |
-
array(
|
290 |
-
array( 'file' => $theme_root ),
|
291 |
-
array( 'function' => 'wp_nav_menu' ),
|
292 |
-
array( 'function' => 'login_footer' ),
|
293 |
-
array( 'function' => 'get_custom_logo' ),
|
294 |
-
array( 'function' => 'render_block_core_site_title' ),
|
295 |
-
)
|
296 |
-
);
|
297 |
}
|
298 |
|
299 |
-
// We don't want to filter the home url in these cases
|
300 |
if ( empty( $this->black_list ) ) {
|
|
|
|
|
|
|
|
|
301 |
|
302 |
/**
|
303 |
-
*
|
304 |
-
* The $args contains an array of arrays each of them having
|
305 |
-
* a 'file' key and/or a 'function' key to decide which functions in
|
306 |
-
* which files using home_url() calls must be filtered
|
307 |
*
|
308 |
* @since 1.1.2
|
309 |
*
|
310 |
-
* @param array
|
|
|
|
|
311 |
*/
|
312 |
-
$this->black_list = apply_filters(
|
313 |
-
'pll_home_url_black_list',
|
314 |
-
array(
|
315 |
-
array( 'file' => 'searchform.php' ), // Since WP 3.6 searchform.php is passed through get_search_form
|
316 |
-
array( 'function' => 'get_search_form' ),
|
317 |
-
)
|
318 |
-
);
|
319 |
}
|
320 |
|
321 |
$traces = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
@@ -324,13 +319,13 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
324 |
foreach ( $traces as $trace ) {
|
325 |
// Black list first
|
326 |
foreach ( $this->black_list as $v ) {
|
327 |
-
if ( ( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) ) || (
|
328 |
return $url;
|
329 |
}
|
330 |
}
|
331 |
|
332 |
foreach ( $this->white_list as $v ) {
|
333 |
-
if ( (
|
334 |
( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) && in_array( $trace['function'], array( 'home_url', 'get_home_url', 'bloginfo', 'get_bloginfo' ) ) ) ) {
|
335 |
$ok = true;
|
336 |
}
|
@@ -352,230 +347,4 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
|
352 |
public function admin_url( $url, $path ) {
|
353 |
return 'admin-ajax.php' === $path ? $this->links_model->switch_language_in_link( $url, $this->curlang ) : $url;
|
354 |
}
|
355 |
-
|
356 |
-
/**
|
357 |
-
* If the language code is not in agreement with the language of the content,
|
358 |
-
* redirects incoming links to the proper URL to avoid duplicate content.
|
359 |
-
*
|
360 |
-
* @since 0.9.6
|
361 |
-
*
|
362 |
-
* @param string $requested_url Optional, defaults to requested url.
|
363 |
-
* @param bool $do_redirect Optional, whether to perform the redirect or not.
|
364 |
-
* @return string|void Returns if redirect is not performed.
|
365 |
-
*/
|
366 |
-
public function check_canonical_url( $requested_url = '', $do_redirect = true ) {
|
367 |
-
// Don't redirect in same cases as WP.
|
368 |
-
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $GLOBALS['is_IIS'] && ! iis7_supports_permalinks() ) ) {
|
369 |
-
return;
|
370 |
-
}
|
371 |
-
|
372 |
-
// Don't redirect mysite.com/?attachment_id= to mysite.com/en/?attachment_id=.
|
373 |
-
if ( 1 == $this->options['force_lang'] && is_attachment() && isset( $_GET['attachment_id'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
374 |
-
return;
|
375 |
-
}
|
376 |
-
|
377 |
-
/*
|
378 |
-
* If the default language code is not hidden and the static front page url contains the page name,
|
379 |
-
* the customizer lands here and the code below would redirect to the list of posts.
|
380 |
-
*/
|
381 |
-
if ( is_customize_preview() ) {
|
382 |
-
return;
|
383 |
-
}
|
384 |
-
|
385 |
-
if ( empty( $requested_url ) ) {
|
386 |
-
$requested_url = pll_get_requested_url();
|
387 |
-
}
|
388 |
-
|
389 |
-
if ( is_single() || is_page() ) {
|
390 |
-
$post = get_post();
|
391 |
-
if ( $post instanceof WP_Post && $this->model->is_translated_post_type( $post->post_type ) ) {
|
392 |
-
$language = $this->model->post->get_language( (int) $post->ID );
|
393 |
-
}
|
394 |
-
}
|
395 |
-
|
396 |
-
elseif ( $this->links_model->using_permalinks && is_category() && ! empty( $this->wp_query()->query['cat'] ) ) {
|
397 |
-
// When we receive a plain permaling with a cat query var, we need to redirect to the pretty permalink.
|
398 |
-
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $this->wp_query()->tax_query ) ) ) {
|
399 |
-
$term_id = $this->get_queried_term_id( $this->wp_query()->tax_query );
|
400 |
-
if ( $term_id ) {
|
401 |
-
$language = $this->model->term->get_language( $term_id );
|
402 |
-
$redirect_url = $this->maybe_add_page_to_redirect_url( get_term_link( $term_id ) );
|
403 |
-
}
|
404 |
-
}
|
405 |
-
}
|
406 |
-
|
407 |
-
elseif ( is_category() || is_tag() || is_tax() ) {
|
408 |
-
// We need to switch the language when there is no language provided in a pretty permalink.
|
409 |
-
$obj = get_queried_object();
|
410 |
-
if ( ! empty( $obj ) && $this->model->is_translated_taxonomy( $obj->taxonomy ) ) {
|
411 |
-
$language = $this->model->term->get_language( (int) $obj->term_id );
|
412 |
-
}
|
413 |
-
}
|
414 |
-
|
415 |
-
elseif ( is_404() && ! empty( $this->wp_query()->tax_query ) ) {
|
416 |
-
// When a wrong language is passed through a pretty permalink, we just need to switch the language.
|
417 |
-
if ( $this->model->is_translated_taxonomy( $this->get_queried_taxonomy( $this->wp_query()->tax_query ) ) ) {
|
418 |
-
$term_id = $this->get_queried_term_id( $this->wp_query()->tax_query );
|
419 |
-
if ( $term_id ) {
|
420 |
-
$language = $this->model->term->get_language( $term_id );
|
421 |
-
}
|
422 |
-
}
|
423 |
-
}
|
424 |
-
|
425 |
-
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' ) ) {
|
426 |
-
$language = $this->model->post->get_language( (int) $id );
|
427 |
-
$redirect_url = $this->maybe_add_page_to_redirect_url( get_permalink( $id ) );
|
428 |
-
}
|
429 |
-
|
430 |
-
elseif ( $this->wp_query()->is_posts_page ) {
|
431 |
-
$obj = get_queried_object();
|
432 |
-
if ( $obj instanceof WP_Post ) {
|
433 |
-
$language = $this->model->post->get_language( (int) $obj->ID );
|
434 |
-
}
|
435 |
-
}
|
436 |
-
|
437 |
-
if ( 3 === $this->options['force_lang'] ) {
|
438 |
-
$requested_host = wp_parse_url( $requested_url, PHP_URL_HOST );
|
439 |
-
foreach ( $this->options['domains'] as $lang => $domain ) {
|
440 |
-
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
441 |
-
if ( 'www.' . $requested_host === $host || 'www.' . $host === $requested_host ) {
|
442 |
-
$language = $this->model->get_language( $lang );
|
443 |
-
$redirect_url = str_replace( '://' . $requested_host, '://' . $host, $requested_url );
|
444 |
-
}
|
445 |
-
}
|
446 |
-
}
|
447 |
-
|
448 |
-
if ( empty( $language ) ) {
|
449 |
-
$language = $this->curlang;
|
450 |
-
$redirect_url = $requested_url;
|
451 |
-
} elseif ( empty( $redirect_url ) ) {
|
452 |
-
// First get the canonical url evaluated by WP
|
453 |
-
// Workaround a WP bug which removes the port for some urls and get it back at second call to redirect_canonical
|
454 |
-
$_redirect_url = ( ! $_redirect_url = redirect_canonical( $requested_url, false ) ) ? $requested_url : $_redirect_url;
|
455 |
-
$redirect_url = ( ! $redirect_url = redirect_canonical( $_redirect_url, false ) ) ? $_redirect_url : $redirect_url;
|
456 |
-
|
457 |
-
// Then get the right language code in url
|
458 |
-
$redirect_url = $this->options['force_lang'] ?
|
459 |
-
$this->links_model->switch_language_in_link( $redirect_url, $language ) :
|
460 |
-
$this->links_model->remove_language_from_link( $redirect_url ); // Works only for default permalinks
|
461 |
-
}
|
462 |
-
|
463 |
-
/**
|
464 |
-
* Filters the canonical url detected by Polylang.
|
465 |
-
*
|
466 |
-
* @since 1.6
|
467 |
-
*
|
468 |
-
* @param string|false $redirect_url False or the url to redirect to.
|
469 |
-
* @param PLL_Language $language The language detected.
|
470 |
-
*/
|
471 |
-
$redirect_url = apply_filters( 'pll_check_canonical_url', $redirect_url, $language );
|
472 |
-
|
473 |
-
// The language is not correctly set so let's redirect to the correct url for this object
|
474 |
-
if ( $do_redirect ) {
|
475 |
-
// Protect against chained redirects.
|
476 |
-
if ( $redirect_url && $requested_url != $redirect_url && $redirect_url === $this->check_canonical_url( $redirect_url, false ) && wp_validate_redirect( $redirect_url ) ) {
|
477 |
-
wp_safe_redirect( $redirect_url, 301, POLYLANG );
|
478 |
-
exit;
|
479 |
-
} else {
|
480 |
-
return;
|
481 |
-
}
|
482 |
-
}
|
483 |
-
|
484 |
-
return $redirect_url;
|
485 |
-
}
|
486 |
-
|
487 |
-
/**
|
488 |
-
* Returns the link to the paged page if requested.
|
489 |
-
*
|
490 |
-
* @since 2.9
|
491 |
-
*
|
492 |
-
* @param string $redirect_url The url to redirect to.
|
493 |
-
* @return string
|
494 |
-
*/
|
495 |
-
protected function maybe_add_page_to_redirect_url( $redirect_url ) {
|
496 |
-
if ( ! empty( $this->wp_query()->query['paged'] ) && $page = get_query_var( 'paged' ) ) {
|
497 |
-
$redirect_url = $this->links_model->add_paged_to_link( $redirect_url, $page );
|
498 |
-
}
|
499 |
-
return $redirect_url;
|
500 |
-
}
|
501 |
-
|
502 |
-
/**
|
503 |
-
* Returns the term_id of the requested term.
|
504 |
-
*
|
505 |
-
* @since 2.9
|
506 |
-
*
|
507 |
-
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
508 |
-
* @return int|false
|
509 |
-
*/
|
510 |
-
protected function get_queried_term_id( $tax_query ) {
|
511 |
-
$queried_terms = $tax_query->queried_terms;
|
512 |
-
$taxonomy = $this->get_queried_taxonomy( $tax_query );
|
513 |
-
|
514 |
-
if ( ! is_array( $queried_terms[ $taxonomy ]['terms'] ) ) {
|
515 |
-
return false;
|
516 |
-
}
|
517 |
-
$field = $queried_terms[ $taxonomy ]['field'];
|
518 |
-
$term = reset( $queried_terms[ $taxonomy ]['terms'] );
|
519 |
-
$lang = isset( $queried_terms['language']['terms'] ) ? reset( $queried_terms['language']['terms'] ) : '';
|
520 |
-
|
521 |
-
// We can get a term_id when requesting a plain permalink, eg /?cat=1.
|
522 |
-
if ( 'term_id' === $field ) {
|
523 |
-
return $term;
|
524 |
-
}
|
525 |
-
|
526 |
-
// We get a slug when requesting a pretty permalink. Let's query all corresponding terms.
|
527 |
-
$args = array(
|
528 |
-
'lang' => '',
|
529 |
-
'taxonomy' => $taxonomy,
|
530 |
-
$field => $term,
|
531 |
-
'hide_empty' => false,
|
532 |
-
'fields' => 'ids',
|
533 |
-
);
|
534 |
-
$terms = get_terms( $args );
|
535 |
-
|
536 |
-
$filtered_terms_by_lang = array_filter(
|
537 |
-
$terms,
|
538 |
-
function ( $term ) use ( $lang ) {
|
539 |
-
$term_lang = $this->model->term->get_language( $term );
|
540 |
-
|
541 |
-
return ! empty( $term_lang ) && $term_lang->slug === $lang;
|
542 |
-
}
|
543 |
-
);
|
544 |
-
|
545 |
-
$tr_term = reset( $filtered_terms_by_lang );
|
546 |
-
|
547 |
-
if ( ! empty( $tr_term ) ) {
|
548 |
-
// The queried term exists in the desired language.
|
549 |
-
return $tr_term;
|
550 |
-
}
|
551 |
-
|
552 |
-
// The queried term doesn't exist in the desired language, let's return the first one retrieved.
|
553 |
-
return reset( $terms );
|
554 |
-
}
|
555 |
-
|
556 |
-
/**
|
557 |
-
* Find the taxonomy being queried.
|
558 |
-
*
|
559 |
-
* @since 2.9
|
560 |
-
*
|
561 |
-
* @param WP_Tax_Query $tax_query An instance of WP_Tax_Query.
|
562 |
-
* @return string A taxonomy slug
|
563 |
-
*/
|
564 |
-
protected function get_queried_taxonomy( $tax_query ) {
|
565 |
-
$queried_terms = $tax_query->queried_terms;
|
566 |
-
unset( $queried_terms['language'] );
|
567 |
-
|
568 |
-
return key( $queried_terms );
|
569 |
-
}
|
570 |
-
|
571 |
-
/**
|
572 |
-
* Returns the Global WordPress WP_Query object.
|
573 |
-
*
|
574 |
-
* @since 3.0
|
575 |
-
*
|
576 |
-
* @return WP_Query
|
577 |
-
*/
|
578 |
-
protected function wp_query() {
|
579 |
-
return $GLOBALS['wp_query'];
|
580 |
-
}
|
581 |
}
|
11 |
class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
|
12 |
|
13 |
/**
|
14 |
+
* @var PLL_Frontend_Links|null
|
15 |
*/
|
16 |
public $links;
|
17 |
|
73 |
// Rewrites ajax url
|
74 |
add_filter( 'admin_url', array( $this, 'admin_url' ), 10, 2 );
|
75 |
}
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
|
78 |
/**
|
270 |
$theme_root = get_theme_root();
|
271 |
$theme_root = ( false === strpos( $theme_root, '\\' ) ) ? $theme_root : str_replace( '/', '\\', $theme_root );
|
272 |
|
273 |
+
$white_list = array(
|
274 |
+
array( 'file' => $theme_root ),
|
275 |
+
array( 'function' => 'wp_nav_menu' ),
|
276 |
+
array( 'function' => 'login_footer' ),
|
277 |
+
array( 'function' => 'get_custom_logo' ),
|
278 |
+
array( 'function' => 'render_block_core_site_title' ),
|
279 |
+
);
|
280 |
+
|
281 |
+
if ( 3 === $this->options['force_lang'] ) {
|
282 |
+
$white_list[] = array( 'function' => 'redirect_canonical' );
|
283 |
+
}
|
284 |
+
|
285 |
/**
|
286 |
+
* Filters the white list of the Polylang 'home_url' filter.
|
|
|
|
|
|
|
287 |
*
|
288 |
* @since 1.1.2
|
289 |
*
|
290 |
+
* @param string[][] $white_list An array of arrays each of them having a 'file' key
|
291 |
+
* and/or a 'function' key to decide which functions in
|
292 |
+
* which files using home_url() calls must be filtered.
|
293 |
*/
|
294 |
+
$this->white_list = apply_filters( 'pll_home_url_white_list', $white_list );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
}
|
296 |
|
297 |
+
// We don't want to filter the home url in these cases.
|
298 |
if ( empty( $this->black_list ) ) {
|
299 |
+
$black_list = array(
|
300 |
+
array( 'file' => 'searchform.php' ), // Since WP 3.6 searchform.php is passed through get_search_form.
|
301 |
+
array( 'function' => 'get_search_form' ),
|
302 |
+
);
|
303 |
|
304 |
/**
|
305 |
+
* Filters the black list of the Polylang 'home_url' filter.
|
|
|
|
|
|
|
306 |
*
|
307 |
* @since 1.1.2
|
308 |
*
|
309 |
+
* @param string[][] $black_list An array of arrays each of them having a 'file' key
|
310 |
+
* and/or a 'function' key to decide which functions in
|
311 |
+
* which files using home_url() calls must be filtered.
|
312 |
*/
|
313 |
+
$this->black_list = apply_filters( 'pll_home_url_black_list', $black_list );
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
}
|
315 |
|
316 |
$traces = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions
|
319 |
foreach ( $traces as $trace ) {
|
320 |
// Black list first
|
321 |
foreach ( $this->black_list as $v ) {
|
322 |
+
if ( ( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) ) || ( ! empty( $v['function'] ) && $trace['function'] === $v['function'] ) ) {
|
323 |
return $url;
|
324 |
}
|
325 |
}
|
326 |
|
327 |
foreach ( $this->white_list as $v ) {
|
328 |
+
if ( ( ! empty( $v['function'] ) && $trace['function'] === $v['function'] ) ||
|
329 |
( isset( $trace['file'], $v['file'] ) && false !== strpos( $trace['file'], $v['file'] ) && in_array( $trace['function'], array( 'home_url', 'get_home_url', 'bloginfo', 'get_bloginfo' ) ) ) ) {
|
330 |
$ok = true;
|
331 |
}
|
347 |
public function admin_url( $url, $path ) {
|
348 |
return 'admin-ajax.php' === $path ? $this->links_model->switch_language_in_link( $url, $this->curlang ) : $url;
|
349 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
}
|
frontend/frontend-filters-search.php
CHANGED
@@ -19,7 +19,7 @@ class PLL_Frontend_Filters_Search {
|
|
19 |
/**
|
20 |
* Current language.
|
21 |
*
|
22 |
-
* @var PLL_Language
|
23 |
*/
|
24 |
public $curlang;
|
25 |
|
@@ -38,9 +38,13 @@ class PLL_Frontend_Filters_Search {
|
|
38 |
// Low priority in case the search form is created using the same filter as described in http://codex.wordpress.org/Function_Reference/get_search_form
|
39 |
add_filter( 'get_search_form', array( $this, 'get_search_form' ), 99 );
|
40 |
|
|
|
|
|
|
|
41 |
// Adds the language information in admin bar search form
|
42 |
add_action( 'add_admin_bar_menus', array( $this, 'add_admin_bar_menus' ) );
|
43 |
|
|
|
44 |
// Adds javascript at the end of the document
|
45 |
// Was used for WP < 3.6. kept just in case
|
46 |
if ( defined( 'PLL_SEARCH_FORM_JS' ) && PLL_SEARCH_FORM_JS ) {
|
@@ -59,17 +63,25 @@ class PLL_Frontend_Filters_Search {
|
|
59 |
* @return string Modified search form.
|
60 |
*/
|
61 |
public function get_search_form( $form ) {
|
62 |
-
if ( $form ) {
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
return $form;
|
19 |
/**
|
20 |
* Current language.
|
21 |
*
|
22 |
+
* @var PLL_Language|null
|
23 |
*/
|
24 |
public $curlang;
|
25 |
|
38 |
// Low priority in case the search form is created using the same filter as described in http://codex.wordpress.org/Function_Reference/get_search_form
|
39 |
add_filter( 'get_search_form', array( $this, 'get_search_form' ), 99 );
|
40 |
|
41 |
+
// Adds the language information in the search block.
|
42 |
+
add_filter( 'render_block_core/search', array( $this, 'get_search_form' ) );
|
43 |
+
|
44 |
// Adds the language information in admin bar search form
|
45 |
add_action( 'add_admin_bar_menus', array( $this, 'add_admin_bar_menus' ) );
|
46 |
|
47 |
+
|
48 |
// Adds javascript at the end of the document
|
49 |
// Was used for WP < 3.6. kept just in case
|
50 |
if ( defined( 'PLL_SEARCH_FORM_JS' ) && PLL_SEARCH_FORM_JS ) {
|
63 |
* @return string Modified search form.
|
64 |
*/
|
65 |
public function get_search_form( $form ) {
|
66 |
+
if ( empty( $form ) ) {
|
67 |
+
return $form;
|
68 |
+
}
|
69 |
+
|
70 |
+
if ( $this->links_model->using_permalinks ) {
|
71 |
+
// Take care to modify only the url in the <form> tag.
|
72 |
+
preg_match( '#<form.+?>#', $form, $matches );
|
73 |
+
$old = reset( $matches );
|
74 |
+
if ( empty( $old ) ) {
|
75 |
+
return $form;
|
76 |
+
}
|
77 |
+
// Replace action attribute (a text with no space and no closing tag within double quotes or simple quotes or without quotes).
|
78 |
+
$new = preg_replace( '#\saction=("[^"\r\n]+"|\'[^\'\r\n]+\'|[^\'"][^>\s]+)#', ' action="' . esc_url( $this->curlang->search_url ) . '"', $old );
|
79 |
+
if ( empty( $new ) ) {
|
80 |
+
return $form;
|
81 |
}
|
82 |
+
$form = str_replace( $old, $new, $form );
|
83 |
+
} else {
|
84 |
+
$form = str_replace( '</form>', '<input type="hidden" name="lang" value="' . esc_attr( $this->curlang->slug ) . '" /></form>', $form );
|
85 |
}
|
86 |
|
87 |
return $form;
|
frontend/frontend-filters-widgets.php
CHANGED
@@ -19,7 +19,7 @@ class PLL_Frontend_Filters_Widgets {
|
|
19 |
/**
|
20 |
* Current language.
|
21 |
*
|
22 |
-
* @var PLL_Language
|
23 |
*/
|
24 |
public $curlang;
|
25 |
|
19 |
/**
|
20 |
* Current language.
|
21 |
*
|
22 |
+
* @var PLL_Language|null
|
23 |
*/
|
24 |
public $curlang;
|
25 |
|
frontend/frontend-filters.php
CHANGED
@@ -121,7 +121,15 @@ class PLL_Frontend_Filters extends PLL_Filters {
|
|
121 |
* @return string modified WHERE clause
|
122 |
*/
|
123 |
public function getarchives_where( $sql, $r ) {
|
124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
|
127 |
/**
|
121 |
* @return string modified WHERE clause
|
122 |
*/
|
123 |
public function getarchives_where( $sql, $r ) {
|
124 |
+
if ( ! $this->curlang instanceof PLL_Language ) {
|
125 |
+
return $sql;
|
126 |
+
}
|
127 |
+
|
128 |
+
if ( empty( $r['post_type'] ) || ! $this->model->is_translated_post_type( $r['post_type'] ) ) {
|
129 |
+
return $sql;
|
130 |
+
}
|
131 |
+
|
132 |
+
return $sql . $this->model->post->where_clause( $this->curlang );
|
133 |
}
|
134 |
|
135 |
/**
|
frontend/frontend-links.php
CHANGED
@@ -9,12 +9,6 @@
|
|
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.
|
@@ -89,7 +83,7 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
89 |
if ( ! empty( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) ) {
|
90 |
|
91 |
$tax = get_taxonomy( $tax_query['taxonomy'] );
|
92 |
-
$terms = get_terms( $tax->name,
|
93 |
|
94 |
foreach ( $tax_query['terms'] as $slug ) {
|
95 |
$term_id = array_search( $slug, $terms ); // What is the term_id corresponding to taxonomy term?
|
@@ -115,7 +109,7 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
115 |
elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
|
116 |
if ( $tr_term = get_term( $tr_id, $term->taxonomy ) ) {
|
117 |
// Check if translated term ( or children ) have posts
|
118 |
-
$count = $tr_term->count || ( is_taxonomy_hierarchical( $term->taxonomy ) && array_sum( wp_list_pluck( get_terms( $term->taxonomy,
|
119 |
|
120 |
/**
|
121 |
* Filter whether to hide an archive translation url
|
@@ -166,6 +160,8 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
166 |
}
|
167 |
}
|
168 |
|
|
|
|
|
169 |
/**
|
170 |
* Filter the translation url of the current page before Polylang caches it
|
171 |
*
|
@@ -174,7 +170,7 @@ class PLL_Frontend_Links extends PLL_Links {
|
|
174 |
* @param null|string $url The translation url, null if none was found
|
175 |
* @param string $language The language code of the translation
|
176 |
*/
|
177 |
-
$translation_url = apply_filters( 'pll_translation_url',
|
178 |
|
179 |
// Don't cache before template_redirect to avoid a conflict with Barrel + WP Bakery Page Builder
|
180 |
if ( did_action( 'template_redirect' ) ) {
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
class PLL_Frontend_Links extends PLL_Links {
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
* Internal non persistent cache object.
|
83 |
if ( ! empty( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) ) {
|
84 |
|
85 |
$tax = get_taxonomy( $tax_query['taxonomy'] );
|
86 |
+
$terms = get_terms( array( 'taxonomy' => $tax->name, 'fields' => 'id=>slug' ) ); // Filtered by current language
|
87 |
|
88 |
foreach ( $tax_query['terms'] as $slug ) {
|
89 |
$term_id = array_search( $slug, $terms ); // What is the term_id corresponding to taxonomy term?
|
109 |
elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
|
110 |
if ( $tr_term = get_term( $tr_id, $term->taxonomy ) ) {
|
111 |
// Check if translated term ( or children ) have posts
|
112 |
+
$count = $tr_term->count || ( is_taxonomy_hierarchical( $term->taxonomy ) && array_sum( wp_list_pluck( get_terms( array( 'taxonomy' => $term->taxonomy, 'child_of' => $tr_term->term_id, 'lang' => $language->slug ) ), 'count' ) ) );
|
113 |
|
114 |
/**
|
115 |
* Filter whether to hide an archive translation url
|
160 |
}
|
161 |
}
|
162 |
|
163 |
+
$url = ! empty( $url ) && ! is_wp_error( $url ) ? $url : null;
|
164 |
+
|
165 |
/**
|
166 |
* Filter the translation url of the current page before Polylang caches it
|
167 |
*
|
170 |
* @param null|string $url The translation url, null if none was found
|
171 |
* @param string $language The language code of the translation
|
172 |
*/
|
173 |
+
$translation_url = apply_filters( 'pll_translation_url', $url, $language->slug );
|
174 |
|
175 |
// Don't cache before template_redirect to avoid a conflict with Barrel + WP Bakery Page Builder
|
176 |
if ( did_action( 'template_redirect' ) ) {
|
frontend/frontend-nav-menu.php
CHANGED
@@ -12,7 +12,7 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
12 |
/**
|
13 |
* Current language.
|
14 |
*
|
15 |
-
* @var PLL_Language
|
16 |
*/
|
17 |
public $curlang;
|
18 |
|
@@ -90,6 +90,10 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
|
|
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
|
94 |
return $items;
|
95 |
}
|
12 |
/**
|
13 |
* Current language.
|
14 |
*
|
15 |
+
* @var PLL_Language|null|false
|
16 |
*/
|
17 |
public $curlang;
|
18 |
|
90 |
* @return stdClass[] Modified menu items.
|
91 |
*/
|
92 |
public function wp_get_nav_menu_items( $items ) {
|
93 |
+
if ( empty( $this->curlang ) ) {
|
94 |
+
return $items;
|
95 |
+
}
|
96 |
+
|
97 |
if ( doing_action( 'customize_register' ) ) { // needed since WP 4.3, doing_action available since WP 3.9
|
98 |
return $items;
|
99 |
}
|
frontend/frontend-static-pages.php
CHANGED
@@ -17,7 +17,7 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
17 |
protected $links_model;
|
18 |
|
19 |
/**
|
20 |
-
* @var PLL_Frontend_Links
|
21 |
*/
|
22 |
protected $links;
|
23 |
|
@@ -34,7 +34,6 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
34 |
$this->links_model = &$polylang->links_model;
|
35 |
$this->links = &$polylang->links;
|
36 |
|
37 |
-
add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ) );
|
38 |
add_action( 'pll_home_requested', array( $this, 'pll_home_requested' ) );
|
39 |
|
40 |
// Manages the redirection of the homepage
|
@@ -55,12 +54,7 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
55 |
* @return void
|
56 |
*/
|
57 |
public function pll_language_defined() {
|
58 |
-
|
59 |
-
$this->init();
|
60 |
-
|
61 |
-
// Translates page for posts and page on front
|
62 |
-
add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) );
|
63 |
-
add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
|
64 |
|
65 |
// Support theme customizer
|
66 |
if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
@@ -80,19 +74,6 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
80 |
set_query_var( 'page_id', $this->curlang->page_on_front );
|
81 |
}
|
82 |
|
83 |
-
/**
|
84 |
-
* Translates page on front
|
85 |
-
*
|
86 |
-
* @since 1.8
|
87 |
-
*
|
88 |
-
* @param int $v page on front page id
|
89 |
-
* @return int
|
90 |
-
*/
|
91 |
-
public function translate_page_on_front( $v ) {
|
92 |
-
// Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache
|
93 |
-
return isset( $this->curlang->page_on_front ) && ( $this->curlang->page_on_front ) && ! doing_action( 'switch_blog' ) ? $this->curlang->page_on_front : $v;
|
94 |
-
}
|
95 |
-
|
96 |
/**
|
97 |
* Manages canonical redirection of the homepage when using page on front
|
98 |
*
|
@@ -184,13 +165,8 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
184 |
return $lang;
|
185 |
}
|
186 |
|
187 |
-
// The home page is requested
|
188 |
-
if ( did_action( 'home_requested' ) ) {
|
189 |
-
$query->set( 'page_id', $lang->page_on_front );
|
190 |
-
}
|
191 |
-
|
192 |
// Redirect the language page to the homepage when using a static front page
|
193 |
-
|
194 |
$query->is_archive = $query->is_tax = false;
|
195 |
if ( ! empty( $lang->page_on_front ) ) {
|
196 |
$query->set( 'page_id', $lang->page_on_front );
|
@@ -205,6 +181,9 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
205 |
// Fix paged static front page in plain permalinks when Settings > Reading doesn't match the default language
|
206 |
elseif ( ! $this->links_model->using_permalinks && count( $query->query ) === 1 && ! empty( $query->query['page'] ) ) {
|
207 |
$lang = $this->model->get_language( $this->options['default_lang'] );
|
|
|
|
|
|
|
208 |
$query->set( 'page_id', $lang->page_on_front );
|
209 |
$query->is_singular = $query->is_page = true;
|
210 |
$query->is_archive = $query->is_tax = false;
|
@@ -249,7 +228,7 @@ class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
|
|
249 |
if ( ! empty( $page_id ) && in_array( $page_id, $pages = $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) {
|
250 |
// Fill the cache with all pages for posts to avoid one query per page later
|
251 |
// The posts_per_page limit is a trick to avoid splitting the query
|
252 |
-
get_posts( array( 'posts_per_page' =>
|
253 |
|
254 |
$lang = $this->model->post->get_language( $page_id );
|
255 |
$query->is_singular = $query->is_page = false;
|
17 |
protected $links_model;
|
18 |
|
19 |
/**
|
20 |
+
* @var PLL_Frontend_Links|null
|
21 |
*/
|
22 |
protected $links;
|
23 |
|
34 |
$this->links_model = &$polylang->links_model;
|
35 |
$this->links = &$polylang->links;
|
36 |
|
|
|
37 |
add_action( 'pll_home_requested', array( $this, 'pll_home_requested' ) );
|
38 |
|
39 |
// Manages the redirection of the homepage
|
54 |
* @return void
|
55 |
*/
|
56 |
public function pll_language_defined() {
|
57 |
+
parent::pll_language_defined();
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
// Support theme customizer
|
60 |
if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
74 |
set_query_var( 'page_id', $this->curlang->page_on_front );
|
75 |
}
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
/**
|
78 |
* Manages canonical redirection of the homepage when using page on front
|
79 |
*
|
165 |
return $lang;
|
166 |
}
|
167 |
|
|
|
|
|
|
|
|
|
|
|
168 |
// Redirect the language page to the homepage when using a static front page
|
169 |
+
if ( ( $this->options['redirect_lang'] || $this->options['hide_default'] ) && $this->is_front_page( $query ) && $lang = $this->model->get_language( get_query_var( 'lang' ) ) ) {
|
170 |
$query->is_archive = $query->is_tax = false;
|
171 |
if ( ! empty( $lang->page_on_front ) ) {
|
172 |
$query->set( 'page_id', $lang->page_on_front );
|
181 |
// Fix paged static front page in plain permalinks when Settings > Reading doesn't match the default language
|
182 |
elseif ( ! $this->links_model->using_permalinks && count( $query->query ) === 1 && ! empty( $query->query['page'] ) ) {
|
183 |
$lang = $this->model->get_language( $this->options['default_lang'] );
|
184 |
+
if ( empty( $lang ) ) {
|
185 |
+
return $lang;
|
186 |
+
}
|
187 |
$query->set( 'page_id', $lang->page_on_front );
|
188 |
$query->is_singular = $query->is_page = true;
|
189 |
$query->is_archive = $query->is_tax = false;
|
228 |
if ( ! empty( $page_id ) && in_array( $page_id, $pages = $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) {
|
229 |
// Fill the cache with all pages for posts to avoid one query per page later
|
230 |
// The posts_per_page limit is a trick to avoid splitting the query
|
231 |
+
get_posts( array( 'posts_per_page' => 99, 'post_type' => 'page', 'post__in' => $pages, 'lang' => '' ) );
|
232 |
|
233 |
$lang = $this->model->post->get_language( $page_id );
|
234 |
$query->is_singular = $query->is_page = false;
|
frontend/frontend.php
CHANGED
@@ -12,54 +12,54 @@ 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 |
-
* @var PLL_Frontend_Filters_Widgets
|
63 |
*/
|
64 |
public $filters_widgets;
|
65 |
|
@@ -128,6 +128,14 @@ class PLL_Frontend extends PLL_Base {
|
|
128 |
$this->filters_search = new PLL_Frontend_Filters_Search( $this );
|
129 |
$this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
// Auto translate for Ajax
|
132 |
if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
|
133 |
$this->auto_translate();
|
12 |
/**
|
13 |
* Current language.
|
14 |
*
|
15 |
+
* @var PLL_Language|null
|
16 |
*/
|
17 |
public $curlang;
|
18 |
|
19 |
/**
|
20 |
+
* @var PLL_Frontend_Auto_Translate|null
|
21 |
*/
|
22 |
public $auto_translate;
|
23 |
|
24 |
/**
|
25 |
* The class selecting the current language.
|
26 |
*
|
27 |
+
* @var PLL_Choose_Lang|null
|
28 |
*/
|
29 |
public $choose_lang;
|
30 |
|
31 |
/**
|
32 |
+
* @var PLL_Frontend_Filters|null
|
33 |
*/
|
34 |
public $filters;
|
35 |
|
36 |
/**
|
37 |
+
* @var PLL_Frontend_Filters_Links|null
|
38 |
*/
|
39 |
public $filters_links;
|
40 |
|
41 |
/**
|
42 |
+
* @var PLL_Frontend_Filters_Search|null
|
43 |
*/
|
44 |
public $filters_search;
|
45 |
|
46 |
/**
|
47 |
+
* @var PLL_Frontend_Links|null
|
48 |
*/
|
49 |
public $links;
|
50 |
|
51 |
/**
|
52 |
+
* @var PLL_Frontend_Nav_Menu|null
|
53 |
*/
|
54 |
public $nav_menu;
|
55 |
|
56 |
/**
|
57 |
+
* @var PLL_Frontend_Static_Pages|null
|
58 |
*/
|
59 |
public $static_pages;
|
60 |
|
61 |
/**
|
62 |
+
* @var PLL_Frontend_Filters_Widgets|null
|
63 |
*/
|
64 |
public $filters_widgets;
|
65 |
|
128 |
$this->filters_search = new PLL_Frontend_Filters_Search( $this );
|
129 |
$this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
|
130 |
|
131 |
+
/*
|
132 |
+
* Redirects to canonical url before WordPress redirect_canonical
|
133 |
+
* but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!!
|
134 |
+
* and restores it in 'template_redirect' with priority 1.
|
135 |
+
*/
|
136 |
+
$this->canonical = new PLL_Canonical( $this );
|
137 |
+
add_action( 'template_redirect', array( $this->canonical, 'check_canonical_url' ), 4 );
|
138 |
+
|
139 |
// Auto translate for Ajax
|
140 |
if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
|
141 |
$this->auto_translate();
|
include/base.php
CHANGED
@@ -8,6 +8,7 @@
|
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
|
|
11 |
abstract class PLL_Base {
|
12 |
/**
|
13 |
* Stores the plugin options.
|
@@ -31,14 +32,14 @@ abstract class PLL_Base {
|
|
31 |
/**
|
32 |
* Registers hooks on insert / update post related actions and filters.
|
33 |
*
|
34 |
-
* @var PLL_CRUD_Posts
|
35 |
*/
|
36 |
public $posts;
|
37 |
|
38 |
/**
|
39 |
* Registers hooks on insert / update term related action and filters.
|
40 |
*
|
41 |
-
* @var PLL_CRUD_Terms
|
42 |
*/
|
43 |
public $terms;
|
44 |
|
8 |
*
|
9 |
* @since 1.2
|
10 |
*/
|
11 |
+
#[AllowDynamicProperties]
|
12 |
abstract class PLL_Base {
|
13 |
/**
|
14 |
* Stores the plugin options.
|
32 |
/**
|
33 |
* Registers hooks on insert / update post related actions and filters.
|
34 |
*
|
35 |
+
* @var PLL_CRUD_Posts|null
|
36 |
*/
|
37 |
public $posts;
|
38 |
|
39 |
/**
|
40 |
* Registers hooks on insert / update term related action and filters.
|
41 |
*
|
42 |
+
* @var PLL_CRUD_Terms|null
|
43 |
*/
|
44 |
public $terms;
|
45 |
|
include/cache.php
CHANGED
@@ -22,7 +22,7 @@ class PLL_Cache {
|
|
22 |
*
|
23 |
* @var array
|
24 |
*/
|
25 |
-
protected $cache;
|
26 |
|
27 |
/**
|
28 |
* Constructor
|
22 |
*
|
23 |
* @var array
|
24 |
*/
|
25 |
+
protected $cache = array();
|
26 |
|
27 |
/**
|
28 |
* Constructor
|
include/class-polylang.php
CHANGED
@@ -193,9 +193,8 @@ class Polylang {
|
|
193 |
*/
|
194 |
$class = apply_filters( 'pll_model', PLL_SETTINGS || self::is_wizard() ? 'PLL_Admin_Model' : 'PLL_Model' );
|
195 |
$model = new $class( $options );
|
196 |
-
$links_model = $model->get_links_model();
|
197 |
|
198 |
-
if ( ! $model->
|
199 |
/**
|
200 |
* Fires when no language has been defined yet
|
201 |
* Used to load overridden textdomains
|
@@ -213,7 +212,7 @@ class Polylang {
|
|
213 |
$class = 'PLL_Admin';
|
214 |
} elseif ( self::is_rest_request() ) {
|
215 |
$class = 'PLL_REST_Request';
|
216 |
-
} elseif ( $model->
|
217 |
$class = 'PLL_Frontend';
|
218 |
}
|
219 |
|
@@ -227,7 +226,8 @@ class Polylang {
|
|
227 |
$class = apply_filters( 'pll_context', $class );
|
228 |
|
229 |
if ( ! empty( $class ) ) {
|
230 |
-
$
|
|
|
231 |
|
232 |
/**
|
233 |
* Fires after the $polylang object is created and before the API is loaded
|
193 |
*/
|
194 |
$class = apply_filters( 'pll_model', PLL_SETTINGS || self::is_wizard() ? 'PLL_Admin_Model' : 'PLL_Model' );
|
195 |
$model = new $class( $options );
|
|
|
196 |
|
197 |
+
if ( ! $model->has_languages() ) {
|
198 |
/**
|
199 |
* Fires when no language has been defined yet
|
200 |
* Used to load overridden textdomains
|
212 |
$class = 'PLL_Admin';
|
213 |
} elseif ( self::is_rest_request() ) {
|
214 |
$class = 'PLL_REST_Request';
|
215 |
+
} elseif ( $model->has_languages() ) {
|
216 |
$class = 'PLL_Frontend';
|
217 |
}
|
218 |
|
226 |
$class = apply_filters( 'pll_context', $class );
|
227 |
|
228 |
if ( ! empty( $class ) ) {
|
229 |
+
$links_model = $model->get_links_model();
|
230 |
+
$polylang = new $class( $links_model );
|
231 |
|
232 |
/**
|
233 |
* Fires after the $polylang object is created and before the API is loaded
|
include/crud-posts.php
CHANGED
@@ -18,14 +18,14 @@ class PLL_CRUD_Posts {
|
|
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 |
|
@@ -123,10 +123,10 @@ class PLL_CRUD_Posts {
|
|
123 |
*
|
124 |
* @since 2.3
|
125 |
*
|
126 |
-
* @param int
|
127 |
-
* @param
|
128 |
-
* @param int[]
|
129 |
-
* @param string
|
130 |
* @return void
|
131 |
*/
|
132 |
public function set_object_terms( $object_id, $terms, $tt_ids, $taxonomy ) {
|
@@ -139,7 +139,7 @@ class PLL_CRUD_Posts {
|
|
139 |
// Convert to term ids if we got tag names
|
140 |
$strings = array_filter( $terms, 'is_string' );
|
141 |
if ( ! empty( $strings ) ) {
|
142 |
-
$_terms = get_terms( $taxonomy,
|
143 |
$terms = array_merge( array_diff( $terms, $strings ), $_terms );
|
144 |
}
|
145 |
|
@@ -283,7 +283,9 @@ class PLL_CRUD_Posts {
|
|
283 |
// Create a new attachment ( translate attachment parent if exists ).
|
284 |
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
|
285 |
unset( $post['ID'] ); // Will force the creation.
|
286 |
-
|
|
|
|
|
287 |
$post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
|
288 |
$tr_id = wp_insert_attachment( wp_slash( $post ) );
|
289 |
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
|
18 |
/**
|
19 |
* Preferred language to assign to a new post.
|
20 |
*
|
21 |
+
* @var PLL_Language|null
|
22 |
*/
|
23 |
protected $pref_lang;
|
24 |
|
25 |
/**
|
26 |
* Current language.
|
27 |
*
|
28 |
+
* @var PLL_Language|null
|
29 |
*/
|
30 |
protected $curlang;
|
31 |
|
123 |
*
|
124 |
* @since 2.3
|
125 |
*
|
126 |
+
* @param int $object_id Object ID.
|
127 |
+
* @param int[]|string[] $terms An array of object term IDs or slugs.
|
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 ) {
|
139 |
// Convert to term ids if we got tag names
|
140 |
$strings = array_filter( $terms, 'is_string' );
|
141 |
if ( ! empty( $strings ) ) {
|
142 |
+
$_terms = get_terms( array( 'taxonomy' => $taxonomy, 'name' => $strings, 'object_ids' => $object_id, 'fields' => 'ids' ) );
|
143 |
$terms = array_merge( array_diff( $terms, $strings ), $_terms );
|
144 |
}
|
145 |
|
283 |
// Create a new attachment ( translate attachment parent if exists ).
|
284 |
add_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Avoid a conflict with automatic duplicate at upload.
|
285 |
unset( $post['ID'] ); // Will force the creation.
|
286 |
+
if ( ! empty( $post['post_parent'] ) ) {
|
287 |
+
$post['post_parent'] = (int) $this->model->post->get_translation( $post['post_parent'], $lang->slug );
|
288 |
+
}
|
289 |
$post['tax_input'] = array( 'language' => array( $lang->slug ) ); // Assigns the language.
|
290 |
$tr_id = wp_insert_attachment( wp_slash( $post ) );
|
291 |
remove_filter( 'pll_enable_duplicate_media', '__return_false', 99 ); // Restore automatic duplicate at upload.
|
include/crud-terms.php
CHANGED
@@ -18,31 +18,38 @@ class PLL_CRUD_Terms {
|
|
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 |
/**
|
47 |
* Constructor
|
48 |
*
|
@@ -51,14 +58,16 @@ class PLL_CRUD_Terms {
|
|
51 |
* @param object $polylang
|
52 |
*/
|
53 |
public function __construct( &$polylang ) {
|
54 |
-
$this->model
|
55 |
-
$this->curlang
|
56 |
$this->filter_lang = &$polylang->filter_lang;
|
57 |
-
$this->pref_lang
|
58 |
|
59 |
// Saving terms
|
60 |
add_action( 'create_term', array( $this, 'save_term' ), 999, 3 );
|
61 |
add_action( 'edit_term', array( $this, 'save_term' ), 999, 3 ); // After PLL_Admin_Filters_Term
|
|
|
|
|
62 |
|
63 |
// Adds cache domain when querying terms
|
64 |
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
|
@@ -244,4 +253,77 @@ class PLL_CRUD_Terms {
|
|
244 |
$this->model->term->delete_translation( $term_id );
|
245 |
$this->model->term->delete_language( $term_id );
|
246 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
}
|
18 |
/**
|
19 |
* Current language (used to filter the content).
|
20 |
*
|
21 |
+
* @var PLL_Language|null
|
22 |
*/
|
23 |
public $curlang;
|
24 |
|
25 |
/**
|
26 |
* Language selected in the admin language filter.
|
27 |
*
|
28 |
+
* @var PLL_Language|null
|
29 |
*/
|
30 |
public $filter_lang;
|
31 |
|
32 |
/**
|
33 |
* Preferred language to assign to new contents.
|
34 |
*
|
35 |
+
* @var PLL_Language|null
|
36 |
*/
|
37 |
public $pref_lang;
|
38 |
|
39 |
/**
|
40 |
* Stores the 'lang' query var from WP_Query.
|
41 |
*
|
42 |
+
* @var string|null
|
43 |
*/
|
44 |
private $tax_query_lang;
|
45 |
|
46 |
+
/**
|
47 |
+
* Stores the term name before creating a slug if needed.
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
+
private $pre_term_name = '';
|
52 |
+
|
53 |
/**
|
54 |
* Constructor
|
55 |
*
|
58 |
* @param object $polylang
|
59 |
*/
|
60 |
public function __construct( &$polylang ) {
|
61 |
+
$this->model = &$polylang->model;
|
62 |
+
$this->curlang = &$polylang->curlang;
|
63 |
$this->filter_lang = &$polylang->filter_lang;
|
64 |
+
$this->pref_lang = &$polylang->pref_lang;
|
65 |
|
66 |
// Saving terms
|
67 |
add_action( 'create_term', array( $this, 'save_term' ), 999, 3 );
|
68 |
add_action( 'edit_term', array( $this, 'save_term' ), 999, 3 ); // After PLL_Admin_Filters_Term
|
69 |
+
add_filter( 'pre_term_name', array( $this, 'set_pre_term_name' ) );
|
70 |
+
add_filter( 'pre_term_slug', array( $this, 'set_pre_term_slug' ), 10, 2 );
|
71 |
|
72 |
// Adds cache domain when querying terms
|
73 |
add_filter( 'get_terms_args', array( $this, 'get_terms_args' ), 10, 2 );
|
253 |
$this->model->term->delete_translation( $term_id );
|
254 |
$this->model->term->delete_language( $term_id );
|
255 |
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Stores the term name for use in pre_term_slug
|
259 |
+
*
|
260 |
+
* @since 0.9.5
|
261 |
+
*
|
262 |
+
* @param string $name term name
|
263 |
+
* @return string unmodified term name
|
264 |
+
*/
|
265 |
+
public function set_pre_term_name( $name ) {
|
266 |
+
return $this->pre_term_name = $name;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Appends language slug to the term slug if needed.
|
271 |
+
*
|
272 |
+
* @since 3.3
|
273 |
+
*
|
274 |
+
* @param string $slug Term slug.
|
275 |
+
* @param string $taxonomy Term taxonomy.
|
276 |
+
* @return string Slug with a language suffix if found.
|
277 |
+
*/
|
278 |
+
public function set_pre_term_slug( $slug, $taxonomy ) {
|
279 |
+
if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
280 |
+
return $slug;
|
281 |
+
}
|
282 |
+
|
283 |
+
if ( ! $slug ) {
|
284 |
+
$slug = sanitize_title( $this->pre_term_name );
|
285 |
+
}
|
286 |
+
|
287 |
+
if ( ! term_exists( $slug, $taxonomy ) ) {
|
288 |
+
return $slug;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Filters the subsequently inserted term language.
|
293 |
+
*
|
294 |
+
* @since 3.3
|
295 |
+
*
|
296 |
+
* @param PLL_Language|null $lang Found language object, null otherwise.
|
297 |
+
* @param string $taxonomy Term taonomy.
|
298 |
+
* @param string $slug Term slug
|
299 |
+
*/
|
300 |
+
$lang = apply_filters( 'pll_inserted_term_language', null, $taxonomy, $slug );
|
301 |
+
|
302 |
+
if ( ! $lang instanceof PLL_Language ) {
|
303 |
+
return $slug;
|
304 |
+
}
|
305 |
+
|
306 |
+
$parent = 0;
|
307 |
+
if ( is_taxonomy_hierarchical( $taxonomy ) ) {
|
308 |
+
/**
|
309 |
+
* Filters the subsequently inserted term parent.
|
310 |
+
*
|
311 |
+
* @since 3.3
|
312 |
+
*
|
313 |
+
* @param int $parent Parent term ID, 0 if none.
|
314 |
+
* @param string $taxonomy Term taxonomy.
|
315 |
+
* @param string $slug Term slug
|
316 |
+
*/
|
317 |
+
$parent = apply_filters( 'pll_inserted_term_parent', 0, $taxonomy, $slug );
|
318 |
+
}
|
319 |
+
|
320 |
+
$term_id = (int) $this->model->term_exists_by_slug( $slug, $lang, $taxonomy, $parent );
|
321 |
+
|
322 |
+
// If no term exist in the given language with that slug, it can be created.
|
323 |
+
if ( ! $term_id ) {
|
324 |
+
$slug .= '-' . $lang->slug;
|
325 |
+
}
|
326 |
+
|
327 |
+
return $slug;
|
328 |
+
}
|
329 |
}
|
include/db-tools.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* @package Polylang
|
4 |
*/
|
5 |
|
6 |
-
defined( 'ABSPATH' ) || exit;
|
7 |
|
8 |
/**
|
9 |
* Small set of tools to work with the database.
|
@@ -18,8 +18,8 @@ class PLL_Db_Tools {
|
|
18 |
*
|
19 |
* @since 3.2
|
20 |
*
|
21 |
-
* @param
|
22 |
-
* @return string
|
23 |
*/
|
24 |
public static function prepare_values_list( $values ) {
|
25 |
$values = array_map( array( __CLASS__, 'prepare_value' ), (array) $values );
|
@@ -31,10 +31,11 @@ class PLL_Db_Tools {
|
|
31 |
* Wraps a value in escaped double quotes or casts as an integer.
|
32 |
* Only string and integers and supported for now.
|
33 |
*
|
34 |
-
* @since
|
|
|
35 |
* @global wpdb $wpdb
|
36 |
*
|
37 |
-
* @param
|
38 |
* @return int|string
|
39 |
*/
|
40 |
public static function prepare_value( $value ) {
|
3 |
* @package Polylang
|
4 |
*/
|
5 |
|
6 |
+
defined( 'ABSPATH' ) || exit;
|
7 |
|
8 |
/**
|
9 |
* Small set of tools to work with the database.
|
18 |
*
|
19 |
* @since 3.2
|
20 |
*
|
21 |
+
* @param (int|string)[] $values An array of values.
|
22 |
+
* @return string A comma separated list of values.
|
23 |
*/
|
24 |
public static function prepare_values_list( $values ) {
|
25 |
$values = array_map( array( __CLASS__, 'prepare_value' ), (array) $values );
|
31 |
* Wraps a value in escaped double quotes or casts as an integer.
|
32 |
* Only string and integers and supported for now.
|
33 |
*
|
34 |
+
* @since 3.2
|
35 |
+
*
|
36 |
* @global wpdb $wpdb
|
37 |
*
|
38 |
+
* @param int|string $value A value.
|
39 |
* @return int|string
|
40 |
*/
|
41 |
public static function prepare_value( $value ) {
|
include/filters-links.php
CHANGED
@@ -29,14 +29,14 @@ class PLL_Filters_Links {
|
|
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 |
|
@@ -185,16 +185,16 @@ class PLL_Filters_Links {
|
|
185 |
|
186 |
/**
|
187 |
* Modifies the post type archive links to add the language parameter
|
188 |
-
* only if the post type is translated
|
189 |
*
|
190 |
* The filter was originally only on frontend but is needed on admin too for
|
191 |
-
* compatibility with the archive link of the ACF link field since ACF 5.4.0
|
192 |
*
|
193 |
* @since 1.7.6
|
194 |
*
|
195 |
-
* @param string $link
|
196 |
-
* @param string $post_type
|
197 |
-
* @return string
|
198 |
*/
|
199 |
public function post_type_archive_link( $link, $post_type ) {
|
200 |
return $this->model->is_translated_post_type( $post_type ) && 'post' !== $post_type ? $this->links_model->switch_language_in_link( $link, $this->curlang ) : $link;
|
29 |
public $links_model;
|
30 |
|
31 |
/**
|
32 |
+
* @var PLL_Links|null
|
33 |
*/
|
34 |
public $links;
|
35 |
|
36 |
/**
|
37 |
* Current language.
|
38 |
*
|
39 |
+
* @var PLL_Language|null
|
40 |
*/
|
41 |
public $curlang;
|
42 |
|
185 |
|
186 |
/**
|
187 |
* Modifies the post type archive links to add the language parameter
|
188 |
+
* only if the post type is translated.
|
189 |
*
|
190 |
* The filter was originally only on frontend but is needed on admin too for
|
191 |
+
* compatibility with the archive link of the ACF link field since ACF 5.4.0.
|
192 |
*
|
193 |
* @since 1.7.6
|
194 |
*
|
195 |
+
* @param string $link The post type archive permalink.
|
196 |
+
* @param string $post_type Post type name.
|
197 |
+
* @return string
|
198 |
*/
|
199 |
public function post_type_archive_link( $link, $post_type ) {
|
200 |
return $this->model->is_translated_post_type( $post_type ) && 'post' !== $post_type ? $this->links_model->switch_language_in_link( $link, $this->curlang ) : $link;
|
include/filters.php
CHANGED
@@ -31,7 +31,7 @@ class PLL_Filters {
|
|
31 |
/**
|
32 |
* Current language.
|
33 |
*
|
34 |
-
* @var PLL_Language
|
35 |
*/
|
36 |
public $curlang;
|
37 |
|
@@ -425,10 +425,10 @@ class PLL_Filters {
|
|
425 |
*
|
426 |
* @since 3.2
|
427 |
*
|
428 |
-
* @param array
|
429 |
-
* @param int|string
|
430 |
-
* @param string
|
431 |
-
* @return array
|
432 |
*/
|
433 |
public function term_exists_default_query_args( $defaults, $term, $taxonomy ) {
|
434 |
if ( ! empty( $taxonomy ) && ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
31 |
/**
|
32 |
* Current language.
|
33 |
*
|
34 |
+
* @var PLL_Language|null
|
35 |
*/
|
36 |
public $curlang;
|
37 |
|
425 |
*
|
426 |
* @since 3.2
|
427 |
*
|
428 |
+
* @param array $defaults An array of arguments passed to get_terms().
|
429 |
+
* @param int|string $term The term to check. Accepts term ID, slug, or name.
|
430 |
+
* @param string $taxonomy The taxonomy name to use. An empty string indicates the search is against all taxonomies.
|
431 |
+
* @return array
|
432 |
*/
|
433 |
public function term_exists_default_query_args( $defaults, $term, $taxonomy ) {
|
434 |
if ( ! empty( $taxonomy ) && ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
|
include/language.php
CHANGED
@@ -9,6 +9,7 @@
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
|
|
12 |
class PLL_Language {
|
13 |
/**
|
14 |
* Id of the term in 'language' taxonomy.
|
@@ -90,35 +91,35 @@ class PLL_Language {
|
|
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 |
|
@@ -132,14 +133,14 @@ class PLL_Language {
|
|
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 |
|
@@ -153,28 +154,28 @@ class PLL_Language {
|
|
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 |
public $custom_flag_url;
|
173 |
|
174 |
/**
|
175 |
* Html markup of the custom flag if it exists.
|
176 |
*
|
177 |
-
* @var string
|
178 |
*/
|
179 |
public $custom_flag;
|
180 |
|
@@ -459,11 +460,19 @@ class PLL_Language {
|
|
459 |
* @return void
|
460 |
*/
|
461 |
public function set_url_scheme() {
|
462 |
-
|
463 |
-
|
|
|
|
|
|
|
|
|
|
|
464 |
|
465 |
// Set url scheme, also for the flags.
|
466 |
-
|
|
|
|
|
|
|
467 |
if ( ! empty( $this->custom_flag_url ) ) {
|
468 |
$this->custom_flag_url = set_url_scheme( $this->custom_flag_url );
|
469 |
}
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
12 |
+
#[AllowDynamicProperties]
|
13 |
class PLL_Language {
|
14 |
/**
|
15 |
* Id of the term in 'language' taxonomy.
|
91 |
/**
|
92 |
* W3C locale.
|
93 |
*
|
94 |
+
* @var string
|
95 |
*/
|
96 |
public $w3c;
|
97 |
|
98 |
/**
|
99 |
* Facebook locale.
|
100 |
*
|
101 |
+
* @var string|null
|
102 |
*/
|
103 |
public $facebook;
|
104 |
|
105 |
/**
|
106 |
* Home url in this language.
|
107 |
*
|
108 |
+
* @var string|null
|
109 |
*/
|
110 |
public $home_url;
|
111 |
|
112 |
/**
|
113 |
* Home url to use in search forms.
|
114 |
*
|
115 |
+
* @var string|null
|
116 |
*/
|
117 |
public $search_url;
|
118 |
|
119 |
/**
|
120 |
* Host corresponding to this language.
|
121 |
*
|
122 |
+
* @var string|null
|
123 |
*/
|
124 |
public $host;
|
125 |
|
133 |
/**
|
134 |
* Id of the page on front in this language ( set from pll_languages_list filter ).
|
135 |
*
|
136 |
+
* @var int|null
|
137 |
*/
|
138 |
public $page_on_front;
|
139 |
|
140 |
/**
|
141 |
* Id of the page for posts in this language ( set from pll_languages_list filter ).
|
142 |
*
|
143 |
+
* @var int|null
|
144 |
*/
|
145 |
public $page_for_posts;
|
146 |
|
154 |
/**
|
155 |
* Url of the flag.
|
156 |
*
|
157 |
+
* @var string|null
|
158 |
*/
|
159 |
public $flag_url;
|
160 |
|
161 |
/**
|
162 |
* Html markup of the flag.
|
163 |
*
|
164 |
+
* @var string|null
|
165 |
*/
|
166 |
public $flag;
|
167 |
|
168 |
/**
|
169 |
* Url of the custom flag if it exists.
|
170 |
*
|
171 |
+
* @var string|null
|
172 |
*/
|
173 |
public $custom_flag_url;
|
174 |
|
175 |
/**
|
176 |
* Html markup of the custom flag if it exists.
|
177 |
*
|
178 |
+
* @var string|null
|
179 |
*/
|
180 |
public $custom_flag;
|
181 |
|
460 |
* @return void
|
461 |
*/
|
462 |
public function set_url_scheme() {
|
463 |
+
if ( ! empty( $this->home_url ) ) {
|
464 |
+
$this->home_url = set_url_scheme( $this->home_url );
|
465 |
+
}
|
466 |
+
|
467 |
+
if ( ! empty( $this->search_url ) ) {
|
468 |
+
$this->search_url = set_url_scheme( $this->search_url );
|
469 |
+
}
|
470 |
|
471 |
// Set url scheme, also for the flags.
|
472 |
+
if ( ! empty( $this->flag_url ) ) {
|
473 |
+
$this->flag_url = set_url_scheme( $this->flag_url );
|
474 |
+
}
|
475 |
+
|
476 |
if ( ! empty( $this->custom_flag_url ) ) {
|
477 |
$this->custom_flag_url = set_url_scheme( $this->custom_flag_url );
|
478 |
}
|
include/license.php
CHANGED
@@ -33,7 +33,7 @@ class PLL_License {
|
|
33 |
/**
|
34 |
* License data, obtained from the API request.
|
35 |
*
|
36 |
-
* @var stdClass
|
37 |
*/
|
38 |
public $license_data;
|
39 |
|
33 |
/**
|
34 |
* License data, obtained from the API request.
|
35 |
*
|
36 |
+
* @var stdClass|null
|
37 |
*/
|
38 |
public $license_data;
|
39 |
|
include/links-abstract-domain.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model for use when using one domain or subdomain per language
|
8 |
*
|
9 |
* @since 2.0
|
10 |
*/
|
@@ -20,7 +20,7 @@ abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
|
20 |
public function __construct( &$model ) {
|
21 |
parent::__construct( $model );
|
22 |
|
23 |
-
// Avoid cross domain requests (
|
24 |
add_filter( 'content_url', array( $this, 'site_url' ) );
|
25 |
add_filter( 'theme_root_uri', array( $this, 'site_url' ) ); // The above filter is not sufficient with WPMU Domain Mapping.
|
26 |
add_filter( 'plugins_url', array( $this, 'site_url' ) );
|
@@ -29,14 +29,13 @@ abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
* Returns the language based on language code in url
|
33 |
-
* links_model interface
|
34 |
*
|
35 |
* @since 1.2
|
36 |
-
* @since 2.0
|
37 |
*
|
38 |
-
* @param string $url
|
39 |
-
* @return string
|
40 |
*/
|
41 |
public function get_language_from_url( $url = '' ) {
|
42 |
if ( empty( $url ) ) {
|
@@ -60,12 +59,12 @@ abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
|
60 |
}
|
61 |
|
62 |
/**
|
63 |
-
*
|
64 |
*
|
65 |
* @since 1.8
|
66 |
*
|
67 |
-
* @param string $url
|
68 |
-
* @return string
|
69 |
*/
|
70 |
public function site_url( $url ) {
|
71 |
$lang = $this->get_language_from_url();
|
@@ -74,11 +73,11 @@ abstract class PLL_Links_Abstract_Domain extends PLL_Links_Permalinks {
|
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
*
|
78 |
*
|
79 |
* @since 2.0.6
|
80 |
*
|
81 |
-
* @param array $uploads
|
82 |
* @return array
|
83 |
*/
|
84 |
public function upload_dir( $uploads ) {
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model for use when using one domain or subdomain per language.
|
8 |
*
|
9 |
* @since 2.0
|
10 |
*/
|
20 |
public function __construct( &$model ) {
|
21 |
parent::__construct( $model );
|
22 |
|
23 |
+
// Avoid cross domain requests (mainly for custom fonts).
|
24 |
add_filter( 'content_url', array( $this, 'site_url' ) );
|
25 |
add_filter( 'theme_root_uri', array( $this, 'site_url' ) ); // The above filter is not sufficient with WPMU Domain Mapping.
|
26 |
add_filter( 'plugins_url', array( $this, 'site_url' ) );
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
+
* Returns the language based on the language code in url.
|
|
|
33 |
*
|
34 |
* @since 1.2
|
35 |
+
* @since 2.0 Add the $url argument.
|
36 |
*
|
37 |
+
* @param string $url Optional, defaults to the current url.
|
38 |
+
* @return string Language slug.
|
39 |
*/
|
40 |
public function get_language_from_url( $url = '' ) {
|
41 |
if ( empty( $url ) ) {
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
+
* Modifies an url to use the domain associated to the current language.
|
63 |
*
|
64 |
* @since 1.8
|
65 |
*
|
66 |
+
* @param string $url The url to modify.
|
67 |
+
* @return string The modified url.
|
68 |
*/
|
69 |
public function site_url( $url ) {
|
70 |
$lang = $this->get_language_from_url();
|
73 |
}
|
74 |
|
75 |
/**
|
76 |
+
* Fixes the domain for the upload directory.
|
77 |
*
|
78 |
* @since 2.0.6
|
79 |
*
|
80 |
+
* @param array $uploads Array of information about the upload directory. @see wp_upload_dir().
|
81 |
* @return array
|
82 |
*/
|
83 |
public function upload_dir( $uploads ) {
|
include/links-default.php
CHANGED
@@ -4,9 +4,8 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model for default permalinks
|
8 |
-
* for example mysite.com/?somevar=something&lang=en
|
9 |
-
* implements the "links_model interface"
|
10 |
*
|
11 |
* @since 1.2
|
12 |
*/
|
@@ -20,66 +19,62 @@ class PLL_Links_Default extends PLL_Links_Model {
|
|
20 |
|
21 |
/**
|
22 |
* Adds the language code in a url.
|
23 |
-
* links_model interface.
|
24 |
*
|
25 |
* @since 1.2
|
26 |
*
|
27 |
-
* @param string
|
28 |
-
* @param PLL_Language $lang The language object.
|
29 |
-
* @return string
|
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 );
|
33 |
}
|
34 |
|
35 |
/**
|
36 |
-
* Removes the language information from an url
|
37 |
-
* links_model interface
|
38 |
*
|
39 |
* @since 1.2
|
40 |
*
|
41 |
-
* @param string $url url to modify
|
42 |
-
* @return string modified url
|
43 |
*/
|
44 |
public function remove_language_from_link( $url ) {
|
45 |
return remove_query_arg( 'lang', $url );
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
-
* Returns the link to the first page
|
50 |
-
* links_model interface
|
51 |
*
|
52 |
* @since 1.2
|
53 |
*
|
54 |
-
* @param string $url url to modify
|
55 |
-
* @return string modified url
|
56 |
*/
|
57 |
public function remove_paged_from_link( $url ) {
|
58 |
return remove_query_arg( 'paged', $url );
|
59 |
}
|
60 |
|
61 |
/**
|
62 |
-
* Returns the link to the paged page
|
63 |
*
|
64 |
* @since 1.5
|
65 |
*
|
66 |
-
* @param string $url url to modify
|
67 |
-
* @param int $page
|
68 |
-
* @return string modified url
|
69 |
*/
|
70 |
public function add_paged_to_link( $url, $page ) {
|
71 |
return add_query_arg( array( 'paged' => $page ), $url );
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
-
* Gets the language slug from the url if present
|
76 |
-
* links_model interface
|
77 |
*
|
78 |
* @since 1.2
|
79 |
-
* @since 2.0
|
80 |
*
|
81 |
-
* @param string $url
|
82 |
-
* @return string
|
83 |
*/
|
84 |
public function get_language_from_url( $url = '' ) {
|
85 |
if ( empty( $url ) ) {
|
@@ -91,7 +86,7 @@ class PLL_Links_Default extends PLL_Links_Model {
|
|
91 |
}
|
92 |
|
93 |
/**
|
94 |
-
* Returns the static front page url.
|
95 |
*
|
96 |
* @since 1.8
|
97 |
*
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model for the default permalinks
|
8 |
+
* for example mysite.com/?somevar=something&lang=en.
|
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
19 |
|
20 |
/**
|
21 |
* Adds the language code in a url.
|
|
|
22 |
*
|
23 |
* @since 1.2
|
24 |
*
|
25 |
+
* @param string $url The url to modify.
|
26 |
+
* @param PLL_Language|false $lang The language object.
|
27 |
+
* @return string The modified url.
|
28 |
*/
|
29 |
public function add_language_to_link( $url, $lang ) {
|
30 |
return empty( $lang ) || ( $this->options['hide_default'] && $this->options['default_lang'] == $lang->slug ) ? $url : add_query_arg( 'lang', $lang->slug, $url );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* Removes the language information from an url.
|
|
|
35 |
*
|
36 |
* @since 1.2
|
37 |
*
|
38 |
+
* @param string $url The url to modify.
|
39 |
+
* @return string The modified url.
|
40 |
*/
|
41 |
public function remove_language_from_link( $url ) {
|
42 |
return remove_query_arg( 'lang', $url );
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
+
* Returns the link to the first page.
|
|
|
47 |
*
|
48 |
* @since 1.2
|
49 |
*
|
50 |
+
* @param string $url The url to modify.
|
51 |
+
* @return string The modified url.
|
52 |
*/
|
53 |
public function remove_paged_from_link( $url ) {
|
54 |
return remove_query_arg( 'paged', $url );
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
+
* Returns the link to the paged page.
|
59 |
*
|
60 |
* @since 1.5
|
61 |
*
|
62 |
+
* @param string $url The url to modify.
|
63 |
+
* @param int $page The page number.
|
64 |
+
* @return string The modified url.
|
65 |
*/
|
66 |
public function add_paged_to_link( $url, $page ) {
|
67 |
return add_query_arg( array( 'paged' => $page ), $url );
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
+
* Gets the language slug from the url if present.
|
|
|
72 |
*
|
73 |
* @since 1.2
|
74 |
+
* @since 2.0 Add the $url argument.
|
75 |
*
|
76 |
+
* @param string $url Optional, defaults to the current url.
|
77 |
+
* @return string Language slug.
|
78 |
*/
|
79 |
public function get_language_from_url( $url = '' ) {
|
80 |
if ( empty( $url ) ) {
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
+
* Returns the static front page url in the given language.
|
90 |
*
|
91 |
* @since 1.8
|
92 |
*
|
include/links-directory.php
CHANGED
@@ -4,9 +4,8 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model for use when the language code is added in url as a directory
|
8 |
-
* for example mysite.com/en/something
|
9 |
-
* implements the "links_model interface"
|
10 |
*
|
11 |
* @since 1.2
|
12 |
*/
|
@@ -38,7 +37,7 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
-
* Called only at first object creation to avoid duplicating filters when switching blog
|
42 |
*
|
43 |
* @since 1.6
|
44 |
*
|
@@ -51,19 +50,18 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
51 |
add_action( 'setup_theme', array( $this, 'add_permastruct' ), 2 );
|
52 |
}
|
53 |
|
54 |
-
// Make sure to prepare rewrite rules when flushing
|
55 |
add_action( 'pre_option_rewrite_rules', array( $this, 'prepare_rewrite_rules' ) );
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
* Adds the language code in a url.
|
60 |
-
* links_model interface.
|
61 |
*
|
62 |
* @since 1.2
|
63 |
*
|
64 |
-
* @param string
|
65 |
-
* @param PLL_Language $lang The language object.
|
66 |
-
* @return string
|
67 |
*/
|
68 |
public function add_language_to_link( $url, $lang ) {
|
69 |
if ( ! empty( $lang ) ) {
|
@@ -74,20 +72,19 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
74 |
if ( false === strpos( $url, $new = $root . $slug ) ) {
|
75 |
$pattern = preg_quote( $root, '#' );
|
76 |
$pattern = '#' . $pattern . '#';
|
77 |
-
return preg_replace( $pattern, $new, $url, 1 ); // Only once
|
78 |
}
|
79 |
}
|
80 |
return $url;
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
* Returns the url without language code
|
85 |
-
* links_model interface
|
86 |
*
|
87 |
* @since 1.2
|
88 |
*
|
89 |
-
* @param string $url url to modify
|
90 |
-
* @return string modified url
|
91 |
*/
|
92 |
public function remove_language_from_link( $url ) {
|
93 |
$languages = array();
|
@@ -101,22 +98,21 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
101 |
if ( ! empty( $languages ) ) {
|
102 |
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '#^https?://#', '://', $this->home . '/' . $this->root );
|
103 |
|
104 |
-
$pattern = preg_quote( $root, '
|
105 |
-
$pattern = '
|
106 |
-
$url = preg_replace( $pattern, $root, $url );
|
107 |
}
|
108 |
return $url;
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
-
* Returns the language based on language code in url
|
113 |
-
* links_model interface
|
114 |
*
|
115 |
* @since 1.2
|
116 |
-
* @since 2.0
|
117 |
*
|
118 |
-
* @param string $url
|
119 |
-
* @return string language slug
|
120 |
*/
|
121 |
public function get_language_from_url( $url = '' ) {
|
122 |
if ( empty( $url ) ) {
|
@@ -129,16 +125,15 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
129 |
$pattern = (string) wp_parse_url( $root . ( $this->options['rewrite'] ? '' : 'language/' ), PHP_URL_PATH );
|
130 |
$pattern = preg_quote( $pattern, '#' );
|
131 |
$pattern = '#^' . $pattern . '(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(/|$)#';
|
132 |
-
return preg_match( $pattern, trailingslashit( $path ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
|
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
|
142 |
* @return string
|
143 |
*/
|
144 |
public function home_url( $lang ) {
|
@@ -148,16 +143,14 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
148 |
}
|
149 |
|
150 |
/**
|
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 )
|
159 |
-
// The 3rd parameter structure has been modified in WP 3.4
|
160 |
-
// Leads to error 404 for pages when there is no language created yet
|
161 |
if ( $this->model->get_languages_list() ) {
|
162 |
add_permastruct( 'language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array( 'with_front' => false ) );
|
163 |
}
|
@@ -172,23 +165,26 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
172 |
* @return mixed
|
173 |
*/
|
174 |
public function prepare_rewrite_rules( $pre ) {
|
175 |
-
|
176 |
-
|
|
|
|
|
|
|
177 |
if ( $this->model->get_languages_list() && did_action( 'wp_loaded' ) && ! has_filter( 'language_rewrite_rules', '__return_empty_array' ) ) {
|
178 |
-
// Suppress the rules created by WordPress for our taxonomy
|
179 |
-
add_filter( 'language_rewrite_rules', '__return_empty_array' );
|
180 |
|
181 |
foreach ( $this->get_rewrite_rules_filters() as $type ) {
|
182 |
add_filter( $type . '_rewrite_rules', array( $this, 'rewrite_rules' ) );
|
183 |
}
|
184 |
|
185 |
-
add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) ); //
|
186 |
}
|
187 |
return $pre;
|
188 |
}
|
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 |
*
|
@@ -212,23 +208,23 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
212 |
$slug = $wp_rewrite->root . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')/';
|
213 |
}
|
214 |
|
215 |
-
// For custom post type archives
|
216 |
$cpts = array_intersect( $this->model->get_translated_post_types(), get_post_types( array( '_builtin' => false ) ) );
|
217 |
$cpts = $cpts ? '#post_type=(' . implode( '|', $cpts ) . ')#' : '';
|
218 |
|
219 |
foreach ( $rules as $key => $rule ) {
|
220 |
-
// Special case for translated post types and taxonomies to allow canonical redirection
|
221 |
if ( $this->options['force_lang'] && in_array( $filter, array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies() ) ) ) {
|
222 |
|
223 |
/**
|
224 |
-
* Filters the rewrite rules to modify
|
225 |
*
|
226 |
* @since 1.9.1
|
227 |
*
|
228 |
-
* @param bool $modify
|
229 |
-
* @param array $rule
|
230 |
-
* @param string $filter
|
231 |
-
* @param string|bool $archive
|
232 |
*/
|
233 |
if ( isset( $slug ) && apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, false ) ) {
|
234 |
$newrules[ $slug . str_replace( $wp_rewrite->root, '', ltrim( $key, '^' ) ) ] = str_replace(
|
@@ -241,7 +237,7 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
241 |
$newrules[ $key ] = $rule;
|
242 |
}
|
243 |
|
244 |
-
// Rewrite rules filtered by language
|
245 |
elseif ( in_array( $filter, $this->always_rewrite ) || in_array( $filter, $this->model->get_filtered_taxonomies() ) || ( $cpts && preg_match( $cpts, $rule, $matches ) && ! strpos( $rule, 'name=' ) ) || ( 'rewrite_rules_array' != $filter && $this->options['force_lang'] ) ) {
|
246 |
|
247 |
/** This filter is documented in include/links-directory.php */
|
@@ -262,13 +258,13 @@ class PLL_Links_Directory extends PLL_Links_Permalinks {
|
|
262 |
}
|
263 |
}
|
264 |
|
265 |
-
// Unmodified rules
|
266 |
else {
|
267 |
$newrules[ $key ] = $rule;
|
268 |
}
|
269 |
}
|
270 |
|
271 |
-
// The home rewrite rule
|
272 |
if ( 'root' == $filter && isset( $slug ) ) {
|
273 |
$newrules[ $slug . '?$' ] = $wp_rewrite->index . '?lang=$matches[1]';
|
274 |
}
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model for use when the language code is added in the url as a directory
|
8 |
+
* for example mysite.com/en/something.
|
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
+
* Called only at first object creation to avoid duplicating filters when switching blog.
|
41 |
*
|
42 |
* @since 1.6
|
43 |
*
|
50 |
add_action( 'setup_theme', array( $this, 'add_permastruct' ), 2 );
|
51 |
}
|
52 |
|
53 |
+
// Make sure to prepare rewrite rules when flushing.
|
54 |
add_action( 'pre_option_rewrite_rules', array( $this, 'prepare_rewrite_rules' ) );
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
* Adds the language code in a url.
|
|
|
59 |
*
|
60 |
* @since 1.2
|
61 |
*
|
62 |
+
* @param string $url The url to modify.
|
63 |
+
* @param PLL_Language|false $lang The language object.
|
64 |
+
* @return string The modified url.
|
65 |
*/
|
66 |
public function add_language_to_link( $url, $lang ) {
|
67 |
if ( ! empty( $lang ) ) {
|
72 |
if ( false === strpos( $url, $new = $root . $slug ) ) {
|
73 |
$pattern = preg_quote( $root, '#' );
|
74 |
$pattern = '#' . $pattern . '#';
|
75 |
+
return preg_replace( $pattern, $new, $url, 1 ); // Only once.
|
76 |
}
|
77 |
}
|
78 |
return $url;
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* Returns the url without the language code.
|
|
|
83 |
*
|
84 |
* @since 1.2
|
85 |
*
|
86 |
+
* @param string $url The url to modify.
|
87 |
+
* @return string The modified url.
|
88 |
*/
|
89 |
public function remove_language_from_link( $url ) {
|
90 |
$languages = array();
|
98 |
if ( ! empty( $languages ) ) {
|
99 |
$root = ( false === strpos( $url, '://' ) ) ? $this->home_relative . $this->root : preg_replace( '#^https?://#', '://', $this->home . '/' . $this->root );
|
100 |
|
101 |
+
$pattern = preg_quote( $root, '@' );
|
102 |
+
$pattern = '@' . $pattern . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')(([?#])|(/|$))@';
|
103 |
+
$url = preg_replace( $pattern, $root . '$3', $url );
|
104 |
}
|
105 |
return $url;
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
+
* Returns the language based on the language code in the url.
|
|
|
110 |
*
|
111 |
* @since 1.2
|
112 |
+
* @since 2.0 Add the $url argument.
|
113 |
*
|
114 |
+
* @param string $url Optional, defaults to the current url.
|
115 |
+
* @return string The language slug.
|
116 |
*/
|
117 |
public function get_language_from_url( $url = '' ) {
|
118 |
if ( empty( $url ) ) {
|
125 |
$pattern = (string) wp_parse_url( $root . ( $this->options['rewrite'] ? '' : 'language/' ), PHP_URL_PATH );
|
126 |
$pattern = preg_quote( $pattern, '#' );
|
127 |
$pattern = '#^' . $pattern . '(' . implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(/|$)#';
|
128 |
+
return preg_match( $pattern, trailingslashit( $path ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language.
|
129 |
}
|
130 |
|
131 |
/**
|
132 |
* Returns the home url in a given language.
|
|
|
133 |
*
|
134 |
* @since 1.3.1
|
135 |
*
|
136 |
+
* @param PLL_Language $lang The language object.
|
137 |
* @return string
|
138 |
*/
|
139 |
public function home_url( $lang ) {
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
+
* Optionally removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/.
|
147 |
*
|
148 |
* @since 1.2
|
149 |
*
|
150 |
* @return void
|
151 |
*/
|
152 |
public function add_permastruct() {
|
153 |
+
// Language information always in front of the uri ( 'with_front' => false ).
|
|
|
|
|
154 |
if ( $this->model->get_languages_list() ) {
|
155 |
add_permastruct( 'language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array( 'with_front' => false ) );
|
156 |
}
|
165 |
* @return mixed
|
166 |
*/
|
167 |
public function prepare_rewrite_rules( $pre ) {
|
168 |
+
/*
|
169 |
+
* Don't modify the rules if there is no languages created yet and make sure
|
170 |
+
* to add the filters only once and if all custom post types and taxonomies
|
171 |
+
* have been registered.
|
172 |
+
*/
|
173 |
if ( $this->model->get_languages_list() && did_action( 'wp_loaded' ) && ! has_filter( 'language_rewrite_rules', '__return_empty_array' ) ) {
|
174 |
+
add_filter( 'language_rewrite_rules', '__return_empty_array' ); // Suppress the rules created by WordPress for our taxonomy.
|
|
|
175 |
|
176 |
foreach ( $this->get_rewrite_rules_filters() as $type ) {
|
177 |
add_filter( $type . '_rewrite_rules', array( $this, 'rewrite_rules' ) );
|
178 |
}
|
179 |
|
180 |
+
add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) ); // Needed for post type archives.
|
181 |
}
|
182 |
return $pre;
|
183 |
}
|
184 |
|
185 |
/**
|
186 |
* The rewrite rules !
|
187 |
+
*
|
188 |
* Always make sure that the default language is at the end in case the language information is hidden for default language.
|
189 |
* Thanks to brbrbr http://wordpress.org/support/topic/plugin-polylang-rewrite-rules-not-correct.
|
190 |
*
|
208 |
$slug = $wp_rewrite->root . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')/';
|
209 |
}
|
210 |
|
211 |
+
// For custom post type archives.
|
212 |
$cpts = array_intersect( $this->model->get_translated_post_types(), get_post_types( array( '_builtin' => false ) ) );
|
213 |
$cpts = $cpts ? '#post_type=(' . implode( '|', $cpts ) . ')#' : '';
|
214 |
|
215 |
foreach ( $rules as $key => $rule ) {
|
216 |
+
// Special case for translated post types and taxonomies to allow canonical redirection.
|
217 |
if ( $this->options['force_lang'] && in_array( $filter, array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies() ) ) ) {
|
218 |
|
219 |
/**
|
220 |
+
* Filters the rewrite rules to modify.
|
221 |
*
|
222 |
* @since 1.9.1
|
223 |
*
|
224 |
+
* @param bool $modify Whether to modify or not the rule, defaults to true.
|
225 |
+
* @param array $rule Original rewrite rule.
|
226 |
+
* @param string $filter Current set of rules being modified.
|
227 |
+
* @param string|bool $archive Custom post post type archive name or false if it is not a cpt archive.
|
228 |
*/
|
229 |
if ( isset( $slug ) && apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, false ) ) {
|
230 |
$newrules[ $slug . str_replace( $wp_rewrite->root, '', ltrim( $key, '^' ) ) ] = str_replace(
|
237 |
$newrules[ $key ] = $rule;
|
238 |
}
|
239 |
|
240 |
+
// Rewrite rules filtered by language.
|
241 |
elseif ( in_array( $filter, $this->always_rewrite ) || in_array( $filter, $this->model->get_filtered_taxonomies() ) || ( $cpts && preg_match( $cpts, $rule, $matches ) && ! strpos( $rule, 'name=' ) ) || ( 'rewrite_rules_array' != $filter && $this->options['force_lang'] ) ) {
|
242 |
|
243 |
/** This filter is documented in include/links-directory.php */
|
258 |
}
|
259 |
}
|
260 |
|
261 |
+
// Unmodified rules.
|
262 |
else {
|
263 |
$newrules[ $key ] = $rule;
|
264 |
}
|
265 |
}
|
266 |
|
267 |
+
// The home rewrite rule.
|
268 |
if ( 'root' == $filter && isset( $slug ) ) {
|
269 |
$newrules[ $slug . '?$' ] = $wp_rewrite->index . '?lang=$matches[1]';
|
270 |
}
|
include/links-domain.php
CHANGED
@@ -5,8 +5,7 @@
|
|
5 |
|
6 |
/**
|
7 |
* Links model for use when using one domain per language
|
8 |
-
* for example mysite.com/
|
9 |
-
* implements the "links_model interface"
|
10 |
*
|
11 |
* @since 1.2
|
12 |
*/
|
@@ -20,31 +19,30 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
20 |
protected $hosts;
|
21 |
|
22 |
/**
|
23 |
-
* Constructor
|
24 |
*
|
25 |
* @since 1.8
|
26 |
*
|
27 |
-
* @param object $model PLL_Model instance
|
28 |
*/
|
29 |
public function __construct( &$model ) {
|
30 |
parent::__construct( $model );
|
31 |
|
32 |
$this->hosts = $this->get_hosts();
|
33 |
|
34 |
-
//
|
35 |
add_filter( 'site_url', array( $this, 'site_url' ) );
|
36 |
}
|
37 |
|
38 |
|
39 |
/**
|
40 |
-
*
|
41 |
-
* links_model interface
|
42 |
*
|
43 |
* @since 1.2
|
44 |
*
|
45 |
-
* @param string
|
46 |
-
* @param PLL_Language $lang The language object.
|
47 |
-
* @return string
|
48 |
*/
|
49 |
public function add_language_to_link( $url, $lang ) {
|
50 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
@@ -54,13 +52,12 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
-
* Returns the url
|
58 |
-
* links_model interface
|
59 |
*
|
60 |
* @since 1.2
|
61 |
*
|
62 |
-
* @param string $url url to modify
|
63 |
-
* @return string modified url
|
64 |
*/
|
65 |
public function remove_language_from_link( $url ) {
|
66 |
if ( ! empty( $this->hosts ) ) {
|
@@ -71,11 +68,10 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
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
|
79 |
* @return string
|
80 |
*/
|
81 |
public function home_url( $lang ) {
|
@@ -83,7 +79,7 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
-
* Get hosts managed on the website.
|
87 |
*
|
88 |
* @since 1.5
|
89 |
*
|
@@ -93,7 +89,7 @@ class PLL_Links_Domain extends PLL_Links_Abstract_Domain {
|
|
93 |
$hosts = array();
|
94 |
foreach ( $this->options['domains'] as $lang => $domain ) {
|
95 |
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
96 |
-
// idn_to_ascii is much faster than the WordPress method.
|
97 |
if ( function_exists( 'idn_to_ascii' ) ) {
|
98 |
// The use of the constant is mandatory in PHP 7.2 and PHP 7.3 to avoid a deprecated notice.
|
99 |
$hosts[ $lang ] = defined( 'INTL_IDNA_VARIANT_UTS46' ) ? idn_to_ascii( $host, 0, INTL_IDNA_VARIANT_UTS46 ) : idn_to_ascii( $host );
|
5 |
|
6 |
/**
|
7 |
* Links model for use when using one domain per language
|
8 |
+
* for example mysite.com/something and mysite.fr/quelquechose.
|
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
19 |
protected $hosts;
|
20 |
|
21 |
/**
|
22 |
+
* Constructor.
|
23 |
*
|
24 |
* @since 1.8
|
25 |
*
|
26 |
+
* @param object $model PLL_Model instance.
|
27 |
*/
|
28 |
public function __construct( &$model ) {
|
29 |
parent::__construct( $model );
|
30 |
|
31 |
$this->hosts = $this->get_hosts();
|
32 |
|
33 |
+
// Filters the site url (mainly to get the correct login form).
|
34 |
add_filter( 'site_url', array( $this, 'site_url' ) );
|
35 |
}
|
36 |
|
37 |
|
38 |
/**
|
39 |
+
* Switches the primary domain to a secondary domain in the url.
|
|
|
40 |
*
|
41 |
* @since 1.2
|
42 |
*
|
43 |
+
* @param string $url The url to modify.
|
44 |
+
* @param PLL_Language|false $lang The language object.
|
45 |
+
* @return string The modified url.
|
46 |
*/
|
47 |
public function add_language_to_link( $url, $lang ) {
|
48 |
if ( ! empty( $lang ) && ! empty( $this->hosts[ $lang->slug ] ) ) {
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
+
* Returns the url with the primary domain.
|
|
|
56 |
*
|
57 |
* @since 1.2
|
58 |
*
|
59 |
+
* @param string $url The url to modify.
|
60 |
+
* @return string The modified url.
|
61 |
*/
|
62 |
public function remove_language_from_link( $url ) {
|
63 |
if ( ! empty( $this->hosts ) ) {
|
68 |
|
69 |
/**
|
70 |
* Returns the home url in a given language.
|
|
|
71 |
*
|
72 |
* @since 1.3.1
|
73 |
*
|
74 |
+
* @param PLL_Language $lang The language object.
|
75 |
* @return string
|
76 |
*/
|
77 |
public function home_url( $lang ) {
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* Get the hosts managed on the website.
|
83 |
*
|
84 |
* @since 1.5
|
85 |
*
|
89 |
$hosts = array();
|
90 |
foreach ( $this->options['domains'] as $lang => $domain ) {
|
91 |
$host = wp_parse_url( $domain, PHP_URL_HOST );
|
92 |
+
// The function idn_to_ascii() is much faster than the WordPress method.
|
93 |
if ( function_exists( 'idn_to_ascii' ) ) {
|
94 |
// The use of the constant is mandatory in PHP 7.2 and PHP 7.3 to avoid a deprecated notice.
|
95 |
$hosts[ $lang ] = defined( 'INTL_IDNA_VARIANT_UTS46' ) ? idn_to_ascii( $host, 0, INTL_IDNA_VARIANT_UTS46 ) : idn_to_ascii( $host );
|
include/links-model.php
CHANGED
@@ -60,9 +60,9 @@ abstract class PLL_Links_Model {
|
|
60 |
*
|
61 |
* @since 1.2
|
62 |
*
|
63 |
-
* @param string
|
64 |
-
* @param PLL_Language $lang The language object.
|
65 |
-
* @return string
|
66 |
*/
|
67 |
abstract public function add_language_to_link( $url, $lang );
|
68 |
|
@@ -72,7 +72,7 @@ abstract class PLL_Links_Model {
|
|
72 |
* @since 1.2
|
73 |
*
|
74 |
* @param string $url The url to modify.
|
75 |
-
* @return string
|
76 |
*/
|
77 |
abstract public function remove_language_from_link( $url );
|
78 |
|
@@ -82,7 +82,7 @@ abstract class PLL_Links_Model {
|
|
82 |
* @since 1.2
|
83 |
*
|
84 |
* @param string $url The url to modify.
|
85 |
-
* @return string
|
86 |
*/
|
87 |
abstract public function remove_paged_from_link( $url );
|
88 |
|
@@ -93,23 +93,23 @@ abstract class PLL_Links_Model {
|
|
93 |
*
|
94 |
* @param string $url The url to modify.
|
95 |
* @param int $page The page number.
|
96 |
-
* @return string
|
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
|
105 |
*
|
106 |
-
* @param string $url Optional, defaults to
|
107 |
-
* @return string
|
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 |
*
|
@@ -125,7 +125,7 @@ abstract class PLL_Links_Model {
|
|
125 |
*
|
126 |
* @param string $url The url to modify.
|
127 |
* @param PLL_Language $lang The language object.
|
128 |
-
* @return string
|
129 |
*/
|
130 |
public function switch_language_in_link( $url, $lang ) {
|
131 |
$url = $this->remove_language_from_link( $url );
|
@@ -133,7 +133,7 @@ abstract class PLL_Links_Model {
|
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
-
* Get hosts managed on the website.
|
137 |
*
|
138 |
* @since 1.5
|
139 |
*
|
@@ -148,7 +148,7 @@ abstract class PLL_Links_Model {
|
|
148 |
*
|
149 |
* @since 1.3.1
|
150 |
*
|
151 |
-
* @param PLL_Language $lang
|
152 |
* @return string
|
153 |
*/
|
154 |
public function home_url( $lang ) {
|
@@ -161,16 +161,13 @@ abstract class PLL_Links_Model {
|
|
161 |
*
|
162 |
* @since 1.8
|
163 |
*
|
164 |
-
* @param PLL_Language $language
|
165 |
* @return void
|
166 |
*/
|
167 |
protected function set_home_url( $language ) {
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
$home_url = empty( $language->page_on_front ) || $this->options['redirect_lang'] ? $search_url : $this->front_page_url( $language );
|
172 |
-
$language->set_home_url( $search_url, $home_url );
|
173 |
-
}
|
174 |
}
|
175 |
|
176 |
/**
|
@@ -205,7 +202,7 @@ abstract class PLL_Links_Model {
|
|
205 |
$this->set_home_url( $language );
|
206 |
}
|
207 |
|
208 |
-
// Ensures that the (
|
209 |
$language->set_url_scheme();
|
210 |
}
|
211 |
return $languages;
|
60 |
*
|
61 |
* @since 1.2
|
62 |
*
|
63 |
+
* @param string $url The url to modify.
|
64 |
+
* @param PLL_Language|false $lang The language object.
|
65 |
+
* @return string The modified url.
|
66 |
*/
|
67 |
abstract public function add_language_to_link( $url, $lang );
|
68 |
|
72 |
* @since 1.2
|
73 |
*
|
74 |
* @param string $url The url to modify.
|
75 |
+
* @return string The modified url.
|
76 |
*/
|
77 |
abstract public function remove_language_from_link( $url );
|
78 |
|
82 |
* @since 1.2
|
83 |
*
|
84 |
* @param string $url The url to modify.
|
85 |
+
* @return string The modified url.
|
86 |
*/
|
87 |
abstract public function remove_paged_from_link( $url );
|
88 |
|
93 |
*
|
94 |
* @param string $url The url to modify.
|
95 |
* @param int $page The page number.
|
96 |
+
* @return string The modified url.
|
97 |
*/
|
98 |
abstract public function add_paged_to_link( $url, $page );
|
99 |
|
100 |
/**
|
101 |
+
* Returns the language based on the language code in the url.
|
102 |
*
|
103 |
* @since 1.2
|
104 |
+
* @since 2.0 Add the $url argument.
|
105 |
*
|
106 |
+
* @param string $url Optional, defaults to the current url.
|
107 |
+
* @return string The language slug.
|
108 |
*/
|
109 |
abstract public function get_language_from_url( $url = '' );
|
110 |
|
111 |
/**
|
112 |
+
* Returns the static front page url in a given language.
|
113 |
*
|
114 |
* @since 1.8
|
115 |
*
|
125 |
*
|
126 |
* @param string $url The url to modify.
|
127 |
* @param PLL_Language $lang The language object.
|
128 |
+
* @return string The 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 the hosts managed on the website.
|
137 |
*
|
138 |
* @since 1.5
|
139 |
*
|
148 |
*
|
149 |
* @since 1.3.1
|
150 |
*
|
151 |
+
* @param PLL_Language $lang The language object.
|
152 |
* @return string
|
153 |
*/
|
154 |
public function home_url( $lang ) {
|
161 |
*
|
162 |
* @since 1.8
|
163 |
*
|
164 |
+
* @param PLL_Language $language The language object.
|
165 |
* @return void
|
166 |
*/
|
167 |
protected function set_home_url( $language ) {
|
168 |
+
$search_url = $this->home_url( $language );
|
169 |
+
$home_url = empty( $language->page_on_front ) || $this->options['redirect_lang'] ? $search_url : $this->front_page_url( $language );
|
170 |
+
$language->set_home_url( $search_url, $home_url );
|
|
|
|
|
|
|
171 |
}
|
172 |
|
173 |
/**
|
202 |
$this->set_home_url( $language );
|
203 |
}
|
204 |
|
205 |
+
// Ensures that the (possibly cached) home and flag urls use the right scheme http or https.
|
206 |
$language->set_url_scheme();
|
207 |
}
|
208 |
return $languages;
|
include/links-permalinks.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model base class when using pretty permalinks
|
8 |
*
|
9 |
* @since 1.6
|
10 |
*/
|
@@ -56,60 +56,60 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
56 |
public function __construct( &$model ) {
|
57 |
parent::__construct( $model );
|
58 |
|
59 |
-
// Inspired by
|
60 |
$permalink_structure = get_option( 'permalink_structure' );
|
61 |
$this->root = preg_match( '#^/*' . $this->index . '#', $permalink_structure ) ? $this->index . '/' : '';
|
62 |
$this->use_trailing_slashes = ( '/' == substr( $permalink_structure, -1, 1 ) );
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
* Returns the link to the first page when using pretty permalinks
|
67 |
*
|
68 |
* @since 1.2
|
69 |
*
|
70 |
-
* @param string $url url to modify
|
71 |
-
* @return string modified url
|
72 |
*/
|
73 |
public function remove_paged_from_link( $url ) {
|
74 |
/**
|
75 |
-
*
|
76 |
*
|
77 |
* @since 2.0.6
|
78 |
*
|
79 |
-
* @param string $modified_url The link to the first page
|
80 |
-
* @param string $original_url
|
81 |
*/
|
82 |
return apply_filters( 'pll_remove_paged_from_link', preg_replace( '#/page/[0-9]+/?#', $this->use_trailing_slashes ? '/' : '', $url ), $url );
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
-
* Returns the link to the paged page when using pretty permalinks
|
87 |
*
|
88 |
* @since 1.5
|
89 |
*
|
90 |
-
* @param string $url url to modify
|
91 |
-
* @param int $page
|
92 |
-
* @return string modified url
|
93 |
*/
|
94 |
public function add_paged_to_link( $url, $page ) {
|
95 |
/**
|
96 |
-
*
|
97 |
*
|
98 |
* @since 2.0.6
|
99 |
*
|
100 |
-
* @param string $modified_url The link to the paged page
|
101 |
-
* @param string $original_url
|
102 |
-
* @param int $page The page number
|
103 |
*/
|
104 |
return apply_filters( 'pll_add_paged_to_link', user_trailingslashit( trailingslashit( $url ) . 'page/' . $page, 'paged' ), $url, $page );
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* Returns the home url.
|
109 |
*
|
110 |
* @since 1.3.1
|
111 |
*
|
112 |
-
* @param PLL_Language $lang
|
113 |
* @return string
|
114 |
*/
|
115 |
public function home_url( $lang ) {
|
@@ -134,23 +134,23 @@ abstract class PLL_Links_Permalinks extends PLL_Links_Model {
|
|
134 |
}
|
135 |
|
136 |
/**
|
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
|
145 |
$types = array_values( array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies(), $this->model->get_filtered_taxonomies() ) );
|
146 |
$types = array_merge( $this->always_rewrite, $types );
|
147 |
|
148 |
/**
|
149 |
-
*
|
150 |
*
|
151 |
* @since 0.8.1
|
152 |
*
|
153 |
-
* @param array $types
|
154 |
*/
|
155 |
return apply_filters( 'pll_rewrite_rules', $types );
|
156 |
}
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model base class when using pretty permalinks.
|
8 |
*
|
9 |
* @since 1.6
|
10 |
*/
|
56 |
public function __construct( &$model ) {
|
57 |
parent::__construct( $model );
|
58 |
|
59 |
+
// Inspired by WP_Rewrite.
|
60 |
$permalink_structure = get_option( 'permalink_structure' );
|
61 |
$this->root = preg_match( '#^/*' . $this->index . '#', $permalink_structure ) ? $this->index . '/' : '';
|
62 |
$this->use_trailing_slashes = ( '/' == substr( $permalink_structure, -1, 1 ) );
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
+
* Returns the link to the first page when using pretty permalinks.
|
67 |
*
|
68 |
* @since 1.2
|
69 |
*
|
70 |
+
* @param string $url The url to modify.
|
71 |
+
* @return string The modified url.
|
72 |
*/
|
73 |
public function remove_paged_from_link( $url ) {
|
74 |
/**
|
75 |
+
* Filters an url after the paged part has been removed.
|
76 |
*
|
77 |
* @since 2.0.6
|
78 |
*
|
79 |
+
* @param string $modified_url The link to the first page.
|
80 |
+
* @param string $original_url The link to the original paged page.
|
81 |
*/
|
82 |
return apply_filters( 'pll_remove_paged_from_link', preg_replace( '#/page/[0-9]+/?#', $this->use_trailing_slashes ? '/' : '', $url ), $url );
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
+
* Returns the link to the paged page when using pretty permalinks.
|
87 |
*
|
88 |
* @since 1.5
|
89 |
*
|
90 |
+
* @param string $url The url to modify.
|
91 |
+
* @param int $page The page number.
|
92 |
+
* @return string The modified url.
|
93 |
*/
|
94 |
public function add_paged_to_link( $url, $page ) {
|
95 |
/**
|
96 |
+
* Filters an url after the paged part has been added.
|
97 |
*
|
98 |
* @since 2.0.6
|
99 |
*
|
100 |
+
* @param string $modified_url The link to the paged page.
|
101 |
+
* @param string $original_url The link to the original first page.
|
102 |
+
* @param int $page The page number.
|
103 |
*/
|
104 |
return apply_filters( 'pll_add_paged_to_link', user_trailingslashit( trailingslashit( $url ) . 'page/' . $page, 'paged' ), $url, $page );
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* Returns the home url in a given language.
|
109 |
*
|
110 |
* @since 1.3.1
|
111 |
*
|
112 |
+
* @param PLL_Language $lang A language object.
|
113 |
* @return string
|
114 |
*/
|
115 |
public function home_url( $lang ) {
|
134 |
}
|
135 |
|
136 |
/**
|
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 that we have the right post types and taxonomies.
|
145 |
$types = array_values( array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies(), $this->model->get_filtered_taxonomies() ) );
|
146 |
$types = array_merge( $this->always_rewrite, $types );
|
147 |
|
148 |
/**
|
149 |
+
* Filters the list of rewrite rules filters to be used by Polylang.
|
150 |
*
|
151 |
* @since 0.8.1
|
152 |
*
|
153 |
+
* @param array $types The list of filters (without '_rewrite_rules' at the end).
|
154 |
*/
|
155 |
return apply_filters( 'pll_rewrite_rules', $types );
|
156 |
}
|
include/links-subdomain.php
CHANGED
@@ -4,9 +4,8 @@
|
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
-
* Links model for use when the language code is added in url as a subdomain
|
8 |
-
* for example en.mysite.com/something
|
9 |
-
* implements the "links_model interface"
|
10 |
*
|
11 |
* @since 1.2
|
12 |
*/
|
@@ -33,13 +32,12 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
33 |
|
34 |
/**
|
35 |
* Adds the language code in a url.
|
36 |
-
* links_model interface.
|
37 |
*
|
38 |
* @since 1.2
|
39 |
*
|
40 |
-
* @param string
|
41 |
-
* @param PLL_Language $lang The language object.
|
42 |
-
* @return string
|
43 |
*/
|
44 |
public function add_language_to_link( $url, $lang ) {
|
45 |
if ( ! empty( $lang ) && false === strpos( $url, '://' . $lang->slug . '.' ) ) {
|
@@ -49,13 +47,12 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
-
* Returns the url without language code
|
53 |
-
* links_model interface
|
54 |
*
|
55 |
* @since 1.2
|
56 |
*
|
57 |
-
* @param string $url url to modify
|
58 |
-
* @return string modified url
|
59 |
*/
|
60 |
public function remove_language_from_link( $url ) {
|
61 |
$languages = array();
|
@@ -74,7 +71,7 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
* Get hosts managed on the website.
|
78 |
*
|
79 |
* @since 1.5
|
80 |
*
|
@@ -83,7 +80,8 @@ class PLL_Links_Subdomain extends PLL_Links_Abstract_Domain {
|
|
83 |
public function get_hosts() {
|
84 |
$hosts = array();
|
85 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
86 |
-
$
|
|
|
87 |
}
|
88 |
return $hosts;
|
89 |
}
|
4 |
*/
|
5 |
|
6 |
/**
|
7 |
+
* Links model for use when the language code is added in the url as a subdomain
|
8 |
+
* for example en.mysite.com/something.
|
|
|
9 |
*
|
10 |
* @since 1.2
|
11 |
*/
|
32 |
|
33 |
/**
|
34 |
* Adds the language code in a url.
|
|
|
35 |
*
|
36 |
* @since 1.2
|
37 |
*
|
38 |
+
* @param string $url The url to modify.
|
39 |
+
* @param PLL_Language|false $lang The language object.
|
40 |
+
* @return string The modified url.
|
41 |
*/
|
42 |
public function add_language_to_link( $url, $lang ) {
|
43 |
if ( ! empty( $lang ) && false === strpos( $url, '://' . $lang->slug . '.' ) ) {
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
+
* Returns the url without the language code.
|
|
|
51 |
*
|
52 |
* @since 1.2
|
53 |
*
|
54 |
+
* @param string $url The url to modify.
|
55 |
+
* @return string The modified url.
|
56 |
*/
|
57 |
public function remove_language_from_link( $url ) {
|
58 |
$languages = array();
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* Get the hosts managed on the website.
|
75 |
*
|
76 |
* @since 1.5
|
77 |
*
|
80 |
public function get_hosts() {
|
81 |
$hosts = array();
|
82 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
83 |
+
$host = wp_parse_url( $this->home_url( $lang ), PHP_URL_HOST );
|
84 |
+
$hosts[ $lang->slug ] = $host ? $host : '';
|
85 |
}
|
86 |
return $hosts;
|
87 |
}
|
include/links.php
CHANGED
@@ -28,6 +28,13 @@ class PLL_Links {
|
|
28 |
*/
|
29 |
public $links_model;
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
/**
|
32 |
* Constructor
|
33 |
*
|
28 |
*/
|
29 |
public $links_model;
|
30 |
|
31 |
+
/**
|
32 |
+
* Current language (used to filter the content).
|
33 |
+
*
|
34 |
+
* @var PLL_Language|null
|
35 |
+
*/
|
36 |
+
public $curlang;
|
37 |
+
|
38 |
/**
|
39 |
* Constructor
|
40 |
*
|
include/model.php
CHANGED
@@ -65,6 +65,25 @@ class PLL_Model {
|
|
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.
|
@@ -88,7 +107,7 @@ class PLL_Model {
|
|
88 |
|
89 |
$post_languages = $this->get_language_terms();
|
90 |
|
91 |
-
$term_languages = get_terms( 'term_language',
|
92 |
$term_languages = empty( $term_languages ) || is_wp_error( $term_languages ) ?
|
93 |
array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
|
94 |
|
@@ -216,9 +235,9 @@ class PLL_Model {
|
|
216 |
*
|
217 |
* @since 1.2
|
218 |
*
|
219 |
-
* @param string[]
|
220 |
-
* @param PLL_Language $lang PLL_Language object.
|
221 |
-
* @return string[]
|
222 |
*/
|
223 |
public function terms_clauses( $clauses, $lang ) {
|
224 |
if ( ! empty( $lang ) && false === strpos( $clauses['join'], 'pll_tr' ) ) {
|
@@ -411,11 +430,16 @@ class PLL_Model {
|
|
411 |
* @param string $taxonomy Taxonomy name.
|
412 |
* @param int $parent Parent term id.
|
413 |
* @param string|PLL_Language $language The language slug or object.
|
414 |
-
* @return
|
415 |
*/
|
416 |
public function term_exists( $term_name, $taxonomy, $parent, $language ) {
|
417 |
global $wpdb;
|
418 |
|
|
|
|
|
|
|
|
|
|
|
419 |
$term_name = trim( wp_unslash( $term_name ) );
|
420 |
$term_name = _wp_specialchars( $term_name );
|
421 |
|
@@ -423,7 +447,7 @@ class PLL_Model {
|
|
423 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
424 |
$join .= $this->term->join_clause();
|
425 |
$where = $wpdb->prepare( ' WHERE tt.taxonomy = %s AND t.name = %s', $taxonomy, $term_name );
|
426 |
-
$where .= $this->term->where_clause( $
|
427 |
|
428 |
if ( $parent > 0 ) {
|
429 |
$where .= $wpdb->prepare( ' AND tt.parent = %d', $parent );
|
@@ -443,16 +467,21 @@ class PLL_Model {
|
|
443 |
* @param string|PLL_Language $language The language slug or object.
|
444 |
* @param string $taxonomy Optional taxonomy name.
|
445 |
* @param int $parent Optional parent term id.
|
446 |
-
* @return
|
447 |
*/
|
448 |
public function term_exists_by_slug( $slug, $language, $taxonomy = '', $parent = 0 ) {
|
449 |
global $wpdb;
|
450 |
|
|
|
|
|
|
|
|
|
|
|
451 |
$select = "SELECT t.term_id FROM {$wpdb->terms} AS t";
|
452 |
$join = " INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
|
453 |
$join .= $this->term->join_clause();
|
454 |
$where = $wpdb->prepare( ' WHERE t.slug = %s', $slug );
|
455 |
-
$where .= $this->term->where_clause( $
|
456 |
|
457 |
if ( ! empty( $taxonomy ) ) {
|
458 |
$where .= $wpdb->prepare( ' AND tt.taxonomy = %s', $taxonomy );
|
@@ -699,7 +728,7 @@ class PLL_Model {
|
|
699 |
SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
|
700 |
)
|
701 |
%s",
|
702 |
-
implode( "','",
|
703 |
implode( ',', array_map( 'intval', $languages ) ),
|
704 |
$limit > 0 ? sprintf( 'LIMIT %d', intval( $limit ) ) : ''
|
705 |
);
|
@@ -756,7 +785,7 @@ class PLL_Model {
|
|
756 |
*
|
757 |
* @since 3.2.3
|
758 |
*
|
759 |
-
* @return
|
760 |
*/
|
761 |
protected function get_language_terms() {
|
762 |
add_filter( 'get_terms_orderby', array( $this, 'filter_language_terms_orderby' ), 10, 3 );
|
65 |
add_filter( 'language_description', '__return_empty_string' );
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* Checks if there are languages or not.
|
70 |
+
*
|
71 |
+
* @since 3.3
|
72 |
+
*
|
73 |
+
* @return bool True if there are, false otherwise.
|
74 |
+
*/
|
75 |
+
public function has_languages() {
|
76 |
+
if ( false !== $this->cache->get( 'languages' ) ) {
|
77 |
+
return true;
|
78 |
+
}
|
79 |
+
|
80 |
+
if ( false !== get_transient( 'pll_languages_list' ) ) {
|
81 |
+
return true;
|
82 |
+
}
|
83 |
+
|
84 |
+
return ! empty( $this->get_language_terms() );
|
85 |
+
}
|
86 |
+
|
87 |
/**
|
88 |
* Returns the list of available languages.
|
89 |
* - Stores the list in a db transient ( except flags ), unless PLL_CACHE_LANGUAGES is set to false.
|
107 |
|
108 |
$post_languages = $this->get_language_terms();
|
109 |
|
110 |
+
$term_languages = get_terms( array( 'taxonomy' => 'term_language', 'hide_empty' => false ) );
|
111 |
$term_languages = empty( $term_languages ) || is_wp_error( $term_languages ) ?
|
112 |
array() : array_combine( wp_list_pluck( $term_languages, 'slug' ), $term_languages );
|
113 |
|
235 |
*
|
236 |
* @since 1.2
|
237 |
*
|
238 |
+
* @param string[] $clauses The list of sql clauses in terms query.
|
239 |
+
* @param PLL_Language|false $lang PLL_Language object.
|
240 |
+
* @return string[] Modified list of clauses.
|
241 |
*/
|
242 |
public function terms_clauses( $clauses, $lang ) {
|
243 |
if ( ! empty( $lang ) && false === strpos( $clauses['join'], 'pll_tr' ) ) {
|
430 |
* @param string $taxonomy Taxonomy name.
|
431 |
* @param int $parent Parent term id.
|
432 |
* @param string|PLL_Language $language The language slug or object.
|
433 |
+
* @return int The `term_id` of the found term. 0 otherwise.
|
434 |
*/
|
435 |
public function term_exists( $term_name, $taxonomy, $parent, $language ) {
|
436 |
global $wpdb;
|
437 |
|
438 |
+
$language = $this->get_language( $language );
|
439 |
+
if ( empty( $language ) ) {
|
440 |
+
return 0;
|
441 |
+
}
|
442 |
+
|
443 |
$term_name = trim( wp_unslash( $term_name ) );
|
444 |
$term_name = _wp_specialchars( $term_name );
|
445 |
|
447 |
$join = " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
|
448 |
$join .= $this->term->join_clause();
|
449 |
$where = $wpdb->prepare( ' WHERE tt.taxonomy = %s AND t.name = %s', $taxonomy, $term_name );
|
450 |
+
$where .= $this->term->where_clause( $language );
|
451 |
|
452 |
if ( $parent > 0 ) {
|
453 |
$where .= $wpdb->prepare( ' AND tt.parent = %d', $parent );
|
467 |
* @param string|PLL_Language $language The language slug or object.
|
468 |
* @param string $taxonomy Optional taxonomy name.
|
469 |
* @param int $parent Optional parent term id.
|
470 |
+
* @return int The `term_id` of the found term. 0 otherwise.
|
471 |
*/
|
472 |
public function term_exists_by_slug( $slug, $language, $taxonomy = '', $parent = 0 ) {
|
473 |
global $wpdb;
|
474 |
|
475 |
+
$language = $this->get_language( $language );
|
476 |
+
if ( empty( $language ) ) {
|
477 |
+
return 0;
|
478 |
+
}
|
479 |
+
|
480 |
$select = "SELECT t.term_id FROM {$wpdb->terms} AS t";
|
481 |
$join = " INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id";
|
482 |
$join .= $this->term->join_clause();
|
483 |
$where = $wpdb->prepare( ' WHERE t.slug = %s', $slug );
|
484 |
+
$where .= $this->term->where_clause( $language );
|
485 |
|
486 |
if ( ! empty( $taxonomy ) ) {
|
487 |
$where .= $wpdb->prepare( ' AND tt.taxonomy = %s', $taxonomy );
|
728 |
SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
|
729 |
)
|
730 |
%s",
|
731 |
+
implode( "','", esc_sql( $taxonomies ) ),
|
732 |
implode( ',', array_map( 'intval', $languages ) ),
|
733 |
$limit > 0 ? sprintf( 'LIMIT %d', intval( $limit ) ) : ''
|
734 |
);
|
785 |
*
|
786 |
* @since 3.2.3
|
787 |
*
|
788 |
+
* @return WP_Term[]
|
789 |
*/
|
790 |
protected function get_language_terms() {
|
791 |
add_filter( 'get_terms_orderby', array( $this, 'filter_language_terms_orderby' ), 10, 3 );
|
include/olt-manager.php
CHANGED
@@ -16,14 +16,14 @@ 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 |
|
@@ -93,9 +93,9 @@ class PLL_OLT_Manager {
|
|
93 |
*/
|
94 |
public function load_textdomains() {
|
95 |
// Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain
|
96 |
-
remove_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' )
|
97 |
-
remove_filter( 'gettext', array( $this, 'gettext' )
|
98 |
-
remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' )
|
99 |
$new_locale = get_locale();
|
100 |
|
101 |
// Don't try to save time for en_US as some users have theme written in another language
|
16 |
/**
|
17 |
* Singleton instance
|
18 |
*
|
19 |
+
* @var PLL_OLT_Manager|null
|
20 |
*/
|
21 |
protected static $instance;
|
22 |
|
23 |
/**
|
24 |
* Stores the default site locale before it is modified.
|
25 |
*
|
26 |
+
* @var string|null
|
27 |
*/
|
28 |
protected $default_locale;
|
29 |
|
93 |
*/
|
94 |
public function load_textdomains() {
|
95 |
// Our load_textdomain_mofile filter has done its job. let's remove it before calling load_textdomain
|
96 |
+
remove_filter( 'load_textdomain_mofile', array( $this, 'load_textdomain_mofile' ) );
|
97 |
+
remove_filter( 'gettext', array( $this, 'gettext' ) );
|
98 |
+
remove_filter( 'gettext_with_context', array( $this, 'gettext_with_context' ) );
|
99 |
$new_locale = get_locale();
|
100 |
|
101 |
// Don't try to save time for en_US as some users have theme written in another language
|
include/query.php
CHANGED
@@ -92,7 +92,7 @@ class PLL_Query {
|
|
92 |
* @return array queried taxonomies
|
93 |
*/
|
94 |
public function get_queried_taxonomies() {
|
95 |
-
return
|
96 |
}
|
97 |
|
98 |
/**
|
@@ -100,16 +100,22 @@ class PLL_Query {
|
|
100 |
* Optimized for (and requires) WP 3.5+.
|
101 |
*
|
102 |
* @since 2.2
|
|
|
103 |
*
|
104 |
-
* @param PLL_Language $
|
105 |
* @return void
|
106 |
*/
|
107 |
-
public function set_language( $
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
109 |
$lang_query = array(
|
110 |
'taxonomy' => 'language',
|
111 |
'field' => 'term_taxonomy_id', // Since WP 3.5
|
112 |
-
'terms' => $
|
113 |
'operator' => 'IN',
|
114 |
);
|
115 |
|
@@ -118,7 +124,7 @@ class PLL_Query {
|
|
118 |
if ( isset( $tax_query['relation'] ) && 'OR' === $tax_query['relation'] ) {
|
119 |
$tax_query = array(
|
120 |
$lang_query,
|
121 |
-
|
122 |
'relation' => 'AND',
|
123 |
);
|
124 |
} elseif ( is_array( $tax_query ) ) {
|
@@ -137,7 +143,7 @@ class PLL_Query {
|
|
137 |
*
|
138 |
* @since 2.2
|
139 |
*
|
140 |
-
* @param PLL_Language $lang Language.
|
141 |
* @return void
|
142 |
*/
|
143 |
public function filter_query( $lang ) {
|
@@ -174,6 +180,8 @@ class PLL_Query {
|
|
174 |
}
|
175 |
}
|
176 |
} else {
|
|
|
|
|
177 |
// Do not filter untranslatable post types such as nav_menu_item
|
178 |
if ( isset( $qvars['post_type'] ) && ! $this->model->is_translated_post_type( $qvars['post_type'] ) && ( empty( $qvars['tax_query'] ) || ! $this->have_translated_taxonomy( $qvars['tax_query'] ) ) ) {
|
179 |
unset( $qvars['lang'] );
|
@@ -185,4 +193,38 @@ class PLL_Query {
|
|
185 |
}
|
186 |
}
|
187 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
92 |
* @return array queried taxonomies
|
93 |
*/
|
94 |
public function get_queried_taxonomies() {
|
95 |
+
return ! empty( $this->query->tax_query->queried_terms ) ? array_keys( wp_list_filter( $this->query->tax_query->queried_terms, array( 'operator' => 'NOT IN' ), 'NOT' ) ) : array();
|
96 |
}
|
97 |
|
98 |
/**
|
100 |
* Optimized for (and requires) WP 3.5+.
|
101 |
*
|
102 |
* @since 2.2
|
103 |
+
* @since 3.3 Accepts now an array of languages.
|
104 |
*
|
105 |
+
* @param PLL_Language|PLL_Language[] $languages Language object(s).
|
106 |
* @return void
|
107 |
*/
|
108 |
+
public function set_language( $languages ) {
|
109 |
+
if ( ! is_array( $languages ) ) {
|
110 |
+
$languages = array( $languages );
|
111 |
+
}
|
112 |
+
$tt_ids = wp_list_pluck( $languages, 'term_taxonomy_id' );
|
113 |
+
|
114 |
+
// Defining directly the tax_query (rather than setting 'lang' avoids transforming the query by WP).
|
115 |
$lang_query = array(
|
116 |
'taxonomy' => 'language',
|
117 |
'field' => 'term_taxonomy_id', // Since WP 3.5
|
118 |
+
'terms' => $tt_ids,
|
119 |
'operator' => 'IN',
|
120 |
);
|
121 |
|
124 |
if ( isset( $tax_query['relation'] ) && 'OR' === $tax_query['relation'] ) {
|
125 |
$tax_query = array(
|
126 |
$lang_query,
|
127 |
+
$tax_query,
|
128 |
'relation' => 'AND',
|
129 |
);
|
130 |
} elseif ( is_array( $tax_query ) ) {
|
143 |
*
|
144 |
* @since 2.2
|
145 |
*
|
146 |
+
* @param PLL_Language|false $lang Language.
|
147 |
* @return void
|
148 |
*/
|
149 |
public function filter_query( $lang ) {
|
180 |
}
|
181 |
}
|
182 |
} else {
|
183 |
+
$this->maybe_set_language_for_or_relation();
|
184 |
+
|
185 |
// Do not filter untranslatable post types such as nav_menu_item
|
186 |
if ( isset( $qvars['post_type'] ) && ! $this->model->is_translated_post_type( $qvars['post_type'] ) && ( empty( $qvars['tax_query'] ) || ! $this->have_translated_taxonomy( $qvars['tax_query'] ) ) ) {
|
187 |
unset( $qvars['lang'] );
|
193 |
}
|
194 |
}
|
195 |
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Sets the language correctly if the current query is a 'OR' relation,
|
199 |
+
* since WordPress merges the language with the other query vars when the relation is OR.
|
200 |
+
*
|
201 |
+
* @since 3.3
|
202 |
+
*
|
203 |
+
* @return void
|
204 |
+
*/
|
205 |
+
protected function maybe_set_language_for_or_relation() {
|
206 |
+
if ( ! $this->query->tax_query instanceof WP_Tax_Query ) {
|
207 |
+
return;
|
208 |
+
}
|
209 |
+
|
210 |
+
if ( 'OR' !== $this->query->tax_query->relation ) {
|
211 |
+
return;
|
212 |
+
}
|
213 |
+
|
214 |
+
if ( ! isset( $this->query->tax_query->queried_terms['language'] ) ) {
|
215 |
+
return;
|
216 |
+
}
|
217 |
+
|
218 |
+
$langs = $this->query->tax_query->queried_terms['language']['terms'];
|
219 |
+
if ( is_string( $langs ) ) {
|
220 |
+
$langs = explode( ',', $langs );
|
221 |
+
}
|
222 |
+
$langs = array_map( array( $this->model, 'get_language' ), $langs );
|
223 |
+
$langs = array_filter( $langs );
|
224 |
+
|
225 |
+
if ( ! empty( $langs ) ) {
|
226 |
+
$this->set_language( $langs );
|
227 |
+
unset( $this->query->query_vars['lang'] ); // Unset the language query var otherwise WordPress would add the language query by slug in WP_Query::parse_tax_query().
|
228 |
+
}
|
229 |
+
}
|
230 |
}
|
include/rest-request.php
CHANGED
@@ -59,10 +59,37 @@ class PLL_REST_Request extends PLL_Base {
|
|
59 |
return;
|
60 |
}
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
|
67 |
if ( empty( $this->curlang ) && ! empty( $this->options['default_lang'] ) && is_string( $this->options['default_lang'] ) ) {
|
68 |
// A lang has been requested but it is invalid, let's fall back to the default one.
|
@@ -78,16 +105,6 @@ class PLL_REST_Request extends PLL_Base {
|
|
78 |
do_action( 'pll_no_language_defined' ); // To load overridden textdomains.
|
79 |
}
|
80 |
|
81 |
-
|
82 |
-
$this->filters = new PLL_Filters( $this );
|
83 |
-
$this->filters_widgets_options = new PLL_Filters_Widgets_Options( $this );
|
84 |
-
|
85 |
-
// Static front page and page for posts.
|
86 |
-
if ( 'page' === get_option( 'show_on_front' ) ) {
|
87 |
-
$this->static_pages = new PLL_Static_Pages( $this );
|
88 |
-
}
|
89 |
-
|
90 |
-
$this->links = new PLL_Admin_Links( $this );
|
91 |
-
$this->nav_menu = new PLL_Nav_Menu( $this ); // For auto added pages to menu.
|
92 |
}
|
93 |
}
|
59 |
return;
|
60 |
}
|
61 |
|
62 |
+
add_filter( 'rest_pre_dispatch', array( $this, 'set_language' ), 10, 3 );
|
63 |
+
|
64 |
+
$this->filters_links = new PLL_Filters_Links( $this );
|
65 |
+
$this->filters = new PLL_Filters( $this );
|
66 |
+
$this->filters_widgets_options = new PLL_Filters_Widgets_Options( $this );
|
67 |
+
|
68 |
+
// Static front page and page for posts.
|
69 |
+
if ( 'page' === get_option( 'show_on_front' ) ) {
|
70 |
+
$this->static_pages = new PLL_Static_Pages( $this );
|
71 |
+
}
|
72 |
+
|
73 |
+
$this->links = new PLL_Admin_Links( $this );
|
74 |
+
$this->nav_menu = new PLL_Frontend_Nav_Menu( $this ); // For auto added pages to menu.
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Sets the current language during a REST request if sent.
|
79 |
+
*
|
80 |
+
* @since 3.3
|
81 |
+
*
|
82 |
+
* @param mixed $result Response to replace the requested version with. Remains untouched.
|
83 |
+
* @param WP_REST_Server $server Server instance.
|
84 |
+
* @param WP_REST_Request $request Request used to generate the response.
|
85 |
+
*
|
86 |
+
* @return mixed Untouched $result.
|
87 |
+
*/
|
88 |
+
public function set_language( $result, $server, $request ) {
|
89 |
+
$lang = $request->get_param( 'lang' );
|
90 |
+
|
91 |
+
if ( ! empty( $lang ) && is_string( $lang ) ) {
|
92 |
+
$this->curlang = $this->model->get_language( sanitize_key( $lang ) );
|
93 |
|
94 |
if ( empty( $this->curlang ) && ! empty( $this->options['default_lang'] ) && is_string( $this->options['default_lang'] ) ) {
|
95 |
// A lang has been requested but it is invalid, let's fall back to the default one.
|
105 |
do_action( 'pll_no_language_defined' ); // To load overridden textdomains.
|
106 |
}
|
107 |
|
108 |
+
return $result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
}
|
110 |
}
|
include/static-pages.php
CHANGED
@@ -12,14 +12,14 @@ 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 |
|
@@ -38,7 +38,7 @@ class PLL_Static_Pages {
|
|
38 |
/**
|
39 |
* Current language.
|
40 |
*
|
41 |
-
* @var PLL_Language
|
42 |
*/
|
43 |
protected $curlang;
|
44 |
|
@@ -56,6 +56,8 @@ class PLL_Static_Pages {
|
|
56 |
|
57 |
$this->init();
|
58 |
|
|
|
|
|
59 |
// Modifies the page link in case the front page is not in the default language
|
60 |
add_filter( 'page_link', array( $this, 'page_link' ), 20, 2 );
|
61 |
|
@@ -88,6 +90,19 @@ class PLL_Static_Pages {
|
|
88 |
}
|
89 |
}
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
/**
|
92 |
* Modifies the page link in case the front page is not in the default language
|
93 |
*
|
@@ -127,16 +142,30 @@ class PLL_Static_Pages {
|
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
-
* Translates page
|
131 |
*
|
132 |
* @since 1.8
|
|
|
133 |
*
|
134 |
-
* @param
|
135 |
* @return int
|
136 |
*/
|
137 |
-
public function
|
138 |
-
// Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache
|
139 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
}
|
141 |
|
142 |
/**
|
@@ -151,10 +180,11 @@ class PLL_Static_Pages {
|
|
151 |
*/
|
152 |
public function oembed_request_post_id( $post_id, $url ) {
|
153 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
154 |
-
if ( trailingslashit( $url ) === trailingslashit( $lang->home_url ) ) {
|
155 |
-
|
156 |
}
|
157 |
}
|
|
|
158 |
return $post_id;
|
159 |
}
|
160 |
}
|
12 |
/**
|
13 |
* Id of the page on front.
|
14 |
*
|
15 |
+
* @var int|null
|
16 |
*/
|
17 |
public $page_on_front;
|
18 |
|
19 |
/**
|
20 |
* Id of the page for posts.
|
21 |
*
|
22 |
+
* @var int|null
|
23 |
*/
|
24 |
public $page_for_posts;
|
25 |
|
38 |
/**
|
39 |
* Current language.
|
40 |
*
|
41 |
+
* @var PLL_Language|null
|
42 |
*/
|
43 |
protected $curlang;
|
44 |
|
56 |
|
57 |
$this->init();
|
58 |
|
59 |
+
add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ) );
|
60 |
+
|
61 |
// Modifies the page link in case the front page is not in the default language
|
62 |
add_filter( 'page_link', array( $this, 'page_link' ), 20, 2 );
|
63 |
|
90 |
}
|
91 |
}
|
92 |
|
93 |
+
/**
|
94 |
+
* Init the hooks that filter the "page on front" and "page for posts" options.
|
95 |
+
*
|
96 |
+
* @since 3.3
|
97 |
+
*
|
98 |
+
* @return void
|
99 |
+
*/
|
100 |
+
public function pll_language_defined() {
|
101 |
+
// Translates page for posts and page on front.
|
102 |
+
add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) );
|
103 |
+
add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
|
104 |
+
}
|
105 |
+
|
106 |
/**
|
107 |
* Modifies the page link in case the front page is not in the default language
|
108 |
*
|
142 |
}
|
143 |
|
144 |
/**
|
145 |
+
* Translates the page on front option.
|
146 |
*
|
147 |
* @since 1.8
|
148 |
+
* @since 3.3 Was previously defined in PLL_Frontend_Static_Pages.
|
149 |
*
|
150 |
+
* @param int $page_id ID of the page on front.
|
151 |
* @return int
|
152 |
*/
|
153 |
+
public function translate_page_on_front( $page_id ) {
|
154 |
+
// Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache.
|
155 |
+
return ! empty( $this->curlang->page_on_front ) && ! doing_action( 'switch_blog' ) ? $this->curlang->page_on_front : $page_id;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Translates the page for posts option.
|
160 |
+
*
|
161 |
+
* @since 1.8
|
162 |
+
*
|
163 |
+
* @param int $page_id ID of the page for posts.
|
164 |
+
* @return int
|
165 |
+
*/
|
166 |
+
public function translate_page_for_posts( $page_id ) {
|
167 |
+
// Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache.
|
168 |
+
return ! empty( $this->curlang->page_for_posts ) && ! doing_action( 'switch_blog' ) ? $this->curlang->page_for_posts : $page_id;
|
169 |
}
|
170 |
|
171 |
/**
|
180 |
*/
|
181 |
public function oembed_request_post_id( $post_id, $url ) {
|
182 |
foreach ( $this->model->get_languages_list() as $lang ) {
|
183 |
+
if ( is_string( $lang->home_url ) && trailingslashit( $url ) === trailingslashit( $lang->home_url ) ) {
|
184 |
+
return (int) $lang->page_on_front;
|
185 |
}
|
186 |
}
|
187 |
+
|
188 |
return $post_id;
|
189 |
}
|
190 |
}
|
include/switcher.php
CHANGED
@@ -27,7 +27,7 @@ class PLL_Switcher {
|
|
27 |
);
|
28 |
|
29 |
/**
|
30 |
-
* @var PLL_Links
|
31 |
*/
|
32 |
protected $links;
|
33 |
|
27 |
);
|
28 |
|
29 |
/**
|
30 |
+
* @var PLL_Links|null
|
31 |
*/
|
32 |
protected $links;
|
33 |
|
include/translate-option.php
CHANGED
@@ -192,7 +192,7 @@ class PLL_Translate_Option {
|
|
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' )
|
196 |
$unfiltered_old_value = get_option( $name );
|
197 |
add_filter( 'option_' . $name, array( $this, 'translate' ), 20, 2 );
|
198 |
|
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' ) );
|
196 |
$unfiltered_old_value = get_option( $name );
|
197 |
add_filter( 'option_' . $name, array( $this, 'translate' ), 20, 2 );
|
198 |
|
include/translated-object.php
CHANGED
@@ -171,8 +171,8 @@ abstract class PLL_Translated_Object {
|
|
171 |
*
|
172 |
* @since 3.2
|
173 |
*
|
174 |
-
* @param
|
175 |
-
* @return
|
176 |
*/
|
177 |
public function get_translations_from_term_id( $term_id ) {
|
178 |
$term_id = $this->sanitize_int_id( $term_id );
|
@@ -216,7 +216,7 @@ abstract class PLL_Translated_Object {
|
|
216 |
*
|
217 |
* @param int $id Object id ( typically a post_id or term_id ).
|
218 |
* @param int[] $translations An associative array of translations with language code as key and translation id as value.
|
219 |
-
* @return int[]
|
220 |
*/
|
221 |
public function save_translations( $id, $translations ) {
|
222 |
$id = $this->sanitize_int_id( $id );
|
@@ -410,7 +410,7 @@ abstract class PLL_Translated_Object {
|
|
410 |
*
|
411 |
* @since 1.2
|
412 |
*
|
413 |
-
* @param PLL_Language|string|string[] $lang PLL_Language object or a comma separated list of language slug or an array of language slugs.
|
414 |
* @return string Where clause.
|
415 |
*/
|
416 |
public function where_clause( $lang ) {
|
@@ -425,16 +425,24 @@ abstract class PLL_Translated_Object {
|
|
425 |
}
|
426 |
|
427 |
/*
|
428 |
-
* $lang is
|
429 |
-
*
|
430 |
*/
|
431 |
-
$
|
432 |
-
$
|
433 |
-
foreach ( $
|
434 |
-
$
|
|
|
|
|
|
|
|
|
435 |
}
|
436 |
|
437 |
-
|
|
|
|
|
|
|
|
|
438 |
}
|
439 |
|
440 |
/**
|
@@ -488,11 +496,13 @@ abstract class PLL_Translated_Object {
|
|
488 |
*
|
489 |
* @since 3.2
|
490 |
*
|
491 |
-
* @param
|
492 |
-
* @return int
|
|
|
|
|
493 |
*/
|
494 |
public function sanitize_int_id( $id ) {
|
495 |
-
return is_numeric( $id ) && $id >= 1 ? (int) $id : 0;
|
496 |
}
|
497 |
|
498 |
/**
|
@@ -501,8 +511,8 @@ abstract class PLL_Translated_Object {
|
|
501 |
*
|
502 |
* @since 3.2
|
503 |
*
|
504 |
-
* @param
|
505 |
-
* @return
|
506 |
*/
|
507 |
public function sanitize_int_ids_list( $ids ) {
|
508 |
if ( empty( $ids ) || ! is_array( $ids ) ) {
|
@@ -526,13 +536,13 @@ abstract class PLL_Translated_Object {
|
|
526 |
* @since 3.2 Doesn't return `0` ID values.
|
527 |
* @since 3.2 Added parameters `$id` and `$context`.
|
528 |
*
|
529 |
-
* @param
|
530 |
-
*
|
531 |
-
* @param
|
532 |
-
*
|
533 |
-
* @param
|
534 |
-
*
|
535 |
-
*
|
536 |
* @return int[]
|
537 |
*/
|
538 |
protected function validate_translations( $translations, $id = 0, $context = 'save' ) {
|
171 |
*
|
172 |
* @since 3.2
|
173 |
*
|
174 |
+
* @param int $term_id Term ID.
|
175 |
+
* @return int[] An associative array of translations with language code as key and translation id as value.
|
176 |
*/
|
177 |
public function get_translations_from_term_id( $term_id ) {
|
178 |
$term_id = $this->sanitize_int_id( $term_id );
|
216 |
*
|
217 |
* @param int $id Object id ( typically a post_id or term_id ).
|
218 |
* @param int[] $translations An associative array of translations with language code as key and translation id as value.
|
219 |
+
* @return int[] An associative array with language codes as key and post ids as values.
|
220 |
*/
|
221 |
public function save_translations( $id, $translations ) {
|
222 |
$id = $this->sanitize_int_id( $id );
|
410 |
*
|
411 |
* @since 1.2
|
412 |
*
|
413 |
+
* @param PLL_Language|PLL_Language[]|string|string[] $lang PLL_Language object or a comma separated list of language slug or an array of language slugs or objects.
|
414 |
* @return string Where clause.
|
415 |
*/
|
416 |
public function where_clause( $lang ) {
|
425 |
}
|
426 |
|
427 |
/*
|
428 |
+
* $lang is an array of objects, an array of slugs, or a comma separated list of slugs.
|
429 |
+
* The comma separated list of slugs can happen if the query is coming from outside with a 'lang' parameter.
|
430 |
*/
|
431 |
+
$languages = is_array( $lang ) ? $lang : explode( ',', $lang );
|
432 |
+
$languages_tt_ids = array();
|
433 |
+
foreach ( $languages as $language ) {
|
434 |
+
$language = $this->model->get_language( $language );
|
435 |
+
|
436 |
+
if ( ! empty( $language ) ) {
|
437 |
+
$languages_tt_ids[] = absint( $language->$tt_id );
|
438 |
+
}
|
439 |
}
|
440 |
|
441 |
+
if ( empty( $languages_tt_ids ) ) {
|
442 |
+
return '';
|
443 |
+
}
|
444 |
+
|
445 |
+
return ' AND pll_tr.term_taxonomy_id IN ( ' . implode( ',', $languages_tt_ids ) . ' )';
|
446 |
}
|
447 |
|
448 |
/**
|
496 |
*
|
497 |
* @since 3.2
|
498 |
*
|
499 |
+
* @param mixed $id A supposedly numeric ID.
|
500 |
+
* @return int A positive integer. `0` for non numeric values and negative integers.
|
501 |
+
*
|
502 |
+
* @phpstan-return int<0,max>
|
503 |
*/
|
504 |
public function sanitize_int_id( $id ) {
|
505 |
+
return is_numeric( $id ) && $id >= 1 ? abs( (int) $id ) : 0;
|
506 |
}
|
507 |
|
508 |
/**
|
511 |
*
|
512 |
* @since 3.2
|
513 |
*
|
514 |
+
* @param mixed $ids An associative array of translations with language code as key and translation ID as value.
|
515 |
+
* @return int[] An associative array of translations with language code as key and translation ID as value.
|
516 |
*/
|
517 |
public function sanitize_int_ids_list( $ids ) {
|
518 |
if ( empty( $ids ) || ! is_array( $ids ) ) {
|
536 |
* @since 3.2 Doesn't return `0` ID values.
|
537 |
* @since 3.2 Added parameters `$id` and `$context`.
|
538 |
*
|
539 |
+
* @param int[] $translations An associative array of translations with language code as key and translation ID as
|
540 |
+
* value.
|
541 |
+
* @param int $id Optional. The object ID for which the translations are validated. When provided, the
|
542 |
+
* process makes sure it is added to the list. Default 0.
|
543 |
+
* @param string $context Optional. The operation for which the translations are validated. When set to
|
544 |
+
* 'save', a check is done to verify that the IDs and langs correspond.
|
545 |
+
* 'display' should be used otherwise. Default 'save'.
|
546 |
* @return int[]
|
547 |
*/
|
548 |
protected function validate_translations( $translations, $id = 0, $context = 'save' ) {
|
include/translated-term.php
CHANGED
@@ -26,10 +26,7 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
26 |
|
27 |
parent::__construct( $model );
|
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 |
|
@@ -205,23 +202,6 @@ class PLL_Translated_Term extends PLL_Translated_Object {
|
|
205 |
return $terms;
|
206 |
}
|
207 |
|
208 |
-
/**
|
209 |
-
* When terms are found for posts, add their language and translations to cache.
|
210 |
-
*
|
211 |
-
* @since 1.2
|
212 |
-
*
|
213 |
-
* @param WP_Term[] $terms Array of terms for the given object or objects.
|
214 |
-
* @param int[] $object_ids Array of object IDs for which terms were retrieved.
|
215 |
-
* @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
|
216 |
-
* @return WP_Term[] Unmodified $terms.
|
217 |
-
*/
|
218 |
-
public function wp_get_object_terms( $terms, $object_ids, $taxonomies ) {
|
219 |
-
if ( ! in_array( $this->tax_translations, $taxonomies ) ) {
|
220 |
-
$this->_prime_terms_cache( $terms, $taxonomies );
|
221 |
-
}
|
222 |
-
return $terms;
|
223 |
-
}
|
224 |
-
|
225 |
/**
|
226 |
* When the term cache is cleaned, cleans the object term cache too.
|
227 |
*
|
26 |
|
27 |
parent::__construct( $model );
|
28 |
|
|
|
29 |
add_filter( 'get_terms', array( $this, '_prime_terms_cache' ), 10, 2 );
|
|
|
|
|
30 |
add_action( 'clean_term_cache', array( $this, 'clean_term_cache' ) );
|
31 |
}
|
32 |
|
202 |
return $terms;
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
/**
|
206 |
* When the term cache is cleaned, cleans the object term cache too.
|
207 |
*
|
include/walker-dropdown.php
CHANGED
@@ -14,7 +14,7 @@ class PLL_Walker_Dropdown extends Walker {
|
|
14 |
*
|
15 |
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
*
|
17 |
-
* @var
|
18 |
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
14 |
*
|
15 |
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
*
|
17 |
+
* @var string[]
|
18 |
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
include/walker-list.php
CHANGED
@@ -14,7 +14,7 @@ class PLL_Walker_List extends Walker {
|
|
14 |
*
|
15 |
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
*
|
17 |
-
* @var
|
18 |
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
14 |
*
|
15 |
* @see https://developer.wordpress.org/reference/classes/walker/#properties Walker::$db_fields.
|
16 |
*
|
17 |
+
* @var string[]
|
18 |
*/
|
19 |
public $db_fields = array( 'parent' => 'parent', 'id' => 'id' );
|
20 |
|
include/widget-languages.php
CHANGED
@@ -38,8 +38,11 @@ class PLL_Widget_Languages extends WP_Widget {
|
|
38 |
public function widget( $args, $instance ) {
|
39 |
// Sets a unique id for dropdown.
|
40 |
$instance['dropdown'] = empty( $instance['dropdown'] ) ? 0 : $this->id;
|
|
|
|
|
|
|
41 |
|
42 |
-
if ( $list
|
43 |
$title = empty( $instance['title'] ) ? '' : $instance['title'];
|
44 |
|
45 |
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
|
38 |
public function widget( $args, $instance ) {
|
39 |
// Sets a unique id for dropdown.
|
40 |
$instance['dropdown'] = empty( $instance['dropdown'] ) ? 0 : $this->id;
|
41 |
+
$instance['echo'] = 0;
|
42 |
+
$instance['raw'] = 0;
|
43 |
+
$list = pll_the_languages( $instance );
|
44 |
|
45 |
+
if ( $list ) {
|
46 |
$title = empty( $instance['title'] ) ? '' : $instance['title'];
|
47 |
|
48 |
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
|
install/t15s.php
CHANGED
@@ -35,14 +35,14 @@ class PLL_T15S {
|
|
35 |
/**
|
36 |
* Installed translations.
|
37 |
*
|
38 |
-
* @var array
|
39 |
*/
|
40 |
private static $installed_translations;
|
41 |
|
42 |
/**
|
43 |
* Available languages.
|
44 |
*
|
45 |
-
* @var array
|
46 |
*/
|
47 |
private static $available_languages;
|
48 |
|
35 |
/**
|
36 |
* Installed translations.
|
37 |
*
|
38 |
+
* @var array|null
|
39 |
*/
|
40 |
private static $installed_translations;
|
41 |
|
42 |
/**
|
43 |
* Available languages.
|
44 |
*
|
45 |
+
* @var array|null
|
46 |
*/
|
47 |
private static $available_languages;
|
48 |
|
install/upgrade.php
CHANGED
@@ -105,7 +105,10 @@ class PLL_Upgrade {
|
|
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 |
-
|
|
|
|
|
|
|
109 |
}
|
110 |
}
|
111 |
|
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 |
+
$method_to_call = array( $this, 'upgrade_' . str_replace( '.', '_', $version ) );
|
109 |
+
if ( is_callable( $method_to_call ) ) {
|
110 |
+
call_user_func( $method_to_call );
|
111 |
+
}
|
112 |
}
|
113 |
}
|
114 |
|
integrations/integrations.php
CHANGED
@@ -10,11 +10,12 @@
|
|
10 |
* @since 1.0
|
11 |
* @since 2.8 Renamed from PLL_Plugins_Compat to PLL_Integrations.
|
12 |
*/
|
|
|
13 |
class PLL_Integrations {
|
14 |
/**
|
15 |
* Singleton instance.
|
16 |
*
|
17 |
-
* @var PLL_Integrations
|
18 |
*/
|
19 |
protected static $instance;
|
20 |
|
10 |
* @since 1.0
|
11 |
* @since 2.8 Renamed from PLL_Plugins_Compat to PLL_Integrations.
|
12 |
*/
|
13 |
+
#[AllowDynamicProperties]
|
14 |
class PLL_Integrations {
|
15 |
/**
|
16 |
* Singleton instance.
|
17 |
*
|
18 |
+
* @var PLL_Integrations|null
|
19 |
*/
|
20 |
protected static $instance;
|
21 |
|
integrations/wp-importer/wp-import.php
CHANGED
@@ -41,7 +41,7 @@ class PLL_WP_Import extends WP_Import {
|
|
41 |
|
42 |
// Assign the default language in case the importer created the first language.
|
43 |
if ( empty( PLL()->options['default_lang'] ) ) {
|
44 |
-
$languages = get_terms( 'language',
|
45 |
$default_lang = reset( $languages );
|
46 |
PLL()->options['default_lang'] = $default_lang->slug;
|
47 |
update_option( 'polylang', PLL()->options );
|
41 |
|
42 |
// Assign the default language in case the importer created the first language.
|
43 |
if ( empty( PLL()->options['default_lang'] ) ) {
|
44 |
+
$languages = get_terms( array( 'taxonomy' => 'language', 'hide_empty' => false, 'orderby' => 'term_id' ) );
|
45 |
$default_lang = reset( $languages );
|
46 |
PLL()->options['default_lang'] = $default_lang->slug;
|
47 |
update_option( 'polylang', PLL()->options );
|
integrations/wp-offload-media/as3cf.php
CHANGED
@@ -15,7 +15,7 @@ class PLL_AS3CF {
|
|
15 |
*
|
16 |
* @var bool[]
|
17 |
*/
|
18 |
-
private $is_media_translated;
|
19 |
|
20 |
/**
|
21 |
* Initializes filters and actions.
|
15 |
*
|
16 |
* @var bool[]
|
17 |
*/
|
18 |
+
private $is_media_translated = array();
|
19 |
|
20 |
/**
|
21 |
* Initializes filters and actions.
|
integrations/wpseo/wpseo.php
CHANGED
@@ -46,6 +46,7 @@ class PLL_WPSEO {
|
|
46 |
} else {
|
47 |
add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 4 );
|
48 |
add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 );
|
|
|
49 |
|
50 |
// Yoast SEO adds the columns hooks only for the 'inline-save' action. We need them for 'pll_update_post_rows' too.
|
51 |
if ( wp_doing_ajax() && isset( $_POST['action'] ) && 'pll_update_post_rows' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
@@ -127,40 +128,43 @@ class PLL_WPSEO {
|
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
-
* Modifies the sql request for posts sitemaps
|
131 |
-
* Only when using multiple domains or subdomains or if some languages are not active
|
132 |
*
|
133 |
* @since 1.6.4
|
134 |
*
|
135 |
-
* @param string $sql JOIN clause
|
136 |
-
* @param string $post_type
|
137 |
* @return string
|
138 |
*/
|
139 |
public function wpseo_posts_join( $sql, $post_type ) {
|
140 |
-
return pll_is_translated_post_type( $post_type )
|
141 |
}
|
142 |
|
143 |
/**
|
144 |
-
* Modifies the sql request for posts sitemaps
|
145 |
-
* Only when using multiple domains or subdomains or if some languages are not active
|
146 |
*
|
147 |
* @since 1.6.4
|
148 |
*
|
149 |
-
* @param string $sql WHERE clause
|
150 |
-
* @param string $post_type
|
151 |
* @return string
|
152 |
*/
|
153 |
public function wpseo_posts_where( $sql, $post_type ) {
|
154 |
-
if ( pll_is_translated_post_type( $post_type ) ) {
|
155 |
-
|
156 |
-
|
157 |
-
}
|
158 |
|
159 |
-
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
|
|
|
|
162 |
}
|
163 |
-
|
|
|
164 |
}
|
165 |
|
166 |
/**
|
@@ -425,23 +429,16 @@ class PLL_WPSEO {
|
|
425 |
public function copy_post_metas( $keys, $sync, $from, $to ) {
|
426 |
if ( ! $sync ) {
|
427 |
// Text requiring translation.
|
428 |
-
$keys
|
429 |
-
$keys[] = '_yoast_wpseo_metadesc';
|
430 |
-
$keys[] = '_yoast_wpseo_bctitle';
|
431 |
-
$keys[] = '_yoast_wpseo_focuskw';
|
432 |
-
$keys[] = '_yoast_wpseo_opengraph-title';
|
433 |
-
$keys[] = '_yoast_wpseo_opengraph-description';
|
434 |
-
$keys[] = '_yoast_wpseo_twitter-title';
|
435 |
-
$keys[] = '_yoast_wpseo_twitter-description';
|
436 |
|
437 |
// Copy the image urls.
|
438 |
$keys[] = '_yoast_wpseo_opengraph-image';
|
439 |
$keys[] = '_yoast_wpseo_twitter-image';
|
440 |
-
}
|
441 |
|
442 |
-
|
443 |
-
|
444 |
-
|
|
|
445 |
|
446 |
$taxonomies = get_taxonomies(
|
447 |
array(
|
@@ -483,4 +480,36 @@ class PLL_WPSEO {
|
|
483 |
|
484 |
return pll_get_term( $value, $lang );
|
485 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
486 |
}
|
46 |
} else {
|
47 |
add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 10, 4 );
|
48 |
add_filter( 'pll_translate_post_meta', array( $this, 'translate_post_meta' ), 10, 3 );
|
49 |
+
add_filter( 'pll_post_metas_to_export', array( $this, 'export_post_metas' ) );
|
50 |
|
51 |
// Yoast SEO adds the columns hooks only for the 'inline-save' action. We need them for 'pll_update_post_rows' too.
|
52 |
if ( wp_doing_ajax() && isset( $_POST['action'] ) && 'pll_update_post_rows' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
+
* Modifies the sql request for posts sitemaps.
|
|
|
132 |
*
|
133 |
* @since 1.6.4
|
134 |
*
|
135 |
+
* @param string $sql JOIN clause.
|
136 |
+
* @param string $post_type Post type.
|
137 |
* @return string
|
138 |
*/
|
139 |
public function wpseo_posts_join( $sql, $post_type ) {
|
140 |
+
return pll_is_translated_post_type( $post_type ) ? $sql . PLL()->model->post->join_clause() : $sql;
|
141 |
}
|
142 |
|
143 |
/**
|
144 |
+
* Modifies the sql request for posts sitemaps.
|
|
|
145 |
*
|
146 |
* @since 1.6.4
|
147 |
*
|
148 |
+
* @param string $sql WHERE clause.
|
149 |
+
* @param string $post_type Post type.
|
150 |
* @return string
|
151 |
*/
|
152 |
public function wpseo_posts_where( $sql, $post_type ) {
|
153 |
+
if ( ! pll_is_translated_post_type( $post_type ) ) {
|
154 |
+
return $sql;
|
155 |
+
}
|
|
|
156 |
|
157 |
+
if ( PLL()->options['force_lang'] > 1 && PLL()->curlang instanceof PLL_Language ) {
|
158 |
+
return $sql . PLL()->model->post->where_clause( PLL()->curlang );
|
159 |
+
}
|
160 |
+
|
161 |
+
$languages = $this->wpseo_get_active_languages();
|
162 |
+
|
163 |
+
if ( empty( $languages ) ) { // Empty when all languages are active.
|
164 |
+
$languages = pll_languages_list();
|
165 |
}
|
166 |
+
|
167 |
+
return $sql . PLL()->model->post->where_clause( $languages );
|
168 |
}
|
169 |
|
170 |
/**
|
429 |
public function copy_post_metas( $keys, $sync, $from, $to ) {
|
430 |
if ( ! $sync ) {
|
431 |
// Text requiring translation.
|
432 |
+
$keys = array_merge( $keys, $this->get_translatable_meta_keys() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
|
434 |
// Copy the image urls.
|
435 |
$keys[] = '_yoast_wpseo_opengraph-image';
|
436 |
$keys[] = '_yoast_wpseo_twitter-image';
|
|
|
437 |
|
438 |
+
$keys[] = '_yoast_wpseo_meta-robots-noindex';
|
439 |
+
$keys[] = '_yoast_wpseo_meta-robots-nofollow';
|
440 |
+
$keys[] = '_yoast_wpseo_meta-robots-adv';
|
441 |
+
}
|
442 |
|
443 |
$taxonomies = get_taxonomies(
|
444 |
array(
|
480 |
|
481 |
return pll_get_term( $value, $lang );
|
482 |
}
|
483 |
+
|
484 |
+
/**
|
485 |
+
* Adds the yoast translatable metas to export.
|
486 |
+
*
|
487 |
+
* @param array $metas An array of post metas (keyed with meta keys) to export.
|
488 |
+
* @return array The modified array of post metas to export.
|
489 |
+
*/
|
490 |
+
public function export_post_metas( $metas ) {
|
491 |
+
$metas_to_export = array_fill_keys( $this->get_translatable_meta_keys(), 1 );
|
492 |
+
|
493 |
+
return array_merge( $metas, $metas_to_export );
|
494 |
+
}
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Returns the meta keys with translatable text.
|
498 |
+
*
|
499 |
+
* @since 3.3
|
500 |
+
*
|
501 |
+
* @return string[]
|
502 |
+
*/
|
503 |
+
protected function get_translatable_meta_keys() {
|
504 |
+
return array(
|
505 |
+
'_yoast_wpseo_title',
|
506 |
+
'_yoast_wpseo_metadesc',
|
507 |
+
'_yoast_wpseo_bctitle',
|
508 |
+
'_yoast_wpseo_focuskw',
|
509 |
+
'_yoast_wpseo_opengraph-title',
|
510 |
+
'_yoast_wpseo_opengraph-description',
|
511 |
+
'_yoast_wpseo_twitter-title',
|
512 |
+
'_yoast_wpseo_twitter-description',
|
513 |
+
);
|
514 |
+
}
|
515 |
}
|
js/build/block-editor.js
CHANGED
@@ -102,6 +102,49 @@ const initializeLanguageOldValue = () => {
|
|
102 |
languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
|
103 |
};
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
;// CONCATENATED MODULE: ./js/src/block-editor.js
|
106 |
/**
|
107 |
* @package Polylang
|
@@ -109,6 +152,8 @@ const initializeLanguageOldValue = () => {
|
|
109 |
|
110 |
|
111 |
|
|
|
|
|
112 |
/**
|
113 |
* Filter REST API requests to add the language in the request
|
114 |
*
|
@@ -131,14 +176,20 @@ wp.apiFetch.use(
|
|
131 |
);
|
132 |
|
133 |
/**
|
134 |
-
*
|
135 |
*
|
136 |
* @since 2.5
|
137 |
*
|
138 |
* @return {Element.value}
|
139 |
*/
|
140 |
function getCurrentLanguage() {
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
}
|
143 |
|
144 |
/**
|
@@ -197,7 +248,7 @@ jQuery(
|
|
197 |
|
198 |
dialogResult.then(
|
199 |
() => {
|
200 |
-
|
201 |
action: 'post_lang_choice',
|
202 |
lang: selectedOption.value,
|
203 |
post_type: $( '#post_type' ).val(),
|
@@ -205,28 +256,12 @@ jQuery(
|
|
205 |
_pll_nonce: $( '#_pll_nonce' ).val()
|
206 |
}
|
207 |
|
|
|
|
|
208 |
$.post(
|
209 |
ajaxurl,
|
210 |
data,
|
211 |
-
function(
|
212 |
-
// Target a non existing WP HTML id to avoid a conflict with WP ajax requests.
|
213 |
-
var res = wpAjax.parseAjaxResponse( response, 'pll-ajax-response' );
|
214 |
-
$.each(
|
215 |
-
res.responses,
|
216 |
-
function() {
|
217 |
-
switch ( this.what ) {
|
218 |
-
case 'translations': // Translations fields
|
219 |
-
// Data is built and come from server side and is well escaped when necessary
|
220 |
-
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
221 |
-
init_translations();
|
222 |
-
break;
|
223 |
-
case 'flag': // Flag in front of the select dropdown
|
224 |
-
// Data is built and come from server side and is well escaped when necessary
|
225 |
-
$( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
226 |
-
break;
|
227 |
-
}
|
228 |
-
}
|
229 |
-
);
|
230 |
blockEditorSavePostAndReloadPage();
|
231 |
}
|
232 |
);
|
@@ -310,47 +345,7 @@ jQuery(
|
|
310 |
}
|
311 |
);
|
312 |
|
313 |
-
|
314 |
-
function init_translations() {
|
315 |
-
$( '.tr_lang' ).each(
|
316 |
-
function(){
|
317 |
-
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
318 |
-
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
319 |
-
|
320 |
-
$( this ).autocomplete(
|
321 |
-
{
|
322 |
-
minLength: 0,
|
323 |
-
|
324 |
-
source: ajaxurl + '?action=pll_posts_not_translated' +
|
325 |
-
'&post_language=' + $( '.post_lang_choice' ).val() +
|
326 |
-
'&translation_language=' + tr_lang +
|
327 |
-
'&post_type=' + $( '#post_type' ).val() +
|
328 |
-
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
329 |
-
|
330 |
-
select: function( event, ui ) {
|
331 |
-
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
332 |
-
// ui.item.link is built and come from server side and is well escaped when necessary
|
333 |
-
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
334 |
-
},
|
335 |
-
}
|
336 |
-
);
|
337 |
-
|
338 |
-
// When the input box is emptied
|
339 |
-
$( this ).on(
|
340 |
-
'blur',
|
341 |
-
function() {
|
342 |
-
if ( ! $( this ).val() ) {
|
343 |
-
$( '#htr_lang_' + tr_lang ).val( 0 );
|
344 |
-
// Value is retrieved from HTML already generated server side
|
345 |
-
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
346 |
-
}
|
347 |
-
}
|
348 |
-
);
|
349 |
-
}
|
350 |
-
);
|
351 |
-
}
|
352 |
-
|
353 |
-
init_translations();
|
354 |
}
|
355 |
);
|
356 |
|
102 |
languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
|
103 |
};
|
104 |
|
105 |
+
;// CONCATENATED MODULE: ./js/src/lib/metabox-autocomplete.js
|
106 |
+
/**
|
107 |
+
* @package Polylang
|
108 |
+
*/
|
109 |
+
|
110 |
+
// Translations autocomplete input box.
|
111 |
+
function initMetaboxAutoComplete() {
|
112 |
+
jQuery('.tr_lang').each(
|
113 |
+
function () {
|
114 |
+
var tr_lang = jQuery(this).attr('id').substring(8);
|
115 |
+
var td = jQuery(this).parent().parent().siblings('.pll-edit-column');
|
116 |
+
|
117 |
+
jQuery(this).autocomplete(
|
118 |
+
{
|
119 |
+
minLength: 0,
|
120 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
121 |
+
'&post_language=' + jQuery('.post_lang_choice').val() +
|
122 |
+
'&translation_language=' + tr_lang +
|
123 |
+
'&post_type=' + jQuery('#post_type').val() +
|
124 |
+
'&_pll_nonce=' + jQuery('#_pll_nonce').val(),
|
125 |
+
select: function (event, ui) {
|
126 |
+
jQuery('#htr_lang_' + tr_lang).val(ui.item.id);
|
127 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
128 |
+
td.html(ui.item.link); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
129 |
+
},
|
130 |
+
}
|
131 |
+
);
|
132 |
+
|
133 |
+
// when the input box is emptied
|
134 |
+
jQuery(this).on(
|
135 |
+
'blur',
|
136 |
+
function () {
|
137 |
+
if ( ! jQuery(this).val() ) {
|
138 |
+
jQuery('#htr_lang_' + tr_lang).val(0);
|
139 |
+
// Value is retrieved from HTML already generated server side
|
140 |
+
td.html(td.siblings('.hidden').children().clone()); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
141 |
+
}
|
142 |
+
}
|
143 |
+
);
|
144 |
+
}
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
;// CONCATENATED MODULE: ./js/src/block-editor.js
|
149 |
/**
|
150 |
* @package Polylang
|
152 |
|
153 |
|
154 |
|
155 |
+
|
156 |
+
|
157 |
/**
|
158 |
* Filter REST API requests to add the language in the request
|
159 |
*
|
176 |
);
|
177 |
|
178 |
/**
|
179 |
+
* Gets the language of the currently edited post, fallback to default language if none is found.
|
180 |
*
|
181 |
* @since 2.5
|
182 |
*
|
183 |
* @return {Element.value}
|
184 |
*/
|
185 |
function getCurrentLanguage() {
|
186 |
+
const lang = document.querySelector( '[name=post_lang_choice]' );
|
187 |
+
|
188 |
+
if ( null === lang ) {
|
189 |
+
return pllDefaultLanguage;
|
190 |
+
}
|
191 |
+
|
192 |
+
return lang.value;
|
193 |
}
|
194 |
|
195 |
/**
|
248 |
|
249 |
dialogResult.then(
|
250 |
() => {
|
251 |
+
let data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
|
252 |
action: 'post_lang_choice',
|
253 |
lang: selectedOption.value,
|
254 |
post_type: $( '#post_type' ).val(),
|
256 |
_pll_nonce: $( '#_pll_nonce' ).val()
|
257 |
}
|
258 |
|
259 |
+
// Update post language in database as soon as possible.
|
260 |
+
// Because, in addition of the block editor save process, the legacy metabox uses a post.php process to update the language and is too late compared to the page reload.
|
261 |
$.post(
|
262 |
ajaxurl,
|
263 |
data,
|
264 |
+
function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
blockEditorSavePostAndReloadPage();
|
266 |
}
|
267 |
);
|
345 |
}
|
346 |
);
|
347 |
|
348 |
+
initMetaboxAutoComplete();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
}
|
350 |
);
|
351 |
|
js/build/block-editor.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";var __webpack_exports__={};const languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const{__:t}=wp.i18n,
|
1 |
+
"use strict";var __webpack_exports__={};const languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const{__:t}=wp.i18n,e=jQuery("<div/>",{id:"pll-dialog",style:"display:none;"}).text(t("Are you sure you want to change the language of the current content?","polylang"));languagesList.after(e);const a=new Promise(((a,n)=>{const l=t=>{switch(t){case"yes":languagesList.data("old-value",languagesList.children(":selected").first().val()),a();break;case"no":languagesList.val(languagesList.data("old-value")),n("Cancel")}e.dialog("close")},i={autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:t("Change language","polylang"),minWidth:600,maxWidth:"100%",open:function(t,e){jQuery("body").hasClass("rtl")&&jQuery(this).parent().css({right:jQuery(this).parent().css("left"),left:"auto"})},close:function(t,e){l("no")},buttons:[{text:t("OK","polylang"),click:function(t){l("yes")}},{text:t("Cancel","polylang"),click:function(t){l("no")}}]};jQuery.ui.version>="1.12.0"?Object.assign(i,{classes:{"ui-dialog":"pll-confirmation-modal"}}):Object.assign(i,{dialogClass:"pll-confirmation-modal"}),e.dialog(i)}));return{dialogContainer:e,dialogResult:a}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected").first().val())};function initMetaboxAutoComplete(){jQuery(".tr_lang").each((function(){var t=jQuery(this).attr("id").substring(8),e=jQuery(this).parent().parent().siblings(".pll-edit-column");jQuery(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+jQuery(".post_lang_choice").val()+"&translation_language="+t+"&post_type="+jQuery("#post_type").val()+"&_pll_nonce="+jQuery("#_pll_nonce").val(),select:function(a,n){jQuery("#htr_lang_"+t).val(n.item.id),e.html(n.item.link)}}),jQuery(this).on("blur",(function(){jQuery(this).val()||(jQuery("#htr_lang_"+t).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}function getCurrentLanguage(){const t=document.querySelector("[name=post_lang_choice]");return null===t?pllDefaultLanguage:t.value}wp.apiFetch.use((function(t,e){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()),e(t)})),jQuery((function(t){initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(e){const a=wp.data.select,n=wp.data.dispatch,l=wp.data.subscribe,i=function(){const t=wp.data.select("core/editor"),e=t.getEditedPostAttribute("title").trim(),a=t.getEditedPostAttribute("content").trim(),n=t.getEditedPostAttribute("excerpt").trim();return!e&&!a&&!n}(),o=initializeConfimationModal(),{dialogContainer:s}=o;let{dialogResult:c}=o;const u=e.target;var r;location.pathname.match(/post-new.php/gi)&&i&&(r=u.value,-1!=location.search.indexOf("new_lang")?window.location.search=window.location.search.replace(/(?:new_lang=[^&]*)(&)?(.*)/,"new_lang="+r+"$1$2"):window.location.search=window.location.search+(-1!=window.location.search.indexOf("?")?"&":"?")+"new_lang="+r),t(this).data("old-value")===u.value||i?(initializeLanguageOldValue(),c=Promise.resolve()):s.dialog("open"),c.then((()=>{let e={action:"post_lang_choice",lang:u.value,post_type:t("#post_type").val(),post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,e,(function(){!function(){let t=null;const e=new Promise((function(e,n){t=l((function(){const t=a("core/editor").didPostSaveRequestSucceed(),l=a("core/editor").didPostSaveRequestFail();(t||l)&&(l?n():e())}))}));n("core/editor").savePost(),e.then((function(){window.location.reload()}),(function(){t()})).catch((function(){t()}))}()}))}),(()=>{}))})),initMetaboxAutoComplete()}));
|
js/build/classic-editor.js
CHANGED
@@ -102,6 +102,49 @@ const initializeLanguageOldValue = () => {
|
|
102 |
languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
|
103 |
};
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
;// CONCATENATED MODULE: ./js/src/classic-editor.js
|
106 |
/**
|
107 |
* @package Polylang
|
@@ -109,6 +152,8 @@ const initializeLanguageOldValue = () => {
|
|
109 |
|
110 |
|
111 |
|
|
|
|
|
112 |
// tag suggest in metabox
|
113 |
jQuery(
|
114 |
function( $ ) {
|
@@ -247,7 +292,7 @@ jQuery(
|
|
247 |
case 'translations': // translations fields
|
248 |
// Data is built and come from server side and is well escaped when necessary
|
249 |
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
250 |
-
|
251 |
break;
|
252 |
case 'taxonomy': // categories metabox for posts
|
253 |
var tax = this.data;
|
@@ -314,45 +359,7 @@ jQuery(
|
|
314 |
}
|
315 |
);
|
316 |
|
317 |
-
|
318 |
-
function init_translations() {
|
319 |
-
$( '.tr_lang' ).each(
|
320 |
-
function(){
|
321 |
-
var tr_lang = $( this ).attr( 'id' ).substring( 8 );
|
322 |
-
var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
|
323 |
-
|
324 |
-
$( this ).autocomplete(
|
325 |
-
{
|
326 |
-
minLength: 0,
|
327 |
-
source: ajaxurl + '?action=pll_posts_not_translated' +
|
328 |
-
'&post_language=' + $( '.post_lang_choice' ).val() +
|
329 |
-
'&translation_language=' + tr_lang +
|
330 |
-
'&post_type=' + $( '#post_type' ).val() +
|
331 |
-
'&_pll_nonce=' + $( '#_pll_nonce' ).val(),
|
332 |
-
select: function( event, ui ) {
|
333 |
-
$( '#htr_lang_' + tr_lang ).val( ui.item.id );
|
334 |
-
// ui.item.link is built and come from server side and is well escaped when necessary
|
335 |
-
td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
336 |
-
},
|
337 |
-
}
|
338 |
-
);
|
339 |
-
|
340 |
-
// when the input box is emptied
|
341 |
-
$( this ).on(
|
342 |
-
'blur',
|
343 |
-
function() {
|
344 |
-
if ( ! $( this ).val() ) {
|
345 |
-
$( '#htr_lang_' + tr_lang ).val( 0 );
|
346 |
-
// Value is retrieved from HTML already generated server side
|
347 |
-
td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
348 |
-
}
|
349 |
-
}
|
350 |
-
);
|
351 |
-
}
|
352 |
-
);
|
353 |
-
}
|
354 |
-
|
355 |
-
init_translations();
|
356 |
}
|
357 |
);
|
358 |
|
102 |
languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
|
103 |
};
|
104 |
|
105 |
+
;// CONCATENATED MODULE: ./js/src/lib/metabox-autocomplete.js
|
106 |
+
/**
|
107 |
+
* @package Polylang
|
108 |
+
*/
|
109 |
+
|
110 |
+
// Translations autocomplete input box.
|
111 |
+
function initMetaboxAutoComplete() {
|
112 |
+
jQuery('.tr_lang').each(
|
113 |
+
function () {
|
114 |
+
var tr_lang = jQuery(this).attr('id').substring(8);
|
115 |
+
var td = jQuery(this).parent().parent().siblings('.pll-edit-column');
|
116 |
+
|
117 |
+
jQuery(this).autocomplete(
|
118 |
+
{
|
119 |
+
minLength: 0,
|
120 |
+
source: ajaxurl + '?action=pll_posts_not_translated' +
|
121 |
+
'&post_language=' + jQuery('.post_lang_choice').val() +
|
122 |
+
'&translation_language=' + tr_lang +
|
123 |
+
'&post_type=' + jQuery('#post_type').val() +
|
124 |
+
'&_pll_nonce=' + jQuery('#_pll_nonce').val(),
|
125 |
+
select: function (event, ui) {
|
126 |
+
jQuery('#htr_lang_' + tr_lang).val(ui.item.id);
|
127 |
+
// ui.item.link is built and come from server side and is well escaped when necessary
|
128 |
+
td.html(ui.item.link); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
129 |
+
},
|
130 |
+
}
|
131 |
+
);
|
132 |
+
|
133 |
+
// when the input box is emptied
|
134 |
+
jQuery(this).on(
|
135 |
+
'blur',
|
136 |
+
function () {
|
137 |
+
if ( ! jQuery(this).val() ) {
|
138 |
+
jQuery('#htr_lang_' + tr_lang).val(0);
|
139 |
+
// Value is retrieved from HTML already generated server side
|
140 |
+
td.html(td.siblings('.hidden').children().clone()); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
141 |
+
}
|
142 |
+
}
|
143 |
+
);
|
144 |
+
}
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
;// CONCATENATED MODULE: ./js/src/classic-editor.js
|
149 |
/**
|
150 |
* @package Polylang
|
152 |
|
153 |
|
154 |
|
155 |
+
|
156 |
+
|
157 |
// tag suggest in metabox
|
158 |
jQuery(
|
159 |
function( $ ) {
|
292 |
case 'translations': // translations fields
|
293 |
// Data is built and come from server side and is well escaped when necessary
|
294 |
$( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
|
295 |
+
initMetaboxAutoComplete();
|
296 |
break;
|
297 |
case 'taxonomy': // categories metabox for posts
|
298 |
var tax = this.data;
|
359 |
}
|
360 |
);
|
361 |
|
362 |
+
initMetaboxAutoComplete();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
}
|
364 |
);
|
365 |
|
js/build/classic-editor.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
"use strict";var __webpack_exports__={};const languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const{__:t}=wp.i18n,a=jQuery("<div/>",{id:"pll-dialog",style:"display:none;"}).text(t("Are you sure you want to change the language of the current content?","polylang"));languagesList.after(a);const e=new Promise(((e,l)=>{const n=t=>{switch(t){case"yes":languagesList.data("old-value",languagesList.children(":selected").first().val()),e();break;case"no":languagesList.val(languagesList.data("old-value")),l("Cancel")}a.dialog("close")},i={autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:t("Change language","polylang"),minWidth:600,maxWidth:"100%",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:t("OK","polylang"),click:function(t){n("yes")}},{text:t("Cancel","polylang"),click:function(t){n("no")}}]};jQuery.ui.version>="1.12.0"?Object.assign(i,{classes:{"ui-dialog":"pll-confirmation-modal"}}):Object.assign(i,{dialogClass:"pll-confirmation-modal"}),a.dialog(i)}));return{dialogContainer:a,dialogResult:e}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected").first().val())};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;
|
1 |
+
"use strict";var __webpack_exports__={};const languagesList=jQuery(".post_lang_choice"),initializeConfimationModal=()=>{const{__:t}=wp.i18n,a=jQuery("<div/>",{id:"pll-dialog",style:"display:none;"}).text(t("Are you sure you want to change the language of the current content?","polylang"));languagesList.after(a);const e=new Promise(((e,l)=>{const n=t=>{switch(t){case"yes":languagesList.data("old-value",languagesList.children(":selected").first().val()),e();break;case"no":languagesList.val(languagesList.data("old-value")),l("Cancel")}a.dialog("close")},i={autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:t("Change language","polylang"),minWidth:600,maxWidth:"100%",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:t("OK","polylang"),click:function(t){n("yes")}},{text:t("Cancel","polylang"),click:function(t){n("no")}}]};jQuery.ui.version>="1.12.0"?Object.assign(i,{classes:{"ui-dialog":"pll-confirmation-modal"}}):Object.assign(i,{dialogClass:"pll-confirmation-modal"}),a.dialog(i)}));return{dialogContainer:a,dialogResult:e}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected").first().val())};function initMetaboxAutoComplete(){jQuery(".tr_lang").each((function(){var t=jQuery(this).attr("id").substring(8),a=jQuery(this).parent().parent().siblings(".pll-edit-column");jQuery(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+jQuery(".post_lang_choice").val()+"&translation_language="+t+"&post_type="+jQuery("#post_type").val()+"&_pll_nonce="+jQuery("#_pll_nonce").val(),select:function(e,l){jQuery("#htr_lang_"+t).val(l.item.id),a.html(l.item.link)}}),jQuery(this).on("blur",(function(){jQuery(this).val()||(jQuery("#htr_lang_"+t).val(0),a.html(a.siblings(".hidden").children().clone()))}))}))}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;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(e){const l=initializeConfimationModal(),{dialogContainer:n}=l;let{dialogResult:i}=l;const o=e.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}()?i=Promise.resolve():n.dialog("open"),i.then((()=>{var e=o.options[o.options.selectedIndex].lang,l=t('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),n={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,n,(function(a){var n=wpAjax.parseAjaxResponse(a,"pll-ajax-response");t.each(n.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),initMetaboxAutoComplete();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 e=t("#edit-slug-box");"-1"!=this.data&&e.children().length&&e.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-"+l),t("#content_ifr").contents().find("html").attr("lang",e).attr("dir",l),t("#content_ifr").contents().find("body").attr("dir",l),pll.media.resetAllAttachmentsCollections()}))}),(()=>{}))})),initMetaboxAutoComplete()}));var pll=window.pll||{};_.extend(pll,{media:{}});var media=_.extend(pll.media,{attachmentsCollections:[],query:function(t){var a=pll.media.query.delegate(t);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())}))}});"undefined"!=typeof wp&&void 0!==wp.media&&(media.query=_.extend(media.query,{delegate:wp.media.query}),wp.media.query=media.query);
|
js/build/post.js
CHANGED
@@ -23,81 +23,84 @@ jQuery(
|
|
23 |
*/
|
24 |
jQuery(
|
25 |
function( $ ) {
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
33 |
-
var post_id = t.prev().attr( 'id' ).replace( "post-", "" );
|
34 |
|
35 |
if ( post_id > 0 ) {
|
36 |
-
// language dropdown
|
37 |
-
|
38 |
-
|
39 |
-
select.
|
40 |
|
41 |
-
filter_terms( lang ); //
|
42 |
-
filter_pages( lang ); //
|
43 |
|
44 |
-
//
|
45 |
-
select.
|
46 |
'change',
|
47 |
-
function() {
|
48 |
-
|
49 |
-
|
|
|
50 |
}
|
51 |
-
|
|
|
52 |
}
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
);
|
77 |
}
|
78 |
-
}
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
97 |
}
|
98 |
}
|
99 |
-
|
100 |
-
);
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
);
|
103 |
|
23 |
*/
|
24 |
jQuery(
|
25 |
function( $ ) {
|
26 |
+
const handleQuickEditInsertion = ( mutationsList ) => {
|
27 |
+
for ( const mutation of mutationsList ) {
|
28 |
+
const form = mutation.addedNodes[0];
|
29 |
+
if ( 0 < mutation.addedNodes.length && form.classList.contains( 'inline-editor' ) ) {
|
30 |
+
// WordPress has inserted the quick edit form.
|
31 |
+
const post_id = Number( form.id.substring( 5 ) );
|
|
|
|
|
32 |
|
33 |
if ( post_id > 0 ) {
|
34 |
+
// Get the language dropdown.
|
35 |
+
const select = form.querySelector( 'select[name="inline_lang_choice"]' );
|
36 |
+
const lang = document.querySelector( '#lang_' + String( post_id ) ).innerHTML;
|
37 |
+
select.value = lang; // Populates the dropdown with the post language.
|
38 |
|
39 |
+
filter_terms( lang ); // Initial filter for category checklist.
|
40 |
+
filter_pages( lang ); // Initial filter for parent dropdown.
|
41 |
|
42 |
+
// Modify category checklist and parent dropdown on language change.
|
43 |
+
select.addEventListener(
|
44 |
'change',
|
45 |
+
function( event ) {
|
46 |
+
const newLang = event.target.value;
|
47 |
+
filter_terms( newLang );
|
48 |
+
filter_pages( newLang );
|
49 |
}
|
50 |
+
);
|
51 |
+
}
|
52 |
}
|
53 |
+
/**
|
54 |
+
* Filters the category checklist.
|
55 |
+
*/
|
56 |
+
function filter_terms( lang ) {
|
57 |
+
if ( "undefined" != typeof( pll_term_languages ) ) {
|
58 |
+
$.each(
|
59 |
+
pll_term_languages,
|
60 |
+
function( lg, term_tax ) {
|
61 |
+
$.each(
|
62 |
+
term_tax,
|
63 |
+
function( tax, terms ) {
|
64 |
+
$.each(
|
65 |
+
terms,
|
66 |
+
function( i ) {
|
67 |
+
id = '#' + tax + '-' + pll_term_languages[ lg ][ tax ][ i ];
|
68 |
+
lang == lg ? $( id ).show() : $( id ).hide();
|
69 |
+
}
|
70 |
+
);
|
71 |
+
}
|
72 |
+
);
|
73 |
+
}
|
74 |
+
);
|
75 |
+
}
|
|
|
76 |
}
|
|
|
77 |
|
78 |
+
/**
|
79 |
+
* Filters the parent page dropdown list.
|
80 |
+
*/
|
81 |
+
function filter_pages( lang ) {
|
82 |
+
if ( "undefined" != typeof( pll_page_languages ) ) {
|
83 |
+
$.each(
|
84 |
+
pll_page_languages,
|
85 |
+
function( lg, pages ) {
|
86 |
+
$.each(
|
87 |
+
pages,
|
88 |
+
function( i ) {
|
89 |
+
v = $( '#post_parent option[value="' + pll_page_languages[ lg ][ i ] + '"]' );
|
90 |
+
lang == lg ? v.show() : v.hide();
|
91 |
+
}
|
92 |
+
);
|
93 |
+
}
|
94 |
+
);
|
95 |
+
}
|
96 |
}
|
97 |
}
|
98 |
+
}
|
99 |
+
const table = document.getElementById( 'the-list' );
|
100 |
+
const config = { childList: true, subtree: true };
|
101 |
+
const observer = new MutationObserver( handleQuickEditInsertion );
|
102 |
+
|
103 |
+
observer.observe( table, config);
|
104 |
}
|
105 |
);
|
106 |
|
js/build/post.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var __webpack_exports__={};jQuery((function(
|
1 |
+
var __webpack_exports__={};jQuery((function(n){n.ajaxPrefilter((function(e,t,a){"string"==typeof e.data&&-1!==e.data.indexOf("action=ajax-tag-search")&&(lang=n(':input[name="inline_lang_choice"]').val())&&(e.data="lang="+lang+"&"+e.data)}))})),jQuery((function(n){const e=document.getElementById("the-list");new MutationObserver((e=>{for(const i of e){const o=i.addedNodes[0];if(0<i.addedNodes.length&&o.classList.contains("inline-editor")){const s=Number(o.id.substring(5));if(s>0){const l=o.querySelector('select[name="inline_lang_choice"]'),c=document.querySelector("#lang_"+String(s)).innerHTML;l.value=c,t(c),a(c),l.addEventListener("change",(function(n){const e=n.target.value;t(e),a(e)}))}}function t(e){"undefined"!=typeof pll_term_languages&&n.each(pll_term_languages,(function(t,a){n.each(a,(function(a,i){n.each(i,(function(i){id="#"+a+"-"+pll_term_languages[t][a][i],e==t?n(id).show():n(id).hide()}))}))}))}function a(e){"undefined"!=typeof pll_page_languages&&n.each(pll_page_languages,(function(t,a){n.each(a,(function(a){v=n('#post_parent option[value="'+pll_page_languages[t][a]+'"]'),e==t?v.show():v.hide()}))}))}}})).observe(e,{childList:!0,subtree:!0})})),jQuery((function(n){n(document).ajaxSuccess((function(e,t,a){if("string"==typeof a.data){var i=wpAjax.unserialize(a.data);void 0!==i.action&&"inline-save"==i.action&&function(e){var t=new Array;n(".translation_"+e).each((function(){t.push(n(this).parent().parent().attr("id").substring(5))}));var a={action:"pll_update_post_rows",post_id:e,translations:t.join(","),post_type:n("input[name='post_type']").val(),screen:n("input[name='screen']").val(),_pll_nonce:n("input[name='_inline_edit']").val()};n.post(ajaxurl,a,(function(e){if(e){var t=wpAjax.parseAjaxResponse(e,"pll-ajax-response");n.each(t.responses,(function(){"row"==this.what&&n("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(n){n.ajaxPrefilter((function(e,t,a){"string"==typeof e.data&&-1!==e.data.indexOf("action=find_posts")&&(e.data="pll_post_id="+n("#affected").val()+"&"+e.data)}))}));
|
js/build/term.js
CHANGED
@@ -8,30 +8,36 @@ var __webpack_exports__ = {};
|
|
8 |
*/
|
9 |
jQuery(
|
10 |
function( $ ) {
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
if ( 'inline-edit' == t.attr( 'id' ) ) {
|
18 |
-
var term_id = t.prev().attr( 'id' ).replace( "tag-", "" );
|
19 |
|
20 |
if ( term_id > 0 ) {
|
21 |
-
// language dropdown
|
22 |
-
|
23 |
-
|
24 |
-
select.
|
25 |
|
26 |
-
//
|
27 |
-
|
28 |
if ( term_id == default_cat ) {
|
29 |
-
select.
|
30 |
}
|
31 |
}
|
32 |
}
|
33 |
}
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
);
|
37 |
|
8 |
*/
|
9 |
jQuery(
|
10 |
function( $ ) {
|
11 |
+
const handleQuickEditInsertion = ( mutationsList ) => {
|
12 |
+
for ( const mutation of mutationsList ) {
|
13 |
+
const form = mutation.addedNodes[0];
|
14 |
+
if ( 0 < mutation.addedNodes.length && form.classList.contains( 'inline-edit-row' ) ) {
|
15 |
+
// WordPress has inserted the quick edit form.
|
16 |
+
const term_id = Number( form.id.substring( 5 ) );
|
|
|
|
|
17 |
|
18 |
if ( term_id > 0 ) {
|
19 |
+
// Get the language dropdown.
|
20 |
+
const select = form.querySelector( 'select[name="inline_lang_choice"]' );
|
21 |
+
const lang = document.querySelector( '#lang_' + String( term_id ) ).innerHTML;
|
22 |
+
select.value = lang; // Populates the dropdown with the post language.
|
23 |
|
24 |
+
// Disable the language dropdown for default categories.
|
25 |
+
const default_cat = document.querySelector( `#default_cat_${term_id}` ).innerHTML;
|
26 |
if ( term_id == default_cat ) {
|
27 |
+
select.disabled = true;
|
28 |
}
|
29 |
}
|
30 |
}
|
31 |
}
|
32 |
+
}
|
33 |
+
const table = document.getElementById( 'the-list' );
|
34 |
+
if ( null !== table ) {
|
35 |
+
// Ensure the table is displayed before listening to any change.
|
36 |
+
const config = { childList: true, subtree: true };
|
37 |
+
const observer = new MutationObserver( handleQuickEditInsertion );
|
38 |
+
|
39 |
+
observer.observe( table, config);
|
40 |
+
}
|
41 |
}
|
42 |
);
|
43 |
|
js/build/term.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var __webpack_exports__={};jQuery((function(
|
1 |
+
var __webpack_exports__={};jQuery((function(t){const a=t=>{for(const a of t){const t=a.addedNodes[0];if(0<a.addedNodes.length&&t.classList.contains("inline-edit-row")){const a=Number(t.id.substring(5));if(a>0){const e=t.querySelector('select[name="inline_lang_choice"]'),n=document.querySelector("#lang_"+String(a)).innerHTML;e.value=n;a==document.querySelector(`#default_cat_${a}`).innerHTML&&(e.disabled=!0)}}}},e=document.getElementById("the-list");if(null!==e){const t={childList:!0,subtree:!0};new MutationObserver(a).observe(e,t)}})),jQuery((function(t){t(document).ajaxSuccess((function(a,e,n){function l(a){var e=new Array;t(".translation_"+a).each((function(){e.push(t(this).parent().parent().attr("id").substring(4))}));var n={action:"pll_update_term_rows",term_id:a,translations:e.join(","),taxonomy:t("input[name='taxonomy']").val(),post_type:t("input[name='post_type']").val(),screen:t("input[name='screen']").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,n,(function(a){if(a){var e=wpAjax.parseAjaxResponse(a,"pll-ajax-response");t.each(e.responses,(function(){"row"==this.what&&t("#tag-"+this.supplemental.term_id).replaceWith(this.data)}))}}))}var s=wpAjax.unserialize(n.data);if(void 0!==s.action)switch(s.action){case"add-tag":res=wpAjax.parseAjaxResponse(e.responseXML,"pll-ajax-response"),t.each(res.responses,(function(){"term"==this.what&&l(this.supplemental.term_id)})),t(".htr_lang").val(0);break;case"delete-tag":l(s.tag_ID);break;case"inline-save-tax":l(s.tax_ID)}}))})),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_terms_not_translated&term_language="+t("#term_lang_choice").val()+"&term_id="+t("input[name='tag_ID']").val()+"&taxonomy="+t("input[name='taxonomy']").val()+"&translation_language="+a+"&post_type="+typenow+"&_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()))}))}))}a(),t("#term_lang_choice").on("change",(function(){var e=t(this).val(),n=t(this).children('option[value="'+e+'"]').attr("lang"),l=t('.pll-translation-column > span[lang="'+n+'"]').attr("dir"),s={action:"term_lang_choice",lang:e,from_tag:t("input[name='from_tag']").val(),term_id:t("input[name='tag_ID']").val(),taxonomy:t("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,s,(function(e){var n=wpAjax.parseAjaxResponse(e,"pll-ajax-response");t.each(n.responses,(function(){switch(this.what){case"translations":t("#term-translations").html(this.data),a();break;case"parent":t("#parent").replaceWith(this.data);break;case"tag_cloud":t(".tagcloud").replaceWith(this.data);break;case"flag":t(".pll-select-flag").html(this.data)}})),t("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)}))}))}));
|
modules/site-health/admin-site-health.php
CHANGED
@@ -25,7 +25,7 @@ class PLL_Admin_Site_Health {
|
|
25 |
*
|
26 |
* @since 2.8
|
27 |
*
|
28 |
-
* @var PLL_Admin_Static_Pages
|
29 |
*/
|
30 |
protected $static_pages;
|
31 |
|
@@ -104,10 +104,83 @@ class PLL_Admin_Site_Health {
|
|
104 |
}
|
105 |
}
|
106 |
);
|
107 |
-
|
108 |
return implode( ' | ', $array );
|
109 |
}
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
/**
|
112 |
* Add Polylang Options to Site Health Informations tab.
|
113 |
*
|
@@ -118,56 +191,59 @@ class PLL_Admin_Site_Health {
|
|
118 |
*/
|
119 |
public function info_options( $debug_info ) {
|
120 |
$fields = array();
|
|
|
121 |
foreach ( $this->model->options as $key => $value ) {
|
122 |
if ( in_array( $key, $this->exclude_options_keys() ) ) {
|
123 |
continue;
|
124 |
}
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
130 |
|
131 |
-
$fields[ $key ]['label'] = $key;
|
132 |
-
$fields[ $key ]['value'] = $value;
|
133 |
-
} elseif ( empty( $value ) ) {
|
134 |
-
$fields[ $key ]['label'] = $key;
|
135 |
-
$fields[ $key ]['value'] = '0';
|
136 |
-
} else {
|
137 |
-
switch ( $key ) {
|
138 |
-
case 'post_types':
|
139 |
-
$fields[ $key ]['label'] = $key;
|
140 |
-
$fields[ $key ]['value'] = implode( ', ', $this->model->get_translated_post_types() );
|
141 |
-
break;
|
142 |
-
case 'taxonomies':
|
143 |
-
$fields[ $key ]['label'] = $key;
|
144 |
-
$fields[ $key ]['value'] = implode( ', ', $this->model->get_translated_taxonomies() );
|
145 |
-
break;
|
146 |
-
case 'domains':
|
147 |
$fields[ $key ]['label'] = $key;
|
148 |
-
$fields[ $key ]['value'] = $
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
case 'media':
|
161 |
-
foreach ( $value as $sub_key => $sub_value ) {
|
162 |
-
$fields[ "$key-$sub_key" ]['label'] = "$key $sub_key";
|
163 |
-
$fields[ "$key-$sub_key" ]['value'] = $sub_value;
|
164 |
}
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
172 |
}
|
173 |
|
@@ -192,7 +268,7 @@ class PLL_Admin_Site_Health {
|
|
192 |
foreach ( $this->model->get_languages_list() as $language ) {
|
193 |
$fields = array();
|
194 |
|
195 |
-
foreach ( $language as $key => $value ) {
|
196 |
if ( in_array( $key, $this->exclude_language_keys(), true ) ) {
|
197 |
continue;
|
198 |
}
|
25 |
*
|
26 |
* @since 2.8
|
27 |
*
|
28 |
+
* @var PLL_Admin_Static_Pages|null
|
29 |
*/
|
30 |
protected $static_pages;
|
31 |
|
104 |
}
|
105 |
}
|
106 |
);
|
|
|
107 |
return implode( ' | ', $array );
|
108 |
}
|
109 |
|
110 |
+
/**
|
111 |
+
* Transforms the option value to readable human sentence.
|
112 |
+
*
|
113 |
+
* @since 3.3
|
114 |
+
*
|
115 |
+
* @param string $key Option name.
|
116 |
+
* @param mixed $value Option value.
|
117 |
+
* @return mixed Option value.
|
118 |
+
*/
|
119 |
+
public function format_value( $key, $value ) {
|
120 |
+
switch ( $key ) {
|
121 |
+
case 'browser':
|
122 |
+
if ( ! $value ) {
|
123 |
+
$value = '0: ' . esc_html__( 'Detect browser language deactivated', 'polylang' );
|
124 |
+
break;
|
125 |
+
}
|
126 |
+
$value = '1: ' . esc_html__( 'Detect browser language activated', 'polylang' );
|
127 |
+
break;
|
128 |
+
case 'rewrite':
|
129 |
+
if ( $value ) {
|
130 |
+
$value = '1: ' . esc_html__( 'Remove /language/ in pretty permalinks', 'polylang' );
|
131 |
+
break;
|
132 |
+
}
|
133 |
+
$value = '0: ' . esc_html__( 'Keep /language/ in pretty permalinks', 'polylang' );
|
134 |
+
break;
|
135 |
+
case 'hide_default':
|
136 |
+
if ( $value ) {
|
137 |
+
$value = '1: ' . esc_html__( 'Hide URL language information for default language', 'polylang' );
|
138 |
+
break;
|
139 |
+
}
|
140 |
+
$value = '0: ' . esc_html__( 'Display URL language information for default language', 'polylang' );
|
141 |
+
break;
|
142 |
+
case 'force_lang':
|
143 |
+
switch ( $value ) {
|
144 |
+
case '0':
|
145 |
+
$value = '0: ' . esc_html__( 'The language is set from content', 'polylang' );
|
146 |
+
break;
|
147 |
+
case '1':
|
148 |
+
$value = '1: ' . esc_html__( 'The language is set from the directory name in pretty permalinks', 'polylang' );
|
149 |
+
break;
|
150 |
+
case '2':
|
151 |
+
$value = '2: ' . esc_html__( 'The language is set from the subdomain name in pretty permalinks', 'polylang' );
|
152 |
+
break;
|
153 |
+
case '3':
|
154 |
+
$value = '3: ' . esc_html__( 'The language is set from different domains', 'polylang' );
|
155 |
+
break;
|
156 |
+
}
|
157 |
+
break;
|
158 |
+
case 'redirect_lang':
|
159 |
+
if ( $value ) {
|
160 |
+
$value = '1: ' . esc_html__( 'The front page URL contains the language code instead of the page name or page id', 'polylang' );
|
161 |
+
break;
|
162 |
+
}
|
163 |
+
$value = '0: ' . esc_html__( 'The front page URL contains the page name or page id instead of the language code', 'polylang' );
|
164 |
+
|
165 |
+
break;
|
166 |
+
case 'media_support':
|
167 |
+
if ( ! $value ) {
|
168 |
+
$value = '0: ' . esc_html__( 'The media are not translated', 'polylang' );
|
169 |
+
break;
|
170 |
+
}
|
171 |
+
$value = '1: ' . esc_html__( 'The media are translated', 'polylang' );
|
172 |
+
break;
|
173 |
+
|
174 |
+
case 'sync':
|
175 |
+
if ( empty( $value ) ) {
|
176 |
+
$value = '0: ' . esc_html__( 'Synchronization disabled', 'polylang' );
|
177 |
+
}
|
178 |
+
break;
|
179 |
+
}
|
180 |
+
|
181 |
+
return $value;
|
182 |
+
}
|
183 |
+
|
184 |
/**
|
185 |
* Add Polylang Options to Site Health Informations tab.
|
186 |
*
|
191 |
*/
|
192 |
public function info_options( $debug_info ) {
|
193 |
$fields = array();
|
194 |
+
|
195 |
foreach ( $this->model->options as $key => $value ) {
|
196 |
if ( in_array( $key, $this->exclude_options_keys() ) ) {
|
197 |
continue;
|
198 |
}
|
199 |
|
200 |
+
$value = $this->format_value( $key, $value );
|
201 |
+
|
202 |
+
switch ( $key ) {
|
203 |
+
case 'domains':
|
204 |
+
if ( 3 === $this->model->options['force_lang'] ) {
|
205 |
+
$value = is_array( $value ) ? $value : array();
|
206 |
+
$value = $this->format_array( $value );
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
$fields[ $key ]['label'] = $key;
|
209 |
+
$fields[ $key ]['value'] = $value;
|
210 |
+
}
|
211 |
+
break;
|
212 |
+
|
213 |
+
case 'nav_menus':
|
214 |
+
$current_theme = get_stylesheet();
|
215 |
+
if ( is_array( $value ) && isset( $value[ $current_theme ] ) ) {
|
216 |
+
foreach ( $value[ $current_theme ] as $location => $lang ) {
|
217 |
+
$lang = is_array( $lang ) ? $lang : array();
|
218 |
+
|
219 |
+
$fields[ $location ]['label'] = sprintf( 'menu: %s', $location );
|
220 |
+
$fields[ $location ]['value'] = $this->format_array( $lang );
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
+
}
|
223 |
+
break;
|
224 |
+
|
225 |
+
case 'media':
|
226 |
+
$value = is_array( $value ) ? $value : array();
|
227 |
+
foreach ( $value as $sub_key => $sub_value ) {
|
228 |
+
$fields[ "$key-$sub_key" ]['label'] = "$key $sub_key";
|
229 |
+
$fields[ "$key-$sub_key" ]['value'] = $sub_value;
|
230 |
+
}
|
231 |
+
break;
|
232 |
+
|
233 |
+
case 'post_types':
|
234 |
+
$fields[ $key ]['label'] = $key;
|
235 |
+
$fields[ $key ]['value'] = implode( ', ', $this->model->get_translated_post_types() );
|
236 |
+
break;
|
237 |
+
|
238 |
+
case 'taxonomies':
|
239 |
+
$fields[ $key ]['label'] = $key;
|
240 |
+
$fields[ $key ]['value'] = implode( ', ', $this->model->get_translated_taxonomies() );
|
241 |
+
break;
|
242 |
+
|
243 |
+
default:
|
244 |
+
$fields[ $key ]['label'] = $key;
|
245 |
+
$fields[ $key ]['value'] = empty( $value ) ? '0' : $value;
|
246 |
+
break;
|
247 |
}
|
248 |
}
|
249 |
|
268 |
foreach ( $this->model->get_languages_list() as $language ) {
|
269 |
$fields = array();
|
270 |
|
271 |
+
foreach ( get_object_vars( $language ) as $key => $value ) {
|
272 |
if ( in_array( $key, $this->exclude_language_keys(), true ) ) {
|
273 |
continue;
|
274 |
}
|
modules/sitemaps/sitemaps.php
CHANGED
@@ -71,19 +71,6 @@ class PLL_Sitemaps extends PLL_Abstract_Sitemaps {
|
|
71 |
return $lang;
|
72 |
}
|
73 |
|
74 |
-
/**
|
75 |
-
* Whitelists the home url filter for the sitemaps
|
76 |
-
*
|
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' );
|
84 |
-
return $whitelist;
|
85 |
-
}
|
86 |
-
|
87 |
/**
|
88 |
* Filters the sitemaps rewrite rules to take the languages into account.
|
89 |
*
|
71 |
return $lang;
|
72 |
}
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
/**
|
75 |
* Filters the sitemaps rewrite rules to take the languages into account.
|
76 |
*
|
modules/sync/sync-metas.php
CHANGED
@@ -26,14 +26,14 @@ abstract class PLL_Sync_Metas {
|
|
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
|
@@ -62,7 +62,7 @@ abstract class PLL_Sync_Metas {
|
|
62 |
* @return void
|
63 |
*/
|
64 |
protected function remove_add_meta_action() {
|
65 |
-
remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' )
|
66 |
}
|
67 |
|
68 |
/**
|
@@ -75,11 +75,11 @@ abstract class PLL_Sync_Metas {
|
|
75 |
protected function remove_all_meta_actions() {
|
76 |
$this->remove_add_meta_action();
|
77 |
|
78 |
-
remove_filter( "update_{$this->meta_type}_metadata", array( $this, 'update_metadata' ), 999
|
79 |
-
remove_action( "update_{$this->meta_type}_meta", array( $this, 'update_meta' )
|
80 |
|
81 |
-
remove_action( "delete_{$this->meta_type}_meta", array( $this, 'store_metas_to_sync' )
|
82 |
-
remove_action( "deleted_{$this->meta_type}_meta", array( $this, 'delete_meta' )
|
83 |
}
|
84 |
|
85 |
/**
|
@@ -255,6 +255,7 @@ abstract class PLL_Sync_Metas {
|
|
255 |
*/
|
256 |
public function update_meta( $mid, $id, $meta_key, $meta_value ) {
|
257 |
static $avoid_recursion = false;
|
|
|
258 |
|
259 |
if ( ! $avoid_recursion ) {
|
260 |
$avoid_recursion = true;
|
26 |
*
|
27 |
* @var array
|
28 |
*/
|
29 |
+
protected $prev_value = array();
|
30 |
|
31 |
/**
|
32 |
* Stores the metas to synchronize before deleting them.
|
33 |
*
|
34 |
* @var array
|
35 |
*/
|
36 |
+
protected $to_copy = array();
|
37 |
|
38 |
/**
|
39 |
* Constructor
|
62 |
* @return void
|
63 |
*/
|
64 |
protected function remove_add_meta_action() {
|
65 |
+
remove_action( "added_{$this->meta_type}_meta", array( $this, 'add_meta' ) );
|
66 |
}
|
67 |
|
68 |
/**
|
75 |
protected function remove_all_meta_actions() {
|
76 |
$this->remove_add_meta_action();
|
77 |
|
78 |
+
remove_filter( "update_{$this->meta_type}_metadata", array( $this, 'update_metadata' ), 999 );
|
79 |
+
remove_action( "update_{$this->meta_type}_meta", array( $this, 'update_meta' ) );
|
80 |
|
81 |
+
remove_action( "delete_{$this->meta_type}_meta", array( $this, 'store_metas_to_sync' ) );
|
82 |
+
remove_action( "deleted_{$this->meta_type}_meta", array( $this, 'delete_meta' ) );
|
83 |
}
|
84 |
|
85 |
/**
|
255 |
*/
|
256 |
public function update_meta( $mid, $id, $meta_key, $meta_value ) {
|
257 |
static $avoid_recursion = false;
|
258 |
+
$id = (int) $id;
|
259 |
|
260 |
if ( ! $avoid_recursion ) {
|
261 |
$avoid_recursion = true;
|
modules/sync/sync-tax.php
CHANGED
@@ -211,7 +211,7 @@ class PLL_Sync_Tax {
|
|
211 |
* @return void
|
212 |
*/
|
213 |
public function copy( $from, $to, $lang ) {
|
214 |
-
remove_action( 'set_object_terms', array( $this, 'set_object_terms' )
|
215 |
|
216 |
// Get taxonomies to sync for this post type
|
217 |
$taxonomies = array_intersect( get_post_taxonomies( $from ), $this->get_taxonomies_to_copy( false, $from, $to, $lang ) );
|
@@ -295,7 +295,7 @@ class PLL_Sync_Tax {
|
|
295 |
* @return void
|
296 |
*/
|
297 |
public function pre_delete_term() {
|
298 |
-
remove_action( 'set_object_terms', array( $this, 'set_object_terms' )
|
299 |
}
|
300 |
|
301 |
/**
|
211 |
* @return void
|
212 |
*/
|
213 |
public function copy( $from, $to, $lang ) {
|
214 |
+
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ) );
|
215 |
|
216 |
// Get taxonomies to sync for this post type
|
217 |
$taxonomies = array_intersect( get_post_taxonomies( $from ), $this->get_taxonomies_to_copy( false, $from, $to, $lang ) );
|
295 |
* @return void
|
296 |
*/
|
297 |
public function pre_delete_term() {
|
298 |
+
remove_action( 'set_object_terms', array( $this, 'set_object_terms' ) );
|
299 |
}
|
300 |
|
301 |
/**
|
modules/sync/sync.php
CHANGED
@@ -212,7 +212,7 @@ class PLL_Sync {
|
|
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 ),
|
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 && ! ( $term->parent && empty( $tr_parent ) ) ) {
|
216 |
$wpdb->update(
|
217 |
$wpdb->term_taxonomy,
|
218 |
array( 'parent' => $tr_parent ? $tr_parent : 0 ),
|
modules/wizard/wizard.php
CHANGED
@@ -39,7 +39,7 @@ class PLL_Wizard {
|
|
39 |
/**
|
40 |
* The current step.
|
41 |
*
|
42 |
-
* @var string
|
43 |
*/
|
44 |
protected $step;
|
45 |
|
39 |
/**
|
40 |
* The current step.
|
41 |
*
|
42 |
+
* @var string|null
|
43 |
*/
|
44 |
protected $step;
|
45 |
|
modules/wpml/wpml-api.php
CHANGED
@@ -15,7 +15,7 @@ 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 |
|
15 |
/**
|
16 |
* Stores the original language when the language is switched.
|
17 |
*
|
18 |
+
* @var PLL_Language|null
|
19 |
*/
|
20 |
private static $original_language = null;
|
21 |
|
modules/wpml/wpml-compat.php
CHANGED
@@ -14,7 +14,7 @@ class PLL_WPML_Compat {
|
|
14 |
/**
|
15 |
* Singleton instance
|
16 |
*
|
17 |
-
* @var PLL_WPML_Compat
|
18 |
*/
|
19 |
protected static $instance;
|
20 |
|
14 |
/**
|
15 |
* Singleton instance
|
16 |
*
|
17 |
+
* @var PLL_WPML_Compat|null
|
18 |
*/
|
19 |
protected static $instance;
|
20 |
|
modules/wpml/wpml-config.php
CHANGED
@@ -14,7 +14,7 @@ class PLL_WPML_Config {
|
|
14 |
/**
|
15 |
* Singleton instance
|
16 |
*
|
17 |
-
* @var PLL_WPML_Config
|
18 |
*/
|
19 |
protected static $instance;
|
20 |
|
@@ -23,15 +23,24 @@ class PLL_WPML_Config {
|
|
23 |
*
|
24 |
* @var SimpleXMLElement[]
|
25 |
*/
|
26 |
-
protected $xmls;
|
27 |
|
28 |
/**
|
29 |
-
* The list of xml
|
30 |
*
|
31 |
-
* @var string[]
|
|
|
|
|
32 |
*/
|
33 |
protected $files;
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
/**
|
36 |
* Constructor
|
37 |
*
|
@@ -66,96 +75,94 @@ class PLL_WPML_Config {
|
|
66 |
*/
|
67 |
public function init() {
|
68 |
$this->xmls = array();
|
69 |
-
$files
|
70 |
|
71 |
-
if (
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
81 |
}
|
82 |
}
|
83 |
|
84 |
-
if (
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
111 |
}
|
112 |
}
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
-
*
|
117 |
*
|
118 |
* @since 3.1
|
119 |
*
|
120 |
-
* @return array
|
|
|
|
|
121 |
*/
|
122 |
public function get_files() {
|
123 |
-
|
124 |
-
if ( ! empty( $this->files ) ) {
|
125 |
return $this->files;
|
126 |
}
|
127 |
|
128 |
-
$files =
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
// Theme
|
142 |
-
if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) ) {
|
143 |
-
$files[ get_template() ] = $file;
|
144 |
-
}
|
145 |
-
|
146 |
-
// Child theme
|
147 |
-
if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) ) {
|
148 |
-
$files[ get_stylesheet() ] = $file;
|
149 |
-
}
|
150 |
-
|
151 |
-
// Custom
|
152 |
-
if ( file_exists( $file = PLL_LOCAL_DIR . '/wpml-config.xml' ) ) {
|
153 |
-
$files['Polylang'] = $file;
|
154 |
-
}
|
155 |
-
|
156 |
-
$this->files = $files;
|
157 |
|
158 |
-
return $files;
|
159 |
}
|
160 |
|
161 |
/**
|
@@ -170,17 +177,22 @@ class PLL_WPML_Config {
|
|
170 |
public function copy_post_metas( $metas, $sync ) {
|
171 |
foreach ( $this->xmls as $xml ) {
|
172 |
$cfs = $xml->xpath( 'custom-fields/custom-field' );
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
|
|
|
|
|
|
|
|
181 |
}
|
182 |
}
|
183 |
}
|
|
|
184 |
return $metas;
|
185 |
}
|
186 |
|
@@ -196,20 +208,143 @@ class PLL_WPML_Config {
|
|
196 |
public function copy_term_metas( $metas, $sync ) {
|
197 |
foreach ( $this->xmls as $xml ) {
|
198 |
$cfs = $xml->xpath( 'custom-term-fields/custom-term-field' );
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
}
|
209 |
}
|
|
|
210 |
return $metas;
|
211 |
}
|
212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
/**
|
214 |
* Language and translation management for custom post types.
|
215 |
*
|
@@ -222,17 +357,22 @@ class PLL_WPML_Config {
|
|
222 |
public function translate_types( $types, $hide ) {
|
223 |
foreach ( $this->xmls as $xml ) {
|
224 |
$pts = $xml->xpath( 'custom-types/custom-type' );
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
233 |
}
|
234 |
}
|
235 |
}
|
|
|
236 |
return $types;
|
237 |
}
|
238 |
|
@@ -248,20 +388,126 @@ class PLL_WPML_Config {
|
|
248 |
public function translate_taxonomies( $taxonomies, $hide ) {
|
249 |
foreach ( $this->xmls as $xml ) {
|
250 |
$taxos = $xml->xpath( 'taxonomies/taxonomy' );
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
|
|
|
|
|
|
|
|
259 |
}
|
260 |
}
|
261 |
}
|
|
|
262 |
return $taxonomies;
|
263 |
}
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
/**
|
266 |
* Registers or translates the strings for an option
|
267 |
*
|
@@ -281,23 +527,193 @@ class PLL_WPML_Config {
|
|
281 |
* Recursively transforms xml nodes to an array, ready for PLL_Translate_Option.
|
282 |
*
|
283 |
* @since 2.9
|
|
|
|
|
|
|
284 |
*
|
285 |
-
* @param SimpleXMLElement $key
|
286 |
-
* @param array $arr
|
|
|
287 |
* @return array
|
288 |
*/
|
289 |
-
protected function xml_to_array( $key,
|
290 |
-
$
|
291 |
-
|
|
|
|
|
|
|
|
|
292 |
$children = $key->children();
|
293 |
|
294 |
if ( count( $children ) ) {
|
295 |
foreach ( $children as $child ) {
|
296 |
-
$arr[ $name ]
|
|
|
|
|
|
|
|
|
297 |
}
|
298 |
} else {
|
299 |
-
$arr[ $name ] =
|
300 |
}
|
|
|
301 |
return $arr;
|
302 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
}
|
14 |
/**
|
15 |
* Singleton instance
|
16 |
*
|
17 |
+
* @var PLL_WPML_Config|null
|
18 |
*/
|
19 |
protected static $instance;
|
20 |
|
23 |
*
|
24 |
* @var SimpleXMLElement[]
|
25 |
*/
|
26 |
+
protected $xmls = array();
|
27 |
|
28 |
/**
|
29 |
+
* The list of xml file paths.
|
30 |
*
|
31 |
+
* @var string[]|null
|
32 |
+
*
|
33 |
+
* @phpstan-var array<string, string>|null
|
34 |
*/
|
35 |
protected $files;
|
36 |
|
37 |
+
/**
|
38 |
+
* List of rules to extract strings to translate from blocks.
|
39 |
+
*
|
40 |
+
* @var string[][][]|null
|
41 |
+
*/
|
42 |
+
protected $parsing_rules = null;
|
43 |
+
|
44 |
/**
|
45 |
* Constructor
|
46 |
*
|
75 |
*/
|
76 |
public function init() {
|
77 |
$this->xmls = array();
|
78 |
+
$files = $this->get_files();
|
79 |
|
80 |
+
if ( empty( $files ) ) {
|
81 |
+
return;
|
82 |
+
}
|
83 |
|
84 |
+
if ( ! extension_loaded( 'simplexml' ) ) {
|
85 |
+
return;
|
86 |
+
}
|
87 |
+
|
88 |
+
// Read all files.
|
89 |
+
foreach ( $files as $context => $file ) {
|
90 |
+
$xml = simplexml_load_file( $file );
|
91 |
+
if ( false !== $xml ) {
|
92 |
+
$this->xmls[ $context ] = $xml;
|
93 |
}
|
94 |
}
|
95 |
|
96 |
+
if ( empty( $this->xmls ) ) {
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
|
100 |
+
add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 20, 2 );
|
101 |
+
add_filter( 'pll_copy_term_metas', array( $this, 'copy_term_metas' ), 20, 2 );
|
102 |
+
add_filter( 'pll_get_post_types', array( $this, 'translate_types' ), 10, 2 );
|
103 |
+
add_filter( 'pll_get_taxonomies', array( $this, 'translate_taxonomies' ), 10, 2 );
|
104 |
+
add_filter( 'pll_blocks_xpath_rules', array( $this, 'translate_blocks' ) );
|
105 |
+
add_filter( 'pll_blocks_rules_for_attributes', array( $this, 'translate_blocks_attributes' ) );
|
106 |
+
|
107 |
+
// Export.
|
108 |
+
add_filter( 'pll_post_metas_to_export', array( $this, 'post_metas_to_export' ) );
|
109 |
+
add_filter( 'pll_term_metas_to_export', array( $this, 'term_metas_to_export' ) );
|
110 |
+
|
111 |
+
foreach ( $this->xmls as $context => $xml ) {
|
112 |
+
$keys = $xml->xpath( 'admin-texts/key' );
|
113 |
+
|
114 |
+
if ( ! is_array( $keys ) ) {
|
115 |
+
continue;
|
116 |
+
}
|
117 |
+
|
118 |
+
foreach ( $keys as $key ) {
|
119 |
+
$name = $this->get_field_attribute( $key, 'name' );
|
120 |
+
|
121 |
+
if ( false === strpos( $name, '*' ) ) {
|
122 |
+
$this->register_or_translate_option( $context, $name, $key );
|
123 |
+
continue;
|
124 |
+
}
|
125 |
+
|
126 |
+
$pattern = '#^' . str_replace( '*', '(?:.+)', $name ) . '$#';
|
127 |
+
$names = preg_grep( $pattern, array_keys( wp_load_alloptions() ) );
|
128 |
+
|
129 |
+
if ( ! is_array( $names ) ) {
|
130 |
+
continue;
|
131 |
+
}
|
132 |
+
|
133 |
+
foreach ( $names as $_name ) {
|
134 |
+
$this->register_or_translate_option( $context, $_name, $key );
|
135 |
}
|
136 |
}
|
137 |
}
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* Returns all wpml-config.xml files in MU plugins, plugins, theme, child theme, and Polylang custom directory.
|
142 |
*
|
143 |
* @since 3.1
|
144 |
*
|
145 |
+
* @return string[] A context identifier as array key, a file path as array value.
|
146 |
+
*
|
147 |
+
* @phpstan-return array<string, string>
|
148 |
*/
|
149 |
public function get_files() {
|
150 |
+
if ( is_array( $this->files ) ) {
|
|
|
151 |
return $this->files;
|
152 |
}
|
153 |
|
154 |
+
$this->files = array_merge(
|
155 |
+
// Plugins.
|
156 |
+
$this->get_plugin_files(),
|
157 |
+
// Theme and child theme.
|
158 |
+
$this->get_theme_files(),
|
159 |
+
// MU Plugins.
|
160 |
+
$this->get_mu_plugin_files(),
|
161 |
+
// Custom.
|
162 |
+
$this->get_custom_files()
|
163 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
+
return $this->files;
|
166 |
}
|
167 |
|
168 |
/**
|
177 |
public function copy_post_metas( $metas, $sync ) {
|
178 |
foreach ( $this->xmls as $xml ) {
|
179 |
$cfs = $xml->xpath( 'custom-fields/custom-field' );
|
180 |
+
|
181 |
+
if ( ! is_array( $cfs ) ) {
|
182 |
+
continue;
|
183 |
+
}
|
184 |
+
|
185 |
+
foreach ( $cfs as $cf ) {
|
186 |
+
$action = $this->get_field_attribute( $cf, 'action' );
|
187 |
+
|
188 |
+
if ( 'copy' === $action || ( ! $sync && in_array( $action, array( 'translate', 'copy-once' ), true ) ) ) {
|
189 |
+
$metas[] = (string) $cf;
|
190 |
+
} else {
|
191 |
+
$metas = array_diff( $metas, array( (string) $cf ) );
|
192 |
}
|
193 |
}
|
194 |
}
|
195 |
+
|
196 |
return $metas;
|
197 |
}
|
198 |
|
208 |
public function copy_term_metas( $metas, $sync ) {
|
209 |
foreach ( $this->xmls as $xml ) {
|
210 |
$cfs = $xml->xpath( 'custom-term-fields/custom-term-field' );
|
211 |
+
|
212 |
+
if ( ! is_array( $cfs ) ) {
|
213 |
+
continue;
|
214 |
+
}
|
215 |
+
|
216 |
+
foreach ( $cfs as $cf ) {
|
217 |
+
$action = $this->get_field_attribute( $cf, 'action' );
|
218 |
+
|
219 |
+
if ( 'copy' === $action || ( ! $sync && in_array( $action, array( 'translate', 'copy-once' ), true ) ) ) {
|
220 |
+
$metas[] = (string) $cf;
|
221 |
+
} else {
|
222 |
+
$metas = array_diff( $metas, array( (string) $cf ) );
|
223 |
}
|
224 |
}
|
225 |
}
|
226 |
+
|
227 |
return $metas;
|
228 |
}
|
229 |
|
230 |
+
/**
|
231 |
+
* Adds post meta keys to export.
|
232 |
+
*
|
233 |
+
* @since 3.3
|
234 |
+
* @see PLL_Export_Metas
|
235 |
+
*
|
236 |
+
* @param array $keys {
|
237 |
+
* A recursive array containing nested meta sub-keys to translate.
|
238 |
+
* Ex: array(
|
239 |
+
* 'meta_to_translate_1' => 1,
|
240 |
+
* 'meta_to_translate_2' => 1,
|
241 |
+
* 'meta_to_translate_3' => array(
|
242 |
+
* 'sub_key_to_translate_1' => 1,
|
243 |
+
* 'sub_key_to_translate_2' => array(
|
244 |
+
* 'sub_sub_key_to_translate_1' => 1,
|
245 |
+
* ),
|
246 |
+
* ),
|
247 |
+
* )
|
248 |
+
* }
|
249 |
+
* @return array
|
250 |
+
*
|
251 |
+
* @phpstan-param array<string, mixed> $keys
|
252 |
+
* @phpstan-return array<string, mixed>
|
253 |
+
*/
|
254 |
+
public function post_metas_to_export( $keys ) {
|
255 |
+
// Add keys that have the `action` attribute set to `translate`.
|
256 |
+
foreach ( $this->xmls as $xml ) {
|
257 |
+
$fields = $xml->xpath( 'custom-fields/custom-field' );
|
258 |
+
|
259 |
+
if ( ! is_array( $fields ) ) {
|
260 |
+
// No custom fields.
|
261 |
+
continue;
|
262 |
+
}
|
263 |
+
|
264 |
+
foreach ( $fields as $field ) {
|
265 |
+
$action = $this->get_field_attribute( $field, 'action' );
|
266 |
+
|
267 |
+
if ( 'translate' !== $action ) {
|
268 |
+
continue;
|
269 |
+
}
|
270 |
+
|
271 |
+
$keys[ (string) $field ] = 1;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
// Deal with sub-field translations.
|
276 |
+
foreach ( $this->xmls as $xml ) {
|
277 |
+
$fields = $xml->xpath( 'custom-fields-texts/key' );
|
278 |
+
|
279 |
+
if ( ! is_array( $fields ) ) {
|
280 |
+
// No 'custom-fields-texts' nodes.
|
281 |
+
continue;
|
282 |
+
}
|
283 |
+
|
284 |
+
foreach ( $fields as $field ) {
|
285 |
+
$name = $this->get_field_attribute( $field, 'name' );
|
286 |
+
|
287 |
+
if ( '' === $name ) {
|
288 |
+
// Wrong configuration: empty `name` attribute (meta name).
|
289 |
+
continue;
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( ! array_key_exists( $name, $keys ) ) {
|
293 |
+
// Wrong configuration: the field is not in `custom-fields/custom-field`.
|
294 |
+
continue;
|
295 |
+
}
|
296 |
+
|
297 |
+
$keys = $this->xml_to_array( $field, $keys, 1 );
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
return $keys;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Adds term meta keys to export.
|
306 |
+
* Note: sub-key translations are not currently supported by WPML.
|
307 |
+
*
|
308 |
+
* @since 3.3
|
309 |
+
* @see PLL_Export_Metas
|
310 |
+
*
|
311 |
+
* @param array $keys {
|
312 |
+
* An array containing meta keys to translate.
|
313 |
+
* Ex: array(
|
314 |
+
* 'meta_to_translate_1' => 1,
|
315 |
+
* 'meta_to_translate_2' => 1,
|
316 |
+
* 'meta_to_translate_3' => 1,
|
317 |
+
* )
|
318 |
+
* }
|
319 |
+
* @return array
|
320 |
+
*
|
321 |
+
* @phpstan-param array<string, mixed> $keys
|
322 |
+
* @phpstan-return array<string, mixed>
|
323 |
+
*/
|
324 |
+
public function term_metas_to_export( $keys ) {
|
325 |
+
// Add keys that have the `action` attribute set to `translate`.
|
326 |
+
foreach ( $this->xmls as $xml ) {
|
327 |
+
$fields = $xml->xpath( 'custom-term-fields/custom-term-field' );
|
328 |
+
|
329 |
+
if ( ! is_array( $fields ) ) {
|
330 |
+
// No custom fields.
|
331 |
+
continue;
|
332 |
+
}
|
333 |
+
|
334 |
+
foreach ( $fields as $field ) {
|
335 |
+
$action = $this->get_field_attribute( $field, 'action' );
|
336 |
+
|
337 |
+
if ( 'translate' !== $action ) {
|
338 |
+
continue;
|
339 |
+
}
|
340 |
+
|
341 |
+
$keys[ (string) $field ] = 1;
|
342 |
+
}
|
343 |
+
}
|
344 |
+
|
345 |
+
return $keys;
|
346 |
+
}
|
347 |
+
|
348 |
/**
|
349 |
* Language and translation management for custom post types.
|
350 |
*
|
357 |
public function translate_types( $types, $hide ) {
|
358 |
foreach ( $this->xmls as $xml ) {
|
359 |
$pts = $xml->xpath( 'custom-types/custom-type' );
|
360 |
+
|
361 |
+
if ( ! is_array( $pts ) ) {
|
362 |
+
continue;
|
363 |
+
}
|
364 |
+
|
365 |
+
foreach ( $pts as $pt ) {
|
366 |
+
$translate = $this->get_field_attribute( $pt, 'translate' );
|
367 |
+
|
368 |
+
if ( '1' === $translate && ! $hide ) {
|
369 |
+
$types[ (string) $pt ] = (string) $pt;
|
370 |
+
} else {
|
371 |
+
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
|
372 |
}
|
373 |
}
|
374 |
}
|
375 |
+
|
376 |
return $types;
|
377 |
}
|
378 |
|
388 |
public function translate_taxonomies( $taxonomies, $hide ) {
|
389 |
foreach ( $this->xmls as $xml ) {
|
390 |
$taxos = $xml->xpath( 'taxonomies/taxonomy' );
|
391 |
+
|
392 |
+
if ( ! is_array( $taxos ) ) {
|
393 |
+
continue;
|
394 |
+
}
|
395 |
+
|
396 |
+
foreach ( $taxos as $tax ) {
|
397 |
+
$translate = $this->get_field_attribute( $tax, 'translate' );
|
398 |
+
|
399 |
+
if ( '1' === $translate && ! $hide ) {
|
400 |
+
$taxonomies[ (string) $tax ] = (string) $tax;
|
401 |
+
} else {
|
402 |
+
unset( $taxonomies[ (string) $tax ] ); // the theme/plugin author decided what to do with the taxonomy so don't allow the user to change this
|
403 |
}
|
404 |
}
|
405 |
}
|
406 |
+
|
407 |
return $taxonomies;
|
408 |
}
|
409 |
|
410 |
+
/**
|
411 |
+
* Translation management for strings in blocks content.
|
412 |
+
*
|
413 |
+
* @since 3.3
|
414 |
+
*
|
415 |
+
* @param string[][] $parsing_rules Rules as Xpath expressions to evaluate in the blocks content.
|
416 |
+
* @return string[][] Rules completed with ones from wpml-config file.
|
417 |
+
*
|
418 |
+
* @phpstan-param array<string,array<string>> $parsing_rules
|
419 |
+
* @phpstan-return array<string,array<string>>
|
420 |
+
*/
|
421 |
+
public function translate_blocks( $parsing_rules ) {
|
422 |
+
return array_merge( $parsing_rules, $this->get_blocks_parsing_rules( 'xpath' ) );
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Translation management for blocks attributes.
|
427 |
+
*
|
428 |
+
* @since 3.3
|
429 |
+
*
|
430 |
+
* @param string[][] $parsing_rules Rules for blocks attributes to translate.
|
431 |
+
* @return string[][] Rules completed with ones from wpml-config file.
|
432 |
+
*
|
433 |
+
* @phpstan-param array<string,array<string>> $parsing_rules
|
434 |
+
* @phpstan-return array<string,array<string>>
|
435 |
+
*/
|
436 |
+
public function translate_blocks_attributes( $parsing_rules ) {
|
437 |
+
return array_merge( $parsing_rules, $this->get_blocks_parsing_rules( 'key' ) );
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Returns rules to extract translatable strings from blocks.
|
442 |
+
*
|
443 |
+
* @since 3.3
|
444 |
+
*
|
445 |
+
* @param string $rule_tag Tag name to extract.
|
446 |
+
* @return string[][] The rules.
|
447 |
+
*/
|
448 |
+
protected function get_blocks_parsing_rules( $rule_tag ) {
|
449 |
+
|
450 |
+
if ( null === $this->parsing_rules ) {
|
451 |
+
$this->parsing_rules = $this->extract_blocks_parsing_rules();
|
452 |
+
}
|
453 |
+
|
454 |
+
return isset( $this->parsing_rules[ $rule_tag ] ) ? $this->parsing_rules[ $rule_tag ] : array();
|
455 |
+
}
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Extract all rules from WPML config file to translate strings for blocks.
|
459 |
+
*
|
460 |
+
* @since 3.3
|
461 |
+
*
|
462 |
+
* @return string[][][] Rules completed with ones from wpml-config file.
|
463 |
+
*/
|
464 |
+
protected function extract_blocks_parsing_rules() {
|
465 |
+
$parsing_rules = array();
|
466 |
+
|
467 |
+
foreach ( $this->xmls as $xml ) {
|
468 |
+
$blocks = $xml->xpath( 'gutenberg-blocks/gutenberg-block' );
|
469 |
+
|
470 |
+
if ( ! is_array( $blocks ) ) {
|
471 |
+
continue;
|
472 |
+
}
|
473 |
+
|
474 |
+
foreach ( $blocks as $block ) {
|
475 |
+
$translate = $this->get_field_attribute( $block, 'translate' );
|
476 |
+
|
477 |
+
if ( '1' !== $translate ) {
|
478 |
+
continue;
|
479 |
+
}
|
480 |
+
|
481 |
+
$block_name = $this->get_field_attribute( $block, 'type' );
|
482 |
+
|
483 |
+
if ( '' === $block_name ) {
|
484 |
+
continue;
|
485 |
+
}
|
486 |
+
|
487 |
+
foreach ( $block->children() as $child ) {
|
488 |
+
$rule = '';
|
489 |
+
$child_tag = $child->getName();
|
490 |
+
|
491 |
+
switch ( $child_tag ) {
|
492 |
+
case 'xpath':
|
493 |
+
$rule = trim( (string) $child );
|
494 |
+
break;
|
495 |
+
|
496 |
+
case 'key':
|
497 |
+
$rule = $this->get_field_attribute( $child, 'name' );
|
498 |
+
break;
|
499 |
+
}
|
500 |
+
|
501 |
+
if ( '' !== $rule ) {
|
502 |
+
$parsing_rules[ $child_tag ][ $block_name ][] = $rule;
|
503 |
+
}
|
504 |
+
}
|
505 |
+
}
|
506 |
+
}
|
507 |
+
|
508 |
+
return $parsing_rules;
|
509 |
+
}
|
510 |
+
|
511 |
/**
|
512 |
* Registers or translates the strings for an option
|
513 |
*
|
527 |
* Recursively transforms xml nodes to an array, ready for PLL_Translate_Option.
|
528 |
*
|
529 |
* @since 2.9
|
530 |
+
* @since 3.3 Type-hinted the parameters `$key` and `$arr`.
|
531 |
+
* @since 3.3 `$arr` is not passed by reference anymore.
|
532 |
+
* @since 3.3 Added the parameter `$fill_value`.
|
533 |
*
|
534 |
+
* @param SimpleXMLElement $key XML node.
|
535 |
+
* @param array $arr Array of option keys to translate.
|
536 |
+
* @param mixed $fill_value Value to use when filling entries. Default is true.
|
537 |
* @return array
|
538 |
*/
|
539 |
+
protected function xml_to_array( SimpleXMLElement $key, array $arr = array(), $fill_value = true ) {
|
540 |
+
$name = $this->get_field_attribute( $key, 'name' );
|
541 |
+
|
542 |
+
if ( '' === $name ) {
|
543 |
+
return $arr;
|
544 |
+
}
|
545 |
+
|
546 |
$children = $key->children();
|
547 |
|
548 |
if ( count( $children ) ) {
|
549 |
foreach ( $children as $child ) {
|
550 |
+
if ( ! isset( $arr[ $name ] ) || ! is_array( $arr[ $name ] ) ) {
|
551 |
+
$arr[ $name ] = array();
|
552 |
+
}
|
553 |
+
|
554 |
+
$arr[ $name ] = $this->xml_to_array( $child, $arr[ $name ], $fill_value );
|
555 |
}
|
556 |
} else {
|
557 |
+
$arr[ $name ] = $fill_value; // Multiline as in WPML.
|
558 |
}
|
559 |
+
|
560 |
return $arr;
|
561 |
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Get the value of an attribute.
|
565 |
+
*
|
566 |
+
* @since 3.3
|
567 |
+
*
|
568 |
+
* @param SimpleXMLElement $field A XML node.
|
569 |
+
* @param string $attribute_name Node of the attribute.
|
570 |
+
* @return string
|
571 |
+
*/
|
572 |
+
private function get_field_attribute( SimpleXMLElement $field, $attribute_name ) {
|
573 |
+
$attributes = $field->attributes();
|
574 |
+
|
575 |
+
if ( empty( $attributes ) || ! isset( $attributes[ $attribute_name ] ) ) {
|
576 |
+
return '';
|
577 |
+
}
|
578 |
+
|
579 |
+
return trim( (string) $attributes[ $attribute_name ] );
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Returns all wpml-config.xml files in MU plugins.
|
584 |
+
*
|
585 |
+
* @since 3.3
|
586 |
+
*
|
587 |
+
* @return string[] A context identifier as array key, a file path as array value.
|
588 |
+
*
|
589 |
+
* @phpstan-return array<string, string>
|
590 |
+
*/
|
591 |
+
private function get_mu_plugin_files() {
|
592 |
+
if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
|
593 |
+
return array();
|
594 |
+
}
|
595 |
+
|
596 |
+
$files = array();
|
597 |
+
|
598 |
+
// Search for top level wpml-config.xml file.
|
599 |
+
$file_path = WPMU_PLUGIN_DIR . '/wpml-config.xml';
|
600 |
+
|
601 |
+
if ( file_exists( $file_path ) ) {
|
602 |
+
$files['mu-plugins'] = $file_path;
|
603 |
+
}
|
604 |
+
|
605 |
+
// Search in proxy loaded MU plugins.
|
606 |
+
foreach ( new DirectoryIterator( WPMU_PLUGIN_DIR ) as $file_info ) {
|
607 |
+
if ( $file_info->isDot() || ! $file_info->isDir() ) {
|
608 |
+
continue;
|
609 |
+
}
|
610 |
+
|
611 |
+
$file_path = $file_info->getPathname() . '/wpml-config.xml';
|
612 |
+
|
613 |
+
if ( file_exists( $file_path ) ) {
|
614 |
+
$files[ 'mu-plugins/' . $file_info->getFilename() ] = $file_path;
|
615 |
+
}
|
616 |
+
}
|
617 |
+
|
618 |
+
return $files;
|
619 |
+
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* Returns all wpml-config.xml files in plugins.
|
623 |
+
*
|
624 |
+
* @since 3.3
|
625 |
+
*
|
626 |
+
* @return string[] A context identifier as array key, a file path as array value.
|
627 |
+
*
|
628 |
+
* @phpstan-return array<string, string>
|
629 |
+
*/
|
630 |
+
private function get_plugin_files() {
|
631 |
+
$files = array();
|
632 |
+
$plugins = array();
|
633 |
+
|
634 |
+
if ( is_multisite() ) {
|
635 |
+
// Don't forget sitewide active plugins thanks to Reactorshop http://wordpress.org/support/topic/polylang-and-yoast-seo-plugin/page/2?replies=38#post-4801829.
|
636 |
+
$sitewide_plugins = get_site_option( 'active_sitewide_plugins', array() );
|
637 |
+
|
638 |
+
if ( ! empty( $sitewide_plugins ) && is_array( $sitewide_plugins ) ) {
|
639 |
+
$plugins = array_keys( $sitewide_plugins );
|
640 |
+
}
|
641 |
+
}
|
642 |
+
|
643 |
+
// By-site plugins.
|
644 |
+
$active_plugins = get_option( 'active_plugins', array() );
|
645 |
+
|
646 |
+
if ( ! empty( $active_plugins ) && is_array( $active_plugins ) ) {
|
647 |
+
$plugins = array_merge( $plugins, $active_plugins );
|
648 |
+
}
|
649 |
+
|
650 |
+
$plugin_path = trailingslashit( WP_PLUGIN_DIR ) . '%s/wpml-config.xml';
|
651 |
+
|
652 |
+
foreach ( $plugins as $plugin ) {
|
653 |
+
if ( ! is_string( $plugin ) || '' === $plugin ) {
|
654 |
+
continue;
|
655 |
+
}
|
656 |
+
|
657 |
+
$file_dir = dirname( $plugin );
|
658 |
+
$file_path = sprintf( $plugin_path, $file_dir );
|
659 |
+
|
660 |
+
if ( file_exists( $file_path ) ) {
|
661 |
+
$files[ "plugins/{$file_dir}" ] = $file_path;
|
662 |
+
}
|
663 |
+
}
|
664 |
+
|
665 |
+
return $files;
|
666 |
+
}
|
667 |
+
|
668 |
+
/**
|
669 |
+
* Returns all wpml-config.xml files in theme and child theme.
|
670 |
+
*
|
671 |
+
* @since 3.3
|
672 |
+
*
|
673 |
+
* @return string[] A context identifier as array key, a file path as array value.
|
674 |
+
*
|
675 |
+
* @phpstan-return array<string, string>
|
676 |
+
*/
|
677 |
+
private function get_theme_files() {
|
678 |
+
$files = array();
|
679 |
+
|
680 |
+
// Theme.
|
681 |
+
$template_path = get_template_directory();
|
682 |
+
$file_path = "{$template_path}/wpml-config.xml";
|
683 |
+
|
684 |
+
if ( file_exists( $file_path ) ) {
|
685 |
+
$files[ 'themes/' . get_template() ] = $file_path;
|
686 |
+
}
|
687 |
+
|
688 |
+
// Child theme.
|
689 |
+
$stylesheet_path = get_stylesheet_directory();
|
690 |
+
$file_path = "{$stylesheet_path}/wpml-config.xml";
|
691 |
+
|
692 |
+
if ( $stylesheet_path !== $template_path && file_exists( $file_path ) ) {
|
693 |
+
$files[ 'themes/' . get_stylesheet() ] = $file_path;
|
694 |
+
}
|
695 |
+
|
696 |
+
return $files;
|
697 |
+
}
|
698 |
+
|
699 |
+
/**
|
700 |
+
* Returns the wpml-config.xml file in Polylang custom directory.
|
701 |
+
*
|
702 |
+
* @since 3.3
|
703 |
+
*
|
704 |
+
* @return string[] A context identifier as array key, a file path as array value.
|
705 |
+
*
|
706 |
+
* @phpstan-return array<string, string>
|
707 |
+
*/
|
708 |
+
private function get_custom_files() {
|
709 |
+
$file_path = PLL_LOCAL_DIR . '/wpml-config.xml';
|
710 |
+
|
711 |
+
if ( ! file_exists( $file_path ) ) {
|
712 |
+
return array();
|
713 |
+
}
|
714 |
+
|
715 |
+
return array(
|
716 |
+
'Polylang' => $file_path,
|
717 |
+
);
|
718 |
+
}
|
719 |
}
|
modules/wpml/wpml-legacy-api.php
CHANGED
@@ -359,10 +359,13 @@ if ( ! function_exists( 'wpml_get_copied_fields_for_post_edit' ) ) {
|
|
359 |
|
360 |
$arr = array( 'original_post_id' => (int) $_GET['from_post'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
361 |
|
362 |
-
// Don't know what WPML does but Polylang does copy all public meta keys by default
|
363 |
-
|
364 |
-
|
365 |
-
|
|
|
|
|
|
|
366 |
}
|
367 |
}
|
368 |
|
359 |
|
360 |
$arr = array( 'original_post_id' => (int) $_GET['from_post'] ); // phpcs:ignore WordPress.Security.NonceVerification
|
361 |
|
362 |
+
// Don't know what WPML does but Polylang does copy all public meta keys by default.
|
363 |
+
$keys = get_post_custom_keys( $arr['original_post_id'] );
|
364 |
+
if ( is_array( $keys ) ) {
|
365 |
+
foreach ( $keys as $k => $meta_key ) {
|
366 |
+
if ( is_protected_meta( $meta_key ) ) {
|
367 |
+
unset( $keys[ $k ] );
|
368 |
+
}
|
369 |
}
|
370 |
}
|
371 |
|
polylang.php
CHANGED
@@ -10,8 +10,8 @@
|
|
10 |
* Plugin Name: Polylang
|
11 |
* Plugin URI: https://polylang.pro
|
12 |
* Description: Adds multilingual capability to WordPress
|
13 |
-
* Version: 3.
|
14 |
-
* Requires at least: 5.
|
15 |
* Requires PHP: 5.6
|
16 |
* Author: WP SYNTEX
|
17 |
* Author URI: https://polylang.pro
|
@@ -53,8 +53,8 @@ if ( defined( 'POLYLANG_VERSION' ) ) {
|
|
53 |
}
|
54 |
} else {
|
55 |
// Go on loading the plugin
|
56 |
-
define( 'POLYLANG_VERSION', '3.
|
57 |
-
define( 'PLL_MIN_WP_VERSION', '5.
|
58 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
59 |
|
60 |
define( 'POLYLANG_FILE', __FILE__ );
|
10 |
* Plugin Name: Polylang
|
11 |
* Plugin URI: https://polylang.pro
|
12 |
* Description: Adds multilingual capability to WordPress
|
13 |
+
* Version: 3.3
|
14 |
+
* Requires at least: 5.7
|
15 |
* Requires PHP: 5.6
|
16 |
* Author: WP SYNTEX
|
17 |
* Author URI: https://polylang.pro
|
53 |
}
|
54 |
} else {
|
55 |
// Go on loading the plugin
|
56 |
+
define( 'POLYLANG_VERSION', '3.3' );
|
57 |
+
define( 'PLL_MIN_WP_VERSION', '5.7' );
|
58 |
define( 'PLL_MIN_PHP_VERSION', '5.6' );
|
59 |
|
60 |
define( 'POLYLANG_FILE', __FILE__ );
|
readme.txt
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
Contributors: Chouby, manooweb, raaaahman, marianne38, sebastienserre, greglone, hugod
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
-
Requires at least: 5.
|
6 |
Tested up to: 6.1
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 3.
|
9 |
License: GPLv3 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -70,7 +70,7 @@ Wherever third party code has been used, credit has been given in the code’s c
|
|
70 |
|
71 |
== Installation ==
|
72 |
|
73 |
-
1. Make sure you are using WordPress 5.
|
74 |
1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
|
75 |
1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
|
76 |
1. The [setup wizard](https://polylang.pro/doc/setup-wizard/) is automatically launched to help you get started more easily with Polylang by configuring the main features.
|
@@ -103,6 +103,35 @@ Wherever third party code has been used, credit has been given in the code’s c
|
|
103 |
|
104 |
== Changelog ==
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
= 3.2.8 (2022-10-17) =
|
107 |
|
108 |
* Fix PHP warning when a filtered taxonomy has no query var #1124
|
2 |
Contributors: Chouby, manooweb, raaaahman, marianne38, sebastienserre, greglone, hugod
|
3 |
Donate link: https://polylang.pro
|
4 |
Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
|
5 |
+
Requires at least: 5.7
|
6 |
Tested up to: 6.1
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 3.3
|
9 |
License: GPLv3 or later
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
70 |
|
71 |
== Installation ==
|
72 |
|
73 |
+
1. Make sure you are using WordPress 5.7 or later and that your server is running PHP 5.6 or later (same requirement as WordPress itself).
|
74 |
1. If you tried other multilingual plugins, deactivate them before activating Polylang, otherwise, you may get unexpected results!
|
75 |
1. Install and activate the plugin as usual from the 'Plugins' menu in WordPress.
|
76 |
1. The [setup wizard](https://polylang.pro/doc/setup-wizard/) is automatically launched to help you get started more easily with Polylang by configuring the main features.
|
103 |
|
104 |
== Changelog ==
|
105 |
|
106 |
+
= 3.3 (2022-11-28) =
|
107 |
+
|
108 |
+
* Requires WP 5.7 as minimum version
|
109 |
+
* Pro: Allow to export and import XLIFF files for posts
|
110 |
+
* Pro: Honor the provided context for the navigation language switcher block.
|
111 |
+
* Pro: Remove the parent hyperlink in the navigation language switcher block.
|
112 |
+
* Pro: Add spacing between flag and name in the navigation language switcher block.
|
113 |
+
* Pro: Disallow some special characters in translated slugs to avoid 404 errors.
|
114 |
+
* Pro: Fix string translation not imported when the original is registered but has never been saved in database.
|
115 |
+
* Pro: Fix string translation not imported when it includes an html entity.
|
116 |
+
* Pro: Fix navigation language switcher block rendering in block editor.
|
117 |
+
* Pro: Fix navigation language switcher may be displayed wrong color.
|
118 |
+
* Translate the post pages in get_post_type_archive_link() on admin side too. #1000
|
119 |
+
* Enable the block editor in page for posts translations to match the WordPress behavior since version 5.8 #1002
|
120 |
+
* Improve the site health report #1062 #1076
|
121 |
+
* Set the current language when saving a post #1065
|
122 |
+
* The search block is now filtered by language #1081
|
123 |
+
* Display slug of CPT and taxonomies in Custom post types and Taxonomies settings. Props @nicomollet #1112
|
124 |
+
* Add support for wpml-config.xml to MU plugins #1140 Props Jeremy Simkins
|
125 |
+
* Fix some deprecated notices fired by PHP 8.1 #975
|
126 |
+
* Fix some missing canonical redirect taxonomies #1074
|
127 |
+
* Fix redirect when permalink structure has no trailing slash #1080
|
128 |
+
* Fix language switcher in legacy navigation menu widget not rendered in widgets block editor #1083
|
129 |
+
* Fix language in tax query when an OR relation is used #1098
|
130 |
+
* Fix parent of translated category removed when assigning an untranslated parent #1105
|
131 |
+
* Fix is_front_page() when a static front page is not translated #1123
|
132 |
+
* Yoast SEO: Fix posts without language displayed in the sitemap #1103
|
133 |
+
* Yoast SEO: Avoid syncing robots meta. #1118
|
134 |
+
|
135 |
= 3.2.8 (2022-10-17) =
|
136 |
|
137 |
* Fix PHP warning when a filtered taxonomy has no query var #1124
|
settings/settings-browser.php
CHANGED
@@ -24,7 +24,9 @@ class PLL_Settings_Browser extends PLL_Settings_Module {
|
|
24 |
* @param object $polylang polylang object
|
25 |
*/
|
26 |
public function __construct( &$polylang ) {
|
|
|
27 |
$this->options = &$polylang->options;
|
|
|
28 |
parent::__construct(
|
29 |
$polylang,
|
30 |
array(
|
24 |
* @param object $polylang polylang object
|
25 |
*/
|
26 |
public function __construct( &$polylang ) {
|
27 |
+
// Needed for `$this->is_available()`, which is used before calling the parent's constructor.
|
28 |
$this->options = &$polylang->options;
|
29 |
+
|
30 |
parent::__construct(
|
31 |
$polylang,
|
32 |
array(
|
settings/settings-cpt.php
CHANGED
@@ -107,9 +107,16 @@ class PLL_Settings_CPT extends PLL_Settings_Module {
|
|
107 |
printf(
|
108 |
'<li><label><input name="post_types[%s]" type="checkbox" value="1" %s %s/> %s</label></li>',
|
109 |
esc_attr( $post_type ),
|
110 |
-
checked( in_array( $post_type, $this->options['post_types'] )
|
111 |
disabled( $disabled, true, false ),
|
112 |
-
esc_html(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
);
|
114 |
}
|
115 |
}
|
@@ -131,9 +138,16 @@ class PLL_Settings_CPT extends PLL_Settings_Module {
|
|
131 |
printf(
|
132 |
'<li><label><input name="taxonomies[%s]" type="checkbox" value="1" %s %s/> %s</label></li>',
|
133 |
esc_attr( $taxonomy ),
|
134 |
-
checked( in_array( $taxonomy, $this->options['taxonomies'] )
|
135 |
disabled( $disabled, true, false ),
|
136 |
-
esc_html(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
);
|
138 |
}
|
139 |
}
|
107 |
printf(
|
108 |
'<li><label><input name="post_types[%s]" type="checkbox" value="1" %s %s/> %s</label></li>',
|
109 |
esc_attr( $post_type ),
|
110 |
+
checked( $disabled || in_array( $post_type, $this->options['post_types'], true ), true, false ),
|
111 |
disabled( $disabled, true, false ),
|
112 |
+
esc_html(
|
113 |
+
sprintf(
|
114 |
+
/* translators: 1 is a post type or taxonomy label, 2 is a post type or taxonomy key. */
|
115 |
+
_x( '%1$s (%2$s)', 'content type setting choice', 'polylang' ),
|
116 |
+
$pt->labels->name,
|
117 |
+
$pt->name
|
118 |
+
)
|
119 |
+
)
|
120 |
);
|
121 |
}
|
122 |
}
|
138 |
printf(
|
139 |
'<li><label><input name="taxonomies[%s]" type="checkbox" value="1" %s %s/> %s</label></li>',
|
140 |
esc_attr( $taxonomy ),
|
141 |
+
checked( $disabled || in_array( $taxonomy, $this->options['taxonomies'], true ), true, false ),
|
142 |
disabled( $disabled, true, false ),
|
143 |
+
esc_html(
|
144 |
+
sprintf(
|
145 |
+
/* translators: 1 is a post type or taxonomy label, 2 is a post type or taxonomy key. */
|
146 |
+
_x( '%1$s (%2$s)', 'content type setting choice', 'polylang' ),
|
147 |
+
$tax->labels->name,
|
148 |
+
$tax->name
|
149 |
+
)
|
150 |
+
)
|
151 |
);
|
152 |
}
|
153 |
}
|
settings/settings-module.php
CHANGED
@@ -46,7 +46,7 @@ class PLL_Settings_Module {
|
|
46 |
* Stores the module name.
|
47 |
* It must be unique.
|
48 |
*
|
49 |
-
* @var string
|
50 |
*/
|
51 |
public $module;
|
52 |
|
46 |
* Stores the module name.
|
47 |
* It must be unique.
|
48 |
*
|
49 |
+
* @var string|null
|
50 |
*/
|
51 |
public $module;
|
52 |
|
settings/settings-url.php
CHANGED
@@ -19,7 +19,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
19 |
/**
|
20 |
* The page id of the static front page.
|
21 |
*
|
22 |
-
* @var int
|
23 |
*/
|
24 |
protected $page_on_front;
|
25 |
|
@@ -37,7 +37,6 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
37 |
'module' => 'url',
|
38 |
'title' => __( 'URL modifications', 'polylang' ),
|
39 |
'description' => __( 'Decide how your URLs will look like.', 'polylang' ),
|
40 |
-
'configure' => true,
|
41 |
)
|
42 |
);
|
43 |
|
@@ -257,6 +256,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
|
|
257 |
}
|
258 |
|
259 |
if ( 3 == $options['force_lang'] && isset( $options['domains'] ) && is_array( $options['domains'] ) ) {
|
|
|
260 |
foreach ( $options['domains'] as $key => $domain ) {
|
261 |
if ( empty( $domain ) ) {
|
262 |
$lang = $this->model->get_language( $key );
|
19 |
/**
|
20 |
* The page id of the static front page.
|
21 |
*
|
22 |
+
* @var int|null
|
23 |
*/
|
24 |
protected $page_on_front;
|
25 |
|
37 |
'module' => 'url',
|
38 |
'title' => __( 'URL modifications', 'polylang' ),
|
39 |
'description' => __( 'Decide how your URLs will look like.', 'polylang' ),
|
|
|
40 |
)
|
41 |
);
|
42 |
|
256 |
}
|
257 |
|
258 |
if ( 3 == $options['force_lang'] && isset( $options['domains'] ) && is_array( $options['domains'] ) ) {
|
259 |
+
$newoptions['domains'] = array();
|
260 |
foreach ( $options['domains'] as $key => $domain ) {
|
261 |
if ( empty( $domain ) ) {
|
262 |
$lang = $this->model->get_language( $key );
|
settings/settings.php
CHANGED
@@ -18,14 +18,14 @@ class PLL_Settings extends PLL_Admin_Base {
|
|
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 |
|
18 |
/**
|
19 |
* Name of the active module.
|
20 |
*
|
21 |
+
* @var string|null
|
22 |
*/
|
23 |
protected $active_tab;
|
24 |
|
25 |
/**
|
26 |
* Array of modules classes.
|
27 |
*
|
28 |
+
* @var PLL_Settings_Module[]|null
|
29 |
*/
|
30 |
protected $modules;
|
31 |
|
settings/table-string.php
CHANGED
@@ -125,8 +125,12 @@ class PLL_Table_String extends WP_List_Table {
|
|
125 |
* @return string
|
126 |
*/
|
127 |
public function column_translations( $item ) {
|
128 |
-
$
|
129 |
-
$
|
|
|
|
|
|
|
|
|
130 |
|
131 |
foreach ( $item['translations'] as $key => $translation ) {
|
132 |
$input_type = $item['multiline'] ?
|
@@ -382,7 +386,7 @@ class PLL_Table_String extends WP_List_Table {
|
|
382 |
continue;
|
383 |
}
|
384 |
|
385 |
-
$translations = array_map( 'trim', wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
386 |
|
387 |
$mo = new PLL_MO();
|
388 |
$mo->import_from_db( $language );
|
125 |
* @return string
|
126 |
*/
|
127 |
public function column_translations( $item ) {
|
128 |
+
$out = '';
|
129 |
+
$languages = array();
|
130 |
+
|
131 |
+
foreach ( $this->languages as $language ) {
|
132 |
+
$languages[ $language->slug ] = $language->name;
|
133 |
+
}
|
134 |
|
135 |
foreach ( $item['translations'] as $key => $translation ) {
|
136 |
$input_type = $item['multiline'] ?
|
386 |
continue;
|
387 |
}
|
388 |
|
389 |
+
$translations = array_map( 'trim', (array) wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
390 |
|
391 |
$mo = new PLL_MO();
|
392 |
$mo->import_from_db( $language );
|
uninstall.php
CHANGED
@@ -58,7 +58,7 @@ class PLL_Uninstall {
|
|
58 |
register_taxonomy( $taxonomy, null, array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false ) );
|
59 |
}
|
60 |
|
61 |
-
$languages = get_terms( 'language',
|
62 |
|
63 |
// Delete users options
|
64 |
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
|
@@ -103,7 +103,7 @@ class PLL_Uninstall {
|
|
103 |
$term_ids = array();
|
104 |
$tt_ids = array();
|
105 |
|
106 |
-
foreach ( get_terms( $pll_taxonomies,
|
107 |
$term_ids[] = (int) $term->term_id;
|
108 |
$tt_ids[] = (int) $term->term_taxonomy_id;
|
109 |
}
|
58 |
register_taxonomy( $taxonomy, null, array( 'label' => false, 'public' => false, 'query_var' => false, 'rewrite' => false ) );
|
59 |
}
|
60 |
|
61 |
+
$languages = get_terms( array( 'taxonomy' => 'language', 'hide_empty' => false ) );
|
62 |
|
63 |
// Delete users options
|
64 |
foreach ( get_users( array( 'fields' => 'ID' ) ) as $user_id ) {
|
103 |
$term_ids = array();
|
104 |
$tt_ids = array();
|
105 |
|
106 |
+
foreach ( get_terms( array( 'taxonomy' => $pll_taxonomies, 'hide_empty' => false ) ) as $term ) {
|
107 |
$term_ids[] = (int) $term->term_id;
|
108 |
$tt_ids[] = (int) $term->term_taxonomy_id;
|
109 |
}
|
vendor/composer/InstalledVersions.php
ADDED
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer;
|
14 |
+
|
15 |
+
use Composer\Autoload\ClassLoader;
|
16 |
+
use Composer\Semver\VersionParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* This class is copied in every Composer installed project and available to all
|
20 |
+
*
|
21 |
+
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
22 |
+
*
|
23 |
+
* To require its presence, you can require `composer-runtime-api ^2.0`
|
24 |
+
*
|
25 |
+
* @final
|
26 |
+
*/
|
27 |
+
class InstalledVersions
|
28 |
+
{
|
29 |
+
/**
|
30 |
+
* @var mixed[]|null
|
31 |
+
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
32 |
+
*/
|
33 |
+
private static $installed;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var bool|null
|
37 |
+
*/
|
38 |
+
private static $canGetVendors;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var array[]
|
42 |
+
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
43 |
+
*/
|
44 |
+
private static $installedByVendor = array();
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
48 |
+
*
|
49 |
+
* @return string[]
|
50 |
+
* @psalm-return list<string>
|
51 |
+
*/
|
52 |
+
public static function getInstalledPackages()
|
53 |
+
{
|
54 |
+
$packages = array();
|
55 |
+
foreach (self::getInstalled() as $installed) {
|
56 |
+
$packages[] = array_keys($installed['versions']);
|
57 |
+
}
|
58 |
+
|
59 |
+
if (1 === \count($packages)) {
|
60 |
+
return $packages[0];
|
61 |
+
}
|
62 |
+
|
63 |
+
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Returns a list of all package names with a specific type e.g. 'library'
|
68 |
+
*
|
69 |
+
* @param string $type
|
70 |
+
* @return string[]
|
71 |
+
* @psalm-return list<string>
|
72 |
+
*/
|
73 |
+
public static function getInstalledPackagesByType($type)
|
74 |
+
{
|
75 |
+
$packagesByType = array();
|
76 |
+
|
77 |
+
foreach (self::getInstalled() as $installed) {
|
78 |
+
foreach ($installed['versions'] as $name => $package) {
|
79 |
+
if (isset($package['type']) && $package['type'] === $type) {
|
80 |
+
$packagesByType[] = $name;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
return $packagesByType;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Checks whether the given package is installed
|
90 |
+
*
|
91 |
+
* This also returns true if the package name is provided or replaced by another package
|
92 |
+
*
|
93 |
+
* @param string $packageName
|
94 |
+
* @param bool $includeDevRequirements
|
95 |
+
* @return bool
|
96 |
+
*/
|
97 |
+
public static function isInstalled($packageName, $includeDevRequirements = true)
|
98 |
+
{
|
99 |
+
foreach (self::getInstalled() as $installed) {
|
100 |
+
if (isset($installed['versions'][$packageName])) {
|
101 |
+
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Checks whether the given package satisfies a version constraint
|
110 |
+
*
|
111 |
+
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
112 |
+
*
|
113 |
+
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
114 |
+
*
|
115 |
+
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
116 |
+
* @param string $packageName
|
117 |
+
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
118 |
+
* @return bool
|
119 |
+
*/
|
120 |
+
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
121 |
+
{
|
122 |
+
$constraint = $parser->parseConstraints($constraint);
|
123 |
+
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
124 |
+
|
125 |
+
return $provided->matches($constraint);
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Returns a version constraint representing all the range(s) which are installed for a given package
|
130 |
+
*
|
131 |
+
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
132 |
+
* whether a given version of a package is installed, and not just whether it exists
|
133 |
+
*
|
134 |
+
* @param string $packageName
|
135 |
+
* @return string Version constraint usable with composer/semver
|
136 |
+
*/
|
137 |
+
public static function getVersionRanges($packageName)
|
138 |
+
{
|
139 |
+
foreach (self::getInstalled() as $installed) {
|
140 |
+
if (!isset($installed['versions'][$packageName])) {
|
141 |
+
continue;
|
142 |
+
}
|
143 |
+
|
144 |
+
$ranges = array();
|
145 |
+
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
146 |
+
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
147 |
+
}
|
148 |
+
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
149 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
150 |
+
}
|
151 |
+
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
152 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
153 |
+
}
|
154 |
+
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
155 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
156 |
+
}
|
157 |
+
|
158 |
+
return implode(' || ', $ranges);
|
159 |
+
}
|
160 |
+
|
161 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param string $packageName
|
166 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
167 |
+
*/
|
168 |
+
public static function getVersion($packageName)
|
169 |
+
{
|
170 |
+
foreach (self::getInstalled() as $installed) {
|
171 |
+
if (!isset($installed['versions'][$packageName])) {
|
172 |
+
continue;
|
173 |
+
}
|
174 |
+
|
175 |
+
if (!isset($installed['versions'][$packageName]['version'])) {
|
176 |
+
return null;
|
177 |
+
}
|
178 |
+
|
179 |
+
return $installed['versions'][$packageName]['version'];
|
180 |
+
}
|
181 |
+
|
182 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @param string $packageName
|
187 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
188 |
+
*/
|
189 |
+
public static function getPrettyVersion($packageName)
|
190 |
+
{
|
191 |
+
foreach (self::getInstalled() as $installed) {
|
192 |
+
if (!isset($installed['versions'][$packageName])) {
|
193 |
+
continue;
|
194 |
+
}
|
195 |
+
|
196 |
+
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
197 |
+
return null;
|
198 |
+
}
|
199 |
+
|
200 |
+
return $installed['versions'][$packageName]['pretty_version'];
|
201 |
+
}
|
202 |
+
|
203 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* @param string $packageName
|
208 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
209 |
+
*/
|
210 |
+
public static function getReference($packageName)
|
211 |
+
{
|
212 |
+
foreach (self::getInstalled() as $installed) {
|
213 |
+
if (!isset($installed['versions'][$packageName])) {
|
214 |
+
continue;
|
215 |
+
}
|
216 |
+
|
217 |
+
if (!isset($installed['versions'][$packageName]['reference'])) {
|
218 |
+
return null;
|
219 |
+
}
|
220 |
+
|
221 |
+
return $installed['versions'][$packageName]['reference'];
|
222 |
+
}
|
223 |
+
|
224 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @param string $packageName
|
229 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
230 |
+
*/
|
231 |
+
public static function getInstallPath($packageName)
|
232 |
+
{
|
233 |
+
foreach (self::getInstalled() as $installed) {
|
234 |
+
if (!isset($installed['versions'][$packageName])) {
|
235 |
+
continue;
|
236 |
+
}
|
237 |
+
|
238 |
+
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
239 |
+
}
|
240 |
+
|
241 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @return array
|
246 |
+
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
247 |
+
*/
|
248 |
+
public static function getRootPackage()
|
249 |
+
{
|
250 |
+
$installed = self::getInstalled();
|
251 |
+
|
252 |
+
return $installed[0]['root'];
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Returns the raw installed.php data for custom implementations
|
257 |
+
*
|
258 |
+
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
259 |
+
* @return array[]
|
260 |
+
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
261 |
+
*/
|
262 |
+
public static function getRawData()
|
263 |
+
{
|
264 |
+
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
265 |
+
|
266 |
+
if (null === self::$installed) {
|
267 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
268 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
269 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
270 |
+
self::$installed = include __DIR__ . '/installed.php';
|
271 |
+
} else {
|
272 |
+
self::$installed = array();
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
return self::$installed;
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
281 |
+
*
|
282 |
+
* @return array[]
|
283 |
+
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
284 |
+
*/
|
285 |
+
public static function getAllRawData()
|
286 |
+
{
|
287 |
+
return self::getInstalled();
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Lets you reload the static array from another file
|
292 |
+
*
|
293 |
+
* This is only useful for complex integrations in which a project needs to use
|
294 |
+
* this class but then also needs to execute another project's autoloader in process,
|
295 |
+
* and wants to ensure both projects have access to their version of installed.php.
|
296 |
+
*
|
297 |
+
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
298 |
+
* the data it needs from this class, then call reload() with
|
299 |
+
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
300 |
+
* the project in which it runs can then also use this class safely, without
|
301 |
+
* interference between PHPUnit's dependencies and the project's dependencies.
|
302 |
+
*
|
303 |
+
* @param array[] $data A vendor/composer/installed.php data set
|
304 |
+
* @return void
|
305 |
+
*
|
306 |
+
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
307 |
+
*/
|
308 |
+
public static function reload($data)
|
309 |
+
{
|
310 |
+
self::$installed = $data;
|
311 |
+
self::$installedByVendor = array();
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* @return array[]
|
316 |
+
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
317 |
+
*/
|
318 |
+
private static function getInstalled()
|
319 |
+
{
|
320 |
+
if (null === self::$canGetVendors) {
|
321 |
+
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
322 |
+
}
|
323 |
+
|
324 |
+
$installed = array();
|
325 |
+
|
326 |
+
if (self::$canGetVendors) {
|
327 |
+
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
328 |
+
if (isset(self::$installedByVendor[$vendorDir])) {
|
329 |
+
$installed[] = self::$installedByVendor[$vendorDir];
|
330 |
+
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
331 |
+
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
332 |
+
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
333 |
+
self::$installed = $installed[count($installed) - 1];
|
334 |
+
}
|
335 |
+
}
|
336 |
+
}
|
337 |
+
}
|
338 |
+
|
339 |
+
if (null === self::$installed) {
|
340 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
341 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
342 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
343 |
+
self::$installed = require __DIR__ . '/installed.php';
|
344 |
+
} else {
|
345 |
+
self::$installed = array();
|
346 |
+
}
|
347 |
+
}
|
348 |
+
$installed[] = self::$installed;
|
349 |
+
|
350 |
+
return $installed;
|
351 |
+
}
|
352 |
+
}
|
vendor/composer/autoload_classmap.php
CHANGED
@@ -37,6 +37,7 @@ return array(
|
|
37 |
'PLL_CRUD_Terms' => $baseDir . '/include/crud-terms.php',
|
38 |
'PLL_Cache' => $baseDir . '/include/cache.php',
|
39 |
'PLL_Cache_Compat' => $baseDir . '/integrations/cache/cache-compat.php',
|
|
|
40 |
'PLL_Cft' => $baseDir . '/integrations/custom-field-template/cft.php',
|
41 |
'PLL_Choose_Lang' => $baseDir . '/frontend/choose-lang.php',
|
42 |
'PLL_Choose_Lang_Content' => $baseDir . '/frontend/choose-lang-content.php',
|
37 |
'PLL_CRUD_Terms' => $baseDir . '/include/crud-terms.php',
|
38 |
'PLL_Cache' => $baseDir . '/include/cache.php',
|
39 |
'PLL_Cache_Compat' => $baseDir . '/integrations/cache/cache-compat.php',
|
40 |
+
'PLL_Canonical' => $baseDir . '/frontend/canonical.php',
|
41 |
'PLL_Cft' => $baseDir . '/integrations/custom-field-template/cft.php',
|
42 |
'PLL_Choose_Lang' => $baseDir . '/frontend/choose-lang.php',
|
43 |
'PLL_Choose_Lang_Content' => $baseDir . '/frontend/choose-lang-content.php',
|
vendor/composer/autoload_static.php
CHANGED
@@ -38,6 +38,7 @@ class ComposerStaticInit57e007bdf76a1fe336cb43b59389545b
|
|
38 |
'PLL_CRUD_Terms' => __DIR__ . '/../..' . '/include/crud-terms.php',
|
39 |
'PLL_Cache' => __DIR__ . '/../..' . '/include/cache.php',
|
40 |
'PLL_Cache_Compat' => __DIR__ . '/../..' . '/integrations/cache/cache-compat.php',
|
|
|
41 |
'PLL_Cft' => __DIR__ . '/../..' . '/integrations/custom-field-template/cft.php',
|
42 |
'PLL_Choose_Lang' => __DIR__ . '/../..' . '/frontend/choose-lang.php',
|
43 |
'PLL_Choose_Lang_Content' => __DIR__ . '/../..' . '/frontend/choose-lang-content.php',
|
38 |
'PLL_CRUD_Terms' => __DIR__ . '/../..' . '/include/crud-terms.php',
|
39 |
'PLL_Cache' => __DIR__ . '/../..' . '/include/cache.php',
|
40 |
'PLL_Cache_Compat' => __DIR__ . '/../..' . '/integrations/cache/cache-compat.php',
|
41 |
+
'PLL_Canonical' => __DIR__ . '/../..' . '/frontend/canonical.php',
|
42 |
'PLL_Cft' => __DIR__ . '/../..' . '/integrations/custom-field-template/cft.php',
|
43 |
'PLL_Choose_Lang' => __DIR__ . '/../..' . '/frontend/choose-lang.php',
|
44 |
'PLL_Choose_Lang_Content' => __DIR__ . '/../..' . '/frontend/choose-lang-content.php',
|
vendor/composer/installed.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php return array(
|
2 |
+
'root' => array(
|
3 |
+
'name' => 'wpsyntex/polylang',
|
4 |
+
'pretty_version' => '3.2.x-dev',
|
5 |
+
'version' => '3.2.9999999.9999999-dev',
|
6 |
+
'reference' => '9555976eb2dc703519184632f83fa6114d3a9ce3',
|
7 |
+
'type' => 'wordpress-plugin',
|
8 |
+
'install_path' => __DIR__ . '/../../',
|
9 |
+
'aliases' => array(),
|
10 |
+
'dev' => false,
|
11 |
+
),
|
12 |
+
'versions' => array(
|
13 |
+
'wpsyntex/polylang' => array(
|
14 |
+
'pretty_version' => '3.2.x-dev',
|
15 |
+
'version' => '3.2.9999999.9999999-dev',
|
16 |
+
'reference' => '9555976eb2dc703519184632f83fa6114d3a9ce3',
|
17 |
+
'type' => 'wordpress-plugin',
|
18 |
+
'install_path' => __DIR__ . '/../../',
|
19 |
+
'aliases' => array(),
|
20 |
+
'dev_requirement' => false,
|
21 |
+
),
|
22 |
+
),
|
23 |
+
);
|
vendor/composer/platform_check.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// platform_check.php @generated by Composer
|
4 |
+
|
5 |
+
$issues = array();
|
6 |
+
|
7 |
+
if (!(PHP_VERSION_ID >= 50600)) {
|
8 |
+
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
|
9 |
+
}
|
10 |
+
|
11 |
+
if ($issues) {
|
12 |
+
if (!headers_sent()) {
|
13 |
+
header('HTTP/1.1 500 Internal Server Error');
|
14 |
+
}
|
15 |
+
if (!ini_get('display_errors')) {
|
16 |
+
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
17 |
+
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
18 |
+
} elseif (!headers_sent()) {
|
19 |
+
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
trigger_error(
|
23 |
+
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
24 |
+
E_USER_ERROR
|
25 |
+
);
|
26 |
+
}
|