Skip to content

Commit 4d619fc

Browse files
committed
Prepare version 1.1.1
1 parent ecc84fd commit 4d619fc

File tree

11 files changed

+284
-129
lines changed

11 files changed

+284
-129
lines changed

README.md

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Ultimate Member - Polylang
22

3-
Integrates the **Ultimate Member** community plugin with the **Polylang** multilingual plugin.
3+
Integrates the **Ultimate Member** plugin with the **Polylang** plugin. Makes Ultimate Member multilingual.
44

55
## Key features
66

@@ -12,49 +12,62 @@ Integrates the **Ultimate Member** community plugin with the **Polylang** multil
1212

1313
## Installation
1414

15-
__Note:__ This plugin requires the [Ultimate Member](https://wordpress.org/plugins/ultimate-member/) and [Polylang](https://uk.wordpress.org/plugins/polylang/) plugins to be installed first.
15+
__Note:__ This plugin requires the [Ultimate Member](https://wordpress.org/plugins/ultimate-member/) and [Polylang](https://wordpress.org/plugins/polylang/) plugins to be installed first.
1616

1717
### How to install from GitHub
1818

1919
Open git bash, navigate to the **plugins** folder and execute this command:
2020

2121
`git clone --branch=main git@github.com:umdevelopera/um-polylang.git um-polylang`
2222

23-
Once the plugin is cloned, enter your site admin dashboard and go to _wp-admin > Plugins > Installed Plugins_. Find the "Ultimate Member - Polylang" plugin and click the "Activate" link.
23+
Once the plugin is cloned, enter your site admin dashboard and go to _wp-admin > Plugins > Installed Plugins_. Find the **Ultimate Member - Polylang** plugin and click the **Activate** link.
2424

2525
### How to install from ZIP archive
2626

27-
You can install this plugin from the [ZIP archive](https://drive.google.com/file/d/1Lpgu5b-6CLkjK0Ik24CBB836aIcRcmaj/view) as any other plugin. Follow [this instruction](https://wordpress.org/support/article/managing-plugins/#upload-via-wordpress-admin).
27+
You can install this plugin from the [ZIP archive](https://drive.google.com/file/d/17n3Kr05_B_edsGY7An7xu85TZ7H5gbOT/view?usp=sharing) as any other plugin. Follow [this instruction](https://wordpress.org/support/article/managing-plugins/#upload-via-wordpress-admin).
2828

2929
## How to use
3030

31+
### How to translate pages
32+
3133
Go to *wp-admin > Pages* to translate Ultimate Member pages. Click the **Create Pages** button in the notice to duplicate Ultimate Member pages for all languages. Or click the "+" icon unter the flag to duplicate each page manually.
3234

3335
Image - Translate pages.
3436
![Pages](https://github.com/umdevelopera/um-polylang/assets/113178913/40543c1b-d428-4832-9090-d2cc9166b616)
3537

36-
Go to *wp-admin > Ultimate Member > Forms* to translate Ultimate Member forms. Click the **Create Forms** button in the notice to duplicate Ultimate Member forms for all languages. Or click the "+" icon unter the flag to duplicate each form manually.
38+
Go to *wp-admin > Settings > Permalinks* and click the **Save Changes** button if you need to update rewrite rules for the Account and User page permalinks.
39+
Note: The "Post name" permalink structure is recommended.
3740

38-
Once forms for languages are created you can open these forms and translate fields. You have to translate a **Label** for custom fields. You also can translate **Placeholder** and **Help Text** if needed.
41+
Image - Permalink settings.
42+
![WP Settings, Permalink (default)](https://github.com/umdevelopera/um-polylang/assets/113178913/69be91c9-12dd-490c-9145-b163c5beb26d)
43+
44+
### How to translate forms
45+
46+
Go to *wp-admin > Ultimate Member > Forms* to translate Ultimate Member forms. Click the **Create Forms** button in the notice to duplicate Ultimate Member forms for all languages. Or click the "+" icon unter the flag to duplicate each form manually.
3947

4048
Image - Translate forms.
4149
![Forms](https://github.com/umdevelopera/um-polylang/assets/113178913/76763122-a774-4778-ab2c-748b3e983779)
4250

43-
Go to *wp-admin > Ultimate Member > Settings > Email* to translate email templates. Click the "+" icon unter the flag to translate a template for the language. The plugin saves translated email templates to locale subfolders in the theme, see [Email Templates](https://docs.ultimatemember.com/article/1335-email-templates).
51+
Once forms for languages are created you can open these forms and translate fields. You have to translate a **Label** for custom fields. You also can translate **Placeholder** and **Help Text** if needed.
4452

45-
Image - Translate emails.
46-
![Email](https://github.com/umdevelopera/um-polylang/assets/113178913/17167ba5-8564-4fe9-ba33-ef69bfb67f57)
53+
**Choices** are not translatable, this is necessary for the directory search to work correctly. Don't try to translate choices in the field settings! You can use custom functions to translate choices.
54+
See examples:
55+
- [How to translate choices of the Checkbox field](https://gist.github.com/umdevelopera/f7b0e07d5db870c9ce9fc1e513224e45)
56+
- [How to translate choices of the Dropdown field](https://gist.github.com/umdevelopera/bcc8c882ead5914845b489ece73b612d)
4757

48-
Go to *wp-admin > Settings > Permalinks* and click the "Save Changes" button if you need to update rewrite rules for the Account and Profile permalinks.
58+
![UM Forms, Edit Form, Edit Field - Dropdown (use Choices Callback to translate values)+](https://github.com/umdevelopera/um-polylang/assets/113178913/4e58118e-a9b4-430a-ba02-cb766ec72c6a)
4959

50-
Image - Permalink settings.
51-
![WP Settings, Permalink (default)](https://github.com/umdevelopera/um-polylang/assets/113178913/69be91c9-12dd-490c-9145-b163c5beb26d)
60+
### How to translate E-mails
5261

53-
__Note:__ The "Post name" permalink structure is recommended.
62+
Go to *wp-admin > Ultimate Member > Settings > Email* to translate email templates. Click the "+" icon unter the flag to translate a template for the language. The plugin saves translated email templates to locale subfolders in the theme, see [Email Templates](https://docs.ultimatemember.com/article/1335-email-templates).
63+
64+
Image - Translate emails.
65+
![Email](https://github.com/umdevelopera/um-polylang/assets/113178913/17167ba5-8564-4fe9-ba33-ef69bfb67f57)
5466

5567
## Support
5668

57-
This is a free extension created for the community. The Ultimate Member team does not provide support for this extension. Open new [issue](https://github.com/umdevelopera/um-polylang/issues) if you face a problem.
69+
This is a free extension created for the community. The Ultimate Member team does not provide support for this extension.
70+
Open new [issue](https://github.com/umdevelopera/um-polylang/issues) if you are facing a problem or have a suggestion.
5871

5972
## Related links
6073

includes/admin/class-admin.php

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public function __construct() {
3030
add_action( 'in_admin_header', array( $this, 'notice_create_forms' ) );
3131
add_action( 'in_admin_header', array( $this, 'notice_create_pages' ) );
3232
add_filter( 'um_adm_action_custom_notice_update', array( $this, 'notice_update' ), 10, 2 );
33+
add_filter( 'um_adm_action_custom_update_notice', array( $this, 'notice_update' ), 10, 2 );
3334

3435
// Create Forms.
3536
add_action( 'um_admin_do_action__um_pll_create_forms', array( $this, 'action_create_forms' ) );
@@ -60,7 +61,7 @@ public function action_create_forms() {
6061
);
6162
$posts = get_posts( $args );
6263

63-
UM()->Polylang()->setup()->create_posts( $posts, 'um_form' );
64+
UM()->Polylang()->posts()->create_posts( $posts, 'um_form' );
6465

6566
$url = add_query_arg( 'update', 'um_pll_create_forms', admin_url( 'edit.php?post_type=um_form' ) );
6667
exit( wp_safe_redirect( $url ) );
@@ -73,7 +74,7 @@ public function action_create_forms() {
7374
public function action_create_pages() {
7475
$posts = UM()->config()->permalinks;
7576

76-
UM()->Polylang()->setup()->create_posts( $posts, 'page' );
77+
UM()->Polylang()->posts()->create_posts( $posts, 'page' );
7778

7879
$url = add_query_arg( 'update', 'um_pll_create_pages', admin_url( 'edit.php?post_type=page' ) );
7980
exit( wp_safe_redirect( $url ) );
@@ -95,6 +96,7 @@ public function notice_create_forms() {
9596
if ( empty( $languages ) ) {
9697
return;
9798
}
99+
$def_lang = pll_default_language();
98100

99101
$args = array(
100102
'fields' => 'ids',
@@ -109,10 +111,12 @@ public function notice_create_forms() {
109111

110112
$need_translations = array();
111113
foreach ( $posts as $post => $post_id ) {
114+
if ( $def_lang !== pll_get_post_language( $post_id ) ) {
115+
continue;
116+
}
112117
$post_translations = pll_get_post_translations( $post_id );
113118
if ( array_diff( $languages, array_keys( $post_translations ) ) ) {
114-
$need_translations[] = $post_id;
115-
break;
119+
$need_translations[ $post_id ] = get_the_title( $post_id );
116120
}
117121
}
118122

@@ -129,10 +133,13 @@ public function notice_create_forms() {
129133

130134
<p>
131135
<?php
132-
// translators: %s: Plugin name.
133-
echo wp_kses(
134-
sprintf( __( '%s needs to create required forms for every language to function correctly.', 'um-polylang' ), UM_PLUGIN_NAME ),
135-
UM()->get_allowed_html( 'admin_notice' )
136+
// translators: %1$s - plugin name, %2$s - a list of forms.
137+
echo esc_html(
138+
sprintf(
139+
__( '%1$s needs to create required forms for every language to function correctly. Forms that need translation: %2$s', 'um-polylang' ),
140+
UM_PLUGIN_NAME,
141+
implode( ', ', $need_translations )
142+
)
136143
);
137144
?>
138145
</p>
@@ -170,6 +177,7 @@ public function notice_create_pages() {
170177
if ( empty( $languages ) ) {
171178
return;
172179
}
180+
$def_lang = pll_default_language();
173181

174182
$posts = UM()->config()->permalinks;
175183
if ( empty( $posts ) ) {
@@ -178,10 +186,12 @@ public function notice_create_pages() {
178186

179187
$need_translations = array();
180188
foreach ( $posts as $post => $post_id ) {
189+
if ( $def_lang !== pll_get_post_language( $post_id ) ) {
190+
continue;
191+
}
181192
$post_translations = pll_get_post_translations( $post_id );
182193
if ( array_diff( $languages, array_keys( $post_translations ) ) ) {
183-
$need_translations[] = $post_id;
184-
break;
194+
$need_translations[ $post_id ] = get_the_title( $post_id );
185195
}
186196
}
187197

@@ -198,10 +208,13 @@ public function notice_create_pages() {
198208

199209
<p>
200210
<?php
201-
// translators: %s: Plugin name.
202-
echo wp_kses(
203-
sprintf( __( '%s needs to create required pages for every language to function correctly.', 'um-polylang' ), UM_PLUGIN_NAME ),
204-
UM()->get_allowed_html( 'admin_notice' )
211+
// translators: %1$s - plugin name, %2$s - a list of pages.
212+
echo esc_html(
213+
sprintf(
214+
__( '%1$s needs to create required pages for every language to function correctly. Pages that need translation: %2$s', 'um-polylang' ),
215+
UM_PLUGIN_NAME,
216+
implode( ', ', $need_translations )
217+
)
205218
);
206219
?>
207220
</p>

includes/core/class-permalinks.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class Permalinks {
2424
* Class Permalinks constructor.
2525
*/
2626
public function __construct() {
27+
28+
// Add rewrite rules for the Account and User page.
2729
add_filter( 'rewrite_rules_array', array( &$this, 'add_rewrite_rules' ), 10, 1 );
2830

2931
// Links in emails.
@@ -46,7 +48,7 @@ public function __construct() {
4648

4749

4850
/**
49-
* Add UM rewrite rules for the Account page and Profile page.
51+
* Add rewrite rules for the Account and User page.
5052
*
5153
* @hook rewrite_rules_array
5254
*
@@ -111,6 +113,7 @@ public function add_rewrite_rules( $rules ) {
111113
return array_merge( $newrules, $rules );
112114
}
113115

116+
114117
/**
115118
* Filter the link in the language switcher.
116119
*

includes/core/class-posts.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
/**
3+
* Create translated posts and forms
4+
*
5+
* @package um_ext\um_polylang\core
6+
*/
7+
8+
namespace um_ext\um_polylang\core;
9+
10+
if ( ! defined( 'ABSPATH' ) ) {
11+
exit;
12+
}
13+
14+
/**
15+
* Create translated pages and forms
16+
*
17+
* @package um_ext\um_polylang\core
18+
*/
19+
class Posts {
20+
21+
public function __construct() {
22+
add_action( 'pll_save_post', array( $this, 'pll_save_post' ), 20, 3 );
23+
}
24+
25+
26+
/**
27+
* Create pages and forms for languages.
28+
*
29+
* @since 1.1.0
30+
*
31+
* @param array $posts An array of posts to duplicate.
32+
* @param string $post_type Post type.
33+
*
34+
* @return array Information about posts.
35+
*/
36+
public function create_posts( $posts, $post_type ) {
37+
38+
$languages = pll_languages_list();
39+
if ( empty( $languages ) || empty( $posts ) ) {
40+
return;
41+
}
42+
$def_lang = pll_default_language();
43+
44+
$posts_translations = array();
45+
foreach( $posts as $post => $post_id ) {
46+
$cur_lang = PLL()->model->post->get_language( $post_id );
47+
if ( false === $cur_lang ) {
48+
PLL()->model->post->set_language( $post_id, PLL()->pref_lang );
49+
}
50+
if ( $def_lang !== $cur_lang->get_prop( 'slug' ) ) {
51+
continue;
52+
}
53+
54+
$translations = pll_get_post_translations( $post_id );
55+
$untranslated = array_diff( $languages, array_keys( $translations ) );
56+
57+
if ( $untranslated ) {
58+
$postdata = get_post( $post_id, ARRAY_A );
59+
$postmeta = get_post_meta( $post_id );
60+
61+
foreach ( $untranslated as $lang ) {
62+
$tr_arr = $postdata;
63+
$tr_arr['ID'] = null;
64+
$tr_arr['post_date'] = null;
65+
$tr_arr['post_date_gmt'] = null;
66+
$tr_arr['post_name'] = $tr_arr['post_name'] . '-' . $lang;
67+
$tr_arr['post_title'] = $tr_arr['post_title'] . " ($lang)";
68+
69+
// Polylang need the 'new_lang' parameter to set a proper language.
70+
$_GET['new_lang'] = $lang;
71+
$tr_id = wp_insert_post( $tr_arr );
72+
unset( $_GET['new_lang'] );
73+
74+
// Duplicate postmeta.
75+
foreach ( $postmeta as $key => $value ) {
76+
if ( '_um_core' === $key ) {
77+
continue;
78+
}
79+
$meta_value = maybe_unserialize( $value[0] );
80+
update_post_meta( $tr_id, $key, $meta_value );
81+
}
82+
update_post_meta( $tr_id, '_icl_lang_duplicate_of', $post_id );
83+
84+
$translations[ $lang ] = $tr_id;
85+
do_action( 'um_polylang_create_posts', $tr_id, $post_id, $lang, $post_type );
86+
}
87+
PLL()->model->post->save_translations( $post_id, $translations );
88+
}
89+
90+
$posts_translations[ $post ] = $translations;
91+
}
92+
UM()->rewrite()->reset_rules();
93+
94+
return $posts_translations;
95+
}
96+
97+
98+
/**
99+
* Synchronizes post fields in the page or form translation.
100+
*
101+
* Hook `pll_save_post` fires after the post language and translations are saved.
102+
*
103+
* @see \PLL_CRUD_Posts::save_post()
104+
*
105+
* @since 1.1.1
106+
*
107+
* @param int $tr_id Post id.
108+
* @param WP_Post $post Post object.
109+
* @param int[] $translations Post translations.
110+
*
111+
* @return void
112+
*/
113+
public function pll_save_post( $tr_id, $post, $translations ) {
114+
global $wpdb;
115+
116+
if (
117+
is_a( $post, 'WP_Post' ) && 'auto-draft' === $post->post_status
118+
&& PLL()->model->post->current_user_can_synchronize( $tr_id )
119+
&& isset( $GLOBALS['pagenow'], $_GET['from_post'], $_GET['new_lang'] ) && 'post-new.php' === $GLOBALS['pagenow']
120+
) {
121+
check_admin_referer( 'new-post-translation' );
122+
123+
$lang = sanitize_key( $_GET['new_lang'] );
124+
$post_id = absint( $_GET['from_post'] );
125+
$original = get_post( $post_id );
126+
127+
if ( empty( $original ) ) {
128+
return;
129+
}
130+
131+
if ( 'um_form' === $original->post_type
132+
|| ( 'page' === $original->post_type && in_array( $post_id, UM()->config()->permalinks, true ) )
133+
) {
134+
135+
// Duplicate content.
136+
$wpdb->update(
137+
$wpdb->posts,
138+
array(
139+
'post_content' => $original->post_content,
140+
'post_title' => $original->post_title . " ($lang)",
141+
),
142+
array(
143+
'ID' => $tr_id,
144+
)
145+
);
146+
147+
// Duplicate postmeta.
148+
$postmeta = get_post_meta( $post_id );
149+
foreach ( $postmeta as $key => $value ) {
150+
if ( '_um_core' === $key ) {
151+
continue;
152+
}
153+
$meta_value = maybe_unserialize( $value[0] );
154+
update_post_meta( $tr_id, $key, $meta_value );
155+
}
156+
update_post_meta( $tr_id, '_icl_lang_duplicate_of', $post_id );
157+
}
158+
}
159+
}
160+
161+
}

0 commit comments

Comments
 (0)