| @@ -499,8 +499,10 @@ | ||
| 499 | 499 | |
| 500 | 500 | $get = $this->run_check('GET'); |
| 501 | 501 | $post = $this->run_check('POST'); |
| 502 | 502 | |
| 503 | + $previous = $this->get_last_result(); | |
| 504 | + | |
| 503 | 505 | $result = [ |
| 504 | 506 | 'get_blocked' => !empty($get['blocked']), |
| 505 | 507 | 'post_blocked' => !empty($post['blocked']), |
| 506 | 508 | 'checked_at' => current_time('mysql'), |
| @@ -507,8 +509,10 @@ | ||
| 507 | 509 | ]; |
| 508 | 510 | |
| 509 | 511 | update_option(self::RESULT_OPTION, $result, true); |
| 510 | 512 | |
| 513 | + $this->track_result($result, $previous, !empty($get['checker_unreachable']) || !empty($post['checker_unreachable'])); | |
| 514 | + | |
| 511 | 515 | if (!empty($get['checker_unreachable']) || !empty($post['checker_unreachable'])) { |
| 512 | 516 | $this->log(sprintf( |
| 513 | 517 | 'Inconclusive automatic check (checker unavailable) — no warning shown. GET: %s | POST: %s', |
| 514 | 518 | $get['details'], |
| @@ -526,8 +530,44 @@ | ||
| 526 | 530 | )); |
| 527 | 531 | } |
| 528 | 532 | |
| 529 | 533 | return $result; |
| 534 | + } | |
| 535 | + | |
| 536 | + /** | |
| 537 | + * Consent-gated analytics for the automatic check: sent while the host is | |
| 538 | + * blocking us, and once when a block clears. A clean run that stays clean | |
| 539 | + * sends nothing; an inconclusive run never reports a block as cleared. | |
| 540 | + * | |
| 541 | + * @param array $result Result just stored. | |
| 542 | + * @param array|null $previous Result before this run, null on first run. | |
| 543 | + * @param bool $inconclusive Whether the checker itself was unreachable. | |
| 544 | + */ | |
| 545 | + private function track_result(array $result, $previous, $inconclusive) | |
| 546 | + { | |
| 547 | + $blocked = $result['get_blocked'] || $result['post_blocked']; | |
| 548 | + $was_blocked = is_array($previous) && (!empty($previous['get_blocked']) || !empty($previous['post_blocked'])); | |
| 549 | + | |
| 550 | + if (!$blocked && (!$was_blocked || $inconclusive)) { | |
| 551 | + return; | |
| 552 | + } | |
| 553 | + | |
| 554 | + if ($previous === null) { | |
| 555 | + $trigger = 'first_check'; | |
| 556 | + } elseif ($blocked !== $was_blocked | |
| 557 | + || $result['get_blocked'] !== !empty($previous['get_blocked']) | |
| 558 | + || $result['post_blocked'] !== !empty($previous['post_blocked'])) { | |
| 559 | + $trigger = 'state_change'; | |
| 560 | + } else { | |
| 561 | + $trigger = 'recheck'; | |
| 562 | + } | |
| 563 | + | |
| 564 | + Metasync_PostHog::feature('host_blocking_detected', [ | |
| 565 | + 'get_blocked' => $result['get_blocked'], | |
| 566 | + 'post_blocked' => $result['post_blocked'], | |
| 567 | + 'trigger' => $trigger, | |
| 568 | + 'inconclusive' => (bool) $inconclusive, | |
| 569 | + ]); | |
| 530 | 570 | } |
| 531 | 571 | |
| 532 | 572 | /** |
| 533 | 573 | * Whether the inbound leg of the check can possibly succeed. |