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
@@ -130,6 +130,29 @@ class ContentSchema
throw new LogicException(sprintf('No field source "%s" registered.', $field->source));
}
/**
* Keys of fields that store attachment IDs (file fields, relations to media) over all
* managed post types, sorted – used by the media usage search.
*
* @return list<string>
*/
public function mediaFieldKeys(): array
{
$keys = [];
foreach ($this->postTypeNames() as $postType) {
foreach ($this->fields($postType) as $field) {
if ($field->type === 'file' || ($field->related['object_type'] ?? null) === 'media') {
$keys[$field->key] = true;
}
}
}
$keys = array_map('strval', array_keys($keys));
sort($keys);
return $keys;
}
/** @return list<array{name: string, label: string, hierarchical: bool}> */
public function taxonomies(string $postType): array
{