PluginProbe
WebberZone Top 10 — Popular Posts / 4.3.0
WebberZone Top 10 — Popular Posts v4.3.0
4.5.2 4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 All 118 releases
top-10 / includes / admin / class-settings-wizard.php

class-settings-wizard.php in WebberZone Top 10 — Popular Posts 4.3.0, at includes/admin/class-settings-wizard.php

390 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings Wizard class.
4 *
5 * @package WebberZone\Top_Ten\Admin
6 */
7
8 namespace WebberZone\Top_Ten\Admin;
9
10 use WebberZone\Top_Ten\Admin\Settings\Settings_Wizard_API;
11 use WebberZone\Top_Ten\Admin\Settings;
12 use function WebberZone\Top_Ten\wz_top_ten;
13
14 // If this file is called directly, abort.
15 if ( ! defined( 'WPINC' ) ) {
16 die;
17 }
18
19 /**
20 * Settings Wizard class for Top 10.
21 *
22 * @since 4.2.0
23 */
24 class Settings_Wizard extends Settings_Wizard_API {
25
26 /**
27 * Main constructor class.
28 *
29 * @since 4.2.0
30 */
31 public function __construct() {
32 $settings_key = 'tptn_settings';
33 $prefix = 'tptn';
34
35 $args = array(
36 'steps' => $this->get_wizard_steps(),
37 'translation_strings' => $this->get_translation_strings(),
38 'page_slug' => 'tptn_wizard',
39 'menu_args' => array(
40 'parent' => 'tptn_options_page',
41 'capability' => 'manage_options',
42 ),
43 );
44
45 parent::__construct( $settings_key, $prefix, $args );
46 $this->additional_hooks();
47 }
48
49 /**
50 * Additional hooks specific to Top 10.
51 *
52 * @since 4.2.0
53 */
54 protected function additional_hooks() {
55 // Trigger wizard setup logic on plugin activation.
56 add_action( 'tptn_activate', array( $this, 'trigger_wizard_on_activation' ) );
57 add_action( 'admin_init', array( $this, 'register_wizard_notice' ) );
58
59 // Register Tom Select AJAX handlers for wizard taxonomy fields.
60 add_action( 'wp_ajax_nopriv_' . $this->prefix . '_taxonomy_search_tom_select', array( Settings::class, 'taxonomy_search_tom_select' ) );
61 add_action( 'wp_ajax_' . $this->prefix . '_taxonomy_search_tom_select', array( Settings::class, 'taxonomy_search_tom_select' ) );
62 }
63
64 /**
65 * Get wizard steps configuration.
66 *
67 * @since 4.2.0
68 *
69 * @return array Wizard steps.
70 */
71 public function get_wizard_steps() {
72 $all_settings_grouped = Settings::get_registered_settings();
73 $all_settings = array();
74 foreach ( $all_settings_grouped as $section_settings ) {
75 $all_settings = array_merge( $all_settings, $section_settings );
76 }
77
78 $basic_settings_keys = array(
79 'add_to',
80 'limit',
81 'post_types',
82 'range_desc',
83 'daily_range',
84 'hour_range',
85 );
86
87 $display_settings_keys = array(
88 'title',
89 'title_daily',
90 'show_excerpt',
91 'show_author',
92 'show_date',
93 'post_thumb_op',
94 'thumb_size',
95 );
96
97 $content_tuning_keys = array(
98 'exclude_front',
99 'exclude_post_ids',
100 'exclude_cat_slugs',
101 'exclude_on_cat_slugs',
102 );
103
104 $admin_settings_keys = array(
105 'show_metabox',
106 'show_metabox_admins',
107 'pv_in_admin',
108 'show_count_non_admins',
109 );
110
111 $pro_settings_keys = array(
112 'use_global_settings',
113 'admin_column_post_types',
114 'show_dashboard_to_roles',
115 'max_execution_time',
116 );
117
118 $steps = array(
119 'welcome' => array(
120 'title' => __( 'Welcome to Top 10', 'top-10' ),
121 'description' => __( 'Thank you for installing Top 10! This wizard will help you configure the essential settings to get your popular posts list working perfectly.', 'top-10' ),
122 'settings' => array(),
123 ),
124 'basic_settings' => array(
125 'title' => __( 'Basic Settings', 'top-10' ),
126 'description' => __( 'Configure how Top 10 tracks and counts your popular posts.', 'top-10' ),
127 'settings' => $this->build_step_settings( $basic_settings_keys, $all_settings ),
128 ),
129 'display_options' => array(
130 'title' => __( 'Display Options', 'top-10' ),
131 'description' => __( 'Customize how your popular posts list will look and what information to display.', 'top-10' ),
132 'settings' => $this->build_step_settings( $display_settings_keys, $all_settings ),
133 ),
134 'content_tuning' => array(
135 'title' => __( 'Content Tuning', 'top-10' ),
136 'description' => __( 'Fine-tune which content is included and how posts are excluded from the list.', 'top-10' ),
137 'settings' => $this->build_step_settings( $content_tuning_keys, $all_settings ),
138 ),
139 'admin_settings' => array(
140 'title' => __( 'Admin Settings', 'top-10' ),
141 'description' => __( 'Configure how Top 10 integrates with your admin area, dashboards, and user roles.', 'top-10' ),
142 'settings' => $this->build_step_settings( $admin_settings_keys, $all_settings ),
143 ),
144 'pro_settings' => array(
145 'title' => __( 'Pro Settings', 'top-10' ),
146 'description' => __( 'Configure Pro-only options such as global block settings, category exclusions, and query optimisation. These features require Top 10 Pro.', 'top-10' ),
147 'settings' => $this->build_step_settings( $pro_settings_keys, $all_settings ),
148 ),
149 );
150
151 /**
152 * Filter wizard steps.
153 *
154 * @param array $steps Wizard steps.
155 */
156 return apply_filters( 'tptn_wizard_steps', $steps );
157 }
158
159 /**
160 * Build settings array for a wizard step from keys.
161 *
162 * @since 4.2.0
163 *
164 * @param array $keys Setting keys for this step.
165 * @param array $all_settings All settings array.
166 * @return array
167 */
168 protected function build_step_settings( $keys, $all_settings ) {
169 $step_settings = array();
170
171 foreach ( $keys as $key ) {
172 if ( isset( $all_settings[ $key ] ) ) {
173 $step_settings[ $key ] = $all_settings[ $key ];
174 }
175 }
176
177 return $step_settings;
178 }
179
180 /**
181 * Get translation strings for the wizard.
182 *
183 * @since 4.2.0
184 *
185 * @return array Translation strings.
186 */
187 public function get_translation_strings() {
188 return array(
189 'page_title' => __( 'Top 10 Setup Wizard', 'top-10' ),
190 'menu_title' => __( 'Setup Wizard', 'top-10' ),
191 'next_step' => __( 'Next Step', 'top-10' ),
192 'previous_step' => __( 'Previous Step', 'top-10' ),
193 'finish_setup' => __( 'Finish Setup', 'top-10' ),
194 'skip_wizard' => __( 'Skip Wizard', 'top-10' ),
195 /* translators: %s: Search query. */
196 'tom_select_no_results' => __( 'No results found for "%s"', 'top-10' ),
197 'steps_nav_aria_label' => __( 'Setup Wizard Steps', 'top-10' ),
198 /* translators: %1$d: Current step number, %2$d: Total number of steps */
199 'step_of' => __( 'Step %1$d of %2$d', 'top-10' ),
200 'wizard_complete' => __( 'Setup Complete!', 'top-10' ),
201 'setup_complete' => __( 'Your Top 10 plugin has been configured successfully. You can now start displaying popular posts on your site!', 'top-10' ),
202 'go_to_settings' => __( 'Go to Settings', 'top-10' ),
203 'checkbox_modified' => __( 'Modified from default setting', 'top-10' ),
204 );
205 }
206
207 /**
208 * Trigger wizard on plugin activation.
209 *
210 * @since 4.2.0
211 */
212 public function trigger_wizard_on_activation() {
213 // Set a transient that will trigger the wizard on first admin page visit.
214 // This works better than an option because it's temporary and won't persist
215 // if the wizard is never accessed.
216 set_transient( 'tptn_show_wizard_activation_redirect', true, HOUR_IN_SECONDS );
217
218 // Also set an option for more persistent storage in multisite environments.
219 update_option( 'tptn_show_wizard', true );
220 }
221
222 /**
223 * Register the wizard notice with the Admin_Notices_API.
224 *
225 * @since 4.2.0
226 */
227 public function register_wizard_notice() {
228 $admin_notices_api = wz_top_ten()->admin->admin_notices_api;
229 if ( ! $admin_notices_api ) {
230 return;
231 }
232
233 $admin_notices_api->register_notice(
234 array(
235 'id' => 'tptn_wizard_notice',
236 'message' => sprintf(
237 '<p>%s</p><p><a href="%s" class="button button-primary">%s</a></p>',
238 esc_html__( 'Welcome to Top 10! Would you like to run the setup wizard to configure the plugin?', 'top-10' ),
239 esc_url( admin_url( 'admin.php?page=tptn_wizard' ) ),
240 esc_html__( 'Run Setup Wizard', 'top-10' )
241 ),
242 'type' => 'info',
243 'dismissible' => true,
244 'capability' => 'manage_options',
245 'conditions' => array(
246 function () {
247 $page = sanitize_key( (string) filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
248
249 return ! $this->is_wizard_completed() &&
250 ! get_option( 'tptn_wizard_notice_dismissed', false ) &&
251 ( get_transient( 'tptn_show_wizard_activation_redirect' ) || get_option( 'tptn_show_wizard', false ) ) &&
252 'tptn_wizard' !== $page;
253 },
254 ),
255 )
256 );
257 }
258
259 /**
260 * Get the URL to redirect to after wizard completion.
261 *
262 * @since 4.2.0
263 *
264 * @return string Redirect URL.
265 */
266 protected function get_completion_redirect_url() {
267 return admin_url( 'admin.php?page=tptn_options_page' );
268 }
269
270 /**
271 * Override render_wizard_page to handle custom steps.
272 *
273 * @since 4.2.0
274 */
275 public function render_wizard_page() {
276 $this->current_step = $this->get_current_step();
277 $step_config = $this->get_current_step_config();
278
279 if ( empty( $step_config ) ) {
280 $this->render_completion_page();
281 return;
282 }
283
284 // Check if this is a custom step.
285 if ( ! empty( $step_config['custom_step'] ) ) {
286 $this->render_custom_tables_step( $step_config );
287 return;
288 }
289
290 // Use parent method for regular steps.
291 parent::render_wizard_page();
292 }
293
294 /**
295 * Render the custom tables indexing step.
296 *
297 * @since 4.2.0
298 *
299 * @param array $step_config Step configuration.
300 */
301 protected function render_custom_tables_step( $step_config ) {
302 ?>
303 <div class="wrap wizard-wrap">
304 <h1><?php echo esc_html( $this->translation_strings['wizard_title'] ); ?></h1>
305
306 <?php $this->render_wizard_steps_navigation(); ?>
307
308 <div class="wizard-progress">
309 <div class="wizard-progress-bar">
310 <div class="wizard-progress-fill" style="width: <?php echo esc_attr( (string) ( ( $this->current_step / $this->total_steps ) * 100 ) ); ?>%;"></div>
311 </div>
312 <p class="wizard-step-counter">
313 <?php
314 printf(
315 esc_html( $this->translation_strings['step_of'] ),
316 esc_html( (string) $this->current_step ),
317 esc_html( (string) $this->total_steps )
318 );
319 ?>
320 </p>
321 </div>
322
323 <div class="wizard-content">
324 <div class="wizard-step">
325 <h2><?php echo esc_html( $step_config['title'] ?? '' ); ?></h2>
326
327 <?php if ( ! empty( $step_config['description'] ) ) : ?>
328 <p class="wizard-step-description"><?php echo wp_kses_post( $step_config['description'] ); ?></p>
329 <?php endif; ?>
330
331 <form method="post" action="">
332 <?php wp_nonce_field( "{$this->prefix}_wizard_nonce", "{$this->prefix}_wizard_nonce" ); ?>
333
334 <div class="wizard-fields">
335 <?php $this->render_custom_tables_interface(); ?>
336 </div>
337
338 <div class="wizard-actions">
339 <?php $this->render_wizard_buttons(); ?>
340 </div>
341 </form>
342 </div>
343 </div>
344 </div>
345 <?php
346 }
347
348 /**
349 * Render the custom tables indexing interface.
350 *
351 * @since 4.2.0
352 */
353 protected function render_custom_tables_interface() {
354 // Top 10 does not implement the CRP custom tables UI in its wizard.
355 // Intentionally left blank.
356 }
357
358 /**
359 * Override the render completion page to show Top 10 specific content.
360 *
361 * @since 4.2.0
362 */
363 protected function render_completion_page() {
364 ?>
365 <div class="wrap wizard-wrap wizard-complete">
366 <div class="wizard-completion-header">
367 <h1><?php echo esc_html( $this->translation_strings['wizard_complete'] ); ?></h1>
368 <p class="wizard-completion-message">
369 <?php echo esc_html( $this->translation_strings['setup_complete'] ); ?>
370 </p>
371 </div>
372
373 <div class="wizard-completion-content">
374 <div class="wizard-completion-actions">
375 <a href="<?php echo esc_url( $this->get_completion_redirect_url() ); ?>" class="button button-primary button-large">
376 <?php esc_html_e( 'Go to Settings', 'top-10' ); ?>
377 </a>
378 <a href="<?php echo esc_url( admin_url( 'admin.php?page=tptn_tools_page' ) ); ?>" class="button button-secondary button-large">
379 <?php esc_html_e( 'Go to Tools', 'top-10' ); ?>
380 </a>
381 <a href="<?php echo esc_url( home_url( '/' ) ); ?>" class="button button-secondary button-large" target="_blank" rel="noopener noreferrer">
382 <?php esc_html_e( 'View Site', 'top-10' ); ?>
383 </a>
384 </div>
385 </div>
386 </div>
387 <?php
388 }
389 }
390