ACF\AI\GEO

Schema::infer_types_from_propertiespublic staticACF 6.8.0

Infer the minimal set of types needed for a set of properties

Given a list of properties, returns the most general types that directly define those properties, avoiding redundant child types.

For example:

  • ['prepTime', 'cookTime'] -> ['Recipe'] (most specific type with those properties)
  • ['headline'] -> ['CreativeWork'] (the base type that defines headline)

Method of the class: Schema{}

No Hooks.

Returns

Array. Array of type names

Usage

$result = Schema::infer_types_from_properties( $properties );
$properties(array) (required)
Array of property names.

Changelog

Since 6.8.0 Introduced.

Schema::infer_types_from_properties() code ACF 6.8.8

public static function infer_types_from_properties( $properties ) {
	if ( empty( $properties ) ) {
		return array();
	}

	// For each property, collect the types that directly define it
	$types_per_property = array();
	$property_domains   = SchemaData::get_property_domains();

	foreach ( $properties as $property ) {
		if ( ! isset( $property_domains[ $property ] ) ) {
			continue;
		}

		// These are the types that directly define this property
		$types_per_property[ $property ] = $property_domains[ $property ];
	}

	if ( empty( $types_per_property ) ) {
		return array();
	}

	// If we only have one property, return its direct types
	if ( count( $types_per_property ) === 1 ) {
		return array_values( reset( $types_per_property ) );
	}

	// Find types that can cover all properties (directly or through inheritance)
	$all_types   = array_unique( array_merge( ...array_values( $types_per_property ) ) );
	$valid_types = array();

	foreach ( $all_types as $type ) {
		$type_chain = array_merge( array( $type ), self::get_type_parents( $type ) );
		$covers_all = true;

		foreach ( $types_per_property as $property => $defining_types ) {
			// Check if this type or any of its parents define this property
			if ( empty( array_intersect( $type_chain, $defining_types ) ) ) {
				$covers_all = false;
				break;
			}
		}

		if ( $covers_all ) {
			$valid_types[] = $type;
		}
	}

	// If we found types that cover everything, remove redundant parents
	if ( ! empty( $valid_types ) ) {
		$minimal_types = array();
		foreach ( $valid_types as $type ) {
			$is_redundant = false;
			foreach ( $valid_types as $other_type ) {
				if ( $type !== $other_type && self::is_parent_of( $type, $other_type ) ) {
					// This type is a parent of another type in the list, so it's redundant
					$is_redundant = true;
					break;
				}
			}
			if ( ! $is_redundant ) {
				$minimal_types[] = $type;
			}
		}
		return array_values( $minimal_types );
	}

	// No single type covers all properties, need multiple types
	return self::find_minimal_type_set( $properties );
}