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:
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Media;
|
||||
|
||||
use LIT\MCP\Abilities\Errors;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
|
||||
/**
|
||||
* Loads an attachment for abilities and checks the capability on that attachment
|
||||
* (spec §4.5). Every error is ready to be returned from permission()/execute().
|
||||
*/
|
||||
final class MediaGuard
|
||||
{
|
||||
/**
|
||||
* Trashed attachments (only possible with MEDIA_TRASH) are refused unless $allowTrashed:
|
||||
* readers pass it, writers must not (a change or a delete there would be surprising or permanent).
|
||||
*
|
||||
* @param string $capability Meta capability checked on the attachment: edit_post, delete_post or read_post.
|
||||
*/
|
||||
public static function attachment(
|
||||
mixed $id,
|
||||
string $capability = 'edit_post',
|
||||
bool $allowTrashed = false
|
||||
): WP_Post|WP_Error {
|
||||
$attachmentId = PostGuard::id($id);
|
||||
if ($attachmentId === null) {
|
||||
return Errors::invalidInput('id fehlt oder ist ungültig.', ['id' => 'positive Ganzzahl erwartet']);
|
||||
}
|
||||
|
||||
$attachment = get_post($attachmentId);
|
||||
if (! $attachment instanceof WP_Post || $attachment->post_type !== 'attachment') {
|
||||
return Errors::notFound(
|
||||
sprintf('Medium %d nicht gefunden.', $attachmentId),
|
||||
'ID prüfen; Medien über lit-media-search suchen.'
|
||||
);
|
||||
}
|
||||
|
||||
if (! current_user_can($capability, $attachmentId)) {
|
||||
return Errors::forbidden(sprintf('Keine Berechtigung für Medium %d.', $attachmentId));
|
||||
}
|
||||
|
||||
if (! $allowTrashed && $attachment->post_status === 'trash') {
|
||||
return Errors::invalidInput(
|
||||
sprintf('Medium %d liegt im Papierkorb.', $attachmentId),
|
||||
['id' => 'Medium liegt im Papierkorb'],
|
||||
'Medium zuerst in der WordPress-Mediathek wiederherstellen.'
|
||||
);
|
||||
}
|
||||
|
||||
return $attachment;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user