=== lern.link Portal ===
Contributors: lernlink
Tags: elearning, lernlink, pptx, player
Requires at least: 6.0
Requires PHP: 8.0
Stable tag: 0.13.0
License: GPLv2 or later

Bettet lern.link-Lerninhalte in WordPress ein (Player-Embed gegen die llp-api).

== Description ==
Shortcode [llp content="<content_id>" height="540"] bettet den Player geschützt ein (Player-HTML wird
serverseitig mit API-Key geholt und per iframe srcdoc eingebettet). Plus Einstellungsseite (lern.link →
Einstellungen), Content-Picker (lern.link → Inhalte), Gutenberg-Block und der Player↔WordPress-Bridge
(Fortschritt/Wiedereinstieg, Bewertung, Abrechnung) — siehe README.md.

== Changelog ==
= 0.13.0 =
* Vollbild im eingebetteten Player funktioniert wieder (Testerbefund "fullscreen geht nicht").
  Ursache war nicht der Vollbild-Knopf, sondern dass in Block-Themes (Twenty Twenty-Five und jedes
  andere Theme mit Website-Editor) das Bruecken-Skript des Plugins GAR NICHT geladen wurde:
  WordPress rendert den Block-Baum dort, bevor die Skript-Registrierung laeuft, und das Plugin liess
  den Ladevorgang in diesem Fall still aus. Damit fielen zugleich Fortschritt/Wiedereinstieg,
  Sterne-Bewertung, Quiz-Ergebnis, die Portal-Lasche und das Folien-Seitenverhaeltnis aus.
  Klassische Themes waren nie betroffen.
* Vollbild schaltet jetzt um: derselbe Knopf geht hinein UND wieder heraus (vorher ging nur hinein).
  Verweigert der Browser den Vollbildmodus, bleibt es still statt eine Fehlermeldung in der Konsole
  zu hinterlassen.
* Das Vorschau-Fenster in der WordPress-Verwaltung (lern.link -> Inhalte, Klick auf einen Deck-Namen)
  beantwortet den Vollbild-Wunsch jetzt ebenfalls — dort passierte bisher gar nichts. Beim Schliessen
  der Vorschau wird ein laufendes Vollbild sauber verlassen.

= 0.12.0 =
* Portal-Lasche im Player: Der Klick auf die Lasche ganz links im Mini-Player oeffnet das Portal
  jetzt DIREKT auf der Folie, die gerade zu sehen war (Player meldet {llp:"trainer-open", slide_id},
  die Bridge haengt &slide_id=... an den Portal-Link). Meldet ein aelterer Player keine Folie,
  bleibt der Link unveraendert. Das Ziel unterliegt derselben Berechtigungspruefung wie der
  "Im Portal bearbeiten"-Knopf — Besucher ohne Berechtigung bekommen die Portal-URL gar nicht.

= 0.11.1 =
* Autoplay-Vertonung: Ton-Freigabe im eingebetteten Player (allow="autoplay" am Player-iframe,
  Frontend-Embed und Admin-Vorschau). Ohne das Attribut blockierte Chromium in sandboxed
  iframes das automatische Abspielen der Vertonung/Karaoke dauerhaft.

= 0.11.0 =
* Sicherheit: Selbst-Update jetzt fail-closed — ein Update wird nur noch eingespielt, wenn das
  Manifest eine SHA-256-Prüfsumme liefert UND Manifest- wie Paket-URL HTTPS sind; andernfalls wird
  es abgelehnt statt ungeprüft geladen (vorher wurde ohne sha256 im Manifest still durchgewinkt).
* Sicherheit: Die API-Key-Option wird nicht mehr bei jedem Seitenaufruf autogeladen (autoload=no,
  inkl. einmaliger Umstellung bei Bestandsinstallationen). Die Einstellungsseite stellt die
  wp-config-Konstante WP_LLP_API_KEY als bevorzugten, sichereren Weg voran.
* Sicherheit: Die Player↔WordPress-Bridge (Fortschritt/Bewertung/Quiz) bindet ihre Nonce jetzt an
  die content_id — die Endpunkte akzeptieren nur noch Decks, die auf dieser Site tatsächlich
  eingebettet sind; für beliebige fremde content_ids lassen sich keine Bewertungen/Telemetrie mehr
  einschleusen.

= 0.10.0 =
* Neues Attribut player="simple|standard|kiosk|exam" am Shortcode und am Gutenberg-Block (Auswahl
  im Editor). Default ist der neue Besucher-Player „simple": nur Blättern, Fortschritt, Vollbild und
  das Abspielen bereits vorhandener Audios — keine Generier-/Trainer-/Kommentar-/Bewertungs-UI, denn
  Webseiten-Besucher sollen solche Autorenfunktionen nie sehen. player="standard" stellt das bisherige
  Verhalten (Deck-Voreinstellung) wieder her. Ungültige Werte fallen auf „simple" zurück.
  Der Embed-Cache unterscheidet jetzt zusätzlich nach dem gewählten Player.

= 0.9.3 =
* Player-Einbettung passt sich dem Seitenverhältnis der Folie an — keine schwarzen Balken mehr bei nicht-
  16:9-Inhalten. (Eine per Shortcode gesetzte feste Höhe bleibt erhalten.)

= 0.9.2 =
* Bewertungs-Badge unter dem eingebetteten Player (Durchschnitt + Anzahl Sterne, analog Moodle).
  Wird serverseitig geholt und kurz gecacht; erscheint nur, wenn bereits Bewertungen vorliegen.

= 0.9.1 =
* Lerndaten: WP-stämmige Nutzungs-/Abrechnungssignale tragen jetzt eine Kanal-Markierung („wordpress"),
  damit die lern.link-Plattform Lerndaten je Auslieferungsweg (Portal/SCORM/WordPress) unterscheiden kann.

= 0.9.0 =
* Player↔WordPress-Bridge: der eingebettete Player meldet jetzt Fortschritt an WordPress. Eingeloggte
  Nutzer steigen automatisch dort wieder ein, wo sie aufgehört haben (Wiedereinstieg auto/fragen/aus);
  Gäste merken sich den Stand im Browser. Sterne-Bewertungen und die Nutzungs-/Token-Abrechnung werden
  serverseitig an die lern.link-Plattform weitergereicht. Sicherheit: API-Key bleibt serverseitig,
  alle Endpunkte mit Nonce + strikter Eingabeprüfung.

= 0.8.0 =
* Selbst-Updates über einen eigenen Kanal (lern.link, nicht wordpress.org): „Update verfügbar" +
  Ein-Klick-Update aus einem Manifest. Standardmäßig stilles Hintergrund-Auto-Update, in den
  Einstellungen abschaltbar. SHA-256-Prüfung der ZIP vor dem Einspielen.

= 0.7.1 =
* Embed-Cache an updated_at des Decks gekoppelt: Player-Einstellungen (und andere Änderungen) wirken
  jetzt ohne Verzögerung — der Cache invalidiert automatisch, sobald sich am Deck etwas ändert.

= 0.7.0 =
* Gutenberg-Block „lern.link Player" (dynamisch): Deck-Auswahl im Editor + Live-Vorschau
  (ServerSideRender), rendert im Frontend über dieselbe Engine wie der Shortcode.
* Größe der Einbettung wählbar (Automatisch/Klein/Mittel/Groß) — im Block per Auswahl, am Shortcode
  via size="small|medium|large".

= 0.6.0 =
* Content-Picker zeigt jetzt per Default ALLE für den Key freigegebenen Pakete (Filter „nur
  Plattform-Bibliothek" ist opt-in).
* „Bearbeiten"-Knopf am Player: Deep-Link in den Portal-Editor, sichtbar nur ab wählbarer Rolle
  (Einstellung, Default „Autoren und höher"); normale Besucher sehen ihn nie.
* Neue Einstellungen: Portal-URL + Edit-Knopf-Rolle.

= 0.5.0 =
* Content-Picker: Klick auf den Deck-Namen öffnet eine Player-Vorschau im Modal (server-seitig per
  admin-ajax geholt, manage_options + Nonce; Sandbox-iframe). Schließen per ×, Backdrop oder Esc.

= 0.4.4 =
* Vereinfachung: Einstellung „Standard-Höhe" entfernt (Folien sind 16:9; der Player füllt automatisch).
  Optionales height="<px>" am Shortcode bleibt als Sonderfall.

= 0.4.3 =
* Embed-Fix: Player-HTML wird fürs srcdoc jetzt doppelt escaped (double_encode). esc_attr() verdoppelt
  vorhandene Entities NICHT, wodurch der Browser den Escaping-Helper des Players zerlegte (JS-Syntaxfehler
  → Player startete nicht → nur Folienkopf sichtbar). Jetzt rendern Text und Bilder vollständig.

= 0.4.2 =
* Embed-Sizing korrigiert: Player füllt jetzt korrekt per aspect-ratio 16:9 (vorher zeigte ein festes
  height-Attribut nur einen Folienausschnitt). Standard-Höhe 0 = automatisch. iframe zusätzlich
  sandboxed (allow-scripts, allow=fullscreen) — wie der mod_llp-Player.
* Content-Picker: Schalter „alle Inhalte zeigen" (ohne pickable-Filter), nicht nur die Bibliothek.

= 0.4.1 =
* Sicherheit: API-Key kann als Konstante WP_LLP_API_KEY in wp-config.php gesetzt werden (hat Vorrang
  vor der DB-Option) — hält den Key aus Datenbank/Backups. Settings-Feld wird dann deaktiviert.

= 0.4.0 =
* Geschützter serverseitiger Embed: Shortcode holt die Player-HTML mit Bearer-Key (GET /content/{id}/embed,
  Accept text/html) und bettet sie per iframe srcdoc ein — behebt das 401 des nackten Browser-iframes.
* Transient-Cache (300s) für die Embed-HTML; Fehler werden nicht gecacht.

= 0.3.0 =
* Content-Picker: Admin-Seite "lern.link → Inhalte" listet verfügbare Decks (GET /content/?pickable=true)
  mit Kopier-Knopf für den Shortcode.
* Serverseitiger API-Client (Bearer-Key) als geteilte Basis für Picker/Block/Embed.
* Top-Level-Menü "lern.link" (Inhalte + Einstellungen).

= 0.2.0 =
* Einstellungsseite via WordPress Settings API (API-Basis-URL, API-Key, Standard-Höhe).
* Embed-URL trifft jetzt die /api/v1-Routen der llp-api (Fix).
* Basis-URL-Validierung (http/https) + responsives Player-CSS.

= 0.1.0 =
* Gerüst: aktivierbares Plugin, Shortcode [llp], ungeschützter Embed-iframe.
