feat: media usage finder and media-get tool

Usage search distinguishes certain (ID referenced) and possible (file URL
only) usages, hides titles the user cannot read, and keeps queries bounded.
MediaGuard checks per-attachment capabilities and refuses trashed media
unless the caller opts in.

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:
2026-09-26 01:54:55 +02:00
co-authored by Claude Opus 5.5
parent 51e8846e1f
commit a2a2da1ae7
14 changed files with 1182 additions and 3 deletions
@@ -94,4 +94,23 @@ final class ContentSchemaTest extends TestCase
self::assertSame('footnotes', $withFields['fields'][0]['key']);
self::assertNull($schema->describe('et_pb_layout', false));
}
public function testMediaFieldKeysCoverFileFieldsAndMediaRelations(): void
{
Functions\when('get_post_types')->justReturn(['page' => 'page', 'lit_person' => 'lit_person']);
$source = Mockery::mock(FieldSource::class);
$source->allows('id')->andReturn('pods');
$source->allows('fieldsFor')->andReturnUsing(static fn (string $type): array => $type === 'lit_person'
? [
new FieldDefinition('photo', 'Foto', 'file', 'pods', 'writable'),
new FieldDefinition('logo', 'Logo', 'relation', 'pods', 'writable', false, false, null, [
'object_type' => 'media',
'name' => null,
]),
new FieldDefinition('role', 'Funktion', 'string', 'pods', 'writable'),
]
: [new FieldDefinition('photo', 'Foto', 'file', 'pods', 'writable')]);
self::assertSame(['logo', 'photo'], (new ContentSchema([$source]))->mediaFieldKeys());
}
}