PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.2
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.2
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
metasync / includes / class-metasync-setup-wizard.php

class-metasync-setup-wizard.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.7.2, at includes/class-metasync-setup-wizard.php

568 lines 17.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The setup wizard functionality of the plugin
5 *
6 * @link https://searchatlas.com
7 * @since 1.0.0
8 *
9 * @package Metasync
10 * @subpackage Metasync/includes
11 */
12
13 /**
14 * The setup wizard class.
15 *
16 * This class handles the setup wizard functionality for first-time plugin setup.
17 * Guides users through connecting the platform, importing from other SEO plugins,
18 * and configuring basic SEO settings.
19 *
20 * @since 1.0.0
21 * @package Metasync
22 * @subpackage Metasync/includes
23 * @author Engineering Team <[email protected]>
24 */
25 class Metasync_Setup_Wizard
26 {
27 /**
28 * The ID of this plugin.
29 *
30 * @since 1.0.0
31 * @access private
32 * @var string $plugin_name The ID of this plugin.
33 */
34 private $plugin_name;
35
36 /**
37 * The version of this plugin.
38 *
39 * @since 1.0.0
40 * @access private
41 * @var string $version The current version of this plugin.
42 */
43 private $version;
44
45 /**
46 * Total number of wizard steps
47 *
48 * @since 1.0.0
49 * @access private
50 * @var int
51 */
52 private $total_steps = 6;
53
54 /**
55 * Initialize the class and set its properties.
56 *
57 * @since 1.0.0
58 * @param string $plugin_name The name of this plugin.
59 * @param string $version The version of this plugin.
60 */
61 public function __construct($plugin_name, $version)
62 {
63 $this->plugin_name = $plugin_name;
64 $this->version = $version;
65 }
66
67 /**
68 * Check if wizard should auto-launch
69 *
70 * @since 1.0.0
71 * @return boolean
72 */
73 public function should_auto_launch_wizard()
74 {
75 // Check if wizard has been completed
76 $wizard_completed = get_option('metasync_wizard_completed', false);
77
78 if ($wizard_completed && !empty($wizard_completed['completed'])) {
79 return false;
80 }
81
82 // Check if first activation flag is set
83 return get_option('metasync_show_wizard', false);
84 }
85
86 /**
87 * Render the setup wizard page
88 *
89 * @since 1.0.0
90 */
91 public function render_wizard_page()
92 {
93 // Check user has access
94 if (!Metasync::current_user_has_plugin_access()) {
95 wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'metasync'));
96 }
97
98 // Get current wizard state
99 $user_id = get_current_user_id();
100 $wizard_state = get_transient("metasync_wizard_state_{$user_id}");
101
102 if (!$wizard_state) {
103 // Initialize wizard state
104 $wizard_state = array(
105 'current_step' => 1,
106 'completed_steps' => array(),
107 'started_at' => time(),
108 'user_id' => $user_id
109 );
110 set_transient("metasync_wizard_state_{$user_id}", $wizard_state, DAY_IN_SECONDS);
111 }
112
113 // Load wizard template
114 require_once plugin_dir_path(dirname(__FILE__)) . 'views/metasync-setup-wizard.php';
115 }
116
117 /**
118 * Get all wizard steps configuration
119 *
120 * @since 1.0.0
121 * @return array
122 */
123 private function get_wizard_steps()
124 {
125 return array(
126 1 => array(
127 'id' => 'welcome',
128 'title' => 'Welcome',
129 'description' => 'Welcome to MetaSync'
130 ),
131 2 => array(
132 'id' => 'connection',
133 'title' => 'Connect',
134 'description' => 'Connect to platform'
135 ),
136 3 => array(
137 'id' => 'import',
138 'title' => 'Import',
139 'description' => 'Import from other plugins'
140 ),
141 4 => array(
142 'id' => 'seo_settings',
143 'title' => 'SEO Settings',
144 'description' => 'Configure indexation'
145 ),
146 5 => array(
147 'id' => 'schema',
148 'title' => 'Schema',
149 'description' => 'Schema preferences'
150 ),
151 6 => array(
152 'id' => 'complete',
153 'title' => 'Complete',
154 'description' => 'Setup complete'
155 )
156 );
157 }
158
159 /**
160 * Render Step 1: Welcome Screen
161 *
162 * @since 1.0.0
163 */
164 public function render_step_welcome()
165 {
166 $plugin_name = Metasync::get_effective_plugin_name();
167 ?>
168 <div class="wizard-step wizard-step-welcome active" data-step="1">
169 <div class="wizard-step-header">
170 <h2>🎉 Welcome to <?php echo esc_html($plugin_name); ?>!</h2>
171 <p>Let's get your site optimized for search engines in just a few minutes.</p>
172 </div>
173
174 <div class="wizard-step-content">
175 <div class="wizard-benefits">
176 <div class="wizard-benefit-card">
177 <span class="benefit-icon"><span class="dashicons dashicons-performance" style="font-size:24px;width:24px;height:24px;"></span></span>
178 <h3>Automated SEO</h3>
179 <p>Automatically optimize your content for search engines</p>
180 </div>
181 <div class="wizard-benefit-card">
182 <span class="benefit-icon"><span class="dashicons dashicons-chart-bar" style="font-size:24px;width:24px;height:24px;"></span></span>
183 <h3>Performance Tracking</h3>
184 <p>Monitor your site's search performance in real-time</p>
185 </div>
186 <div class="wizard-benefit-card">
187 <span class="benefit-icon"><span class="dashicons dashicons-admin-links" style="font-size:24px;width:24px;height:24px;"></span></span>
188 <h3>Seamless Integration</h3>
189 <p>Connect with <?php echo esc_html($plugin_name); ?> for advanced features</p>
190 </div>
191 </div>
192
193 <div class="wizard-time-estimate">
194 <span>Estimated time: 3-5 minutes</span>
195 </div>
196 </div>
197 </div>
198 <?php
199 }
200
201 /**
202 * Render Step 2: Connection
203 *
204 * @since 1.0.0
205 */
206 public function render_step_connection()
207 {
208 $plugin_name = Metasync::get_effective_plugin_name();
209 $general_settings = Metasync::get_option('general');
210 $is_connected = !empty($general_settings['searchatlas_api_key']);
211 $analytics_enabled = get_option('metasync_analytics_opt_in', 'no') === 'yes';
212 ?>
213 <div class="wizard-step wizard-step-connection" data-step="2">
214 <div class="wizard-step-header">
215 <h2>Connect to <?php echo esc_html($plugin_name); ?></h2>
216 <p>Link your WordPress site to your <?php echo esc_html($plugin_name); ?> account for advanced features.</p>
217 </div>
218
219 <div class="wizard-step-content">
220 <?php if (!$is_connected): ?>
221 <div class="wizard-connection-box">
222 <p><strong>Why connect?</strong></p>
223 <ul>
224 <li>Access OTTO AI-powered SEO assistant</li>
225 <li>Get real-time search ranking data</li>
226 <li>Receive automated optimization suggestions</li>
227 </ul>
228
229 <button id="wizard-connect-btn" class="wizard-primary-btn">
230 Connect with <?php echo esc_html($plugin_name); ?>
231 </button>
232 </div>
233 <?php else: ?>
234 <div class="wizard-connection-success">
235 <span class="success-icon">✓</span>
236 <h3>Successfully Connected!</h3>
237 <p>Your site is linked to <?php echo esc_html($plugin_name); ?>.</p>
238 </div>
239 <?php endif; ?>
240
241 <div class="wizard-consent-card">
242 <div class="wizard-consent-icon"><span class="dashicons dashicons-chart-bar"></span></div>
243 <div class="wizard-consent-copy">
244 <span class="wizard-consent-eyebrow">Optional</span>
245 <h3>Help improve <?php echo esc_html($plugin_name); ?></h3>
246 <p>Share limited usage data so we can understand which features are useful, prioritize improvements, and troubleshoot plugin issues.</p>
247 <ul>
248 <li>Includes your site URL, plugin version, WordPress environment, and feature usage</li>
249 <li>Never includes names, emails, customer content, API keys, or passwords</li>
250 </ul>
251 <p class="wizard-consent-note">You can change this at any time in General Settings.</p>
252 </div>
253 <label class="wizard-consent-switch" for="wizard-analytics-consent">
254 <input type="checkbox" id="wizard-analytics-consent" <?php checked($analytics_enabled); ?>>
255 <span class="wizard-consent-slider" aria-hidden="true"></span>
256 <span class="wizard-consent-state"><?php echo $analytics_enabled ? 'On' : 'Off'; ?></span>
257 </label>
258 </div>
259 </div>
260 </div>
261 <?php
262 }
263
264 /**
265 * Render Step 3: Plugin Import
266 *
267 * @since 1.0.0
268 */
269 public function render_step_import()
270 {
271 $installed_plugins = $this->detect_seo_plugins();
272 ?>
273 <div class="wizard-step wizard-step-import" data-step="3">
274 <div class="wizard-step-header">
275 <h2>Import from Other SEO Plugins</h2>
276 <p>We detected other SEO plugins. Import your existing settings to save time.</p>
277 </div>
278
279 <div class="wizard-step-content">
280 <?php if (!empty($installed_plugins)): ?>
281 <div class="wizard-import-grid">
282 <?php foreach ($installed_plugins as $plugin): ?>
283 <div class="wizard-import-card">
284 <div class="import-card-header">
285 <h3><?php echo esc_html($plugin['name']); ?></h3>
286 <span class="import-badge">Detected</span>
287 </div>
288
289 <div class="import-card-options">
290 <label>
291 <input type="checkbox" class="import-option"
292 data-plugin="<?php echo esc_attr($plugin['slug']); ?>"
293 data-type="robots">
294 Robots.txt
295 </label>
296 <label>
297 <input type="checkbox" class="import-option"
298 data-plugin="<?php echo esc_attr($plugin['slug']); ?>"
299 data-type="sitemap">
300 Sitemap Settings
301 </label>
302 <label>
303 <input type="checkbox" class="import-option"
304 data-plugin="<?php echo esc_attr($plugin['slug']); ?>"
305 data-type="redirections">
306 Redirections
307 </label>
308 <label>
309 <input type="checkbox" class="import-option"
310 data-plugin="<?php echo esc_attr($plugin['slug']); ?>"
311 data-type="indexation">
312 Indexation/Robots Meta
313 </label>
314 <label>
315 <input type="checkbox" class="import-option"
316 data-plugin="<?php echo esc_attr($plugin['slug']); ?>"
317 data-type="schema">
318 Schema Markup
319 </label>
320 </div>
321
322 <div class="import-card-footer">
323 <button class="wizard-import-btn"
324 data-plugin="<?php echo esc_attr($plugin['slug']); ?>">
325 Import Selected
326 </button>
327 <div class="import-progress" style="display:none;">
328 <div class="import-progress-bar"></div>
329 <span class="import-progress-text">Importing...</span>
330 </div>
331 </div>
332 </div>
333 <?php endforeach; ?>
334 </div>
335 <?php else: ?>
336 <div class="wizard-no-imports">
337 <p>No compatible SEO plugins detected. You can skip this step.</p>
338 </div>
339 <?php endif; ?>
340 </div>
341 </div>
342 <?php
343 }
344
345
346 /**
347 * Render Step 4: SEO Settings (Indexation Controls)
348 *
349 * @since 1.0.0
350 */
351 public function render_step_seo_settings()
352 {
353 $seo_controls = Metasync::get_option('seo_controls') ?: array();
354 ?>
355 <div class="wizard-step wizard-step-seo" data-step="4">
356 <div class="wizard-step-header">
357 <h2>Basic SEO Settings</h2>
358 <p>Choose which archive types should be indexed by search engines.</p>
359 </div>
360
361 <div class="wizard-step-content">
362 <div class="wizard-seo-grid">
363 <div class="wizard-seo-card">
364 <h3>Archive Types</h3>
365 <p>Control which WordPress archives are visible to search engines.</p>
366
367 <div class="wizard-toggle-group">
368 <label class="wizard-toggle-label">
369 <input type="checkbox" name="seo_date_archives"
370 <?php checked(!isset($seo_controls['index_date_archives']) || $seo_controls['index_date_archives'] !== 'true'); ?>>
371 <span>Index Date Archives</span>
372 </label>
373
374 <label class="wizard-toggle-label">
375 <input type="checkbox" name="seo_author_archives"
376 <?php checked(!isset($seo_controls['index_author_archives']) || $seo_controls['index_author_archives'] !== 'true'); ?>>
377 <span>Index Author Archives</span>
378 </label>
379
380 <label class="wizard-toggle-label">
381 <input type="checkbox" name="seo_category_archives"
382 <?php checked(!isset($seo_controls['index_category_archives']) || $seo_controls['index_category_archives'] !== 'true'); ?>>
383 <span>Index Category Archives</span>
384 </label>
385
386 <label class="wizard-toggle-label">
387 <input type="checkbox" name="seo_tag_archives"
388 <?php checked(!isset($seo_controls['index_tag_archives']) || $seo_controls['index_tag_archives'] !== 'true'); ?>>
389 <span>Index Tag Archives</span>
390 </label>
391 </div>
392 </div>
393
394 <div class="wizard-recommendation-box">
395 <h4>Recommended Settings</h4>
396 <p>For most sites, we recommend:</p>
397 <ul>
398 <li>✓ Index Category and Tag archives (helps with SEO)</li>
399 <li>✗ Noindex Date archives (usually duplicate content)</li>
400 <li>✗ Noindex Author archives (unless multi-author blog)</li>
401 </ul>
402 <button class="wizard-apply-recommended">Apply Recommended</button>
403 </div>
404 </div>
405 </div>
406 </div>
407 <?php
408 }
409
410 /**
411 * Render Step 5: Schema Preferences
412 *
413 * @since 1.0.0
414 */
415 public function render_step_schema()
416 {
417 $general_settings = Metasync::get_option('general');
418 $schema_enabled = !empty($general_settings['enable_schema_markup']);
419 ?>
420 <div class="wizard-step wizard-step-schema" data-step="5">
421 <div class="wizard-step-header">
422 <h2>Schema Markup Preferences</h2>
423 <p>Configure structured data to help search engines understand your content.</p>
424 </div>
425
426 <div class="wizard-step-content">
427 <div class="wizard-schema-enable">
428 <label class="wizard-toggle-label-large">
429 <input type="checkbox" id="schema-enabled" name="schema_enabled"
430 <?php checked($schema_enabled); ?>>
431 <span>Enable Automatic Schema Markup</span>
432 </label>
433 <p class="wizard-field-help">
434 Schema markup helps search engines display rich snippets in search results.
435 </p>
436 </div>
437
438 <div class="wizard-schema-settings" style="display: <?php echo $schema_enabled ? 'block' : 'none'; ?>;">
439 <h3>Default Schema Types</h3>
440
441 <div class="wizard-schema-types">
442 <label class="wizard-schema-type-card">
443 <input type="radio" name="default_schema_type" value="article"
444 <?php checked(($general_settings['default_schema_type'] ?? 'article') === 'article'); ?>>
445 <div class="schema-type-content">
446 <span class="schema-type-icon"><span class="dashicons dashicons-media-text" style="font-size:24px;width:24px;height:24px;"></span></span>
447 <h4>Article</h4>
448 <p>Best for blog posts and news articles</p>
449 </div>
450 </label>
451
452 <label class="wizard-schema-type-card">
453 <input type="radio" name="default_schema_type" value="webpage"
454 <?php checked(($general_settings['default_schema_type'] ?? '') === 'webpage'); ?>>
455 <div class="schema-type-content">
456 <span class="schema-type-icon"><span class="dashicons dashicons-media-default" style="font-size:24px;width:24px;height:24px;"></span></span>
457 <h4>WebPage</h4>
458 <p>Best for general website pages</p>
459 </div>
460 </label>
461
462 <label class="wizard-schema-type-card">
463 <input type="radio" name="default_schema_type" value="product"
464 <?php checked(($general_settings['default_schema_type'] ?? '') === 'product'); ?>>
465 <div class="schema-type-content">
466 <span class="schema-type-icon"><span class="dashicons dashicons-cart" style="font-size:24px;width:24px;height:24px;"></span></span>
467 <h4>Product</h4>
468 <p>Best for e-commerce sites</p>
469 </div>
470 </label>
471 </div>
472 </div>
473 </div>
474 </div>
475 <?php
476 }
477
478 /**
479 * Render Step 7: Completion Screen
480 *
481 * @since 1.0.0
482 */
483 public function render_step_complete()
484 {
485 $menu_slug = 'searchatlas';
486 $data = Metasync::get_option('general');
487 if (!empty($data['white_label_plugin_menu_slug'])) {
488 $menu_slug = $data['white_label_plugin_menu_slug'];
489 }
490 ?>
491 <div class="wizard-step wizard-step-complete" data-step="6">
492 <div class="wizard-step-header">
493 <div class="wizard-complete-icon">🎉</div>
494 <h2>Setup Complete!</h2>
495 <p>Your site is now optimized for search engines.</p>
496 </div>
497
498 <div class="wizard-step-content">
499 <div class="wizard-complete-summary">
500 <h3>What's Next?</h3>
501
502 <div class="wizard-next-steps">
503 <div class="wizard-next-step-card">
504 <span class="next-step-number">1</span>
505 <div class="next-step-content">
506 <h4>Explore the Dashboard</h4>
507 <p>View your SEO performance metrics and insights</p>
508 <a href="?page=<?php echo esc_attr($menu_slug); ?>-dashboard"
509 class="wizard-next-step-link">View Dashboard →</a>
510 </div>
511 </div>
512
513 <div class="wizard-next-step-card">
514 <span class="next-step-number">2</span>
515 <div class="next-step-content">
516 <h4>Optimize Your Content</h4>
517 <p>Start optimizing individual posts and pages</p>
518 <a href="<?php echo esc_url(admin_url('edit.php')); ?>"
519 class="wizard-next-step-link">View Posts →</a>
520 </div>
521 </div>
522
523 <div class="wizard-next-step-card">
524 <span class="next-step-number">3</span>
525 <div class="next-step-content">
526 <h4>Fine-Tune Settings</h4>
527 <p>Adjust advanced SEO settings for your specific needs</p>
528 <a href="?page=<?php echo esc_attr($menu_slug); ?>"
529 class="wizard-next-step-link">View Settings →</a>
530 </div>
531 </div>
532 </div>
533 </div>
534
535 <div class="wizard-complete-actions">
536 <button class="wizard-primary-btn wizard-complete-btn">
537 Get Started with <?php echo esc_html(Metasync::get_effective_plugin_name()); ?>
538 </button>
539 </div>
540 </div>
541 </div>
542 <?php
543 }
544
545 /**
546 * Detect installed SEO plugins
547 *
548 * @since 1.0.0
549 * @return array
550 */
551 private function detect_seo_plugins()
552 {
553 $detected = array();
554
555 if (defined('WPSEO_VERSION')) {
556 $detected[] = array('name' => 'Yoast SEO', 'slug' => 'yoast');
557 }
558 if (defined('RANK_MATH_VERSION')) {
559 $detected[] = array('name' => 'Rank Math', 'slug' => 'rankmath');
560 }
561 if (defined('AIOSEO_VERSION')) {
562 $detected[] = array('name' => 'All in One SEO', 'slug' => 'aioseo');
563 }
564
565 return $detected;
566 }
567 }
568