Skip to content

fix(metadata): apply YAML/XML attributes to virtual (method-backed) properties#8220

Merged
soyuka merged 1 commit into
api-platform:4.3from
soyuka:fix/8178-yaml-virtual-property-extractor
Jun 2, 2026
Merged

fix(metadata): apply YAML/XML attributes to virtual (method-backed) properties#8220
soyuka merged 1 commit into
api-platform:4.3from
soyuka:fix/8178-yaml-virtual-property-extractor

Conversation

@soyuka

@soyuka soyuka commented Jun 2, 2026

Copy link
Copy Markdown
Member

Summary

ExtractorPropertyMetadataFactory::create() short-circuited to handleNotFound() whenever the resource class did not declare a real PHP property matching the requested name:

if (
    !property_exists($resourceClass, $property) && !interface_exists($resourceClass)
    || null === ($propertyMetadata = $this->extractor->getProperties()[$resourceClass][$property] ?? null)
) {
    return $this->handleNotFound($parentPropertyMetadata, $resourceClass, $property);
}

YAML and XML mappings can legitimately declare virtual properties backed by methods — e.g. admin mapped to isAdmin() — and ExtractorPropertyNameCollectionFactory already surfaces those names. The guard silently dropped configured metadata (security expressions, descriptions, IRIs, …) for any such property. PHP #[ApiProperty] attributes worked because they bypass this factory.

The remaining null-coalesce on the extractor lookup already provides the correct fallback to handleNotFound() when the property is not in the extracted mapping, so the property_exists clause is redundant for real PHP properties and incorrect for virtual ones.

Truth table after the change:

Real PHP prop Declared in YAML/XML Before After
yes yes extractor extractor
yes no handleNotFound handleNotFound (via ?? null)
no yes handleNotFound (bug) extractor (fix)
no no handleNotFound handleNotFound (via ?? null)

Only the third row changes.

Closes #8178

Test plan

  • New unit test ExtractorPropertyMetadataFactoryTest::testCreateVirtualPropertyFromExtractor — fails before the fix with PropertyNotFoundException: Property "admin" of the resource class … not found., green after.
  • src/Metadata/Tests/Property suite green (37/37).
  • PropertyMetadataCompatibilityTest (YAML + XML) still green.

ExtractorPropertyMetadataFactory short-circuited to
handleNotFound() when the resource class did not declare a PHP
property matching the requested name. YAML and XML mappings are
free to declare virtual properties backed by methods (e.g.
`admin` mapped to isAdmin()), and ExtractorPropertyNameCollection-
Factory already exposes them, so the guard silently dropped
configured metadata (security expressions, descriptions, etc.).
Remove the property_exists/interface_exists clause: the remaining
`extractor->getProperties()[$resourceClass][$property] ?? null`
already returns null when the property is not in the extracted
mapping, falling through to handleNotFound().

Closes api-platform#8178
@soyuka soyuka merged commit 6fc55c2 into api-platform:4.3 Jun 2, 2026
118 of 120 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant