| @@ -168,17 +168,8 @@ | ||
| 168 | 168 | $result = $importer->import_schema($plugin); |
| 169 | 169 | break; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | - // A schema import that only found already-migrated or unsupported | |
| 173 | - // records is an accurate report, not a failure — keep the breakdown | |
| 174 | - // with the response so the UI can show each category separately. | |
| 175 | - if (isset($result['breakdown'])) { | |
| 176 | - $result['breakdown'] = array_map('intval', (array) $result['breakdown']); | |
| 177 | - } | |
| 178 | - | |
| 179 | - Metasync_PostHog::import_batch($plugin, $type, $result, $offset); | |
| 180 | - | |
| 181 | 172 | if ($result['success']) { |
| 182 | 173 | wp_send_json_success($result); |
| 183 | 174 | } else { |
| 184 | 175 | wp_send_json_error($result); |
| @@ -226,12 +217,8 @@ | ||
| 226 | 217 | ]; |
| 227 | 218 | |
| 228 | 219 | $result = $importer->import_seo_metadata($plugin, $options); |
| 229 | 220 | |
| 230 | - Metasync_PostHog::import_batch($plugin, 'seo_metadata', $result, $offset, array( | |
| 231 | - 'overwrite_existing' => $overwrite_existing, | |
| 232 | - )); | |
| 233 | - | |
| 234 | 221 | if ($result['success']) { |
| 235 | 222 | wp_send_json_success($result); |
| 236 | 223 | } else { |
| 237 | 224 | wp_send_json_error($result); |
| @@ -332,9 +319,9 @@ | ||
| 332 | 319 | $step = isset($_POST['step']) ? intval($_POST['step']) : 0; |
| 333 | 320 | $raw_data = isset($_POST['data']) ? $_POST['data'] : array(); |
| 334 | 321 | |
| 335 | 322 | // Allowlist top-level wizard data keys to prevent mass assignment |
| 336 | - $allowed_wizard_keys = array('verification', 'seo_settings', 'schema', 'analytics'); | |
| 323 | + $allowed_wizard_keys = array('verification', 'seo_settings', 'schema'); | |
| 337 | 324 | $data = is_array($raw_data) ? array_intersect_key($raw_data, array_flip($allowed_wizard_keys)) : array(); |
| 338 | 325 | |
| 339 | 326 | $options = get_option('metasync_options', array()); |
| 340 | 327 | |
| @@ -364,13 +351,8 @@ | ||
| 364 | 351 | $options['general']['enable_schema_markup'] = $data['schema']['enabled']; |
| 365 | 352 | $options['general']['default_schema_type'] = sanitize_text_field($data['schema']['default_type']); |
| 366 | 353 | } |
| 367 | 354 | |
| 368 | - if (isset($data['analytics']) && is_array($data['analytics'])) { | |
| 369 | - update_option('metasync_analytics_opt_in', !empty($data['analytics']['enabled']) ? 'yes' : 'no'); | |
| 370 | - update_option('metasync_analytics_consent_explicit', 'yes'); | |
| 371 | - } | |
| 372 | - | |
| 373 | 355 | update_option('metasync_options', $options); |
| 374 | 356 | |
| 375 | 357 | wp_send_json_success(array('message' => 'Progress saved')); |
| 376 | 358 | } |
| @@ -392,14 +374,8 @@ | ||
| 392 | 374 | |
| 393 | 375 | $user_id = get_current_user_id(); |
| 394 | 376 | delete_transient("metasync_wizard_state_{$user_id}"); |
| 395 | 377 | |
| 396 | - // Consent-gated product analytics: setup funnel completion. | |
| 397 | - $general_settings = Metasync::get_option('general'); | |
| 398 | - Metasync_PostHog::feature('setup_wizard_completed', array( | |
| 399 | - 'connected' => !empty($general_settings['searchatlas_api_key']), | |
| 400 | - )); | |
| 401 | - | |
| 402 | 378 | wp_send_json_success(array('message' => 'Wizard completed')); |
| 403 | 379 | } |
| 404 | 380 | |
| 405 | 381 | public function ajax_validate_robots() |
| @@ -712,43 +688,8 @@ | ||
| 712 | 688 | error_log('MetaSync: Transient cleanup failed - ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets |
| 713 | 689 | } |
| 714 | 690 | } |
| 715 | 691 | |
| 716 | - /** | |
| 717 | - * Collect the locally stored white-label settings for an issue-report payload. | |
| 718 | - * | |
| 719 | - * The values are attached to the Sentry event so support can tell from the | |
| 720 | - * event alone whether the reporting site is white-labeled. Local options | |
| 721 | - * can be stale — the reply-drafting process must still cross-check the | |
| 722 | - * backend account record before sending. | |
| 723 | - * | |
| 724 | - * Static and public so the unit suite can exercise the reads directly; the | |
| 725 | - * AJAX handler itself dies on wp_send_json_* before returning. | |
| 726 | - * | |
| 727 | - * @return array Keys: is_whitelabel, whitelabel_brand_name, whitelabel_support_email, site_url. | |
| 728 | - */ | |
| 729 | - public static function build_issue_report_whitelabel_context() | |
| 730 | - { | |
| 731 | - $whitelabel_settings = Metasync::get_whitelabel_settings(); | |
| 732 | - if (!is_array($whitelabel_settings)) { | |
| 733 | - $whitelabel_settings = array(); | |
| 734 | - } | |
| 735 | - $whitelabel_support_email = ''; | |
| 736 | - foreach (array('support_email_override', 'support_email', 'recovery_email') as $email_key) { | |
| 737 | - if (!empty($whitelabel_settings[$email_key])) { | |
| 738 | - $whitelabel_support_email = sanitize_email($whitelabel_settings[$email_key]); | |
| 739 | - break; | |
| 740 | - } | |
| 741 | - } | |
| 742 | - return array( | |
| 743 | - 'is_whitelabel' => Metasync::is_whitelabel_enabled(), | |
| 744 | - 'whitelabel_brand_name' => !empty($whitelabel_settings['company_name']) | |
| 745 | - ? sanitize_text_field($whitelabel_settings['company_name']) : '', | |
| 746 | - 'whitelabel_support_email' => $whitelabel_support_email, | |
| 747 | - 'site_url' => esc_url_raw(home_url()), | |
| 748 | - ); | |
| 749 | - } | |
| 750 | - | |
| 751 | 692 | public function ajax_submit_issue_report() |
| 752 | 693 | { |
| 753 | 694 | try { |
| 754 | 695 | # Verify nonce |
| @@ -819,11 +760,8 @@ | ||
| 819 | 760 | ); |
| 820 | 761 | } |
| 821 | 762 | } |
| 822 | 763 | |
| 823 | - # Read the locally stored white-label settings for the report payload. | |
| 824 | - $whitelabel_context = self::build_issue_report_whitelabel_context(); | |
| 825 | - | |
| 826 | 764 | # Get general options (same way as used throughout the plugin) |
| 827 | 765 | $general_options = Metasync::get_option('general'); |
| 828 | 766 | if (!is_array($general_options)) { |
| 829 | 767 | $general_options = array(); |
| @@ -883,13 +821,9 @@ | ||
| 883 | 821 | } |
| 884 | 822 | } else { |
| 885 | 823 | $feedback_data = array( |
| 886 | 824 | 'message' => $issue_message, |
| 887 | - 'severity' => $issue_severity, | |
| 888 | - 'is_whitelabel' => $whitelabel_context['is_whitelabel'], | |
| 889 | - 'whitelabel_brand_name' => $whitelabel_context['whitelabel_brand_name'], | |
| 890 | - 'whitelabel_support_email' => $whitelabel_context['whitelabel_support_email'], | |
| 891 | - 'site_url' => $whitelabel_context['site_url'] | |
| 825 | + 'severity' => $issue_severity | |
| 892 | 826 | ); |
| 893 | 827 | |
| 894 | 828 | # Add user information if requested |
| 895 | 829 | if ($include_user_info) { |
| @@ -1280,20 +1214,40 @@ | ||
| 1280 | 1214 | wp_die('Security verification failed.'); |
| 1281 | 1215 | } |
| 1282 | 1216 | |
| 1283 | 1217 | try { |
| 1284 | - # Source the white-label export payload from the shared helper so | |
| 1285 | - # reset and export can never drift apart: whatever the reset | |
| 1286 | - # preserves is exactly what the export serialises. No API | |
| 1287 | - # credentials (apikey / searchatlas_api_key / otto_pixel_uuid / ...) | |
| 1288 | - # are ever serialised - the helper only captures the whitelabel | |
| 1289 | - # blob and the general branding keys. | |
| 1290 | - if (!class_exists('Metasync_Whitelabel_Preservation')) { | |
| 1291 | - require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-metasync-whitelabel-preservation.php'; | |
| 1218 | + # Get all whitelabel settings | |
| 1219 | + $whitelabel_settings = Metasync::get_whitelabel_settings(); | |
| 1220 | + | |
| 1221 | + # Export the settings password as plaintext (not the encrypted blob): | |
| 1222 | + # the encryption key derives from this site's salts, so the blob | |
| 1223 | + # would be undecryptable after import on a different site. The | |
| 1224 | + # importer re-encrypts it at rest with the destination site's salts. | |
| 1225 | + if (!empty($whitelabel_settings['settings_password'])) { | |
| 1226 | + $whitelabel_settings['settings_password'] = Metasync::get_whitelabel_password(); | |
| 1292 | 1227 | } |
| 1293 | - $export_payload = Metasync_Whitelabel_Preservation::build_whitelabel_export_data(); | |
| 1294 | - $whitelabel_settings = $export_payload['whitelabel_settings']; | |
| 1295 | - $whitelabel_related_general = $export_payload['general_settings']; | |
| 1228 | + | |
| 1229 | + # Get general settings that relate to whitelabel | |
| 1230 | + $general_settings = Metasync::get_option('general'); | |
| 1231 | + $whitelabel_related_general = array(); | |
| 1232 | + | |
| 1233 | + # Include ALL whitelabel-related general settings | |
| 1234 | + $whitelabel_keys = array( | |
| 1235 | + 'white_label_plugin_name', | |
| 1236 | + 'white_label_plugin_description', | |
| 1237 | + 'white_label_plugin_author', | |
| 1238 | + 'white_label_plugin_author_uri', | |
| 1239 | + 'white_label_plugin_uri', | |
| 1240 | + 'white_label_plugin_menu_slug', | |
| 1241 | + 'white_label_plugin_menu_icon', | |
| 1242 | + 'whitelabel_otto_name' | |
| 1243 | + ); | |
| 1244 | + | |
| 1245 | + foreach ($whitelabel_keys as $key) { | |
| 1246 | + if (isset($general_settings[$key])) { | |
| 1247 | + $whitelabel_related_general[$key] = $general_settings[$key]; | |
| 1248 | + } | |
| 1249 | + } | |
| 1296 | 1250 | |
| 1297 | 1251 | # Bundle the menu icon file so it survives import on a different site. |
| 1298 | 1252 | # If the icon is a local URL (media library), replace it with a special |
| 1299 | 1253 | # marker and include the actual file in the ZIP under the plugin folder. |
| @@ -1495,9 +1449,9 @@ | ||
| 1495 | 1449 | echo '<div class="metasync-dashboard-widget-empty">'; |
| 1496 | 1450 | echo '<span class="dashicons dashicons-admin-page" style="font-size: 48px; opacity: 0.3; display: block; margin: 20px auto;"></span>'; |
| 1497 | 1451 | echo '<p style="text-align: center; color: #666;">'; |
| 1498 | 1452 | /* translators: %s: HTML source label. */ |
| 1499 | - echo sprintf(esc_html__('No pages created with %s yet.', 'metasync'), '<strong>' . esc_html($label) . '</strong>'); | |
| 1453 | + echo sprintf(__('No pages created with %s yet.', 'metasync'), '<strong>' . esc_html($label) . '</strong>'); | |
| 1500 | 1454 | echo '</p>'; |
| 1501 | 1455 | echo '<p style="text-align: center;">'; |
| 1502 | 1456 | echo '<a href="' . esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug)) . '" class="button button-primary">'; |
| 1503 | 1457 | echo esc_html__('Get Started', 'metasync'); |