1010/**
1111 * Add task to select the site locale.
1212 */
13- class Select_Locale extends Tasks {
13+ class Select_Locale extends Tasks_Interactive {
14+
15+ /**
16+ * The capability required to perform the task.
17+ *
18+ * @var string
19+ */
20+ protected const CAPABILITY = 'install_languages ' ;
1421
1522 /**
1623 * Whether the task is an onboarding task.
@@ -26,13 +33,29 @@ class Select_Locale extends Tasks {
2633 */
2734 protected const PROVIDER_ID = 'select-locale ' ;
2835
36+ /**
37+ * The popover ID.
38+ *
39+ * @var string
40+ */
41+ const POPOVER_ID = 'select-locale ' ;
42+
2943 /**
3044 * Whether the task is dismissable.
3145 *
3246 * @var bool
3347 */
3448 protected $ is_dismissable = true ;
3549
50+ /**
51+ * Initialize the task.
52+ *
53+ * @return void
54+ */
55+ public function init () {
56+ \add_action ( 'wp_ajax_prpl_interactive_task_submit_select-locale ' , [ $ this , 'handle_interactive_task_specific_submit ' ] );
57+ }
58+
3659 /**
3760 * Get the task URL.
3861 *
@@ -144,4 +167,126 @@ function ( $locale ) {
144167 // Return the locales.
145168 return $ locales ;
146169 }
170+
171+ /**
172+ * Check if the task is completed.
173+ *
174+ * @param string $task_id Optional task ID to check completion for.
175+ * @return bool
176+ */
177+ public function is_task_completed ( $ task_id = '' ) {
178+ $ locale_activity = \progress_planner ()->get_activities__query ()->query_activities (
179+ [
180+ 'category ' => 'suggested_task ' ,
181+ 'data_id ' => static ::PROVIDER_ID ,
182+ ]
183+ );
184+
185+ return ! empty ( $ locale_activity );
186+ }
187+
188+ /**
189+ * Get the popover instructions.
190+ *
191+ * @return void
192+ */
193+ public function print_popover_instructions () {
194+ echo '<p> ' . \esc_html__ ( 'Select your site locale to ensure your site is displayed correctly in the correct language ' , 'progress-planner ' ) . '</p> ' ;
195+ }
196+
197+ /**
198+ * Print the popover input field for the form.
199+ *
200+ * @return void
201+ */
202+ public function print_popover_form_contents () {
203+
204+ if ( ! function_exists ( 'wp_get_available_translations ' ) ) {
205+ require_once ABSPATH . 'wp-admin/includes/translation-install.php ' ; // @phpstan-ignore requireOnce.fileNotFound
206+ }
207+
208+ $ languages = \get_available_languages ();
209+ $ translations = \wp_get_available_translations ();
210+ $ locale = \get_locale ();
211+ if ( ! in_array ( $ locale , $ languages , true ) ) {
212+ $ locale = '' ;
213+ }
214+
215+ wp_dropdown_languages (
216+ [
217+ 'name ' => 'language ' ,
218+ 'id ' => 'language ' ,
219+ 'selected ' => $ locale ,
220+ 'languages ' => $ languages ,
221+ 'translations ' => $ translations ,
222+ 'show_available_translations ' => current_user_can ( 'install_languages ' ) && wp_can_install_language_pack (),
223+ ]
224+ );
225+ ?>
226+ <button type="submit" class="prpl-button prpl-button-primary" style="color: #fff;">
227+ <?php \esc_html_e ( 'Select locale ' , 'progress-planner ' ); ?>
228+ </button>
229+ <?php
230+ }
231+
232+ /**
233+ * Handle the interactive task submit.
234+ *
235+ * This is only for interactive tasks that change non-core settings.
236+ * The $_POST data is expected to be:
237+ * - setting: (string) The setting to update.
238+ * - value: (mixed) The value to update the setting to.
239+ * - setting_path: (array) The path to the setting to update.
240+ * Use an empty array if the setting is not nested.
241+ * If the value is nested, use an array of keys.
242+ * Example: [ 'a', 'b', 'c' ] will update the value of $option['a']['b']['c'].
243+ * - nonce: (string) The nonce.
244+ *
245+ * @return void
246+ */
247+ public function handle_interactive_task_specific_submit () {
248+ // Check the nonce.
249+ if ( ! \check_ajax_referer ( 'progress_planner ' , 'nonce ' , false ) ) {
250+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Invalid nonce. ' , 'progress-planner ' ) ] );
251+ }
252+
253+ if ( ! isset ( $ _POST ['setting ' ] ) ) {
254+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Missing setting. ' , 'progress-planner ' ) ] );
255+ }
256+
257+ if ( ! isset ( $ _POST ['value ' ] ) ) {
258+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Missing value. ' , 'progress-planner ' ) ] );
259+ }
260+
261+ if ( ! isset ( $ _POST ['setting_path ' ] ) ) {
262+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Missing setting path. ' , 'progress-planner ' ) ] );
263+ }
264+
265+ $ option_updated = false ;
266+ $ language_for_update = \sanitize_text_field ( \wp_unslash ( $ _POST ['value ' ] ) );
267+
268+ if ( empty ( $ language_for_update ) ) {
269+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Invalid language. ' , 'progress-planner ' ) ] );
270+ }
271+
272+ // Handle translation installation.
273+ if ( current_user_can ( 'install_languages ' ) ) {
274+ require_once ABSPATH . 'wp-admin/includes/translation-install.php ' ; // @phpstan-ignore requireOnce.fileNotFound
275+
276+ if ( wp_can_install_language_pack () ) {
277+ $ language = wp_download_language_pack ( $ language_for_update );
278+ if ( $ language ) {
279+ $ language_for_update = $ language ;
280+
281+ $ option_updated = \update_option ( 'WPLANG ' , $ language_for_update );
282+ }
283+ }
284+ }
285+
286+ if ( $ option_updated ) {
287+ \wp_send_json_success ( [ 'message ' => \esc_html__ ( 'Setting updated. ' , 'progress-planner ' ) ] );
288+ }
289+
290+ \wp_send_json_error ( [ 'message ' => \esc_html__ ( 'Failed to update setting. ' , 'progress-planner ' ) ] );
291+ }
147292}
0 commit comments