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
← All changes | telemetry/sentry-wordpress-integration.php +66 -35 2.6.24 → 2.7.2 View file →
@@ -43,14 +43,14 @@
43 43 $this->host = null; // Proxy handles this
44 44 $this->scheme = 'proxy';
45 45 } else {
46 46 // Legacy DSN format for backward compatibility
47 - $parsed = parse_url($this->dsn);
48 - $this->public_key = isset($parsed['user']) ? $parsed['user'] : null;
49 - $this->secret_key = isset($parsed['pass']) ? $parsed['pass'] : null;
50 - $this->project_id = trim($parsed['path'], '/');
51 - $this->host = isset($parsed['host']) ? $parsed['host'] : null;
52 - $this->scheme = isset($parsed['scheme']) ? $parsed['scheme'] : 'https';
47 + $parsed = wp_parse_url($this->dsn);
48 + $this->public_key = is_array($parsed) && isset($parsed['user']) ? $parsed['user'] : null;
49 + $this->secret_key = is_array($parsed) && isset($parsed['pass']) ? $parsed['pass'] : null;
50 + $this->project_id = is_array($parsed) && isset($parsed['path']) ? trim($parsed['path'], '/') : null;
51 + $this->host = is_array($parsed) && isset($parsed['host']) ? $parsed['host'] : null;
52 + $this->scheme = is_array($parsed) && isset($parsed['scheme']) ? $parsed['scheme'] : 'https';
53 53 }
54 54 }
55 55
56 56 /**
@@ -243,8 +243,12 @@
243 243 } else {
244 244 $event_data['tags'] = ['category' => 'user-feedback'];
245 245 }
246 246
247 + // Attach white-label metadata to the issue-report event (not only the
248 + // user-feedback item) so support can identify the reporting site.
249 + $event_data = self::apply_white_label_context($event_data, $feedback);
250 +
247 251 // Send the event first with attachment
248 252 $event_result = $this->sendToSentry($event_data, 'event', $attachment);
249 253
250 254 // Extract event_id from response
@@ -269,10 +273,47 @@
269 273 $feedback_result = $this->sendToSentry($data, 'user_report');
270 274
271 275 return is_array($feedback_result) ? $feedback_result['success'] : $feedback_result;
272 276 }
273 -
277 +
274 278 /**
279 + * Attach white-label metadata to an issue-report event payload.
280 + *
281 + * Support needs to tell from the Sentry event alone whether the reporting
282 + * site is white-labeled, so the values go on the event itself (tags plus a
283 + * white_label context), not only on the associated user-feedback item.
284 + *
285 + * Static and public so the unit suite can exercise the mapping directly;
286 + * captureFeedback() runs the result through a private curl sender that has
287 + * no test seam.
288 + *
289 + * @param array $event_data Event payload built by formatMessage().
290 + * @param array $feedback Feedback data supplied by the report handler.
291 + * @return array The event payload with white-label tags and context added.
292 + */
293 + public static function apply_white_label_context(array $event_data, array $feedback)
294 + {
295 + $is_whitelabel = !empty($feedback['is_whitelabel']);
296 + $brand_name = isset($feedback['whitelabel_brand_name'])
297 + ? sanitize_text_field($feedback['whitelabel_brand_name']) : '';
298 + $support_email = isset($feedback['whitelabel_support_email'])
299 + ? sanitize_email($feedback['whitelabel_support_email']) : '';
300 + $site_url = isset($feedback['site_url']) ? esc_url_raw($feedback['site_url']) : '';
301 + $event_data['tags']['is_whitelabel'] = $is_whitelabel ? 'true' : 'false';
302 + $event_data['tags']['whitelabel_brand_name'] = $brand_name;
303 + $event_data['tags']['whitelabel_support_email'] = $support_email;
304 + $event_data['tags']['site_url'] = $site_url;
305 + $event_data['contexts']['white_label'] = array(
306 + 'is_whitelabel' => $is_whitelabel,
307 + 'whitelabel_brand_name' => $brand_name,
308 + 'whitelabel_support_email' => $support_email,
309 + 'site_url' => $site_url,
310 + );
311 +
312 + return $event_data;
313 + }
314 +
315 + /**
275 316 * Format exception data for Sentry API
276 317 */
277 318 private function formatException($exception, $extra = []) {
278 319 $trace = [];
@@ -393,9 +434,9 @@
393 434 /**
394 435 * Check if the current environment is localhost/development
395 436 */
396 437 private function isLocalhost() {
397 - $host = parse_url(home_url(), PHP_URL_HOST);
438 + $host = wp_parse_url(home_url(), PHP_URL_HOST);
398 439
399 440 // Check for common localhost patterns
400 441 $localhost_patterns = [
401 442 'localhost',
@@ -408,9 +449,9 @@
408 449 '.localhost'
409 450 ];
410 451
411 452 foreach ($localhost_patterns as $pattern) {
412 - if (strpos($host, $pattern) !== false) {
453 + if ($host !== false && $host !== null && strpos($host, $pattern) !== false) {
413 454 return true;
414 455 }
415 456 }
416 457
@@ -479,32 +520,23 @@
479 520 'X-Plugin-Version' => $plugin_version,
480 521 'User-Agent' => 'WordPress MetaSync Plugin/' . $plugin_version
481 522 ];
482 523
483 - // Use cURL directly to ensure proper envelope format
484 - $ch = curl_init();
485 - curl_setopt($ch, CURLOPT_URL, $url);
486 - curl_setopt($ch, CURLOPT_POST, true);
487 - curl_setopt($ch, CURLOPT_POSTFIELDS, $envelope);
488 - curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function($key, $value) {
489 - return $key . ': ' . $value;
490 - }, array_keys($headers), $headers));
491 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
492 - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
493 - curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 5 second timeout as requested
494 - curl_setopt($ch, CURLOPT_USERAGENT, 'WordPress MetaSync Plugin/' . $plugin_version);
495 - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 5 second connection timeout
496 -
497 - $response = curl_exec($ch);
498 - $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
499 - $error = curl_error($ch);
524 + $response_data = wp_remote_post($url, [
525 + 'body' => $envelope,
526 + 'headers' => $headers,
527 + 'timeout' => 5, // 5 second timeout as requested
528 + 'sslverify' => true,
529 + 'user-agent' => 'WordPress MetaSync Plugin/' . $plugin_version,
530 + ]);
531 + $error = is_wp_error($response_data) ? $response_data->get_error_message() : '';
532 + $response_code = is_wp_error($response_data) ? 0 : (int) wp_remote_retrieve_response_code($response_data);
533 + $response = is_wp_error($response_data) ? '' : wp_remote_retrieve_body($response_data);
500 534
501 - #curl_close($ch);
502 -
503 535 // Log errors in debug mode for troubleshooting
504 536 if (defined('WP_DEBUG') && WP_DEBUG && WP_DEBUG_LOG) {
505 537 if ($error) {
506 - error_log(sprintf(
538 + error_log(sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- debug-gated, no secrets
507 539 'MetaSync Sentry Error (%s): %s | Response Code: %s | Item Type: %s',
508 540 $item_type,
509 541 $error,
510 542 $response_code,
@@ -510,13 +542,12 @@
510 542 $response_code,
511 543 $item_type
512 544 ));
513 545 } elseif ($response_code < 200 || $response_code >= 300) {
514 - error_log(sprintf(
515 - 'MetaSync Sentry HTTP Error (%s): Response Code: %s | Response: %s | Item Type: %s',
546 + error_log(sprintf( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- debug-gated, no secrets
547 + 'MetaSync Sentry HTTP Error (%s): Response Code: %s | Item Type: %s',
516 548 $item_type,
517 549 $response_code,
518 - substr($response, 0, 200),
519 550 $item_type
520 551 ));
521 552 }
522 553 }
@@ -739,9 +770,9 @@
739 770 'max_execution_time' => ini_get('max_execution_time'),
740 771 'active_plugins' => count(get_option('active_plugins', [])),
741 772 'active_theme' => get_template(),
742 773 'multisite' => is_multisite(),
743 - 'mysql_version' => method_exists($wpdb, 'get_var') ? $wpdb->get_var('SELECT VERSION()') : 'unknown',
774 + 'mysql_version' => method_exists($wpdb, 'get_var') ? $wpdb->get_var('SELECT VERSION()') : 'unknown', // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- diagnostic metadata — SELECT VERSION() has no cached WordPress API
744 775 'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown',
745 776 // Dynamic data added per request
746 777 'memory_usage' => memory_get_usage(true),
747 778 'memory_peak' => memory_get_peak_usage(true),
@@ -822,10 +853,10 @@
822 853 if ($this->isLocalhost()) {
823 854 return 'development';
824 855 }
825 856
826 - $host = parse_url(home_url(), PHP_URL_HOST);
827 - if (strpos($host, 'staging') !== false || strpos($host, 'dev') !== false) {
857 + $host = wp_parse_url(home_url(), PHP_URL_HOST);
858 + if ($host !== false && $host !== null && (strpos($host, 'staging') !== false || strpos($host, 'dev') !== false)) {
828 859 return 'staging';
829 860 }
830 861
831 862 return 'production';