Preferred Languages - Version 1.8.0

Version Description

This release contains various smaller bugfixes, Site Health integration, as well as improved compatibility with other plugins such as WPML.

Download this release

Release Info

Developer swissspidy
Plugin Icon Preferred Languages
Version 1.8.0
Comparing to
See all releases

Code changes from version 1.7.1 to 1.8.0

build/preferred-languages-rtl.css CHANGED
@@ -98,7 +98,6 @@
98
  /* stylelint-disable selector-id-pattern */
99
  .js label[for="WPLANG"],
100
  .js #WPLANG,
101
- .js .user-language-wrap,
102
  .no-js .preferred-languages,
103
  .no-js #preferred-languages-label,
104
  .no-js .user-preferred-languages-wrap {
98
  /* stylelint-disable selector-id-pattern */
99
  .js label[for="WPLANG"],
100
  .js #WPLANG,
 
101
  .no-js .preferred-languages,
102
  .no-js #preferred-languages-label,
103
  .no-js .user-preferred-languages-wrap {
build/preferred-languages.asset.php CHANGED
@@ -1 +1 @@
1
- <?php return array('dependencies' => array('wp-a11y', 'wp-i18n', 'wp-polyfill'), 'version' => 'db84fb8954710b116b049c69edf8a5ef');
1
+ <?php return array('dependencies' => array('wp-a11y', 'wp-i18n', 'wp-polyfill'), 'version' => '739f786332604454d820a649fe172c9a');
build/preferred-languages.css CHANGED
@@ -98,7 +98,6 @@
98
  /* stylelint-disable selector-id-pattern */
99
  .js label[for="WPLANG"],
100
  .js #WPLANG,
101
- .js .user-language-wrap,
102
  .no-js .preferred-languages,
103
  .no-js #preferred-languages-label,
104
  .no-js .user-preferred-languages-wrap {
98
  /* stylelint-disable selector-id-pattern */
99
  .js label[for="WPLANG"],
100
  .js #WPLANG,
 
101
  .no-js .preferred-languages,
102
  .no-js #preferred-languages-label,
103
  .no-js .user-preferred-languages-wrap {
build/preferred-languages.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function a(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,a),r.l=!0,r.exports}a.m=e,a.c=t,a.d=function(e,t,n){a.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(a.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)a.d(n,r,function(t){return e[t]}.bind(null,r));return n},a.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(t,"a",t),t},a.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},a.p="",a(a.s=2)}([function(e,t){e.exports=window.wp.a11y},function(e,t){e.exports=window.wp.i18n},function(e,t,a){"use strict";a.r(t);var n=a(0),r=a(1);a(3),function(e){var t=e(document),a=e(".active-locales-list"),l=e(".active-locales-controls"),i=e("#active-locales-empty-message"),o=e(".inactive-locales-list"),s=o.find("select"),c=e(".inactive-locales-controls"),d=e('input[name="preferred_languages"]'),f=a.find('li[aria-selected="true"]');function u(e){var t=a.find(".active-locale");l.find(".locales-move-up").attr("disabled",a.hasClass("empty-list")||t.first().is(e)),l.find(".locales-move-down").attr("disabled",a.hasClass("empty-list")||t.last().is(e)),l.find(".locales-remove").attr("disabled",a.hasClass("empty-list")),c.find(".locales-add").attr("disabled","disabled"===s.attr("disabled"))}function p(e){var t=e.attr("aria-selected"),n="true"!==t;"true"!==t&&(f.attr("aria-selected",!1),e.attr("aria-selected",n),!0===n&&(f=e,a.attr("aria-activedescendant",f.attr("id"))),u(e))}function v(){var t=[];a.children(".active-locale").each((function(a,n){t.push(e(n).attr("id"))})),d.val(t.join(","))}function m(){f.insertBefore(f.prev()),v(),u(f),Object(n.speak)(Object(r.__)("Locale moved up","preferred-languages"))}function g(){f.insertAfter(f.next()),v(),u(f),Object(n.speak)(Object(r.__)("Locale moved down","preferred-languages"))}function h(){a.hasClass("empty-list")?(a.removeClass("empty-list"),i.addClass("hidden")):(a.addClass("empty-list"),a.attr("aria-activedescendant",""),i.removeClass("hidden"),Object(n.speak)(i.data("a11y-message")))}function b(){var e,t=f.attr("id");0===(e=f.prevAll(":first")).length&&(e=f.nextAll(":first")),f.remove(),e.length?p(e):h(),s.find('option[value="'.concat(t,'"]')).removeClass("hidden"),s.attr("disabled",!1),v(),u(f),Object(n.speak)(Object(r.__)("Locale removed from list","preferred-languages"))}function y(t){var l,i=t.val()||"en_US";if(t.removeAttr("selected").addClass("hidden"),(l=t.prevAll(":not(.hidden):first")).length||(l=t.nextAll(":not(.hidden):first")),l.length||(l=s.find("option:not(.hidden):first")),l.length||s.attr("disabled",!0),l.attr("selected",!0),c.val(l.val()),!a.find("#".concat(i)).length){a.hasClass("empty-list")&&h();var o=e("<li/>",{text:t.text(),role:"option","aria-selected":!1,id:i,class:"active-locale"});a.append(o),p(o),a.animate({scrollTop:o.offset().top-a.offset().top+a.scrollTop()}),v(),Object(n.speak)(Object(r.__)("Locale added to list","preferred-languages"))}}if(e(".user-language-wrap").replaceWith(e(".user-preferred-languages-wrap")),e(".options-general-php #WPLANG").parent().parent().replaceWith(e(".site-preferred-languages-wrap")),e(".network-admin.settings-php #WPLANG").parent().parent().replaceWith(e(".network-preferred-languages-wrap")),o.filter('[data-show-en_US="false"]').find('[lang="en"][value=""]').remove(),u(f),d.val().length){e.each(d.val().split(","),(function(e,t){t="en_US"===t?"":t,s.find('[value="'.concat(t,'"]')).removeAttr("selected").addClass("hidden")}));var w=s.find("option:not(.hidden):first");w.attr("selected",!0),c.val(w.val())}0===s.find(":not(.hidden)").length&&(s.attr("disabled",!0),c.find(".locales-add").attr("disabled",!0)),a.sortable({axis:"y",cursor:"move",items:":not(#active-locales-list-empty-message)",update:function(){v(),u(f)}}),t.on("keydown",(function(e){if(document.querySelector(".preferred-languages").contains(document.activeElement))switch(e.which){case 38:e.altKey?m():f.prev().length?p(f.prev()):a.focus(),e.preventDefault();break;case 40:e.altKey?g():f.next().length?p(f.next()):a.focus(),e.preventDefault();break;case 65:e.altKey&&y(s.find("option:selected")),e.preventDefault();break;case 8:b(),e.preventDefault()}})),c.find(".locales-add").on("click",(function(){y(s.find("option:selected"))})),a.on("click",".active-locale",(function(t){p(e(t.currentTarget))})),l.find(".locales-move-up").on("click",m),l.find(".locales-move-down").on("click",g),l.find(".locales-remove").on("click",b)}(window.jQuery)},function(e,t,a){}]);
1
+ !function(e){var t={};function n(a){if(t[a])return t[a].exports;var l=t[a]={i:a,l:!1,exports:{}};return e[a].call(l.exports,l,l.exports,n),l.l=!0,l.exports}n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(n.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)n.d(a,l,function(t){return e[t]}.bind(null,l));return a},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t){e.exports=window.wp.a11y},function(e,t){e.exports=window.wp.i18n},function(e,t,n){"use strict";n.r(t);var a=n(0),l=n(1);(e=>{const t=e(document),n=e(".active-locales-list"),r=e(".active-locales-controls"),i=e("#active-locales-empty-message"),s=e(".inactive-locales-list"),o=s.find("select"),d=e(".inactive-locales-controls"),c=e('input[name="preferred_languages"]');let f=n.find('li[aria-selected="true"]');function p(e){const t=n.find(".active-locale");r.find(".locales-move-up").attr("disabled",n.hasClass("empty-list")||t.first().is(e)),r.find(".locales-move-down").attr("disabled",n.hasClass("empty-list")||t.last().is(e)),r.find(".locales-remove").attr("disabled",n.hasClass("empty-list")),d.find(".locales-add").attr("disabled","disabled"===o.attr("disabled"))}function u(e){const t=e.attr("aria-selected"),a="true"!==t;"true"!==t&&(f.attr("aria-selected",!1),e.attr("aria-selected",a),!0===a&&(f=e,n.attr("aria-activedescendant",f.attr("id"))),p(e))}function v(){const t=[];n.children(".active-locale").each((n,a)=>{t.push(e(a).attr("id"))}),c.val(t.join(","))}function m(){f.insertBefore(f.prev()),v(),p(f),Object(a.speak)(Object(l.__)("Locale moved up","preferred-languages"))}function g(){f.insertAfter(f.next()),v(),p(f),Object(a.speak)(Object(l.__)("Locale moved down","preferred-languages"))}function h(){n.hasClass("empty-list")?(n.removeClass("empty-list"),i.addClass("hidden")):(n.addClass("empty-list"),n.attr("aria-activedescendant",""),i.removeClass("hidden"),Object(a.speak)(i.data("a11y-message")))}function b(){const e="en_US"!==f.attr("id")?f.attr("id"):"";let t;t=f.prevAll(":first"),0===t.length&&(t=f.nextAll(":first")),f.remove(),t.length?u(t):h(),o.find(`option[value="${e}"]`).removeClass("hidden"),o.attr("disabled",!1),o.children().eq(o.prop("selectedIndex")).is(":hidden")&&o.prop("selectedIndex",o.find("option:not(.hidden):first").index()),v(),p(f),Object(a.speak)(Object(l.__)("Locale removed from list","preferred-languages"))}function y(t){const r=t.val()||"en_US";let i;if(t.removeAttr("selected").addClass("hidden"),i=t.prevAll(":not(.hidden):first"),i.length||(i=t.nextAll(":not(.hidden):first")),i.length||(i=o.find("option:not(.hidden):first")),i.length?(i.attr("selected",!0),o.val(i.val()),o.prop("selectedIndex",i.index())):o.attr("disabled",!0),n.find("#"+r).length)return;n.hasClass("empty-list")&&h();const s=e("<li/>",{text:t.text(),role:"option","aria-selected":!1,id:r,class:"active-locale"});n.append(s),u(s),n.animate({scrollTop:s.offset().top-n.offset().top+n.scrollTop()}),v(),Object(a.speak)(Object(l.__)("Locale added to list","preferred-languages"))}t.ready(()=>{if(e(".user-language-wrap").first().replaceWith(e(".user-preferred-languages-wrap")),e(".options-general-php #WPLANG").parent().parent().replaceWith(e(".site-preferred-languages-wrap")),e(".network-admin.settings-php #WPLANG").parent().parent().replaceWith(e(".network-preferred-languages-wrap")),s.filter('[data-show-en_US="false"]').find('[lang="en"][value=""]').remove(),p(f),c.val().length){e.each(c.val().split(","),(e,t)=>{t="en_US"===t?"":t,o.find(`[value="${t}"]`).removeAttr("selected").addClass("hidden")});const t=o.find("option:not(.hidden):first");t.attr("selected",!0),d.val(t.val())}0===o.find(":not(.hidden)").length&&(o.attr("disabled",!0),d.find(".locales-add").attr("disabled",!0)),n.sortable({axis:"y",cursor:"move",items:":not(#active-locales-list-empty-message)",update:function(){v(),p(f)}}),t.on("keydown",e=>{if(document.querySelector(".preferred-languages").contains(document.activeElement))switch(e.which){case 38:e.altKey?m():f.prev().length?u(f.prev()):n.focus(),e.preventDefault();break;case 40:e.altKey?g():f.next().length?u(f.next()):n.focus(),e.preventDefault();break;case 65:e.altKey&&y(o.find("option:selected")),e.preventDefault();break;case 8:b(),e.preventDefault()}}),d.find(".locales-add").on("click",()=>{y(o.find("option:selected"))}),n.on("click",".active-locale",t=>{u(e(t.currentTarget))}),r.find(".locales-move-up").on("click",m),r.find(".locales-move-down").on("click",g),r.find(".locales-remove").on("click",b)})})(window.jQuery)}]);
inc/class-preferred-languages-textdomain-registry.php CHANGED
@@ -29,13 +29,12 @@ class Preferred_Languages_Textdomain_Registry {
29
  *
30
  * @var array
31
  */
32
- protected $cached_mofiles;
33
 
34
  /**
35
  * Returns the MO file path for a specific domain.
36
  *
37
  * @since 1.1.0
38
- * @access public
39
  *
40
  * @param string $domain Text domain.
41
  *
@@ -43,90 +42,95 @@ class Preferred_Languages_Textdomain_Registry {
43
  * Null if none have been fetched yet.
44
  */
45
  public function get( $domain ) {
46
- return isset( $this->domains[ $domain ] ) ? $this->domains[ $domain ] : null;
 
 
 
 
47
  }
48
 
49
  /**
50
  * Sets the MO file path for a specific domain.
51
  *
52
- * @since 1.1.0
53
- * @access public
54
  *
55
- * @param string $domain Text domain.
56
- * @param string $path Language directory path.
57
  */
58
  public function set( $domain, $path ) {
59
- $this->domains[ $domain ] = $path;
60
  }
61
 
62
  /**
63
  * Resets the registry state.
64
  *
65
- * @since 1.1.0
66
- * @access public
67
  */
68
  public function reset() {
69
- $this->cached_mofiles = null;
70
- $this->domains = array();
71
  }
72
 
73
  /**
74
  * Gets the path to a translation file in the languages directory for the current locale.
75
  *
76
- * @since 1.1.0
77
- * @access public
78
  *
79
- * @see _get_path_to_translation_from_lang_dir()
80
  *
81
  * @param string $domain Text domain.
 
82
  */
83
- public function get_translation_from_lang_dir( $domain ) {
84
- if ( null === $this->cached_mofiles ) {
85
- $this->cached_mofiles = array();
86
 
87
- $this->fetch_available_mofiles();
88
  }
89
 
90
  foreach ( preferred_languages_get_list() as $locale ) {
91
- $mofile = "{$domain}-{$locale}.mo";
92
 
93
- $path = WP_LANG_DIR . '/plugins/' . $mofile;
94
- if ( in_array( $path, $this->cached_mofiles, true ) ) {
95
- $this->set( $domain, WP_LANG_DIR . '/plugins/' );
 
96
 
97
- return;
98
  }
99
 
100
- $path = WP_LANG_DIR . '/themes/' . $mofile;
101
- if ( in_array( $path, $this->cached_mofiles, true ) ) {
102
- $this->set( $domain, WP_LANG_DIR . '/themes/' );
 
103
 
104
- return;
105
  }
106
  }
107
 
108
  $this->set( $domain, false );
 
 
109
  }
110
 
111
  /**
112
- * Fetches all available MO files from the plugins and themes language directories.
113
  *
114
- * @since 1.1.0
115
- * @access protected
116
  *
117
  * @see _get_path_to_translation_from_lang_dir()
118
  */
119
- protected function fetch_available_mofiles() {
120
  $locations = array(
121
  WP_LANG_DIR . '/plugins',
122
  WP_LANG_DIR . '/themes',
123
  );
124
 
125
  foreach ( $locations as $location ) {
126
- $mofiles = glob( $location . '/*.mo' );
127
 
128
- if ( $mofiles ) {
129
- $this->cached_mofiles = array_merge( $this->cached_mofiles, $mofiles );
130
  }
131
  }
132
  }
29
  *
30
  * @var array
31
  */
32
+ protected $cached_mo_files;
33
 
34
  /**
35
  * Returns the MO file path for a specific domain.
36
  *
37
  * @since 1.1.0
 
38
  *
39
  * @param string $domain Text domain.
40
  *
42
  * Null if none have been fetched yet.
43
  */
44
  public function get( $domain ) {
45
+ if ( isset( $this->domains[ $domain ] ) ) {
46
+ return $this->domains[ $domain ];
47
+ }
48
+
49
+ return $this->get_path_from_lang_dir( $domain );
50
  }
51
 
52
  /**
53
  * Sets the MO file path for a specific domain.
54
  *
55
+ * @since 1.1.0
 
56
  *
57
+ * @param string $domain Text domain.
58
+ * @param string|false $path Language directory path or false if there is none available.
59
  */
60
  public function set( $domain, $path ) {
61
+ $this->domains[ $domain ] = $path ? trailingslashit( $path ) : false;
62
  }
63
 
64
  /**
65
  * Resets the registry state.
66
  *
67
+ * @since 1.1.0
 
68
  */
69
  public function reset() {
70
+ $this->cached_mo_files = null;
71
+ $this->domains = array();
72
  }
73
 
74
  /**
75
  * Gets the path to a translation file in the languages directory for the current locale.
76
  *
77
+ * @since 1.8.0
 
78
  *
79
+ * @see _get_path_to_translation_from_lang_dir()
80
  *
81
  * @param string $domain Text domain.
82
+ * @return string|false MO file path or false if there is none available.
83
  */
84
+ private function get_path_from_lang_dir( $domain ) {
85
+ if ( null === $this->cached_mo_files ) {
86
+ $this->cached_mo_files = array();
87
 
88
+ $this->set_cached_mo_files();
89
  }
90
 
91
  foreach ( preferred_languages_get_list() as $locale ) {
92
+ $mo_file = "{$domain}-{$locale}.mo";
93
 
94
+ $path = WP_LANG_DIR . '/plugins/' . $mo_file;
95
+ if ( in_array( $path, $this->cached_mo_files, true ) ) {
96
+ $path = WP_LANG_DIR . '/plugins/';
97
+ $this->set( $domain, $path );
98
 
99
+ return $path;
100
  }
101
 
102
+ $path = WP_LANG_DIR . '/themes/' . $mo_file;
103
+ if ( in_array( $path, $this->cached_mo_files, true ) ) {
104
+ $path = WP_LANG_DIR . '/themes/';
105
+ $this->set( $domain, $path );
106
 
107
+ return $path;
108
  }
109
  }
110
 
111
  $this->set( $domain, false );
112
+
113
+ return false;
114
  }
115
 
116
  /**
117
+ * Reads and caches all available MO files from the plugins and themes language directories.
118
  *
119
+ * @since 1.8.0
 
120
  *
121
  * @see _get_path_to_translation_from_lang_dir()
122
  */
123
+ protected function set_cached_mo_files() {
124
  $locations = array(
125
  WP_LANG_DIR . '/plugins',
126
  WP_LANG_DIR . '/themes',
127
  );
128
 
129
  foreach ( $locations as $location ) {
130
+ $mo_files = glob( $location . '/*.mo' );
131
 
132
+ if ( $mo_files ) {
133
+ array_push( $this->cached_mo_files, ...$mo_files );
134
  }
135
  }
136
  }
inc/default-filters.php CHANGED
@@ -23,13 +23,17 @@ add_action( 'edit_user_profile_update', 'preferred_languages_update_user_option'
23
 
24
  add_filter( 'pre_update_option', 'preferred_languages_pre_update_option', 10, 3 );
25
  add_filter( 'pre_update_site_option', 'preferred_languages_pre_update_option', 10, 3 );
26
- add_filter( 'update_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
27
- add_filter( 'update_site_option_preferred_languages', 'preferred_languages_update_site_option', 10, 2 );
28
- add_filter( 'update_user_metadata', 'preferred_languages_pre_update_user_meta', 10, 5 );
 
 
29
  add_action( 'update_user_meta', 'preferred_languages_update_user_meta', 10, 4 );
30
  add_filter( 'get_user_metadata', 'preferred_languages_filter_user_locale', 10, 3 );
31
  add_filter( 'locale', 'preferred_languages_filter_locale', 5 ); // Before WP_Locale_Switcher.
32
  add_filter( 'override_load_textdomain', 'preferred_languages_override_load_textdomain', 10, 3 );
33
- add_filter( 'load_textdomain_mofile', 'preferred_languages_load_textdomain_mofile', 10, 2 );
34
  add_filter( 'pre_load_script_translations', 'preferred_languages_pre_load_script_translations', 10, 4 );
35
  add_filter( 'load_script_translation_file', 'preferred_languages_load_script_translation_file' );
 
 
23
 
24
  add_filter( 'pre_update_option', 'preferred_languages_pre_update_option', 10, 3 );
25
  add_filter( 'pre_update_site_option', 'preferred_languages_pre_update_option', 10, 3 );
26
+ add_action( 'add_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
27
+ add_action( 'update_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
28
+ add_action( 'add_site_option_preferred_languages', 'preferred_languages_update_site_option', 10, 2 );
29
+ add_action( 'update_site_option_preferred_languages', 'preferred_languages_update_site_option', 10, 2 );
30
+ add_action( 'add_user_meta', 'preferred_languages_add_user_meta', 10, 3 );
31
  add_action( 'update_user_meta', 'preferred_languages_update_user_meta', 10, 4 );
32
  add_filter( 'get_user_metadata', 'preferred_languages_filter_user_locale', 10, 3 );
33
  add_filter( 'locale', 'preferred_languages_filter_locale', 5 ); // Before WP_Locale_Switcher.
34
  add_filter( 'override_load_textdomain', 'preferred_languages_override_load_textdomain', 10, 3 );
35
+ add_filter( 'load_textdomain_mofile', 'preferred_languages_load_textdomain_mofile', 10 );
36
  add_filter( 'pre_load_script_translations', 'preferred_languages_pre_load_script_translations', 10, 4 );
37
  add_filter( 'load_script_translation_file', 'preferred_languages_load_script_translation_file' );
38
+
39
+ add_filter( 'debug_information', 'preferred_languages_filter_debug_information' );
inc/functions.php CHANGED
@@ -51,9 +51,19 @@ function preferred_languages_register_meta() {
51
  * @param int $user_id The user ID.
52
  */
53
  function preferred_languages_update_user_option( $user_id ) {
54
- if ( isset( $_POST['preferred_languages'] ) ) {
55
- update_user_meta( $user_id, 'preferred_languages', $_POST['preferred_languages'] );
 
 
 
 
56
  }
 
 
 
 
 
 
57
  }
58
 
59
  /**
@@ -150,32 +160,45 @@ function preferred_languages_get_list() {
150
  }
151
 
152
  /**
153
- * Downloads language packs when saving user meta without any changes.
154
  *
155
- * Makes sure the translations are downloaded when it didn't work the first time around.
156
  *
157
- * @since 1.4.0
158
  *
159
- * @param null|bool $check Whether to allow updating metadata for the given type.
160
- * @param int $user_id User ID.
161
- * @param string $meta_key Meta key.
162
- * @param mixed $value Meta value.
163
- * @param mixed $old_value The previous meta value.
164
- * @return mixed
165
  */
166
- function preferred_languages_pre_update_user_meta( $check, $user_id, $meta_key, $value, $old_value ) {
167
- if ( 'preferred_languages' === $meta_key ) {
168
- if ( empty( $old_value ) ) {
169
- $old_value = get_user_meta( $user_id, $meta_key, true );
170
- }
171
 
172
- if ( $value === $old_value ) {
173
- $locales = array_filter( explode( ',', $value ) );
174
- preferred_languages_download_language_packs( $locales );
175
- }
 
 
 
176
  }
177
 
178
- return $check;
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
 
181
  /**
@@ -197,21 +220,23 @@ function preferred_languages_update_user_meta( $meta_id, $object_id, $meta_key,
197
  return;
198
  }
199
 
 
 
 
200
  // Clearing the preferred languages list should also clear the 'locale' user meta
201
  // to prevent stale data.
202
  if ( empty( $meta_value ) ) {
203
  update_user_meta( $object_id, 'locale', '' );
204
  }
205
 
206
- remove_filter( 'update_user_meta', 'preferred_languages_update_user_meta' );
207
-
208
  $locales = array_filter( explode( ',', $meta_value ) );
209
  $installed_languages = preferred_languages_download_language_packs( $locales );
210
 
211
  // Only store actually installed languages in user meta.
212
  update_user_meta( $object_id, 'preferred_languages', implode( ',', $installed_languages ) );
213
 
214
- add_filter( 'update_user_meta', 'preferred_languages_update_user_meta', 10, 4 );
 
215
 
216
  // Reload translations after save.
217
  if ( get_current_user_id() === $object_id ) {
@@ -249,6 +274,7 @@ function preferred_languages_pre_update_option( $value, $option, $old_value ) {
249
  * @param string $value The new option value.
250
  */
251
  function preferred_languages_update_option( $old_value, $value ) {
 
252
  remove_filter( 'update_option_preferred_languages', 'preferred_languages_update_option' );
253
 
254
  $locales = array_filter( explode( ',', $value ) );
@@ -257,6 +283,7 @@ function preferred_languages_update_option( $old_value, $value ) {
257
  // Only store actually installed languages in option.
258
  update_option( 'preferred_languages', implode( ',', $installed_languages ) );
259
 
 
260
  add_filter( 'update_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
261
 
262
  // Reload translations after save.
@@ -272,6 +299,11 @@ function preferred_languages_update_option( $old_value, $value ) {
272
  * @param string $value The new option value.
273
  */
274
  function preferred_languages_update_site_option( $old_value, $value ) {
 
 
 
 
 
275
  remove_filter( 'update_site_option_preferred_languages', 'preferred_languages_update_option' );
276
 
277
  $locales = array_filter( explode( ',', $value ) );
@@ -280,6 +312,7 @@ function preferred_languages_update_site_option( $old_value, $value ) {
280
  // Only store actually installed languages in option.
281
  update_site_option( 'preferred_languages', implode( ',', $installed_languages ) );
282
 
 
283
  add_filter( 'update_site_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
284
 
285
  // Reload translations after save.
@@ -363,11 +396,11 @@ function preferred_languages_filter_locale( $locale ) {
363
  $preferred_languages = preferred_languages_get_network_list();
364
  }
365
 
366
- if ( empty( $preferred_languages ) ) {
367
- return $locale;
368
  }
369
 
370
- return reset( $preferred_languages );
371
  }
372
 
373
  /**
@@ -460,7 +493,7 @@ function preferred_languages_override_load_textdomain( $override, $domain, $mofi
460
  }
461
 
462
  add_filter( 'override_load_textdomain', 'preferred_languages_override_load_textdomain', 10, 3 );
463
- add_filter( 'load_textdomain_mofile', 'preferred_languages_load_textdomain_mofile', 10, 2 );
464
 
465
  if ( null !== $first_mofile ) {
466
  return true;
@@ -475,11 +508,10 @@ function preferred_languages_override_load_textdomain( $override, $domain, $mofi
475
  * @since 1.0.0
476
  *
477
  * @param string $mofile Path to the MO file.
478
- * @param string $domain Text domain. Unique identifier for retrieving translated strings.
479
  *
480
  * @return string The modified MO file path.
481
  */
482
- function preferred_languages_load_textdomain_mofile( $mofile, $domain ) {
483
  $preferred_locales = preferred_languages_get_list();
484
 
485
  if ( empty( $preferred_locales ) ) {
@@ -594,10 +626,6 @@ function preferred_languages_pre_load_script_translations( $translations, $file,
594
  * @return string The modified JSON file path.
595
  */
596
  function preferred_languages_load_script_translation_file( $file ) {
597
- if ( is_readable( $file ) ) {
598
- return $file;
599
- }
600
-
601
  $preferred_locales = preferred_languages_get_list();
602
 
603
  if ( empty( $preferred_locales ) ) {
@@ -651,8 +679,7 @@ function preferred_languages_register_scripts() {
651
  'preferred-languages',
652
  plugins_url( 'build/preferred-languages.css', __DIR__ ),
653
  array(),
654
- $asset['version'],
655
- 'screen'
656
  );
657
 
658
  wp_style_add_data( 'preferred-languages', 'rtl', 'replace' );
@@ -715,6 +742,10 @@ function preferred_languages_network_settings_field() {
715
  * @since 1.7.0
716
  */
717
  function preferred_languages_update_network_settings() {
 
 
 
 
718
  $nonce = isset( $_POST['preferred_languages_network_settings_nonce'] ) ? wp_unslash( $_POST['preferred_languages_network_settings_nonce'] ) : null;
719
 
720
  if ( ! wp_verify_nonce( $nonce, 'preferred_languages_network_settings' ) ) {
@@ -1003,12 +1034,6 @@ function preferred_languages_filter_gettext( $translation, $text, $domain ) {
1003
 
1004
  $path = $preferred_languages_textdomain_registry->get( $domain );
1005
 
1006
- if ( ! $path ) {
1007
- $preferred_languages_textdomain_registry->get_translation_from_lang_dir( $domain );
1008
- }
1009
-
1010
- $path = $preferred_languages_textdomain_registry->get( $domain );
1011
-
1012
  if ( ! $path ) {
1013
  return $translation;
1014
  }
@@ -1034,3 +1059,24 @@ function preferred_languages_filter_gettext( $translation, $text, $domain ) {
1034
 
1035
  return $translation;
1036
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  * @param int $user_id The user ID.
52
  */
53
  function preferred_languages_update_user_option( $user_id ) {
54
+ if ( ! isset( $_POST['_wpnonce'], $_POST['preferred_languages'] ) ) {
55
+ return;
56
+ }
57
+
58
+ if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'update-user_' . $user_id ) ) {
59
+ return;
60
  }
61
+
62
+ if ( ! current_user_can( 'edit_user', $user_id ) ) {
63
+ return;
64
+ }
65
+
66
+ update_user_meta( $user_id, 'preferred_languages', $_POST['preferred_languages'] );
67
  }
68
 
69
  /**
160
  }
161
 
162
  /**
163
+ * Hooks into user meta additions.
164
  *
165
+ * Downloads language pack when populating list of preferred languages.
166
  *
167
+ * Also updates the 'locale' user meta if the list is empty.
168
  *
169
+ * @since 1.7.2
170
+ *
171
+ * @param int $object_id Object ID.
172
+ * @param string $meta_key Meta key.
173
+ * @param mixed $meta_value Meta value.
 
174
  */
175
+ function preferred_languages_add_user_meta( $object_id, $meta_key, $meta_value ) {
176
+ if ( 'preferred_languages' !== $meta_key ) {
177
+ return;
178
+ }
 
179
 
180
+ remove_action( 'add_user_meta', 'preferred_languages_add_user_meta' );
181
+ remove_action( 'update_user_meta', 'preferred_languages_update_user_meta' );
182
+
183
+ // Clearing the preferred languages list should also clear the 'locale' user meta
184
+ // to prevent stale data.
185
+ if ( empty( $meta_value ) ) {
186
+ update_user_meta( $object_id, 'locale', '' );
187
  }
188
 
189
+ $locales = array_filter( explode( ',', $meta_value ) );
190
+ $installed_languages = preferred_languages_download_language_packs( $locales );
191
+
192
+ // Only store actually installed languages in user meta.
193
+ update_user_meta( $object_id, 'preferred_languages', implode( ',', $installed_languages ) );
194
+
195
+ add_action( 'add_user_meta', 'preferred_languages_add_user_meta', 10, 3 );
196
+ add_action( 'update_user_meta', 'preferred_languages_update_user_meta', 10, 4 );
197
+
198
+ // Reload translations after save.
199
+ if ( get_current_user_id() === $object_id ) {
200
+ load_default_textdomain( determine_locale() );
201
+ }
202
  }
203
 
204
  /**
220
  return;
221
  }
222
 
223
+ remove_action( 'add_user_meta', 'preferred_languages_add_user_meta' );
224
+ remove_action( 'update_user_meta', 'preferred_languages_update_user_meta' );
225
+
226
  // Clearing the preferred languages list should also clear the 'locale' user meta
227
  // to prevent stale data.
228
  if ( empty( $meta_value ) ) {
229
  update_user_meta( $object_id, 'locale', '' );
230
  }
231
 
 
 
232
  $locales = array_filter( explode( ',', $meta_value ) );
233
  $installed_languages = preferred_languages_download_language_packs( $locales );
234
 
235
  // Only store actually installed languages in user meta.
236
  update_user_meta( $object_id, 'preferred_languages', implode( ',', $installed_languages ) );
237
 
238
+ add_action( 'add_user_meta', 'preferred_languages_add_user_meta', 10, 3 );
239
+ add_action( 'update_user_meta', 'preferred_languages_update_user_meta', 10, 4 );
240
 
241
  // Reload translations after save.
242
  if ( get_current_user_id() === $object_id ) {
274
  * @param string $value The new option value.
275
  */
276
  function preferred_languages_update_option( $old_value, $value ) {
277
+ remove_filter( 'add_option_preferred_languages', 'preferred_languages_update_option' );
278
  remove_filter( 'update_option_preferred_languages', 'preferred_languages_update_option' );
279
 
280
  $locales = array_filter( explode( ',', $value ) );
283
  // Only store actually installed languages in option.
284
  update_option( 'preferred_languages', implode( ',', $installed_languages ) );
285
 
286
+ add_filter( 'add_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
287
  add_filter( 'update_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
288
 
289
  // Reload translations after save.
299
  * @param string $value The new option value.
300
  */
301
  function preferred_languages_update_site_option( $old_value, $value ) {
302
+ if ( ! is_multisite() ) {
303
+ return;
304
+ }
305
+
306
+ remove_filter( 'add_site_option_preferred_languages', 'preferred_languages_update_option' );
307
  remove_filter( 'update_site_option_preferred_languages', 'preferred_languages_update_option' );
308
 
309
  $locales = array_filter( explode( ',', $value ) );
312
  // Only store actually installed languages in option.
313
  update_site_option( 'preferred_languages', implode( ',', $installed_languages ) );
314
 
315
+ add_filter( 'add_site_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
316
  add_filter( 'update_site_option_preferred_languages', 'preferred_languages_update_option', 10, 2 );
317
 
318
  // Reload translations after save.
396
  $preferred_languages = preferred_languages_get_network_list();
397
  }
398
 
399
+ if ( ! empty( $preferred_languages ) ) {
400
+ return reset( $preferred_languages );
401
  }
402
 
403
+ return $locale;
404
  }
405
 
406
  /**
493
  }
494
 
495
  add_filter( 'override_load_textdomain', 'preferred_languages_override_load_textdomain', 10, 3 );
496
+ add_filter( 'load_textdomain_mofile', 'preferred_languages_load_textdomain_mofile' );
497
 
498
  if ( null !== $first_mofile ) {
499
  return true;
508
  * @since 1.0.0
509
  *
510
  * @param string $mofile Path to the MO file.
 
511
  *
512
  * @return string The modified MO file path.
513
  */
514
+ function preferred_languages_load_textdomain_mofile( $mofile ) {
515
  $preferred_locales = preferred_languages_get_list();
516
 
517
  if ( empty( $preferred_locales ) ) {
626
  * @return string The modified JSON file path.
627
  */
628
  function preferred_languages_load_script_translation_file( $file ) {
 
 
 
 
629
  $preferred_locales = preferred_languages_get_list();
630
 
631
  if ( empty( $preferred_locales ) ) {
679
  'preferred-languages',
680
  plugins_url( 'build/preferred-languages.css', __DIR__ ),
681
  array(),
682
+ $asset['version']
 
683
  );
684
 
685
  wp_style_add_data( 'preferred-languages', 'rtl', 'replace' );
742
  * @since 1.7.0
743
  */
744
  function preferred_languages_update_network_settings() {
745
+ if ( ! is_multisite() ) {
746
+ return;
747
+ }
748
+
749
  $nonce = isset( $_POST['preferred_languages_network_settings_nonce'] ) ? wp_unslash( $_POST['preferred_languages_network_settings_nonce'] ) : null;
750
 
751
  if ( ! wp_verify_nonce( $nonce, 'preferred_languages_network_settings' ) ) {
1034
 
1035
  $path = $preferred_languages_textdomain_registry->get( $domain );
1036
 
 
 
 
 
 
 
1037
  if ( ! $path ) {
1038
  return $translation;
1039
  }
1059
 
1060
  return $translation;
1061
  }
1062
+
1063
+ /**
1064
+ * Filters debug information to include Preferred Languages data.
1065
+ *
1066
+ * @since 1.8.0
1067
+ *
1068
+ * @param array $args The debug information to be added to the core information page.
1069
+ *
1070
+ * @return array Filtered debug information.
1071
+ */
1072
+ function preferred_languages_filter_debug_information( $args ) {
1073
+ if ( isset( $args['wp-core']['fields']['site_language']['value'] ) ) {
1074
+ $args['wp-core']['fields']['site_language']['value'] = implode( ', ', preferred_languages_get_site_list() );
1075
+ }
1076
+
1077
+ if ( isset( $args['wp-core']['fields']['user_language']['value'] ) ) {
1078
+ $args['wp-core']['fields']['user_language']['value'] = implode( ', ', preferred_languages_get_list() );
1079
+ }
1080
+
1081
+ return $args;
1082
+ }
preferred-languages.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Preferred Languages
4
  * Plugin URI: https://github.com/swissspidy/preferred-languages/
5
  * Description: Choose languages for displaying WordPress in, in order of preference.
6
- * Version: 1.7.1
7
  * Author: Pascal Birchler
8
  * Author URI: https://pascalbirchler.com
9
  * License: GPL-2.0+
3
  * Plugin Name: Preferred Languages
4
  * Plugin URI: https://github.com/swissspidy/preferred-languages/
5
  * Description: Choose languages for displaying WordPress in, in order of preference.
6
+ * Version: 1.8.0
7
  * Author: Pascal Birchler
8
  * Author URI: https://pascalbirchler.com
9
  * License: GPL-2.0+
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Preferred Languages ===
2
  Contributors: swissspidy
3
  Tags: internationalization, i18n, localization, l10n, language, locale, translation
4
- Tested up to: 5.8
5
- Stable tag: 1.7.1
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
 
@@ -33,6 +33,10 @@ For the plugin's changelog, please head over to [the GitHub repository](https://
33
 
34
  == Upgrade Notice ==
35
 
 
 
 
 
36
  = 1.7.1 =
37
 
38
  This release contains improvements to translation merging and fixes issues with the user language not being correctly applied.
1
  === Preferred Languages ===
2
  Contributors: swissspidy
3
  Tags: internationalization, i18n, localization, l10n, language, locale, translation
4
+ Tested up to: 5.9
5
+ Stable tag: 1.8.0
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
 
33
 
34
  == Upgrade Notice ==
35
 
36
+ = 1.8.0 =
37
+
38
+ This release contains various smaller bugfixes, Site Health integration, as well as improved compatibility with other plugins such as WPML.
39
+
40
  = 1.7.1 =
41
 
42
  This release contains improvements to translation merging and fixes issues with the user language not being correctly applied.