# woocommerce-pos/1.10.17/includes/API/V2/Ping.php

WCPOS – Point of Sale (POS) plugin for WooCommerce, version 1.10.17. 222 lines.

- Page: https://pluginprobe.com/plugins/woocommerce-pos/1.10.17/code/includes/API/V2/Ping.php
- Raw: https://pluginprobe.com/plugins/woocommerce-pos/1.10.17/raw/includes/API/V2/Ping.php
- Modified: 2026-09-16T13:33:14+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/woocommerce-pos/1.10.17/code/includes/API/V2/Ping.php#L10-L20`.

```php
<?php
/**
 * Public ping REST API controller and bootstrap fast path.
 *
 * @package WCPOS\WooCommercePOS\API\V2
 */

namespace WCPOS\WooCommercePOS\API\V2;

use WP_REST_Response;
use const WCPOS\WooCommercePOS\VERSION;
/**
 * Serves the lightweight public status response.
 *
 * Loaded cross-plugin: Pro bundles a copy of this file and, on a site running both
 * plugins, whichever plugin loads first declares the class for BOTH. So the version
 * of this class in memory may be older or newer than the bootstrap calling into it,
 * and that call happens during the plugin include phase where a "Call to undefined
 * method" is an unrecoverable site-wide fatal. Treat the public static entry points
 * as a frozen ABI: add methods, never rename or change the signature of an existing
 * one.
 */
final class Ping {
	private const ROUTE        = '/wcpos/v2/ping';
	private const PRETTY_ROUTE = '/wp-json/wcpos/v2/ping';

	/**
	 * Request-scoped host pressure bucket.
	 *
	 * @var string|null
	 */
	private static $host_pressure_bucket = null;

	/**
	 * Whether host pressure has been read this request.
	 *
	 * @var bool
	 */
	private static $host_pressure_checked = false;

	/**
	 * Host CPU count, or null when unavailable.
	 *
	 * @var int|null
	 */
	private static $host_cpu_count = null;

	/**
	 * Whether the host CPU count has been resolved.
	 *
	 * @var bool
	 */
	private static $host_cpu_count_resolved = false;
	// phpcs:disable Squiz.Commenting.FunctionComment.MissingParamTag, Squiz.Commenting.FunctionComment.Missing -- Typed signatures keep this bootstrap path within its strict size budget.
	/** Detect an exact raw ping request. */
	public static function matches_request( string $method, string $request_uri, ?string $rest_route ): bool {
		if ( 'GET' !== $method && 'HEAD' !== $method ) {
			return false;
		}
		$path = explode( '?', $request_uri, 2 )[0];

		return self::ROUTE === $rest_route || ( \strlen( $path ) >= \strlen( self::PRETTY_ROUTE ) && self::PRETTY_ROUTE === substr( $path, -\strlen( self::PRETTY_ROUTE ) ) );
	}

	/**
	 * Response headers that keep the ping out of proxy and server caches.
	 *
	 * The fast path answers before WP REST exists, so Rest_Cors never adds
	 * its cache-defeating headers here; without these an origin page cache
	 * served one host's ping (timestamp and pressure bucket) frozen for its
	 * whole TTL (measured 2026-09-16). Same Cache-Control value as Rest_Cors.
	 *
	 * @return array<string, string>
	 */
	public static function cache_defeating_headers(): array {
		return array(
			'Cache-Control'             => 'private, no-store',
			'X-LiteSpeed-Cache-Control' => 'no-cache',
		);
	}

	/** Belt and braces for drop-in page caches that finalise at shutdown and read constants, not headers. */
	private static function forbid_page_cache(): void {
		foreach ( array( 'DONOTCACHEPAGE', 'LSCACHE_NO_CACHE' ) as $constant ) {
			if ( ! \defined( $constant ) ) {
				\define( $constant, true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- third-party constant.
			}
		}
	}

	/** Serve a matching request before the remaining plugins load. */
	public static function maybe_serve(): void {
		$method = isset( $_SERVER['REQUEST_METHOD'] ) && \is_string( $_SERVER['REQUEST_METHOD'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : '';
		if ( 'GET' !== $method && 'HEAD' !== $method ) {
			return;
		}
		$request_uri = isset( $_SERVER['REQUEST_URI'] ) && \is_string( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
		if ( false === strpos( $request_uri, 'wcpos' ) ) {
			return;
		}
		$rest_route = isset( $_GET['rest_route'] ) && \is_string( $_GET['rest_route'] ) ? sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ) : null;
		if ( ! self::matches_request( $method, $request_uri, $rest_route ) ) {
			return;
		}
		$data = self::payload();
		self::forbid_page_cache();
		http_response_code( 200 );
		header( 'Content-Type: application/json; charset=UTF-8' );
		foreach ( self::cache_defeating_headers() as $name => $value ) {
			header( $name . ': ' . $value );
		}
		header( 'Access-Control-Allow-Origin: *' );
		// Deliberately just the one header this fast path can emit, not the
		// full Rest_Cors::EXPOSE_HEADERS set: this short-circuits before the
		// autoloader and WP REST exist. The OPTIONS preflight for this route
		// is answered by Rest_Cors on the normal REST lane.
		header( 'Access-Control-Expose-Headers: X-WCPOS-Pressure' );
		if ( isset( $data['pressure'] ) ) {
			header( 'X-WCPOS-Pressure: ' . $data['pressure'] );
		}
		if ( 'HEAD' !== $method ) {
			echo wp_json_encode( $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON HTTP response.
		}
		// Ship the response before exit's shutdown handlers run: the OTel
		// wordpress instrumentation reads conditional tags (is_404) at shutdown,
		// and with no query having run, WP_DEBUG_DISPLAY sites would append a
		// _doing_it_wrong notice after the JSON body (#1582). Under FPM, closing
		// the request first makes late output unreachable; elsewhere, mute
		// display so shutdown notices cannot corrupt the payload.
		if ( \function_exists( 'fastcgi_finish_request' ) ) {
			fastcgi_finish_request();
		} else {
			@ini_set( 'display_errors', '0' ); // phpcs:ignore WordPress.PHP.IniSet.display_errors_Disallowed, WordPress.PHP.NoSilencedErrors.Discouraged -- last-resort mute on non-FPM SAPIs; the response is already emitted.
		}
		exit;
	}

	/** Register the canonical REST fallback. */
	public function register_routes(): void {
		register_rest_route(
			'wcpos/v2',
			'/ping',
			array(
				'methods'             => 'GET, HEAD',
				'callback'            => array( $this, 'get_ping' ),
				'permission_callback' => '__return_true',
			)
		);
	}

	/** @return array<string, string[]> */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort -- compact typed classification.
	public function wcpos_route_classifications(): array {
		return array( 'public' => array( self::ROUTE ) );
	}

	/** Return the canonical REST response. */
	public function get_ping(): WP_REST_Response {
		$data     = self::payload();
		$response = new WP_REST_Response( $data, 200 );
		if ( isset( $data['pressure'] ) ) {
			$response->header( 'X-WCPOS-Pressure', $data['pressure'] );
		}

		return $response;
	}

	/** Convert normalized load to a pressure bucket, or read host load when omitted (memoized per request so body and header always agree). */
	public static function pressure_bucket( ?float $load = null ): ?string {
		if ( null === $load ) {
			if ( ! self::$host_pressure_checked ) {
				self::$host_pressure_checked = true;
				self::$host_pressure_bucket  = self::read_host_pressure_bucket();
			}

			return self::$host_pressure_bucket;
		}
		if ( $load < 0.9 ) {
			return 'low';
		}

		return $load <= 1.8 ? 'elevated' : 'high';
	}

	/**
	 * Use only /proc/cpuinfo because sys_getloadavg() reads host-wide /proc/loadavg,
	 * so its CPU divisor must share the host namespace rather than a container quota.
	 */
	public static function cpu_count_from_cpuinfo( ?string $cpuinfo ): ?int {
		$found = null !== $cpuinfo ? preg_match_all( '/^processor\s*:/m', $cpuinfo ) : false;

		return \is_int( $found ) && $found > 0 ? $found : null;
	}

	/**
	 * Normalize host load using the /proc/cpuinfo CPU count.
	 * Unknown counts yield null (no header), rather than misleading pressure from a guessed divisor.
	 */
	private static function read_host_pressure_bucket(): ?string {
		if ( ! \function_exists( 'sys_getloadavg' ) || ! \is_array( $average = @sys_getloadavg() ) || ! isset( $average[0] ) ) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure -- call only after availability check.
			return null;
		}
		if ( ! self::$host_cpu_count_resolved ) {
			$cpuinfo                       = @file_get_contents( '/proc/cpuinfo' );
			self::$host_cpu_count          = self::cpu_count_from_cpuinfo( false === $cpuinfo ? null : $cpuinfo );
			self::$host_cpu_count_resolved = true;
		}

		return null === self::$host_cpu_count ? null : self::pressure_bucket( (float) $average[0] / self::$host_cpu_count );
	}

	/** @return array<string, bool|int|string> */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort -- compact typed payload.
	private static function payload(): array {
		$data     = array( 'ok' => true, 'ts' => time(), 'v' => VERSION ); // phpcs:ignore WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound -- fixed four-field maximum.
		$pressure = self::pressure_bucket();
		if ( null !== $pressure ) {
			$data['pressure'] = $pressure;
		}

		return $data;
	}
}

```
