Polylang - Version 3.1

Version Description

(2021-07-27) =

  • Add compatibility with WordPress 5.8
  • Raise Minimum WordPress version to 5.4
  • Pro: Allow to filter blocks by language in the widget block editor
  • Pro: Allow to export and import XLIFF files for string translations
  • Pro: Add the language switcher in the navigation block (experimental)
  • Pro: Replace dashicons by svg icons in the block editor
  • Pro: The Events Calendar: Add compatibility with Views V2 (only for sites using only one domain)
  • Pro: Fix + icon displayed in the block editor sidebar when the user cannot create a translation
  • Add a warning section to the site health for posts and terms without languages #825
  • Require the simplexml extension in the site health if a wpml-config.xml is found #827
  • Remove the information about the WPML compabitility mode in settings #843
  • The browser preferred language detection is now deactivated by default
  • The media are now untranslated by default
  • Highlight the language filter in the admin toolbar when it's active #821
  • Allow to query comments in multiple languages (just as posts and terms) #840
  • Don't disable the translation input field in the classic metabox #841 Props Onatcer
  • Optimize all images including flags #848 Props lowwebtech
  • Don't redirect if WordPress doesn't validate the redirect url to avoid redirects to /wp-admin/ #879
  • Fix media appearing to have a language after the language is changed in the media library grid view #807
  • Fix media not all deleted when bulk deleting from the grid view of the media library #830
  • Fix when more than one language switcher are added to the same menu #853
  • Fix PHP notice when adding a CPT archive link to a menu #868 Props davidwebca
Download this release

Release Info

Developer Chouby
Plugin Icon 128x128 Polylang
Version 3.1
Comparing to
See all releases

Code changes from version 3.0.6 to 3.1

Files changed (350) hide show
  1. admin/admin-base.php +21 -8
  2. admin/admin-block-editor.php +2 -2
  3. admin/admin-classic-editor.php +8 -12
  4. admin/admin-default-term.php +268 -0
  5. admin/admin-filters-columns.php +0 -5
  6. admin/admin-filters-media.php +2 -6
  7. admin/admin-filters-post-base.php +1 -8
  8. admin/admin-filters-post.php +5 -47
  9. admin/admin-filters-term.php +17 -65
  10. admin/admin-filters-widgets-options.php +1 -21
  11. admin/admin-model.php +8 -81
  12. admin/admin-nav-menu.php +1 -1
  13. admin/admin.php +2 -2
  14. admin/block-editor-filter-preload-paths.php +59 -0
  15. admin/view-translations-post.php +1 -2
  16. css/admin.css +0 -457
  17. css/build/admin.css +37 -10
  18. css/build/admin.min.css +1 -1
  19. css/build/dialog.min.css +1 -1
  20. css/build/selectmenu.min.css +1 -1
  21. css/build/wizard.min.css +1 -1
  22. css/dialog.css +0 -85
  23. css/selectmenu.css +0 -239
  24. flags/ad.png +0 -0
  25. flags/ae.png +0 -0
  26. flags/af.png +0 -0
  27. flags/ag.png +0 -0
  28. flags/ai.png +0 -0
  29. flags/al.png +0 -0
  30. flags/am.png +0 -0
  31. flags/an.png +0 -0
  32. flags/ao.png +0 -0
  33. flags/ar.png +0 -0
  34. flags/arab.png +0 -0
  35. flags/as.png +0 -0
  36. flags/at.png +0 -0
  37. flags/au.png +0 -0
  38. flags/aw.png +0 -0
  39. flags/ax.png +0 -0
  40. flags/az.png +0 -0
  41. flags/ba.png +0 -0
  42. flags/basque.png +0 -0
  43. flags/bb.png +0 -0
  44. flags/bd.png +0 -0
  45. flags/be.png +0 -0
  46. flags/bf.png +0 -0
  47. flags/bg.png +0 -0
  48. flags/bh.png +0 -0
  49. flags/bi.png +0 -0
  50. flags/bj.png +0 -0
  51. flags/bm.png +0 -0
  52. flags/bn.png +0 -0
  53. flags/bo.png +0 -0
  54. flags/br.png +0 -0
  55. flags/bs.png +0 -0
  56. flags/bt.png +0 -0
  57. flags/bw.png +0 -0
  58. flags/by.png +0 -0
  59. flags/bz.png +0 -0
  60. flags/ca.png +0 -0
  61. flags/catalonia.png +0 -0
  62. flags/cc.png +0 -0
  63. flags/cd.png +0 -0
  64. flags/cf.png +0 -0
  65. flags/cg.png +0 -0
  66. flags/ch.png +0 -0
  67. flags/ci.png +0 -0
  68. flags/ck.png +0 -0
  69. flags/cl.png +0 -0
  70. flags/cm.png +0 -0
  71. flags/cn.png +0 -0
  72. flags/co.png +0 -0
  73. flags/cr.png +0 -0
  74. flags/cu.png +0 -0
  75. flags/cv.png +0 -0
  76. flags/cx.png +0 -0
  77. flags/cy.png +0 -0
  78. flags/cz.png +0 -0
  79. flags/de.png +0 -0
  80. flags/dj.png +0 -0
  81. flags/dk.png +0 -0
  82. flags/dm.png +0 -0
  83. flags/do.png +0 -0
  84. flags/dz.png +0 -0
  85. flags/ec.png +0 -0
  86. flags/ee.png +0 -0
  87. flags/eg.png +0 -0
  88. flags/eh.png +0 -0
  89. flags/england.png +0 -0
  90. flags/er.png +0 -0
  91. flags/es.png +0 -0
  92. flags/esperanto.png +0 -0
  93. flags/et.png +0 -0
  94. flags/fi.png +0 -0
  95. flags/fj.png +0 -0
  96. flags/fk.png +0 -0
  97. flags/fm.png +0 -0
  98. flags/fo.png +0 -0
  99. flags/fr.png +0 -0
  100. flags/ga.png +0 -0
  101. flags/galicia.png +0 -0
  102. flags/gb.png +0 -0
  103. flags/gd.png +0 -0
  104. flags/ge.png +0 -0
  105. flags/gh.png +0 -0
  106. flags/gi.png +0 -0
  107. flags/gl.png +0 -0
  108. flags/gm.png +0 -0
  109. flags/gn.png +0 -0
  110. flags/gp.png +0 -0
  111. flags/gq.png +0 -0
  112. flags/gr.png +0 -0
  113. flags/gs.png +0 -0
  114. flags/gt.png +0 -0
  115. flags/gu.png +0 -0
  116. flags/gw.png +0 -0
  117. flags/gy.png +0 -0
  118. flags/hk.png +0 -0
  119. flags/hm.png +0 -0
  120. flags/hn.png +0 -0
  121. flags/hr.png +0 -0
  122. flags/ht.png +0 -0
  123. flags/hu.png +0 -0
  124. flags/id.png +0 -0
  125. flags/ie.png +0 -0
  126. flags/il.png +0 -0
  127. flags/in.png +0 -0
  128. flags/io.png +0 -0
  129. flags/iq.png +0 -0
  130. flags/ir.png +0 -0
  131. flags/is.png +0 -0
  132. flags/it.png +0 -0
  133. flags/jm.png +0 -0
  134. flags/jo.png +0 -0
  135. flags/jp.png +0 -0
  136. flags/ke.png +0 -0
  137. flags/kg.png +0 -0
  138. flags/kh.png +0 -0
  139. flags/ki.png +0 -0
  140. flags/km.png +0 -0
  141. flags/kn.png +0 -0
  142. flags/kp.png +0 -0
  143. flags/kr.png +0 -0
  144. flags/kurdistan.png +0 -0
  145. flags/kw.png +0 -0
  146. flags/ky.png +0 -0
  147. flags/kz.png +0 -0
  148. flags/la.png +0 -0
  149. flags/lb.png +0 -0
  150. flags/lc.png +0 -0
  151. flags/li.png +0 -0
  152. flags/lk.png +0 -0
  153. flags/lr.png +0 -0
  154. flags/ls.png +0 -0
  155. flags/lt.png +0 -0
  156. flags/lu.png +0 -0
  157. flags/lv.png +0 -0
  158. flags/ly.png +0 -0
  159. flags/ma.png +0 -0
  160. flags/mc.png +0 -0
  161. flags/md.png +0 -0
  162. flags/me.png +0 -0
  163. flags/mg.png +0 -0
  164. flags/mh.png +0 -0
  165. flags/mk.png +0 -0
  166. flags/ml.png +0 -0
  167. flags/mm.png +0 -0
  168. flags/mn.png +0 -0
  169. flags/mo.png +0 -0
  170. flags/mp.png +0 -0
  171. flags/mq.png +0 -0
  172. flags/mr.png +0 -0
  173. flags/ms.png +0 -0
  174. flags/mt.png +0 -0
  175. flags/mu.png +0 -0
  176. flags/mv.png +0 -0
  177. flags/mw.png +0 -0
  178. flags/mx.png +0 -0
  179. flags/my.png +0 -0
  180. flags/mz.png +0 -0
  181. flags/na.png +0 -0
  182. flags/nc.png +0 -0
  183. flags/ne.png +0 -0
  184. flags/nf.png +0 -0
  185. flags/ng.png +0 -0
  186. flags/ni.png +0 -0
  187. flags/nl.png +0 -0
  188. flags/no.png +0 -0
  189. flags/np.png +0 -0
  190. flags/nr.png +0 -0
  191. flags/nu.png +0 -0
  192. flags/nz.png +0 -0
  193. flags/occitania.png +0 -0
  194. flags/om.png +0 -0
  195. flags/pa.png +0 -0
  196. flags/pe.png +0 -0
  197. flags/pf.png +0 -0
  198. flags/pg.png +0 -0
  199. flags/ph.png +0 -0
  200. flags/pk.png +0 -0
  201. flags/pl.png +0 -0
  202. flags/pm.png +0 -0
  203. flags/pn.png +0 -0
  204. flags/pr.png +0 -0
  205. flags/ps.png +0 -0
  206. flags/pt.png +0 -0
  207. flags/pw.png +0 -0
  208. flags/py.png +0 -0
  209. flags/qa.png +0 -0
  210. flags/quebec.png +0 -0
  211. flags/ro.png +0 -0
  212. flags/rs.png +0 -0
  213. flags/ru.png +0 -0
  214. flags/rw.png +0 -0
  215. flags/sa.png +0 -0
  216. flags/sb.png +0 -0
  217. flags/sc.png +0 -0
  218. flags/scotland.png +0 -0
  219. flags/sd.png +0 -0
  220. flags/se.png +0 -0
  221. flags/sg.png +0 -0
  222. flags/sh.png +0 -0
  223. flags/si.png +0 -0
  224. flags/sk.png +0 -0
  225. flags/sl.png +0 -0
  226. flags/sm.png +0 -0
  227. flags/sn.png +0 -0
  228. flags/so.png +0 -0
  229. flags/sr.png +0 -0
  230. flags/ss.png +0 -0
  231. flags/st.png +0 -0
  232. flags/sv.png +0 -0
  233. flags/sy.png +0 -0
  234. flags/sz.png +0 -0
  235. flags/tc.png +0 -0
  236. flags/td.png +0 -0
  237. flags/tf.png +0 -0
  238. flags/tg.png +0 -0
  239. flags/th.png +0 -0
  240. flags/tibet.png +0 -0
  241. flags/tj.png +0 -0
  242. flags/tk.png +0 -0
  243. flags/tl.png +0 -0
  244. flags/tm.png +0 -0
  245. flags/tn.png +0 -0
  246. flags/to.png +0 -0
  247. flags/tr.png +0 -0
  248. flags/tt.png +0 -0
  249. flags/tv.png +0 -0
  250. flags/tw.png +0 -0
  251. flags/tz.png +0 -0
  252. flags/ua.png +0 -0
  253. flags/ug.png +0 -0
  254. flags/us.png +0 -0
  255. flags/uy.png +0 -0
  256. flags/uz.png +0 -0
  257. flags/va.png +0 -0
  258. flags/vc.png +0 -0
  259. flags/ve.png +0 -0
  260. flags/veneto.png +0 -0
  261. flags/vg.png +0 -0
  262. flags/vi.png +0 -0
  263. flags/vn.png +0 -0
  264. flags/vu.png +0 -0
  265. flags/wales.png +0 -0
  266. flags/wf.png +0 -0
  267. flags/ws.png +0 -0
  268. flags/ye.png +0 -0
  269. flags/yt.png +0 -0
  270. flags/za.png +0 -0
  271. flags/zm.png +0 -0
  272. flags/zw.png +0 -0
  273. frontend/accept-language.php +3 -3
  274. frontend/accept-languages-collection.php +0 -6
  275. frontend/choose-lang.php +2 -1
  276. frontend/frontend-filters-links.php +1 -1
  277. frontend/frontend-filters-search.php +1 -1
  278. frontend/frontend-filters-widgets.php +155 -0
  279. frontend/frontend-filters.php +1 -62
  280. frontend/frontend-nav-menu.php +9 -4
  281. frontend/frontend.php +6 -0
  282. include/crud-posts.php +7 -7
  283. include/filters-widgets-options.php +12 -24
  284. include/filters.php +31 -42
  285. include/model.php +107 -38
  286. include/nav-menu.php +1 -1
  287. include/olt-manager.php +1 -1
  288. include/rest-request.php +2 -2
  289. include/switcher.php +30 -16
  290. include/translated-object.php +52 -2
  291. include/translated-post.php +1 -0
  292. include/walker-list.php +3 -2
  293. include/widget-languages.php +1 -1
  294. install/install.php +9 -9
  295. install/plugin-updater.php +0 -3
  296. js/admin.js +0 -415
  297. js/block-editor.js +0 -252
  298. js/build/admin.js +1 -0
  299. js/build/admin.min.js +1 -1
  300. js/build/block-editor.js +3 -2
  301. js/build/block-editor.min.js +1 -1
  302. js/build/classic-editor.js +3 -2
  303. js/build/classic-editor.min.js +1 -1
  304. js/build/languages-step.js +1 -0
  305. js/build/languages-step.min.js +1 -1
  306. js/build/nav-menu.js +1 -0
  307. js/build/nav-menu.min.js +1 -1
  308. js/build/post.js +1 -0
  309. js/build/post.min.js +1 -1
  310. js/build/term.js +1 -0
  311. js/build/term.min.js +1 -1
  312. js/build/user.js +1 -0
  313. js/build/user.min.js +1 -1
  314. js/build/widgets.js +59 -39
  315. js/build/widgets.min.js +1 -1
  316. js/classic-editor.js +0 -341
  317. js/lib/confirmation-modal.js +0 -99
  318. js/nav-menu.js +0 -104
  319. js/post.js +0 -177
  320. js/term.js +0 -221
  321. js/user.js +0 -33
  322. js/widgets.js +0 -132
  323. modules/lingotek/image01.gif +0 -0
  324. modules/lingotek/image02.png +0 -0
  325. modules/lingotek/image03.png +0 -0
  326. modules/lingotek/image04.png +0 -0
  327. modules/share-slug/load.php +1 -1
  328. modules/share-slug/settings-preview-share-slug.php +70 -0
  329. modules/share-slug/settings-share-slug.php +0 -97
  330. modules/site-health/admin-site-health.php +95 -7
  331. modules/sync/admin-sync.php +9 -6
  332. modules/translate-slugs/load.php +1 -1
  333. modules/translate-slugs/settings-preview-translate-slugs.php +70 -0
  334. modules/translate-slugs/settings-translate-slugs.php +0 -58
  335. modules/wizard/images/media-screen-rtl.png +0 -0
  336. modules/wizard/images/media-screen.png +0 -0
  337. modules/wizard/images/polylang-logo.png +0 -0
  338. modules/wizard/view-wizard-step-media.php +1 -1
  339. modules/wpml/load.php +3 -11
  340. modules/wpml/settings-wpml.php +0 -47
  341. modules/wpml/wpml-config.php +66 -22
  342. polylang.php +4 -4
  343. readme.txt +29 -4
  344. settings/settings-browser.php +1 -1
  345. settings/settings-media.php +1 -1
  346. settings/settings-url.php +2 -1
  347. settings/table-string.php +2 -1
  348. settings/view-tab-lang.php +1 -1
  349. vendor/composer/autoload_classmap.php +5 -3
  350. vendor/composer/autoload_static.php +5 -3
admin/admin-base.php CHANGED
@@ -50,6 +50,11 @@ abstract class PLL_Admin_Base extends PLL_Base {
50
  */
51
  public $static_pages;
52
 
 
 
 
 
 
53
  /**
54
  * Setups actions needed on all admin pages.
55
  *
@@ -88,6 +93,8 @@ abstract class PLL_Admin_Base extends PLL_Base {
88
  $this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
89
  $this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ?
90
  $this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
 
 
91
 
92
  // Filter admin language for users
93
  // We must not call user info before WordPress defines user roles in wp-settings.php
@@ -457,15 +464,21 @@ abstract class PLL_Admin_Base extends PLL_Base {
457
  */
458
  $items = apply_filters( 'pll_admin_languages_filter', array_merge( array( $all_item ), $this->model->get_languages_list() ) );
459
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  if ( ! empty( $items ) ) {
461
- $wp_admin_bar->add_menu(
462
- array(
463
- 'id' => 'languages',
464
- 'title' => $selected->flag . $title,
465
- 'href' => esc_url( add_query_arg( 'lang', $selected->slug, remove_query_arg( 'paged' ) ) ),
466
- 'meta' => array( 'title' => __( 'Filters content by language', 'polylang' ) ),
467
- )
468
- );
469
  }
470
 
471
  foreach ( $items as $lang ) {
50
  */
51
  public $static_pages;
52
 
53
+ /**
54
+ * @var PLL_Admin_Default_Term
55
+ */
56
+ public $default_term;
57
+
58
  /**
59
  * Setups actions needed on all admin pages.
60
  *
93
  $this->links = new PLL_Admin_Links( $this ); // FIXME needed here ?
94
  $this->static_pages = new PLL_Admin_Static_Pages( $this ); // FIXME needed here ?
95
  $this->filters_links = new PLL_Filters_Links( $this ); // FIXME needed here ?
96
+ $this->default_term = new PLL_Admin_Default_Term( $this );
97
+ $this->default_term->add_hooks();
98
 
99
  // Filter admin language for users
100
  // We must not call user info before WordPress defines user roles in wp-settings.php
464
  */
465
  $items = apply_filters( 'pll_admin_languages_filter', array_merge( array( $all_item ), $this->model->get_languages_list() ) );
466
 
467
+ $menu = array(
468
+ 'id' => 'languages',
469
+ 'title' => $selected->flag . $title,
470
+ 'href' => esc_url( add_query_arg( 'lang', $selected->slug, remove_query_arg( 'paged' ) ) ),
471
+ 'meta' => array(
472
+ 'title' => __( 'Filters content by language', 'polylang' ),
473
+ ),
474
+ );
475
+
476
+ if ( 'all' !== $selected->slug ) {
477
+ $menu['meta']['class'] = 'pll-filtered-languages';
478
+ }
479
+
480
  if ( ! empty( $items ) ) {
481
+ $wp_admin_bar->add_menu( $menu );
 
 
 
 
 
 
 
482
  }
483
 
484
  foreach ( $items as $lang ) {
admin/admin-block-editor.php CHANGED
@@ -32,7 +32,7 @@ class PLL_Admin_Block_Editor {
32
  $this->model = &$polylang->model;
33
  $this->pref_lang = &$polylang->pref_lang;
34
 
35
- add_filter( 'block_editor_preload_paths', array( $this, 'preload_paths' ), 10, 2 );
36
  }
37
 
38
  /**
@@ -47,7 +47,7 @@ class PLL_Admin_Block_Editor {
47
  * @return (string|string[])[]
48
  */
49
  public function preload_paths( $preload_paths, $post ) {
50
- if ( $this->model->is_translated_post_type( $post->post_type ) ) {
51
  $lang = $this->model->post->get_language( $post->ID );
52
 
53
  if ( ! $lang ) {
32
  $this->model = &$polylang->model;
33
  $this->pref_lang = &$polylang->pref_lang;
34
 
35
+ new PLL_Block_Editor_Filter_Preload_Paths( array( $this, 'preload_paths' ), 10, 2 );
36
  }
37
 
38
  /**
47
  * @return (string|string[])[]
48
  */
49
  public function preload_paths( $preload_paths, $post ) {
50
+ if ( $post instanceof WP_Post && $this->model->is_translated_post_type( $post->post_type ) ) {
51
  $lang = $this->model->post->get_language( $post->ID );
52
 
53
  if ( ! $lang ) {
admin/admin-classic-editor.php CHANGED
@@ -159,34 +159,30 @@ class PLL_Admin_Classic_Editor {
159
  check_ajax_referer( 'pll_language', '_pll_nonce' );
160
 
161
  if ( ! isset( $_POST['post_id'], $_POST['lang'], $_POST['post_type'] ) ) {
162
- wp_die( 0 );
163
  }
164
 
165
  global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
166
  $post_ID = (int) $_POST['post_id'];
167
- $lang = $this->model->get_language( sanitize_key( $_POST['lang'] ) );
 
168
  $post_type = sanitize_key( $_POST['post_type'] );
169
 
170
- if ( empty( $lang ) || ! post_type_exists( $post_type ) ) {
171
- wp_die( 0 );
172
  }
173
 
174
  $post_type_object = get_post_type_object( $post_type );
175
 
176
  if ( empty( $post_type_object ) ) {
177
- wp_die( 0 );
178
  }
179
 
180
  if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
181
- wp_die( -1 );
182
  }
183
 
184
- $this->model->post->set_language( $post_ID, $lang ); // Save language, useful to set the language when uploading media from post
185
-
186
- // We also need to save the translations to match the language change
187
- $translations = $this->model->post->get_translations( $post_ID );
188
- $translations = array_diff( $translations, array( $post_ID ) );
189
- $this->model->post->save_translations( $post_ID, $translations );
190
 
191
  ob_start();
192
  if ( 'attachment' === $post_type ) {
159
  check_ajax_referer( 'pll_language', '_pll_nonce' );
160
 
161
  if ( ! isset( $_POST['post_id'], $_POST['lang'], $_POST['post_type'] ) ) {
162
+ wp_die( 'The request is missing the parameter "post_type", "lang" and/or "post_id".' );
163
  }
164
 
165
  global $post_ID; // Obliged to use the global variable for wp_popular_terms_checklist
166
  $post_ID = (int) $_POST['post_id'];
167
+ $lang_slug = sanitize_key( $_POST['lang'] );
168
+ $lang = $this->model->get_language( $lang_slug );
169
  $post_type = sanitize_key( $_POST['post_type'] );
170
 
171
+ if ( empty( $lang ) ) {
172
+ wp_die( esc_html( "{$lang_slug} is not a valid language code." ) );
173
  }
174
 
175
  $post_type_object = get_post_type_object( $post_type );
176
 
177
  if ( empty( $post_type_object ) ) {
178
+ wp_die( esc_html( "{$post_type} is not a valid post type." ) );
179
  }
180
 
181
  if ( ! current_user_can( $post_type_object->cap->edit_post, $post_ID ) ) {
182
+ wp_die( 'You are not allowed to edit this post.' );
183
  }
184
 
185
+ $this->model->post->update_language( $post_ID, $lang );
 
 
 
 
 
186
 
187
  ob_start();
188
  if ( 'attachment' === $post_type ) {
admin/admin-default-term.php ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Polylang
4
+ */
5
+
6
+ /**
7
+ * Manages filters and actions related to default terms.
8
+ *
9
+ * @since 3.1
10
+ */
11
+ class PLL_Admin_Default_Term {
12
+
13
+ /**
14
+ * A reference to the PLL_Model instance.
15
+ *
16
+ * @var PLL_Model
17
+ */
18
+ protected $model;
19
+
20
+ /**
21
+ * Preferred language to assign to new contents.
22
+ *
23
+ * @var PLL_Language
24
+ */
25
+ protected $pref_lang;
26
+
27
+ /**
28
+ * Reference to Polylang options array
29
+ *
30
+ * @var array
31
+ */
32
+ protected $options;
33
+
34
+ /**
35
+ * Array of registered taxonomy names for which Polylang manages languages and translations.
36
+ *
37
+ * @var string[]
38
+ */
39
+ protected $taxonomies;
40
+
41
+ /**
42
+ * Constructor: setups properties.
43
+ *
44
+ * @since 3.1
45
+ *
46
+ * @param object $polylang
47
+ */
48
+ public function __construct( &$polylang ) {
49
+ $this->model = &$polylang->model;
50
+ $this->pref_lang = &$polylang->pref_lang;
51
+ $this->options = &$polylang->options;
52
+ $this->taxonomies = $this->model->get_translated_taxonomies();
53
+ }
54
+
55
+ /**
56
+ * Setups filters and actions needed.
57
+ *
58
+ * @since 3.1
59
+ *
60
+ * @return void
61
+ */
62
+ public function add_hooks() {
63
+ foreach ( $this->taxonomies as $taxonomy ) {
64
+ if ( 'category' === $taxonomy ) {
65
+ // Allows to get the default terms in all languages
66
+ add_filter( 'option_default_' . $taxonomy, array( $this, 'option_default_term' ) );
67
+ add_action( 'update_option_default_' . $taxonomy, array( $this, 'update_option_default_term' ), 10, 2 );
68
+
69
+ // Adds the language column in the 'Terms' table.
70
+ add_filter( 'manage_' . $taxonomy . '_custom_column', array( $this, 'term_column' ), 10, 3 );
71
+ }
72
+ }
73
+ add_action( 'pll_add_language', array( $this, 'handle_default_term_on_create_language' ) );
74
+
75
+ // The default term should be in the default language
76
+ add_action( 'pll_update_default_lang', array( $this, 'update_default_term_language' ) );
77
+
78
+ // Prevents deleting all the translations of the default term
79
+ add_filter( 'map_meta_cap', array( $this, 'fix_delete_default_term' ), 10, 4 );
80
+ }
81
+
82
+ /**
83
+ * Filters the default term in note below the term list table and in settings->writing dropdown
84
+ *
85
+ * @since 1.2
86
+ *
87
+ * @param int $taxonomy_term_id The taxonomy term id.
88
+ * @return int A taxonomy term id.
89
+ */
90
+ public function option_default_term( $taxonomy_term_id ) {
91
+ if ( isset( $this->pref_lang ) && $tr = $this->model->term->get( $taxonomy_term_id, $this->pref_lang ) ) {
92
+ $taxonomy_term_id = $tr;
93
+ }
94
+ return $taxonomy_term_id;
95
+ }
96
+
97
+ /**
98
+ * Checks if the new default term is translated in all languages
99
+ * If not, create the translations
100
+ *
101
+ * @since 1.7
102
+ *
103
+ * @param int $old_value The old option value.
104
+ * @param int $value The new option value.
105
+ * @return void
106
+ */
107
+ public function update_option_default_term( $old_value, $value ) {
108
+ $default_cat_lang = $this->model->term->get_language( $value );
109
+
110
+ // Assign a default language to default term
111
+ if ( ! $default_cat_lang ) {
112
+ $default_cat_lang = $this->model->get_language( $this->options['default_lang'] );
113
+ $this->model->term->set_language( (int) $value, $default_cat_lang );
114
+ }
115
+
116
+ $taxonomy = substr( current_filter(), 22 );
117
+
118
+ foreach ( $this->model->get_languages_list() as $language ) {
119
+ if ( $language->slug != $default_cat_lang->slug && ! $this->model->term->get_translation( $value, $language ) ) {
120
+ $this->create_default_term( $language, $taxonomy );
121
+ }
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Create a default term for a language
127
+ *
128
+ * @since 1.2
129
+ *
130
+ * @param object|string|int $lang language
131
+ * @param string $taxonomy The current taxonomy
132
+ * @return void
133
+ */
134
+ public function create_default_term( $lang, $taxonomy ) {
135
+ $lang = $this->model->get_language( $lang );
136
+
137
+ // create a new term
138
+ // FIXME this is translated in admin language when we would like it in $lang
139
+ $cat_name = __( 'Uncategorized', 'polylang' );
140
+ $cat_slug = sanitize_title( $cat_name . '-' . $lang->slug );
141
+ $cat = wp_insert_term( $cat_name, $taxonomy, array( 'slug' => $cat_slug ) );
142
+
143
+ // check that the term was not previously created ( in case the language was deleted and recreated )
144
+ $cat = isset( $cat->error_data['term_exists'] ) ? $cat->error_data['term_exists'] : $cat['term_id'];
145
+
146
+ // set language
147
+ $this->model->term->set_language( (int) $cat, $lang );
148
+
149
+ // this is a translation of the default term
150
+ $default = (int) get_option( 'default_' . $taxonomy );
151
+ $translations = $this->model->term->get_translations( $default );
152
+
153
+ $this->model->term->save_translations( (int) $cat, $translations );
154
+ }
155
+
156
+ /**
157
+ * Manages the default term when new languages are created.
158
+ *
159
+ * @since 3.1
160
+ *
161
+ * @param array $args Argument used to create the language. @see PLL_Admin_Model::add_language().
162
+ * @return void
163
+ */
164
+ public function handle_default_term_on_create_language( $args ) {
165
+ foreach ( $this->taxonomies as $taxonomy ) {
166
+ if ( 'category' === $taxonomy ) {
167
+ $default = (int) get_option( 'default_' . $taxonomy );
168
+
169
+ // Assign default language to default term
170
+ if ( ! $this->model->term->get_language( $default ) ) {
171
+ $this->model->term->set_language( $default, $args['slug'] );
172
+ } elseif ( empty( $args['no_default_cat'] ) && ! $this->model->term->get( $default, $args['slug'] ) ) {
173
+ $this->create_default_term( $args['slug'], $taxonomy );
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Identify the default term in the terms list table to disable the language dropdown in js.
181
+ *
182
+ * @since 3.1
183
+ *
184
+ * @param string $out The output.
185
+ * @param string $column The custom column's name.
186
+ * @param int $term_id The term id.
187
+ * @return string The HTML string.
188
+ */
189
+ public function term_column( $out, $column, $term_id ) {
190
+ if ( $column === $this->get_first_language_column() && $this->is_default_term( $term_id ) ) {
191
+ $out .= sprintf( '<div class="hidden" id="default_cat_%1$d">%1$d</div>', intval( $term_id ) );
192
+ }
193
+
194
+ return $out;
195
+ }
196
+
197
+ /**
198
+ * Returns the first language column in the posts, pages and media library tables
199
+ *
200
+ * @since 0.9
201
+ *
202
+ * @return string first language column name
203
+ */
204
+ protected function get_first_language_column() {
205
+ $columns = array();
206
+
207
+ foreach ( $this->model->get_languages_list() as $language ) {
208
+ $columns[] = 'language_' . $language->slug;
209
+ }
210
+
211
+ return empty( $columns ) ? '' : reset( $columns );
212
+ }
213
+
214
+ /**
215
+ * Prevents deleting all the translations of the default term
216
+ *
217
+ * @since 2.1
218
+ *
219
+ * @param array $caps The user's actual capabilities.
220
+ * @param string $cap Capability name.
221
+ * @param int $user_id The user ID.
222
+ * @param array $args Adds the context to the cap. The term id.
223
+ * @return array
224
+ */
225
+ public function fix_delete_default_term( $caps, $cap, $user_id, $args ) {
226
+ if ( 'delete_term' === $cap && $this->is_default_term( reset( $args ) ) ) {
227
+ $caps[] = 'do_not_allow';
228
+ }
229
+
230
+ return $caps;
231
+ }
232
+
233
+ /**
234
+ * Check if the term is the default term.
235
+ *
236
+ * @since 3.1
237
+ *
238
+ * @param int $term_id The term id.
239
+ * @return bool True if the term is the default term, false otherwise.
240
+ */
241
+ public function is_default_term( $term_id ) {
242
+ $term = get_term( $term_id );
243
+ if ( $term instanceof WP_Term ) {
244
+ $default_term_id = get_option( 'default_' . $term->taxonomy );
245
+ return $default_term_id && in_array( $default_term_id, $this->model->term->get_translations( $term_id ) );
246
+ }
247
+ return false;
248
+ }
249
+
250
+ /**
251
+ * Updates the default term language.
252
+ *
253
+ * @since 3.1
254
+ *
255
+ * @param string $slug Language slug.
256
+ * @return void
257
+ */
258
+ public function update_default_term_language( $slug ) {
259
+ foreach ( $this->taxonomies as $taxonomy ) {
260
+ if ( 'category' === $taxonomy ) {
261
+ $default_cats = $this->model->term->get_translations( get_option( 'default_' . $taxonomy ) );
262
+ if ( isset( $default_cats[ $slug ] ) ) {
263
+ update_option( 'default_' . $taxonomy, $default_cats[ $slug ] );
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
admin/admin-filters-columns.php CHANGED
@@ -302,11 +302,6 @@ class PLL_Admin_Filters_Columns {
302
 
303
  if ( $column == $this->get_first_language_column() ) {
304
  $out = sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
305
-
306
- // Identify the default categories to disable the language dropdown in js
307
- if ( in_array( get_option( 'default_category' ), $this->model->term->get_translations( $term_id ) ) ) {
308
- $out .= sprintf( '<div class="hidden" id="default_cat_%1$d">%1$d</div>', intval( $term_id ) );
309
- }
310
  }
311
 
312
  // Link to edit term ( or a translation )
302
 
303
  if ( $column == $this->get_first_language_column() ) {
304
  $out = sprintf( '<div class="hidden" id="lang_%d">%s</div>', intval( $term_id ), esc_html( $lang->slug ) );
 
 
 
 
 
305
  }
306
 
307
  // Link to edit term ( or a translation )
admin/admin-filters-media.php CHANGED
@@ -115,12 +115,8 @@ class PLL_Admin_Filters_Media extends PLL_Admin_Filters_Post_Base {
115
  public function save_media( $post, $attachment ) {
116
  // Language is filled in attachment by the function applying the filter 'attachment_fields_to_save'
117
  // All security checks have been done by functions applying this filter
118
- if ( ! empty( $attachment['language'] ) ) {
119
- $this->model->post->set_language( $post['ID'], $attachment['language'] );
120
- }
121
-
122
- if ( isset( $_POST['media_tr_lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
123
- $this->save_translations( $post['ID'], array_map( 'absint', $_POST['media_tr_lang'] ) ); // phpcs:ignore WordPress.Security.NonceVerification
124
  }
125
 
126
  return $post;
115
  public function save_media( $post, $attachment ) {
116
  // Language is filled in attachment by the function applying the filter 'attachment_fields_to_save'
117
  // All security checks have been done by functions applying this filter
118
+ if ( ! empty( $attachment['language'] ) && current_user_can( 'edit_post', $post['ID'] ) ) {
119
+ $this->model->post->update_language( $post['ID'], $this->model->get_language( $attachment['language'] ) );
 
 
 
 
120
  }
121
 
122
  return $post;
admin/admin-filters-post-base.php CHANGED
@@ -52,14 +52,7 @@ abstract class PLL_Admin_Filters_Post_Base {
52
  // Security check as 'wp_insert_post' can be called from outside WP admin.
53
  check_admin_referer( 'pll_language', '_pll_nonce' );
54
 
55
- $translations = array();
56
-
57
- // Save translations after checking the translated post is in the right language.
58
- foreach ( $arr as $lang => $tr_id ) {
59
- $translations[ $lang ] = ( $tr_id && $this->model->post->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
60
- }
61
-
62
- $this->model->post->save_translations( $post_id, $translations );
63
  return $translations;
64
  }
65
  }
52
  // Security check as 'wp_insert_post' can be called from outside WP admin.
53
  check_admin_referer( 'pll_language', '_pll_nonce' );
54
 
55
+ $translations = $this->model->post->save_translations( $post_id, $arr );
 
 
 
 
 
 
 
56
  return $translations;
57
  }
58
  }
admin/admin-filters-post.php CHANGED
@@ -154,50 +154,6 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
154
  }
155
  }
156
 
157
- /**
158
- * Saves a post language when inline editing or bulk editing.
159
- * Fixes the translations if necessary.
160
- *
161
- * @since 2.3
162
- *
163
- * @param int $post_id Post ID.
164
- * @param PLL_Language $lang Language.
165
- * @return void
166
- */
167
- protected function inline_save_language( $post_id, $lang ) {
168
- $post = get_post( $post_id );
169
-
170
- if ( empty( $post ) ) {
171
- return;
172
- }
173
-
174
- $post_type_object = get_post_type_object( $post->post_type );
175
-
176
- if ( empty( $post_type_object ) ) {
177
- return;
178
- }
179
-
180
- if ( current_user_can( $post_type_object->cap->edit_post, $post_id ) ) {
181
- $old_lang = $this->model->post->get_language( $post_id ); // Stores the old language
182
- $this->model->post->set_language( $post_id, $lang ); // set new language
183
-
184
- // Checks if the new language already exists in the translation group
185
- if ( $old_lang && $old_lang->slug != $lang->slug ) {
186
- $translations = $this->model->post->get_translations( $post_id );
187
-
188
- // If yes, separate this post from the translation group
189
- if ( array_key_exists( $lang->slug, $translations ) ) {
190
- $this->model->post->delete_translation( $post_id );
191
- }
192
-
193
- elseif ( array_key_exists( $old_lang->slug, $translations ) ) {
194
- unset( $translations[ $old_lang->slug ] );
195
- $this->model->post->save_translations( $post_id, $translations );
196
- }
197
- }
198
- }
199
- }
200
-
201
  /**
202
  * Save language when bulk editing a post
203
  *
@@ -212,7 +168,9 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
212
  if ( $lang = $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) ) {
213
  $post_ids = array_map( 'intval', (array) $_REQUEST['post'] );
214
  foreach ( $post_ids as $post_id ) {
215
- $this->inline_save_language( $post_id, $lang );
 
 
216
  }
217
  }
218
  }
@@ -231,8 +189,8 @@ class PLL_Admin_Filters_Post extends PLL_Admin_Filters_Post_Base {
231
  if ( isset( $_POST['post_ID'], $_POST['inline_lang_choice'] ) ) {
232
  $post_id = (int) $_POST['post_ID'];
233
  $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) );
234
- if ( $post_id && $lang ) {
235
- $this->inline_save_language( $post_id, $lang );
236
  }
237
  }
238
  }
154
  }
155
  }
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  /**
158
  * Save language when bulk editing a post
159
  *
168
  if ( $lang = $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) ) {
169
  $post_ids = array_map( 'intval', (array) $_REQUEST['post'] );
170
  foreach ( $post_ids as $post_id ) {
171
+ if ( current_user_can( 'edit_post', $post_id ) ) {
172
+ $this->model->post->update_language( $post_id, $lang );
173
+ }
174
  }
175
  }
176
  }
189
  if ( isset( $_POST['post_ID'], $_POST['inline_lang_choice'] ) ) {
190
  $post_id = (int) $_POST['post_ID'];
191
  $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) );
192
+ if ( $post_id && $lang && current_user_can( 'edit_post', $post_id ) ) {
193
+ $this->model->post->update_language( $post_id, $lang );
194
  }
195
  }
196
  }
admin/admin-filters-term.php CHANGED
@@ -54,6 +54,15 @@ class PLL_Admin_Filters_Term {
54
  */
55
  protected $post_id;
56
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * Constructor: setups filters and actions
59
  *
@@ -64,6 +73,7 @@ class PLL_Admin_Filters_Term {
64
  $this->model = &$polylang->model;
65
  $this->options = &$polylang->options;
66
  $this->pref_lang = &$polylang->pref_lang;
 
67
 
68
  foreach ( $this->model->get_translated_taxonomies() as $tax ) {
69
  // Adds the language field in the 'Categories' and 'Post Tags' panels
@@ -85,10 +95,6 @@ class PLL_Admin_Filters_Term {
85
  add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
86
  add_action( 'wp_ajax_pll_terms_not_translated', array( $this, 'ajax_terms_not_translated' ) );
87
 
88
- // Allows to get the default categories in all languages
89
- add_filter( 'option_default_category', array( $this, 'option_default_category' ) );
90
- add_action( 'update_option_default_category', array( $this, 'update_option_default_category' ), 10, 2 );
91
-
92
  // Updates the translations term ids when splitting a shared term
93
  add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); // WP 4.2
94
  }
@@ -186,8 +192,8 @@ class PLL_Admin_Filters_Term {
186
  $lang = $this->model->term->get_language( $term_id );
187
  $lang = empty( $lang ) ? $this->pref_lang : $lang;
188
 
189
- // Disable the language dropdown and the translations input fields for default categories to prevent removal
190
- $disabled = in_array( get_option( 'default_category' ), $this->model->term->get_translations( $term_id ) );
191
 
192
  $dropdown = new PLL_Walker_Dropdown();
193
 
@@ -329,7 +335,9 @@ class PLL_Admin_Filters_Term {
329
  }
330
 
331
  else {
332
- $this->model->term->set_language( $term_id, $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) );
 
 
333
  }
334
  }
335
 
@@ -340,23 +348,8 @@ class PLL_Admin_Filters_Term {
340
  '_inline_edit'
341
  );
342
 
343
- $old_lang = $this->model->term->get_language( $term_id ); // Stores the old language
344
- $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) ); // New language
345
- $translations = $this->model->term->get_translations( $term_id );
346
-
347
- // Checks if the new language already exists in the translation group
348
- if ( $old_lang && $old_lang->slug != $lang->slug ) {
349
- if ( array_key_exists( $lang->slug, $translations ) ) {
350
- $this->model->term->delete_translation( $term_id );
351
- }
352
-
353
- elseif ( array_key_exists( $old_lang->slug, $translations ) ) {
354
- unset( $translations[ $old_lang->slug ] );
355
- $this->model->term->save_translations( $term_id, $translations );
356
- }
357
- }
358
-
359
- $this->model->term->set_language( $term_id, $lang ); // Set new language
360
  }
361
 
362
  // Edit post
@@ -618,47 +611,6 @@ class PLL_Admin_Filters_Term {
618
  wp_die( wp_json_encode( $return ) );
619
  }
620
 
621
- /**
622
- * Filters the default category in note below the category list table and in settings->writing dropdown
623
- *
624
- * @since 1.2
625
- *
626
- * @param int $value
627
- * @return int
628
- */
629
- public function option_default_category( $value ) {
630
- if ( isset( $this->pref_lang ) && $tr = $this->model->term->get( $value, $this->pref_lang ) ) {
631
- $value = $tr;
632
- }
633
- return $value;
634
- }
635
-
636
- /**
637
- * Checks if the new default category is translated in all languages
638
- * If not, create the translations
639
- *
640
- * @since 1.7
641
- *
642
- * @param int $old_value
643
- * @param int $value
644
- * @return void
645
- */
646
- public function update_option_default_category( $old_value, $value ) {
647
- $default_cat_lang = $this->model->term->get_language( $value );
648
-
649
- // Assign a default language to default category
650
- if ( ! $default_cat_lang ) {
651
- $default_cat_lang = $this->model->get_language( $this->options['default_lang'] );
652
- $this->model->term->set_language( (int) $value, $default_cat_lang );
653
- }
654
-
655
- foreach ( $this->model->get_languages_list() as $language ) {
656
- if ( $language->slug != $default_cat_lang->slug && ! $this->model->term->get_translation( $value, $language ) ) {
657
- $this->model->create_default_category( $language );
658
- }
659
- }
660
- }
661
-
662
  /**
663
  * Updates the translations term ids when splitting a shared term
664
  * Splits translations if these are shared terms too
54
  */
55
  protected $post_id;
56
 
57
+ /**
58
+ * A reference to the PLL_Admin_Default_Term instance.
59
+ *
60
+ * @since 2.8
61
+ *
62
+ * @var PLL_Admin_Default_Term
63
+ */
64
+ protected $default_term;
65
+
66
  /**
67
  * Constructor: setups filters and actions
68
  *
73
  $this->model = &$polylang->model;
74
  $this->options = &$polylang->options;
75
  $this->pref_lang = &$polylang->pref_lang;
76
+ $this->default_term = &$polylang->default_term;
77
 
78
  foreach ( $this->model->get_translated_taxonomies() as $tax ) {
79
  // Adds the language field in the 'Categories' and 'Post Tags' panels
95
  add_action( 'wp_ajax_term_lang_choice', array( $this, 'term_lang_choice' ) );
96
  add_action( 'wp_ajax_pll_terms_not_translated', array( $this, 'ajax_terms_not_translated' ) );
97
 
 
 
 
 
98
  // Updates the translations term ids when splitting a shared term
99
  add_action( 'split_shared_term', array( $this, 'split_shared_term' ), 10, 4 ); // WP 4.2
100
  }
192
  $lang = $this->model->term->get_language( $term_id );
193
  $lang = empty( $lang ) ? $this->pref_lang : $lang;
194
 
195
+ // Disable the language dropdown and the translations input fields for default terms to prevent removal
196
+ $disabled = $this->default_term->is_default_term( $term_id );
197
 
198
  $dropdown = new PLL_Walker_Dropdown();
199
 
335
  }
336
 
337
  else {
338
+ if ( current_user_can( 'edit_term', $term_id ) ) {
339
+ $this->model->term->set_language( $term_id, $this->model->get_language( sanitize_key( $_GET['inline_lang_choice'] ) ) );
340
+ }
341
  }
342
  }
343
 
348
  '_inline_edit'
349
  );
350
 
351
+ $lang = $this->model->get_language( sanitize_key( $_POST['inline_lang_choice'] ) );
352
+ $this->model->term->update_language( $term_id, $lang );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  }
354
 
355
  // Edit post
611
  wp_die( wp_json_encode( $return ) );
612
  }
613
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614
  /**
615
  * Updates the translations term ids when splitting a shared term
616
  * Splits translations if these are shared terms too
admin/admin-filters-widgets-options.php CHANGED
@@ -27,29 +27,9 @@ class PLL_Admin_Filters_Widgets_Options extends PLL_Filters_Widgets_Options {
27
 
28
  // Test the Widgets screen and the Customizer to avoid displaying the option in page builders
29
  // Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET.
30
- if ( ( isset( $screen ) && in_array( $screen->base, array( 'widgets', 'appearance_page_gutenberg-widgets' ) ) ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
31
  parent::in_widget_form( $widget, $return, $instance );
32
  }
33
  }
34
 
35
- /**
36
- * Called when widget options are saved.
37
- * Saves the language associated to the widget.
38
- *
39
- * @since 3.0
40
- *
41
- * @param array $instance The current Widget's options.
42
- * @param array $new_instance The new Widget's options.
43
- * @param array $old_instance Not used.
44
- * @param WP_Widget $widget The Widget object.
45
- * @return array The processed Widget options.
46
- */
47
- public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
48
- $key = $this->get_language_key( $widget );
49
- if ( ! empty( $_POST[ $key ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
50
- $new_instance[ $key ] = sanitize_key( $_POST[ $key ] ); // phpcs:ignore WordPress.Security.NonceVerification
51
- }
52
- return parent::widget_update_callback( $instance, $new_instance, $old_instance, $widget );
53
- }
54
-
55
  }
27
 
28
  // Test the Widgets screen and the Customizer to avoid displaying the option in page builders
29
  // Saving the widget reloads the form. And curiously the action is in $_REQUEST but neither in $_POST, nor in $_GET.
30
+ if ( ( isset( $screen ) && 'widgets' === $screen->base ) || ( isset( $_REQUEST['action'] ) && 'save-widget' === $_REQUEST['action'] ) || isset( $GLOBALS['wp_customize'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
31
  parent::in_widget_form( $widget, $return, $instance );
32
  }
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
admin/admin-model.php CHANGED
@@ -52,11 +52,6 @@ class PLL_Admin_Model extends PLL_Model {
52
  // If this is the first language created, set it as default language
53
  $this->options['default_lang'] = $args['slug'];
54
  update_option( 'polylang', $this->options );
55
-
56
- // And assign default language to default category
57
- $this->term->set_language( (int) get_option( 'default_category' ), (int) $r['term_id'] );
58
- } elseif ( empty( $args['no_default_cat'] ) ) {
59
- $this->create_default_category( $args['slug'] );
60
  }
61
 
62
  // Init a mo_id for this language
@@ -436,77 +431,6 @@ class PLL_Admin_Model extends PLL_Model {
436
  clean_term_cache( $term_ids, $taxonomy );
437
  }
438
 
439
- /**
440
- * Returns untranslated posts and terms ids ( used in settings ).
441
- *
442
- * @since 0.9
443
- * @since 2.2.6 Add the $limit argument.
444
- *
445
- * @param int $limit Max number of posts or terms to return. Defaults to -1 (no limit).
446
- * @return array {
447
- * Objects without language.
448
- *
449
- * @type int[] $posts Array of post ids.
450
- * @type int[] $terms Array of term ids.
451
- * }
452
- */
453
- public function get_objects_with_no_lang( $limit = -1 ) {
454
- global $wpdb;
455
-
456
- /**
457
- * Filters the max number of posts or terms to return when searching objects with no language.
458
- * This filter can be used to decrease the memory usage in case the number of objects
459
- * without language is too big. Using a negative value is equivalent to have no limit.
460
- *
461
- * @since 2.2.6
462
- *
463
- * @param int $limit Max number of posts or terms to retrieve from the database.
464
- */
465
- $limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
466
-
467
- $posts = get_posts(
468
- array(
469
- 'numberposts' => $limit,
470
- 'nopaging' => $limit <= 0,
471
- 'post_type' => $this->get_translated_post_types(),
472
- 'post_status' => 'any',
473
- 'fields' => 'ids',
474
- 'tax_query' => array(
475
- array(
476
- 'taxonomy' => 'language',
477
- 'terms' => $this->get_languages_list( array( 'fields' => 'term_id' ) ),
478
- 'operator' => 'NOT IN',
479
- ),
480
- ),
481
- )
482
- );
483
-
484
- // PHPCS:disable WordPress.DB.PreparedSQL
485
- $terms = $wpdb->get_col(
486
- sprintf(
487
- "SELECT {$wpdb->term_taxonomy}.term_id FROM {$wpdb->term_taxonomy}
488
- WHERE taxonomy IN ('%s')
489
- AND {$wpdb->term_taxonomy}.term_id NOT IN (
490
- SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
491
- )
492
- %s",
493
- implode( "','", array_map( 'esc_sql', $this->get_translated_taxonomies() ) ),
494
- implode( ',', array_map( 'intval', $this->get_languages_list( array( 'fields' => 'tl_term_taxonomy_id' ) ) ) ),
495
- $limit > 0 ? "LIMIT {$limit}" : ''
496
- )
497
- );
498
- // PHPCS:enable
499
-
500
- /**
501
- * Filters the list of untranslated posts ids and terms ids
502
- *
503
- * @since 0.9
504
- *
505
- * @param array|false $objects false if no ids found, list of post and/or term ids otherwise.
506
- */
507
- return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
508
- }
509
-
510
  /**
511
  * Updates the translations when a language slug has been modified in settings
512
  * or deletes them when a language is removed.
@@ -606,11 +530,14 @@ class PLL_Admin_Model extends PLL_Model {
606
  set_theme_mod( 'nav_menu_locations', $menus );
607
  }
608
 
609
- // The default category should be in the default language
610
- $default_cats = $this->term->get_translations( get_option( 'default_category' ) );
611
- if ( isset( $default_cats[ $slug ] ) ) {
612
- update_option( 'default_category', $default_cats[ $slug ] );
613
- }
 
 
 
614
 
615
  // Update options
616
  $this->options['default_lang'] = $slug;
52
  // If this is the first language created, set it as default language
53
  $this->options['default_lang'] = $args['slug'];
54
  update_option( 'polylang', $this->options );
 
 
 
 
 
55
  }
56
 
57
  // Init a mo_id for this language
431
  clean_term_cache( $term_ids, $taxonomy );
432
  }
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  /**
435
  * Updates the translations when a language slug has been modified in settings
436
  * or deletes them when a language is removed.
530
  set_theme_mod( 'nav_menu_locations', $menus );
531
  }
532
 
533
+ /**
534
+ * Fires when a default language is updated.
535
+ *
536
+ * @since 3.1
537
+ *
538
+ * @param string $slug Slug.
539
+ */
540
+ do_action( 'pll_update_default_lang', $slug );
541
 
542
  // Update options
543
  $this->options['default_lang'] = $slug;
admin/admin-nav-menu.php CHANGED
@@ -72,7 +72,7 @@ class PLL_Admin_Nav_Menu extends PLL_Nav_Menu {
72
  <input type="checkbox" class="menu-item-checkbox" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-object-id]" value="-1"> <?php esc_html_e( 'Languages', 'polylang' ); ?>
73
  </label>
74
  <input type="hidden" class="menu-item-type" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-type]" value="custom">
75
- <input type="hidden" class="menu-item-title" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-title]" value="<?php esc_html_e( 'Languages', 'polylang' ); ?>">
76
  <input type="hidden" class="menu-item-url" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-url]" value="#pll_switcher">
77
  </li>
78
  </ul>
72
  <input type="checkbox" class="menu-item-checkbox" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-object-id]" value="-1"> <?php esc_html_e( 'Languages', 'polylang' ); ?>
73
  </label>
74
  <input type="hidden" class="menu-item-type" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-type]" value="custom">
75
+ <input type="hidden" class="menu-item-title" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-title]" value="<?php esc_attr_e( 'Languages', 'polylang' ); ?>">
76
  <input type="hidden" class="menu-item-url" name="menu-item[<?php echo (int) $_nav_menu_placeholder; ?>][menu-item-url]" value="#pll_switcher">
77
  </li>
78
  </ul>
admin/admin.php CHANGED
@@ -59,7 +59,7 @@ class PLL_Admin extends PLL_Admin_Base {
59
  /**
60
  * @var PLL_Admin_Filters_Widgets_Options
61
  */
62
- public $filters_widgets;
63
 
64
  /**
65
  * Setups filters and action needed on all admin pages and on plugins page.
@@ -129,7 +129,7 @@ class PLL_Admin extends PLL_Admin_Base {
129
  */
130
  public function add_filters() {
131
  $this->filters_sanitization = new PLL_Filters_Sanitization( $this->get_locale_for_sanitization() );
132
- $this->filters_widgets = new PLL_Admin_Filters_Widgets_Options( $this );
133
 
134
  // All these are separated just for convenience and maintainability
135
  $classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Classic_Editor', 'Block_Editor' );
59
  /**
60
  * @var PLL_Admin_Filters_Widgets_Options
61
  */
62
+ public $filters_widgets_options;
63
 
64
  /**
65
  * Setups filters and action needed on all admin pages and on plugins page.
129
  */
130
  public function add_filters() {
131
  $this->filters_sanitization = new PLL_Filters_Sanitization( $this->get_locale_for_sanitization() );
132
+ $this->filters_widgets_options = new PLL_Admin_Filters_Widgets_Options( $this );
133
 
134
  // All these are separated just for convenience and maintainability
135
  $classes = array( 'Filters', 'Filters_Columns', 'Filters_Post', 'Filters_Term', 'Nav_Menu', 'Classic_Editor', 'Block_Editor' );
admin/block-editor-filter-preload-paths.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Polylang
4
+ */
5
+
6
+ /**
7
+ * This class handles the deprecated filter 'block_editor_preload_paths'
8
+ * to replace it by the new filter 'block_editor_rest_api_preload_paths'
9
+ * and is used for backward compatibility with WP < 5.8.
10
+ *
11
+ * @since 3.1
12
+ */
13
+ class PLL_Block_Editor_Filter_Preload_Paths {
14
+
15
+ /**
16
+ * @var callable
17
+ */
18
+ private $callback;
19
+
20
+ /**
21
+ * PLL_Block_Editor_Filter_Preload_Paths constructor.
22
+ *
23
+ * @since 3.1
24
+ *
25
+ * @param callable $callback Function or method to be executed when the filter is triggered.
26
+ * @param int $priority Priority of execution for the given callback. Default 10.
27
+ * @param int $arguments_number Number of arguments to pass to the callback. Default 1.
28
+ */
29
+ public function __construct( $callback, $priority = 10, $arguments_number = 1 ) {
30
+ $this->callback = $callback;
31
+
32
+ if ( class_exists( 'WP_Block_Editor_Context' ) ) { // Since WP 5.8.
33
+ add_filter( 'block_editor_rest_api_preload_paths', array( $this, 'block_editor_rest_api_preload_paths' ), $priority, $arguments_number );
34
+ } else {
35
+ add_filter( 'block_editor_preload_paths', $callback, $priority, $arguments_number );
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Filters the array of REST API paths that will be used to preloaded common data to use with the block editor.
41
+ *
42
+ * Converts the WP_Block_Editor_Context object to a WP_Post if provided in the context.
43
+ *
44
+ * @since 3.1
45
+ *
46
+ * @param string[] $preload_paths The preload paths loaded by the Block Editor.
47
+ * @param WP_Block_Editor_Context $block_editor_context The post resource data.
48
+ * @return array|mixed|string[] (string|string[])[]
49
+ */
50
+ public function block_editor_rest_api_preload_paths( $preload_paths, $block_editor_context = null ) {
51
+ if ( null === $block_editor_context ) {
52
+ return call_user_func( $this->callback, $preload_paths );
53
+ } elseif ( ! empty( $block_editor_context->post ) ) {
54
+ return call_user_func_array( $this->callback, array( $preload_paths, $block_editor_context->post ) );
55
+ }
56
+
57
+ return call_user_func_array( $this->callback, array( $preload_paths, $block_editor_context ) );
58
+ }
59
+ }
admin/view-translations-post.php CHANGED
@@ -52,13 +52,12 @@ if ( ! defined( 'ABSPATH' ) ) {
52
  printf(
53
  '<label class="screen-reader-text" for="tr_lang_%1$s">%2$s</label>
54
  <input type="hidden" name="post_tr_lang[%1$s]" id="htr_lang_%1$s" value="%3$s" />
55
- <span lang="%6$s" dir="%7$s"><input type="text" class="tr_lang" id="tr_lang_%1$s" value="%4$s"%5$s /></span>',
56
  esc_attr( $language->slug ),
57
  /* translators: accessibility text */
58
  esc_html__( 'Translation', 'polylang' ),
59
  ( empty( $value ) ? 0 : esc_attr( $selected->ID ) ),
60
  ( empty( $value ) ? '' : esc_attr( $selected->post_title ) ),
61
- disabled( empty( $link ), true, false ),
62
  esc_attr( $language->get_locale( 'display' ) ),
63
  ( $language->is_rtl ? 'rtl' : 'ltr' )
64
  );
52
  printf(
53
  '<label class="screen-reader-text" for="tr_lang_%1$s">%2$s</label>
54
  <input type="hidden" name="post_tr_lang[%1$s]" id="htr_lang_%1$s" value="%3$s" />
55
+ <span lang="%5$s" dir="%6$s"><input type="text" class="tr_lang" id="tr_lang_%1$s" value="%4$s" /></span>',
56
  esc_attr( $language->slug ),
57
  /* translators: accessibility text */
58
  esc_html__( 'Translation', 'polylang' ),
59
  ( empty( $value ) ? 0 : esc_attr( $selected->ID ) ),
60
  ( empty( $value ) ? '' : esc_attr( $selected->post_title ) ),
 
61
  esc_attr( $language->get_locale( 'display' ) ),
62
  ( $language->is_rtl ? 'rtl' : 'ltr' )
63
  );
css/admin.css DELETED
@@ -1,457 +0,0 @@
1
- /* languages admin panel */
2
- #add-lang select {
3
- width: 95%;
4
- }
5
-
6
- .column-locale,
7
- .languages .column-slug {
8
- width : 15%
9
- }
10
-
11
- .column-default_lang {
12
- width : 5%;
13
- }
14
-
15
- .column-term_group,
16
- .column-flag, .column-count {
17
- width : 10%;
18
- }
19
-
20
- .icon-default-lang:before {
21
- font-family: 'dashicons';
22
- content: "\f155";
23
- }
24
- .pll-icon:before{
25
- display: inline-block;
26
- text-align: left;
27
- width: 15px;
28
- }
29
- .pll-circle:before{
30
- content: "\25cf";
31
- }
32
-
33
- .form-field input[type="radio"] {
34
- width: auto;
35
- margin-right: 2px;
36
- }
37
-
38
- /* about Polylang metabox */
39
- #pll-about-box p,
40
- #pll-recommended p {
41
- text-align: justify;
42
- }
43
-
44
- #pll-about-box input {
45
- margin: 0;
46
- padding: 0;
47
- float: right;
48
- }
49
-
50
- /* strings translation table */
51
- .stringstranslations .column-name,
52
- .stringstranslations .column-context {
53
- width: 10%;
54
- }
55
-
56
- .stringstranslations .column-string {
57
- width: 33%;
58
- }
59
-
60
- .translation label {
61
- display: inline-block;
62
- width: 23%;
63
- vertical-align: top;
64
- }
65
-
66
- .translation {
67
- display: flex; /* fix #691 to remove default margin bottom */
68
- }
69
- @media screen and (max-width: 782px) { /* reset default display property for small device */
70
- .translation{
71
- display: block;
72
- }
73
- }
74
- .translation textarea{
75
- display: block; /* fix #691 to remove default margin bottom */
76
- }
77
- .translation input,
78
- .translation textarea {
79
- width: 72%;
80
- box-sizing: border-box; /* to be sure field don't overrun outside their wrapper */
81
- margin-bottom: 4px; /* fix #691 set the same margin bottom for both textarea and input tags */
82
- }
83
-
84
- /* settings */
85
- .pll-settings {
86
- margin-top: 20px;
87
- }
88
-
89
- .pll-settings .plugin-title {
90
- width: 25%;
91
- }
92
-
93
- #wpbody-content .pll-settings .pll-configure tr {
94
- display: table-row;
95
- }
96
-
97
- #wpbody-content .pll-settings .pll-configure td {
98
- display: table-cell;
99
- }
100
-
101
- #wpbody-content .pll-settings .pll-configure > td {
102
- padding: 20px 20px 20px 40px;
103
- }
104
-
105
- .pll-configure legend {
106
- font-size: 14px;
107
- font-weight: 600;
108
- margin-bottom: 0.5em;
109
- }
110
-
111
- .pll-configure td .description {
112
- margin-top: 2px;
113
- margin-bottom: 0.5em;
114
- }
115
-
116
- .pll-configure p.submit {
117
- margin-top: 20px;
118
- }
119
-
120
- .pll-configure .button {
121
- margin-right: 20px;
122
- }
123
-
124
- .pll-configure fieldset {
125
- margin-bottom: 1.5em;
126
- }
127
-
128
- .pll-inline-block-list {
129
- margin: 0;
130
- }
131
-
132
- .pll-inline-block-list li {
133
- display: inline-block;
134
- margin: 0;
135
- width: 250px;
136
- }
137
-
138
- /* settings URL modifications */
139
- #pll-domains-table td {
140
- padding: 2px 2px 2px 1.5em;
141
- -webkit-box-shadow: none;
142
- box-shadow: none;
143
- border: none;
144
- }
145
-
146
- .pll-settings-url-col {
147
- display: inline-block;
148
- width: 49%;
149
- vertical-align: top;
150
- }
151
-
152
- /* settings Activation keys */
153
- #pll-licenses-table td {
154
- vertical-align: top;
155
- }
156
-
157
- #pll-licenses-table label {
158
- font-size: 1em;
159
- font-weight: 600;
160
- }
161
-
162
- .pll-configure .pll-deactivate-license {
163
- margin: 0 0 0 20px;
164
- }
165
-
166
- /* language columns in edit.php and edit-tags.php */
167
- .wp-list-table th[class*='column-language_'],
168
- .wp-list-table td[class*='column-language_'] {
169
- width: 1.5em;
170
- box-sizing: content-box; /* Override ACF 5.9.0 styles */
171
- }
172
-
173
- /* Text direction in post.php and edit-tags.php */
174
- .pll-dir-rtl textarea,
175
- .pll-dir-rtl input[type="text"] {
176
- direction: rtl;
177
- }
178
-
179
- .pll-dir-ltr textarea,
180
- .pll-dir-ltr input[type="text"] {
181
- direction: ltr;
182
- }
183
-
184
- .pll-dir-ltr .tr_lang,
185
- .pll-dir-rtl .tr_lang {
186
- direction: inherit;
187
- }
188
-
189
- /* languages metabox in post.php */
190
- #post-translations p {
191
- float: left;
192
- }
193
-
194
- #post-translations table {
195
- table-layout: fixed;
196
- width: 100%;
197
- clear: both;
198
- }
199
-
200
- #post-translations a {
201
- text-decoration: none;
202
- }
203
-
204
- #post-translations .pll-language-column,
205
- #post-translations .pll-column-icon {
206
- width: 20px;
207
- }
208
-
209
- #post-translations .tr_lang {
210
- width: 100%;
211
- }
212
-
213
- #post-translations td {
214
- padding: 2px;
215
- }
216
-
217
- #post-translations .spinner,
218
- #term-translations .spinner {
219
- float: none;
220
- margin: 0;
221
- background-position: center;
222
- width: auto;
223
- }
224
-
225
- .pll-column-icon {
226
- text-align: center;
227
- }
228
-
229
- #select-post-language .pll-select-flag {
230
- padding: 4px;
231
- margin-right: 32px;
232
- }
233
-
234
- /* specific cases for media */
235
- #select-media-language .pll-select-flag {
236
- padding: 4px;
237
- margin-right: 10px;
238
- }
239
-
240
- .pll-media-edit-column {
241
- float: right;
242
- }
243
-
244
- /* language and translations in edit-tags.php */
245
- .pll-translation-flag { /* also for media */
246
- margin-right: 14px;
247
- }
248
-
249
- #select-add-term-language .pll-select-flag {
250
- padding: 11px;
251
- margin-right: 13px;
252
- }
253
-
254
- #select-edit-term-language .pll-select-flag {
255
- padding: 11px;
256
- margin-right: 4px;
257
- }
258
-
259
- #term-translations p {
260
- /* same style as label */
261
- font-weight: 400;
262
- font-style: normal;
263
- padding: 2px;
264
- color: #23282d;
265
- }
266
-
267
- #add-term-translations,
268
- #edit-term-translations {
269
- width: 95%;
270
- }
271
-
272
- #term-translations .pll-language-column {
273
- line-height: 28px;
274
- width: 20%;
275
- }
276
-
277
- #term-translations .pll-edit-column,
278
- #add-term-translations .pll-language-column {
279
- width: 20px;
280
- }
281
-
282
- #edit-term-translations .pll-language-column {
283
- padding: 15px 10px;
284
- font-weight: normal;
285
- }
286
-
287
- /* icon fonts */
288
- .pll_icon_add:before {
289
- content: "\f132";
290
- }
291
-
292
- .pll_icon_edit:before {
293
- content: "\f464";
294
- }
295
-
296
- [class^="pll_icon_"] {
297
- font: 20px/1 'dashicons';
298
- vertical-align: middle;
299
- }
300
-
301
- /* admin bar */
302
- #wpadminbar #wp-admin-bar-languages .ab-item img {
303
- margin: 0 8px 0 2px;
304
- }
305
-
306
- #wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
307
- float: none;
308
- top: 4px;
309
- }
310
-
311
- #wpadminbar #wp-admin-bar-languages .ab-icon:before {
312
- content: "\f326";
313
- top: 1px;
314
- }
315
-
316
- /* Notices */
317
- .pll-notice.notice {
318
- padding-right: 38px;
319
- position: relative;
320
- }
321
-
322
- .pll-notice a.notice-dismiss {
323
- text-decoration: none;
324
- }
325
-
326
- .pll-notice .button {
327
- margin-right: 10px;
328
- }
329
-
330
- /* Metaboxes holder in Strings translations screen */
331
- .languages_page_mlang_strings .metabox-holder > div {
332
- display: flex;
333
- }
334
- .languages_page_mlang_strings .metabox-holder > div > div {
335
- flex-grow: 1;
336
- }
337
- .languages_page_mlang_strings .metabox-holder > div > div:nth-child(2n) {
338
- margin-left: 1rem;
339
- }
340
- .languages_page_mlang_strings .metabox-holder > div > div.closed {
341
- border:0;
342
- background: none;
343
- }
344
- .languages_page_mlang_strings .metabox-holder > div > div.closed .postbox-header{
345
- border: 1px solid #ccd0d4;
346
- background: #fff;
347
- }
348
-
349
- @media screen and ( max-width: 782px ) {
350
- /* settings */
351
- #wpbody-content .pll-settings .pll-configure > td {
352
- padding: 20px;
353
- }
354
-
355
- #wpbody-content .pll-settings #cb {
356
- padding: 20px 9px;
357
- }
358
-
359
- /* settings URL modifications */
360
- .pll-inline-block {
361
- width: auto;
362
- }
363
-
364
- .pll-settings-url-col {
365
- display: block;
366
- width: 100%;
367
- }
368
-
369
- /* settings licenses */
370
- #wpbody-content .pll-settings #pll-licenses-table td {
371
- display: block;
372
- }
373
-
374
- .pll-configure .pll-deactivate-license {
375
- margin: 10px 0 5px;
376
- }
377
-
378
- /* strings translations table */
379
- .translation label {
380
- display: block;
381
- width: 95%;
382
- padding-left: 0;
383
- }
384
-
385
- .translation input,
386
- .translation textarea {
387
- width: 95%;
388
- }
389
-
390
- /* Metaboxes holder in Strings translations screen */
391
- .languages_page_mlang_strings .metabox-holder > div {
392
- flex-direction: column;
393
- }
394
- .languages_page_mlang_strings .metabox-holder > div > div:nth-child(2n) {
395
- margin-left: 0;
396
- }
397
-
398
- /* hide selected language flag and translations language name */
399
- #select-add-term-language .pll-select-flag,
400
- #select-edit-term-language .pll-select-flag,
401
- #edit-term-translations .pll-language-name {
402
- display: none;
403
- }
404
-
405
- #edit-term-translations {
406
- width: 100%;
407
- }
408
-
409
- #add-term-translations .pll-language-column {
410
- line-height: 38px;
411
- }
412
-
413
- #edit-term-translations td {
414
- padding: 8px 10px;
415
- }
416
-
417
- #edit-term-translations .pll-language-column,
418
- #edit-term-translations .pll-edit-column {
419
- width: 20px;
420
- }
421
-
422
- /* translations tables should be kept as table */
423
- .term-translations .pll-language-column,
424
- .term-translations .pll-edit-column,
425
- .term-translations .pll-translation-column {
426
- display: table-cell;
427
- }
428
-
429
- .term-translations .hidden {
430
- display: none;
431
- }
432
-
433
- /* admin bar */
434
- #wpadminbar #wp-admin-bar-languages {
435
- display: block; /*shows our menu on mobile devices */
436
- }
437
-
438
- #wpadminbar #wp-admin-bar-languages > .ab-item {
439
- width: 50px;
440
- text-align: center;
441
- }
442
-
443
- #wpadminbar #wp-admin-bar-languages > .ab-item .ab-icon:before {
444
- font: 32px/1 'dashicons';
445
- top: -1px;
446
- }
447
-
448
- #wpadminbar #wp-admin-bar-languages > .ab-item img {
449
- margin: 19px 0;
450
- }
451
-
452
- #wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon {
453
- margin-right: 6px;
454
- font-size: 20px !important;
455
- line-height: 20px !important;
456
- }
457
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/build/admin.css CHANGED
@@ -3,6 +3,19 @@
3
  width: 95%;
4
  }
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  .column-locale,
7
  .languages .column-slug {
8
  width : 15%
@@ -30,11 +43,6 @@
30
  content: "\25cf";
31
  }
32
 
33
- .form-field input[type="radio"] {
34
- width: auto;
35
- margin-right: 2px;
36
- }
37
-
38
  /* about Polylang metabox */
39
  #pll-about-box p,
40
  #pll-recommended p {
@@ -187,8 +195,17 @@
187
  }
188
 
189
  /* languages metabox in post.php */
 
 
 
 
190
  #post-translations p {
191
  float: left;
 
 
 
 
 
192
  }
193
 
194
  #post-translations table {
@@ -222,13 +239,15 @@
222
  width: auto;
223
  }
224
 
225
- .pll-column-icon {
226
- text-align: center;
227
- }
228
-
229
  #select-post-language .pll-select-flag {
230
  padding: 4px;
231
- margin-right: 32px;
 
 
 
 
 
 
232
  }
233
 
234
  /* specific cases for media */
@@ -313,6 +332,14 @@
313
  top: 1px;
314
  }
315
 
 
 
 
 
 
 
 
 
316
  /* Notices */
317
  .pll-notice.notice {
318
  padding-right: 38px;
3
  width: 95%;
4
  }
5
 
6
+ #add-lang label {
7
+ margin: 0.35em 0 0.5em;
8
+ }
9
+
10
+ .pll-legend {
11
+ display: block;
12
+ padding: 2px 0;
13
+ color: #1d2327;
14
+ font-weight: 400;
15
+ text-shadow: none;
16
+ margin: 0.35em 0 0.5em;
17
+ }
18
+
19
  .column-locale,
20
  .languages .column-slug {
21
  width : 15%
43
  content: "\25cf";
44
  }
45
 
 
 
 
 
 
46
  /* about Polylang metabox */
47
  #pll-about-box p,
48
  #pll-recommended p {
195
  }
196
 
197
  /* languages metabox in post.php */
198
+ #ml_box p {
199
+ margin-top: 1em;
200
+ }
201
+
202
  #post-translations p {
203
  float: left;
204
+ margin-top: 1em;
205
+ }
206
+
207
+ .rtl #post-translations p {
208
+ float: right;
209
  }
210
 
211
  #post-translations table {
239
  width: auto;
240
  }
241
 
 
 
 
 
242
  #select-post-language .pll-select-flag {
243
  padding: 4px;
244
+ margin-right: 10px;
245
+ }
246
+
247
+ .rtl #select-post-language .pll-select-flag {
248
+ padding: 4px;
249
+ margin-right: 0px;
250
+ margin-left: 10px;
251
  }
252
 
253
  /* specific cases for media */
332
  top: 1px;
333
  }
334
 
335
+ #wp-admin-bar-languages.pll-filtered-languages {
336
+ background: #a03f3f;
337
+ }
338
+ /* Enforce white color for WordPress admin light theme. */
339
+ #wpadminbar #wp-admin-bar-languages.pll-filtered-languages span.ab-label{
340
+ color: #fff;
341
+ }
342
+
343
  /* Notices */
344
  .pll-notice.notice {
345
  padding-right: 38px;
css/build/admin.min.css CHANGED
@@ -1 +1 @@
1
- #add-lang select{width:95%}.column-locale,.languages .column-slug{width:15%}.column-default_lang{width:5%}.column-count,.column-flag,.column-term_group{width:10%}.icon-default-lang:before{font-family:dashicons;content:"\f155"}.pll-icon:before{display:inline-block;text-align:left;width:15px}.pll-circle:before{content:"\25cf"}.form-field input[type=radio]{width:auto;margin-right:2px}#pll-about-box p,#pll-recommended p{text-align:justify}#pll-about-box input{margin:0;padding:0;float:right}.stringstranslations .column-context,.stringstranslations .column-name{width:10%}.stringstranslations .column-string{width:33%}.translation label{display:inline-block;width:23%;vertical-align:top}.translation{display:flex}@media screen and (max-width:782px){.translation{display:block}}.translation textarea{display:block}.translation input,.translation textarea{width:72%;box-sizing:border-box;margin-bottom:4px}.pll-settings{margin-top:20px}.pll-settings .plugin-title{width:25%}#wpbody-content .pll-settings .pll-configure tr{display:table-row}#wpbody-content .pll-settings .pll-configure td{display:table-cell}#wpbody-content .pll-settings .pll-configure>td{padding:20px 20px 20px 40px}.pll-configure legend{font-size:14px;font-weight:600;margin-bottom:.5em}.pll-configure td .description{margin-top:2px;margin-bottom:.5em}.pll-configure p.submit{margin-top:20px}.pll-configure .button{margin-right:20px}.pll-configure fieldset{margin-bottom:1.5em}.pll-inline-block-list{margin:0}.pll-inline-block-list li{display:inline-block;margin:0;width:250px}#pll-domains-table td{padding:2px 2px 2px 1.5em;-webkit-box-shadow:none;box-shadow:none;border:none}.pll-settings-url-col{display:inline-block;width:49%;vertical-align:top}#pll-licenses-table td{vertical-align:top}#pll-licenses-table label{font-size:1em;font-weight:600}.pll-configure .pll-deactivate-license{margin:0 0 0 20px}.wp-list-table td[class*=column-language_],.wp-list-table th[class*=column-language_]{width:1.5em;box-sizing:content-box}.pll-dir-rtl input[type=text],.pll-dir-rtl textarea{direction:rtl}.pll-dir-ltr input[type=text],.pll-dir-ltr textarea{direction:ltr}.pll-dir-ltr .tr_lang,.pll-dir-rtl .tr_lang{direction:inherit}#post-translations p{float:left}#post-translations table{table-layout:fixed;width:100%;clear:both}#post-translations a{text-decoration:none}#post-translations .pll-column-icon,#post-translations .pll-language-column{width:20px}#post-translations .tr_lang{width:100%}#post-translations td{padding:2px}#post-translations .spinner,#term-translations .spinner{float:none;margin:0;background-position:50%;width:auto}.pll-column-icon{text-align:center}#select-post-language .pll-select-flag{padding:4px;margin-right:32px}#select-media-language .pll-select-flag{padding:4px;margin-right:10px}.pll-media-edit-column{float:right}.pll-translation-flag{margin-right:14px}#select-add-term-language .pll-select-flag{padding:11px;margin-right:13px}#select-edit-term-language .pll-select-flag{padding:11px;margin-right:4px}#term-translations p{font-weight:400;font-style:normal;padding:2px;color:#23282d}#add-term-translations,#edit-term-translations{width:95%}#term-translations .pll-language-column{line-height:28px;width:20%}#add-term-translations .pll-language-column,#term-translations .pll-edit-column{width:20px}#edit-term-translations .pll-language-column{padding:15px 10px;font-weight:400}.pll_icon_add:before{content:"\f132"}.pll_icon_edit:before{content:"\f464"}[class^=pll_icon_]{font:20px/1 dashicons;vertical-align:middle}#wpadminbar #wp-admin-bar-languages .ab-item img{margin:0 8px 0 2px}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{float:none;top:4px}#wpadminbar #wp-admin-bar-languages .ab-icon:before{content:"\f326";top:1px}.pll-notice.notice{padding-right:38px;position:relative}.pll-notice a.notice-dismiss{text-decoration:none}.pll-notice .button{margin-right:10px}.languages_page_mlang_strings .metabox-holder>div{display:flex}.languages_page_mlang_strings .metabox-holder>div>div{flex-grow:1}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:1rem}.languages_page_mlang_strings .metabox-holder>div>div.closed{border:0;background:none}.languages_page_mlang_strings .metabox-holder>div>div.closed .postbox-header{border:1px solid #ccd0d4;background:#fff}@media screen and (max-width:782px){#wpbody-content .pll-settings .pll-configure>td{padding:20px}#wpbody-content .pll-settings #cb{padding:20px 9px}.pll-inline-block{width:auto}.pll-settings-url-col{display:block;width:100%}#wpbody-content .pll-settings #pll-licenses-table td{display:block}.pll-configure .pll-deactivate-license{margin:10px 0 5px}.translation label{display:block;width:95%;padding-left:0}.translation input,.translation textarea{width:95%}.languages_page_mlang_strings .metabox-holder>div{flex-direction:column}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:0}#edit-term-translations .pll-language-name,#select-add-term-language .pll-select-flag,#select-edit-term-language .pll-select-flag{display:none}#edit-term-translations{width:100%}#add-term-translations .pll-language-column{line-height:38px}#edit-term-translations td{padding:8px 10px}#edit-term-translations .pll-edit-column,#edit-term-translations .pll-language-column{width:20px}.term-translations .pll-edit-column,.term-translations .pll-language-column,.term-translations .pll-translation-column{display:table-cell}.term-translations .hidden{display:none}#wpadminbar #wp-admin-bar-languages{display:block}#wpadminbar #wp-admin-bar-languages>.ab-item{width:50px;text-align:center}#wpadminbar #wp-admin-bar-languages>.ab-item .ab-icon:before{font:32px/1 dashicons;top:-1px}#wpadminbar #wp-admin-bar-languages>.ab-item img{margin:19px 0}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{margin-right:6px;font-size:20px!important;line-height:20px!important}}
1
+ #add-lang select{width:95%}#add-lang label,.pll-legend{margin:.35em 0 .5em}.pll-legend{color:#1d2327;display:block;font-weight:400;padding:2px 0;text-shadow:none}.column-locale,.languages .column-slug{width:15%}.column-default_lang{width:5%}.column-count,.column-flag,.column-term_group{width:10%}.icon-default-lang:before{content:"\f155";font-family:dashicons}.pll-icon:before{display:inline-block;text-align:left;width:15px}.pll-circle:before{content:"\25cf"}#pll-about-box p,#pll-recommended p{text-align:justify}#pll-about-box input{float:right;margin:0;padding:0}.stringstranslations .column-context,.stringstranslations .column-name{width:10%}.stringstranslations .column-string{width:33%}.translation label{display:inline-block;vertical-align:top;width:23%}.translation{display:flex}@media screen and (max-width:782px){.translation{display:block}}.translation textarea{display:block}.translation input,.translation textarea{box-sizing:border-box;margin-bottom:4px;width:72%}.pll-settings{margin-top:20px}.pll-settings .plugin-title{width:25%}#wpbody-content .pll-settings .pll-configure tr{display:table-row}#wpbody-content .pll-settings .pll-configure td{display:table-cell}#wpbody-content .pll-settings .pll-configure>td{padding:20px 20px 20px 40px}.pll-configure legend{font-size:14px;font-weight:600;margin-bottom:.5em}.pll-configure td .description{margin-bottom:.5em;margin-top:2px}.pll-configure p.submit{margin-top:20px}.pll-configure .button{margin-right:20px}.pll-configure fieldset{margin-bottom:1.5em}.pll-inline-block-list{margin:0}.pll-inline-block-list li{display:inline-block;margin:0;width:250px}#pll-domains-table td{border:none;-webkit-box-shadow:none;box-shadow:none;padding:2px 2px 2px 1.5em}.pll-settings-url-col{display:inline-block;vertical-align:top;width:49%}#pll-licenses-table td{vertical-align:top}#pll-licenses-table label{font-size:1em;font-weight:600}.pll-configure .pll-deactivate-license{margin:0 0 0 20px}.wp-list-table td[class*=column-language_],.wp-list-table th[class*=column-language_]{box-sizing:content-box;width:1.5em}.pll-dir-rtl input[type=text],.pll-dir-rtl textarea{direction:rtl}.pll-dir-ltr input[type=text],.pll-dir-ltr textarea{direction:ltr}.pll-dir-ltr .tr_lang,.pll-dir-rtl .tr_lang{direction:inherit}#ml_box p{margin-top:1em}#post-translations p{float:left;margin-top:1em}.rtl #post-translations p{float:right}#post-translations table{clear:both;table-layout:fixed;width:100%}#post-translations a{text-decoration:none}#post-translations .pll-column-icon,#post-translations .pll-language-column{width:20px}#post-translations .tr_lang{width:100%}#post-translations td{padding:2px}#post-translations .spinner,#term-translations .spinner{background-position:50%;float:none;margin:0;width:auto}#select-post-language .pll-select-flag{margin-right:10px;padding:4px}.rtl #select-post-language .pll-select-flag{margin-left:10px;margin-right:0;padding:4px}#select-media-language .pll-select-flag{margin-right:10px;padding:4px}.pll-media-edit-column{float:right}.pll-translation-flag{margin-right:14px}#select-add-term-language .pll-select-flag{margin-right:13px;padding:11px}#select-edit-term-language .pll-select-flag{margin-right:4px;padding:11px}#term-translations p{color:#23282d;font-style:normal;font-weight:400;padding:2px}#add-term-translations,#edit-term-translations{width:95%}#term-translations .pll-language-column{line-height:28px;width:20%}#add-term-translations .pll-language-column,#term-translations .pll-edit-column{width:20px}#edit-term-translations .pll-language-column{font-weight:400;padding:15px 10px}.pll_icon_add:before{content:"\f132"}.pll_icon_edit:before{content:"\f464"}[class^=pll_icon_]{font:20px/1 dashicons;vertical-align:middle}#wpadminbar #wp-admin-bar-languages .ab-item img{margin:0 8px 0 2px}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{float:none;top:4px}#wpadminbar #wp-admin-bar-languages .ab-icon:before{content:"\f326";top:1px}#wp-admin-bar-languages.pll-filtered-languages{background:#a03f3f}#wpadminbar #wp-admin-bar-languages.pll-filtered-languages span.ab-label{color:#fff}.pll-notice.notice{padding-right:38px;position:relative}.pll-notice a.notice-dismiss{text-decoration:none}.pll-notice .button{margin-right:10px}.languages_page_mlang_strings .metabox-holder>div{display:flex}.languages_page_mlang_strings .metabox-holder>div>div{flex-grow:1}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:1rem}.languages_page_mlang_strings .metabox-holder>div>div.closed{background:none;border:0}.languages_page_mlang_strings .metabox-holder>div>div.closed .postbox-header{background:#fff;border:1px solid #ccd0d4}@media screen and (max-width:782px){#wpbody-content .pll-settings .pll-configure>td{padding:20px}#wpbody-content .pll-settings #cb{padding:20px 9px}.pll-inline-block{width:auto}.pll-settings-url-col{display:block;width:100%}#wpbody-content .pll-settings #pll-licenses-table td{display:block}.pll-configure .pll-deactivate-license{margin:10px 0 5px}.translation label{display:block;padding-left:0;width:95%}.translation input,.translation textarea{width:95%}.languages_page_mlang_strings .metabox-holder>div{flex-direction:column}.languages_page_mlang_strings .metabox-holder>div>div:nth-child(2n){margin-left:0}#edit-term-translations .pll-language-name,#select-add-term-language .pll-select-flag,#select-edit-term-language .pll-select-flag{display:none}#edit-term-translations{width:100%}#add-term-translations .pll-language-column{line-height:38px}#edit-term-translations td{padding:8px 10px}#edit-term-translations .pll-edit-column,#edit-term-translations .pll-language-column{width:20px}.term-translations .pll-edit-column,.term-translations .pll-language-column,.term-translations .pll-translation-column{display:table-cell}.term-translations .hidden{display:none}#wpadminbar #wp-admin-bar-languages{display:block}#wpadminbar #wp-admin-bar-languages>.ab-item{text-align:center;width:50px}#wpadminbar #wp-admin-bar-languages>.ab-item .ab-icon:before{font:32px/1 dashicons;top:-1px}#wpadminbar #wp-admin-bar-languages>.ab-item img{margin:19px 0}#wpadminbar #wp-admin-bar-languages #wp-admin-bar-all .ab-item .ab-icon{font-size:20px!important;line-height:20px!important;margin-right:6px}}
css/build/dialog.min.css CHANGED
@@ -1 +1 @@
1
- .pll-confirmation-modal.ui-widget,.pll-confirmation-modal .ui-widget,.pll-confirmation-modal.ui-widget .ui-widget{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.pll-confirmation-modal.ui-dialog{padding:0;z-index:100102;background:#fff;border:0;color:#444;border-radius:0}.ui-dialog.pll-confirmation-modal .ui-dialog-titlebar{background:#fcfcfc;border-radius:0;border:0;border-bottom:1px solid #dfdfdf;height:36px;font-size:18px;font-weight:600;line-height:2;padding:0 36px 0 16px;color:#444;position:static}.ui-dialog.pll-confirmation-modal .ui-dialog-title{float:none;width:auto;margin:0}.pll-confirmation-modal .ui-widget-header .ui-icon{background:none;position:static}.pll-confirmation-modal .ui-button.ui-dialog-titlebar-close{padding:0;margin:0;top:0;right:0;width:36px;height:36px;border:0;background:none}.ui-dialog.pll-confirmation-modal .ui-dialog-content{border:0;padding:16px;color:#444;position:static;box-sizing:border-box}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{margin:0;padding:16px;border:0;background:#fcfcfc;border-top:1px solid #dfdfdf}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{margin:0 0 0 16px;padding:0 10px 1px;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;position:static;line-height:2;vertical-align:top}.ui-dialog.pll-confirmation-modal .ui-button:focus,.ui-dialog.pll-confirmation-modal .ui-button:hover{background:#fafafa;border-color:#999;color:#23282d}.pll-confirmation-modal+.ui-widget-overlay{background:#000;opacity:.7;z-index:100101}
1
+ .pll-confirmation-modal.ui-widget,.pll-confirmation-modal .ui-widget,.pll-confirmation-modal.ui-widget .ui-widget{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.pll-confirmation-modal.ui-dialog{background:#fff;border:0;border-radius:0;color:#444;padding:0;z-index:100102}.ui-dialog.pll-confirmation-modal .ui-dialog-titlebar{background:#fcfcfc;border:0;border-bottom:1px solid #dfdfdf;border-radius:0;color:#444;font-size:18px;font-weight:600;height:36px;line-height:2;padding:0 36px 0 16px;position:static}.ui-dialog.pll-confirmation-modal .ui-dialog-title{float:none;margin:0;width:auto}.pll-confirmation-modal .ui-widget-header .ui-icon{background:none;position:static}.pll-confirmation-modal .ui-button.ui-dialog-titlebar-close{background:none;border:0;height:36px;margin:0;padding:0;right:0;top:0;width:36px}.ui-dialog.pll-confirmation-modal .ui-dialog-content{border:0;box-sizing:border-box;color:#444;padding:16px;position:static}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{background:#fcfcfc;border:0;border-top:1px solid #dfdfdf;margin:0;padding:16px}.ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{background:#f7f7f7;border:1px solid #ccc;border-radius:3px;line-height:2;margin:0 0 0 16px;padding:0 10px 1px;position:static;vertical-align:top}.ui-dialog.pll-confirmation-modal .ui-button:focus,.ui-dialog.pll-confirmation-modal .ui-button:hover{background:#fafafa;border-color:#999;color:#23282d}.pll-confirmation-modal+.ui-widget-overlay{background:#000;opacity:.7;z-index:100101}
css/build/selectmenu.min.css CHANGED
@@ -1 +1 @@
1
- .ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item:not([role]){padding:0}.ui-menu-item-wrapper{padding:3px 1em 3px 2em}.rtl .ui-menu .ui-menu-item{text-align:right}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item[role]{padding-left:2em}.rtl .ui-menu-icons .ui-menu-item[role],.rtl .ui-menu-item-wrapper{padding-left:1em;padding-right:2em}.ui-menu .ui-icon,.ui-selectmenu-text .ui-icon{position:absolute;top:0;bottom:0;left:.3em;margin:auto 0}.rtl .ui-menu .ui-icon,.rtl .ui-selectmenu-text .ui-icon{right:.3em;left:auto}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:700;line-height:23px;padding:2px .4em;margin:.5em 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button,.ui-selectmenu-button.ui-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;box-sizing:border-box;text-align:left;white-space:nowrap;vertical-align:top;padding:0;line-height:normal;height:28px}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;position:absolute;top:26%;width:16px;height:16px;text-indent:0;background:none}.rtl .ui-selectmenu-button span.ui-icon{left:.5em;right:auto}.ui-selectmenu-button.ui-widget span.ui-selectmenu-text,.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.1em 2.1em .2em 2em;display:block;line-height:23px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.rtl .ui-selectmenu-button span.ui-selectmenu-text{text-align:right;padding:.2em 2em .2em 2.1em}.ui-button.ui-selectmenu-button-closed,.ui-button.ui-selectmenu-button-open,.ui-selectmenu-button.ui-state-default,.ui-state-default,.ui-widget-content,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);color:#32373c}.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed,.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open,.toplevel_page_mlang .ui-selectmenu-button.ui-state-default{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993}.pll-selectmenu-button.ui-widget,.pll-selectmenu-menu .ui-widget{font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif}.toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{color:#016087;border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent;background:#fff}.toplevel_page_mlang .ui-menu-item,.toplevel_page_mlang .ui-widget-content .ui-state-active,.toplevel_page_mlang .ui-widget-content .ui-state-focus,.toplevel_page_mlang .ui-widget-content .ui-state-hover{color:#016087;margin:0}.pll-selectmenu-menu .ui-widget-content .ui-state-active,.pll-selectmenu-menu .ui-widget-content .ui-state-focus,.pll-selectmenu-menu .ui-widget-content .ui-state-hover,.ui-selectmenu-open .ui-widget-content .ui-state-active,.ui-selectmenu-open .ui-widget-content .ui-state-focus,.ui-selectmenu-open .ui-widget-content .ui-state-hover{background:#d5d5d5;border:0}.ui-selectmenu-button.ui-state-focus{border:1px solid #5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}.ui-icon-triangle-1-s:before{content:"";background:#fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0 top 55%;background-size:16px 16px;box-sizing:border-box;position:absolute;width:16px;height:16px}.pll-selectmenu-button.ui-button:hover,.pll-wizard .ui-button:focus,.pll-wizard .ui-button:hover{background:#fff}.ui-widget-content{max-height:231px;box-shadow:0 2px 6px hsla(0,0%,39.2%,.3)}
1
+ .ui-widget-overlay{height:100%;left:0;position:fixed;top:0;width:100%}.ui-menu{display:block;list-style:none;margin:0;outline:none;padding:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");margin:0;min-height:0;padding:3px 1em 3px .4em;position:relative}.ui-menu .ui-menu-item:not([role]){padding:0}.ui-menu-item-wrapper{padding:3px 1em 3px 2em}.rtl .ui-menu .ui-menu-item{text-align:right}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item[role]{padding-left:2em}.rtl .ui-menu-icons .ui-menu-item[role],.rtl .ui-menu-item-wrapper{padding-left:1em;padding-right:2em}.ui-menu .ui-icon,.ui-selectmenu-text .ui-icon{bottom:0;left:.3em;margin:auto 0;position:absolute;top:0}.rtl .ui-menu .ui-icon,.rtl .ui-selectmenu-text .ui-icon{left:auto;right:.3em}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-selectmenu-menu{display:none;left:0;margin:0;padding:0;position:absolute;top:0}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{border:0;font-size:1em;font-weight:700;height:auto;line-height:23px;margin:.5em 0 0;padding:2px .4em}.ui-selectmenu-open{display:block}.ui-selectmenu-button,.ui-selectmenu-button.ui-button{box-sizing:border-box;display:inline-block;height:28px;line-height:normal;overflow:hidden;padding:0;position:relative;text-align:left;text-decoration:none;vertical-align:top;white-space:nowrap}.ui-selectmenu-button span.ui-icon{background:none;height:16px;left:auto;position:absolute;right:.5em;text-indent:0;top:26%;width:16px}.rtl .ui-selectmenu-button span.ui-icon{left:.5em;right:auto}.ui-selectmenu-button.ui-widget span.ui-selectmenu-text,.ui-selectmenu-button span.ui-selectmenu-text{display:block;line-height:23px;margin:0;overflow:hidden;padding:.1em 2.1em .2em 2em;text-align:left;text-overflow:ellipsis;white-space:nowrap}.rtl .ui-selectmenu-button span.ui-selectmenu-text{padding:.2em 2em .2em 2.1em;text-align:right}.ui-button.ui-selectmenu-button-closed,.ui-button.ui-selectmenu-button-open,.ui-selectmenu-button.ui-state-default,.ui-state-default,.ui-widget-content,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);color:#32373c}.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed,.toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open,.toplevel_page_mlang .ui-selectmenu-button.ui-state-default{border:1px solid #7e8993;border-radius:4px;box-shadow:0 0 0 transparent}.pll-selectmenu-button.ui-widget,.pll-selectmenu-menu .ui-widget{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;font-size:13px}.toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{background:#fff;border-color:#007cba;box-shadow:0 0 0 1px #007cba;color:#016087;outline:2px solid transparent}.toplevel_page_mlang .ui-menu-item,.toplevel_page_mlang .ui-widget-content .ui-state-active,.toplevel_page_mlang .ui-widget-content .ui-state-focus,.toplevel_page_mlang .ui-widget-content .ui-state-hover{color:#016087;margin:0}.pll-selectmenu-menu .ui-widget-content .ui-state-active,.pll-selectmenu-menu .ui-widget-content .ui-state-focus,.pll-selectmenu-menu .ui-widget-content .ui-state-hover,.ui-selectmenu-open .ui-widget-content .ui-state-active,.ui-selectmenu-open .ui-widget-content .ui-state-focus,.ui-selectmenu-open .ui-widget-content .ui-state-hover{background:#d5d5d5;border:0}.ui-selectmenu-button.ui-state-focus{border:1px solid #5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}.ui-icon-triangle-1-s:before{background:#fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0 top 55%;background-size:16px 16px;box-sizing:border-box;content:"";height:16px;position:absolute;width:16px}.pll-selectmenu-button.ui-button:hover,.pll-wizard .ui-button:focus,.pll-wizard .ui-button:hover{background:#fff}.ui-widget-content{box-shadow:0 2px 6px hsla(0,0%,39%,.3);max-height:231px}
css/build/wizard.min.css CHANGED
@@ -1 +1 @@
1
- body{margin:65px auto 24px;box-shadow:none;background:#f1f1f1}#pll-logo,body{padding:0;border:0}#pll-logo{margin:0 0 24px;text-align:center;font-family:sans-serif;font-size:64px;text-transform:uppercase;color:#000;line-height:normal}#pll-logo a{display:flex;justify-content:center;color:#000;text-decoration:none}#pll-logo img{max-width:100%;margin-right:16px}.rtl #pll-logo img{margin-right:0;margin-left:16px}.pll-wizard-footer{text-align:center}.pll-wizard .select2-container{text-align:left;width:auto}.pll-wizard .hidden{display:none}.pll-wizard-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:2em;margin:0 0 20px;background:#fff;overflow:hidden;zoom:1;text-align:left}.rtl .pll-wizard-content{text-align:right}.pll-wizard-content h1,.pll-wizard-content h2,.pll-wizard-content h3,.pll-wizard-content table{margin:0 0 20px;border:0;padding:0;color:#666;clear:none;font-weight:500}.pll-wizard-content p{margin:20px 0;font-size:1em;line-height:1.75em;color:#666}.pll-wizard-content table{font-size:1em;line-height:1.75em;color:#666;width:100%;margin-top:20px}.pll-wizard-content table td span{display:inline-block}.pll-wizard-content table caption{caption-side:bottom;font-style:italic;text-align:right}.rtl .pll-wizard-content table caption{text-align:left}.pll-wizard-content table caption .icon-default-lang{font-style:normal}.pll-wizard-content a{color:#a03f3f}.pll-wizard-content a:focus,.pll-wizard-content a:hover,.pll-wizard-footer-links:hover{color:#dd5454}.pll-wizard-content .pll-wizard-next-steps{overflow:hidden;margin:0 0 24px;padding-bottom:2px}.pll-wizard-content .pll-wizard-next-steps h2{margin-bottom:12px}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first{float:left;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last{float:right;width:50%;box-sizing:border-box}.pll-wizard-content .pll-wizard-next-steps ul{padding:0 2em 0 0;list-style:none outside;margin:0}.pll-wizard-content .pll-wizard-next-steps ul li a{display:block;padding:0 0 .75em}.pll-wizard-content .pll-wizard-next-steps ul li a:before{color:#82878c;font:normal 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;text-decoration:none!important;vertical-align:top}.pll-wizard-steps{padding:0 0 24px;margin:0;list-style:none outside;overflow:hidden;color:#ccc;width:100%;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex}.pll-wizard-steps li{width:100%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.pll-wizard-steps li a{color:#a03f3f;text-decoration:none;padding:1.5em;margin:-1.5em;position:relative;z-index:1}.pll-wizard-steps li a:focus,.pll-wizard-steps li a:hover{color:#dd5454;text-decoration:underline}.pll-wizard-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.pll-wizard-steps li.active{border-color:#a03f3f;color:#a03f3f;font-weight:700}.pll-wizard-steps li.active:before{border-color:#a03f3f}.pll-wizard-steps li.done{border-color:#a03f3f;color:#a03f3f}.pll-wizard-steps li.done:before{border-color:#a03f3f;background:#a03f3f}.pll-wizard .pll-wizard-actions{overflow:hidden;margin:20px 0 0;position:relative}.pll-wizard .pll-wizard-actions .button{font-size:16px;font-weight:300;padding:1em 2em;line-height:1em;margin-right:.5em;margin-bottom:2px;margin-top:10px;height:auto;border-radius:4px;box-shadow:none;min-width:auto;border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-content .button{border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-actions .button-primary,.pll-wizard .pll-wizard-content .button-primary{background-color:#a03f3f;border-color:#a03f3f;color:#fff;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #a03f3f;text-shadow:0 -1px 1px #a03f3f,1px 0 1px #a03f3f,0 1px 1px #a03f3f,-1px 0 1px #a03f3f;margin:0;opacity:1}.pll-wizard .pll-wizard-content .button-small .dashicons{font-size:15px;height:auto;vertical-align:middle}.pll-wizard .button-primary:active,.pll-wizard .button-primary:focus,.pll-wizard .button-primary:hover,.pll-wizard input[type=checkbox]:focus+label.button-primary{background:#dd5454;border-color:#dd5454;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #dd5454}.pll-wizard .pll-wizard-actions .button-primary.disabled,.pll-wizard .pll-wizard-actions .button-primary:disabled,.pll-wizard .pll-wizard-actions .button-primary[disabled]{cursor:wait;background-color:#bb5454!important;border-color:#bb5454!important;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #bb5454!important;text-shadow:0 -1px 1px #bb5454,1px 0 1px #bb5454,0 1px 1px #bb5454,-1px 0 1px #bb5454!important;color:#ffa3a3!important}.pll-wizard-content p:last-child{margin-bottom:0}.pll-wizard-footer-links{font-size:.85em;color:#7b7b7b;margin:1.18em auto;display:inline-block;text-align:center}.pll-wizard-services{border:1px solid #eee;padding:0;margin:0 0 1em;list-style:none outside;border-radius:4px;overflow:hidden}.pll-wizard-services p{margin:0 0 1em;padding:0;font-size:1em;line-height:1.5em}.pll-wizard-service-item{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;padding:0;border-bottom:1px solid #eee;color:#666;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.media-step .pll-wizard-service-item{border:0}.media-step .pll-wizard-service-item:last-child{display:block}.media-step .pll-wizard-service-item .pll-wizard-service-enable{padding-bottom:0}.pll-wizard-service-item:last-child{border-bottom:0}.pll-wizard-service-item .pll-wizard-service-name{-webkit-flex-basis:0;flex-basis:0;min-width:160px;text-align:center;font-weight:700;padding:2em 0;-webkit-align-self:stretch;align-self:stretch;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:baseline;-webkit-align-items:baseline;align-items:baseline}.pll-wizard-service-item .pll-wizard-service-name img{max-width:75px}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;padding:20px}.pll-wizard-service-item .pll-wizard-service-example{padding:0 20px 20px}.pll-wizard-service-item .pll-wizard-service-example p{text-align:right}.rtl .pll-wizard-service-item .pll-wizard-service-example p{text-align:left}.pll-wizard-service-item .pll-wizard-service-description p{margin-bottom:1em}.pll-wizard-service-item .pll-wizard-service-description p:last-child{margin-bottom:0}.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description{display:block;font-style:italic;color:#999}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-flex-basis:0;flex-basis:0;min-width:75px;text-align:center;cursor:pointer;padding:2em 0;position:relative;max-height:1.5em;-webkit-align-self:flex-start;align-self:flex-start;-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-toggle{position:relative}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]{position:absolute;opacity:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label{position:relative;display:inline-block;width:44px;height:20px;border-radius:10em;cursor:pointer;text-indent:-9999px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus+label{border:1px dashed #777}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after,.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{content:"";position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{left:0;top:0;width:44px;height:20px;background:#ddd;border-radius:10em;transition:background-color .2s}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after{width:16px;height:16px;transition:all .2s;border-radius:50%;background:#fff;margin:2px;top:0;left:0}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:before{background:#a03f3f}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:after{right:0;left:auto}.pll-wizard-service-item .pll-wizard-service-settings{display:none;margin-top:.75em;margin-bottom:0;cursor:default}.pll-wizard-service-item .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.checked .pll-wizard-service-settings{display:inline-block}.pll-wizard-service-item.checked .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.closed{border-bottom:0}.step{text-align:center}.pll-wizard .button .dashicons{vertical-align:middle}.rtl .dashicons-arrow-right-alt2:before{content:"\f341"}.pll-wizard .pll-wizard-actions .button:active,.pll-wizard .pll-wizard-actions .button:focus,.pll-wizard .pll-wizard-actions .button:hover{box-shadow:none}.pll-wizard-next-steps{border:1px solid #eee;border-radius:4px;list-style:none;padding:0}.pll-wizard-next-steps li{padding:0}.pll-wizard-next-steps .pll-wizard-next-step-item{display:-webkit-box;display:-webkit-flex;display:flex;border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,.pll-wizard-next-steps .pll-wizard-next-step-item:first-child{border-top:0}.pll-wizard-next-steps .pll-wizard-next-step-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;margin:1.5em}.pll-wizard-next-steps .pll-wizard-next-step-action{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.pll-wizard-next-steps .pll-wizard-next-step-action .button{margin:1em 1.5em}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description{margin-top:0}.pll-wizard-next-steps p.next-step-heading{margin:0;font-size:.95em;font-weight:400;font-variant:all-petite-caps}.pll-wizard-next-steps p.next-step-extra-info{margin:0}.pll-wizard-next-steps h3.next-step-description{margin:0;font-size:16px;font-weight:600}.pll-wizard-next-steps .pll-wizard-additional-steps{border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions{margin:0 0 1.5em}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{font-size:15px;margin:1em 0 1em 1.5em}.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{margin:1em 1.5em 1em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child{margin-right:1.5em}.pll-wizard-content img{max-width:100%;margin-right:.5em}.rtl .pll-wizard-content img{margin-left:.5em}.pll-wizard-content .form-field label{margin-bottom:5px;display:block}.pll-wizard-content .form-field select{padding:3px}.pll-wizard-content .languages-step select,.pll-wizard-content .untranslated-contents-step select{width:100%}.languages-step .form-field .button{margin-left:15px}.languages-step .form-field .button>span{margin-right:.3em}.rtl .languages-step .form-field .button{margin-left:0;margin-right:15px}.rtl .languages-step .form-field .button>span{margin-left:.3em;margin-right:0}.pll-wizard-content .languages-step .select-language-field{display:flex}.pll-wizard-content #languages{display:none}.pll-wizard-content #languages tr th:first-child{width:80%}.pll-wizard-content #languages .dashicons{color:#a03f3f}.pll-wizard-content #languages img{margin-right:5px}.pll-wizard-content .error{color:#a03f3f;font-weight:700}.pll-wizard-content #messages .error{background:#fccfcf;padding:.5rem;border:1px solid #a03f3f;margin-bottom:.5rem}.pll-wizard-content #slide-toggle{position:absolute;opacity:0}.pll-wizard-content #slide-toggle+label{position:relative}.pll-wizard-content #slide-toggle+label+span{display:block}.pll-wizard-content #slide-toggle+label .dashicons{margin-right:.3em}.rtl .pll-wizard-content #slide-toggle+label .dashicons{margin-left:.3em;margin-right:0}.pll-wizard-content #slide-toggle~#screenshot>img{max-height:500px;margin-top:10px;-webkit-transition:all .5s cubic-bezier(0,1,.5,1);transition:all .5s cubic-bezier(0,1,.5,1)}.pll-wizard-content #slide-toggle:checked~#screenshot>img{max-height:0}.hide{display:none}.field-in-error,input[type=checkbox].field-in-error,input[type=color].field-in-error,input[type=date].field-in-error,input[type=datetime-local].field-in-error,input[type=datetime].field-in-error,input[type=email].field-in-error,input[type=month].field-in-error,input[type=number].field-in-error,input[type=password].field-in-error,input[type=radio].field-in-error,input[type=search].field-in-error,input[type=tel].field-in-error,input[type=text].field-in-error,input[type=time].field-in-error,input[type=url].field-in-error,input[type=week].field-in-error,select.field-in-error,span.field-in-error,textarea.field-in-error{border-color:#a03f3f}.field-in-error:focus,input[type=checkbox].field-in-error:focus,input[type=color].field-in-error:focus,input[type=date].field-in-error:focus,input[type=datetime-local].field-in-error:focus,input[type=datetime].field-in-error:focus,input[type=email].field-in-error:focus,input[type=month].field-in-error:focus,input[type=number].field-in-error:focus,input[type=password].field-in-error:focus,input[type=radio].field-in-error:focus,input[type=search].field-in-error:focus,input[type=tel].field-in-error:focus,input[type=text].field-in-error:focus,input[type=time].field-in-error:focus,input[type=url].field-in-error:focus,input[type=week].field-in-error:focus,select.field-in-error:focus,span.field-in-error:focus,textarea.field-in-error:focus{border:1px solid #a03f3f;box-shadow:0 0 2px rgba(160,63,63,.8);outline-color:#a03f3f;outline-style:auto;outline-width:thin}.form-table input.regular-text{width:25em}.form-table input.field-in-error{border-color:#a03f3f}#pll-licenses-table td{padding:10px 9px}#pll-licenses-table .license-valid td p{min-width:35em}#pll-licenses-table .pll-deactivate-license{margin:0 0 0 20px}.rtl #pll-licenses-table .pll-deactivate-license{margin:0 10px 0 0}.pll-wizard-content .documentation{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.pll-wizard-content .documentation p{padding:0;margin:0 0 12px}.documentation-container{display:-webkit-box;display:-webkit-flex;display:flex;justify-content:flex-end}.documentation-container .documentation-button-container{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}.wc-setup .wc-setup-actions .button.documentation-button{height:42px;padding:0 1em;margin:0}#dialog{display:none}.pll-wizard .ui-dialog.ui-widget-content{max-height:none}.pll-wizard .ui-dialog-title:before{content:"\f534";font-family:dashicons;display:inline-block;line-height:1;font-weight:400;font-style:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:20px;height:20px;font-size:20px;vertical-align:middle;text-align:center;margin:0 5px 5px 0;transition:color .1s ease-in}.rtl.pll-wizard .ui-dialog-title:before{margin-right:0;margin-left:5px}.pll-wizard .ui-dialog ul{list-style:disc;padding-left:20px}.rtl.pll-wizard .ui-dialog ul{padding-left:0;padding-right:20px}.pll-wizard li{margin-bottom:0}#translations{border-collapse:collapse}#translations tbody:nth-child(odd){background-color:#f9f9f9}#translations.striped>tbody>:nth-child(odd){background-color:transparent}.pll-wizard-content mark{background:transparent none;color:#7ad03a}@media screen and (max-width:782px){.languages-step .form-field .button{font-size:13px;line-height:26px;height:28px;padding:0 10px 1px;vertical-align:top}#pll-licenses-table .pll-deactivate-license{margin:10px 0 5px}}@media only screen and (max-width:620px){.ui-dialog{width:100%!important}}@media only screen and (max-width:500px){#pll-logo a,.select-language-field{flex-direction:column}.select-language-field .action-buttons{display:flex;justify-content:flex-end}.languages-step .form-field .button{margin:5px 0 0}}@media only screen and (max-width:400px){#pll-logo{font-size:56px}.pll-wizard-steps{display:none}.pll-wizard-service-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:3;-webkit-order:2;order:2;padding:20px 0 0}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-name{padding:20px 20px 0;text-align:left;-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;justify-content:space-between!important}.pll-wizard-service-item .pll-wizard-service-name img{margin:0}.pll-wizard-next-steps .pll-wizard-next-step-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p{margin:0}}@media only screen and (max-width:360px){#pll-logo{font-size:48px}}
1
+ body{background:#f1f1f1;box-shadow:none;margin:65px auto 24px}#pll-logo,body{border:0;padding:0}#pll-logo{color:#000;font-family:sans-serif;font-size:64px;line-height:normal;margin:0 0 24px;text-align:center;text-transform:uppercase}#pll-logo a{color:#000;display:flex;justify-content:center;text-decoration:none}#pll-logo img{margin-right:16px;max-width:100%}.rtl #pll-logo img{margin-left:16px;margin-right:0}.pll-wizard-footer{text-align:center}.pll-wizard .select2-container{text-align:left;width:auto}.pll-wizard .hidden{display:none}.pll-wizard-content{zoom:1;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);margin:0 0 20px;overflow:hidden;padding:2em;text-align:left}.rtl .pll-wizard-content{text-align:right}.pll-wizard-content h1,.pll-wizard-content h2,.pll-wizard-content h3,.pll-wizard-content table{border:0;clear:none;color:#666;font-weight:500;margin:0 0 20px;padding:0}.pll-wizard-content p{color:#666;font-size:1em;line-height:1.75em;margin:20px 0}.pll-wizard-content table{color:#666;font-size:1em;line-height:1.75em;margin-top:20px;width:100%}.pll-wizard-content table td span{display:inline-block}.pll-wizard-content table caption{caption-side:bottom;font-style:italic;text-align:right}.rtl .pll-wizard-content table caption{text-align:left}.pll-wizard-content table caption .icon-default-lang{font-style:normal}.pll-wizard-content a{color:#a03f3f}.pll-wizard-content a:focus,.pll-wizard-content a:hover,.pll-wizard-footer-links:hover{color:#dd5454}.pll-wizard-content .pll-wizard-next-steps{margin:0 0 24px;overflow:hidden;padding-bottom:2px}.pll-wizard-content .pll-wizard-next-steps h2{margin-bottom:12px}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-first{box-sizing:border-box;float:left;width:50%}.pll-wizard-content .pll-wizard-next-steps .pll-wizard-next-steps-last{box-sizing:border-box;float:right;width:50%}.pll-wizard-content .pll-wizard-next-steps ul{list-style:none outside;margin:0;padding:0 2em 0 0}.pll-wizard-content .pll-wizard-next-steps ul li a{display:block;padding:0 0 .75em}.pll-wizard-content .pll-wizard-next-steps ul li a:before{speak:none;color:#82878c;display:inline-block;font:normal 20px/1 dashicons;padding:0 10px 0 0;position:relative;text-decoration:none!important;top:1px;vertical-align:top}.pll-wizard-steps{color:#ccc;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;list-style:none outside;margin:0;overflow:hidden;padding:0 0 24px;width:100%}.pll-wizard-steps li{border-bottom:4px solid #ccc;float:left;line-height:1.4em;margin:0;padding:0 0 .8em;position:relative;text-align:center;width:100%}.pll-wizard-steps li a{color:#a03f3f;margin:-1.5em;padding:1.5em;position:relative;text-decoration:none;z-index:1}.pll-wizard-steps li a:focus,.pll-wizard-steps li a:hover{color:#dd5454;text-decoration:underline}.pll-wizard-steps li:before{background:#fff;border:4px solid #ccc;border-radius:100%;bottom:0;content:"";height:4px;left:50%;margin-bottom:-8px;margin-left:-6px;position:absolute;width:4px}.pll-wizard-steps li.active{border-color:#a03f3f;color:#a03f3f;font-weight:700}.pll-wizard-steps li.active:before{border-color:#a03f3f}.pll-wizard-steps li.done{border-color:#a03f3f;color:#a03f3f}.pll-wizard-steps li.done:before{background:#a03f3f;border-color:#a03f3f}.pll-wizard .pll-wizard-actions{margin:20px 0 0;overflow:hidden;position:relative}.pll-wizard .pll-wizard-actions .button{border-color:#a03f3f;border-radius:4px;box-shadow:none;color:#a03f3f;font-size:16px;font-weight:300;height:auto;line-height:1em;margin-bottom:2px;margin-right:.5em;margin-top:10px;min-width:auto;padding:1em 2em}.pll-wizard .pll-wizard-content .button{border-color:#a03f3f;color:#a03f3f}.pll-wizard .pll-wizard-actions .button-primary,.pll-wizard .pll-wizard-content .button-primary{background-color:#a03f3f;border-color:#a03f3f;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #a03f3f;color:#fff;margin:0;opacity:1;text-shadow:0 -1px 1px #a03f3f,1px 0 1px #a03f3f,0 1px 1px #a03f3f,-1px 0 1px #a03f3f}.pll-wizard .pll-wizard-content .button-small .dashicons{font-size:15px;height:auto;vertical-align:middle}.pll-wizard .button-primary:active,.pll-wizard .button-primary:focus,.pll-wizard .button-primary:hover,.pll-wizard input[type=checkbox]:focus+label.button-primary{background:#dd5454;border-color:#dd5454;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #dd5454}.pll-wizard .pll-wizard-actions .button-primary.disabled,.pll-wizard .pll-wizard-actions .button-primary:disabled,.pll-wizard .pll-wizard-actions .button-primary[disabled]{background-color:#bb5454!important;border-color:#bb5454!important;box-shadow:inset 0 1px 0 hsla(0,0%,100%,.25),0 1px 0 #bb5454!important;color:#ffa3a3!important;cursor:wait;text-shadow:0 -1px 1px #bb5454,1px 0 1px #bb5454,0 1px 1px #bb5454,-1px 0 1px #bb5454!important}.pll-wizard-content p:last-child{margin-bottom:0}.pll-wizard-footer-links{color:#7b7b7b;display:inline-block;font-size:.85em;margin:1.18em auto;text-align:center}.pll-wizard-services{border:1px solid #eee;border-radius:4px;list-style:none outside;margin:0 0 1em;overflow:hidden;padding:0}.pll-wizard-services p{font-size:1em;line-height:1.5em;margin:0 0 1em;padding:0}.pll-wizard-service-item{-webkit-box-pack:justify;-webkit-box-align:center;-webkit-align-items:center;align-items:center;border-bottom:1px solid #eee;color:#666;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-justify-content:space-between;justify-content:space-between;padding:0}.media-step .pll-wizard-service-item{border:0}.media-step .pll-wizard-service-item:last-child{display:block}.media-step .pll-wizard-service-item .pll-wizard-service-enable{padding-bottom:0}.pll-wizard-service-item:last-child{border-bottom:0}.pll-wizard-service-item .pll-wizard-service-name{-webkit-box-align:baseline;-webkit-align-items:baseline;align-items:baseline;-webkit-align-self:stretch;align-self:stretch;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-basis:0;flex-basis:0;font-weight:700;min-width:160px;padding:2em 0;text-align:center}.pll-wizard-service-item .pll-wizard-service-name img{max-width:75px}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;padding:20px}.pll-wizard-service-item .pll-wizard-service-example{padding:0 20px 20px}.pll-wizard-service-item .pll-wizard-service-example p{text-align:right}.rtl .pll-wizard-service-item .pll-wizard-service-example p{text-align:left}.pll-wizard-service-item .pll-wizard-service-description p{margin-bottom:1em}.pll-wizard-service-item .pll-wizard-service-description p:last-child{margin-bottom:0}.pll-wizard-service-item .pll-wizard-service-description .pll-wizard-service-settings-description{color:#999;display:block;font-style:italic}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:4;-webkit-align-self:flex-start;align-self:flex-start;cursor:pointer;-webkit-flex-basis:0;flex-basis:0;max-height:1.5em;min-width:75px;-webkit-order:3;order:3;padding:2em 0;position:relative;text-align:center}.pll-wizard-service-item .pll-wizard-service-toggle{position:relative}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]{opacity:0;position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label{border-radius:10em;cursor:pointer;display:inline-block;height:20px;position:relative;text-indent:-9999px;width:44px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:focus+label{border:1px dashed #777}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after,.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{content:"";position:absolute}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:before{background:#ddd;border-radius:10em;height:20px;left:0;top:0;transition:background-color .2s;width:44px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]+label:after{background:#fff;border-radius:50%;height:16px;left:0;margin:2px;top:0;transition:all .2s;width:16px}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:before{background:#a03f3f}.pll-wizard-service-item .pll-wizard-service-toggle input[type=checkbox]:checked+label:after{left:auto;right:0}.pll-wizard-service-item .pll-wizard-service-settings{cursor:default;display:none;margin-bottom:0;margin-top:.75em}.pll-wizard-service-item .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.checked .pll-wizard-service-settings{display:inline-block}.pll-wizard-service-item.checked .pll-wizard-service-settings.hide{display:none}.pll-wizard-service-item.closed{border-bottom:0}.step{text-align:center}.pll-wizard .button .dashicons{vertical-align:middle}.rtl .dashicons-arrow-right-alt2:before{content:"\f341"}.pll-wizard .pll-wizard-actions .button:active,.pll-wizard .pll-wizard-actions .button:focus,.pll-wizard .pll-wizard-actions .button:hover{box-shadow:none}.pll-wizard-next-steps{border:1px solid #eee;border-radius:4px;list-style:none;padding:0}.pll-wizard-next-steps li{padding:0}.pll-wizard-next-steps .pll-wizard-next-step-item{border-top:1px solid #eee;display:-webkit-box;display:-webkit-flex;display:flex}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border,.pll-wizard-next-steps .pll-wizard-next-step-item:first-child{border-top:0}.pll-wizard-next-steps .pll-wizard-next-step-description{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;margin:1.5em}.pll-wizard-next-steps .pll-wizard-next-step-action{-webkit-box-flex:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-grow:0;flex-grow:0}.pll-wizard-next-steps .pll-wizard-next-step-action .button{margin:1em 1.5em}.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-actions,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-action .button,.pll-wizard-next-steps .pll-wizard-next-step-item.no-border .pll-wizard-next-step-description{margin-top:0}.pll-wizard-next-steps p.next-step-heading{font-size:.95em;font-variant:all-petite-caps;font-weight:400;margin:0}.pll-wizard-next-steps p.next-step-extra-info{margin:0}.pll-wizard-next-steps h3.next-step-description{font-size:16px;font-weight:600;margin:0}.pll-wizard-next-steps .pll-wizard-additional-steps{border-top:1px solid #eee}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions{margin:0 0 1.5em}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{font-size:15px;margin:1em 0 1em 1.5em}.rtl .pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button{margin:1em 1.5em 1em 0}.pll-wizard-next-steps .pll-wizard-additional-steps .pll-wizard-actions .button::last-child{margin-right:1.5em}.pll-wizard-content img{margin-right:.5em;max-width:100%}.rtl .pll-wizard-content img{margin-left:.5em}.pll-wizard-content .form-field label{display:block;margin-bottom:5px}.pll-wizard-content .form-field select{padding:3px}.pll-wizard-content .languages-step select,.pll-wizard-content .untranslated-contents-step select{width:100%}.languages-step .form-field .button{margin-left:15px}.languages-step .form-field .button>span{margin-right:.3em}.rtl .languages-step .form-field .button{margin-left:0;margin-right:15px}.rtl .languages-step .form-field .button>span{margin-left:.3em;margin-right:0}.pll-wizard-content .languages-step .select-language-field{display:flex}.pll-wizard-content #languages{display:none}.pll-wizard-content #languages tr th:first-child{width:80%}.pll-wizard-content #languages .dashicons{color:#a03f3f}.pll-wizard-content #languages img{margin-right:5px}.pll-wizard-content .error{color:#a03f3f;font-weight:700}.pll-wizard-content #messages .error{background:#fccfcf;border:1px solid #a03f3f;margin-bottom:.5rem;padding:.5rem}.pll-wizard-content #slide-toggle{opacity:0;position:absolute}.pll-wizard-content #slide-toggle+label{position:relative}.pll-wizard-content #slide-toggle+label+span{display:block}.pll-wizard-content #slide-toggle+label .dashicons{margin-right:.3em}.rtl .pll-wizard-content #slide-toggle+label .dashicons{margin-left:.3em;margin-right:0}.pll-wizard-content #slide-toggle~#screenshot>img{margin-top:10px;max-height:500px;-webkit-transition:all .5s cubic-bezier(0,1,.5,1);transition:all .5s cubic-bezier(0,1,.5,1)}.pll-wizard-content #slide-toggle:checked~#screenshot>img{max-height:0}.hide{display:none}.field-in-error,input[type=checkbox].field-in-error,input[type=color].field-in-error,input[type=date].field-in-error,input[type=datetime-local].field-in-error,input[type=datetime].field-in-error,input[type=email].field-in-error,input[type=month].field-in-error,input[type=number].field-in-error,input[type=password].field-in-error,input[type=radio].field-in-error,input[type=search].field-in-error,input[type=tel].field-in-error,input[type=text].field-in-error,input[type=time].field-in-error,input[type=url].field-in-error,input[type=week].field-in-error,select.field-in-error,span.field-in-error,textarea.field-in-error{border-color:#a03f3f}.field-in-error:focus,input[type=checkbox].field-in-error:focus,input[type=color].field-in-error:focus,input[type=date].field-in-error:focus,input[type=datetime-local].field-in-error:focus,input[type=datetime].field-in-error:focus,input[type=email].field-in-error:focus,input[type=month].field-in-error:focus,input[type=number].field-in-error:focus,input[type=password].field-in-error:focus,input[type=radio].field-in-error:focus,input[type=search].field-in-error:focus,input[type=tel].field-in-error:focus,input[type=text].field-in-error:focus,input[type=time].field-in-error:focus,input[type=url].field-in-error:focus,input[type=week].field-in-error:focus,select.field-in-error:focus,span.field-in-error:focus,textarea.field-in-error:focus{border:1px solid #a03f3f;box-shadow:0 0 2px rgba(160,63,63,.8);outline-color:#a03f3f;outline-style:auto;outline-width:thin}.form-table input.regular-text{width:25em}.form-table input.field-in-error{border-color:#a03f3f}#pll-licenses-table td{padding:10px 9px}#pll-licenses-table .license-valid td p{min-width:35em}#pll-licenses-table .pll-deactivate-license{margin:0 0 0 20px}.rtl #pll-licenses-table .pll-deactivate-license{margin:0 10px 0 0}.pll-wizard-content .documentation{background:#f5f5f5;margin:0 0 24px;overflow:hidden;padding:24px 24px 0}.pll-wizard-content .documentation p{margin:0 0 12px;padding:0}.documentation-container{display:-webkit-box;display:-webkit-flex;display:flex;justify-content:flex-end}.documentation-container .documentation-button-container{-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0}.wc-setup .wc-setup-actions .button.documentation-button{height:42px;margin:0;padding:0 1em}#dialog{display:none}.pll-wizard .ui-dialog.ui-widget-content{max-height:none}.pll-wizard .ui-dialog-title:before{speak:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:"\f534";display:inline-block;font-family:dashicons;font-size:20px;font-style:normal;font-weight:400;height:20px;line-height:1;margin:0 5px 5px 0;text-align:center;text-decoration:inherit;text-transform:none;transition:color .1s ease-in;vertical-align:middle;width:20px}.rtl.pll-wizard .ui-dialog-title:before{margin-left:5px;margin-right:0}.pll-wizard .ui-dialog ul{list-style:disc;padding-left:20px}.rtl.pll-wizard .ui-dialog ul{padding-left:0;padding-right:20px}.pll-wizard li{margin-bottom:0}#translations{border-collapse:collapse}#translations tbody:nth-child(odd){background-color:#f9f9f9}#translations.striped>tbody>:nth-child(odd){background-color:transparent}.pll-wizard-content mark{background:transparent none;color:#7ad03a}@media screen and (max-width:782px){.languages-step .form-field .button{font-size:13px;height:28px;line-height:26px;padding:0 10px 1px;vertical-align:top}#pll-licenses-table .pll-deactivate-license{margin:10px 0 5px}}@media only screen and (max-width:620px){.ui-dialog{width:100%!important}}@media only screen and (max-width:500px){#pll-logo a,.select-language-field{flex-direction:column}.select-language-field .action-buttons{display:flex;justify-content:flex-end}.languages-step .form-field .button{margin:5px 0 0}}@media only screen and (max-width:400px){#pll-logo{font-size:56px}.pll-wizard-steps{display:none}.pll-wizard-service-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-service-item .pll-wizard-service-enable{-webkit-box-ordinal-group:3;-webkit-order:2;order:2;padding:20px 0 0}.pll-wizard-service-item .pll-wizard-service-description{-webkit-box-ordinal-group:4;-webkit-order:3;order:3}.pll-wizard-service-item .pll-wizard-service-name{-webkit-box-pack:justify!important;-webkit-justify-content:space-between!important;justify-content:space-between!important;padding:20px 20px 0;text-align:left}.pll-wizard-service-item .pll-wizard-service-name img{margin:0}.pll-wizard-next-steps .pll-wizard-next-step-item{-webkit-flex-wrap:wrap;flex-wrap:wrap}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-description{margin-bottom:0}.pll-wizard-next-steps .pll-wizard-next-step-item .pll-wizard-next-step-action p{margin:0}}@media only screen and (max-width:360px){#pll-logo{font-size:48px}}
css/dialog.css DELETED
@@ -1,85 +0,0 @@
1
- /* By default Polylang dialog box use WordPress jQuery UI dialog styles.
2
- However WooCommerce loads its own jQuery UI dialog styles and we need to override them by ours
3
- to revert to the default WordPress ones.
4
- */
5
- .pll-confirmation-modal.ui-widget,
6
- .pll-confirmation-modal.ui-widget .ui-widget,
7
- .pll-confirmation-modal .ui-widget {
8
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
9
- font-size: 13px;
10
- }
11
- .pll-confirmation-modal.ui-dialog {
12
- padding: 0;
13
- z-index: 100102;
14
- background: #fff;
15
- border: 0;
16
- color: #444;
17
- border-radius: 0; /* Override WooCommerce dialog styles - jQuery UI 1.11.4 - WP < 5.6 */
18
- }
19
- .ui-dialog.pll-confirmation-modal .ui-dialog-titlebar {
20
- background: #fcfcfc;
21
- border-radius: 0;
22
- border: 0;
23
- border-bottom: 1px solid #dfdfdf;
24
- height: 36px;
25
- font-size: 18px;
26
- font-weight: 600;
27
- line-height: 2;
28
- padding: 0 36px 0 16px;
29
- color: #444;
30
- position: static;
31
- }
32
- .ui-dialog.pll-confirmation-modal .ui-dialog-title {
33
- float: none;
34
- width: auto;
35
- margin: 0;
36
- }
37
- .pll-confirmation-modal .ui-widget-header .ui-icon {
38
- background: none;
39
- position: static;
40
- }
41
- .pll-confirmation-modal .ui-button.ui-dialog-titlebar-close {
42
- padding: 0;
43
- margin: 0;
44
- top: 0;
45
- right: 0;
46
- width: 36px;
47
- height: 36px;
48
- border: 0; /* Override WooCommerce dialog styles - jQuery UI 1.11.4 - WP < 5.6 */
49
- background: none; /* Override WooCommerce dialog styles - jQuery UI 1.11.4 - WP < 5.6 */
50
- }
51
- .ui-dialog.pll-confirmation-modal .ui-dialog-content {
52
- border: 0;
53
- padding: 16px;
54
- color: #444;
55
- position: static;
56
- box-sizing: border-box;
57
- }
58
- .ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane{
59
- margin: 0;
60
- padding: 16px;
61
- border: 0;
62
- background: #fcfcfc;
63
- border-top: 1px solid #dfdfdf;
64
- }
65
- .ui-dialog.pll-confirmation-modal .ui-dialog-buttonpane .ui-button{
66
- margin: 0 0 0 16px;
67
- padding: 0 10px 1px;
68
- background: #f7f7f7;
69
- border: 1px solid #cccccc;
70
- border-radius: 3px;
71
- position: static;
72
- line-height: 2;
73
- vertical-align: top;
74
- }
75
- .ui-dialog.pll-confirmation-modal .ui-button:hover,
76
- .ui-dialog.pll-confirmation-modal .ui-button:focus {
77
- background: #fafafa;
78
- border-color: #999;
79
- color: #23282d;
80
- }
81
- .pll-confirmation-modal + .ui-widget-overlay {
82
- background: #000;
83
- opacity: 0.7;
84
- z-index: 100101;
85
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/selectmenu.css DELETED
@@ -1,239 +0,0 @@
1
- /* Greatly modified version of the jquery-ui.css */
2
-
3
- .ui-widget-overlay {
4
- position: fixed;
5
- top: 0;
6
- left: 0;
7
- width: 100%;
8
- height: 100%;
9
- }
10
-
11
- .ui-menu {
12
- list-style: none;
13
- padding: 0;
14
- margin: 0;
15
- display: block;
16
- outline: none;
17
- }
18
-
19
- .ui-menu .ui-menu {
20
- position: absolute;
21
- }
22
-
23
- .ui-menu .ui-menu-item {
24
- position: relative;
25
- margin: 0;
26
- padding: 3px 1em 3px .4em;
27
- cursor: pointer;
28
- min-height: 0; /* support: IE7 */
29
- /* support: IE10, see #8844 */
30
- list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
31
- }
32
-
33
- /* for jQuery UI 1.12 which introduces a wrapper */
34
- .ui-menu .ui-menu-item:not([role]) {
35
- padding: 0;
36
- }
37
-
38
- .ui-menu-item-wrapper {
39
- padding: 3px 1em 3px 2em;
40
- }
41
- .rtl .ui-menu .ui-menu-item {
42
- text-align: right;
43
- }
44
-
45
- /* icon support */
46
- .ui-menu-icons {
47
- position: relative;
48
- }
49
-
50
- .ui-menu-icons .ui-menu-item[role] {
51
- padding-left: 2em;
52
- }
53
-
54
- .rtl .ui-menu-item-wrapper, /* for jQuery UI 1.12 which introduces a wrapper */
55
- .rtl .ui-menu-icons .ui-menu-item[role] {
56
- padding-left: 1em;
57
- padding-right: 2em;
58
- }
59
-
60
- /* left-aligned */
61
- .ui-selectmenu-text .ui-icon,
62
- .ui-menu .ui-icon {
63
- position: absolute;
64
- top: 0;
65
- bottom: 0;
66
- left: .3em;
67
- margin: auto 0;
68
- }
69
-
70
- .rtl .ui-selectmenu-text .ui-icon,
71
- .rtl .ui-menu .ui-icon {
72
- right: .3em;
73
- left: auto;
74
- }
75
-
76
- /* right-aligned */
77
- .ui-menu .ui-menu-icon {
78
- left: auto;
79
- right: 0;
80
- }
81
-
82
- .ui-selectmenu-menu {
83
- padding: 0;
84
- margin: 0;
85
- position: absolute;
86
- top: 0;
87
- left: 0;
88
- display: none;
89
- }
90
-
91
- .ui-selectmenu-menu .ui-menu {
92
- overflow: auto;
93
- /* Support: IE7 */
94
- overflow-x: hidden;
95
- padding-bottom: 1px;
96
- }
97
-
98
- .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
99
- font-size: 1em;
100
- font-weight: bold;
101
- line-height: 23px;
102
- padding: 2px 0.4em;
103
- margin: 0.5em 0 0 0;
104
- height: auto;
105
- border: 0;
106
- }
107
-
108
- .ui-selectmenu-open {
109
- display: block;
110
- }
111
-
112
- .ui-selectmenu-button, /* jQuery UI 1.11.4 - WP < 5.6 */
113
- .ui-selectmenu-button.ui-button {
114
- display: inline-block;
115
- overflow: hidden;
116
- position: relative;
117
- text-decoration: none;
118
- box-sizing: border-box; /* To keep width calculation in percent since WP 5.6 */
119
- text-align: left;
120
- white-space: nowrap;
121
- vertical-align: top;
122
- padding: 0;
123
- line-height: normal; /* Override WC Bookings styles with WP < 5.6 */
124
- height: 28px; /* Override WC Bookings styles with WP < 5.6 */
125
- }
126
-
127
- .ui-selectmenu-button span.ui-icon {
128
- right: 0.5em;
129
- left: auto;
130
- position: absolute;
131
- top: 26%;
132
- width: 16px;
133
- height: 16px;
134
- text-indent: 0; /* due to text-indent for jquery ui-dialog in wizard */
135
- background: none;
136
- }
137
-
138
- .rtl .ui-selectmenu-button span.ui-icon {
139
- left: 0.5em;
140
- right: auto;
141
- }
142
-
143
-
144
- .ui-selectmenu-button.ui-widget span.ui-selectmenu-text, /* Override WC Bookings styles with WP < 5.6 */
145
- .ui-selectmenu-button span.ui-selectmenu-text {
146
- text-align: left;
147
- padding: 0.1em 2.1em 0.2em 2em;
148
- display: block;
149
- line-height: 23px;
150
- overflow: hidden;
151
- text-overflow: ellipsis;
152
- white-space: nowrap;
153
- margin: 0;
154
- }
155
-
156
- .rtl .ui-selectmenu-button span.ui-selectmenu-text {
157
- text-align: right;
158
- padding: 0.2em 2em 0.2em 2.1em;
159
- }
160
-
161
- .ui-widget-content,
162
- .ui-state-default,
163
- .ui-selectmenu-button.ui-state-default, /* Override WC Bookings styles with WP < 5.6 */
164
- .ui-button.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
165
- .ui-button.ui-selectmenu-button-open, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
166
- .ui-widget-content .ui-state-default,
167
- .ui-widget-header .ui-state-default {
168
- background: #fff;
169
- border: 1px solid #ddd;
170
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07) inset;
171
- color: #32373c;
172
- }
173
- /* Override to have same styles as WP form styles since WordPress 5.4 */
174
- .toplevel_page_mlang .ui-selectmenu-button.ui-state-default,
175
- .toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-closed, /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
176
- .toplevel_page_mlang .ui-selectmenu-button.ui-selectmenu-button-open{ /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
177
- box-shadow: 0 0 0 transparent;
178
- border-radius: 4px;
179
- border: 1px solid #7e8993;
180
- }
181
-
182
- /* From this line and below: override WooCommerce bookings plugin styles which overrides default WordPress styles */
183
- .pll-selectmenu-menu .ui-widget,
184
- .pll-selectmenu-button.ui-widget {
185
- font-size: 13px;
186
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
187
- }
188
-
189
- .toplevel_page_mlang .ui-button.ui-selectmenu-button:focus{
190
- color: #016087; /* Same color as WordPress focused select HTML tag */
191
- border-color: #007cba;
192
- box-shadow: 0 0 0 1px #007cba;
193
- outline: 2px solid transparent;
194
- background: #fff; /* Override bookings plugin styles which overrides default WordPress styles */
195
- }
196
-
197
- .toplevel_page_mlang .ui-menu-item,
198
- .toplevel_page_mlang .ui-widget-content .ui-state-hover,
199
- .toplevel_page_mlang .ui-widget-content .ui-state-focus,
200
- .toplevel_page_mlang .ui-widget-content .ui-state-active {
201
- color: #016087; /* Same color as option in a WordPress focused select HTML tag */
202
- margin: 0;
203
- }
204
-
205
- .ui-selectmenu-open .ui-widget-content .ui-state-hover, /* Override WC Bookings styles with WP < 5.6 */
206
- .ui-selectmenu-open .ui-widget-content .ui-state-focus, /* Override WC Bookings styles with WP < 5.6 */
207
- .ui-selectmenu-open .ui-widget-content .ui-state-active, /* Override WC Bookings styles with WP < 5.6 */
208
- .pll-selectmenu-menu .ui-widget-content .ui-state-hover,
209
- .pll-selectmenu-menu .ui-widget-content .ui-state-focus,
210
- .pll-selectmenu-menu .ui-widget-content .ui-state-active { /* To be compatible jQuery UI 1.12.1 since WordPress 5.6 */
211
- background: #d5d5d5;
212
- border: 0;
213
- }
214
-
215
- .ui-selectmenu-button.ui-state-focus {
216
- border: 1px solid #5b9dd9;
217
- box-shadow: 0 0 2px rgba(30, 140, 190, 0.8);
218
- }
219
-
220
- .ui-icon-triangle-1-s:before {
221
- content: "";
222
- background: #fff url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 0px top 55%;
223
- background-size: 16px 16px;
224
- box-sizing: border-box;
225
- position: absolute;
226
- width: 16px;
227
- height: 16px;
228
- }
229
-
230
- .pll-selectmenu-button.ui-button:hover,
231
- .pll-wizard .ui-button:hover,
232
- .pll-wizard .ui-button:focus {
233
- background: #fff; /* To override jQuery ui-dialog styles provided by WordPress */
234
- }
235
-
236
- .ui-widget-content {
237
- max-height: 231px;
238
- box-shadow: 0 2px 6px rgba(100, 100, 100, 0.3);
239
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
flags/ad.png CHANGED
Binary file
flags/ae.png CHANGED
Binary file
flags/af.png CHANGED
Binary file
flags/ag.png CHANGED
Binary file
flags/ai.png CHANGED
Binary file
flags/al.png CHANGED
Binary file
flags/am.png CHANGED
Binary file
flags/an.png CHANGED
Binary file
flags/ao.png CHANGED
Binary file
flags/ar.png CHANGED
Binary file
flags/arab.png CHANGED
Binary file
flags/as.png CHANGED
Binary file
flags/at.png CHANGED
Binary file
flags/au.png CHANGED
Binary file
flags/aw.png CHANGED
Binary file
flags/ax.png CHANGED
Binary file
flags/az.png CHANGED
Binary file
flags/ba.png CHANGED
Binary file
flags/basque.png CHANGED
Binary file
flags/bb.png CHANGED
Binary file
flags/bd.png CHANGED
Binary file
flags/be.png CHANGED
Binary file
flags/bf.png CHANGED
Binary file
flags/bg.png CHANGED
Binary file
flags/bh.png CHANGED
Binary file
flags/bi.png CHANGED
Binary file
flags/bj.png CHANGED
Binary file
flags/bm.png CHANGED
Binary file
flags/bn.png CHANGED
Binary file
flags/bo.png CHANGED
Binary file
flags/br.png CHANGED
Binary file
flags/bs.png CHANGED
Binary file
flags/bt.png CHANGED
Binary file
flags/bw.png CHANGED
Binary file
flags/by.png CHANGED
Binary file
flags/bz.png CHANGED
Binary file
flags/ca.png CHANGED
Binary file
flags/catalonia.png CHANGED
Binary file
flags/cc.png CHANGED
Binary file
flags/cd.png CHANGED
Binary file
flags/cf.png CHANGED
Binary file
flags/cg.png CHANGED
Binary file
flags/ch.png CHANGED
Binary file
flags/ci.png CHANGED
Binary file
flags/ck.png CHANGED
Binary file
flags/cl.png CHANGED
Binary file
flags/cm.png CHANGED
Binary file
flags/cn.png CHANGED
Binary file
flags/co.png CHANGED
Binary file
flags/cr.png CHANGED
Binary file
flags/cu.png CHANGED
Binary file
flags/cv.png CHANGED
Binary file
flags/cx.png CHANGED
Binary file
flags/cy.png CHANGED
Binary file
flags/cz.png CHANGED
Binary file
flags/de.png CHANGED
Binary file
flags/dj.png CHANGED
Binary file
flags/dk.png CHANGED
Binary file
flags/dm.png CHANGED
Binary file
flags/do.png CHANGED
Binary file
flags/dz.png CHANGED
Binary file
flags/ec.png CHANGED
Binary file
flags/ee.png CHANGED
Binary file
flags/eg.png CHANGED
Binary file
flags/eh.png CHANGED
Binary file
flags/england.png CHANGED
Binary file
flags/er.png CHANGED
Binary file
flags/es.png CHANGED
Binary file
flags/esperanto.png CHANGED
Binary file
flags/et.png CHANGED
Binary file
flags/fi.png CHANGED
Binary file
flags/fj.png CHANGED
Binary file
flags/fk.png CHANGED
Binary file
flags/fm.png CHANGED
Binary file
flags/fo.png CHANGED
Binary file
flags/fr.png CHANGED
Binary file
flags/ga.png CHANGED
Binary file
flags/galicia.png CHANGED
Binary file
flags/gb.png CHANGED
Binary file
flags/gd.png CHANGED
Binary file
flags/ge.png CHANGED
Binary file
flags/gh.png CHANGED
Binary file
flags/gi.png CHANGED
Binary file
flags/gl.png CHANGED
Binary file
flags/gm.png CHANGED
Binary file
flags/gn.png CHANGED
Binary file
flags/gp.png CHANGED
Binary file
flags/gq.png CHANGED
Binary file
flags/gr.png CHANGED
Binary file
flags/gs.png CHANGED
Binary file
flags/gt.png CHANGED
Binary file
flags/gu.png CHANGED
Binary file
flags/gw.png CHANGED
Binary file
flags/gy.png CHANGED
Binary file
flags/hk.png CHANGED
Binary file
flags/hm.png CHANGED
Binary file
flags/hn.png CHANGED
Binary file
flags/hr.png CHANGED
Binary file
flags/ht.png CHANGED
Binary file
flags/hu.png CHANGED
Binary file
flags/id.png CHANGED
Binary file
flags/ie.png CHANGED
Binary file
flags/il.png CHANGED
Binary file
flags/in.png CHANGED
Binary file
flags/io.png CHANGED
Binary file
flags/iq.png CHANGED
Binary file
flags/ir.png CHANGED
Binary file
flags/is.png CHANGED
Binary file
flags/it.png CHANGED
Binary file
flags/jm.png CHANGED
Binary file
flags/jo.png CHANGED
Binary file
flags/jp.png CHANGED
Binary file
flags/ke.png CHANGED
Binary file
flags/kg.png CHANGED
Binary file
flags/kh.png CHANGED
Binary file
flags/ki.png CHANGED
Binary file
flags/km.png CHANGED
Binary file
flags/kn.png CHANGED
Binary file
flags/kp.png CHANGED
Binary file
flags/kr.png CHANGED
Binary file
flags/kurdistan.png CHANGED
Binary file
flags/kw.png CHANGED
Binary file
flags/ky.png CHANGED
Binary file
flags/kz.png CHANGED
Binary file
flags/la.png CHANGED
Binary file
flags/lb.png CHANGED
Binary file
flags/lc.png CHANGED
Binary file
flags/li.png CHANGED
Binary file
flags/lk.png CHANGED
Binary file
flags/lr.png CHANGED
Binary file
flags/ls.png CHANGED
Binary file
flags/lt.png CHANGED
Binary file
flags/lu.png CHANGED
Binary file
flags/lv.png CHANGED
Binary file
flags/ly.png CHANGED
Binary file
flags/ma.png CHANGED
Binary file
flags/mc.png CHANGED
Binary file
flags/md.png CHANGED
Binary file
flags/me.png CHANGED
Binary file
flags/mg.png CHANGED
Binary file
flags/mh.png CHANGED
Binary file
flags/mk.png CHANGED
Binary file
flags/ml.png CHANGED
Binary file
flags/mm.png CHANGED
Binary file
flags/mn.png CHANGED
Binary file
flags/mo.png CHANGED
Binary file
flags/mp.png CHANGED
Binary file
flags/mq.png CHANGED
Binary file
flags/mr.png CHANGED
Binary file
flags/ms.png CHANGED
Binary file
flags/mt.png CHANGED
Binary file
flags/mu.png CHANGED
Binary file
flags/mv.png CHANGED
Binary file
flags/mw.png CHANGED
Binary file
flags/mx.png CHANGED
Binary file
flags/my.png CHANGED
Binary file
flags/mz.png CHANGED
Binary file
flags/na.png CHANGED
Binary file
flags/nc.png CHANGED
Binary file
flags/ne.png CHANGED
Binary file
flags/nf.png CHANGED
Binary file
flags/ng.png CHANGED
Binary file
flags/ni.png CHANGED
Binary file
flags/nl.png CHANGED
Binary file
flags/no.png CHANGED
Binary file
flags/np.png CHANGED
Binary file
flags/nr.png CHANGED
Binary file
flags/nu.png CHANGED
Binary file
flags/nz.png CHANGED
Binary file
flags/occitania.png CHANGED
Binary file
flags/om.png CHANGED
Binary file
flags/pa.png CHANGED
Binary file
flags/pe.png CHANGED
Binary file
flags/pf.png CHANGED
Binary file
flags/pg.png CHANGED
Binary file
flags/ph.png CHANGED
Binary file
flags/pk.png CHANGED
Binary file
flags/pl.png CHANGED
Binary file
flags/pm.png CHANGED
Binary file
flags/pn.png CHANGED
Binary file
flags/pr.png CHANGED
Binary file
flags/ps.png CHANGED
Binary file
flags/pt.png CHANGED
Binary file
flags/pw.png CHANGED
Binary file
flags/py.png CHANGED
Binary file
flags/qa.png CHANGED
Binary file
flags/quebec.png CHANGED
Binary file
flags/ro.png CHANGED
Binary file
flags/rs.png CHANGED
Binary file
flags/ru.png CHANGED
Binary file
flags/rw.png CHANGED
Binary file
flags/sa.png CHANGED
Binary file
flags/sb.png CHANGED
Binary file
flags/sc.png CHANGED
Binary file
flags/scotland.png CHANGED
Binary file
flags/sd.png CHANGED
Binary file
flags/se.png CHANGED
Binary file
flags/sg.png CHANGED
Binary file
flags/sh.png CHANGED
Binary file
flags/si.png CHANGED
Binary file
flags/sk.png CHANGED
Binary file
flags/sl.png CHANGED
Binary file
flags/sm.png CHANGED
Binary file
flags/sn.png CHANGED
Binary file
flags/so.png CHANGED
Binary file
flags/sr.png CHANGED
Binary file
flags/ss.png CHANGED
Binary file
flags/st.png CHANGED
Binary file
flags/sv.png CHANGED
Binary file
flags/sy.png CHANGED
Binary file
flags/sz.png CHANGED
Binary file
flags/tc.png CHANGED
Binary file
flags/td.png CHANGED
Binary file
flags/tf.png CHANGED
Binary file
flags/tg.png CHANGED
Binary file
flags/th.png CHANGED
Binary file
flags/tibet.png CHANGED
Binary file
flags/tj.png CHANGED
Binary file
flags/tk.png CHANGED
Binary file
flags/tl.png CHANGED
Binary file
flags/tm.png CHANGED
Binary file
flags/tn.png CHANGED
Binary file
flags/to.png CHANGED
Binary file
flags/tr.png CHANGED
Binary file
flags/tt.png CHANGED
Binary file
flags/tv.png CHANGED
Binary file
flags/tw.png CHANGED
Binary file
flags/tz.png CHANGED
Binary file
flags/ua.png CHANGED
Binary file
flags/ug.png CHANGED
Binary file
flags/us.png CHANGED
Binary file
flags/uy.png CHANGED
Binary file
flags/uz.png CHANGED
Binary file
flags/va.png CHANGED
Binary file
flags/vc.png CHANGED
Binary file
flags/ve.png CHANGED
Binary file
flags/veneto.png CHANGED
Binary file
flags/vg.png CHANGED
Binary file
flags/vi.png CHANGED
Binary file
flags/vn.png CHANGED
Binary file
flags/vu.png CHANGED
Binary file
flags/wales.png CHANGED
Binary file
flags/wf.png CHANGED
Binary file
flags/ws.png CHANGED
Binary file
flags/ye.png CHANGED
Binary file
flags/yt.png CHANGED
Binary file
flags/za.png CHANGED
Binary file
flags/zm.png CHANGED
Binary file
flags/zw.png CHANGED
Binary file
frontend/accept-language.php CHANGED
@@ -45,11 +45,11 @@ class PLL_Accept_Language {
45
  * @since 3.0
46
  *
47
  * @param string[] $subtags With subtag name as keys and subtag values as names.
48
- * @param float $quality
49
  */
50
  public function __construct( $subtags, $quality = 1.0 ) {
51
  $this->subtags = $subtags;
52
- $this->quality = $quality;
53
  }
54
 
55
  /**
@@ -65,7 +65,7 @@ class PLL_Accept_Language {
65
  array_keys( array_slice( self::SUBTAG_PATTERNS, 0, count( $matches ) - 1 ) ),
66
  array_slice( $matches, 1, count( self::SUBTAG_PATTERNS ) )
67
  );
68
- $quality = count( $matches ) === 9 ? floatval( $matches[8] ) : 1.0;
69
 
70
  return new PLL_Accept_Language( $subtags, $quality );
71
  }
45
  * @since 3.0
46
  *
47
  * @param string[] $subtags With subtag name as keys and subtag values as names.
48
+ * @param mixed $quality Floating point value from 0.0 to 1.0. Higher values indicates a user's preference.
49
  */
50
  public function __construct( $subtags, $quality = 1.0 ) {
51
  $this->subtags = $subtags;
52
+ $this->quality = is_numeric( $quality ) ? floatval( $quality ) : 1.0;
53
  }
54
 
55
  /**
65
  array_keys( array_slice( self::SUBTAG_PATTERNS, 0, count( $matches ) - 1 ) ),
66
  array_slice( $matches, 1, count( self::SUBTAG_PATTERNS ) )
67
  );
68
+ $quality = count( $matches ) === 9 ? $matches[8] : 1.0;
69
 
70
  return new PLL_Accept_Language( $subtags, $quality );
71
  }
frontend/accept-languages-collection.php CHANGED
@@ -74,12 +74,6 @@ class PLL_Accept_Languages_Collection {
74
  );
75
 
76
  if ( $n = count( $k ) ) {
77
- // Set default to 1 for any without q factor.
78
- foreach ( $v as $key => $val ) {
79
- if ( '' === $val || (float) $val > 1 ) {
80
- $v[ $key ] = 1;
81
- }
82
- }
83
 
84
  if ( $n > 1 ) {
85
  for ( $i = 2; $i <= $n; $i++ ) {
74
  );
75
 
76
  if ( $n = count( $k ) ) {
 
 
 
 
 
 
77
 
78
  if ( $n > 1 ) {
79
  for ( $i = 2; $i <= $n; $i++ ) {
frontend/choose-lang.php CHANGED
@@ -258,7 +258,8 @@ abstract class PLL_Choose_Lang {
258
  *
259
  * @param string $redirect the url the visitor will be redirected to
260
  */
261
- if ( $redirect = apply_filters( 'pll_redirect_home', $redirect ) ) {
 
262
  $this->maybe_setcookie();
263
  header( 'Vary: Accept-Language' );
264
  wp_safe_redirect( $redirect, 302, POLYLANG );
258
  *
259
  * @param string $redirect the url the visitor will be redirected to
260
  */
261
+ $redirect = apply_filters( 'pll_redirect_home', $redirect );
262
+ if ( $redirect && wp_validate_redirect( $redirect ) ) {
263
  $this->maybe_setcookie();
264
  header( 'Vary: Accept-Language' );
265
  wp_safe_redirect( $redirect, 302, POLYLANG );
frontend/frontend-filters-links.php CHANGED
@@ -468,7 +468,7 @@ class PLL_Frontend_Filters_Links extends PLL_Filters_Links {
468
  // The language is not correctly set so let's redirect to the correct url for this object
469
  if ( $do_redirect ) {
470
  // Protect against chained redirects.
471
- if ( $redirect_url && $requested_url != $redirect_url && $redirect_url === $this->check_canonical_url( $redirect_url, false ) ) {
472
  wp_safe_redirect( $redirect_url, 301, POLYLANG );
473
  exit;
474
  } else {
468
  // The language is not correctly set so let's redirect to the correct url for this object
469
  if ( $do_redirect ) {
470
  // Protect against chained redirects.
471
+ if ( $redirect_url && $requested_url != $redirect_url && $redirect_url === $this->check_canonical_url( $redirect_url, false ) && wp_validate_redirect( $redirect_url ) ) {
472
  wp_safe_redirect( $redirect_url, 301, POLYLANG );
473
  exit;
474
  } else {
frontend/frontend-filters-search.php CHANGED
@@ -100,7 +100,7 @@ class PLL_Frontend_Filters_Search {
100
  $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
101
  $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
102
  $form .= '<label for="adminbar-search" class="screen-reader-text">' . esc_html__( 'Search', 'polylang' ) . '</label>';
103
- $form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search', 'polylang' ) . '"/>';
104
  $form .= '</form>';
105
 
106
  $wp_admin_bar->add_node(
100
  $form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
101
  $form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
102
  $form .= '<label for="adminbar-search" class="screen-reader-text">' . esc_html__( 'Search', 'polylang' ) . '</label>';
103
+ $form .= '<input type="submit" class="adminbar-button" value="' . esc_attr__( 'Search', 'polylang' ) . '" />';
104
  $form .= '</form>';
105
 
106
  $wp_admin_bar->add_node(
frontend/frontend-filters-widgets.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Polylang
4
+ */
5
+
6
+ /**
7
+ * Filters widgets by language on frontend
8
+ *
9
+ * @since 3.1
10
+ */
11
+ class PLL_Frontend_Filters_Widgets {
12
+ /**
13
+ * Internal non persistent cache object.
14
+ *
15
+ * @var PLL_Cache
16
+ */
17
+ public $cache;
18
+
19
+ /**
20
+ * Current language.
21
+ *
22
+ * @var PLL_Language
23
+ */
24
+ public $curlang;
25
+
26
+ /**
27
+ * Constructor: setups filters and actions
28
+ *
29
+ * @since 1.2
30
+ *
31
+ * @param object $polylang
32
+ */
33
+ public function __construct( &$polylang ) {
34
+ $this->curlang = &$polylang->curlang;
35
+ $this->cache = new PLL_Cache();
36
+
37
+ add_filter( 'sidebars_widgets', array( $this, 'sidebars_widgets' ) );
38
+ }
39
+
40
+ /**
41
+ * Remove widgets from sidebars if they are not visible in the current language
42
+ * Needed to allow is_active_sidebar() to return false if all widgets are not for the current language. See #54
43
+ *
44
+ * @since 2.1
45
+ * @since 2.4 The result is cached as the function can be very expensive in case there are a lot of widgets
46
+ *
47
+ * @param array $sidebars_widgets An associative array of sidebars and their widgets
48
+ * @return array
49
+ */
50
+ public function sidebars_widgets( $sidebars_widgets ) {
51
+ global $wp_registered_widgets;
52
+
53
+ if ( empty( $wp_registered_widgets ) ) {
54
+ return $sidebars_widgets;
55
+ }
56
+
57
+ $cache_key = md5( maybe_serialize( $sidebars_widgets ) );
58
+ $_sidebars_widgets = $this->cache->get( "sidebars_widgets_{$cache_key}" );
59
+
60
+ if ( false !== $_sidebars_widgets ) {
61
+ return $_sidebars_widgets;
62
+ }
63
+
64
+ $sidebars_widgets = $this->filter_widgets_sidebars( $sidebars_widgets, $wp_registered_widgets );
65
+
66
+ $this->cache->set( "sidebars_widgets_{$cache_key}", $sidebars_widgets );
67
+
68
+ return $sidebars_widgets;
69
+ }
70
+
71
+ /**
72
+ * Method that handles the removal of widgets in the sidebars depending on their display language.
73
+ *
74
+ * @since 3.1
75
+ *
76
+ * @param array $widget_data An array containing the widget data
77
+ * @param array $sidebars_widgets An associative array of sidebars and their widgets
78
+ * @param string $sidebar Sidebar name
79
+ * @param int $key Widget number
80
+ * @return array An associative array of sidebars and their widgets
81
+ */
82
+ public function handle_widget_in_sidebar_callback( $widget_data, $sidebars_widgets, $sidebar, $key ) {
83
+ // Remove the widget if not visible in the current language
84
+ if ( ! empty( $widget_data['settings'][ $widget_data['number'] ]['pll_lang'] ) && $widget_data['settings'][ $widget_data['number'] ]['pll_lang'] !== $this->curlang->slug ) {
85
+ unset( $sidebars_widgets[ $sidebar ][ $key ] );
86
+ }
87
+ return $sidebars_widgets;
88
+ }
89
+
90
+ /**
91
+ * Browse the widgets sidebars and sort the ones that should be displayed or not.
92
+ *
93
+ * @since 3.1
94
+ *
95
+ * @param array $sidebars_widgets An associative array of sidebars and their widgets
96
+ * @param array $wp_registered_widgets Array of all registered widgets.
97
+ * @return array An associative array of sidebars and their widgets
98
+ */
99
+ public function filter_widgets_sidebars( $sidebars_widgets, $wp_registered_widgets ) {
100
+ foreach ( $sidebars_widgets as $sidebar => $widgets ) {
101
+ if ( 'wp_inactive_widgets' === $sidebar || empty( $widgets ) ) {
102
+ continue;
103
+ }
104
+
105
+ foreach ( $widgets as $key => $widget ) {
106
+ if ( ! $this->is_widget_object( $wp_registered_widgets, $widget ) ) {
107
+ continue;
108
+ }
109
+
110
+ $widget_data = $this->get_widget_data( $wp_registered_widgets, $widget );
111
+
112
+ $sidebars_widgets = $this->handle_widget_in_sidebar_callback( $widget_data, $sidebars_widgets, $sidebar, $key );
113
+ }
114
+ }
115
+ return $sidebars_widgets;
116
+ }
117
+
118
+ /**
119
+ * Test if the widget is an object.
120
+ *
121
+ * @since 3.1
122
+ *
123
+ * @param array $wp_registered_widgets Array of all registered widgets.
124
+ * @param string $widget String that identifies the widget.
125
+ * @return bool True if object, false otherwise.
126
+ */
127
+ protected function is_widget_object( $wp_registered_widgets, $widget ) {
128
+ // Nothing can be done if the widget is created using pre WP2.8 API :(
129
+ // There is no object, so we can't access it to get the widget options
130
+ return isset( $wp_registered_widgets[ $widget ]['callback'] ) &&
131
+ is_array( $wp_registered_widgets[ $widget ]['callback'] ) &&
132
+ isset( $wp_registered_widgets[ $widget ]['callback'][0] ) &&
133
+ is_object( $wp_registered_widgets[ $widget ]['callback'][0] ) &&
134
+ method_exists( $wp_registered_widgets[ $widget ]['callback'][0], 'get_settings' );
135
+ }
136
+
137
+ /**
138
+ * Get widgets settings and number.
139
+ *
140
+ * @since 3.1
141
+ *
142
+ * @param array $wp_registered_widgets Array of all registered widgets.
143
+ * @param string $widget String that identifies the widget.
144
+ * @return array An array containing the widget settings and number.
145
+ */
146
+ protected function get_widget_data( $wp_registered_widgets, $widget ) {
147
+ $widget_settings = $wp_registered_widgets[ $widget ]['callback'][0]->get_settings();
148
+ $number = $wp_registered_widgets[ $widget ]['params'][0]['number'];
149
+
150
+ return array(
151
+ 'settings' => $widget_settings,
152
+ 'number' => $number,
153
+ );
154
+ }
155
+ }
frontend/frontend-filters.php CHANGED
@@ -9,13 +9,6 @@
9
  * @since 1.2
10
  */
11
  class PLL_Frontend_Filters extends PLL_Filters {
12
- /**
13
- * Internal non persistent cache object.
14
- *
15
- * @var PLL_Cache
16
- */
17
- public $cache;
18
-
19
  /**
20
  * Constructor: setups filters and actions
21
  *
@@ -26,8 +19,6 @@ class PLL_Frontend_Filters extends PLL_Filters {
26
  public function __construct( &$polylang ) {
27
  parent::__construct( $polylang );
28
 
29
- $this->cache = new PLL_Cache();
30
-
31
  // Filters the WordPress locale
32
  add_filter( 'locale', array( $this, 'get_locale' ) );
33
 
@@ -40,7 +31,6 @@ class PLL_Frontend_Filters extends PLL_Filters {
40
 
41
  // Filters the widgets according to the current language
42
  add_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ) );
43
- add_filter( 'sidebars_widgets', array( $this, 'sidebars_widgets' ) );
44
 
45
  if ( $this->options['media_support'] ) {
46
  add_filter( 'widget_media_image_instance', array( $this, 'widget_media_instance' ), 1 ); // Since WP 4.8
@@ -137,6 +127,7 @@ class PLL_Frontend_Filters extends PLL_Filters {
137
  /**
138
  * Filters the widgets according to the current language
139
  * Don't display if a language filter is set and this is not the current one
 
140
  *
141
  * @since 0.3
142
  *
@@ -144,61 +135,9 @@ class PLL_Frontend_Filters extends PLL_Filters {
144
  * @return bool|array false if we hide the widget, unmodified $instance otherwise
145
  */
146
  public function widget_display_callback( $instance ) {
147
- // FIXME it looks like this filter is useless, now the we use the filter sidebars_widgets
148
  return ! empty( $instance['pll_lang'] ) && $instance['pll_lang'] != $this->curlang->slug ? false : $instance;
149
  }
150
 
151
- /**
152
- * Remove widgets from sidebars if they are not visible in the current language
153
- * Needed to allow is_active_sidebar() to return false if all widgets are not for the current language. See #54
154
- *
155
- * @since 2.1
156
- * @since 2.4 The result is cached as the function can be very expensive in case there are a lot of widgets
157
- *
158
- * @param array $sidebars_widgets An associative array of sidebars and their widgets
159
- * @return array
160
- */
161
- public function sidebars_widgets( $sidebars_widgets ) {
162
- global $wp_registered_widgets;
163
-
164
- if ( empty( $wp_registered_widgets ) ) {
165
- return $sidebars_widgets;
166
- }
167
-
168
- $cache_key = md5( maybe_serialize( $sidebars_widgets ) );
169
- $_sidebars_widgets = $this->cache->get( "sidebars_widgets_{$cache_key}" );
170
-
171
- if ( false !== $_sidebars_widgets ) {
172
- return $_sidebars_widgets;
173
- }
174
-
175
- foreach ( $sidebars_widgets as $sidebar => $widgets ) {
176
- if ( 'wp_inactive_widgets' === $sidebar || empty( $widgets ) ) {
177
- continue;
178
- }
179
-
180
- foreach ( $widgets as $key => $widget ) {
181
- // Nothing can be done if the widget is created using pre WP2.8 API :(
182
- // There is no object, so we can't access it to get the widget options
183
- if ( ! isset( $wp_registered_widgets[ $widget ]['callback'] ) || ! is_array( $wp_registered_widgets[ $widget ]['callback'] ) || ! isset( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! is_object( $wp_registered_widgets[ $widget ]['callback'][0] ) || ! method_exists( $wp_registered_widgets[ $widget ]['callback'][0], 'get_settings' ) ) {
184
- continue;
185
- }
186
-
187
- $widget_settings = $wp_registered_widgets[ $widget ]['callback'][0]->get_settings();
188
- $number = $wp_registered_widgets[ $widget ]['params'][0]['number'];
189
-
190
- // Remove the widget if not visible in the current language
191
- if ( ! empty( $widget_settings[ $number ]['pll_lang'] ) && $widget_settings[ $number ]['pll_lang'] !== $this->curlang->slug ) {
192
- unset( $sidebars_widgets[ $sidebar ][ $key ] );
193
- }
194
- }
195
- }
196
-
197
- $this->cache->set( "sidebars_widgets_{$cache_key}", $sidebars_widgets );
198
-
199
- return $sidebars_widgets;
200
- }
201
-
202
  /**
203
  * Translates media in media widgets
204
  *
9
  * @since 1.2
10
  */
11
  class PLL_Frontend_Filters extends PLL_Filters {
 
 
 
 
 
 
 
12
  /**
13
  * Constructor: setups filters and actions
14
  *
19
  public function __construct( &$polylang ) {
20
  parent::__construct( $polylang );
21
 
 
 
22
  // Filters the WordPress locale
23
  add_filter( 'locale', array( $this, 'get_locale' ) );
24
 
31
 
32
  // Filters the widgets according to the current language
33
  add_filter( 'widget_display_callback', array( $this, 'widget_display_callback' ) );
 
34
 
35
  if ( $this->options['media_support'] ) {
36
  add_filter( 'widget_media_image_instance', array( $this, 'widget_media_instance' ), 1 ); // Since WP 4.8
127
  /**
128
  * Filters the widgets according to the current language
129
  * Don't display if a language filter is set and this is not the current one
130
+ * Needed for {@see https://developer.wordpress.org/reference/functions/the_widget/ the_widget()}.
131
  *
132
  * @since 0.3
133
  *
135
  * @return bool|array false if we hide the widget, unmodified $instance otherwise
136
  */
137
  public function widget_display_callback( $instance ) {
 
138
  return ! empty( $instance['pll_lang'] ) && $instance['pll_lang'] != $this->curlang->slug ? false : $instance;
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  /**
142
  * Translates media in media widgets
143
  *
frontend/frontend-nav-menu.php CHANGED
@@ -98,12 +98,11 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
98
  usort( $items, array( $this, 'usort_menu_items' ) );
99
 
100
  $new_items = array();
 
101
  $offset = 0;
102
 
103
  foreach ( $items as $item ) {
104
  if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) {
105
- $i = 0;
106
-
107
  /** This filter is documented in include/switcher.php */
108
  $options = apply_filters( 'pll_the_languages_args', $options ); // Honor the filter here for 'show_flags', 'show_names' and 'dropdown'.
109
 
@@ -119,11 +118,14 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
119
  $item->title = $this->get_item_title( $this->curlang->get_display_flag(), $name, $options );
120
  $item->attr_title = '';
121
  $item->classes = array( 'pll-parent-menu-item' );
 
122
  $new_items[] = $item;
123
  $offset++;
124
  }
125
 
 
126
  foreach ( $the_languages as $lang ) {
 
127
  $lang_item = clone $item;
128
  $lang_item->ID = $lang_item->ID . '-' . $lang['slug']; // A unique ID
129
  $lang_item->title = $this->get_item_title( $lang['flag'], $lang['name'], $options );
@@ -131,14 +133,17 @@ class PLL_Frontend_Nav_Menu extends PLL_Nav_Menu {
131
  $lang_item->url = $lang['url'];
132
  $lang_item->lang = $lang['locale']; // Save this for use in nav_menu_link_attributes
133
  $lang_item->classes = $lang['classes'];
134
- $lang_item->menu_order += $offset + $i++;
135
  if ( ! empty( $options['dropdown'] ) ) {
 
136
  $lang_item->menu_item_parent = $item->db_id;
137
  $lang_item->db_id = 0; // to avoid recursion
 
 
138
  }
139
  $new_items[] = $lang_item;
 
140
  }
141
- $offset += $i - 1;
142
  } else {
143
  $item->menu_order += $offset;
144
  $new_items[] = $item;
98
  usort( $items, array( $this, 'usort_menu_items' ) );
99
 
100
  $new_items = array();
101
+
102
  $offset = 0;
103
 
104
  foreach ( $items as $item ) {
105
  if ( $options = get_post_meta( $item->ID, '_pll_menu_item', true ) ) {
 
 
106
  /** This filter is documented in include/switcher.php */
107
  $options = apply_filters( 'pll_the_languages_args', $options ); // Honor the filter here for 'show_flags', 'show_names' and 'dropdown'.
108
 
118
  $item->title = $this->get_item_title( $this->curlang->get_display_flag(), $name, $options );
119
  $item->attr_title = '';
120
  $item->classes = array( 'pll-parent-menu-item' );
121
+ $item->menu_order += $offset;
122
  $new_items[] = $item;
123
  $offset++;
124
  }
125
 
126
+ $i = 0; // for incrementation of menu order only in case of dropdown
127
  foreach ( $the_languages as $lang ) {
128
+ $i++;
129
  $lang_item = clone $item;
130
  $lang_item->ID = $lang_item->ID . '-' . $lang['slug']; // A unique ID
131
  $lang_item->title = $this->get_item_title( $lang['flag'], $lang['name'], $options );
133
  $lang_item->url = $lang['url'];
134
  $lang_item->lang = $lang['locale']; // Save this for use in nav_menu_link_attributes
135
  $lang_item->classes = $lang['classes'];
 
136
  if ( ! empty( $options['dropdown'] ) ) {
137
+ $lang_item->menu_order = $item->menu_order + $i;
138
  $lang_item->menu_item_parent = $item->db_id;
139
  $lang_item->db_id = 0; // to avoid recursion
140
+ } else {
141
+ $lang_item->menu_order += $offset;
142
  }
143
  $new_items[] = $lang_item;
144
+ $offset++;
145
  }
146
+ $offset--;
147
  } else {
148
  $item->menu_order += $offset;
149
  $new_items[] = $item;
frontend/frontend.php CHANGED
@@ -58,6 +58,11 @@ class PLL_Frontend extends PLL_Base {
58
  */
59
  public $static_pages;
60
 
 
 
 
 
 
61
  /**
62
  * Constructor.
63
  *
@@ -119,6 +124,7 @@ class PLL_Frontend extends PLL_Base {
119
  $this->filters_links = new PLL_Frontend_Filters_Links( $this );
120
  $this->filters = new PLL_Frontend_Filters( $this );
121
  $this->filters_search = new PLL_Frontend_Filters_Search( $this );
 
122
 
123
  // Auto translate for Ajax
124
  if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
58
  */
59
  public $static_pages;
60
 
61
+ /**
62
+ * @var PLL_Frontend_Filters_Widgets
63
+ */
64
+ public $filters_widgets;
65
+
66
  /**
67
  * Constructor.
68
  *
124
  $this->filters_links = new PLL_Frontend_Filters_Links( $this );
125
  $this->filters = new PLL_Frontend_Filters( $this );
126
  $this->filters_search = new PLL_Frontend_Filters_Search( $this );
127
+ $this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
128
 
129
  // Auto translate for Ajax
130
  if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
include/crud-posts.php CHANGED
@@ -228,8 +228,7 @@ class PLL_CRUD_Posts {
228
  }
229
 
230
  /**
231
- * Prevents WP deleting files when there are still media using them
232
- * Thanks to Bruno "Aesqe" Babic and its plugin file gallery in which I took all the ideas for this function
233
  *
234
  * @since 0.9
235
  *
@@ -241,19 +240,20 @@ class PLL_CRUD_Posts {
241
 
242
  $uploadpath = wp_upload_dir();
243
 
 
 
 
 
244
  $ids = $wpdb->get_col(
245
  $wpdb->prepare(
246
  "SELECT post_id FROM $wpdb->postmeta
247
  WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
248
- substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) )
249
  )
250
  );
251
 
252
  if ( ! empty( $ids ) ) {
253
- // Regenerate intermediate sizes if it's an image ( since we could not prevent WP deleting them before ).
254
- require_once ABSPATH . 'wp-admin/includes/image.php'; // In case the file is deleted outside admin.
255
- wp_update_attachment_metadata( $ids[0], wp_slash( wp_generate_attachment_metadata( $ids[0], $file ) ) ); // Directly uses update_post_meta, so expects slashed.
256
- return ''; // Prevent deleting the main file.
257
  }
258
 
259
  return $file;
228
  }
229
 
230
  /**
231
+ * Prevents WP deleting files when there are still media using them.
 
232
  *
233
  * @since 0.9
234
  *
240
 
241
  $uploadpath = wp_upload_dir();
242
 
243
+ // Get the main attached file.
244
+ $attached_file = substr_replace( $file, '', 0, strlen( trailingslashit( $uploadpath['basedir'] ) ) );
245
+ $attached_file = preg_replace( '#-\d+x\d+\.([a-z]+)$#', '.$1', $attached_file );
246
+
247
  $ids = $wpdb->get_col(
248
  $wpdb->prepare(
249
  "SELECT post_id FROM $wpdb->postmeta
250
  WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
251
+ $attached_file
252
  )
253
  );
254
 
255
  if ( ! empty( $ids ) ) {
256
+ return ''; // Prevent deleting the file.
 
 
 
257
  }
258
 
259
  return $file;
include/filters-widgets-options.php CHANGED
@@ -29,13 +29,14 @@ class PLL_Filters_Widgets_Options {
29
  $this->model = $polylang->model;
30
 
31
  add_action( 'in_widget_form', array( $this, 'in_widget_form' ), 10, 3 );
32
- add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ), 10, 4 );
33
  }
34
 
35
  /**
36
  * Add the language filter field to the widgets options form.
37
  *
38
- * @since 3.0 Moved PLL_Admin_Filters
 
39
  *
40
  * @param WP_Widget $widget
41
  * @param null $return
@@ -52,7 +53,8 @@ class PLL_Filters_Widgets_Options {
52
  ),
53
  -1,
54
  array(
55
- 'name' => $this->get_language_key( $widget ),
 
56
  'class' => 'tags-input pll-lang-choice',
57
  'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'],
58
  )
@@ -60,7 +62,7 @@ class PLL_Filters_Widgets_Options {
60
 
61
  printf(
62
  '<p><label for="%1$s">%2$s %3$s</label></p>',
63
- esc_attr( $this->get_language_key( $widget ) ),
64
  esc_html__( 'The widget is displayed for:', 'polylang' ),
65
  $dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
66
  );
@@ -71,18 +73,15 @@ class PLL_Filters_Widgets_Options {
71
  * Saves the language associated to the widget.
72
  *
73
  * @since 0.3
74
- * @since 3.0 Moved from PLL_Admin_Filters
 
75
  *
76
- * @param array $instance The current Widget's options.
77
- * @param array $new_instance The new Widget's options.
78
- * @param array $old_instance Not used.
79
- * @param WP_Widget $widget WP_Widget object.
80
  * @return array Widget options.
81
  */
82
- public function widget_update_callback( $instance, $new_instance, $old_instance, $widget ) {
83
- $key = $this->get_language_key( $widget );
84
-
85
- if ( ! empty( $new_instance[ $key ] ) && $lang = $this->model->get_language( $new_instance[ $key ] ) ) {
86
  $instance['pll_lang'] = $lang->slug;
87
  } else {
88
  unset( $instance['pll_lang'] );
@@ -91,15 +90,4 @@ class PLL_Filters_Widgets_Options {
91
  return $instance;
92
  }
93
 
94
- /**
95
- * Returns the key used by Polylang to pass language data.
96
- *
97
- * @since 3.0
98
- *
99
- * @param WP_Widget $widget
100
- * @return string
101
- */
102
- protected function get_language_key( $widget ) {
103
- return $widget->id . '_lang_choice';
104
- }
105
  }
29
  $this->model = $polylang->model;
30
 
31
  add_action( 'in_widget_form', array( $this, 'in_widget_form' ), 10, 3 );
32
+ add_filter( 'widget_update_callback', array( $this, 'widget_update_callback' ), 10, 2 );
33
  }
34
 
35
  /**
36
  * Add the language filter field to the widgets options form.
37
  *
38
+ * @since 3.0 Moved PLL_Admin_Filters.
39
+ * @since 3.1 Rename lang_choice field name and id to pll_lang as the widget setting.
40
  *
41
  * @param WP_Widget $widget
42
  * @param null $return
53
  ),
54
  -1,
55
  array(
56
+ 'id' => $widget->get_field_id( 'pll_lang' ),
57
+ 'name' => $widget->get_field_name( 'pll_lang' ),
58
  'class' => 'tags-input pll-lang-choice',
59
  'selected' => empty( $instance['pll_lang'] ) ? '' : $instance['pll_lang'],
60
  )
62
 
63
  printf(
64
  '<p><label for="%1$s">%2$s %3$s</label></p>',
65
+ esc_attr( $widget->get_field_id( 'pll_lang' ) ),
66
  esc_html__( 'The widget is displayed for:', 'polylang' ),
67
  $dropdown_html // phpcs:ignore WordPress.Security.EscapeOutput
68
  );
73
  * Saves the language associated to the widget.
74
  *
75
  * @since 0.3
76
+ * @since 3.0 Moved from PLL_Admin_Filters.
77
+ * @since 3.1 Remove unused $old_instance and $widget parameters.
78
  *
79
+ * @param array $instance The current Widget's options.
80
+ * @param array $new_instance The new Widget's options.
 
 
81
  * @return array Widget options.
82
  */
83
+ public function widget_update_callback( $instance, $new_instance ) {
84
+ if ( ! empty( $new_instance['pll_lang'] ) && $lang = $this->model->get_language( $new_instance['pll_lang'] ) ) {
 
 
85
  $instance['pll_lang'] = $lang->slug;
86
  } else {
87
  unset( $instance['pll_lang'] );
90
  return $instance;
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
include/filters.php CHANGED
@@ -69,9 +69,6 @@ class PLL_Filters {
69
  // Converts the locale to a valid W3C locale
70
  add_filter( 'language_attributes', array( $this, 'language_attributes' ) );
71
 
72
- // Prevents deleting all the translations of the default category
73
- add_filter( 'map_meta_cap', array( $this, 'fix_delete_default_category' ), 10, 4 );
74
-
75
  // Translate the site title in emails sent to users
76
  add_filter( 'password_change_email', array( $this, 'translate_user_email' ) );
77
  add_filter( 'email_change_email', array( $this, 'translate_user_email' ) );
@@ -99,24 +96,38 @@ class PLL_Filters {
99
  * Get the language to filter a comments query.
100
  *
101
  * @since 2.0
 
102
  *
103
- * @param WP_Comment_Query $query WP_Comment_Query object.
104
- * @return PLL_Language|false The language to use in the filter, false otherwise.
105
  */
106
- protected function get_comments_queried_language( $query ) {
107
  // Don't filter comments if comment ids or post ids are specified.
108
  $plucked = wp_array_slice_assoc( $query->query_vars, array( 'comment__in', 'parent', 'post_id', 'post__in', 'post_parent' ) );
109
  $fields = array_filter( $plucked );
110
  if ( ! empty( $fields ) ) {
111
- return false;
112
  }
113
 
114
  // Don't filter comments if a non translated post type is specified.
115
  if ( ! empty( $query->query_vars['post_type'] ) && ! $this->model->is_translated_post_type( $query->query_vars['post_type'] ) ) {
116
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
118
 
119
- return empty( $query->query_vars['lang'] ) ? $this->curlang : $this->model->get_language( $query->query_vars['lang'] );
120
  }
121
 
122
  /**
@@ -130,9 +141,10 @@ class PLL_Filters {
130
  * @return void
131
  */
132
  public function parse_comment_query( $query ) {
133
- $lang = $this->get_comments_queried_language( $query );
134
- if ( $lang ) {
135
- $key = '_' . $lang->slug;
 
136
  $query->query_vars['cache_domain'] = empty( $query->query_vars['cache_domain'] ) ? 'pll' . $key : $query->query_vars['cache_domain'] . $key;
137
  }
138
  }
@@ -150,9 +162,11 @@ class PLL_Filters {
150
  public function comments_clauses( $clauses, $query ) {
151
  global $wpdb;
152
 
153
- $lang = $this->get_comments_queried_language( $query );
154
 
155
  if ( ! empty( $lang ) ) {
 
 
156
  // If this clause is not already added by WP.
157
  if ( ! strpos( $clauses['join'], '.ID' ) ) {
158
  $clauses['join'] .= " JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
@@ -206,8 +220,8 @@ class PLL_Filters {
206
  ),
207
  );
208
 
209
- // Take care that 'exclude' argument accepts integer or strings too
210
- $args['exclude'] = array_merge( wp_parse_id_list( $args['exclude'] ), get_posts( $r ) );
211
  $pages = get_pages( $args );
212
  }
213
 
@@ -281,33 +295,8 @@ class PLL_Filters {
281
  }
282
 
283
  /**
284
- * Prevents deleting all the translations of the default category
285
- *
286
- * @since 2.1
287
- *
288
- * @param array $caps The user's actual capabilities.
289
- * @param string $cap Capability name.
290
- * @param int $user_id The user ID.
291
- * @param array $args Adds the context to the cap. The category id.
292
- * @return array
293
- */
294
- public function fix_delete_default_category( $caps, $cap, $user_id, $args ) {
295
- if ( 'delete_term' === $cap ) {
296
- $term = get_term( reset( $args ) ); // Since WP 4.4, we can get the term to get the taxonomy
297
- if ( $term instanceof WP_Term ) {
298
- $default_cat = get_option( 'default_' . $term->taxonomy );
299
- if ( $default_cat && array_intersect( $args, $this->model->term->get_translations( $default_cat ) ) ) {
300
- $caps[] = 'do_not_allow';
301
- }
302
- }
303
- }
304
-
305
- return $caps;
306
- }
307
-
308
- /**
309
- * Translates the site title in emails sent to the user (change email, reset password).
310
- * It is necessary to filter the email because WP evaluates the site title before calling switch_to_locale().
311
  *
312
  * @since 2.1.3
313
  *
69
  // Converts the locale to a valid W3C locale
70
  add_filter( 'language_attributes', array( $this, 'language_attributes' ) );
71
 
 
 
 
72
  // Translate the site title in emails sent to users
73
  add_filter( 'password_change_email', array( $this, 'translate_user_email' ) );
74
  add_filter( 'email_change_email', array( $this, 'translate_user_email' ) );
96
  * Get the language to filter a comments query.
97
  *
98
  * @since 2.0
99
+ * @since 3.1 Always returns an array. Renamed from get_comments_queried_language().
100
  *
101
+ * @param WP_Comment_Query $query WP_Comment_Query object.
102
+ * @return PLL_Language[] The languages to use in the filter.
103
  */
104
+ protected function get_comments_queried_languages( $query ) {
105
  // Don't filter comments if comment ids or post ids are specified.
106
  $plucked = wp_array_slice_assoc( $query->query_vars, array( 'comment__in', 'parent', 'post_id', 'post__in', 'post_parent' ) );
107
  $fields = array_filter( $plucked );
108
  if ( ! empty( $fields ) ) {
109
+ return array();
110
  }
111
 
112
  // Don't filter comments if a non translated post type is specified.
113
  if ( ! empty( $query->query_vars['post_type'] ) && ! $this->model->is_translated_post_type( $query->query_vars['post_type'] ) ) {
114
+ return array();
115
+ }
116
+
117
+ // If comments are queried with a 'lang' parameter, keeps only language codes.
118
+ if ( isset( $query->query_vars['lang'] ) ) {
119
+ $languages = is_string( $query->query_vars['lang'] ) ? explode( ',', $query->query_vars['lang'] ) : $query->query_vars['lang'];
120
+ if ( is_array( $languages ) ) {
121
+ $languages = array_map( array( $this->model, 'get_language' ), $languages );
122
+ return array_filter( $languages );
123
+ }
124
+ }
125
+
126
+ if ( ! empty( $this->curlang ) ) {
127
+ return array( $this->curlang );
128
  }
129
 
130
+ return array();
131
  }
132
 
133
  /**
141
  * @return void
142
  */
143
  public function parse_comment_query( $query ) {
144
+ $lang = $this->get_comments_queried_languages( $query );
145
+ if ( ! empty( $lang ) ) {
146
+ $lang = wp_list_pluck( $lang, 'slug' );
147
+ $key = '_' . implode( ',', $lang );
148
  $query->query_vars['cache_domain'] = empty( $query->query_vars['cache_domain'] ) ? 'pll' . $key : $query->query_vars['cache_domain'] . $key;
149
  }
150
  }
162
  public function comments_clauses( $clauses, $query ) {
163
  global $wpdb;
164
 
165
+ $lang = $this->get_comments_queried_languages( $query );
166
 
167
  if ( ! empty( $lang ) ) {
168
+ $lang = wp_list_pluck( $lang, 'slug' );
169
+
170
  // If this clause is not already added by WP.
171
  if ( ! strpos( $clauses['join'], '.ID' ) ) {
172
  $clauses['join'] .= " JOIN $wpdb->posts ON $wpdb->posts.ID = $wpdb->comments.comment_post_ID";
220
  ),
221
  );
222
 
223
+ // Take care that 'exclude' argument accepts integer or strings too.
224
+ $args['exclude'] = array_merge( wp_parse_id_list( $args['exclude'] ), get_posts( $r ) ); // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude
225
  $pages = get_pages( $args );
226
  }
227
 
295
  }
296
 
297
  /**
298
+ * Translates the site title in emails sent to the user (change email, reset password)
299
+ * It is necessary to filter the email because WP evaluates the site title before calling switch_to_locale()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  *
301
  * @since 2.1.3
302
  *
include/model.php CHANGED
@@ -398,44 +398,6 @@ class PLL_Model {
398
  return $query_vars;
399
  }
400
 
401
- /**
402
- * Create a default category for a language
403
- *
404
- * @since 1.2
405
- *
406
- * @param object|string|int $lang language
407
- * @return void
408
- */
409
- public function create_default_category( $lang ) {
410
- $lang = $this->get_language( $lang );
411
-
412
- // create a new category
413
- // FIXME this is translated in admin language when we would like it in $lang
414
- $cat_name = __( 'Uncategorized', 'polylang' );
415
- $cat_slug = sanitize_title( $cat_name . '-' . $lang->slug );
416
- $cat = wp_insert_term( $cat_name, 'category', array( 'slug' => $cat_slug ) );
417
-
418
- // check that the category was not previously created ( in case the language was deleted and recreated )
419
- $cat = isset( $cat->error_data['term_exists'] ) ? $cat->error_data['term_exists'] : $cat['term_id'];
420
-
421
- // set language
422
- $this->term->set_language( (int) $cat, $lang );
423
-
424
- // this is a translation of the default category
425
- $default = (int) get_option( 'default_category' );
426
- $translations = $this->term->get_translations( $default );
427
- if ( empty( $translations ) ) {
428
- if ( $lg = $this->term->get_language( $default ) ) {
429
- $translations[ $lg->slug ] = $default;
430
- }
431
- else {
432
- $translations = array();
433
- }
434
- }
435
-
436
- $this->term->save_translations( (int) $cat, $translations );
437
- }
438
-
439
  /**
440
  * It is possible to have several terms with the same name in the same taxonomy ( one per language )
441
  * but the native term_exists() will return true even if only one exists.
@@ -634,4 +596,111 @@ class PLL_Model {
634
 
635
  return new $class( $this );
636
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
  }
398
  return $query_vars;
399
  }
400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  /**
402
  * It is possible to have several terms with the same name in the same taxonomy ( one per language )
403
  * but the native term_exists() will return true even if only one exists.
596
 
597
  return new $class( $this );
598
  }
599
+
600
+ /**
601
+ * Returns posts and terms ids without language ( used in settings ).
602
+ *
603
+ * @since 0.9
604
+ * @since 2.2.6 Add the $limit argument.
605
+ *
606
+ * @param int $limit Max number of posts or terms to return. Defaults to -1 (no limit).
607
+ * @return array {
608
+ * Objects without language.
609
+ *
610
+ * @type int[] $posts Array of post ids.
611
+ * @type int[] $terms Array of term ids.
612
+ * }
613
+ */
614
+ public function get_objects_with_no_lang( $limit = -1 ) {
615
+ /**
616
+ * Filters the max number of posts or terms to return when searching objects with no language.
617
+ * This filter can be used to decrease the memory usage in case the number of objects
618
+ * without language is too big. Using a negative value is equivalent to have no limit.
619
+ *
620
+ * @since 2.2.6
621
+ *
622
+ * @param int $limit Max number of posts or terms to retrieve from the database.
623
+ */
624
+ $limit = (int) apply_filters( 'get_objects_with_no_lang_limit', $limit );
625
+
626
+ $posts = $this->get_posts_with_no_lang( $this->get_translated_post_types(), $limit );
627
+ $terms = $this->get_terms_with_no_lang( $this->get_translated_taxonomies(), $limit );
628
+
629
+ /**
630
+ * Filters the list of untranslated posts ids and terms ids
631
+ *
632
+ * @since 0.9
633
+ *
634
+ * @param array|false $objects false if no ids found, list of post and/or term ids otherwise.
635
+ */
636
+ return apply_filters( 'pll_get_objects_with_no_lang', empty( $posts ) && empty( $terms ) ? false : array( 'posts' => $posts, 'terms' => $terms ) );
637
+ }
638
+
639
+ /**
640
+ * Returns ids of post without language.
641
+ *
642
+ * @since 3.1
643
+ *
644
+ * @param string|string[] $post_types A translated post type or an array of translated post types.
645
+ * @param int $limit Max number of posts to return.
646
+ * @return int[]
647
+ */
648
+ public function get_posts_with_no_lang( $post_types, $limit ) {
649
+ return get_posts(
650
+ array(
651
+ 'numberposts' => $limit,
652
+ 'nopaging' => $limit <= 0,
653
+ 'post_type' => $post_types,
654
+ 'post_status' => 'any',
655
+ 'fields' => 'ids',
656
+ 'tax_query' => array(
657
+ array(
658
+ 'taxonomy' => 'language',
659
+ 'terms' => $this->get_languages_list( array( 'fields' => 'term_id' ) ),
660
+ 'operator' => 'NOT IN',
661
+ ),
662
+ ),
663
+ )
664
+ );
665
+ }
666
+
667
+ /**
668
+ * Returns ids of terms without language.
669
+ *
670
+ * @since 3.1
671
+ *
672
+ * @param string|string[] $taxonomies A translated taxonomy or an array of taxonomies post types.
673
+ * @param int $limit Max number of terms to return.
674
+ * @return int[]
675
+ */
676
+ public function get_terms_with_no_lang( $taxonomies, $limit ) {
677
+ global $wpdb;
678
+
679
+ $taxonomies = (array) $taxonomies;
680
+
681
+ $sql = sprintf(
682
+ "SELECT {$wpdb->term_taxonomy}.term_id FROM {$wpdb->term_taxonomy}
683
+ WHERE taxonomy IN ('%s')
684
+ AND {$wpdb->term_taxonomy}.term_id NOT IN (
685
+ SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (%s)
686
+ )
687
+ %s",
688
+ implode( "','", array_map( 'esc_sql', $taxonomies ) ),
689
+ implode( ',', array_map( 'intval', $this->get_languages_list( array( 'fields' => 'tl_term_taxonomy_id' ) ) ) ),
690
+ $limit > 0 ? sprintf( 'LIMIT %d', intval( $limit ) ) : ''
691
+ );
692
+
693
+ $key = md5( $sql );
694
+ $last_changed = wp_cache_get_last_changed( 'terms' );
695
+ $cache_key = "terms_no_lang:{$key}:{$last_changed}";
696
+
697
+ $term_ids = wp_cache_get( $cache_key, 'terms' );
698
+
699
+ if ( false === $term_ids ) {
700
+ $term_ids = $wpdb->get_col( $sql ); // PHPCS:ignore WordPress.DB.PreparedSQL.NotPrepared
701
+ wp_cache_set( $cache_key, $term_ids, 'terms' );
702
+ }
703
+
704
+ return $term_ids;
705
+ }
706
  }
include/nav-menu.php CHANGED
@@ -67,7 +67,7 @@ class PLL_Nav_Menu {
67
  * @return stdClass
68
  */
69
  public function wp_setup_nav_menu_item( $item ) {
70
- if ( '#pll_switcher' === $item->url ) {
71
  $item->post_title = __( 'Languages', 'polylang' );
72
  $item->type_label = __( 'Language switcher', 'polylang' );
73
  }
67
  * @return stdClass
68
  */
69
  public function wp_setup_nav_menu_item( $item ) {
70
+ if ( isset( $item->url ) && '#pll_switcher' === $item->url ) {
71
  $item->post_title = __( 'Languages', 'polylang' );
72
  $item->type_label = __( 'Language switcher', 'polylang' );
73
  }
include/olt-manager.php CHANGED
@@ -227,7 +227,7 @@ class PLL_OLT_Manager {
227
  // Use static array to avoid translating several times the same ( default ) labels
228
  static $translated = array();
229
 
230
- foreach ( $type->labels as $key => $label ) {
231
  if ( is_string( $label ) && isset( $this->labels[ $label ] ) ) {
232
  if ( empty( $translated[ $label ] ) ) {
233
  // PHPCS:disable WordPress.WP.I18n
227
  // Use static array to avoid translating several times the same ( default ) labels
228
  static $translated = array();
229
 
230
+ foreach ( (array) $type->labels as $key => $label ) {
231
  if ( is_string( $label ) && isset( $this->labels[ $label ] ) ) {
232
  if ( empty( $translated[ $label ] ) ) {
233
  // PHPCS:disable WordPress.WP.I18n
include/rest-request.php CHANGED
@@ -38,7 +38,7 @@ class PLL_REST_Request extends PLL_Base {
38
  /**
39
  * @var PLL_Filters_Widgets_Options
40
  */
41
- public $filters_widgets;
42
 
43
  /**
44
  * Setup filters.
@@ -57,7 +57,7 @@ class PLL_REST_Request extends PLL_Base {
57
 
58
  $this->filters_links = new PLL_Filters_Links( $this );
59
  $this->filters = new PLL_Filters( $this );
60
- $this->filters_widgets = new PLL_Filters_Widgets_Options( $this );
61
 
62
  // Static front page and page for posts.
63
  if ( 'page' === get_option( 'show_on_front' ) ) {
38
  /**
39
  * @var PLL_Filters_Widgets_Options
40
  */
41
+ public $filters_widgets_options;
42
 
43
  /**
44
  * Setup filters.
57
 
58
  $this->filters_links = new PLL_Filters_Links( $this );
59
  $this->filters = new PLL_Filters( $this );
60
+ $this->filters_widgets_options = new PLL_Filters_Widgets_Options( $this );
61
 
62
  // Static front page and page for posts.
63
  if ( 'page' === get_option( 'show_on_front' ) ) {
include/switcher.php CHANGED
@@ -126,7 +126,14 @@ class PLL_Switcher {
126
  $order = (int) $language->term_group;
127
  $slug = $language->slug;
128
  $locale = $language->get_locale( 'display' );
129
- $classes = array( 'lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr( $slug ) );
 
 
 
 
 
 
 
130
  $current_lang = $this->get_current_language( $args ) === $slug;
131
 
132
  if ( $current_lang ) {
@@ -169,7 +176,7 @@ class PLL_Switcher {
169
  $first = false;
170
  }
171
 
172
- $out[ $slug ] = compact( 'id', 'order', 'slug', 'locale', 'name', 'url', 'flag', 'current_lang', 'no_translation', 'classes' );
173
  }
174
 
175
  return $out;
@@ -185,20 +192,22 @@ class PLL_Switcher {
185
  * @param array $args {
186
  * Optional array of arguments.
187
  *
188
- * @type int $dropdown The list is displayed as dropdown if set, defaults to 0.
189
- * @type int $echo Echoes the list if set to 1, defaults to 1.
190
- * @type int $hide_if_empty Hides languages with no posts ( or pages ) if set to 1, defaults to 1.
191
- * @type int $show_flags Displays flags if set to 1, defaults to 0.
192
- * @type int $show_names Shows language names if set to 1, defaults to 1.
193
- * @type string $display_names_as Whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name.
194
- * @type int $force_home Will always link to home in translated language if set to 1, defaults to 0.
195
- * @type int $hide_if_no_translation Hides the link if there is no translation if set to 1, defaults to 0.
196
- * @type int $hide_current Hides the current language if set to 1, defaults to 0.
197
- * @type int $post_id Returns links to the translations of the post defined by post_id if set, defaults not set.
198
- * @type int $raw Return a raw array instead of html markup if set to 1, defaults to 0.
199
- * @type string $item_spacing Whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to 'preserve'.
200
- * @type int $admin_render Allows to force the current language code in an admin context if set, default to 0. Need to set the admin_current_lang argument below.
201
- * @type string $admin_current_lang The current language code in an admin context. Need to set the admin_render to 1, defaults not set.
 
 
202
  * }
203
  * @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher
204
  */
@@ -215,6 +224,11 @@ class PLL_Switcher {
215
  */
216
  $args = apply_filters( 'pll_the_languages_args', $args );
217
 
 
 
 
 
 
218
  // Prevents showing empty options in dropdown
219
  if ( $args['dropdown'] ) {
220
  $args['show_names'] = 1;
126
  $order = (int) $language->term_group;
127
  $slug = $language->slug;
128
  $locale = $language->get_locale( 'display' );
129
+ $item_classes = array( 'lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr( $slug ) );
130
+ $classes = isset( $args['classes'] ) && is_array( $args['classes'] ) ?
131
+ array_merge(
132
+ $item_classes,
133
+ $args['classes']
134
+ ) :
135
+ $item_classes;
136
+ $link_classes = isset( $args['link_classes'] ) ? $args['link_classes'] : array();
137
  $current_lang = $this->get_current_language( $args ) === $slug;
138
 
139
  if ( $current_lang ) {
176
  $first = false;
177
  }
178
 
179
+ $out[ $slug ] = compact( 'id', 'order', 'slug', 'locale', 'name', 'url', 'flag', 'current_lang', 'no_translation', 'classes', 'link_classes' );
180
  }
181
 
182
  return $out;
192
  * @param array $args {
193
  * Optional array of arguments.
194
  *
195
+ * @type int $dropdown The list is displayed as dropdown if set, defaults to 0.
196
+ * @type int $echo Echoes the list if set to 1, defaults to 1.
197
+ * @type int $hide_if_empty Hides languages with no posts ( or pages ) if set to 1, defaults to 1.
198
+ * @type int $show_flags Displays flags if set to 1, defaults to 0.
199
+ * @type int $show_names Shows language names if set to 1, defaults to 1.
200
+ * @type string $display_names_as Whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name.
201
+ * @type int $force_home Will always link to home in translated language if set to 1, defaults to 0.
202
+ * @type int $hide_if_no_translation Hides the link if there is no translation if set to 1, defaults to 0.
203
+ * @type int $hide_current Hides the current language if set to 1, defaults to 0.
204
+ * @type int $post_id Returns links to the translations of the post defined by post_id if set, defaults not set.
205
+ * @type int $raw Return a raw array instead of html markup if set to 1, defaults to 0.
206
+ * @type string $item_spacing Whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to 'preserve'.
207
+ * @type int $admin_render Allows to force the current language code in an admin context if set, default to 0. Need to set the admin_current_lang argument below.
208
+ * @type string $admin_current_lang The current language code in an admin context. Need to set the admin_render to 1, defaults not set.
209
+ * @type string[] $classes A list of CSS classes to set to each elements outputted.
210
+ * @type string[] $link_classes A list of CSS classes to set to each link outputted.
211
  * }
212
  * @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher
213
  */
224
  */
225
  $args = apply_filters( 'pll_the_languages_args', $args );
226
 
227
+ // Force not to hide the language for the widget preview even if the option is checked.
228
+ if ( $this->links instanceof PLL_Admin_Links ) {
229
+ $args['hide_if_no_translation'] = 0;
230
+ }
231
+
232
  // Prevents showing empty options in dropdown
233
  if ( $args['dropdown'] ) {
234
  $args['show_names'] = 1;
include/translated-object.php CHANGED
@@ -91,6 +91,31 @@ abstract class PLL_Translated_Object {
91
  */
92
  abstract public function get_language( $id );
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Wrap wp_get_object_terms() to cache it and return only one object.
96
  * inspired by the WordPress function get_the_terms().
@@ -164,12 +189,15 @@ abstract class PLL_Translated_Object {
164
  *
165
  * @param int $id Object id ( typically a post_id or term_id ).
166
  * @param int[] $translations An associative array of translations with language code as key and translation id as value.
167
- * @return void
 
168
  */
169
  public function save_translations( $id, $translations ) {
 
 
170
  $id = (int) $id;
171
 
172
- if ( ( $lang = $this->get_language( $id ) ) && is_array( $translations ) ) {
173
  // Sanitize the translations array.
174
  $translations = array_map( 'intval', $translations );
175
  $translations = array_merge( array( $lang->slug => $id ), $translations ); // Make sure this object is in translations.
@@ -211,7 +239,29 @@ abstract class PLL_Translated_Object {
211
  }
212
  }
213
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  }
 
 
215
  }
216
 
217
  /**
91
  */
92
  abstract public function get_language( $id );
93
 
94
+ /**
95
+ * Assigns a new language to an object, taking care of the translations group.
96
+ *
97
+ * @since 3.1
98
+ *
99
+ * @param int $id Object id.
100
+ * @param PLL_Language $lang New language to assign to the object.
101
+ * @return void
102
+ */
103
+ public function update_language( $id, $lang ) {
104
+ if ( $this->get_language( $id ) === $lang ) {
105
+ return;
106
+ }
107
+
108
+ $this->set_language( $id, $lang );
109
+
110
+ $translations = $this->get_translations( $id );
111
+
112
+ if ( $translations ) {
113
+ // Remove the post's former language from the new translations group.
114
+ $translations = array_diff( $translations, array( $id ) );
115
+ $this->save_translations( $id, $translations );
116
+ }
117
+ }
118
+
119
  /**
120
  * Wrap wp_get_object_terms() to cache it and return only one object.
121
  * inspired by the WordPress function get_the_terms().
189
  *
190
  * @param int $id Object id ( typically a post_id or term_id ).
191
  * @param int[] $translations An associative array of translations with language code as key and translation id as value.
192
+ *
193
+ * @return int[] An associative array with language codes as key and post ids as values.
194
  */
195
  public function save_translations( $id, $translations ) {
196
+ $translations = $this->validate_translations( $translations );
197
+
198
  $id = (int) $id;
199
 
200
+ if ( $lang = $this->get_language( $id ) ) {
201
  // Sanitize the translations array.
202
  $translations = array_map( 'intval', $translations );
203
  $translations = array_merge( array( $lang->slug => $id ), $translations ); // Make sure this object is in translations.
239
  }
240
  }
241
  }
242
+ return $translations;
243
+ } else {
244
+ return array();
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Returns translations after checking the translated post is in the right language
250
+ *
251
+ * @since 3.1
252
+ *
253
+ * @param int[] $translations An associative array of translations with language code as key and translation id as value.
254
+ *
255
+ * @return int[]
256
+ */
257
+ public function validate_translations( $translations ) {
258
+ $valid_translations = array();
259
+
260
+ foreach ( $translations as $lang => $tr_id ) {
261
+ $valid_translations[ $lang ] = ( $tr_id && $this->get_language( (int) $tr_id )->slug == $lang ) ? (int) $tr_id : 0;
262
  }
263
+
264
+ return $valid_translations;
265
  }
266
 
267
  /**
include/translated-post.php CHANGED
@@ -265,4 +265,5 @@ class PLL_Translated_Post extends PLL_Translated_Object {
265
 
266
  return $return;
267
  }
 
268
  }
265
 
266
  return $return;
267
  }
268
+
269
  }
include/walker-list.php CHANGED
@@ -32,14 +32,15 @@ class PLL_Walker_List extends Walker {
32
  */
33
  public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
34
  $output .= sprintf(
35
- '%6$s<li class="%1$s"><a lang="%2$s" hreflang="%2$s" href="%3$s">%4$s%5$s</a></li>%7$s',
36
  esc_attr( implode( ' ', $element->classes ) ),
37
  esc_attr( $element->locale ),
38
  esc_url( $element->url ),
39
  $element->flag,
40
  $args['show_flags'] && $args['show_names'] ? sprintf( '<span style="margin-%1$s:0.3em;">%2$s</span>', is_rtl() ? 'right' : 'left', esc_html( $element->name ) ) : esc_html( $element->name ),
41
  'discard' === $args['item_spacing'] ? '' : "\t",
42
- 'discard' === $args['item_spacing'] ? '' : "\n"
 
43
  );
44
  }
45
 
32
  */
33
  public function start_el( &$output, $element, $depth = 0, $args = array(), $current_object_id = 0 ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
34
  $output .= sprintf(
35
+ '%6$s<li class="%1$s"><a %8$s lang="%2$s" hreflang="%2$s" href="%3$s">%4$s%5$s</a></li>%7$s',
36
  esc_attr( implode( ' ', $element->classes ) ),
37
  esc_attr( $element->locale ),
38
  esc_url( $element->url ),
39
  $element->flag,
40
  $args['show_flags'] && $args['show_names'] ? sprintf( '<span style="margin-%1$s:0.3em;">%2$s</span>', is_rtl() ? 'right' : 'left', esc_html( $element->name ) ) : esc_html( $element->name ),
41
  'discard' === $args['item_spacing'] ? '' : "\t",
42
+ 'discard' === $args['item_spacing'] ? '' : "\n",
43
+ empty( $element->link_classes ) ? '' : 'class="' . esc_attr( implode( ' ', $element->link_classes ) ) . '"'
44
  );
45
  }
46
 
include/widget-languages.php CHANGED
@@ -37,7 +37,7 @@ class PLL_Widget_Languages extends WP_Widget {
37
  */
38
  public function widget( $args, $instance ) {
39
  // Sets a unique id for dropdown.
40
- $instance['dropdown'] = empty( $instance['dropdown'] ) ? 0 : $args['widget_id'];
41
 
42
  if ( $list = pll_the_languages( array_merge( $instance, array( 'echo' => 0 ) ) ) ) {
43
  $title = empty( $instance['title'] ) ? '' : $instance['title'];
37
  */
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 = pll_the_languages( array_merge( $instance, array( 'echo' => 0 ) ) ) ) {
43
  $title = empty( $instance['title'] ) ? '' : $instance['title'];
install/install.php CHANGED
@@ -80,7 +80,7 @@ class PLL_Install extends PLL_Install_Base {
80
  }
81
 
82
  /**
83
- * Get default Polylang options
84
  *
85
  * @since 1.8
86
  *
@@ -88,14 +88,14 @@ class PLL_Install extends PLL_Install_Base {
88
  */
89
  public static function get_default_options() {
90
  return array(
91
- 'browser' => 1, // Default language for the front page is set by browser preference
92
- 'rewrite' => 1, // Remove /language/ in permalinks ( was the opposite before 0.7.2 )
93
- 'hide_default' => 1, // Remove URL language information for default language ( was the opposite before 2.1.5 )
94
- 'force_lang' => 1, // Add URL language information ( was 0 before 1.7 )
95
- 'redirect_lang' => 0, // Do not redirect the language page to the homepage
96
- 'media_support' => 1, // Support languages and translation for media by default
97
- 'uninstall' => 0, // Do not remove data when uninstalling Polylang
98
- 'sync' => array(), // Synchronisation is disabled by default ( was the opposite before 1.2 )
99
  'post_types' => array(),
100
  'taxonomies' => array(),
101
  'domains' => array(),
80
  }
81
 
82
  /**
83
+ * Get default Polylang options.
84
  *
85
  * @since 1.8
86
  *
88
  */
89
  public static function get_default_options() {
90
  return array(
91
+ 'browser' => 0, // Default language for the front page is not set by browser preference (was the opposite before 3.1).
92
+ 'rewrite' => 1, // Remove /language/ in permalinks (was the opposite before 0.7.2).
93
+ 'hide_default' => 1, // Remove URL language information for default language (was the opposite before 2.1.5).
94
+ 'force_lang' => 1, // Add URL language information (was 0 before 1.7).
95
+ 'redirect_lang' => 0, // Do not redirect the language page to the homepage.
96
+ 'media_support' => 0, // Do not support languages and translation for media by default (was the opposite before 3.1).
97
+ 'uninstall' => 0, // Do not remove data when uninstalling Polylang.
98
+ 'sync' => array(), // Synchronisation is disabled by default (was the opposite before 1.2).
99
  'post_types' => array(),
100
  'taxonomies' => array(),
101
  'domains' => array(),
install/plugin-updater.php CHANGED
@@ -1,7 +1,4 @@
1
  <?php
2
- /**
3
- * @package Polylang
4
- */
5
 
6
  // Exit if accessed directly
7
  if ( ! defined( 'ABSPATH' ) ) {
1
  <?php
 
 
 
2
 
3
  // Exit if accessed directly
4
  if ( ! defined( 'ABSPATH' ) ) {
js/admin.js DELETED
@@ -1,415 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- jQuery(
6
- function( $ ) {
7
-
8
- // languages list table
9
- // accessibility to row actions on focus
10
- // mainly copy paste of WP code from common.js
11
- var transitionTimeout;
12
- $( 'table.languages' ).on(
13
- { // restricted to languages list table
14
- focusin: function() {
15
- clearTimeout( transitionTimeout );
16
- var focusedRowActions = $( this ).find( '.row-actions' );
17
- // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
18
- $( '.row-actions' ).not( this ).removeClass( 'visible' );
19
- focusedRowActions.addClass( 'visible' );
20
- },
21
- focusout: function() {
22
- // Tabbing between post title and .row-actions links needs a brief pause, otherwise
23
- // the .row-actions div gets hidden in transit in some browsers ( ahem, Firefox ).
24
- transitionTimeout = setTimeout(
25
- function() {
26
- focusedRowActions.removeClass( 'visible' );
27
- },
28
- 30
29
- );
30
- }
31
- },
32
- 'tr'
33
- ); // acts on the whole tr instead of single td as we have actions links in several columns
34
-
35
- /**
36
- * Common functions and variables for overriding languages and flags dropdown list by a jQuery UI selectmenu widget.
37
- */
38
-
39
- // Add a boolean variable to be able to check jQuery UI >= 1.12 which is introduced in WP 5.6.
40
- // Backward compatibility WP < 5.6
41
- var isJqueryUImin112 = $.ui.version >= '1.12.0';
42
- // Allow to check if a flag list dropdown is present. Not present in the Wizard steps or other settings page.
43
- var flagListExist = $( "#flag_list" ).length;
44
- // Allow to check if a language list dropdown is present. Not present in other settings page.
45
- var langListExist = $( "#lang_list" ).length;
46
- // jQuery UI selectmenu widget width option
47
- var defaultSelectmenuWidth = '95%';
48
- var wizardSelectmenuWidth = '100%';
49
-
50
- // Inject flag image when jQuery UI selectmenu is created or an item is selected.
51
- // jQuery UI 1.12 introduce a wrapper inside de li tag which is necessary to selectmenu widget to work correctly.
52
- // Mainly copy from the orginal jQuery UI 1.12 selectmenu widget _renderItem method.
53
- // Note this code works fine with jQuery UI 1.11.4 too.
54
- var selectmenuRenderItem = function( ul, item ) {
55
- var li = $( '<li>' );
56
- var wrapper = $( '<div>');
57
-
58
- if ( item.disabled ) {
59
- this._addClass( li, null, "ui-state-disabled" );
60
- }
61
- this._setText( wrapper, item.label );
62
-
63
- // Add the flag from the data attribute in the selected element.
64
- wrapper.prepend( $( item.element ).data( 'flag-html' ) );
65
- wrapper.children( 'img' ).addClass( 'ui-icon' );
66
-
67
- return li.append( wrapper ).appendTo( ul );
68
- };
69
- // Override selected item to inject flag for jQuery UI less than 1.12.
70
- var selectmenuRefreshButtonText = function( selectElement ) {
71
- var buttonText = $( selectElement ).selectmenu( 'instance' ).buttonText;
72
- buttonText.prepend( $( selectElement ).children( ':selected' ).data( 'flag-html' ) );
73
- buttonText.children( 'img' ).addClass( 'ui-icon' );
74
- };
75
- // Override selected item since jQuery UI 1.12 which introduces extension point method _renderButtonItem.
76
- // @see https://api.jqueryui.com/1.12/selectmenu/#method-_renderButtonItem _renderButtonItem documentation.
77
- var selectmenuRenderButtonItem = function ( selectElement ) {
78
- var buttonItem = $( '<span>' );
79
- this._setText( buttonItem, selectElement.label );
80
- this._addClass( buttonItem, "ui-selectmenu-text" );
81
-
82
- // Add the flag from the data attribute in the selected element.
83
- buttonItem.prepend( $( selectElement.element ).data( 'flag-html' ) );
84
- buttonItem.children( 'img' ).addClass( 'ui-icon' );
85
-
86
- return buttonItem;
87
- }
88
-
89
- /**
90
- * Initialize a jQuery UI selectmenu widget on a DOM element
91
- *
92
- * @param {*} element - The jQuery object representing the DOM element to attach the widget with.
93
- * @param {*} config - All the parameters - options and callbacks - necessary to configure the jQuery UI selectmenu widget.
94
- * @return {Object} - The jQuery UI selectmenu widget object instance.
95
- */
96
- function initializeSelectmenuWidget( element, config ) {
97
- // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
98
- var selectmenuWidgetInstance = element.selectmenu( config ).selectmenu( 'instance' );
99
- // Overrides each item in the jQuery UI selectmenu list by injecting flag image.
100
- selectmenuWidgetInstance._renderItem = selectmenuRenderItem;
101
- // Override the selected item rendering for jQuery UI 1.12
102
- if ( isJqueryUImin112 ) {
103
- selectmenuWidgetInstance._renderButtonItem = selectmenuRenderButtonItem;
104
- // Need to refresh to take in account the new button item rendering method after the selectmenu widget instanciaion.
105
- selectmenuWidgetInstance.refresh();
106
- }
107
- return selectmenuWidgetInstance
108
- }
109
- /**
110
- * Selectmenu widget common parameters for its configuration: options and callbacks.
111
- */
112
-
113
- // Selectmenu widget options
114
- var selectmenuOptions = {
115
- width: defaultSelectmenuWidth,
116
- classes: {
117
- 'ui-selectmenu-menu': 'pll-selectmenu-menu',
118
- 'ui-selectmenu-button': 'pll-selectmenu-button',
119
- }
120
- };
121
-
122
- // Selectmenu widget callbacks
123
- var selectmenuFlagListCallbacks = {};
124
- // Callbacks when Selectmenu widget create or select event is triggered.
125
- var createSelectCallback = function( event, ui ) {
126
- selectmenuRefreshButtonText( event.target );
127
- }
128
-
129
- /**
130
- * Overrides the flag dropdown list with our customized jquery ui selectmenu.
131
- */
132
-
133
- // Callbacks when Selectmenu widget change or open event is triggered.
134
- // Needed to correctly refresh the selected element in the list when editing an existing language or when the value change is triggered by the language choice.
135
- // jQuery UI 1.11 callback version.
136
- var changeOpenCallback = function( event, ui ){
137
- selectmenuRefreshButtonText( $( event.target ).selectmenu( 'refresh' ) );
138
- }
139
- // jQueryUI 1.12 callback version.
140
- var changeOpenCallbackjQueryUI112 = function( event, ui ){
141
- // Just a refresh of the menu is needed with jQuery UI 1.12 because _renderButtonItem is triggered and then inject correctly the flag.
142
- $( event.target ).selectmenu( 'refresh' );
143
- }
144
- // There is no need of create and select callbacks with jQuery UI 1.12 because overriding _renderButtonItem method do the job.
145
- if ( isJqueryUImin112 ) {
146
- selectmenuFlagListCallbacks =
147
- {
148
- change: changeOpenCallbackjQueryUI112,
149
- open: changeOpenCallbackjQueryUI112,
150
- };
151
- } else {
152
- selectmenuFlagListCallbacks = {
153
- create: createSelectCallback,
154
- select: createSelectCallback,
155
- change: changeOpenCallback,
156
- open: changeOpenCallback,
157
- };
158
- }
159
-
160
- // Create the selectmenu widget only if the field is present.
161
- if ( flagListExist ) {
162
- // Create the jQuery UI selectmenu widget for flags list dropdown and return its instance.
163
- var selectmenuFlagList = initializeSelectmenuWidget( $( '#flag_list' ), Object.assign( {}, selectmenuOptions, selectmenuFlagListCallbacks ) );
164
- $( '#lang_list' ).on(
165
- 'languageChanged',
166
- function( event, flag ) {
167
- // Refresh the flag field
168
- selectmenuFlagList.element.val( flag );
169
- selectmenuFlagList._trigger( 'change' );
170
- }
171
- );
172
- }
173
-
174
- /**
175
- * Language choice in predefined languages in Polylang Languages settings page and wizard.
176
- * Overrides the predefined language dropdown list with our customized jQuery ui selectmenu widget.
177
- */
178
-
179
- /**
180
- * Fill the other language form fields from the language element selected in the language list dropdown.
181
- *
182
- * @param {Object} language - language object of the selected element in the language list dropdown.
183
- */
184
- function fillLanguageFields( language ) {
185
- $( '#lang_slug' ).val( language.slug );
186
- $( '#lang_locale' ).val( language.locale );
187
- $( 'input[name="rtl"]' ).val( language.rtl );
188
- $( '#lang_name' ).val( language.name );
189
- }
190
-
191
- /**
192
- * Parse selected language element in the language list dropdown.
193
- *
194
- * @param {object} event - jQuery triggered event.
195
- * @return {object} The language object with its named properties.
196
- */
197
- function parseSelectedLanguage( event ) {
198
- var selectedElement = $('option:selected', event.target);
199
- var values = selectedElement.val().split(':')
200
- return {
201
- slug: values[0],
202
- locale: values[1],
203
- rtl: [values[2]],
204
- flag: values[3],
205
- name: selectedElement.text().split(' - ')[0] // At the moment there is no need of the 2nd part because it corresponds on the locale which is already known by splitting the selected element value
206
- };
207
- }
208
-
209
- // Callback when selectmenu widget change event is triggered.
210
- var changeCallback = function( event, ui ) {
211
- var language = parseSelectedLanguage( event );
212
-
213
- fillLanguageFields( language );
214
-
215
- $( event.target ).trigger( 'languageChanged', language.flag );
216
- };
217
-
218
- // Create the jQuery UI selectmenu widget languages list dropdown and return its instance.
219
- var selectmenuLangListCallbacks = {};
220
- // For the wizard we need a 100% width. So we override the previous defined value of selectmenuOptions.
221
- if( $( '#lang_list' ).closest( '.pll-wizard-content' ).length > 0 ) {
222
- selectmenuOptions = Object.assign( selectmenuOptions, { width: wizardSelectmenuWidth } );
223
- }
224
-
225
- // There is no need of create and select callbacks with jQuery UI 1.12 because overrinding _renderButtonItem method do the job.
226
- if ( isJqueryUImin112 ) {
227
- selectmenuLangListCallbacks = {
228
- change: changeCallback,
229
- };
230
- } else {
231
- selectmenuLangListCallbacks = {
232
- create: createSelectCallback,
233
- select: createSelectCallback,
234
- change: changeCallback,
235
- };
236
- }
237
- if ( langListExist ) {
238
- initializeSelectmenuWidget( $( '#lang_list' ), Object.assign( {}, selectmenuOptions, selectmenuLangListCallbacks ) );
239
- }
240
-
241
- // strings translations
242
- // save translations when pressing enter
243
- $( '.translation input' ).on(
244
- 'keydown',
245
- function( event ){
246
- if ( 'Enter' === event.key ) {
247
- event.preventDefault();
248
- $( '#submit' ).trigger( 'click' );
249
- }
250
- }
251
- );
252
-
253
- // settings page
254
- // click on configure link
255
- $( '#the-list' ).on(
256
- 'click',
257
- '.configure>a',
258
- function(){
259
- $( '.pll-configure' ).hide().prev().show();
260
- $( this ).closest( 'tr' ).hide().next().show();
261
- return false;
262
- }
263
- );
264
-
265
- // cancel
266
- $( '#the-list' ).on(
267
- 'click',
268
- '.cancel',
269
- function(){
270
- $( this ).closest( 'tr' ).hide().prev().show();
271
- }
272
- );
273
-
274
- // save settings
275
- $( '#the-list' ).on(
276
- 'click',
277
- '.save',
278
- function(){
279
- var tr = $( this ).closest( 'tr' );
280
- var parts = tr.attr( 'id' ).split( '-' );
281
-
282
- var data = {
283
- action: 'pll_save_options',
284
- pll_ajax_settings: true,
285
- module: parts[parts.length - 1],
286
- _pll_nonce: $( '#_pll_nonce' ).val()
287
- };
288
-
289
- data = tr.find( ':input' ).serialize() + '&' + $.param( data );
290
-
291
- $.post(
292
- ajaxurl,
293
- data,
294
- function( response ) {
295
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
296
- $.each(
297
- res.responses,
298
- function() {
299
- switch ( this.what ) {
300
- case 'license-update':
301
- $( '#pll-license-' + this.data ).replaceWith( this.supplemental.html );
302
- break;
303
- case 'success':
304
- tr.hide().prev().show(); // close only if there is no error
305
- case 'error':
306
- $( '.settings-error' ).remove(); // remove previous messages if any
307
- $( 'h1' ).after( this.data );
308
-
309
- // Make notices dismissible
310
- // copy paste of common.js from WP 4.2.2
311
- $( '.notice.is-dismissible' ).each(
312
- function() {
313
- var $this = $( this ),
314
- $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
315
- btnText = pll_admin.dismiss_notice || '';
316
-
317
- // Ensure plain text
318
- $button.find( '.screen-reader-text' ).text( btnText );
319
-
320
- // Whitelist because of how the button is built. See above
321
- $this.append( $button ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
322
-
323
- $button.on(
324
- 'click.wp-dismiss-notice',
325
- function( event ) {
326
- event.preventDefault();
327
- $this.fadeTo(
328
- 100,
329
- 0,
330
- function() {
331
- $( this ).slideUp(
332
- 100,
333
- function() {
334
- $( this ).remove();
335
- }
336
- );
337
- }
338
- );
339
- }
340
- );
341
- }
342
- );
343
- break;
344
- }
345
- }
346
- );
347
- }
348
- );
349
- }
350
- );
351
-
352
- // act when pressing enter or esc in configurations
353
- $( '.pll-configure' ).on(
354
- 'keydown',
355
- function( event ){
356
- if ( 'Enter' === event.key ) {
357
- event.preventDefault();
358
- $( this ).find( '.save' ).trigger( 'click' );
359
- }
360
-
361
- if ( 'Escape' === event.key ) {
362
- event.preventDefault();
363
- $( this ).find( '.cancel' ).trigger( 'click' );
364
- }
365
- }
366
- );
367
-
368
- // settings URL modifications
369
- // manages visibility of fields
370
- $( "input[name='force_lang']" ).on(
371
- 'change',
372
- function() {
373
- function pll_toggle( a, test ) {
374
- test ? a.show() : a.hide();
375
- }
376
-
377
- var value = $( this ).val();
378
- pll_toggle( $( '#pll-domains-table' ), 3 == value );
379
- pll_toggle( $( "#pll-hide-default" ), 3 > value );
380
- pll_toggle( $( "#pll-rewrite" ), 2 > value );
381
- pll_toggle( $( "#pll-redirect-lang" ), 2 > value );
382
- }
383
- );
384
-
385
- // settings license
386
- // deactivate button
387
- $( '.pll-deactivate-license' ).on(
388
- 'click',
389
- function() {
390
- var data = {
391
- action: 'pll_deactivate_license',
392
- pll_ajax_settings: true,
393
- id: $( this ).attr( 'id' ),
394
- _pll_nonce: $( '#_pll_nonce' ).val()
395
- };
396
- $.post(
397
- ajaxurl,
398
- data,
399
- function( response ){
400
- $( '#pll-license-' + response.id ).replaceWith( response.html );
401
- }
402
- );
403
- }
404
- );
405
-
406
- // Manage closing the metabox.
407
- // close postboxes that should be closed
408
- $( '.if-js-closed' ).removeClass( 'if-js-closed' ).addClass( 'closed' );
409
- // postboxes setup
410
- if ( 'undefined' !== typeof postboxes ) {
411
- postboxes.add_postbox_toggles( pagenow );
412
- }
413
- }
414
- );
415
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/block-editor.js DELETED
@@ -1,252 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- import {
6
- initializeLanguageOldValue,
7
- initializeConfimationModal
8
- } from './lib/confirmation-modal';
9
-
10
- /**
11
- * Filter REST API requests to add the language in the request
12
- *
13
- * @since 2.5
14
- */
15
- wp.apiFetch.use(
16
- function( options, next ) {
17
- // If options.url is defined, this is not a REST request but a direct call to post.php for legacy metaboxes.
18
- if ( 'undefined' === typeof options.url ) {
19
- if ( 'undefined' === typeof options.data || null === options.data ) {
20
- // GET
21
- options.path += ( ( options.path.indexOf( '?' ) >= 0 ) ? '&lang=' : '?lang=' ) + getCurrentLanguage();
22
- } else {
23
- // PUT, POST
24
- options.data.lang = getCurrentLanguage();
25
- }
26
- }
27
- return next( options );
28
- }
29
- );
30
-
31
- /**
32
- * Get the language from the HTML form
33
- *
34
- * @since 2.5
35
- *
36
- * @return {Element.value}
37
- */
38
- function getCurrentLanguage() {
39
- return document.querySelector( '[name=post_lang_choice]' ).value;
40
- }
41
-
42
- /**
43
- * Handles internals of the metabox:
44
- * Language select, autocomplete input field.
45
- *
46
- * @since 1.5
47
- *
48
- * Save post after lang choice is done and redirect to the same page for refreshing all the data.
49
- *
50
- * @since 2.5
51
- *
52
- * Link post saving after refreshing the metabox.
53
- *
54
- * @since 3.0
55
- */
56
- jQuery(
57
- function( $ ) {
58
- // Initialize current language to be able to compare if it changes.
59
- initializeLanguageOldValue();
60
-
61
-
62
- // Ajax for changing the post's language in the languages metabox
63
- $( '.post_lang_choice' ).on(
64
- 'change',
65
- function( event ) {
66
- const select = wp.data.select;
67
- const dispatch = wp.data.dispatch;
68
- const subscribe = wp.data.subscribe;
69
- const emptyPost = isEmptyPost();
70
-
71
- // Initialize the confirmation dialog box.
72
- const confirmationModal = initializeConfimationModal();
73
- const { dialogContainer : dialog } = confirmationModal;
74
- let { dialogResult } = confirmationModal;
75
- // The selected option in the dropdown list.
76
- const selectedOption = event.target;
77
-
78
- // Specific case for empty posts.
79
- // Place at the beginning because window.location changing triggers automatically page reloading.
80
- if ( location.pathname.match( /post-new.php/gi ) && emptyPost ) {
81
- reloadPageForEmptyPost( selectedOption.value );
82
- }
83
-
84
- // Otherwise send an ajax request to refresh the legacy metabox and set the post language with the new language.
85
- // It needs a confirmation of the user before changing the language.
86
- // Need to wait the ajax response before triggering the block editor post save action.
87
- if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! emptyPost ) {
88
- dialog.dialog( 'open' );
89
- } else {
90
- // Update the old language with the new one to be able to compare it in the next changing.
91
- // Because the page isn't reloaded in this case.
92
- initializeLanguageOldValue();
93
- dialogResult = Promise.resolve();
94
- }
95
-
96
- dialogResult.then(
97
- () => {
98
- var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
99
- action: 'post_lang_choice',
100
- lang: selectedOption.value,
101
- post_type: $( '#post_type' ).val(),
102
- post_id: $( '#post_ID' ).val(),
103
- _pll_nonce: $( '#_pll_nonce' ).val()
104
- }
105
-
106
- $.post(
107
- ajaxurl,
108
- data,
109
- function( response ) {
110
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
111
- $.each(
112
- res.responses,
113
- function() {
114
- switch ( this.what ) {
115
- case 'translations': // Translations fields
116
- // Data is built and come from server side and is well escaped when necessary
117
- $( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
118
- init_translations();
119
- break;
120
- case 'flag': // Flag in front of the select dropdown
121
- // Data is built and come from server side and is well escaped when necessary
122
- $( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
123
- break;
124
- }
125
- }
126
- );
127
- blockEditorSavePostAndReloadPage();
128
- }
129
- );
130
- },
131
- () => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
132
- );
133
-
134
- function isEmptyPost() {
135
- const editor = wp.data.select( 'core/editor' );
136
- const title = editor.getEditedPostAttribute( 'title' ).trim();
137
- const content = editor.getEditedPostAttribute( 'content' ).trim();
138
- const excerpt = editor.getEditedPostAttribute( 'excerpt' ).trim();
139
-
140
- return ! title && ! content && ! excerpt;
141
- }
142
-
143
- /**
144
- * Reload the block editor page for empty posts.
145
- *
146
- * @param {string} lang The target language code.
147
- */
148
- function reloadPageForEmptyPost( lang ) {
149
- // Change the new_lang parameter with the new language value for reloading the page
150
- // WPCS location.search is never written in the page, just used to reload page with the right value of new_lang
151
- // new_lang input is controlled server side in PHP. The value come from the dropdown list of language returned and escaped server side.
152
- // Notice that window.location changing triggers automatically page reloading.
153
- if ( -1 != location.search.indexOf( 'new_lang' ) ) {
154
- // use regexp non capturing group to replace new_lang parameter no matter where it is and capture other parameters which can be behind it
155
- window.location.search = window.location.search.replace( /(?:new_lang=[^&]*)(&)?(.*)/, 'new_lang=' + lang + '$1$2' ); // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
156
- } else {
157
- window.location.search = window.location.search + ( ( -1 != window.location.search.indexOf( '?' ) ) ? '&' : '?' ) + 'new_lang=' + lang; // phpcs:ignore WordPressVIPMinimum.JS.Window.location, WordPressVIPMinimum.JS.Window.VarAssignment
158
- }
159
- };
160
-
161
- /**
162
- * Triggers block editor post save and reload the block editor page when everything is ok.
163
- */
164
- function blockEditorSavePostAndReloadPage() {
165
-
166
- let unsubscribe = null;
167
-
168
- // Listen if the savePost is completely done by subscribing to its events.
169
- const savePostIsDone = new Promise(
170
- function( resolve, reject ) {
171
- unsubscribe = subscribe(
172
- function() {
173
- const isSavePostSucceeded = select( 'core/editor' ).didPostSaveRequestSucceed();
174
- const isSavePostFailed = select( 'core/editor' ).didPostSaveRequestFail();
175
- if ( isSavePostSucceeded || isSavePostFailed ) {
176
- if ( isSavePostFailed ) {
177
- reject();
178
- } else {
179
- resolve();
180
- }
181
- }
182
- }
183
- );
184
- }
185
- );
186
-
187
- // Triggers the post save.
188
- dispatch( 'core/editor' ).savePost();
189
-
190
- // Process
191
- savePostIsDone.then(
192
- function() {
193
- // If the post is well saved, we can reload the page
194
- window.location.reload();
195
- },
196
- function() {
197
- // If the post save failed
198
- unsubscribe();
199
- }
200
- ).catch(
201
- function() {
202
- // If an exception is thrown
203
- unsubscribe();
204
- }
205
- );
206
- };
207
- }
208
- );
209
-
210
- // Translations autocomplete input box
211
- function init_translations() {
212
- $( '.tr_lang' ).each(
213
- function(){
214
- var tr_lang = $( this ).attr( 'id' ).substring( 8 );
215
- var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
216
-
217
- $( this ).autocomplete(
218
- {
219
- minLength: 0,
220
-
221
- source: ajaxurl + '?action=pll_posts_not_translated' +
222
- '&post_language=' + $( '.post_lang_choice' ).val() +
223
- '&translation_language=' + tr_lang +
224
- '&post_type=' + $( '#post_type' ).val() +
225
- '&_pll_nonce=' + $( '#_pll_nonce' ).val(),
226
-
227
- select: function( event, ui ) {
228
- $( '#htr_lang_' + tr_lang ).val( ui.item.id );
229
- // ui.item.link is built and come from server side and is well escaped when necessary
230
- td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
231
- },
232
- }
233
- );
234
-
235
- // When the input box is emptied
236
- $( this ).on(
237
- 'blur',
238
- function() {
239
- if ( ! $( this ).val() ) {
240
- $( '#htr_lang_' + tr_lang ).val( 0 );
241
- // Value is retrieved from HTML already generated server side
242
- td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
243
- }
244
- }
245
- );
246
- }
247
- );
248
- }
249
-
250
- init_translations();
251
- }
252
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/build/admin.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * @package Polylang
3
  */
1
+ var __webpack_exports__ = {};
2
  /**
3
  * @package Polylang
4
  */
js/build/admin.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(e){var t;e("table.languages").on({focusin:function(){clearTimeout(t);var n=e(this).find(".row-actions");e(".row-actions").not(this).removeClass("visible"),n.addClass("visible")},focusout:function(){t=setTimeout((function(){focusedRowActions.removeClass("visible")}),30)}},"tr");var n=e.ui.version>="1.12.0",l=e("#flag_list").length,s=e("#lang_list").length,i=function(t,n){var l=e("<li>"),s=e("<div>");return n.disabled&&this._addClass(l,null,"ui-state-disabled"),this._setText(s,n.label),s.prepend(e(n.element).data("flag-html")),s.children("img").addClass("ui-icon"),l.append(s).appendTo(t)},a=function(t){var n=e(t).selectmenu("instance").buttonText;n.prepend(e(t).children(":selected").data("flag-html")),n.children("img").addClass("ui-icon")},c=function(t){var n=e("<span>");return this._setText(n,t.label),this._addClass(n,"ui-selectmenu-text"),n.prepend(e(t.element).data("flag-html")),n.children("img").addClass("ui-icon"),n};function o(e,t){var l=e.selectmenu(t).selectmenu("instance");return l._renderItem=i,n&&(l._renderButtonItem=c,l.refresh()),l}var r={width:"95%",classes:{"ui-selectmenu-menu":"pll-selectmenu-menu","ui-selectmenu-button":"pll-selectmenu-button"}},u={},d=function(e,t){a(e.target)},p=function(t,n){a(e(t.target).selectmenu("refresh"))},g=function(t,n){e(t.target).selectmenu("refresh")};if(u=n?{change:g,open:g}:{create:d,select:d,change:p,open:p},l){var h=o(e("#flag_list"),Object.assign({},r,u));e("#lang_list").on("languageChanged",(function(e,t){h.element.val(t),h._trigger("change")}))}var f=function(t,n){var l=function(t){var n=e("option:selected",t.target),l=n.val().split(":");return{slug:l[0],locale:l[1],rtl:[l[2]],flag:l[3],name:n.text().split(" - ")[0]}}(t);!function(t){e("#lang_slug").val(t.slug),e("#lang_locale").val(t.locale),e('input[name="rtl"]').val(t.rtl),e("#lang_name").val(t.name)}(l),e(t.target).trigger("languageChanged",l.flag)},v={};e("#lang_list").closest(".pll-wizard-content").length>0&&(r=Object.assign(r,{width:"100%"})),v=n?{change:f}:{create:d,select:d,change:f},s&&o(e("#lang_list"),Object.assign({},r,v)),e(".translation input").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e("#submit").trigger("click"))})),e("#the-list").on("click",".configure>a",(function(){return e(".pll-configure").hide().prev().show(),e(this).closest("tr").hide().next().show(),!1})),e("#the-list").on("click",".cancel",(function(){e(this).closest("tr").hide().prev().show()})),e("#the-list").on("click",".save",(function(){var t=e(this).closest("tr"),n=t.attr("id").split("-"),l={action:"pll_save_options",pll_ajax_settings:!0,module:n[n.length-1],_pll_nonce:e("#_pll_nonce").val()};l=t.find(":input").serialize()+"&"+e.param(l),e.post(ajaxurl,l,(function(n){var l=wpAjax.parseAjaxResponse(n,"ajax-response");e.each(l.responses,(function(){switch(this.what){case"license-update":e("#pll-license-"+this.data).replaceWith(this.supplemental.html);break;case"success":t.hide().prev().show();case"error":e(".settings-error").remove(),e("h1").after(this.data),e(".notice.is-dismissible").each((function(){var t=e(this),n=e('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),l=pll_admin.dismiss_notice||"";n.find(".screen-reader-text").text(l),t.append(n),n.on("click.wp-dismiss-notice",(function(n){n.preventDefault(),t.fadeTo(100,0,(function(){e(this).slideUp(100,(function(){e(this).remove()}))}))}))}))}}))}))})),e(".pll-configure").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e(this).find(".save").trigger("click")),"Escape"===t.key&&(t.preventDefault(),e(this).find(".cancel").trigger("click"))})),e("input[name='force_lang']").on("change",(function(){function t(e,t){t?e.show():e.hide()}var n=e(this).val();t(e("#pll-domains-table"),3==n),t(e("#pll-hide-default"),3>n),t(e("#pll-rewrite"),2>n),t(e("#pll-redirect-lang"),2>n)})),e(".pll-deactivate-license").on("click",(function(){var t={action:"pll_deactivate_license",pll_ajax_settings:!0,id:e(this).attr("id"),_pll_nonce:e("#_pll_nonce").val()};e.post(ajaxurl,t,(function(t){e("#pll-license-"+t.id).replaceWith(t.html)}))})),e(".if-js-closed").removeClass("if-js-closed").addClass("closed"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(pagenow)}));
1
+ var __webpack_exports__={};jQuery((function(e){var t;e("table.languages").on({focusin:function(){clearTimeout(t);var n=e(this).find(".row-actions");e(".row-actions").not(this).removeClass("visible"),n.addClass("visible")},focusout:function(){t=setTimeout((function(){focusedRowActions.removeClass("visible")}),30)}},"tr");var n=e.ui.version>="1.12.0",l=e("#flag_list").length,s=e("#lang_list").length,i=function(t,n){var l=e("<li>"),s=e("<div>");return n.disabled&&this._addClass(l,null,"ui-state-disabled"),this._setText(s,n.label),s.prepend(e(n.element).data("flag-html")),s.children("img").addClass("ui-icon"),l.append(s).appendTo(t)},a=function(t){var n=e(t).selectmenu("instance").buttonText;n.prepend(e(t).children(":selected").data("flag-html")),n.children("img").addClass("ui-icon")},c=function(t){var n=e("<span>");return this._setText(n,t.label),this._addClass(n,"ui-selectmenu-text"),n.prepend(e(t.element).data("flag-html")),n.children("img").addClass("ui-icon"),n};function o(e,t){var l=e.selectmenu(t).selectmenu("instance");return l._renderItem=i,n&&(l._renderButtonItem=c,l.refresh()),l}var r={width:"95%",classes:{"ui-selectmenu-menu":"pll-selectmenu-menu","ui-selectmenu-button":"pll-selectmenu-button"}},u={},d=function(e,t){a(e.target)},p=function(t,n){a(e(t.target).selectmenu("refresh"))},g=function(t,n){e(t.target).selectmenu("refresh")};if(u=n?{change:g,open:g}:{create:d,select:d,change:p,open:p},l){var h=o(e("#flag_list"),Object.assign({},r,u));e("#lang_list").on("languageChanged",(function(e,t){h.element.val(t),h._trigger("change")}))}var f=function(t,n){var l=function(t){var n=e("option:selected",t.target),l=n.val().split(":");return{slug:l[0],locale:l[1],rtl:[l[2]],flag:l[3],name:n.text().split(" - ")[0]}}(t);!function(t){e("#lang_slug").val(t.slug),e("#lang_locale").val(t.locale),e('input[name="rtl"]').val(t.rtl),e("#lang_name").val(t.name)}(l),e(t.target).trigger("languageChanged",l.flag)},v={};e("#lang_list").closest(".pll-wizard-content").length>0&&(r=Object.assign(r,{width:"100%"})),v=n?{change:f}:{create:d,select:d,change:f},s&&o(e("#lang_list"),Object.assign({},r,v)),e(".translation input").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e("#submit").trigger("click"))})),e("#the-list").on("click",".configure>a",(function(){return e(".pll-configure").hide().prev().show(),e(this).closest("tr").hide().next().show(),!1})),e("#the-list").on("click",".cancel",(function(){e(this).closest("tr").hide().prev().show()})),e("#the-list").on("click",".save",(function(){var t=e(this).closest("tr"),n=t.attr("id").split("-"),l={action:"pll_save_options",pll_ajax_settings:!0,module:n[n.length-1],_pll_nonce:e("#_pll_nonce").val()};l=t.find(":input").serialize()+"&"+e.param(l),e.post(ajaxurl,l,(function(n){var l=wpAjax.parseAjaxResponse(n,"ajax-response");e.each(l.responses,(function(){switch(this.what){case"license-update":e("#pll-license-"+this.data).replaceWith(this.supplemental.html);break;case"success":t.hide().prev().show();case"error":e(".settings-error").remove(),e("h1").after(this.data),e(".notice.is-dismissible").each((function(){var t=e(this),n=e('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),l=pll_admin.dismiss_notice||"";n.find(".screen-reader-text").text(l),t.append(n),n.on("click.wp-dismiss-notice",(function(n){n.preventDefault(),t.fadeTo(100,0,(function(){e(this).slideUp(100,(function(){e(this).remove()}))}))}))}))}}))}))})),e(".pll-configure").on("keydown",(function(t){"Enter"===t.key&&(t.preventDefault(),e(this).find(".save").trigger("click")),"Escape"===t.key&&(t.preventDefault(),e(this).find(".cancel").trigger("click"))})),e("input[name='force_lang']").on("change",(function(){function t(e,t){t?e.show():e.hide()}var n=e(this).val();t(e("#pll-domains-table"),3==n),t(e("#pll-hide-default"),3>n),t(e("#pll-rewrite"),2>n),t(e("#pll-redirect-lang"),2>n)})),e(".pll-deactivate-license").on("click",(function(){var t={action:"pll_deactivate_license",pll_ajax_settings:!0,id:e(this).attr("id"),_pll_nonce:e("#_pll_nonce").val()};e.post(ajaxurl,t,(function(t){e("#pll-license-"+t.id).replaceWith(t.html)}))})),e(".if-js-closed").removeClass("if-js-closed").addClass("closed"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(pagenow)}));
js/build/block-editor.js CHANGED
@@ -1,6 +1,7 @@
1
  /******/ "use strict";
 
2
 
3
- ;// CONCATENATED MODULE: ./js/lib/confirmation-modal.js
4
  /**
5
  * @package Polylang
6
  */
@@ -101,7 +102,7 @@ const initializeLanguageOldValue = () => {
101
  languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
102
  };
103
 
104
- ;// CONCATENATED MODULE: ./js/block-editor.js
105
  /**
106
  * @package Polylang
107
  */
1
  /******/ "use strict";
2
+ var __webpack_exports__ = {};
3
 
4
+ ;// CONCATENATED MODULE: ./js/src/lib/confirmation-modal.js
5
  /**
6
  * @package Polylang
7
  */
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
108
  */
js/build/block-editor.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";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,n)=>{const l=t=>{switch(t){case"yes":languagesList.data("old-value",languagesList.children(":selected").first().val()),e();break;case"no":languagesList.val(languagesList.data("old-value")),n("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){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"}),a.dialog(i)}));return{dialogContainer:a,dialogResult:e}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected").first().val())};function getCurrentLanguage(){return document.querySelector("[name=post_lang_choice]").value}wp.apiFetch.use((function(t,a){return void 0===t.url&&(void 0===t.data||null===t.data?t.path+=(t.path.indexOf("?")>=0?"&lang=":"?lang=")+getCurrentLanguage():t.data.lang=getCurrentLanguage()),a(t)})),jQuery((function(t){function a(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+a+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(n,l){t("#htr_lang_"+a).val(l.item.id),e.html(l.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(e){const n=wp.data.select,l=wp.data.dispatch,i=wp.data.subscribe,o=function(){const t=wp.data.select("core/editor"),a=t.getEditedPostAttribute("title").trim(),e=t.getEditedPostAttribute("content").trim(),n=t.getEditedPostAttribute("excerpt").trim();return!a&&!e&&!n}(),s=initializeConfimationModal(),{dialogContainer:c}=s;let{dialogResult:r}=s;const u=e.target;var g;location.pathname.match(/post-new.php/gi)&&o&&(g=u.value,-1!=location.search.indexOf("new_lang")?window.location.search=window.location.search.replace(/(?:new_lang=[^&]*)(&)?(.*)/,"new_lang="+g+"$1$2"):window.location.search=window.location.search+(-1!=window.location.search.indexOf("?")?"&":"?")+"new_lang="+g),t(this).data("old-value")===u.value||o?(initializeLanguageOldValue(),r=Promise.resolve()):c.dialog("open"),r.then((()=>{var 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(e){var o=wpAjax.parseAjaxResponse(e,"ajax-response");t.each(o.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),a();break;case"flag":t(".pll-select-flag").html(this.data)}})),function(){let t=null;const a=new Promise((function(a,e){t=i((function(){const t=n("core/editor").didPostSaveRequestSucceed(),l=n("core/editor").didPostSaveRequestFail();(t||l)&&(l?e():a())}))}));l("core/editor").savePost(),a.then((function(){window.location.reload()}),(function(){t()})).catch((function(){t()}))}()}))}),(()=>{}))})),a()}));
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,n)=>{const l=t=>{switch(t){case"yes":languagesList.data("old-value",languagesList.children(":selected").first().val()),e();break;case"no":languagesList.val(languagesList.data("old-value")),n("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){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"}),a.dialog(i)}));return{dialogContainer:a,dialogResult:e}},initializeLanguageOldValue=()=>{languagesList.attr("data-old-value",languagesList.children(":selected").first().val())};function getCurrentLanguage(){return document.querySelector("[name=post_lang_choice]").value}wp.apiFetch.use((function(t,a){return void 0===t.url&&(void 0===t.data||null===t.data?t.path+=(t.path.indexOf("?")>=0?"&lang=":"?lang=")+getCurrentLanguage():t.data.lang=getCurrentLanguage()),a(t)})),jQuery((function(t){function a(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+a+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(n,l){t("#htr_lang_"+a).val(l.item.id),e.html(l.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(e){const n=wp.data.select,l=wp.data.dispatch,i=wp.data.subscribe,o=function(){const t=wp.data.select("core/editor"),a=t.getEditedPostAttribute("title").trim(),e=t.getEditedPostAttribute("content").trim(),n=t.getEditedPostAttribute("excerpt").trim();return!a&&!e&&!n}(),s=initializeConfimationModal(),{dialogContainer:c}=s;let{dialogResult:r}=s;const u=e.target;var g;location.pathname.match(/post-new.php/gi)&&o&&(g=u.value,-1!=location.search.indexOf("new_lang")?window.location.search=window.location.search.replace(/(?:new_lang=[^&]*)(&)?(.*)/,"new_lang="+g+"$1$2"):window.location.search=window.location.search+(-1!=window.location.search.indexOf("?")?"&":"?")+"new_lang="+g),t(this).data("old-value")===u.value||o?(initializeLanguageOldValue(),r=Promise.resolve()):c.dialog("open"),r.then((()=>{var 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(e){var o=wpAjax.parseAjaxResponse(e,"ajax-response");t.each(o.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),a();break;case"flag":t(".pll-select-flag").html(this.data)}})),function(){let t=null;const a=new Promise((function(a,e){t=i((function(){const t=n("core/editor").didPostSaveRequestSucceed(),l=n("core/editor").didPostSaveRequestFail();(t||l)&&(l?e():a())}))}));l("core/editor").savePost(),a.then((function(){window.location.reload()}),(function(){t()})).catch((function(){t()}))}()}))}),(()=>{}))})),a()}));
js/build/classic-editor.js CHANGED
@@ -1,6 +1,7 @@
1
  /******/ "use strict";
 
2
 
3
- ;// CONCATENATED MODULE: ./js/lib/confirmation-modal.js
4
  /**
5
  * @package Polylang
6
  */
@@ -101,7 +102,7 @@ const initializeLanguageOldValue = () => {
101
  languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
102
  };
103
 
104
- ;// CONCATENATED MODULE: ./js/classic-editor.js
105
  /**
106
  * @package Polylang
107
  */
1
  /******/ "use strict";
2
+ var __webpack_exports__ = {};
3
 
4
+ ;// CONCATENATED MODULE: ./js/src/lib/confirmation-modal.js
5
  /**
6
  * @package Polylang
7
  */
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
108
  */
js/build/classic-editor.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";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;function e(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+a+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(l,n){t("#htr_lang_"+a).val(n.item.id),e.html(n.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}t(".categorydiv").each((function(){var e,l;(e=t(this).attr("id").split("-")).shift(),l=e.join("-"),a.push(l),t("#"+l+"-add-submit").before(t("<input />").attr("type","hidden").attr("id",l+"-lang").attr("name","term_lang_choice").attr("value",t(".post_lang_choice").val()))})),initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(l){const n=initializeConfimationModal(),{dialogContainer:i}=n;let{dialogResult:s}=n;const o=l.target;t(this).data("old-value")===o.value||function(){const a=t("input#title").val(),e=t("textarea#content").val(),l=t("textarea#excerpt").val();return!a&&!e&&!l}()?s=Promise.resolve():i.dialog("open"),s.then((()=>{var l=o.options[o.options.selectedIndex].lang,n=t('.pll-translation-column > span[lang="'+l+'"]').attr("dir"),i={action:"post_lang_choice",lang:o.value,post_type:t("#post_type").val(),taxonomies:a,post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,i,(function(a){var i=wpAjax.parseAjaxResponse(a,"ajax-response");t.each(i.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),e();break;case"taxonomy":var a=this.data;t("#"+a+"checklist").html(this.supplemental.all),t("#"+a+"checklist-pop").html(this.supplemental.populars),t("#new"+a+"_parent").replaceWith(this.supplemental.dropdown),t("#"+a+"-lang").val(t(".post_lang_choice").val());break;case"pages":t("#parent_id").html(this.data);break;case"flag":t(".pll-select-flag").html(this.data);break;case"permalink":var l=t("#edit-slug-box");"-1"!=this.data&&l.children().length&&l.html(this.data)}})),initializeLanguageOldValue(),t(".tagcloud-link").each((function(){var a=t(this).attr("id");tagBox.get(a)})),t("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+n),t("#content_ifr").contents().find("html").attr("lang",l).attr("dir",n),t("#content_ifr").contents().find("body").attr("dir",n),pll.media.resetAllAttachmentsCollections()}))}),(()=>{}))})),e()}));var pll=window.pll||{};_.extend(pll,{media:{}});var media=_.extend(pll.media,{attachmentsCollections:[],query:function(t){var a=pll.media.query.delegate(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);
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;function e(){t(".tr_lang").each((function(){var a=t(this).attr("id").substring(8),e=t(this).parent().parent().siblings(".pll-edit-column");t(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_posts_not_translated&post_language="+t(".post_lang_choice").val()+"&translation_language="+a+"&post_type="+t("#post_type").val()+"&_pll_nonce="+t("#_pll_nonce").val(),select:function(l,n){t("#htr_lang_"+a).val(n.item.id),e.html(n.item.link)}}),t(this).on("blur",(function(){t(this).val()||(t("#htr_lang_"+a).val(0),e.html(e.siblings(".hidden").children().clone()))}))}))}t(".categorydiv").each((function(){var e,l;(e=t(this).attr("id").split("-")).shift(),l=e.join("-"),a.push(l),t("#"+l+"-add-submit").before(t("<input />").attr("type","hidden").attr("id",l+"-lang").attr("name","term_lang_choice").attr("value",t(".post_lang_choice").val()))})),initializeLanguageOldValue(),t(".post_lang_choice").on("change",(function(l){const n=initializeConfimationModal(),{dialogContainer:i}=n;let{dialogResult:s}=n;const o=l.target;t(this).data("old-value")===o.value||function(){const a=t("input#title").val(),e=t("textarea#content").val(),l=t("textarea#excerpt").val();return!a&&!e&&!l}()?s=Promise.resolve():i.dialog("open"),s.then((()=>{var l=o.options[o.options.selectedIndex].lang,n=t('.pll-translation-column > span[lang="'+l+'"]').attr("dir"),i={action:"post_lang_choice",lang:o.value,post_type:t("#post_type").val(),taxonomies:a,post_id:t("#post_ID").val(),_pll_nonce:t("#_pll_nonce").val()};t.post(ajaxurl,i,(function(a){var i=wpAjax.parseAjaxResponse(a,"ajax-response");t.each(i.responses,(function(){switch(this.what){case"translations":t(".translations").html(this.data),e();break;case"taxonomy":var a=this.data;t("#"+a+"checklist").html(this.supplemental.all),t("#"+a+"checklist-pop").html(this.supplemental.populars),t("#new"+a+"_parent").replaceWith(this.supplemental.dropdown),t("#"+a+"-lang").val(t(".post_lang_choice").val());break;case"pages":t("#parent_id").html(this.data);break;case"flag":t(".pll-select-flag").html(this.data);break;case"permalink":var l=t("#edit-slug-box");"-1"!=this.data&&l.children().length&&l.html(this.data)}})),initializeLanguageOldValue(),t(".tagcloud-link").each((function(){var a=t(this).attr("id");tagBox.get(a)})),t("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+n),t("#content_ifr").contents().find("html").attr("lang",l).attr("dir",n),t("#content_ifr").contents().find("body").attr("dir",n),pll.media.resetAllAttachmentsCollections()}))}),(()=>{}))})),e()}));var pll=window.pll||{};_.extend(pll,{media:{}});var media=_.extend(pll.media,{attachmentsCollections:[],query:function(t){var a=pll.media.query.delegate(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/languages-step.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * @package Polylang
3
  */
1
+ var __webpack_exports__ = {};
2
  /**
3
  * @package Polylang
4
  */
js/build/languages-step.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(a){var e=a(".languages-step"),n=a("#language-fields"),t=a("#languages"),l=a("#languages tbody"),i=a("#defined-languages tbody"),r=a("#lang_list"),d=a('[name="save_step"]'),s=a("#messages"),o=new Map,g=a("#dialog");function u(e){var i=a("<td />").text(e.text).prepend(e.flagUrl),d=a("<td />").append(a("<span />").addClass("dashicons dashicons-trash").attr("data-language",e.locale).append(a("<span />").addClass("screen-reader-text").text(pll_wizard_params.i18n_remove_language_icon))),s=a("<tr />").prepend(d).prepend(i),g=a("<input />").attr({type:"hidden",name:"languages[]"}).val(e.locale);r.val(""),r.selectmenu("refresh"),o.set(e.locale,e),l.append(s),l.on("click","span[data-language="+e.locale+"]",(function(e){e.preventDefault(),a(this).parents("tr").remove();n.children("input[value="+a(this).data("language")+"]").remove();l.children().length<=0&&t.hide(),o.delete(a(this).data("language")),c()})),n.append(g)}function p(e){s.empty(),s.prepend(a("<p/>").addClass("error").text(e))}function c(){s.empty(),e.find(".error").removeClass("error field-in-error")}function _(a){a.addClass("error field-in-error")}function m(a){a.trigger("focus")}r.on("selectmenuchange",(function(){c()})),a("#add-language").on("click",(function(e){c();var n=e.currentTarget.form.lang_list.options[e.currentTarget.form.lang_list.selectedIndex];if(""===n.value||o.has(n.value)){var l=pll_wizard_params.i18n_no_language_selected;o.has(n.value)&&(l=pll_wizard_params.i18n_language_already_added),p(l),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))}else u({locale:n.value,text:n.innerText,name:a(n).data("language-name"),flagUrl:a(n).data("flag-html")}),t.show(),m(a("#lang_list-button"))})),e.on("submit",(function(n){var t,l=i.children().length>0,s=a("#lang_list").val();return o.size<=0&&!l?(""===s?(p(pll_wizard_params.i18n_no_language_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):(p(pll_wizard_params.i18n_add_language_needed),_(r.next("span.ui-selectmenu-button")),m(a("#add-language"))),!1):""!==s?(o.has(s)?(p(pll_wizard_params.i18n_language_already_added),_(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):g.dialog("open"),!1):((t=d).prop("disabled",!0),void e.append(a("<input />").prop({type:"hidden",name:t.prop("name"),value:t.prop("value")})))}));var f=new URLSearchParams(document.location.search);function h(n){switch(n){case"yes":var t=a("#lang_list").children(":selected");u({locale:t[0].value,text:t[0].innerText,name:a(t).data("language-name"),flagUrl:a(t).data("flag-html")});break;case"no":r.val("")}g.dialog("close"),"ignore"===n?m(a("#lang_list-button")):e.submit()}f.has("activate_error")&&void 0!==pll_wizard_params[f.get("activate_error")]&&p(pll_wizard_params[f.get("activate_error")]),g.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:pll_wizard_params.i18n_dialog_title,minWidth:600,maxWidth:"100%",open:function(e,n){a("body").hasClass("rtl")&&a(this).parent().css({right:a(this).parent().css("left"),left:"auto"}),a(this).find("#dialog-language").text(a("#lang_list").children(":selected").first().text()),a(this).find("#dialog-language-flag").empty().prepend(a("#lang_list").children(":selected").data("flag-html"))},buttons:[{text:pll_wizard_params.i18n_dialog_yes_button,click:function(a){h("yes")}},{text:pll_wizard_params.i18n_dialog_no_button,click:function(a){h("no")}},{text:pll_wizard_params.i18n_dialog_ignore_button,click:function(a){h("ignore")}}]})}));
1
+ var __webpack_exports__={};jQuery((function(a){var e=a(".languages-step"),n=a("#language-fields"),t=a("#languages"),l=a("#languages tbody"),i=a("#defined-languages tbody"),r=a("#lang_list"),s=a('[name="save_step"]'),d=a("#messages"),o=new Map,g=a("#dialog");function u(e){var i=a("<td />").text(e.text).prepend(e.flagUrl),s=a("<td />").append(a("<span />").addClass("dashicons dashicons-trash").attr("data-language",e.locale).append(a("<span />").addClass("screen-reader-text").text(pll_wizard_params.i18n_remove_language_icon))),d=a("<tr />").prepend(s).prepend(i),g=a("<input />").attr({type:"hidden",name:"languages[]"}).val(e.locale);r.val(""),r.selectmenu("refresh"),o.set(e.locale,e),l.append(d),l.on("click","span[data-language="+e.locale+"]",(function(e){e.preventDefault(),a(this).parents("tr").remove();n.children("input[value="+a(this).data("language")+"]").remove();l.children().length<=0&&t.hide(),o.delete(a(this).data("language")),_()})),n.append(g)}function p(e){d.empty(),d.prepend(a("<p/>").addClass("error").text(e))}function _(){d.empty(),e.find(".error").removeClass("error field-in-error")}function c(a){a.addClass("error field-in-error")}function m(a){a.trigger("focus")}r.on("selectmenuchange",(function(){_()})),a("#add-language").on("click",(function(e){_();var n=e.currentTarget.form.lang_list.options[e.currentTarget.form.lang_list.selectedIndex];if(""===n.value||o.has(n.value)){var l=pll_wizard_params.i18n_no_language_selected;o.has(n.value)&&(l=pll_wizard_params.i18n_language_already_added),p(l),c(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))}else u({locale:n.value,text:n.innerText,name:a(n).data("language-name"),flagUrl:a(n).data("flag-html")}),t.show(),m(a("#lang_list-button"))})),e.on("submit",(function(n){var t,l=i.children().length>0,d=a("#lang_list").val();return o.size<=0&&!l?(""===d?(p(pll_wizard_params.i18n_no_language_added),c(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):(p(pll_wizard_params.i18n_add_language_needed),c(r.next("span.ui-selectmenu-button")),m(a("#add-language"))),!1):""!==d?(o.has(d)?(p(pll_wizard_params.i18n_language_already_added),c(r.next("span.ui-selectmenu-button")),m(a("#lang_list-button"))):g.dialog("open"),!1):((t=s).prop("disabled",!0),void e.append(a("<input />").prop({type:"hidden",name:t.prop("name"),value:t.prop("value")})))}));var f=new URLSearchParams(document.location.search);function h(n){switch(n){case"yes":var t=a("#lang_list").children(":selected");u({locale:t[0].value,text:t[0].innerText,name:a(t).data("language-name"),flagUrl:a(t).data("flag-html")});break;case"no":r.val("")}g.dialog("close"),"ignore"===n?m(a("#lang_list-button")):e.submit()}f.has("activate_error")&&void 0!==pll_wizard_params[f.get("activate_error")]&&p(pll_wizard_params[f.get("activate_error")]),g.dialog({autoOpen:!1,modal:!0,draggable:!1,resizable:!1,title:pll_wizard_params.i18n_dialog_title,minWidth:600,maxWidth:"100%",open:function(e,n){a("body").hasClass("rtl")&&a(this).parent().css({right:a(this).parent().css("left"),left:"auto"}),a(this).find("#dialog-language").text(a("#lang_list").children(":selected").first().text()),a(this).find("#dialog-language-flag").empty().prepend(a("#lang_list").children(":selected").data("flag-html"))},buttons:[{text:pll_wizard_params.i18n_dialog_yes_button,click:function(a){h("yes")}},{text:pll_wizard_params.i18n_dialog_no_button,click:function(a){h("no")}},{text:pll_wizard_params.i18n_dialog_ignore_button,click:function(a){h("ignore")}}]})}));
js/build/nav-menu.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * Handles the options in the language switcher nav menu metabox.
3
  *
1
+ var __webpack_exports__ = {};
2
  /**
3
  * Handles the options in the language switcher nav menu metabox.
4
  *
js/build/nav-menu.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(e){e("#update-nav-menu").on("click",(function(t){t.target&&t.target.className&&-1!=t.target.className.indexOf("item-edit")&&(e("input[value='#pll_switcher'][type=text]").parent().parent().parent().each((function(){var t=e(this).attr("id").substring(19);e(this).children("p:not( .field-move )").remove(),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-title-"+t,name:"menu-item-title["+t+"]",value:pll_data.title}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-url-"+t,name:"menu-item-url["+t+"]",value:"#pll_switcher"}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-pll-detect-"+t,name:"menu-item-pll-detect["+t+"]",value:1}),e(this).append(h),ids=Array("hide_if_no_translation","hide_current","force_home","show_flags","show_names","dropdown");for(var i=0,a=ids.length;i<a;i++)p=e("<p>").attr("class","description"),e(this).prepend(p),label=e("<label>").attr("for","edit-menu-item-"+ids[i]+"-"+t).text(" "+pll_data.strings[ids[i]]),p.append(label),cb=e("<input>").attr({type:"checkbox",id:"edit-menu-item-"+ids[i]+"-"+t,name:"menu-item-"+ids[i]+"["+t+"]",value:1}),(void 0!==pll_data.val[t]&&1==pll_data.val[t][ids[i]]||void 0===pll_data.val[t]&&"show_names"==ids[i])&&cb.prop("checked",!0),label.prepend(cb)})),e(".menu-item-data-object-id").each((function(){var t=e(this).val(),i=["names-","flags-"];e.each(i,(function(a,n){e("#edit-menu-item-show_"+n+t).on("change",(function(){1!=e(this).prop("checked")&&e("#edit-menu-item-show_"+i[1-a]+t).prop("checked",!0)}))}))})))}))}));
1
+ var __webpack_exports__={};jQuery((function(e){e("#update-nav-menu").on("click",(function(t){t.target&&t.target.className&&-1!=t.target.className.indexOf("item-edit")&&(e("input[value='#pll_switcher'][type=text]").parent().parent().parent().each((function(){var t=e(this).attr("id").substring(19);e(this).children("p:not( .field-move )").remove(),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-title-"+t,name:"menu-item-title["+t+"]",value:pll_data.title}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-url-"+t,name:"menu-item-url["+t+"]",value:"#pll_switcher"}),e(this).append(h),h=e("<input>").attr({type:"hidden",id:"edit-menu-item-pll-detect-"+t,name:"menu-item-pll-detect["+t+"]",value:1}),e(this).append(h),ids=Array("hide_if_no_translation","hide_current","force_home","show_flags","show_names","dropdown");for(var i=0,a=ids.length;i<a;i++)p=e("<p>").attr("class","description"),e(this).prepend(p),label=e("<label>").attr("for","edit-menu-item-"+ids[i]+"-"+t).text(" "+pll_data.strings[ids[i]]),p.append(label),cb=e("<input>").attr({type:"checkbox",id:"edit-menu-item-"+ids[i]+"-"+t,name:"menu-item-"+ids[i]+"["+t+"]",value:1}),(void 0!==pll_data.val[t]&&1==pll_data.val[t][ids[i]]||void 0===pll_data.val[t]&&"show_names"==ids[i])&&cb.prop("checked",!0),label.prepend(cb)})),e(".menu-item-data-object-id").each((function(){var t=e(this).val(),i=["names-","flags-"];e.each(i,(function(a,n){e("#edit-menu-item-show_"+n+t).on("change",(function(){1!=e(this).prop("checked")&&e("#edit-menu-item-show_"+i[1-a]+t).prop("checked",!0)}))}))})))}))}));
js/build/post.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * @package Polylang
3
  */
1
+ var __webpack_exports__ = {};
2
  /**
3
  * @package Polylang
4
  */
js/build/post.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)}))})),jQuery((function(a){a(document).on("DOMNodeInserted",(function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),s(o),i.on("change",(function(){l(a(this).val()),s(a(this).val())}))}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,(function(t,e){a.each(e,(function(e,i){a.each(i,(function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()}))}))}))}function s(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,(function(t,e){a.each(e,(function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()}))}))}}))})),jQuery((function(a){a(document).ajaxSuccess((function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each((function(){t.push(a(this).parent().parent().attr("id").substring(5))}));var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,(function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(t.responses,(function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)}))}));
1
+ var __webpack_exports__={};jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=ajax-tag-search")&&(lang=a(':input[name="inline_lang_choice"]').val())&&(n.data="lang="+lang+"&"+n.data)}))})),jQuery((function(a){a(document).on("DOMNodeInserted",(function(n){var t=a(n.target);if("inline-edit"==t.attr("id")){var e=t.prev().attr("id").replace("post-","");if(e>0){var i=t.find(':input[name="inline_lang_choice"]'),o=a("#lang_"+e).html();i.val(o),l(o),p(o),i.on("change",(function(){l(a(this).val()),p(a(this).val())}))}}function l(n){"undefined"!=typeof pll_term_languages&&a.each(pll_term_languages,(function(t,e){a.each(e,(function(e,i){a.each(i,(function(i){id="#"+e+"-"+pll_term_languages[t][e][i],n==t?a(id).show():a(id).hide()}))}))}))}function p(n){"undefined"!=typeof pll_page_languages&&a.each(pll_page_languages,(function(t,e){a.each(e,(function(e){v=a('#post_parent option[value="'+pll_page_languages[t][e]+'"]'),n==t?v.show():v.hide()}))}))}}))})),jQuery((function(a){a(document).ajaxSuccess((function(n,t,e){if("string"==typeof e.data){var i=wpAjax.unserialize(e.data);void 0!==i.action&&"inline-save"==i.action&&function(n){var t=new Array;a(".translation_"+n).each((function(){t.push(a(this).parent().parent().attr("id").substring(5))}));var e={action:"pll_update_post_rows",post_id:n,translations:t.join(","),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("input[name='_inline_edit']").val()};a.post(ajaxurl,e,(function(n){if(n){var t=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(t.responses,(function(){"row"==this.what&&a("#post-"+this.supplemental.post_id).replaceWith(this.data)}))}}))}(i.post_ID)}}))})),jQuery((function(a){a.ajaxPrefilter((function(n,t,e){"string"==typeof n.data&&-1!==n.data.indexOf("action=find_posts")&&(n.data="pll_post_id="+a("#affected").val()+"&"+n.data)}))}));
js/build/term.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * @package Polylang
3
  */
1
+ var __webpack_exports__ = {};
2
  /**
3
  * @package Polylang
4
  */
js/build/term.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(a){a(document).on("DOMNodeInserted",(function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i),e==a("#default_cat_"+e).html()&&l.prop("disabled",!0)}}}))})),jQuery((function(a){a(document).ajaxSuccess((function(t,n,e){function l(t){var n=new Array;a(".translation_"+t).each((function(){n.push(a(this).parent().parent().attr("id").substring(4))}));var e={action:"pll_update_term_rows",term_id:t,translations:n.join(","),taxonomy:a("input[name='taxonomy']").val(),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,e,(function(t){if(t){var n=wpAjax.parseAjaxResponse(t,"ajax-response");a.each(n.responses,(function(){"row"==this.what&&a("#tag-"+this.supplemental.term_id).replaceWith(this.data)}))}}))}var i=wpAjax.unserialize(e.data);if(void 0!==i.action)switch(i.action){case"add-tag":res=wpAjax.parseAjaxResponse(n.responseXML,"ajax-response"),a.each(res.responses,(function(){"term"==this.what&&l(this.supplemental.term_id)})),a(".htr_lang").val(0);break;case"delete-tag":l(i.tag_ID);break;case"inline-save-tax":l(i.tax_ID)}}))})),jQuery((function(a){function t(){a(".tr_lang").each((function(){var t=a(this).attr("id").substring(8),n=a(this).parent().parent().siblings(".pll-edit-column");a(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_terms_not_translated&term_language="+a("#term_lang_choice").val()+"&term_id="+a("input[name='tag_ID']").val()+"&taxonomy="+a("input[name='taxonomy']").val()+"&translation_language="+t+"&post_type="+typenow+"&_pll_nonce="+a("#_pll_nonce").val(),select:function(e,l){a("#htr_lang_"+t).val(l.item.id),n.html(l.item.link)}}),a(this).on("blur",(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))}))}))}t(),a("#term_lang_choice").on("change",(function(){var n=a(this).val(),e=a(this).children('option[value="'+n+'"]').attr("lang"),l=a('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),i={action:"term_lang_choice",lang:n,from_tag:a("input[name='from_tag']").val(),term_id:a("input[name='tag_ID']").val(),taxonomy:a("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,i,(function(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(e.responses,(function(){switch(this.what){case"translations":a("#term-translations").html(this.data),t();break;case"parent":a("#parent").replaceWith(this.data);break;case"tag_cloud":a(".tagcloud").replaceWith(this.data);break;case"flag":a(".pll-select-flag").html(this.data)}})),a("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)}))}))}));
1
+ var __webpack_exports__={};jQuery((function(a){a(document).on("DOMNodeInserted",(function(t){var n=a(t.target);if("inline-edit"==n.attr("id")){var e=n.prev().attr("id").replace("tag-","");if(e>0){var l=n.find(':input[name="inline_lang_choice"]'),i=a("#lang_"+e).html();l.val(i),e==a("#default_cat_"+e).html()&&l.prop("disabled",!0)}}}))})),jQuery((function(a){a(document).ajaxSuccess((function(t,n,e){function l(t){var n=new Array;a(".translation_"+t).each((function(){n.push(a(this).parent().parent().attr("id").substring(4))}));var e={action:"pll_update_term_rows",term_id:t,translations:n.join(","),taxonomy:a("input[name='taxonomy']").val(),post_type:a("input[name='post_type']").val(),screen:a("input[name='screen']").val(),_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,e,(function(t){if(t){var n=wpAjax.parseAjaxResponse(t,"ajax-response");a.each(n.responses,(function(){"row"==this.what&&a("#tag-"+this.supplemental.term_id).replaceWith(this.data)}))}}))}var i=wpAjax.unserialize(e.data);if(void 0!==i.action)switch(i.action){case"add-tag":res=wpAjax.parseAjaxResponse(n.responseXML,"ajax-response"),a.each(res.responses,(function(){"term"==this.what&&l(this.supplemental.term_id)})),a(".htr_lang").val(0);break;case"delete-tag":l(i.tag_ID);break;case"inline-save-tax":l(i.tax_ID)}}))})),jQuery((function(a){function t(){a(".tr_lang").each((function(){var t=a(this).attr("id").substring(8),n=a(this).parent().parent().siblings(".pll-edit-column");a(this).autocomplete({minLength:0,source:ajaxurl+"?action=pll_terms_not_translated&term_language="+a("#term_lang_choice").val()+"&term_id="+a("input[name='tag_ID']").val()+"&taxonomy="+a("input[name='taxonomy']").val()+"&translation_language="+t+"&post_type="+typenow+"&_pll_nonce="+a("#_pll_nonce").val(),select:function(e,l){a("#htr_lang_"+t).val(l.item.id),n.html(l.item.link)}}),a(this).on("blur",(function(){a(this).val()||(a("#htr_lang_"+t).val(0),n.html(n.siblings(".hidden").children().clone()))}))}))}t(),a("#term_lang_choice").on("change",(function(){var n=a(this).val(),e=a(this).children('option[value="'+n+'"]').attr("lang"),l=a('.pll-translation-column > span[lang="'+e+'"]').attr("dir"),i={action:"term_lang_choice",lang:n,from_tag:a("input[name='from_tag']").val(),term_id:a("input[name='tag_ID']").val(),taxonomy:a("input[name='taxonomy']").val(),post_type:typenow,_pll_nonce:a("#_pll_nonce").val()};a.post(ajaxurl,i,(function(n){var e=wpAjax.parseAjaxResponse(n,"ajax-response");a.each(e.responses,(function(){switch(this.what){case"translations":a("#term-translations").html(this.data),t();break;case"parent":a("#parent").replaceWith(this.data);break;case"tag_cloud":a(".tagcloud").replaceWith(this.data);break;case"flag":a(".pll-select-flag").html(this.data)}})),a("body").removeClass("pll-dir-rtl").removeClass("pll-dir-ltr").addClass("pll-dir-"+l)}))}))}));
js/build/user.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * Adds one biography input field per language in the user profile.
3
  *
1
+ var __webpack_exports__ = {};
2
  /**
3
  * Adds one biography input field per language in the user profile.
4
  *
js/build/user.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(e){var n=e("#description").parent(),i=e("#description").clone(),t=n.children(".description").clone();n.children().remove(),e(".biography").each((function(){lang=e(this).attr("name").split("___"),desc=i.clone(),desc.attr("name","description_"+lang[0]),desc.attr("id","description_"+lang[0]),desc.html(e(this).val()),n.append(e("<div></div>").text(lang[1])),n.append(desc)})),n.append("<br />"),n.append(t)}));
1
+ var __webpack_exports__={};jQuery((function(e){var n=e("#description").parent(),i=e("#description").clone(),t=n.children(".description").clone();n.children().remove(),e(".biography").each((function(){lang=e(this).attr("name").split("___"),desc=i.clone(),desc.attr("name","description_"+lang[0]),desc.attr("id","description_"+lang[0]),desc.html(e(this).val()),n.append(e("<div></div>").text(lang[1])),n.append(desc)})),n.append("<br />"),n.append(t)}));
js/build/widgets.js CHANGED
@@ -1,3 +1,4 @@
 
1
  /**
2
  * Adds a flag to the widgets filtered by a language.
3
  *
@@ -6,7 +7,10 @@
6
 
7
  jQuery(
8
  function( $ ) {
9
- var widgets_container, widgets_selector, flags;
 
 
 
10
 
11
  if ( 'undefined' !== typeof pll_widgets && pll_widgets.hasOwnProperty( 'flags' ) ) {
12
  flags = pll_widgets.flags;
@@ -23,7 +27,7 @@ jQuery(
23
  return;
24
  }
25
  widget = $( widget );
26
- var title = $( '.widget-top .widget-title h3', widget ),
27
  locale = $( '.pll-lang-choice option:selected', widget ).val(),
28
  // Icon is HTML built and come from server side and is well escaped when necessary
29
  icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
@@ -43,49 +47,65 @@ jQuery(
43
  }
44
  }
45
 
46
- if ( 'undefined' !== typeof wp.customize ) {
47
-
48
- widgets_container = $( '#customize-controls' );
49
- widgets_selector = '.customize-control .widget';
50
-
51
- /**
52
- * WP Customizer add control listener.
53
- *
54
- * @link https://wordpress.stackexchange.com/questions/256536/callback-after-wordpress-customizer-complete-loading
55
- *
56
- * @param {object} control The control type.
57
- * @return {void} Nothing.
58
- */
59
- function customize_add_flag( control ) {
60
- if ( ! control.extended( wp.customize.Widgets.WidgetControl ) ) {
61
- return;
62
- }
63
 
64
- /*
65
- * Make sure the widget's contents are embedded; normally this is done
66
- * when the control is expanded, for DOM performance reasons.
67
- */
68
- control.embedWidgetContent();
69
 
70
- // Now we know for sure the widget is fully embedded.
71
- add_flag( control.container.find( '.widget' ) );
72
- }
73
- wp.customize.control.each( customize_add_flag );
74
- wp.customize.control.bind( 'add', customize_add_flag );
 
 
 
75
 
76
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- widgets_container = $( '#widgets-right' );
79
- widgets_selector = '.widget';
 
 
 
80
 
81
- }
 
 
 
 
 
 
 
 
 
82
 
83
- // Add flags on load.
84
- $( widgets_selector, widgets_container ).each(
85
- function() {
86
- add_flag( this );
87
  }
88
- );
 
 
 
 
 
 
 
89
 
90
  // Update flags.
91
  widgets_container.on(
@@ -101,7 +121,7 @@ jQuery(
101
  }
102
 
103
  // Remove all options if dropdown is checked.
104
- $( '.widgets-sortables,.control-section-sidebar' ).on(
105
  'change',
106
  '.pll-dropdown',
107
  function() {
@@ -115,7 +135,7 @@ jQuery(
115
  $.each(
116
  options,
117
  function( i, v ) {
118
- $( '.widgets-sortables,.control-section-sidebar' ).on(
119
  'change',
120
  '.pll' + v,
121
  function() {
1
+ var __webpack_exports__ = {};
2
  /**
3
  * Adds a flag to the widgets filtered by a language.
4
  *
7
 
8
  jQuery(
9
  function( $ ) {
10
+ var widgets_container,
11
+ widgets_selector,
12
+ flags,
13
+ isBlockEditor = 'undefined' !== typeof wp.blockEditor;
14
 
15
  if ( 'undefined' !== typeof pll_widgets && pll_widgets.hasOwnProperty( 'flags' ) ) {
16
  flags = pll_widgets.flags;
27
  return;
28
  }
29
  widget = $( widget );
30
+ var title = isBlockEditor ? widget.prev('h3') : $( '.widget-top .widget-title h3', widget ),
31
  locale = $( '.pll-lang-choice option:selected', widget ).val(),
32
  // Icon is HTML built and come from server side and is well escaped when necessary
33
  icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
47
  }
48
  }
49
 
50
+ if ( isBlockEditor ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ widgets_container = $( '.edit-widgets-main-block-list' );
53
+ widgets_selector = '.widget';
 
 
 
54
 
55
+ // Update flags when we click on the legacy widget to display its form.
56
+ widgets_container.on(
57
+ 'click',
58
+ '.wp-block-legacy-widget',
59
+ function() {
60
+ add_flag( $( this ).find( '.widget' ) );
61
+ }
62
+ );
63
 
64
  } else {
65
+ if ( 'undefined' !== typeof wp.customize ) {
66
+
67
+ widgets_container = $( '#customize-controls' );
68
+ widgets_selector = '.customize-control .widget';
69
+
70
+ /**
71
+ * WP Customizer add control listener.
72
+ *
73
+ * @link https://wordpress.stackexchange.com/questions/256536/callback-after-wordpress-customizer-complete-loading
74
+ *
75
+ * @param {object} control The control type.
76
+ * @return {void} Nothing.
77
+ */
78
+ function customize_add_flag( control ) {
79
+ if ( ! control.extended( wp.customize.Widgets.WidgetControl ) ) {
80
+ return;
81
+ }
82
 
83
+ /*
84
+ * Make sure the widget's contents are embedded; normally this is done
85
+ * when the control is expanded, for DOM performance reasons.
86
+ */
87
+ control.embedWidgetContent();
88
 
89
+ // Now we know for sure the widget is fully embedded.
90
+ add_flag( control.container.find( '.widget' ) );
91
+ }
92
+ wp.customize.control.each( customize_add_flag );
93
+ wp.customize.control.bind( 'add', customize_add_flag );
94
+
95
+ } else {
96
+
97
+ widgets_container = $( '#widgets-right' );
98
+ widgets_selector = '.widget';
99
 
 
 
 
 
100
  }
101
+
102
+ // Add flags on load.
103
+ $( widgets_selector, widgets_container ).each(
104
+ function() {
105
+ add_flag( this );
106
+ }
107
+ );
108
+ }
109
 
110
  // Update flags.
111
  widgets_container.on(
121
  }
122
 
123
  // Remove all options if dropdown is checked.
124
+ $( '.widgets-sortables,.control-section-sidebar,.edit-widgets-main-block-list' ).on(
125
  'change',
126
  '.pll-dropdown',
127
  function() {
135
  $.each(
136
  options,
137
  function( i, v ) {
138
+ $( '.widgets-sortables,.control-section-sidebar,.edit-widgets-main-block-list' ).on(
139
  'change',
140
  '.pll' + v,
141
  function() {
js/build/widgets.min.js CHANGED
@@ -1 +1 @@
1
- jQuery((function(e){var t,n,i;function o(t){if(i){t=e(t);var n=e(".widget-top .widget-title h3",t),o=e(".pll-lang-choice option:selected",t).val(),l=o&&i.hasOwnProperty(o)?i[o]:null;if(l){l+=" &nbsp; ";var a=e(".pll-lang",n);a.length?a.html(l):(flag=e("<span />").addClass("pll-lang").html(l),n.prepend(flag))}else e(".pll-lang",n).remove()}}if("undefined"!=typeof pll_widgets&&pll_widgets.hasOwnProperty("flags")&&(i=pll_widgets.flags),void 0!==wp.customize){function l(e){e.extended(wp.customize.Widgets.WidgetControl)&&(e.embedWidgetContent(),o(e.container.find(".widget")))}t=e("#customize-controls"),n=".customize-control .widget",wp.customize.control.each(l),wp.customize.control.bind("add",l)}else t=e("#widgets-right"),n=".widget";e(n,t).each((function(){o(this)})),t.on("change",".pll-lang-choice",(function(){o(e(this).parents(".widget"))})),e(".widgets-sortables,.control-section-sidebar").on("change",".pll-dropdown",(function(){var t,n=e(this).parent().parent().parent().children(".widget-id").attr("value");t=e(".no-dropdown-"+n),1!=e(this).prop("checked")?t.show():t.hide()}));var a=["-show_flags","-show_names"];e.each(a,(function(t,n){e(".widgets-sortables,.control-section-sidebar").on("change",".pll"+n,(function(){var n=e(this).parent().parent().parent().children(".widget-id").attr("value");1!=e(this).prop("checked")&&e("#widget-"+n+a[1-t]).prop("checked",!0)}))}))}));
1
+ var __webpack_exports__={};jQuery((function(e){var t,i,n,o=void 0!==wp.blockEditor;function l(t){if(n){t=e(t);var i=o?t.prev("h3"):e(".widget-top .widget-title h3",t),l=e(".pll-lang-choice option:selected",t).val(),d=l&&n.hasOwnProperty(l)?n[l]:null;if(d){d+=" &nbsp; ";var s=e(".pll-lang",i);s.length?s.html(d):(flag=e("<span />").addClass("pll-lang").html(d),i.prepend(flag))}else e(".pll-lang",i).remove()}}if("undefined"!=typeof pll_widgets&&pll_widgets.hasOwnProperty("flags")&&(n=pll_widgets.flags),o)i=".widget",(t=e(".edit-widgets-main-block-list")).on("click",".wp-block-legacy-widget",(function(){l(e(this).find(".widget"))}));else{if(void 0!==wp.customize){function d(e){e.extended(wp.customize.Widgets.WidgetControl)&&(e.embedWidgetContent(),l(e.container.find(".widget")))}t=e("#customize-controls"),i=".customize-control .widget",wp.customize.control.each(d),wp.customize.control.bind("add",d)}else t=e("#widgets-right"),i=".widget";e(i,t).each((function(){l(this)}))}t.on("change",".pll-lang-choice",(function(){l(e(this).parents(".widget"))})),e(".widgets-sortables,.control-section-sidebar,.edit-widgets-main-block-list").on("change",".pll-dropdown",(function(){var t,i=e(this).parent().parent().parent().children(".widget-id").attr("value");t=e(".no-dropdown-"+i),1!=e(this).prop("checked")?t.show():t.hide()}));var s=["-show_flags","-show_names"];e.each(s,(function(t,i){e(".widgets-sortables,.control-section-sidebar,.edit-widgets-main-block-list").on("change",".pll"+i,(function(){var i=e(this).parent().parent().parent().children(".widget-id").attr("value");1!=e(this).prop("checked")&&e("#widget-"+i+s[1-t]).prop("checked",!0)}))}))}));
js/classic-editor.js DELETED
@@ -1,341 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- import {
6
- initializeLanguageOldValue,
7
- initializeConfimationModal
8
- } from './lib/confirmation-modal';
9
-
10
- // tag suggest in metabox
11
- jQuery(
12
- function( $ ) {
13
- $.ajaxPrefilter(
14
- function( options, originalOptions, jqXHR ) {
15
- var lang = $( '.post_lang_choice' ).val();
16
- if ( 'string' === typeof options.data && -1 !== options.url.indexOf( 'action=ajax-tag-search' ) && lang ) {
17
- options.data = 'lang=' + lang + '&' + options.data;
18
- }
19
- }
20
- );
21
- }
22
- );
23
-
24
- // overrides tagBox.get
25
- jQuery(
26
- function( $ ) {
27
- // overrides function to add the language
28
- tagBox.get = function( id ) {
29
- var tax = id.substr( id.indexOf( '-' ) + 1 );
30
-
31
- // add the language in the $_POST variable
32
- var data = {
33
- action: 'get-tagcloud',
34
- lang: $( '.post_lang_choice' ).val(),
35
- tax: tax
36
- }
37
-
38
- $.post(
39
- ajaxurl,
40
- data,
41
- function( r, stat ) {
42
- if ( 0 == r || 'success' != stat ) {
43
- r = wpAjax.broken;
44
- }
45
-
46
- // @see code from WordPress core https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/js/tags-box.js#L291
47
- // @see wp_generate_tag_cloud function which generate the escaped HTML https://github.com/WordPress/WordPress/blob/a02b5cc2a8eecb8e076fbb7cf4de7bd2ec8a8eb1/wp-includes/category-template.php#L966-L975
48
- r = $( '<div />' ).addClass( 'the-tagcloud' ).attr( 'id', 'tagcloud-' + tax ).html( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
49
- $( 'a', r ).on(
50
- 'click',
51
- function(){
52
- tagBox.flushTags( $( this ).closest( '.inside' ).children( '.tagsdiv' ), this );
53
- return false;
54
- }
55
- );
56
-
57
- var tagCloud = $( '#tagcloud-' + tax );
58
- // add an if else condition to allow modifying the tags outputed when switching the language
59
- var v = tagCloud.css( 'display' );
60
- if ( v ) {
61
- // See the comment above when r variable is created.
62
- $( '#tagcloud-' + tax ).replaceWith( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
63
- $( '#tagcloud-' + tax ).css( 'display', v );
64
- }
65
- else {
66
- // See the comment above when r variable is created.
67
- $( '#' + id ).after( r ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
68
- }
69
- }
70
- );
71
- }
72
- }
73
- );
74
-
75
- jQuery(
76
- function( $ ) {
77
- // collect taxonomies - code partly copied from WordPress
78
- var taxonomies = new Array();
79
- $( '.categorydiv' ).each(
80
- function(){
81
- var this_id = $( this ).attr( 'id' ), taxonomyParts, taxonomy;
82
-
83
- taxonomyParts = this_id.split( '-' );
84
- taxonomyParts.shift();
85
- taxonomy = taxonomyParts.join( '-' );
86
- taxonomies.push( taxonomy ); // store the taxonomy for future use
87
-
88
- // add our hidden field in the new category form - for each hierarchical taxonomy
89
- // to set the language when creating a new category
90
- // html code inserted come from html code itself.
91
- $( '#' + taxonomy + '-add-submit' ).before( // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.before
92
- $( '<input />' ).attr( 'type', 'hidden' )
93
- .attr( 'id', taxonomy + '-lang' )
94
- .attr( 'name', 'term_lang_choice' )
95
- .attr( 'value', $( '.post_lang_choice' ).val() )
96
- );
97
- }
98
- );
99
-
100
- // Initialize current language to be able to compare if it changes.
101
- initializeLanguageOldValue();
102
-
103
- // ajax for changing the post's language in the languages metabox
104
- $( '.post_lang_choice' ).on(
105
- 'change',
106
- function( event ) {
107
- // Initialize the confirmation dialog box.
108
- const confirmationModal = initializeConfimationModal();
109
- const { dialogContainer: dialog } = confirmationModal;
110
- let { dialogResult } = confirmationModal;
111
- // The selected option in the dropdown list.
112
- const selectedOption = event.target;
113
-
114
- if ( $( this ).data( 'old-value' ) !== selectedOption.value && ! isEmptyPost() ) {
115
- dialog.dialog( 'open' );
116
- } else {
117
- dialogResult = Promise.resolve();
118
- }
119
-
120
- // phpcs:disable PEAR.Functions.FunctionCallSignature.EmptyLine
121
- dialogResult.then(
122
- () => {
123
- var lang = selectedOption.options[selectedOption.options.selectedIndex].lang; // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
124
- var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
125
-
126
- var data = { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
127
- action: 'post_lang_choice',
128
- lang: selectedOption.value,
129
- post_type: $( '#post_type' ).val(),
130
- taxonomies: taxonomies,
131
- post_id: $( '#post_ID' ).val(),
132
- _pll_nonce: $( '#_pll_nonce' ).val()
133
- }
134
-
135
- $.post(
136
- ajaxurl,
137
- data,
138
- function( response ) {
139
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
140
- $.each(
141
- res.responses,
142
- function() {
143
- switch ( this.what ) {
144
- case 'translations': // translations fields
145
- // Data is built and come from server side and is well escaped when necessary
146
- $( '.translations' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
147
- init_translations();
148
- break;
149
- case 'taxonomy': // categories metabox for posts
150
- var tax = this.data;
151
- // @see wp_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L175
152
- // @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/class-walker-category-checklist.php#L89-L111
153
- $( '#' + tax + 'checklist' ).html( this.supplemental.all ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
154
- // @see wp_popular_terms_checklist https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/template.php#L236
155
- $( '#' + tax + 'checklist-pop' ).html( this.supplemental.populars ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
156
- // @see wp_dropdown_categories https://github.com/WordPress/WordPress/blob/5.5.1/wp-includes/category-template.php#L336
157
- // which is called by PLL_Admin_Classic_Editor::post_lang_choice to generate supplemental.dropdown
158
- $( '#new' + tax + '_parent' ).replaceWith( this.supplemental.dropdown ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
159
- $( '#' + tax + '-lang' ).val( $( '.post_lang_choice' ).val() ); // hidden field
160
- break;
161
- case 'pages': // parent dropdown list for pages
162
- // @see wp_dropdown_pages https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/post-template.php#L1186-L1208
163
- // @see https://github.com/WordPress/WordPress/blob/5.2.2/wp-includes/class-walker-page-dropdown.php#L88
164
- $( '#parent_id' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
165
- break;
166
- case 'flag': // flag in front of the select dropdown
167
- // Data is built and come from server side and is well escaped when necessary
168
- $( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
169
- break;
170
- case 'permalink': // Sample permalink
171
- var div = $( '#edit-slug-box' );
172
- if ( '-1' != this.data && div.children().length ) {
173
- // @see get_sample_permalink_html https://github.com/WordPress/WordPress/blob/5.2.2/wp-admin/includes/post.php#L1425-L1454
174
- div.html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
175
- }
176
- break;
177
- }
178
- }
179
- );
180
-
181
- // Update the old language with the new one to be able to compare it in the next changing.
182
- initializeLanguageOldValue();
183
- // modifies the language in the tag cloud
184
- $( '.tagcloud-link' ).each(
185
- function() {
186
- var id = $( this ).attr( 'id' );
187
- tagBox.get( id );
188
- }
189
- );
190
-
191
- // Modifies the text direction
192
- $( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
193
- $( '#content_ifr' ).contents().find( 'html' ).attr( 'lang', lang ).attr( 'dir', dir );
194
- $( '#content_ifr' ).contents().find( 'body' ).attr( 'dir', dir );
195
-
196
- pll.media.resetAllAttachmentsCollections();
197
- }
198
- )
199
- },
200
- () => {} // Do nothing when promise is rejected by clicking the Cancel dialog button.
201
- );
202
- // phpcs:enable PEAR.Functions.FunctionCallSignature.EmptyLine
203
-
204
- function isEmptyPost() {
205
- const title = $( 'input#title' ).val();
206
- const content = $( 'textarea#content' ).val();
207
- const excerpt = $( 'textarea#excerpt' ).val();
208
-
209
- return ! title && ! content && ! excerpt;
210
- }
211
- }
212
- );
213
-
214
- // translations autocomplete input box
215
- function init_translations() {
216
- $( '.tr_lang' ).each(
217
- function(){
218
- var tr_lang = $( this ).attr( 'id' ).substring( 8 );
219
- var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
220
-
221
- $( this ).autocomplete(
222
- {
223
- minLength: 0,
224
- source: ajaxurl + '?action=pll_posts_not_translated' +
225
- '&post_language=' + $( '.post_lang_choice' ).val() +
226
- '&translation_language=' + tr_lang +
227
- '&post_type=' + $( '#post_type' ).val() +
228
- '&_pll_nonce=' + $( '#_pll_nonce' ).val(),
229
- select: function( event, ui ) {
230
- $( '#htr_lang_' + tr_lang ).val( ui.item.id );
231
- // ui.item.link is built and come from server side and is well escaped when necessary
232
- td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
233
- },
234
- }
235
- );
236
-
237
- // when the input box is emptied
238
- $( this ).on(
239
- 'blur',
240
- function() {
241
- if ( ! $( this ).val() ) {
242
- $( '#htr_lang_' + tr_lang ).val( 0 );
243
- // Value is retrieved from HTML already generated server side
244
- td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
245
- }
246
- }
247
- );
248
- }
249
- );
250
- }
251
-
252
- init_translations();
253
- }
254
- );
255
-
256
- /**
257
- * @since 3.0
258
- *
259
- * @namespace pll
260
- */
261
- var pll = window.pll || {};
262
-
263
- /**
264
- * @since 3.0
265
- *
266
- * @namespace pll.media
267
- */
268
- _.extend( pll, { media: {} } );
269
-
270
- /**
271
- * @since 3.0
272
- *
273
- * @alias pll.media
274
- * @memberOf pll
275
- * @namespace
276
- */
277
- var media = _.extend(
278
- pll.media, /** @lends pll.media.prototype */
279
- {
280
- /**
281
- * TODO: Find a way to delete references to Attachments collections that are not used anywhere else.
282
- *
283
- * @type {wp.media.model.Attachments}
284
- */
285
- attachmentsCollections : [],
286
-
287
- /**
288
- * Imitates { @see wp.media.query } but log all Attachments collections created.
289
- *
290
- * @param {Object} [props]
291
- * @return {wp.media.model.Attachments}
292
- */
293
- query: function( props ) {
294
- var attachments = pll.media.query.delegate( props );
295
-
296
- pll.media.attachmentsCollections.push( attachments );
297
-
298
- return attachments;
299
- },
300
-
301
- resetAllAttachmentsCollections: function() {
302
- this.attachmentsCollections.forEach(
303
- function( attachmentsCollection ) {
304
- /**
305
- * First reset the { @see wp.media.model.Attachments } collection.
306
- * Then, if it is mirroring a { @see wp.media.model.Query } collection,
307
- * refresh this one too, so it will fetch new data from the server,
308
- * and then the wp.media.model.Attachments collection will syncrhonize with the new data.
309
- */
310
- attachmentsCollection.reset();
311
- if (attachmentsCollection.mirroring) {
312
- attachmentsCollection.mirroring._hasMore = true;
313
- attachmentsCollection.mirroring.reset();
314
- }
315
- }
316
- );
317
- }
318
- }
319
- );
320
-
321
- if ( 'undefined' !== typeof wp && 'undefined' !== typeof wp.media ) {
322
-
323
- /**
324
- * @since 3.0
325
- *
326
- * @memberOf pll.media
327
- */
328
- media.query = _.extend(
329
- media.query, /** @lends pll.media.query prototype */
330
- {
331
- /**
332
- * @type Function References WordPress { @see wp.media.query } constructor
333
- */
334
- delegate: wp.media.query
335
- }
336
- )
337
-
338
- // Substitute WordPress media query shortcut with our decorated function.
339
- wp.media.query = media.query
340
-
341
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/lib/confirmation-modal.js DELETED
@@ -1,99 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- const languagesList = jQuery( '.post_lang_choice' );
6
-
7
- // Dialog box for alerting the user about a risky changing.
8
- export const initializeConfimationModal = () => {
9
- // We can't use underscore or lodash in this common code because it depends of the context classic or block editor.
10
- // Classic editor underscore is loaded, Block editor lodash is loaded.
11
- const { __ } = wp.i18n;
12
-
13
- // Create dialog container.
14
- const dialogContainer = jQuery(
15
- '<div/>',
16
- {
17
- id: 'pll-dialog',
18
- style: 'display:none;'
19
- }
20
- ).text( __( 'Are you sure you want to change the language of the current content?', 'polylang' ) );
21
-
22
- // Put it after languages list dropdown.
23
- // PHPCS ignore dialogContainer is a new safe HTML code generated above.
24
- languagesList.after( dialogContainer ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.after
25
-
26
- const dialogResult = new Promise(
27
- ( confirm, cancel ) => {
28
- const confirmDialog = ( what ) => { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
29
- switch ( what ) { // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
30
- case 'yes':
31
- // Confirm the new language.
32
- languagesList.data( 'old-value', languagesList.children( ':selected' ).first().val() );
33
- confirm();
34
- break;
35
- case 'no':
36
- // Revert to the old language.
37
- languagesList.val( languagesList.data( 'old-value' ) );
38
- cancel( 'Cancel' );
39
- break;
40
- }
41
- dialogContainer.dialog( 'close' ); // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
42
- } // phpcs:ignore PEAR.Functions.FunctionCallSignature.Indent
43
-
44
- // Initialize dialog box in the case a language is selected but not added in the list.
45
- const dialogOptions = {
46
- autoOpen: false,
47
- modal: true,
48
- draggable: false,
49
- resizable: false,
50
- title: __( 'Change language', 'polylang' ),
51
- minWidth: 600,
52
- maxWidth: '100%',
53
- open: function( event, ui ) {
54
- // Change dialog box position for rtl language
55
- if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
56
- jQuery( this ).parent().css(
57
- {
58
- right: jQuery( this ).parent().css( 'left' ),
59
- left: 'auto'
60
- }
61
- );
62
- }
63
- },
64
- close: function( event, ui ) {
65
- // When we're closing the dialog box we need to cancel the language change as we click on Cancel button.
66
- confirmDialog( 'no' );
67
- },
68
- buttons: [
69
- {
70
- text: __( 'OK', 'polylang' ),
71
- click: function( event ) {
72
- confirmDialog( 'yes' );
73
- }
74
- },
75
- {
76
- text: __( 'Cancel', 'polylang' ),
77
- click: function( event ) {
78
- confirmDialog( 'no' );
79
- }
80
- }
81
- ]
82
- };
83
-
84
- if ( jQuery.ui.version >= '1.12.0' ) {
85
- Object.assign( dialogOptions, { classes: { 'ui-dialog': 'pll-confirmation-modal' } } );
86
- } else {
87
- Object.assign( dialogOptions, { dialogClass: 'pll-confirmation-modal' } ); // jQuery UI 1.11.4 - WP < 5.6
88
- }
89
-
90
- dialogContainer.dialog( dialogOptions );
91
- }
92
- );
93
- return { dialogContainer, dialogResult };
94
- }
95
-
96
- export const initializeLanguageOldValue = () => {
97
- // Keep the old language value to be able to compare to the new one and revert to it if necessary.
98
- languagesList.attr( 'data-old-value', languagesList.children( ':selected' ).first().val() );
99
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/nav-menu.js DELETED
@@ -1,104 +0,0 @@
1
- /**
2
- * Handles the options in the language switcher nav menu metabox.
3
- *
4
- * @package Polylang
5
- */
6
-
7
- jQuery(
8
- function( $ ) {
9
- $( '#update-nav-menu' ).on(
10
- 'click',
11
- function( e ) {
12
- if ( e.target && e.target.className && -1 != e.target.className.indexOf( 'item-edit' ) ) {
13
- $( "input[value='#pll_switcher'][type=text]" ).parent().parent().parent().each(
14
- function(){
15
- var item = $( this ).attr( 'id' ).substring( 19 );
16
- $( this ).children( 'p:not( .field-move )' ).remove(); // remove default fields we don't need
17
-
18
- // item is a number part of id of parent menu item built by WordPress
19
- // pll_data is built server side with i18n strings without HTML and data retrieved from post meta
20
- // the usage of attr method is safe before append call.
21
- h = $( '<input>' ).attr(
22
- {
23
- type: 'hidden',
24
- id: 'edit-menu-item-title-' + item,
25
- name: 'menu-item-title[' + item + ']',
26
- value: pll_data.title
27
- }
28
- );
29
- $( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
30
-
31
- h = $( '<input>' ).attr(
32
- {
33
- type: 'hidden',
34
- id: 'edit-menu-item-url-' + item,
35
- name: 'menu-item-url[' + item + ']',
36
- value: '#pll_switcher'
37
- }
38
- );
39
- $( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
40
-
41
- // a hidden field which exits only if our jQuery code has been executed
42
- h = $( '<input>' ).attr(
43
- {
44
- type: 'hidden',
45
- id: 'edit-menu-item-pll-detect-' + item,
46
- name: 'menu-item-pll-detect[' + item + ']',
47
- value: 1
48
- }
49
- );
50
- $( this ).append( h ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
51
-
52
- ids = Array( 'hide_if_no_translation', 'hide_current', 'force_home', 'show_flags', 'show_names', 'dropdown' ); // reverse order
53
-
54
- // add the fields
55
- for ( var i = 0, idsLength = ids.length; i < idsLength; i++ ) {
56
- p = $( '<p>' ).attr( 'class', 'description' );
57
- // p is hardcoded just above by using attr method which is safe.
58
- $( this ).prepend( p ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
59
- // item is a number part of id of parent menu item built by WordPress
60
- // pll_data is built server side with i18n strings without HTML
61
- label = $( '<label>' ).attr( 'for', 'edit-menu-item-' + ids[ i ] + '-' + item ).text( ' ' + pll_data.strings[ ids[ i ] ] );
62
- p.append( label ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
63
- cb = $( '<input>' ).attr(
64
- {
65
- type: 'checkbox',
66
- id: 'edit-menu-item-' + ids[ i ] + '-' + item,
67
- name: 'menu-item-' + ids[ i ] + '[' + item + ']',
68
- value: 1
69
- }
70
- );
71
- if ( ( typeof( pll_data.val[ item ] ) != 'undefined' && pll_data.val[ item ][ ids[ i ] ] == 1 ) || ( typeof( pll_data.val[ item ] ) == 'undefined' && ids[ i ] == 'show_names' ) ) { // show_names as default value
72
- cb.prop( 'checked', true );
73
- }
74
- // See reasons above. Checkbox are totaly hardcoded here with safe value
75
- label.prepend( cb ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
76
- }
77
- }
78
- );
79
-
80
- // disallow unchecking both show names and show flags
81
- $( '.menu-item-data-object-id' ).each(
82
- function() {
83
- var id = $( this ).val();
84
- var options = ['names-', 'flags-'];
85
- $.each(
86
- options,
87
- function( i, v ) {
88
- $( '#edit-menu-item-show_' + v + id ).on(
89
- 'change',
90
- function() {
91
- if ( true != $( this ).prop( 'checked' ) ) {
92
- $( '#edit-menu-item-show_' + options[ 1 - i ] + id ).prop( 'checked', true );
93
- }
94
- }
95
- );
96
- }
97
- );
98
- }
99
- );
100
- }
101
- }
102
- );
103
- }
104
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/post.js DELETED
@@ -1,177 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- /**
6
- * Tag suggest in quick edit
7
- */
8
- jQuery(
9
- function( $ ) {
10
- $.ajaxPrefilter(
11
- function( options, originalOptions, jqXHR ) {
12
- if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=ajax-tag-search' ) && ( lang = $( ':input[name="inline_lang_choice"]' ).val() ) ) {
13
- options.data = 'lang=' + lang + '&' + options.data;
14
- }
15
- }
16
- );
17
- }
18
- );
19
-
20
- /**
21
- * Quick edit
22
- */
23
- jQuery(
24
- function( $ ) {
25
- $( document ).on(
26
- 'DOMNodeInserted',
27
- function( e ) {
28
- var t = $( e.target );
29
-
30
- // WP inserts the quick edit from
31
- if ( 'inline-edit' == t.attr( 'id' ) ) {
32
- var post_id = t.prev().attr( 'id' ).replace( "post-", "" );
33
-
34
- if ( post_id > 0 ) {
35
- // language dropdown
36
- var select = t.find( ':input[name="inline_lang_choice"]' );
37
- var lang = $( '#lang_' + post_id ).html();
38
- select.val( lang ); // populates the dropdown
39
-
40
- filter_terms( lang ); // initial filter for category checklist
41
- filter_pages( lang ); // initial filter for parent dropdown
42
-
43
- // modify category checklist an parent dropdown on language change
44
- select.on(
45
- 'change',
46
- function() {
47
- filter_terms( $( this ).val() );
48
- filter_pages( $( this ).val() );
49
- }
50
- );
51
- }
52
- }
53
-
54
- /**
55
- * Filters the category checklist.
56
- */
57
- function filter_terms( lang ) {
58
- if ( "undefined" != typeof( pll_term_languages ) ) {
59
- $.each(
60
- pll_term_languages,
61
- function( lg, term_tax ) {
62
- $.each(
63
- term_tax,
64
- function( tax, terms ) {
65
- $.each(
66
- terms,
67
- function( i ) {
68
- id = '#' + tax + '-' + pll_term_languages[ lg ][ tax ][ i ];
69
- lang == lg ? $( id ).show() : $( id ).hide();
70
- }
71
- );
72
- }
73
- );
74
- }
75
- );
76
- }
77
- }
78
-
79
- /**
80
- * Filters the parent page dropdown list.
81
- */
82
- function filter_pages( lang ) {
83
- if ( "undefined" != typeof( pll_page_languages ) ) {
84
- $.each(
85
- pll_page_languages,
86
- function( lg, pages ) {
87
- $.each(
88
- pages,
89
- function( i ) {
90
- v = $( '#post_parent option[value="' + pll_page_languages[ lg ][ i ] + '"]' );
91
- lang == lg ? v.show() : v.hide();
92
- }
93
- );
94
- }
95
- );
96
- }
97
- }
98
- }
99
- );
100
- }
101
- );
102
-
103
- /**
104
- * Update rows of translated posts when the language is modified in quick edit
105
- * Acts on ajaxSuccess event
106
- */
107
- jQuery(
108
- function( $ ) {
109
- $( document ).ajaxSuccess(
110
- function( event, xhr, settings ) {
111
- function update_rows( post_id ) {
112
- // collect old translations
113
- var translations = new Array();
114
- $( '.translation_' + post_id ).each(
115
- function() {
116
- translations.push( $( this ).parent().parent().attr( 'id' ).substring( 5 ) );
117
- }
118
- );
119
-
120
- var data = {
121
- action: 'pll_update_post_rows',
122
- post_id: post_id,
123
- translations: translations.join( ',' ),
124
- post_type: $( "input[name='post_type']" ).val(),
125
- screen: $( "input[name='screen']" ).val(),
126
- _pll_nonce: $( "input[name='_inline_edit']" ).val() // reuse quick edit nonce
127
- };
128
-
129
- // get the modified rows in ajax and update them
130
- $.post(
131
- ajaxurl,
132
- data,
133
- function( response ) {
134
- if ( response ) {
135
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
136
- $.each(
137
- res.responses,
138
- function() {
139
- if ( 'row' == this.what ) {
140
- // data is built with a call to WP_Posts_List_Table::single_row method
141
- // which uses internally other WordPress methods which escape correctly values.
142
- // For Polylang language columns the HTML code is correctly escaped in PLL_Admin_Filters_Columns::post_column method.
143
- $( "#post-" + this.supplemental.post_id ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
144
- }
145
- }
146
- );
147
- }
148
- }
149
- );
150
- }
151
-
152
- if ( 'string' == typeof( settings.data ) ) { // Need to check the type due to block editor sometime sending FormData objects
153
- var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
154
- if ( 'undefined' != typeof( data['action'] ) && 'inline-save' == data['action'] ) {
155
- update_rows( data['post_ID'] );
156
- }
157
- }
158
- }
159
- );
160
- }
161
- );
162
-
163
- /**
164
- * Media list table
165
- * When clicking on attach link, filters find post list per media language
166
- */
167
- jQuery(
168
- function( $ ) {
169
- $.ajaxPrefilter(
170
- function ( options, originalOptions, jqXHR ) {
171
- if ( 'string' === typeof options.data && -1 !== options.data.indexOf( 'action=find_posts' ) ) {
172
- options.data = 'pll_post_id=' + $( '#affected' ).val() + '&' + options.data;
173
- }
174
- }
175
- );
176
- }
177
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/term.js DELETED
@@ -1,221 +0,0 @@
1
- /**
2
- * @package Polylang
3
- */
4
-
5
- /**
6
- * Quick edit
7
- */
8
- jQuery(
9
- function( $ ) {
10
- $( document ).on(
11
- 'DOMNodeInserted',
12
- function( e ) {
13
- var t = $( e.target );
14
-
15
- // WP inserts the quick edit from
16
- if ( 'inline-edit' == t.attr( 'id' ) ) {
17
- var term_id = t.prev().attr( 'id' ).replace( "tag-", "" );
18
-
19
- if ( term_id > 0 ) {
20
- // language dropdown
21
- var select = t.find( ':input[name="inline_lang_choice"]' );
22
- var lang = $( '#lang_' + term_id ).html();
23
- select.val( lang ); // populates the dropdown
24
-
25
- // disable the language dropdown for default categories
26
- var default_cat = $( '#default_cat_' + term_id ).html();
27
- if ( term_id == default_cat ) {
28
- select.prop( 'disabled', true );
29
- }
30
- }
31
- }
32
- }
33
- );
34
- }
35
- );
36
-
37
- /**
38
- * Update rows of translated terms when adding / deleting a translation or when the language is modified in quick edit.
39
- * Acts on ajaxSuccess event.
40
- */
41
- jQuery(
42
- function( $ ) {
43
- $( document ).ajaxSuccess(
44
- function( event, xhr, settings ) {
45
- function update_rows( term_id ) {
46
- // collect old translations
47
- var translations = new Array();
48
- $( '.translation_' + term_id ).each(
49
- function() {
50
- translations.push( $( this ).parent().parent().attr( 'id' ).substring( 4 ) );
51
- }
52
- );
53
-
54
- var data = {
55
- action: 'pll_update_term_rows',
56
- term_id: term_id,
57
- translations: translations.join( ',' ),
58
- taxonomy: $( "input[name='taxonomy']" ).val(),
59
- post_type: $( "input[name='post_type']" ).val(),
60
- screen: $( "input[name='screen']" ).val(),
61
- _pll_nonce: $( '#_pll_nonce' ).val()
62
- };
63
-
64
- // get the modified rows in ajax and update them
65
- $.post(
66
- ajaxurl,
67
- data,
68
- function( response ) {
69
- if ( response ) {
70
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
71
- $.each(
72
- res.responses,
73
- function() {
74
- if ( 'row' == this.what ) {
75
- // data is built with a call to WP_Terms_List_Table::single_row method
76
- // which uses internally other WordPress methods which escape correctly values.
77
- // For Polylang language columns the HTML code is correctly escaped in PLL_Admin_Filters_Columns::term_column method.
78
- $( "#tag-" + this.supplemental.term_id ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
79
- }
80
- }
81
- );
82
- }
83
- }
84
- );
85
- }
86
-
87
- var data = wpAjax.unserialize( settings.data ); // what were the data sent by the ajax request?
88
- if ( 'undefined' != typeof( data['action'] ) ) {
89
- switch ( data['action'] ) {
90
- // when adding a term, the new term_id is in the ajax response
91
- case 'add-tag':
92
- res = wpAjax.parseAjaxResponse( xhr.responseXML, 'ajax-response' );
93
- $.each(
94
- res.responses,
95
- function() {
96
- if ( 'term' == this.what ) {
97
- update_rows( this.supplemental.term_id );
98
- }
99
- }
100
- );
101
-
102
- // and also reset translations hidden input fields
103
- $( '.htr_lang' ).val( 0 );
104
- break;
105
-
106
- // when deleting a term
107
- case 'delete-tag':
108
- update_rows( data['tag_ID'] );
109
- break;
110
-
111
- // in case the language is modified in quick edit and breaks translations
112
- case 'inline-save-tax':
113
- update_rows( data['tax_ID'] );
114
- break;
115
- }
116
- }
117
- }
118
- );
119
- }
120
- );
121
-
122
- jQuery(
123
- function( $ ) {
124
- // translations autocomplete input box
125
- function init_translations() {
126
- $( '.tr_lang' ).each(
127
- function(){
128
- var tr_lang = $( this ).attr( 'id' ).substring( 8 );
129
- var td = $( this ).parent().parent().siblings( '.pll-edit-column' );
130
-
131
- $( this ).autocomplete(
132
- {
133
- minLength: 0,
134
- source: ajaxurl + '?action=pll_terms_not_translated' +
135
- '&term_language=' + $( '#term_lang_choice' ).val() +
136
- '&term_id=' + $( "input[name='tag_ID']" ).val() +
137
- '&taxonomy=' + $( "input[name='taxonomy']" ).val() +
138
- '&translation_language=' + tr_lang +
139
- '&post_type=' + typenow +
140
- '&_pll_nonce=' + $( '#_pll_nonce' ).val(),
141
- select: function( event, ui ) {
142
- $( '#htr_lang_' + tr_lang ).val( ui.item.id );
143
- // ui.item.link is built and come from server side and is well escaped when necessary
144
- td.html( ui.item.link ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
145
- },
146
- }
147
- );
148
-
149
- // when the input box is emptied
150
- $( this ).on(
151
- 'blur',
152
- function() {
153
- if ( ! $( this ).val() ) {
154
- $( '#htr_lang_' + tr_lang ).val( 0 );
155
- // Value is retrieved from HTML already generated server side
156
- td.html( td.siblings( '.hidden' ).children().clone() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
157
- }
158
- }
159
- );
160
- }
161
- );
162
- }
163
-
164
- init_translations();
165
-
166
- // ajax for changing the term's language
167
- $( '#term_lang_choice' ).on(
168
- 'change',
169
- function() {
170
- var value = $( this ).val();
171
- var lang = $( this ).children( 'option[value="' + value + '"]' ).attr( 'lang' );
172
- var dir = $( '.pll-translation-column > span[lang="' + lang + '"]' ).attr( 'dir' );
173
-
174
- var data = {
175
- action: 'term_lang_choice',
176
- lang: value,
177
- from_tag: $( "input[name='from_tag']" ).val(),
178
- term_id: $( "input[name='tag_ID']" ).val(),
179
- taxonomy: $( "input[name='taxonomy']" ).val(),
180
- post_type: typenow,
181
- _pll_nonce: $( '#_pll_nonce' ).val()
182
- };
183
-
184
- $.post(
185
- ajaxurl,
186
- data,
187
- function( response ) {
188
- var res = wpAjax.parseAjaxResponse( response, 'ajax-response' );
189
- $.each(
190
- res.responses,
191
- function() {
192
- switch ( this.what ) {
193
- case 'translations': // translations fields
194
- // Data is built and come from server side and is well escaped when necessary
195
- $( "#term-translations" ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
196
- init_translations();
197
- break;
198
- case 'parent': // parent dropdown list for hierarchical taxonomies
199
- // data correctly escaped in PLL_Admin_Filters_Term::term_lang_choice method which uses wp_dropdown_categories function.
200
- $( '#parent' ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
201
- break;
202
- case 'tag_cloud': // popular items
203
- // data correctly escaped in PLL_Admin_Filters_Term::term_lang_choice method which uses wp_tag_cloud and wp_generate_tag_cloud functions.
204
- $( '.tagcloud' ).replaceWith( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.replaceWith
205
- break;
206
- case 'flag': // flag in front of the select dropdown
207
- // Data is built and come from server side and is well escaped when necessary
208
- $( '.pll-select-flag' ).html( this.data ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
209
- break;
210
- }
211
- }
212
- );
213
-
214
- // Modifies the text direction
215
- $( 'body' ).removeClass( 'pll-dir-rtl' ).removeClass( 'pll-dir-ltr' ).addClass( 'pll-dir-' + dir );
216
- }
217
- );
218
- }
219
- );
220
- }
221
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/user.js DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * Adds one biography input field per language in the user profile.
3
- *
4
- * @package Polylang
5
- */
6
-
7
- jQuery(
8
- function( $ ) {
9
- // biography
10
- // FIXME there is probably a more efficient way to do this
11
- var td = $( '#description' ).parent();
12
- var d = $( '#description' ).clone();
13
- var span = td.children( '.description' ).clone();
14
- td.children().remove();
15
-
16
- $( '.biography' ).each(
17
- function(){
18
- lang = $( this ).attr( 'name' ).split( '___' );
19
- desc = d.clone();
20
- desc.attr( 'name', 'description_' + lang[0] );
21
- desc.attr( 'id', 'description_' + lang[0] );
22
- // Whitelist because description and lang value is already escaped by the side of PHP
23
- desc.html( $( this ).val() ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
24
- td.append( $( '<div></div>' ).text( lang[1] ) ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
25
- td.append( desc ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
26
- }
27
- );
28
-
29
- td.append( '<br />' );
30
- // Whitelist because description come from html code generated by WordPress
31
- td.append( span ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.append
32
- }
33
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/widgets.js DELETED
@@ -1,132 +0,0 @@
1
- /**
2
- * Adds a flag to the widgets filtered by a language.
3
- *
4
- * @package Polylang
5
- */
6
-
7
- jQuery(
8
- function( $ ) {
9
- var widgets_container, widgets_selector, flags;
10
-
11
- if ( 'undefined' !== typeof pll_widgets && pll_widgets.hasOwnProperty( 'flags' ) ) {
12
- flags = pll_widgets.flags;
13
- }
14
-
15
- /**
16
- * Prepend widget titles with a flag once a language is selected.
17
- *
18
- * @param {object} widget The widget element.
19
- * @return {void} Nothing.
20
- */
21
- function add_flag( widget ) {
22
- if ( ! flags ) {
23
- return;
24
- }
25
- widget = $( widget );
26
- var title = $( '.widget-top .widget-title h3', widget ),
27
- locale = $( '.pll-lang-choice option:selected', widget ).val(),
28
- // Icon is HTML built and come from server side and is well escaped when necessary
29
- icon = ( locale && flags.hasOwnProperty( locale ) ) ? flags[ locale ] : null;
30
-
31
- if ( icon ) {
32
- icon += ' &nbsp; ';
33
- var current = $( '.pll-lang', title );
34
- if ( current.length ) {
35
- current.html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
36
- } else {
37
- flag = $( '<span />' ).addClass( 'pll-lang' ).html( icon ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.html
38
- // See the comment above about the icon which is safe. So it is also safe to prepend flag which uses icon.
39
- title.prepend( flag ); // phpcs:ignore WordPressVIPMinimum.JS.HTMLExecutingFunctions.prepend
40
- }
41
- } else {
42
- $( '.pll-lang', title ).remove();
43
- }
44
- }
45
-
46
- if ( 'undefined' !== typeof wp.customize ) {
47
-
48
- widgets_container = $( '#customize-controls' );
49
- widgets_selector = '.customize-control .widget';
50
-
51
- /**
52
- * WP Customizer add control listener.
53
- *
54
- * @link https://wordpress.stackexchange.com/questions/256536/callback-after-wordpress-customizer-complete-loading
55
- *
56
- * @param {object} control The control type.
57
- * @return {void} Nothing.
58
- */
59
- function customize_add_flag( control ) {
60
- if ( ! control.extended( wp.customize.Widgets.WidgetControl ) ) {
61
- return;
62
- }
63
-
64
- /*
65
- * Make sure the widget's contents are embedded; normally this is done
66
- * when the control is expanded, for DOM performance reasons.
67
- */
68
- control.embedWidgetContent();
69
-
70
- // Now we know for sure the widget is fully embedded.
71
- add_flag( control.container.find( '.widget' ) );
72
- }
73
- wp.customize.control.each( customize_add_flag );
74
- wp.customize.control.bind( 'add', customize_add_flag );
75
-
76
- } else {
77
-
78
- widgets_container = $( '#widgets-right' );
79
- widgets_selector = '.widget';
80
-
81
- }
82
-
83
- // Add flags on load.
84
- $( widgets_selector, widgets_container ).each(
85
- function() {
86
- add_flag( this );
87
- }
88
- );
89
-
90
- // Update flags.
91
- widgets_container.on(
92
- 'change',
93
- '.pll-lang-choice',
94
- function() {
95
- add_flag( $( this ).parents( '.widget' ) );
96
- }
97
- );
98
-
99
- function pll_toggle( a, test ) {
100
- test ? a.show() : a.hide();
101
- }
102
-
103
- // Remove all options if dropdown is checked.
104
- $( '.widgets-sortables,.control-section-sidebar' ).on(
105
- 'change',
106
- '.pll-dropdown',
107
- function() {
108
- var this_id = $( this ).parent().parent().parent().children( '.widget-id' ).attr( 'value' );
109
- pll_toggle( $( '.no-dropdown-' + this_id ), true != $( this ).prop( 'checked' ) );
110
- }
111
- );
112
-
113
- // Disallow unchecking both show names and show flags.
114
- var options = ['-show_flags', '-show_names'];
115
- $.each(
116
- options,
117
- function( i, v ) {
118
- $( '.widgets-sortables,.control-section-sidebar' ).on(
119
- 'change',
120
- '.pll' + v,
121
- function() {
122
- var this_id = $( this ).parent().parent().parent().children( '.widget-id' ).attr( 'value' );
123
- if ( true != $( this ).prop( 'checked' ) ) {
124
- $( '#widget-' + this_id + options[ 1 - i ] ).prop( 'checked', true );
125
- }
126
- }
127
- );
128
- }
129
- );
130
-
131
- }
132
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/lingotek/image01.gif CHANGED
Binary file
modules/lingotek/image02.png CHANGED
Binary file
modules/lingotek/image03.png CHANGED
Binary file
modules/lingotek/image04.png CHANGED
Binary file
modules/share-slug/load.php CHANGED
@@ -13,7 +13,7 @@ if ( $polylang->model->get_languages_list() ) {
13
  add_filter(
14
  'pll_settings_modules',
15
  function( $modules ) {
16
- $modules[] = 'PLL_Settings_Share_Slug';
17
  return $modules;
18
  }
19
  );
13
  add_filter(
14
  'pll_settings_modules',
15
  function( $modules ) {
16
+ $modules[] = 'PLL_Settings_Preview_Share_Slug';
17
  return $modules;
18
  }
19
  );
modules/share-slug/settings-preview-share-slug.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Polylang
4
+ */
5
+
6
+ /**
7
+ * A class to advertize the Share slugs module.
8
+ *
9
+ * @since 1.9
10
+ * @since 3.1 Renamed from PLL_Settings_Share_Slug.
11
+ */
12
+ class PLL_Settings_Preview_Share_Slug extends PLL_Settings_Module {
13
+ /**
14
+ * Stores the display order priority.
15
+ *
16
+ * @var int
17
+ */
18
+ public $priority = 70;
19
+
20
+ /**
21
+ * Constructor.
22
+ *
23
+ * @since 1.9
24
+ *
25
+ * @param object $polylang Polylang object.
26
+ */
27
+ public function __construct( &$polylang ) {
28
+ parent::__construct(
29
+ $polylang,
30
+ array(
31
+ 'module' => 'share-slugs',
32
+ 'title' => __( 'Share slugs', 'polylang' ),
33
+ 'description' => $this->get_description(),
34
+ )
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Returns the module description.
40
+ *
41
+ * @since 3.1
42
+ *
43
+ * @return string
44
+ */
45
+ protected function get_description() {
46
+ return __( 'Allows to share the same URL slug across languages for posts and terms.', 'polylang' );
47
+ }
48
+
49
+ /**
50
+ * Tells if the module is active.
51
+ *
52
+ * @since 1.9
53
+ *
54
+ * @return bool
55
+ */
56
+ public function is_active() {
57
+ return false;
58
+ }
59
+
60
+ /**
61
+ * Displays an upgrade message.
62
+ *
63
+ * @since 1.9
64
+ *
65
+ * @return string
66
+ */
67
+ public function get_upgrade_message() {
68
+ return $this->default_upgrade_message();
69
+ }
70
+ }
modules/share-slug/settings-share-slug.php DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
- /**
3
- * @package Polylang
4
- */
5
-
6
- /**
7
- * Settings class to advertize the Share slugs module
8
- *
9
- * @since 1.9
10
- */
11
- class PLL_Settings_Share_Slug extends PLL_Settings_Module {
12
- /**
13
- * Stores the display order priority.
14
- *
15
- * @var int
16
- */
17
- public $priority = 70;
18
-
19
- /**
20
- * Constructor
21
- *
22
- * @since 1.9
23
- *
24
- * @param object $polylang polylang object
25
- */
26
- public function __construct( &$polylang ) {
27
- parent::__construct(
28
- $polylang,
29
- array(
30
- 'module' => 'share-slugs',
31
- 'title' => __( 'Share slugs', 'polylang' ),
32
- 'description' => __( 'Allows to share the same url slug across languages for posts and terms.', 'polylang' ),
33
- )
34
- );
35
-
36
- if ( class_exists( 'PLL_Share_Post_Slug', true ) && get_option( 'permalink_structure' ) ) {
37
- add_action( 'admin_print_footer_scripts', array( $this, 'print_js' ) );
38
- }
39
- }
40
-
41
- /**
42
- * Tells if the module is active
43
- *
44
- * @since 1.9
45
- *
46
- * @return bool
47
- */
48
- public function is_active() {
49
- return class_exists( 'PLL_Share_Post_Slug', true ) && $this->options['force_lang'] && get_option( 'permalink_structure' );
50
- }
51
-
52
- /**
53
- * Displays upgrade message
54
- *
55
- * @since 1.9
56
- *
57
- * @return string
58
- */
59
- public function get_upgrade_message() {
60
- return class_exists( 'PLL_Share_Post_Slug', true ) ? '' : $this->default_upgrade_message();
61
- }
62
-
63
- /**
64
- * Displays the javascript to handle dynamically the change in url modifications
65
- * as sharing slugs is not possible when the language is set from the content
66
- *
67
- * @since 1.9
68
- *
69
- * @return void
70
- */
71
- public function print_js() {
72
- wp_enqueue_script( 'jquery' );
73
-
74
- $activated = sprintf( '<span class="activated">%s</span>', $this->action_links['activated'] );
75
- $deactivated = sprintf( '<span class="deactivated">%s</span>', $this->action_links['deactivated'] );
76
-
77
- ?>
78
- <script type='text/javascript'>
79
- //<![CDATA[
80
- jQuery(
81
- function( $ ){
82
- $( "input[name='force_lang']" ).on( 'change', function() {
83
- var value = $( this ).val();
84
- if ( value > 0 ) {
85
- $( "#pll-module-share-slugs" ).removeClass( "inactive" ).addClass( "active" ).children( "td" ).children( ".row-actions" ).html( '<?php echo $activated; // phpcs:ignore WordPress.Security.EscapeOutput ?>' );
86
- }
87
- else {
88
- $( "#pll-module-share-slugs" ).removeClass( "active" ).addClass( "inactive" ).children( "td" ).children( ".row-actions" ).html( '<?php echo $deactivated; // phpcs:ignore WordPress.Security.EscapeOutput ?>' );
89
- }
90
- } );
91
- }
92
- );
93
- // ]]>
94
- </script>
95
- <?php
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/site-health/admin-site-health.php CHANGED
@@ -43,6 +43,7 @@ class PLL_Admin_Site_Health {
43
  // Information tab.
44
  add_filter( 'debug_information', array( $this, 'info_options' ), 15 );
45
  add_filter( 'debug_information', array( $this, 'info_languages' ), 15 );
 
46
 
47
  // Tests Tab.
48
  add_filter( 'site_status_tests', array( $this, 'status_tests' ) );
@@ -82,18 +83,23 @@ class PLL_Admin_Site_Health {
82
  }
83
 
84
  /**
85
- * Formats an array with language as keys to display in options information.
86
  *
87
  * @since 2.8
88
  *
89
- * @param array $array An array with language as keys.
90
  * @return string
91
  */
92
- protected function format_array_with_languages( $array ) {
93
  array_walk(
94
  $array,
95
  function ( &$value, $key ) {
96
- $value = "$key => $value";
 
 
 
 
 
97
  }
98
  );
99
 
@@ -137,7 +143,7 @@ class PLL_Admin_Site_Health {
137
  break;
138
  case 'domains':
139
  $fields[ $key ]['label'] = $key;
140
- $fields[ $key ]['value'] = $this->format_array_with_languages( $value );
141
  break;
142
  case 'nav_menus':
143
  $current_theme = get_stylesheet();
@@ -145,7 +151,7 @@ class PLL_Admin_Site_Health {
145
  foreach ( $value[ $current_theme ] as $location => $lang ) {
146
  /* translators: placeholder is the menu location name */
147
  $fields[ $location ]['label'] = sprintf( 'menu: %s', $location );
148
- $fields[ $location ]['value'] = $this->format_array_with_languages( $lang );
149
  }
150
  }
151
  break;
@@ -162,7 +168,6 @@ class PLL_Admin_Site_Health {
162
  }
163
  }
164
  }
165
-
166
  $debug_info['pll_options'] = array(
167
  /* translators: placeholder is the plugin name */
168
  'label' => sprintf( esc_html__( '%s Options', 'polylang' ), POLYLANG ),
@@ -277,4 +282,87 @@ class PLL_Admin_Site_Health {
277
  }
278
  return $result;
279
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  }
43
  // Information tab.
44
  add_filter( 'debug_information', array( $this, 'info_options' ), 15 );
45
  add_filter( 'debug_information', array( $this, 'info_languages' ), 15 );
46
+ add_filter( 'debug_information', array( $this, 'info_warning' ), 15 );
47
 
48
  // Tests Tab.
49
  add_filter( 'site_status_tests', array( $this, 'status_tests' ) );
83
  }
84
 
85
  /**
86
+ * Formats an array to display in options information.
87
  *
88
  * @since 2.8
89
  *
90
+ * @param array $array An array of formatted data.
91
  * @return string
92
  */
93
+ protected function format_array( $array ) {
94
  array_walk(
95
  $array,
96
  function ( &$value, $key ) {
97
+ if ( is_array( $value ) ) {
98
+ $ids = implode( ' , ', $value );
99
+ $value = "$key => $ids";
100
+ } else {
101
+ $value = "$key => $value";
102
+ }
103
  }
104
  );
105
 
143
  break;
144
  case 'domains':
145
  $fields[ $key ]['label'] = $key;
146
+ $fields[ $key ]['value'] = $this->format_array( $value );
147
  break;
148
  case 'nav_menus':
149
  $current_theme = get_stylesheet();
151
  foreach ( $value[ $current_theme ] as $location => $lang ) {
152
  /* translators: placeholder is the menu location name */
153
  $fields[ $location ]['label'] = sprintf( 'menu: %s', $location );
154
+ $fields[ $location ]['value'] = $this->format_array( $lang );
155
  }
156
  }
157
  break;
168
  }
169
  }
170
  }
 
171
  $debug_info['pll_options'] = array(
172
  /* translators: placeholder is the plugin name */
173
  'label' => sprintf( esc_html__( '%s Options', 'polylang' ), POLYLANG ),
282
  }
283
  return $result;
284
  }
285
+
286
+ /**
287
+ * Add Polylang Warnings to Site Health Informations tab.
288
+ *
289
+ * @since 3.1
290
+ *
291
+ * @param array $debug_info The debug information to be added to the core information page.
292
+ * @return array
293
+ */
294
+ public function info_warning( $debug_info ) {
295
+ $fields = array();
296
+
297
+ $posts_no_lang = $this->get_post_ids_without_lang();
298
+
299
+ if ( ! empty( $posts_no_lang ) ) {
300
+ $fields['post-no-lang']['label'] = __( 'Posts without language', 'polylang' );
301
+ $fields['post-no-lang']['value'] = $this->format_array( $posts_no_lang );
302
+ }
303
+
304
+ $terms_no_lang = $this->get_term_ids_without_lang();
305
+
306
+ if ( ! empty( $terms_no_lang ) ) {
307
+ $fields['term-no-lang']['label'] = __( 'Terms without language', 'polylang' );
308
+ $fields['term-no-lang']['value'] = $this->format_array( $terms_no_lang );
309
+ }
310
+
311
+ if ( ! empty( $fields ) ) {
312
+ $debug_info['pll_warnings'] = array(
313
+ 'label' => sprintf( esc_html__( 'Polylang warnings', 'polylang' ), POLYLANG ),
314
+ 'fields' => $fields,
315
+ );
316
+ }
317
+
318
+ return $debug_info;
319
+ }
320
+
321
+ /**
322
+ * Get an array with post_type as key and post ids as value.
323
+ *
324
+ * @since 3.1
325
+ *
326
+ * @param int $limit Max number of posts to show per post type.
327
+ * @return int[][] Array containing an array of post ids.
328
+ */
329
+ public function get_post_ids_without_lang( $limit = 5 ) {
330
+ $posts = array();
331
+
332
+ foreach ( $this->model->get_translated_post_types() as $post_type ) {
333
+ $post_ids_with_no_language = $this->model->get_posts_with_no_lang( $post_type, $limit );
334
+
335
+ if ( ! empty( $post_ids_with_no_language ) ) {
336
+ foreach ( $post_ids_with_no_language as $id ) {
337
+ $posts[ $post_type ][] = $id;
338
+ }
339
+ }
340
+ }
341
+
342
+ return $posts;
343
+ }
344
+
345
+ /**
346
+ * Get an array with taxonomy as key and term ids as value.
347
+ *
348
+ * @since 3.1
349
+ *
350
+ * @param int $limit Max number of terms to show per post type.
351
+ * @return int[][] Array containing an array of term ids.
352
+ */
353
+ public function get_term_ids_without_lang( $limit = 5 ) {
354
+ $terms = array();
355
+
356
+ foreach ( $this->model->get_translated_taxonomies() as $taxonomy ) {
357
+ $term_ids_with_no_language = $this->model->get_terms_with_no_lang( $taxonomy, $limit );
358
+
359
+ if ( ! empty( $term_ids_with_no_language ) ) {
360
+ foreach ( $term_ids_with_no_language as $id ) {
361
+ $terms[ $taxonomy ][] = $id;
362
+ }
363
+ }
364
+ }
365
+
366
+ return $terms;
367
+ }
368
  }
modules/sync/admin-sync.php CHANGED
@@ -22,8 +22,7 @@ class PLL_Admin_Sync extends PLL_Sync {
22
 
23
  add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 3 );
24
  add_filter( 'wp_insert_post_data', array( $this, 'wp_insert_post_data' ) );
25
- add_action( 'rest_api_init', array( $this, 'new_post_translation' ) ); // Block editor
26
- add_action( 'add_meta_boxes', array( $this, 'new_post_translation' ), 5 ); // Classic editor, before Types which populates custom fields in same hook with priority 10
27
  }
28
 
29
  /**
@@ -82,14 +81,16 @@ class PLL_Admin_Sync extends PLL_Sync {
82
  * Copy post metas, and taxonomies when using "Add new" ( translation )
83
  *
84
  * @since 2.5
 
85
  *
86
- * @return void
 
87
  */
88
- public function new_post_translation() {
89
  global $post;
90
  static $done = array();
91
 
92
- if ( isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow'] && $this->model->is_translated_post_type( $post->post_type ) ) {
93
  check_admin_referer( 'new-post-translation' );
94
 
95
  // Capability check already done in post-new.php
@@ -97,7 +98,7 @@ class PLL_Admin_Sync extends PLL_Sync {
97
  $lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) );
98
 
99
  if ( ! $from_post_id || ! $lang || ! empty( $done[ $from_post_id ] ) ) {
100
- return;
101
  }
102
 
103
  $done[ $from_post_id ] = true; // Avoid a second duplication in the block editor. Using an array only to allow multiple phpunit tests.
@@ -109,6 +110,8 @@ class PLL_Admin_Sync extends PLL_Sync {
109
  stick_post( $post->ID );
110
  }
111
  }
 
 
112
  }
113
 
114
  /**
22
 
23
  add_filter( 'wp_insert_post_parent', array( $this, 'wp_insert_post_parent' ), 10, 3 );
24
  add_filter( 'wp_insert_post_data', array( $this, 'wp_insert_post_data' ) );
25
+ add_filter( 'use_block_editor_for_post', array( $this, 'new_post_translation' ), 5000 ); // After content duplication.
 
26
  }
27
 
28
  /**
81
  * Copy post metas, and taxonomies when using "Add new" ( translation )
82
  *
83
  * @since 2.5
84
+ * @since 3.1 Use of use_block_editor_for_post filter instead of rest_api_init which is triggered too early in WP 5.8.
85
  *
86
+ * @param bool $is_block_editor Whether the post can be edited or not.
87
+ * @return bool
88
  */
89
+ public function new_post_translation( $is_block_editor ) {
90
  global $post;
91
  static $done = array();
92
 
93
+ if ( ! empty( $post ) && isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow'] && $this->model->is_translated_post_type( $post->post_type ) ) {
94
  check_admin_referer( 'new-post-translation' );
95
 
96
  // Capability check already done in post-new.php
98
  $lang = $this->model->get_language( sanitize_key( $_GET['new_lang'] ) );
99
 
100
  if ( ! $from_post_id || ! $lang || ! empty( $done[ $from_post_id ] ) ) {
101
+ return $is_block_editor;
102
  }
103
 
104
  $done[ $from_post_id ] = true; // Avoid a second duplication in the block editor. Using an array only to allow multiple phpunit tests.
110
  stick_post( $post->ID );
111
  }
112
  }
113
+
114
+ return $is_block_editor;
115
  }
116
 
117
  /**
modules/translate-slugs/load.php CHANGED
@@ -13,7 +13,7 @@ if ( $polylang->model->get_languages_list() ) {
13
  add_filter(
14
  'pll_settings_modules',
15
  function( $modules ) {
16
- $modules[] = 'PLL_Settings_Translate_Slugs';
17
  return $modules;
18
  }
19
  );
13
  add_filter(
14
  'pll_settings_modules',
15
  function( $modules ) {
16
+ $modules[] = 'PLL_Settings_Preview_Translate_Slugs';
17
  return $modules;
18
  }
19
  );
modules/translate-slugs/settings-preview-translate-slugs.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package Polylang
4
+ */
5
+
6
+ /**
7
+ * Class to advertize the Translate slugs module.
8
+ *
9
+ * @since 1.9
10
+ * @since 3.1 Renamed from PLL_Settings_Translate_Slugs.
11
+ */
12
+ class PLL_Settings_Preview_Translate_Slugs extends PLL_Settings_Module {
13
+ /**
14
+ * Stores the display order priority.
15
+ *
16
+ * @var int
17
+ */
18
+ public $priority = 80;
19
+
20
+ /**
21
+ * Constructor.
22
+ *
23
+ * @since 1.9
24
+ *
25
+ * @param object $polylang Polylang object.
26
+ */
27
+ public function __construct( &$polylang ) {
28
+ parent::__construct(
29
+ $polylang,
30
+ array(
31
+ 'module' => 'translate-slugs',
32
+ 'title' => __( 'Translate slugs', 'polylang' ),
33
+ 'description' => $this->get_description(),
34
+ )
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Returns the module description.
40
+ *
41
+ * @since 3.1
42
+ *
43
+ * @return string
44
+ */
45
+ protected function get_description() {
46
+ return __( 'Allows to translate custom post types and taxonomies slugs in URLs.', 'polylang' );
47
+ }
48
+
49
+ /**
50
+ * Tells if the module is active.
51
+ *
52
+ * @since 1.9
53
+ *
54
+ * @return bool
55
+ */
56
+ public function is_active() {
57
+ return false;
58
+ }
59
+
60
+ /**
61
+ * Displays an upgrade message.
62
+ *
63
+ * @since 1.9
64
+ *
65
+ * @return string
66
+ */
67
+ public function get_upgrade_message() {
68
+ return $this->default_upgrade_message();
69
+ }
70
+ }
modules/translate-slugs/settings-translate-slugs.php DELETED
@@ -1,58 +0,0 @@
1
- <?php
2
- /**
3
- * @package Polylang
4
- */
5
-
6
- /**
7
- * Settings class to advertize the Translate slugs module
8
- *
9
- * @since 1.9
10
- */
11
- class PLL_Settings_Translate_Slugs extends PLL_Settings_Module {
12
- /**
13
- * Stores the display order priority.
14
- *
15
- * @var int
16
- */
17
- public $priority = 80;
18
-
19
- /**
20
- * Constructor
21
- *
22
- * @since 1.9
23
- *
24
- * @param object $polylang polylang object
25
- */
26
- public function __construct( &$polylang ) {
27
- parent::__construct(
28
- $polylang,
29
- array(
30
- 'module' => 'translate-slugs',
31
- 'title' => __( 'Translate slugs', 'polylang' ),
32
- 'description' => __( 'Allows to translate custom post types and taxonomies slugs in urls.', 'polylang' ),
33
- )
34
- );
35
- }
36
-
37
- /**
38
- * Tells if the module is active
39
- *
40
- * @since 1.9
41
- *
42
- * @return bool
43
- */
44
- public function is_active() {
45
- return class_exists( 'PLL_Translate_Slugs_Model', true ) && get_option( 'permalink_structure' );
46
- }
47
-
48
- /**
49
- * Displays upgrade message
50
- *
51
- * @since 1.9
52
- *
53
- * @return string
54
- */
55
- public function get_upgrade_message() {
56
- return class_exists( 'PLL_Translate_Slugs_Model', true ) ? '' : $this->default_upgrade_message();
57
- }
58
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/wizard/images/media-screen-rtl.png CHANGED
Binary file
modules/wizard/images/media-screen.png CHANGED
Binary file
modules/wizard/images/polylang-logo.png CHANGED
Binary file
modules/wizard/view-wizard-step-media.php CHANGED
@@ -42,7 +42,7 @@ $help_screenshot = '/modules/wizard/images/media-screen' . ( is_rtl() ? '-rtl' :
42
  </div>
43
  <div class="pll-wizard-service-description">
44
  <p>
45
- <?php esc_html_e( 'Allow Polylang translate media', 'polylang' ); ?>
46
  </p>
47
  </div>
48
  </li>
42
  </div>
43
  <div class="pll-wizard-service-description">
44
  <p>
45
+ <?php esc_html_e( 'Allow Polylang to translate media', 'polylang' ); ?>
46
  </p>
47
  </div>
48
  </li>
modules/wpml/load.php CHANGED
@@ -6,20 +6,12 @@
6
  */
7
 
8
  if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Don't access directly
10
  };
11
 
12
  if ( $polylang->model->get_languages_list() ) {
13
  if ( ! defined( 'PLL_WPML_COMPAT' ) || PLL_WPML_COMPAT ) {
14
- PLL_WPML_Compat::instance(); // WPML API
15
- PLL_WPML_Config::instance(); // wpml-config.xml
16
  }
17
-
18
- add_filter(
19
- 'pll_settings_modules',
20
- function( $modules ) {
21
- $modules[] = 'PLL_Settings_WPML';
22
- return $modules;
23
- }
24
- );
25
  }
6
  */
7
 
8
  if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Don't access directly.
10
  };
11
 
12
  if ( $polylang->model->get_languages_list() ) {
13
  if ( ! defined( 'PLL_WPML_COMPAT' ) || PLL_WPML_COMPAT ) {
14
+ PLL_WPML_Compat::instance(); // WPML API.
15
+ PLL_WPML_Config::instance(); // wpml-config.xml.
16
  }
 
 
 
 
 
 
 
 
17
  }
modules/wpml/settings-wpml.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- /**
3
- * @package Polylang
4
- */
5
-
6
- /**
7
- * A class to inform about the WPML compatibility module in Polylang settings
8
- *
9
- * @since 1.8
10
- */
11
- class PLL_Settings_WPML extends PLL_Settings_Module {
12
- /**
13
- * Stores the display order priority.
14
- *
15
- * @var int
16
- */
17
- public $priority = 60;
18
-
19
- /**
20
- * Constructor
21
- *
22
- * @since 1.8
23
- *
24
- * @param object $polylang polylang object
25
- */
26
- public function __construct( &$polylang ) {
27
- parent::__construct(
28
- $polylang,
29
- array(
30
- 'module' => 'wpml',
31
- 'title' => __( 'WPML compatibility', 'polylang' ),
32
- 'description' => __( 'Polylang\'s WPML compatibility mode', 'polylang' ),
33
- )
34
- );
35
- }
36
-
37
- /**
38
- * Tells if the module is active
39
- *
40
- * @since 1.8
41
- *
42
- * @return bool
43
- */
44
- public function is_active() {
45
- return ! defined( 'PLL_WPML_COMPAT' ) || PLL_WPML_COMPAT;
46
- }
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/wpml/wpml-config.php CHANGED
@@ -59,33 +59,22 @@ class PLL_WPML_Config {
59
  */
60
  public function init() {
61
  $this->xmls = array();
 
62
 
63
- // Plugins
64
- // 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
65
- $plugins = ( is_multisite() && $sitewide_plugins = get_site_option( 'active_sitewide_plugins' ) ) && is_array( $sitewide_plugins ) ? array_keys( $sitewide_plugins ) : array();
66
- $plugins = array_merge( $plugins, get_option( 'active_plugins', array() ) );
67
 
68
- foreach ( $plugins as $plugin ) {
69
- if ( file_exists( $file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
70
- $this->xmls[ dirname( $plugin ) ] = $xml;
 
 
 
 
 
71
  }
72
  }
73
 
74
- // Theme
75
- if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
76
- $this->xmls[ get_template() ] = $xml;
77
- }
78
-
79
- // Child theme
80
- if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
81
- $this->xmls[ get_stylesheet() ] = $xml;
82
- }
83
-
84
- // Custom
85
- if ( file_exists( $file = PLL_LOCAL_DIR . '/wpml-config.xml' ) && false !== $xml = simplexml_load_file( $file ) ) {
86
- $this->xmls['Polylang'] = $xml;
87
- }
88
-
89
  if ( ! empty( $this->xmls ) ) {
90
  add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 20, 2 );
91
  add_filter( 'pll_copy_term_metas', array( $this, 'copy_term_metas' ), 20, 2 );
@@ -117,6 +106,61 @@ class PLL_WPML_Config {
117
  }
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
  * Adds custom fields to the list of metas to copy when creating a new translation.
122
  *
59
  */
60
  public function init() {
61
  $this->xmls = array();
62
+ $files = $this->get_files();
63
 
64
+ if ( ! empty( $files ) ) {
65
+ add_filter( 'site_status_test_php_modules', array( $this, 'site_status_test_php_modules' ) ); // Require simplexml in Site health.
 
 
66
 
67
+ // Read all files.
68
+ if ( extension_loaded( 'simplexml' ) ) {
69
+ foreach ( $files as $context => $file ) {
70
+ $xml = simplexml_load_file( $file );
71
+ if ( false !== $xml ) {
72
+ $this->xmls[ $context ] = $xml;
73
+ }
74
+ }
75
  }
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  if ( ! empty( $this->xmls ) ) {
79
  add_filter( 'pll_copy_post_metas', array( $this, 'copy_post_metas' ), 20, 2 );
80
  add_filter( 'pll_copy_term_metas', array( $this, 'copy_term_metas' ), 20, 2 );
106
  }
107
  }
108
 
109
+ /**
110
+ * Get all wpml-config.xml files in plugins, theme, child theme and Polylang custom directory.
111
+ *
112
+ * @since 3.1
113
+ *
114
+ * @return array
115
+ */
116
+ protected function get_files() {
117
+ $files = array();
118
+
119
+ // Plugins
120
+ // 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
121
+ $plugins = ( is_multisite() && $sitewide_plugins = get_site_option( 'active_sitewide_plugins' ) ) && is_array( $sitewide_plugins ) ? array_keys( $sitewide_plugins ) : array();
122
+ $plugins = array_merge( $plugins, get_option( 'active_plugins', array() ) );
123
+
124
+ foreach ( $plugins as $plugin ) {
125
+ if ( file_exists( $file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/wpml-config.xml' ) ) {
126
+ $files[ dirname( $plugin ) ] = $file;
127
+ }
128
+ }
129
+
130
+ // Theme
131
+ if ( file_exists( $file = ( $template = get_template_directory() ) . '/wpml-config.xml' ) ) {
132
+ $files[ get_template() ] = $file;
133
+ }
134
+
135
+ // Child theme
136
+ if ( ( $stylesheet = get_stylesheet_directory() ) !== $template && file_exists( $file = $stylesheet . '/wpml-config.xml' ) ) {
137
+ $files[ get_stylesheet() ] = $file;
138
+ }
139
+
140
+ // Custom
141
+ if ( file_exists( $file = PLL_LOCAL_DIR . '/wpml-config.xml' ) ) {
142
+ $files['Polylang'] = $file;
143
+ }
144
+
145
+ return $files;
146
+ }
147
+
148
+ /**
149
+ * Requires the simplexml PHP module when a wpml-config.xml has been found.
150
+ *
151
+ * @since 3.1
152
+ *
153
+ * @param array $modules An associative array of modules to test for.
154
+ * @return array
155
+ */
156
+ public function site_status_test_php_modules( $modules ) {
157
+ $modules['simplexml'] = array(
158
+ 'extension' => 'simplexml',
159
+ 'required' => true,
160
+ );
161
+ return $modules;
162
+ }
163
+
164
  /**
165
  * Adds custom fields to the list of metas to copy when creating a new translation.
166
  *
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.0.6
14
- * Requires at least: 5.1
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.0.6' );
57
- define( 'PLL_MIN_WP_VERSION', '5.1' );
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.1
14
+ * Requires at least: 5.4
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.1' );
57
+ define( 'PLL_MIN_WP_VERSION', '5.4' );
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
3
  Donate link: https://polylang.pro
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
5
- Requires at least: 5.1
6
- Tested up to: 5.7
7
  Requires PHP: 5.6
8
- Stable tag: 3.0.6
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -78,6 +78,31 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
78
 
79
  == Changelog ==
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  = 3.0.6 (2021-06-22) =
82
 
83
  * Fix a conflict with the WooCommerce cart translation and cache plugins #876
@@ -107,7 +132,7 @@ Don't hesitate to [give your feedback](http://wordpress.org/support/view/plugin-
107
  * Move hreflang attributes higher in the head section #771
108
  * Fix custom flags not working (introduced in 3.0)
109
  * Fix translation of the confirmation modal when changing the language of a post
110
- * Fix js and css not loaded when Polylang is used as a mu-plugin ((introduced in 3.0))
111
  * Fix support for html5 stylesheet link tags #775
112
  * Fix possible warning in frontend-filters-links.php
113
  * Yoast SEO Premium: Take over the multilingual compatibility removed in Yoast SEO Premium 15.8 #796
2
  Contributors: Chouby, manooweb, raaaahman, marianne38, sebastienserre
3
  Donate link: https://polylang.pro
4
  Tags: multilingual, bilingual, translate, translation, language, multilanguage, international, localization
5
+ Requires at least: 5.4
6
+ Tested up to: 5.8
7
  Requires PHP: 5.6
8
+ Stable tag: 3.1
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
78
 
79
  == Changelog ==
80
 
81
+ = 3.1 (2021-07-27) =
82
+
83
+ * Add compatibility with WordPress 5.8
84
+ * Raise Minimum WordPress version to 5.4
85
+ * Pro: Allow to filter blocks by language in the widget block editor
86
+ * Pro: Allow to export and import XLIFF files for string translations
87
+ * Pro: Add the language switcher in the navigation block (experimental)
88
+ * Pro: Replace dashicons by svg icons in the block editor
89
+ * Pro: The Events Calendar: Add compatibility with Views V2 (only for sites using only one domain)
90
+ * Pro: Fix + icon displayed in the block editor sidebar when the user cannot create a translation
91
+ * Add a warning section to the site health for posts and terms without languages #825
92
+ * Require the simplexml extension in the site health if a wpml-config.xml is found #827
93
+ * Remove the information about the WPML compabitility mode in settings #843
94
+ * The browser preferred language detection is now deactivated by default
95
+ * The media are now untranslated by default
96
+ * Highlight the language filter in the admin toolbar when it's active #821
97
+ * Allow to query comments in multiple languages (just as posts and terms) #840
98
+ * Don't disable the translation input field in the classic metabox #841 Props Onatcer
99
+ * Optimize all images including flags #848 Props lowwebtech
100
+ * Don't redirect if WordPress doesn't validate the redirect url to avoid redirects to /wp-admin/ #879
101
+ * Fix media appearing to have a language after the language is changed in the media library grid view #807
102
+ * Fix media not all deleted when bulk deleting from the grid view of the media library #830
103
+ * Fix when more than one language switcher are added to the same menu #853
104
+ * Fix PHP notice when adding a CPT archive link to a menu #868 Props davidwebca
105
+
106
  = 3.0.6 (2021-06-22) =
107
 
108
  * Fix a conflict with the WooCommerce cart translation and cache plugins #876
132
  * Move hreflang attributes higher in the head section #771
133
  * Fix custom flags not working (introduced in 3.0)
134
  * Fix translation of the confirmation modal when changing the language of a post
135
+ * Fix js and css not loaded when Polylang is used as a mu-plugin (introduced in 3.0)
136
  * Fix support for html5 stylesheet link tags #775
137
  * Fix possible warning in frontend-filters-links.php
138
  * Yoast SEO Premium: Take over the multilingual compatibility removed in Yoast SEO Premium 15.8 #796
settings/settings-browser.php CHANGED
@@ -30,7 +30,7 @@ class PLL_Settings_Browser extends PLL_Settings_Module {
30
  array(
31
  'module' => 'browser',
32
  'title' => __( 'Detect browser language', 'polylang' ),
33
- 'description' => __( 'When the front page is visited, set the language according to the browser preference', 'polylang' ),
34
  'active_option' => $this->is_available() ? 'browser' : false,
35
  )
36
  );
30
  array(
31
  'module' => 'browser',
32
  'title' => __( 'Detect browser language', 'polylang' ),
33
+ 'description' => __( 'When the front page is visited, redirects to itself in the browser preferred language. As this doesn\'t work if it is cached, Polylang will attempt to disable the front page cache for known cache plugins.', 'polylang' ),
34
  'active_option' => $this->is_available() ? 'browser' : false,
35
  )
36
  );
settings/settings-media.php CHANGED
@@ -29,7 +29,7 @@ class PLL_Settings_Media extends PLL_Settings_Module {
29
  array(
30
  'module' => 'media',
31
  'title' => __( 'Media', 'polylang' ),
32
- 'description' => __( 'Activate languages and translations for media', 'polylang' ),
33
  'active_option' => 'media_support',
34
  )
35
  );
29
  array(
30
  'module' => 'media',
31
  'title' => __( 'Media', 'polylang' ),
32
+ 'description' => __( 'Activate languages and translations for media only if you need to translate the text attached to the media: the title, the alternative text, the caption, the description... Note that the file is not duplicated.', 'polylang' ),
33
  'active_option' => 'media_support',
34
  )
35
  );
settings/settings-url.php CHANGED
@@ -53,6 +53,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
53
  */
54
  protected function force_lang() {
55
  ?>
 
56
  <label>
57
  <?php
58
  printf(
@@ -180,7 +181,7 @@ class PLL_Settings_Url extends PLL_Settings_Module {
180
  printf(
181
  '<input name="redirect_lang" type="checkbox" value="1" %s/> %s',
182
  checked( $this->options['redirect_lang'], 1, false ),
183
- esc_html__( 'The front page url contains the language code instead of the page name or page id', 'polylang' )
184
  );
185
  ?>
186
  </label>
53
  */
54
  protected function force_lang() {
55
  ?>
56
+ <p class="description"><?php esc_html_e( 'Some themes or plugins may not be fully compatible with the language defined by the content or by domains.', 'polylang' ); ?></p>
57
  <label>
58
  <?php
59
  printf(
181
  printf(
182
  '<input name="redirect_lang" type="checkbox" value="1" %s/> %s',
183
  checked( $this->options['redirect_lang'], 1, false ),
184
+ esc_html__( 'The front page URL contains the language code instead of the page name or page id', 'polylang' )
185
  );
186
  ?>
187
  </label>
settings/table-string.php CHANGED
@@ -382,10 +382,11 @@ class PLL_Table_String extends WP_List_Table {
382
  continue;
383
  }
384
 
 
 
385
  $mo = new PLL_MO();
386
  $mo->import_from_db( $language );
387
 
388
- $translations = array_map( 'trim', wp_unslash( $_POST['translation'][ $language->slug ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
389
  foreach ( $translations as $key => $translation ) {
390
  /**
391
  * Filter the string translation before it is saved in DB
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 );
389
 
 
390
  foreach ( $translations as $key => $translation ) {
391
  /**
392
  * Filter the string translation before it is saved in DB
settings/view-tab-lang.php CHANGED
@@ -107,7 +107,7 @@ if ( ! defined( 'ABSPATH' ) ) {
107
  </div>
108
 
109
  <div class="form-field"><fieldset>
110
- <legend><?php esc_html_e( 'Text direction', 'polylang' ); ?></legend>
111
  <?php
112
  printf(
113
  '<label><input name="rtl" type="radio" value="0" %s /> %s</label>',
107
  </div>
108
 
109
  <div class="form-field"><fieldset>
110
+ <legend class="pll-legend"><?php esc_html_e( 'Text direction', 'polylang' ); ?></legend>
111
  <?php
112
  printf(
113
  '<label><input name="rtl" type="radio" value="0" %s /> %s</label>',
vendor/composer/autoload_classmap.php CHANGED
@@ -14,6 +14,7 @@ return array(
14
  'PLL_Admin_Base' => $baseDir . '/admin/admin-base.php',
15
  'PLL_Admin_Block_Editor' => $baseDir . '/admin/admin-block-editor.php',
16
  'PLL_Admin_Classic_Editor' => $baseDir . '/admin/admin-classic-editor.php',
 
17
  'PLL_Admin_Filters' => $baseDir . '/admin/admin-filters.php',
18
  'PLL_Admin_Filters_Columns' => $baseDir . '/admin/admin-filters-columns.php',
19
  'PLL_Admin_Filters_Media' => $baseDir . '/admin/admin-filters-media.php',
@@ -31,6 +32,7 @@ return array(
31
  'PLL_Admin_Sync' => $baseDir . '/modules/sync/admin-sync.php',
32
  'PLL_Aqua_Resizer' => $baseDir . '/integrations/aqua-resizer/aqua-resizer.php',
33
  'PLL_Base' => $baseDir . '/include/base.php',
 
34
  'PLL_CRUD_Posts' => $baseDir . '/include/crud-posts.php',
35
  'PLL_CRUD_Terms' => $baseDir . '/include/crud-terms.php',
36
  'PLL_Cache' => $baseDir . '/include/cache.php',
@@ -53,6 +55,7 @@ return array(
53
  'PLL_Frontend_Filters' => $baseDir . '/frontend/frontend-filters.php',
54
  'PLL_Frontend_Filters_Links' => $baseDir . '/frontend/frontend-filters-links.php',
55
  'PLL_Frontend_Filters_Search' => $baseDir . '/frontend/frontend-filters-search.php',
 
56
  'PLL_Frontend_Links' => $baseDir . '/frontend/frontend-links.php',
57
  'PLL_Frontend_Nav_Menu' => $baseDir . '/frontend/frontend-nav-menu.php',
58
  'PLL_Frontend_Static_Pages' => $baseDir . '/frontend/frontend-static-pages.php',
@@ -86,11 +89,10 @@ return array(
86
  'PLL_Settings_Licenses' => $baseDir . '/settings/settings-licenses.php',
87
  'PLL_Settings_Media' => $baseDir . '/settings/settings-media.php',
88
  'PLL_Settings_Module' => $baseDir . '/settings/settings-module.php',
89
- 'PLL_Settings_Share_Slug' => $baseDir . '/modules/share-slug/settings-share-slug.php',
 
90
  'PLL_Settings_Sync' => $baseDir . '/modules/sync/settings-sync.php',
91
- 'PLL_Settings_Translate_Slugs' => $baseDir . '/modules/translate-slugs/settings-translate-slugs.php',
92
  'PLL_Settings_Url' => $baseDir . '/settings/settings-url.php',
93
- 'PLL_Settings_WPML' => $baseDir . '/modules/wpml/settings-wpml.php',
94
  'PLL_Sitemaps' => $baseDir . '/modules/sitemaps/sitemaps.php',
95
  'PLL_Sitemaps_Domain' => $baseDir . '/modules/sitemaps/sitemaps-domain.php',
96
  'PLL_Static_Pages' => $baseDir . '/include/static-pages.php',
14
  'PLL_Admin_Base' => $baseDir . '/admin/admin-base.php',
15
  'PLL_Admin_Block_Editor' => $baseDir . '/admin/admin-block-editor.php',
16
  'PLL_Admin_Classic_Editor' => $baseDir . '/admin/admin-classic-editor.php',
17
+ 'PLL_Admin_Default_Term' => $baseDir . '/admin/admin-default-term.php',
18
  'PLL_Admin_Filters' => $baseDir . '/admin/admin-filters.php',
19
  'PLL_Admin_Filters_Columns' => $baseDir . '/admin/admin-filters-columns.php',
20
  'PLL_Admin_Filters_Media' => $baseDir . '/admin/admin-filters-media.php',
32
  'PLL_Admin_Sync' => $baseDir . '/modules/sync/admin-sync.php',
33
  'PLL_Aqua_Resizer' => $baseDir . '/integrations/aqua-resizer/aqua-resizer.php',
34
  'PLL_Base' => $baseDir . '/include/base.php',
35
+ 'PLL_Block_Editor_Filter_Preload_Paths' => $baseDir . '/admin/block-editor-filter-preload-paths.php',
36
  'PLL_CRUD_Posts' => $baseDir . '/include/crud-posts.php',
37
  'PLL_CRUD_Terms' => $baseDir . '/include/crud-terms.php',
38
  'PLL_Cache' => $baseDir . '/include/cache.php',
55
  'PLL_Frontend_Filters' => $baseDir . '/frontend/frontend-filters.php',
56
  'PLL_Frontend_Filters_Links' => $baseDir . '/frontend/frontend-filters-links.php',
57
  'PLL_Frontend_Filters_Search' => $baseDir . '/frontend/frontend-filters-search.php',
58
+ 'PLL_Frontend_Filters_Widgets' => $baseDir . '/frontend/frontend-filters-widgets.php',
59
  'PLL_Frontend_Links' => $baseDir . '/frontend/frontend-links.php',
60
  'PLL_Frontend_Nav_Menu' => $baseDir . '/frontend/frontend-nav-menu.php',
61
  'PLL_Frontend_Static_Pages' => $baseDir . '/frontend/frontend-static-pages.php',
89
  'PLL_Settings_Licenses' => $baseDir . '/settings/settings-licenses.php',
90
  'PLL_Settings_Media' => $baseDir . '/settings/settings-media.php',
91
  'PLL_Settings_Module' => $baseDir . '/settings/settings-module.php',
92
+ 'PLL_Settings_Preview_Share_Slug' => $baseDir . '/modules/share-slug/settings-preview-share-slug.php',
93
+ 'PLL_Settings_Preview_Translate_Slugs' => $baseDir . '/modules/translate-slugs/settings-preview-translate-slugs.php',
94
  'PLL_Settings_Sync' => $baseDir . '/modules/sync/settings-sync.php',
 
95
  'PLL_Settings_Url' => $baseDir . '/settings/settings-url.php',
 
96
  'PLL_Sitemaps' => $baseDir . '/modules/sitemaps/sitemaps.php',
97
  'PLL_Sitemaps_Domain' => $baseDir . '/modules/sitemaps/sitemaps-domain.php',
98
  'PLL_Static_Pages' => $baseDir . '/include/static-pages.php',
vendor/composer/autoload_static.php CHANGED
@@ -15,6 +15,7 @@ class ComposerStaticInit57e007bdf76a1fe336cb43b59389545b
15
  'PLL_Admin_Base' => __DIR__ . '/../..' . '/admin/admin-base.php',
16
  'PLL_Admin_Block_Editor' => __DIR__ . '/../..' . '/admin/admin-block-editor.php',
17
  'PLL_Admin_Classic_Editor' => __DIR__ . '/../..' . '/admin/admin-classic-editor.php',
 
18
  'PLL_Admin_Filters' => __DIR__ . '/../..' . '/admin/admin-filters.php',
19
  'PLL_Admin_Filters_Columns' => __DIR__ . '/../..' . '/admin/admin-filters-columns.php',
20
  'PLL_Admin_Filters_Media' => __DIR__ . '/../..' . '/admin/admin-filters-media.php',
@@ -32,6 +33,7 @@ class ComposerStaticInit57e007bdf76a1fe336cb43b59389545b
32
  'PLL_Admin_Sync' => __DIR__ . '/../..' . '/modules/sync/admin-sync.php',
33
  'PLL_Aqua_Resizer' => __DIR__ . '/../..' . '/integrations/aqua-resizer/aqua-resizer.php',
34
  'PLL_Base' => __DIR__ . '/../..' . '/include/base.php',
 
35
  'PLL_CRUD_Posts' => __DIR__ . '/../..' . '/include/crud-posts.php',
36
  'PLL_CRUD_Terms' => __DIR__ . '/../..' . '/include/crud-terms.php',
37
  'PLL_Cache' => __DIR__ . '/../..' . '/include/cache.php',
@@ -54,6 +56,7 @@ class ComposerStaticInit57e007bdf76a1fe336cb43b59389545b
54
  'PLL_Frontend_Filters' => __DIR__ . '/../..' . '/frontend/frontend-filters.php',
55
  'PLL_Frontend_Filters_Links' => __DIR__ . '/../..' . '/frontend/frontend-filters-links.php',
56
  'PLL_Frontend_Filters_Search' => __DIR__ . '/../..' . '/frontend/frontend-filters-search.php',
 
57
  'PLL_Frontend_Links' => __DIR__ . '/../..' . '/frontend/frontend-links.php',
58
  'PLL_Frontend_Nav_Menu' => __DIR__ . '/../..' . '/frontend/frontend-nav-menu.php',
59
  'PLL_Frontend_Static_Pages' => __DIR__ . '/../..' . '/frontend/frontend-static-pages.php',
@@ -87,11 +90,10 @@ class ComposerStaticInit57e007bdf76a1fe336cb43b59389545b
87
  'PLL_Settings_Licenses' => __DIR__ . '/../..' . '/settings/settings-licenses.php',
88
  'PLL_Settings_Media' => __DIR__ . '/../..' . '/settings/settings-media.php',
89
  'PLL_Settings_Module' => __DIR__ . '/../..' . '/settings/settings-module.php',
90
- 'PLL_Settings_Share_Slug' => __DIR__ . '/../..' . '/modules/share-slug/settings-share-slug.php',
 
91
  'PLL_Settings_Sync' => __DIR__ . '/../..' . '/modules/sync/settings-sync.php',
92
- 'PLL_Settings_Translate_Slugs' => __DIR__ . '/../..' . '/modules/translate-slugs/settings-translate-slugs.php',
93
  'PLL_Settings_Url' => __DIR__ . '/../..' . '/settings/settings-url.php',
94
- 'PLL_Settings_WPML' => __DIR__ . '/../..' . '/modules/wpml/settings-wpml.php',
95
  'PLL_Sitemaps' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps.php',
96
  'PLL_Sitemaps_Domain' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps-domain.php',
97
  'PLL_Static_Pages' => __DIR__ . '/../..' . '/include/static-pages.php',
15
  'PLL_Admin_Base' => __DIR__ . '/../..' . '/admin/admin-base.php',
16
  'PLL_Admin_Block_Editor' => __DIR__ . '/../..' . '/admin/admin-block-editor.php',
17
  'PLL_Admin_Classic_Editor' => __DIR__ . '/../..' . '/admin/admin-classic-editor.php',
18
+ 'PLL_Admin_Default_Term' => __DIR__ . '/../..' . '/admin/admin-default-term.php',
19
  'PLL_Admin_Filters' => __DIR__ . '/../..' . '/admin/admin-filters.php',
20
  'PLL_Admin_Filters_Columns' => __DIR__ . '/../..' . '/admin/admin-filters-columns.php',
21
  'PLL_Admin_Filters_Media' => __DIR__ . '/../..' . '/admin/admin-filters-media.php',
33
  'PLL_Admin_Sync' => __DIR__ . '/../..' . '/modules/sync/admin-sync.php',
34
  'PLL_Aqua_Resizer' => __DIR__ . '/../..' . '/integrations/aqua-resizer/aqua-resizer.php',
35
  'PLL_Base' => __DIR__ . '/../..' . '/include/base.php',
36
+ 'PLL_Block_Editor_Filter_Preload_Paths' => __DIR__ . '/../..' . '/admin/block-editor-filter-preload-paths.php',
37
  'PLL_CRUD_Posts' => __DIR__ . '/../..' . '/include/crud-posts.php',
38
  'PLL_CRUD_Terms' => __DIR__ . '/../..' . '/include/crud-terms.php',
39
  'PLL_Cache' => __DIR__ . '/../..' . '/include/cache.php',
56
  'PLL_Frontend_Filters' => __DIR__ . '/../..' . '/frontend/frontend-filters.php',
57
  'PLL_Frontend_Filters_Links' => __DIR__ . '/../..' . '/frontend/frontend-filters-links.php',
58
  'PLL_Frontend_Filters_Search' => __DIR__ . '/../..' . '/frontend/frontend-filters-search.php',
59
+ 'PLL_Frontend_Filters_Widgets' => __DIR__ . '/../..' . '/frontend/frontend-filters-widgets.php',
60
  'PLL_Frontend_Links' => __DIR__ . '/../..' . '/frontend/frontend-links.php',
61
  'PLL_Frontend_Nav_Menu' => __DIR__ . '/../..' . '/frontend/frontend-nav-menu.php',
62
  'PLL_Frontend_Static_Pages' => __DIR__ . '/../..' . '/frontend/frontend-static-pages.php',
90
  'PLL_Settings_Licenses' => __DIR__ . '/../..' . '/settings/settings-licenses.php',
91
  'PLL_Settings_Media' => __DIR__ . '/../..' . '/settings/settings-media.php',
92
  'PLL_Settings_Module' => __DIR__ . '/../..' . '/settings/settings-module.php',
93
+ 'PLL_Settings_Preview_Share_Slug' => __DIR__ . '/../..' . '/modules/share-slug/settings-preview-share-slug.php',
94
+ 'PLL_Settings_Preview_Translate_Slugs' => __DIR__ . '/../..' . '/modules/translate-slugs/settings-preview-translate-slugs.php',
95
  'PLL_Settings_Sync' => __DIR__ . '/../..' . '/modules/sync/settings-sync.php',
 
96
  'PLL_Settings_Url' => __DIR__ . '/../..' . '/settings/settings-url.php',
 
97
  'PLL_Sitemaps' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps.php',
98
  'PLL_Sitemaps_Domain' => __DIR__ . '/../..' . '/modules/sitemaps/sitemaps-domain.php',
99
  'PLL_Static_Pages' => __DIR__ . '/../..' . '/include/static-pages.php',