PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.5.23
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.5.23
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 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / metasync.php

metasync.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.5.23, at metasync.php

802 lines 28.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is read by WordPress to generate the plugin information in the plugin
5 * admin area. This file also includes all of the dependencies used by the plugin,
6 * registers the activation and deactivation functions, and defines a function
7 * that starts the plugin.
8 *
9 * @package Search Atlas SEO
10 * @copyright Copyright (C) 2021-2025, Search Atlas Group - support@searchatlas.com
11 * @link https://searchatlas.com/
12 * @since 1.0.0
13 *
14 * @wordpress-plugin
15 * Plugin Name: Search Atlas: The Premier AI SEO Plugin for Instant Optimization
16 * Plugin URI: https://searchatlas.com/
17 * Description: Search Atlas SEO is an intuitive WordPress Plugin that transforms the most complicated, most labor-intensive SEO tasks into streamlined, straightforward processes. With a few clicks, the meta-bulk update feature automates the re-optimization of meta tags using AI to increase clicks. Stay up-to-date with the freshest Google Search data for your entire site or targeted URLs within the Meta Sync plug-in page.
18 * Version: 2.5.23
19 * Author: Search Atlas
20 * Author URI: https://searchatlas.com
21 * License: GPL v3
22 * License URI: https://www.gnu.org/licenses/gpl-3.0.txt
23 * Text Domain: metasync
24 */
25
26 // If this file is called directly, abort.
27 if (!defined('WPINC')) {
28 die;
29 }
30
31 /**
32 * Currently plugin version.
33 * Start at version 1.0.0 and use SemVer - https://semver.org
34 * Rename this for your plugin and update it as you release new versions.
35 */
36 $metasync_version = '2.5.23';
37 define('METASYNC_VERSION', preg_match('/^\d+\.\d+/', $metasync_version) ? $metasync_version : '9.9.9');
38 /**
39 * Define the current required php version
40 * This will be used to validate whether the user can install the plugin or not
41 */
42 define('METASYNC_MIN_PHP', '8.2');
43
44 /**
45 * Define the current required php version
46 * This will be used to validate whether the user can install the plugin or not
47 */
48 define('METASYNC_MIN_WP', '5.2');
49
50 /**
51 * Telemetry Configuration Constants
52 * These replace the old database options for better security and consistency
53 */
54 define('METASYNC_SENTRY_PROJECT_ID', '4509950439849985');
55 define('METASYNC_SENTRY_ENVIRONMENT', 'production');
56 define('METASYNC_SENTRY_RELEASE', METASYNC_VERSION);
57 define('METASYNC_SENTRY_SAMPLE_RATE', 1.0);
58
59 /**
60 * Mixpanel Analytics Configuration
61 * Project token for usage tracking
62 *
63 * IMPORTANT: This constant is REQUIRED for Mixpanel tracking to function.
64 * If not defined or empty, all analytics tracking will be disabled.
65 *
66 * To disable tracking: Comment out this line or set to empty string
67 */
68
69 define('METASYNC_MIXPANEL_TOKEN', '90374a20c197bd2eb8312e0706e3b458');
70
71 /**
72 * Define whether to show the plugin status in WordPress admin top navigation bar
73 * Set to false to hide the status indicator
74 */
75 define('METASYNC_SHOW_ADMIN_BAR_STATUS', true);
76
77 /**
78 * Sanitize POST/GET/REQUEST data recursively
79 *
80 * @param array $data Data to sanitize
81 * @return array Sanitized data
82 */
83 if (!function_exists('metasync_sanitize_input_array')) {
84 function metasync_sanitize_input_array($data) {
85 if (!is_array($data)) {
86 return sanitize_text_field($data);
87 }
88
89 $sanitized = [];
90 foreach ($data as $key => $value) {
91 if (is_array($value)) {
92 $sanitized[$key] = metasync_sanitize_input_array($value);
93 } else {
94 // Check if it's a URL
95 if (filter_var($value, FILTER_VALIDATE_URL)) {
96 $sanitized[$key] = esc_url_raw($value);
97 } else {
98 $sanitized[$key] = sanitize_text_field($value);
99 }
100 }
101 }
102 return $sanitized;
103 }
104 }
105
106 /**
107 * Include the Redirection class early (provides regex pattern utilities used across the plugin)
108 */
109 require_once plugin_dir_path( __FILE__ ) . 'redirections/class-metasync-redirection.php';
110
111 /**
112 * Centralized class loading function
113 */
114 function metasync_load_class($class_name) {
115 $class_map = [
116 'Metasync_Sync_History_Database' => 'sync-history/class-metasync-sync-history-database.php',
117 //'Metasync_Admin' => 'admin/class-metasync-admin.php',
118 //'Metasync_Public' => 'public/class-metasync-public.php',
119 //'Metasync_Activator' => 'includes/class-metasync-activator.php',
120 //'MetaSync_DBMigration' => 'database/class-db-migrations.php',
121 // Add more classes as needed
122 ];
123
124 if (isset($class_map[$class_name])) {
125 $file_path = plugin_dir_path(__FILE__) . $class_map[$class_name];
126 if (file_exists($file_path)) {
127 require_once $file_path;
128 }
129 }
130 }
131
132 // Register the autoloader
133 spl_autoload_register('metasync_load_class');
134
135 /**
136 * Include the Session Helper (must load before other classes that use it)
137 * @deprecated 2.5.12 - Kept for backward compatibility only
138 */
139 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-session-helper.php';
140
141 /**
142 * Include the Auth Manager (WordPress-native authentication without sessions)
143 * @since 2.5.12
144 */
145 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-auth-manager.php';
146
147 /**
148 * Include the Cache Purge Handler
149 */
150 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-cache-purge.php';
151
152 /**
153 * Include the Edge Cache / CDN Purge Handler
154 */
155 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-edge-cache-purge.php';
156
157 /**
158 * Include the API Backoff Manager
159 * Handles exponential backoff for HTTP 429/503 responses
160 * @since 2.7.1
161 */
162 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-api-backoff-manager.php';
163
164 /**
165 * Include the API Backoff Admin Notices
166 * Displays admin notices when API endpoints are in backoff mode
167 * @since 2.7.1
168 */
169 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-api-backoff-notices.php';
170
171 /**
172 * Include the API Backoff REST API
173 * Provides REST endpoints for backoff management and monitoring
174 * @since 2.7.1
175 */
176 require_once plugin_dir_path( __FILE__ ) . 'includes/class-metasync-api-backoff-rest.php';
177
178 /**
179 * Include the Otto Pixel Php Code
180 */
181 require_once plugin_dir_path( __FILE__ ) . '/otto/otto_pixel.php';
182
183 /**
184 * Include the Otto Persistence Settings
185 * Handles configuration for which OTTO data should be saved to native WordPress fields
186 */
187 require_once plugin_dir_path( __FILE__ ) . '/otto/class-metasync-otto-persistence-settings.php';
188
189 /**
190 * Include the Otto Persistence Handler
191 * Handles actual persistence of OTTO data to native WordPress fields
192 */
193 require_once plugin_dir_path( __FILE__ ) . '/otto/class-metasync-otto-persistence-handler.php';
194
195 /**
196 * Initialize OTTO Persistence Settings (registers REST API endpoints)
197 */
198 add_action('init', function() {
199 Metasync_Otto_Persistence_Settings::init();
200 }, 5);
201
202 /**
203 * The code that runs during plugin activation.
204 * This action is documented in includes/class-metasync-activator.php
205 */
206 function activate_metasync()
207 {
208 # Include WordPress plugin functions to access plugin metadata
209 if (!function_exists('get_plugin_data')) {
210 require_once ABSPATH . 'wp-admin/includes/plugin.php';
211 }
212
213 # Get plugin data
214 $plugin_data = get_plugin_data(__FILE__);
215
216 # Get the plugin name
217 $plugin_name = $plugin_data['Name'];
218
219 # Get the current WordPress
220 global $wp_version;
221
222 # Get the current php version
223 $php_version = PHP_VERSION;
224
225 # Check for incompatible WordPress version
226 if (version_compare($wp_version, METASYNC_MIN_WP, '<')) {
227
228 #show error
229 wp_die(
230
231 #craft the message
232 sprintf(
233 '%s requires WordPress version %s or later. You are currently using version %s. Please update WordPress to activate this plugin.',
234 esc_html($plugin_name),
235 METASYNC_MIN_WP,
236 esc_html($wp_version)
237 ),
238
239 #the plugin title as page title
240 esc_html($plugin_name).'Plugin Activation Error',
241
242 #include the back link
243 ['back_link' => true]
244 );
245 }
246
247 # Check for incompatible PHP version
248 if (version_compare($php_version, METASYNC_MIN_PHP, '<')) {
249
250 #show error message
251 wp_die(
252
253 #craft the message
254 sprintf(
255 '%s requires PHP version %s or later. You are currently using version %s. Please update PHP to activate this plugin.',
256 esc_html($plugin_name),
257 METASYNC_MIN_PHP,
258 esc_html($php_version)
259 ),
260
261 #the plugin title as page title
262 esc_html($plugin_name).'Plugin Activation Error',
263
264 #include the back link
265 ['back_link' => true]
266 );
267 }
268
269 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-activator.php';
270 require_once plugin_dir_path(__FILE__) . 'database/class-db-migrations.php';
271 Metasync_Activator::activate();
272 // class name is changed at class-db-migrations.php
273 MetaSync_DBMigration::activation();
274
275 // Set initial version
276 update_option('metasync_version', METASYNC_VERSION);
277
278 // Clear all cache plugins to ensure fresh start
279 Metasync_Cache_Purge::purge_all('plugin_activation');
280 }
281
282 // Log-sync removed - error monitoring now handled by Sentry
283 // require_once plugin_dir_path(__FILE__) . 'log-sync/log-sync.php';
284
285 /**
286 * Initialize telemetry system for error monitoring and Sentry integration
287 */
288 require_once plugin_dir_path(__FILE__) . 'telemetry/telemetry-init.php';
289
290 /**
291 * The code that runs during plugin deactivation.
292 * This action is documented in includes/class-metasync-deactivator.php
293 */
294 function deactivate_metasync()
295 {
296 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-deactivator.php';
297 require_once plugin_dir_path(__FILE__) . 'database/class-db-migrations.php';
298 Metasync_Deactivator::deactivate();
299 // class name is changed at class-db-migrations.php
300 MetaSync_DBMigration::deactivation();
301 }
302
303 register_activation_hook(__FILE__, 'activate_metasync');
304 register_deactivation_hook(__FILE__, 'deactivate_metasync');
305
306 /**
307 * Check for plugin updates and run migrations if needed
308 */
309 function check_metasync_updates()
310 {
311 static $checked = false;
312 if ($checked) return;
313 $checked = true;
314
315 $current_version = get_option('metasync_version', '0.0.0');
316 $plugin_version = METASYNC_VERSION;
317
318 // If versions don't match, run migration
319 if (version_compare($current_version, $plugin_version, '<')) {
320 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-activator.php';
321 require_once plugin_dir_path(__FILE__) . 'database/class-db-migrations.php';
322
323 // Import whitelabel settings only if the JSON file is new or changed
324 // (prevents overwriting admin UI changes on every version check)
325 Metasync_Activator::check_whitelabel_settings_update();
326
327 // Run version-specific migrations first
328 MetaSync_DBMigration::run_version_migrations($current_version, $plugin_version);
329
330 // Migration for v2.7.0+: Remove AI Agent, switch to plugin auth token, make MCP always-on
331 if (version_compare($current_version, '2.7.0', '<')) {
332 // Remove old MCP API key option
333 delete_option('metasync_mcp_api_key');
334
335 // Remove MCP enabled/disabled toggle option (MCP is now always enabled)
336 delete_option('metasync_mcp_enabled');
337
338 // Remove AI Agent settings (AI Agent has been removed)
339 delete_option('metasync_ai_agent_mcp_config');
340 delete_option('metasync_ai_agent_ai_config');
341 delete_option('metasync_ai_agent_enabled');
342
343 // Ensure plugin auth token exists
344 $options = get_option('metasync_options', []);
345 if (empty($options['general']['apikey'])) {
346 $options['general']['apikey'] = wp_generate_password(32, false, false);
347 update_option('metasync_options', $options);
348 }
349 }
350
351 // Run full migration to ensure all tables are up to date
352 MetaSync_DBMigration::run_migrations();
353
354 // Update stored version
355 update_option('metasync_version', $plugin_version);
356
357 // Clear all cache plugins after update
358 Metasync_Cache_Purge::purge_all('plugin_update');
359
360 // Log the update
361 //error_log("MetaSync: Plugin updated from {$current_version} to {$plugin_version}. Database migration completed.");
362 }
363 }
364
365 // Hook into WordPress init to check for updates
366 add_action('init', 'check_metasync_updates', 1);
367
368 /**
369 * Handle whitelabel settings import after plugin is updated via WordPress admin
370 * This hook fires when plugins are installed/updated through the WordPress updater
371 *
372 * @param WP_Upgrader $upgrader WP_Upgrader instance
373 * @param array $hook_extra Extra arguments passed to hooked filters
374 */
375 function metasync_handle_plugin_upgrade($upgrader, $hook_extra)
376 {
377 // Only process plugin updates/installs
378 if (!isset($hook_extra['type']) || $hook_extra['type'] !== 'plugin') {
379 return;
380 }
381
382 // Only process install and update actions
383 if (!isset($hook_extra['action']) || !in_array($hook_extra['action'], ['install', 'update'], true)) {
384 return;
385 }
386
387 $this_plugin = plugin_basename(__FILE__);
388 $this_plugin_slug = dirname($this_plugin); // Get 'metasync' from 'metasync/metasync.php'
389 $should_import = false;
390
391 // Handle bulk updates
392 if (isset($hook_extra['bulk']) && $hook_extra['bulk'] === true && isset($hook_extra['plugins'])) {
393 foreach ($hook_extra['plugins'] as $plugin) {
394 // Match by exact path OR by plugin slug/directory
395 if ($plugin === $this_plugin || dirname($plugin) === $this_plugin_slug) {
396 $should_import = true;
397 break;
398 }
399 }
400 }
401
402 // Handle single plugin update/install
403 if (isset($hook_extra['plugin'])) {
404 $plugin = $hook_extra['plugin'];
405 // Match by exact path OR by plugin slug/directory
406 if ($plugin === $this_plugin || dirname($plugin) === $this_plugin_slug) {
407 $should_import = true;
408 }
409 }
410
411 // SPECIAL CASE: When uploading plugin via "Add New > Upload Plugin",
412 // WordPress doesn't set the 'plugin' parameter during 'install' action.
413 // Check if we can get the plugin info from the upgrader result or whitelabel file exists.
414 if (!$should_import && $hook_extra['action'] === 'install') {
415 // Check upgrader result for destination
416 if (isset($upgrader->result) && isset($upgrader->result['destination'])) {
417 $destination = $upgrader->result['destination'];
418 // Check if destination contains our plugin slug
419 if (strpos($destination, $this_plugin_slug) !== false) {
420 $should_import = true;
421 }
422 }
423
424 // Fallback: Check if whitelabel file exists in our plugin directory
425 // This means our plugin was just installed/updated with whitelabel settings
426 if (!$should_import) {
427 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-activator.php';
428 $whitelabel_file = Metasync_Activator::get_whitelabel_settings_file();
429 if ($whitelabel_file !== false) {
430 $should_import = true;
431 }
432 }
433 }
434
435 if ($should_import) {
436 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-activator.php';
437 Metasync_Activator::check_whitelabel_settings_update();
438 }
439 }
440
441 // Hook into WordPress upgrader to detect plugin updates
442 add_action('upgrader_process_complete', 'metasync_handle_plugin_upgrade', 10, 2);
443
444 /**
445 * Fallback: Check for whitelabel file changes on admin pages
446 * This handles edge cases where upgrader_process_complete doesn't fire
447 * (e.g., FTP uploads, manual file replacements)
448 * Only checks once per admin session to minimize performance impact
449 */
450 // function metasync_check_whitelabel_on_admin()
451 // {
452 // // Only check once per admin session to avoid overhead
453 // static $checked = false;
454 // if ($checked) {
455 // return;
456 // }
457 // $checked = true;
458
459 // require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-activator.php';
460 // Metasync_Activator::check_whitelabel_settings_update();
461 // }
462
463 // Check for whitelabel changes on admin pages (fallback for edge cases)
464 // add_action('admin_init', 'metasync_check_whitelabel_on_admin', 1);
465
466 /**
467 * The core plugin class that is used to define internationalization,
468 * admin-specific hooks, and public-facing site hooks.
469 */
470 require plugin_dir_path(__FILE__) . 'admin/class-metasync-admin.php';
471
472 // Include OTTO Debug class for developers
473 require plugin_dir_path(__FILE__) . 'admin/class-metasync-otto-debug.php';
474
475 // Include OTTO MCP Integration class for direct MCP tool access
476 require plugin_dir_path(__FILE__) . 'otto/class-metasync-otto-mcp-integration.php';
477
478 // Include WordPress MCP Server for Model Context Protocol support
479 require plugin_dir_path(__FILE__) . 'wp-mcp-server/class-metasync-mcp-server.php';
480
481 // Include Mixpanel Analytics Integration
482 require plugin_dir_path(__FILE__) . 'includes/class-metasync-mixpanel.php';
483
484 // Include Media Optimization Module
485 require_once plugin_dir_path(__FILE__) . 'media-optimization/media-optimization-loader.php';
486
487 try {
488 require plugin_dir_path(__FILE__) . 'includes/class-metasync.php';
489 } catch (Exception $e) {
490
491 # Log into the default PHP error log and trigger error
492 error_log($e->getMessage());
493 }
494
495 function run_metasync()
496 {
497 $plugin = new Metasync();
498 $plugin->run();
499 }
500 run_metasync();
501
502 /**
503 * Initialize WordPress MCP Server
504 *
505 * Creates and configures the MCP server instance,
506 * registers all available MCP tools for WordPress operations.
507 * Hooked to 'init' for proper WordPress lifecycle integration.
508 */
509 function metasync_init_mcp_server() {
510 // Initialize MCP server
511 global $metasync_mcp_server;
512 try {
513 $metasync_mcp_server = new Metasync_MCP_Server();
514
515 // Load tool classes
516 $tool_path = plugin_dir_path(__FILE__) . 'wp-mcp-server/tools/';
517 require_once $tool_path . 'class-mcp-tool-post-meta.php';
518 require_once $tool_path . 'class-mcp-tool-posts.php';
519 require_once $tool_path . 'class-mcp-tool-seo-analysis.php';
520 require_once $tool_path . 'class-mcp-tool-search.php';
521 require_once $tool_path . 'class-mcp-tool-redirects.php';
522 require_once $tool_path . 'class-mcp-tool-404-monitor.php';
523 require_once $tool_path . 'class-mcp-tool-robots-sitemap.php';
524 require_once $tool_path . 'class-mcp-tool-plugin-settings.php';
525 require_once $tool_path . 'class-mcp-tool-schema-markup.php';
526 require_once $tool_path . 'class-mcp-tool-instant-index.php';
527 require_once $tool_path . 'class-mcp-tool-custom-pages.php';
528 require_once $tool_path . 'class-mcp-tool-html-converter.php';
529 require_once $tool_path . 'class-mcp-tool-code-snippets.php';
530 require_once $tool_path . 'class-mcp-tool-taxonomies.php';
531 require_once $tool_path . 'class-mcp-tool-taxonomy-meta.php';
532 require_once $tool_path . 'class-mcp-tool-media.php';
533 require_once $tool_path . 'class-mcp-tool-bulk-alt-text.php';
534 require_once $tool_path . 'class-mcp-tool-post-crud.php';
535 require_once $tool_path . 'class-mcp-tool-bulk-operations.php';
536 require_once $tool_path . 'class-mcp-tool-wordpress-settings.php';
537 require_once $tool_path . 'class-mcp-tool-otto-persistence.php';
538 } catch (Exception $e) {
539 error_log('MCP Server Initialization Error: ' . $e->getMessage());
540 return;
541 }
542
543 // Helper: register a single tool, logging failures without aborting subsequent registrations
544 $safe_register = function($tool) use ($metasync_mcp_server) {
545 try {
546 $metasync_mcp_server->register_tool($tool);
547 } catch (Exception $e) {
548 error_log('MetaSync MCP: Failed to register tool ' . get_class($tool) . ': ' . $e->getMessage());
549 }
550 };
551
552 // Register MCP Tools (Total: 92 existing + 8 new = 100 tools total!)
553 // NEW in v2.8.0: +4 Taxonomy Meta tools, +4 Bulk Alt Text tools
554
555 // Post Meta Operations (3 tools)
556 $safe_register(new MCP_Tool_Update_Post_Meta());
557 $safe_register(new MCP_Tool_Get_Post_Meta());
558 $safe_register(new MCP_Tool_Get_SEO_Meta());
559
560 // Post Operations (4 tools)
561 $safe_register(new MCP_Tool_Get_Post());
562 $safe_register(new MCP_Tool_Get_Post_By_URL());
563 $safe_register(new MCP_Tool_List_Posts());
564 $safe_register(new MCP_Tool_Update_Post());
565 $safe_register(new MCP_Tool_Get_Post_Types());
566
567 // SEO Analysis (2 tools)
568 $safe_register(new MCP_Tool_Analyze_SEO());
569 $safe_register(new MCP_Tool_Check_Indexability());
570
571 // Search Operations (3 tools)
572 $safe_register(new MCP_Tool_Search_Posts());
573 $safe_register(new MCP_Tool_Search_By_Keyword());
574 $safe_register(new MCP_Tool_Find_Missing_Meta());
575
576 // Redirect Management (4 tools)
577 $safe_register(new MCP_Tool_Create_Redirect());
578 $safe_register(new MCP_Tool_List_Redirects());
579 $safe_register(new MCP_Tool_Delete_Redirect());
580 $safe_register(new MCP_Tool_Update_Redirect());
581
582 // 404 Error Monitoring (5 tools)
583 $safe_register(new MCP_Tool_List_404_Errors());
584 $safe_register(new MCP_Tool_Get_404_Stats());
585 $safe_register(new MCP_Tool_Delete_404_Error());
586 $safe_register(new MCP_Tool_Clear_404_Errors());
587 $safe_register(new MCP_Tool_Create_Redirect_From_404());
588
589 // Robots.txt & Sitemap Management (9 tools - 5 existing + 4 new)
590 $safe_register(new MCP_Tool_Get_Robots_Txt());
591 $safe_register(new MCP_Tool_Update_Robots_Txt());
592 $safe_register(new MCP_Tool_Get_Sitemap_Status());
593 $safe_register(new MCP_Tool_Regenerate_Sitemap());
594 $safe_register(new MCP_Tool_Exclude_From_Sitemap());
595 $safe_register(new MCP_Tool_Add_Robots_Rule());
596 $safe_register(new MCP_Tool_Remove_Robots_Rule());
597 $safe_register(new MCP_Tool_Parse_Robots_Txt());
598 $safe_register(new MCP_Tool_Validate_Robots_Txt());
599
600 // Plugin Settings Management (4 tools)
601 $safe_register(new MCP_Tool_Get_Plugin_Settings());
602 $safe_register(new MCP_Tool_Update_Plugin_Settings());
603 $safe_register(new MCP_Tool_List_Plugin_Settings_Schema());
604 $safe_register(new MCP_Tool_Get_MCP_Settings());
605
606 // Schema Markup Management (5 tools)
607 $safe_register(new MCP_Tool_Get_Schema_Markup());
608 $safe_register(new MCP_Tool_Update_Schema_Markup());
609 $safe_register(new MCP_Tool_Add_Schema_Type());
610 $safe_register(new MCP_Tool_Remove_Schema_Type());
611 $safe_register(new MCP_Tool_Validate_Schema());
612
613 // Google Instant Index (6 tools)
614 $safe_register(new MCP_Tool_Instant_Index_Update());
615 $safe_register(new MCP_Tool_Instant_Index_Delete());
616 $safe_register(new MCP_Tool_Instant_Index_Status());
617 $safe_register(new MCP_Tool_Instant_Index_Bulk_Update());
618 $safe_register(new MCP_Tool_Get_Instant_Index_Settings());
619 $safe_register(new MCP_Tool_Update_Instant_Index_Settings());
620
621 // Custom HTML Pages (5 tools)
622 $safe_register(new MCP_Tool_Create_Custom_Page());
623 $safe_register(new MCP_Tool_Get_Custom_Page());
624 $safe_register(new MCP_Tool_List_Custom_Pages());
625 $safe_register(new MCP_Tool_Update_Custom_Page());
626 $safe_register(new MCP_Tool_Delete_Custom_Page());
627
628 // HTML to Builder Converter (3 tools)
629 $safe_register(new MCP_Tool_Convert_HTML_To_Builder());
630 $safe_register(new MCP_Tool_Create_Builder_Page_From_HTML());
631 $safe_register(new MCP_Tool_Convert_Custom_Page_To_Builder());
632
633 // Code Snippets (6 tools)
634 $safe_register(new MCP_Tool_Get_Header_Snippet());
635 $safe_register(new MCP_Tool_Update_Header_Snippet());
636 $safe_register(new MCP_Tool_Get_Footer_Snippet());
637 $safe_register(new MCP_Tool_Update_Footer_Snippet());
638 $safe_register(new MCP_Tool_Get_Post_Snippets());
639 $safe_register(new MCP_Tool_Update_Post_Snippets());
640
641 // Categories & Taxonomies (15 tools)
642 $safe_register(new MCP_Tool_List_Categories());
643 $safe_register(new MCP_Tool_Get_Category());
644 $safe_register(new MCP_Tool_Create_Category());
645 $safe_register(new MCP_Tool_Update_Category());
646 $safe_register(new MCP_Tool_Delete_Category());
647 $safe_register(new MCP_Tool_Get_Post_Categories());
648 $safe_register(new MCP_Tool_Set_Post_Categories());
649
650 // Tags (8 tools)
651 $safe_register(new MCP_Tool_List_Tags());
652 $safe_register(new MCP_Tool_Get_Tag());
653 $safe_register(new MCP_Tool_Create_Tag());
654 $safe_register(new MCP_Tool_Update_Tag());
655 $safe_register(new MCP_Tool_Delete_Tag());
656 $safe_register(new MCP_Tool_Get_Post_Tags());
657 $safe_register(new MCP_Tool_Set_Post_Tags());
658
659 // Featured Images & Media (6 tools)
660 $safe_register(new MCP_Tool_Get_Featured_Image());
661 $safe_register(new MCP_Tool_Set_Featured_Image());
662 $safe_register(new MCP_Tool_Upload_Featured_Image());
663 $safe_register(new MCP_Tool_Remove_Featured_Image());
664 $safe_register(new MCP_Tool_List_Media());
665 $safe_register(new MCP_Tool_Get_Media_Details());
666
667 // Post CRUD Operations (1 tool - delete/restore disabled for safety)
668 $safe_register(new MCP_Tool_Create_Post());
669 // $safe_register(new MCP_Tool_Delete_Post()); // DISABLED - safety
670 // $safe_register(new MCP_Tool_Restore_Post()); // DISABLED - safety
671
672 // Bulk Operations (3 tools - bulk delete disabled for safety)
673 $safe_register(new MCP_Tool_Bulk_Update_Meta());
674 $safe_register(new MCP_Tool_Bulk_Set_Categories());
675 $safe_register(new MCP_Tool_Bulk_Change_Status());
676 // $safe_register(new MCP_Tool_Bulk_Delete_Posts()); // DISABLED - safety
677
678 // WordPress Core SEO Settings (10 tools)
679 $safe_register(new MCP_Tool_Get_Site_Info());
680 $safe_register(new MCP_Tool_Update_Site_Info());
681 $safe_register(new MCP_Tool_Get_Permalink_Structure());
682 $safe_register(new MCP_Tool_Update_Permalink_Structure());
683 $safe_register(new MCP_Tool_Get_Reading_Settings());
684 $safe_register(new MCP_Tool_Update_Reading_Settings());
685 $safe_register(new MCP_Tool_Get_Search_Visibility());
686 $safe_register(new MCP_Tool_Update_Search_Visibility());
687 $safe_register(new MCP_Tool_Get_Date_Format());
688 $safe_register(new MCP_Tool_Get_Discussion_Settings());
689
690 // Taxonomy Meta Operations (4 tools - NEW in v2.8.0)
691 $safe_register(new MCP_Tool_Get_Term_Meta());
692 $safe_register(new MCP_Tool_Update_Term_Meta());
693 $safe_register(new MCP_Tool_Bulk_Update_Term_Meta());
694 $safe_register(new MCP_Tool_List_Terms_With_Meta());
695
696 // Bulk Alt Text Operations (4 tools - NEW in v2.8.0)
697 $safe_register(new MCP_Tool_Audit_Alt_Text());
698 $safe_register(new MCP_Tool_Bulk_Update_Alt_Text());
699 $safe_register(new MCP_Tool_Generate_Alt_Text());
700 $safe_register(new MCP_Tool_Validate_Alt_Text());
701
702 // OTTO Persistence Settings (2 tools)
703 if (class_exists('MCP_Tool_Get_Otto_Persistence_Settings')) {
704 $safe_register(new MCP_Tool_Get_Otto_Persistence_Settings());
705 }
706 if (class_exists('MCP_Tool_Update_Otto_Persistence_Settings')) {
707 $safe_register(new MCP_Tool_Update_Otto_Persistence_Settings());
708 }
709
710 // Allow other plugins/themes to register tools
711 do_action('metasync_mcp_register_tools', $metasync_mcp_server);
712 }
713 add_action('init', 'metasync_init_mcp_server', 5);
714
715
716
717 /**
718 * Output DYO initialization flag to the frontend
719 * Makes window.__SA_DYO_INITIALIZED__ = true available in the DOM
720 * This indicates the Search Atlas plugin is active and initialized
721 */
722 function metasync_output_dyo_init_flag() {
723 echo '<script>window.__SA_DYO_INITIALIZED__=true;</script>' . "\n";
724 }
725 add_action('wp_head', 'metasync_output_dyo_init_flag', 1);
726
727 /**
728 * Initialize Mixpanel Analytics for Admin Area
729 * Hooked to admin_init for proper WordPress lifecycle integration
730 * Only loads after WordPress, plugins, and themes are fully loaded
731 */
732 function metasync_init_analytics() {
733 // Only initialize in admin area (excludes AJAX and REST API requests)
734 if (is_admin() && !wp_doing_ajax() && !defined('REST_REQUEST')) {
735 Metasync_Mixpanel::get_instance();
736 }
737 }
738 add_action('admin_init', 'metasync_init_analytics', 10);
739
740 /**
741 * Initialize API Backoff System
742 * Hooked to init for proper WordPress lifecycle integration
743 * Monitors API responses and manages exponential backoff for rate limiting
744 * @since 2.7.1
745 */
746 function metasync_init_api_backoff() {
747 // Initialize backoff manager (registers HTTP response filters)
748 Metasync_API_Backoff_Manager::get_instance();
749
750 // Initialize admin notices (only in admin area)
751 if (is_admin()) {
752 Metasync_API_Backoff_Notices::get_instance();
753 }
754 }
755 add_action('init', 'metasync_init_api_backoff', 5);
756
757 /**
758 * Initialize Review Notice
759 * Shows a dismissible notice asking users to rate the plugin after a usage period
760 * @since 2.8.0
761 */
762 function metasync_init_review_notice() {
763 if (is_admin()) {
764 Metasync_Review_Notice::get_instance();
765 }
766 }
767 add_action('init', 'metasync_init_review_notice');
768
769 /**
770 * Global convenience function to get active JWT token
771 * Can be called from anywhere in WordPress (themes, other plugins, etc.)
772 *
773 * @param bool $force_refresh Force generation of new token even if cached one exists
774 * @return string|false JWT token on success, false on failure
775 */
776 if (!function_exists('metasync_get_jwt_token')) {
777 function metasync_get_jwt_token($force_refresh = false)
778 {
779 return Metasync::get_jwt_token($force_refresh);
780 }
781 }
782
783 require plugin_dir_path(__FILE__) . 'MetaSyncDebug.php';
784
785 /**
786 * Include Debug Mode Manager
787 * Handles automatic disable and safety limits for debug mode
788 * UI integrated into Advanced Settings tab in class-metasync-admin.php
789 * @since 2.5.15
790 */
791 require_once plugin_dir_path(__FILE__) . 'includes/class-metasync-debug-mode-manager.php';
792
793 /**
794 * Initialize Debug Mode Manager
795 * Hooked to 'init' for proper WordPress lifecycle integration
796 */
797 function metasync_init_debug_mode_manager() {
798 // Initialize the Debug Mode Manager singleton
799 Metasync_Debug_Mode_Manager::get_instance();
800 }
801 add_action('init', 'metasync_init_debug_mode_manager', 10);
802