'jpg', 'image/png' => 'png', 'image/webp' => 'webp', 'image/gif' => 'gif', ]; public function name(): string { return 'lit/media-preview'; } public function label(): string { return 'Bildvorschau'; } public function description(): string { return 'Zeigt ein Bild der Mediathek als verkleinerte Vorschau (längste Kante max_size, Standard 512 px), ' . 'damit der Inhalt beurteilt werden kann, z. B. für Alt-Texte.'; } public function inputSchema(): array { return [ 'type' => 'object', 'properties' => [ 'id' => ['type' => 'integer', 'minimum' => 1], 'max_size' => ['type' => 'integer', 'minimum' => 64, 'maximum' => 1024], ], 'required' => ['id'], 'additionalProperties' => false, ]; } public function outputSchema(): ?array { return null; } public function annotations(): array { return ['readonly' => true, 'destructive' => false, 'idempotent' => true]; } public function isDirect(): bool { return true; } public function permission(array $input): bool|WP_Error { $attachment = MediaGuard::attachment($input['id'] ?? null); return $attachment instanceof WP_Error ? $attachment : true; } public function execute(array $input): mixed { $attachment = MediaGuard::attachment($input['id'] ?? null); if ($attachment instanceof WP_Error) { return $attachment; } $id = (int) $attachment->ID; if (! wp_attachment_is_image($id)) { return Errors::unsupported( 'Das Medium ist kein Bild.', 'Metadaten über lit/media-get abrufen; Dateien über lit-media-download.' ); } $file = get_attached_file($id); if (! is_string($file) || ! is_readable($file) || ! MediaFiles::isWithinUploads($file)) { return Errors::notFound('Die Bilddatei fehlt auf dem Server.', 'Medium in der Mediathek prüfen.'); } AdminIncludes::load(); $editor = wp_get_image_editor($file); if ($editor instanceof WP_Error) { return Errors::unsupported( 'Das Bild kann nicht verarbeitet werden: ' . $editor->get_error_message(), 'Metadaten über lit/media-get abrufen.' ); } $max = max(64, min(1024, (int) ($input['max_size'] ?? self::DEFAULT_SIZE))); $size = (array) $editor->get_size(); if (max((int) ($size['width'] ?? 0), (int) ($size['height'] ?? 0)) > $max) { $resized = $editor->resize($max, $max, false); if ($resized instanceof WP_Error) { return Errors::unsupported( 'Vorschau konnte nicht verkleinert werden.', 'Metadaten über lit/media-get abrufen.' ); } } $mime = isset(self::EXTENSIONS[$attachment->post_mime_type]) ? (string) $attachment->post_mime_type : 'image/jpeg'; $target = wp_tempnam('lit-mcp-preview'); $saved = $editor->save($target . '.' . self::EXTENSIONS[$mime], $mime); wp_delete_file($target); if (! is_array($saved) || ! isset($saved['path'])) { return Errors::unsupported( 'Vorschau konnte nicht erzeugt werden.', 'Metadaten über lit/media-get abrufen.' ); } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $bytes = file_get_contents((string) $saved['path']); wp_delete_file((string) $saved['path']); if ($bytes === false) { return Errors::internal(); } return ['type' => 'image', 'results' => $bytes, 'mimeType' => (string) ($saved['mime-type'] ?? $mime)]; } }