web/admin/pdf: gemeinsame Bildnachweis-Auflösung, Detailfenster am Artikelbild, Bestätigungsstand in Kunden- und Adminansicht, Wortwahl „automatisierte Prüfung" (Bildkennzeichnung Block D)

- App\Support\ImageCredit: Foto/Quelle-Zeile, KI-Hinweis mit Herkunft, Verantwortlich-Zeile nur mit Protokoll, sichere Links; PDF-Zeilen mit Bestätigungskennung
- Artikelseite: Overlay (eigenes i-Zeichen, Alpine ohne Plugin, Bottom-Sheet auf Mobil) mit Nachweis, Lizenz, Quelle, KI-Hinweis, Verantwortlich-Zeile, „Bild melden"
- Richtlinien 0.2: Prüfung als automatisiert beschrieben, Abschnitt „Bilder" (Decision-Update 3.5); Taglines, Suche, Newsrooms, Startseiten-CTA, Mails ohne „qualitätsgeprüft"
- Cache-Invalidierung bei Bildwechsel an veröffentlichten Meldungen; PHPStan-Baseline für das Resource bereinigt

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-09-22 09:44:34 +00:00
parent 65ac72ce05
commit 2124ffd1f2
26 changed files with 578 additions and 199 deletions

View file

@ -21,6 +21,7 @@ use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
use Laravel\Sanctum\PersonalAccessToken;
use RuntimeException;
class PressReleaseImageController extends Controller
@ -148,9 +149,15 @@ class PressReleaseImageController extends Controller
noCrop: (bool) ($validated['no_crop'] ?? false),
);
// Token-ID fürs Protokoll über den Bearer-Header auflösen: Sanctums
// currentAccessToken() ist im Test ein TransientToken ohne Datensatz;
// ohne Bearer bleibt die ID leer, der Kontoinhaber steht trotzdem drin.
$bearer = $request->bearerToken();
$token = $bearer !== null ? PersonalAccessToken::findToken($bearer) : null;
$actor = ImageUploadActor::api(
$request->user(),
$request->user()->currentAccessToken()?->getKey(),
$token !== null ? (int) $token->getKey() : null,
$request->ip(),
$request->userAgent(),
);

View file

@ -77,7 +77,7 @@ class StorePressReleaseImageRequest extends FormRequest
if ($current === null || $given !== $current->key) {
$validator->errors()->add(
'confirm_text_version',
sprintf('The confirmation text version is not current. Current version: %s.', $current?->key ?? 'none'),
sprintf('The confirmation text version is not current. Current version: %s.', $current !== null ? $current->key : 'none'),
);
}
},

View file

@ -2,9 +2,13 @@
namespace App\Http\Resources;
use App\Models\PressReleaseImage;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* @mixin PressReleaseImage
*/
class PressReleaseImageResource extends JsonResource
{
/**
@ -51,8 +55,8 @@ class PressReleaseImageResource extends JsonResource
'rights_confirmation' => $this->whenLoaded('latestRightsConfirmation', fn () => $this->latestRightsConfirmation === null ? null : [
'version' => $this->latestRightsConfirmation->legal_text_key,
'agb_version' => $this->latestRightsConfirmation->agb_version,
'confirmed_at' => $this->latestRightsConfirmation->confirmed_at?->toIso8601String(),
'channel' => $this->latestRightsConfirmation->channel?->value,
'confirmed_at' => $this->latestRightsConfirmation->confirmed_at->toIso8601String(),
'channel' => $this->latestRightsConfirmation->channel->value,
]),
'warnings' => $this->warnings(),
'is_preview' => $this->is_preview,