• File: Telemetry.php
  • Full Path: /home/slvgwrnz/public_html/wp-content/plugins/woocommerce/src/Internal/ProductCustoms/Telemetry.php
  • Date Modified: 10/26/2026 10:38 AM
  • File size: 2.68 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php
/**
 * Aggregate product customs data for the WooCommerce tracker.
 */

declare( strict_types=1 );

namespace Automattic\WooCommerce\Internal\ProductCustoms;

use Automattic\WooCommerce\Enums\ProductStatus;
use Automattic\WooCommerce\Internal\RegisterHooksInterface;

defined( 'ABSPATH' ) || exit;

/**
 * Counts published products and variations with customs values in the periodic tracker snapshot.
 */
class Telemetry implements RegisterHooksInterface {

	/**
	 * Snapshot keys by "post type/meta key".
	 */
	private const COUNT_KEYS = array(
		'product/_customs_commodity_code'              => 'products_with_commodity_code',
		'product/_customs_country_of_origin'           => 'products_with_country_of_origin',
		'product/_customs_description'                 => 'products_with_customs_description',
		'product_variation/_customs_commodity_code'    => 'variations_with_commodity_code',
		'product_variation/_customs_country_of_origin' => 'variations_with_country_of_origin',
		'product_variation/_customs_description'       => 'variations_with_customs_description',
	);

	/**
	 * Registers the periodic snapshot filter.
	 *
	 * @since 11.3.0
	 *
	 * @return void
	 */
	public function register() {
		add_filter( 'woocommerce_tracker_data', array( $this, 'handle_woocommerce_tracker_data' ) );
	}

	/**
	 * Handle the woocommerce_tracker_data filter by adding aggregate customs counts.
	 *
	 * @internal
	 *
	 * @param mixed $data The tracker payload, which third-party filters may have changed.
	 * @return mixed
	 */
	public function handle_woocommerce_tracker_data( $data ) {
		if ( ! is_array( $data ) ) {
			return $data;
		}

		$data['product_customs'] = $this->collect_snapshot();
		return $data;
	}

	/**
	 * Counts published products and variations with stored customs values.
	 *
	 * @return array<string, int>
	 */
	private function collect_snapshot(): array {
		global $wpdb;

		$counts = array_fill_keys( self::COUNT_KEYS, 0 );
		$rows   = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT p.post_type, pm.meta_key, COUNT(DISTINCT pm.post_id) AS product_count
				 FROM {$wpdb->postmeta} pm
				 INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
				 WHERE pm.meta_key IN (%s, %s, %s)
				   AND pm.meta_value <> ''
				   AND p.post_type IN (%s, %s)
				   AND p.post_status = %s
				 GROUP BY p.post_type, pm.meta_key",
				'_customs_commodity_code',
				'_customs_country_of_origin',
				'_customs_description',
				'product',
				'product_variation',
				ProductStatus::PUBLISH
			)
		);

		foreach ( (array) $rows as $row ) {
			$key = self::COUNT_KEYS[ $row->post_type . '/' . $row->meta_key ] ?? null;
			if ( null !== $key ) {
				$counts[ $key ] = (int) $row->product_count;
			}
		}

		return $counts;
	}
}