Automattic\WooCommerce\Internal\EmailEditor\WCTransactionalEmails

WCEmailTemplateDivergenceDetector::reclassifypublic staticWC 10.9.0

Run the divergence classifier on a single post and stamp the resulting status. Used both by {@see self::run_sweep()} and by every code path that mutates post_content a woo_email post (auto-applier, selective applier, undo). Centralising the write here keeps {@see self::STATUS_META_KEY} consistent regardless of which writer triggered the change.

Returns the stamped status, or null when the classifier cannot decide (no stored source hash yet, post / email cannot be resolved). In the null case the meta is left untouched.

Метод класса: WCEmailTemplateDivergenceDetector{}

Хуков нет.

Возвращает

Строку|null. One of the STATUS_* constants, or null when no decision was made.

Использование

$result = WCEmailTemplateDivergenceDetector::reclassify( $post_id ): ?string;
$post_id(int) (обязательный)
The woo_email post ID.

Список изменений

С версии 10.9.0 Введена.

Код WCEmailTemplateDivergenceDetector::reclassify() WC 10.9.1

public static function reclassify( int $post_id ): ?string {
	$post = get_post( $post_id );
	if ( ! $post instanceof \WP_Post || Integration::EMAIL_POST_TYPE !== $post->post_type ) {
		return null;
	}

	$posts_manager = WCTransactionalEmailPostsManager::get_instance();
	$email_id      = (string) $posts_manager->get_email_type_from_post_id( $post_id );
	if ( '' === $email_id ) {
		return null;
	}

	$canonical_emails = $posts_manager->get_emails_by_id();
	$email            = $canonical_emails[ $email_id ] ?? null;
	if ( ! $email instanceof \WC_Email ) {
		return null;
	}

	$stored_source_hash = (string) get_post_meta( $post_id, self::SOURCE_HASH_META_KEY, true );
	if ( '' === $stored_source_hash ) {
		// This should not normally occur post-backfill: the generator always stamps
		// this meta and RSM-149 is supposed to have backfilled pre-existing posts.
		// Surface at warning so it's visible in the default WC log UI without
		// requiring operators to lower the email-editor logging threshold.
		self::get_logger()->warning(
			sprintf(
				'Email template divergence reclassify skipped post %d for email "%s": no stored source hash.',
				$post_id,
				$email_id
			),
			array(
				'email_id' => $email_id,
				'post_id'  => $post_id,
				'context'  => 'email_template_divergence_detector',
			)
		);
		return null;
	}

	$status = self::classify_post(
		$post_id,
		$email,
		array(
			'post_content'       => (string) $post->post_content,
			'stored_source_hash' => $stored_source_hash,
		)
	);

	if ( null === $status ) {
		return null;
	}

	// Fire `_update_available` on every sweep where the merchant hasn't yet
	// reviewed the current registry version, *before* the idempotency early-
	// return below. A post that stays `core_updated_customized` across
	// multiple core releases (merchant sits on the divergence through 10.7,
	// 10.8, 10.9…) still represents a fresh "update available" signal at
	// each new `version_to`: the status meta is unchanged but the registry
	// version has advanced, so analytics should see one event per release
	// boundary. The per-`(post_id, version_to)` dedup transient in the
	// tracker prevents same-release re-fires; the suppress-during-backfill
	// gate lives there too. Order matters: we fire here rather than after
	// the meta write so the cross-release case isn't accidentally
	// short-circuited by the status-unchanged guard.
	if ( self::STATUS_CORE_UPDATED_CUSTOMIZED === $status ) {
		$sync_config  = WCEmailTemplateSyncRegistry::get_email_sync_config( $email_id );
		$version_to   = null !== $sync_config ? (string) ( $sync_config['version'] ?? '' ) : '';
		$version_from = (string) get_post_meta( $post_id, self::VERSION_META_KEY, true );

		if ( '' !== $version_to && version_compare( $version_from, $version_to, '<' ) ) {
			WCEmailTemplateSyncTracker::record_update_available( $post_id );
		}
	}

	// Idempotent write: skip the meta call entirely when the status hasn't shifted,
	// so successive reclassifies on unchanged state produce zero DB writes (and zero
	// `update_post_metadata` filter calls observed by tests / observers).
	$existing_status = (string) get_post_meta( $post_id, self::STATUS_META_KEY, true );
	if ( $existing_status === $status ) {
		return $status;
	}

	update_post_meta( $post_id, self::STATUS_META_KEY, $status );

	return $status;
}