perf: DynamicFields reads each post type's fields once per check (review M-12 b)
reason() and note() run per key and type of a body check; they now share one offered() result per post type, so the default storage callback loads each pod once instead of per call. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -38,6 +38,9 @@ class DynamicFields
|
||||
/** @var Closure(string): ?string */
|
||||
private Closure $podStorage;
|
||||
|
||||
/** @var array<string, array{0: list<array<string, string>>, 1: list<array<string, string>>}> offered() by type. */
|
||||
private array $known = [];
|
||||
|
||||
/** @param (Closure(string): ?string)|null $podStorage Post type → Pods storage ("meta", "table"), null: none. */
|
||||
public function __construct(private ContentSchema $schema, ?Closure $podStorage = null)
|
||||
{
|
||||
@@ -72,10 +75,21 @@ class DynamicFields
|
||||
return [$fields, $omitted];
|
||||
}
|
||||
|
||||
/**
|
||||
* offered() once per post type for reason()/note() – they run per key and type of a check, and the default
|
||||
* storage callback loads the pod each time (review M-12 b).
|
||||
*
|
||||
* @return array{0: list<array<string, string>>, 1: list<array<string, string>>}
|
||||
*/
|
||||
private function known(string $postType): array
|
||||
{
|
||||
return $this->known[$postType] ??= $this->offered($postType);
|
||||
}
|
||||
|
||||
/** Why {{field:$key}} would not show as text for $postType; null when it does. */
|
||||
public function reason(string $postType, string $key): ?string
|
||||
{
|
||||
[$fields, $omitted] = $this->offered($postType);
|
||||
[$fields, $omitted] = $this->known($postType);
|
||||
foreach ($fields as $field) {
|
||||
if ($field['key'] === $key) {
|
||||
return null;
|
||||
@@ -93,7 +107,7 @@ class DynamicFields
|
||||
/** What to know about an offered field of $postType ($key) that shows other text than expected; else null. */
|
||||
public function note(string $postType, string $key): ?string
|
||||
{
|
||||
[$fields] = $this->offered($postType);
|
||||
[$fields] = $this->known($postType);
|
||||
foreach ($fields as $field) {
|
||||
if ($field['key'] === $key && $field['type'] === 'choice') {
|
||||
return 'Auswahlfeld – Divi zeigt den gespeicherten Wert, nicht die Beschriftung';
|
||||
|
||||
@@ -51,6 +51,28 @@ final class DynamicFieldsTest extends TestCase
|
||||
self::assertNull(self::fields()->note('lit_person', 'telefon'));
|
||||
}
|
||||
|
||||
/** Review M-12 (b): reason() and note() read a type's fields (and its Pods storage) once per instance. */
|
||||
public function testReasonAndNoteReadEachTypeOnce(): void
|
||||
{
|
||||
$schema = Mockery::mock(ContentSchema::class);
|
||||
$schema->shouldReceive('fields')->with('lit_person')->once()->andReturn([
|
||||
new FieldDefinition('role', 'Funktion', 'string', 'pods', FieldDefinition::WRITABLE),
|
||||
]);
|
||||
$storage = 0;
|
||||
$fields = new DynamicFields($schema, static function (string $type) use (&$storage): ?string {
|
||||
++$storage;
|
||||
|
||||
return 'meta';
|
||||
});
|
||||
|
||||
foreach (['role', 'telefon', 'role'] as $key) {
|
||||
$fields->reason('lit_person', $key);
|
||||
$fields->note('lit_person', $key);
|
||||
}
|
||||
|
||||
self::assertSame(1, $storage);
|
||||
}
|
||||
|
||||
private static function content(string $name, array $settings): string
|
||||
{
|
||||
return VariableRef::serialize('content', $name, $settings);
|
||||
|
||||
Reference in New Issue
Block a user