Make identifier resolution resource aware in the Doctrine and Eloquent links handlers
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 48/100
調査の方向性
まず src/Doctrine/Common/State/LinksHandlerTrait.php の getIdentifierValue() とその6つの Doctrine 呼び出し箇所から始め、次に src/Laravel/Eloquent/State/LinksHandler.php の PersistProcessor と Eloquent buildQuery() パスを監査します。LinkProviderParameterTest::testLinkSecurityWithSlug を実行し、クエリの形状を変更せずに、Doctrine ORM、ODM、Laravel 全体でリソースを考慮した識別子の動作を検証します。
索引モデルが issue の本文から書いたものです。
説明
Follow-up to #8491.
#8491 lets a uri variable's parameter provider transform the value used to query the resource, and lets ReadLinkParameterProvider opt into writing the resolved resource into the uri variables (constructor flag, or the write_uri_variable extra property per link). Working on the resource rather than the identifier is usually easier when writing a custom provider.
That opt-in currently only works for resources whose provider does not query a persistence layer. On a Doctrine-backed link it fails with:
Object of class App\Entity\Company could not be converted to string
because the links handler compares the identifier column and binds the value with an explicit Doctrine type:
// src/Doctrine/Orm/State/LinksHandlerTrait.php
$queryBuilder->andWhere("$joinAlias.$identifierProperty = :$placeholder");
$queryBuilder->setParameter(
$placeholder,
$this->getIdentifierValue($identifiers, $hasCompositeIdentifiers ? $identifierProperty : null),
$fromClassMetadata->getTypeOfField($identifierProperty)
);
Proposal
Make identifier resolution accept a resolved resource and read the link's identifier off it, keeping the query shape unchanged. Reading the link's identifier (e.g. a name slug) rather than assuming the Doctrine primary key avoids the identifier-divergence problem.
Both backends funnel through a single method, so this is two small changes rather than three parallel ones:
| Backend | Method | Call sites covered |
|---|---|---|
| Doctrine | getIdentifierValue() in src/Doctrine/Common/State/LinksHandlerTrait.php |
ORM (4), ODM (2), PersistProcessor (4) — all share it |
| Eloquent | buildQuery() in src/Laravel/Eloquent/State/LinksHandler.php |
all 5 entry points funnel through it |
symfony/property-access is already a dependency.
Wrinkle
getIdentifierValue(array &$identifiers, ?string $name = null) only receives the property name when the link has composite identifiers; otherwise it is null and the method does array_shift($identifiers). Reading a property off an object requires knowing which property, and only the caller has it — so $identifierProperty needs to be passed unconditionally at the 6 Doctrine call sites. It is a private method on an @internal trait, so there is no BC surface.
Risk
PersistProcessor shares getIdentifierValue() and uses it to build references on write. It needs verifying that a resolved resource cannot reach it, or an explicit guard.
Suggested sequence
- Pass
$identifierPropertyunconditionally at the Doctrine call sites. - Make
getIdentifierValue()resource aware. - Audit
PersistProcessor. - Gate:
LinkProviderParameterTest::testLinkSecurityWithSluggreen withwrite_uri_variableenabled on a Doctrine-backed link. - Eloquent
buildQuery(). - ODM.
The bulk of the effort is verification across the three backends (the Laravel suite runs under testbench, ODM needs the mongodb environment), not the code itself.
Beyond this
Once identifier resolution is resource aware, flipping the default so ReadLinkParameterProvider always writes the resource becomes a separate, explicit BC decision. It is a real break for consumers independent of Doctrine: plain-ApiResource providers that read uri variables assume scalars — the Issue7939BazResource fixture does (string) ($uriVariables['barId'] ?? '') — so it would need an upgrade note. PreservesUriVariableInterface stays meaningful either way, since consumers still need resources kept out of the uri variables.
- 主要言語
- PHP
- スター
- 2.6k
- フォーク
- 982
- 平均マージ
- 1日 16時間
- マージ済み PR(30日)
- 59
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
api-platform/core のほかの issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
api-platform/core#8573 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
api-platform/core#8571 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
api-platform/core#8564 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
api-platform/core#8495 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
api-platform/core#8471 ·
api-platform/core の issue をすべて見る
似ている issue
-
tooling
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
UX
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
ProfessionalWiki/NeoWiki#1525 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
OpenConext/OpenConext-engineblock#2122 ·
-
Bug
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
Automattic/safe-publish#594 ·