Bereinigungesw_svg_allowed_tags

esw_svg_allowed_tags

Filtert die SVG-Elemente, die Easy SVG beim Bereinigen behält: Lass ein fehlendes Zeichenelement zu oder entferne eines, das du nie speichern willst.

Filter · Easy SVG · Status: Stabil

Easy SVG bereinigt jedes SVG, bevor es gespeichert wird, und wirft jedes Element weg, dessen Name nicht auf einer Erlaubnisliste steht. Mit diesem Filter bekommst du diese Liste in die Hand: Du kannst ein Element ergänzen, das deine Grafiken brauchen, oder eines streichen, das du auf deiner Site nie haben willst. Die Änderung gilt für jeden Upload, jedes Icon und jedes Add-on der Site.

Verwendung

apply_filters( 'esw_svg_allowed_tags', array $tags )
add_filter( 'esw_svg_allowed_tags', 'myplugin_svg_tags' );

Wann du es brauchst

  • Dein Design-Tool exportiert ein Element, das in der Standardliste fehlt, und es verschwindet beim Hochladen. Typisch ist ein Filter-Primitiv wie feDropShadow, das die mitgelieferte Bibliothek nicht kennt.
  • Deine Site soll strenger sein als der Standard und ein Element aus jedem SVG entfernen, zum Beispiel eingebettete Bitmaps (image).
  • Ein Add-on bereinigt Markup über easy_svg_sanitizer() und soll dasselbe Element behalten wie deine Uploads. Das passiert automatisch, du musst nichts zusätzlich verdrahten.

Lass es bleiben:

  • Wenn du Skripte oder eingebettetes HTML erlauben willst. script, foreignObject, animate, set und iframe bleiben draußen. Mehr dazu im Warnkasten unten.
  • Wenn nur eine einzelne Datei betroffen ist. Exportiere sie lieber ohne das Element neu, statt die Liste für die ganze Site zu erweitern.
  • Wenn es eigentlich um ein Attribut geht. Attribute haben ihre eigene Liste, siehe esw_svg_allowed_attributes.

Parameter

body
$tagsstring[]
Required

Ein flaches, numerisch indiziertes Array mit Elementnamen, zum Beispiel array( 'a', 'font', 'image', 'style', 'svg', ... ). Ohne weitere Callbacks ist das die Standardliste der mitgelieferten Bibliothek enshrined/svg-sanitize (70 Einträge in Version 1.0.0). Verglichen wird ohne Rücksicht auf Groß- und Kleinschreibung mit dem Elementnamen, wie er in der Datei steht, samt Namespace-Präfix: svg:rect ist nicht rect.

Rückgabewert

returnstring[]

Die Elementnamen, die der Sanitizer behalten darf. Es muss ein Array sein. Alles andere (etwa null aus einem Callback, der sein return vergessen hat) lässt die Bibliothek beim Aufbau des Sanitizers einen TypeError werfen, und der Upload endet mit einem fatalen Fehler.

Standardwert

Die Liste AllowedTags aus enshrined/svg-sanitize 1.0.0, unverändert. Sie enthält bereits:

  • HTML-Namen: a, font, image, style
  • Formen und Struktur: svg, g, defs, symbol, use, view, switch, path, rect, circle, ellipse, line, polyline, polygon, marker, mask, pattern, clippath
  • Text: text, tspan, textpath, tref, title, desc, metadata und die alten SVG-Font-Elemente (glyph, hkern, vkern, altglyph und Verwandte)
  • Farbe und Effekte: lineargradient, radialgradient, stop, filter und 23 Filter-Primitive von feBlend bis feTurbulence
  • Animation: animatecolor, animatemotion, animatetransform, mpath

Nicht auf der Liste und daher standardmäßig entfernt: script, foreignObject, animate, set, iframe, object, embed, feDropShadow, feImage und alles aus Editor-Namespaces wie sodipodi:namedview.

Beispiele

Ein fehlendes Filter-Primitiv erlauben

/**
 * Schlagschatten aus feDropShadow behalten.
 *
 * @param string[] $tags Erlaubte Elementnamen.
 * @return string[]
 */
function myplugin_allow_drop_shadow( $tags ) {
	$tags[] = 'feDropShadow';
	return $tags;
}
add_filter( 'esw_svg_allowed_tags', 'myplugin_allow_drop_shadow' );

Die Attribute, die feDropShadow braucht (dx, dy, stdDeviation, flood-color, flood-opacity), stehen schon auf der Attributliste, diese eine Zeile reicht also. Ohne sie bleibt das filter-Element leer stehen und der Schatten verschwindet stillschweigend.

Elemente entfernen, die deine Site nie will

/**
 * Eingebettete Bitmaps und alte Font-Elemente aus jedem SVG entfernen.
 *
 * @param string[] $tags Erlaubte Elementnamen.
 * @return string[]
 */
function myplugin_strict_svg_tags( $tags ) {
	$blocked = array( 'image', 'font' );

	return array_values(
		array_filter(
			$tags,
			static function ( $tag ) use ( $blocked ) {
				return ! in_array( strtolower( $tag ), $blocked, true );
			}
		)
	);
}
add_filter( 'esw_svg_allowed_tags', 'myplugin_strict_svg_tags' );

Vergleiche in Kleinbuchstaben. Die Standardliste mischt Schreibweisen (feBlend, lineargradient), ein einfaches array_diff( $tags, array( 'feblend' ) ) findet daher nichts und entfernt nichts.

Defensive Variante für ein Plugin, das du weitergibst

/**
 * Elemente nur einmal ergänzen und immer ein Array zurückgeben.
 *
 * @param mixed $tags Erlaubte Elementnamen.
 * @return string[]
 */
function myplugin_svg_tags_defensive( $tags ) {
	$tags  = is_array( $tags ) ? $tags : array();
	$known = array_map( 'strtolower', $tags );

	foreach ( array( 'feDropShadow' ) as $tag ) {
		if ( ! in_array( strtolower( $tag ), $known, true ) ) {
			$tags[] = $tag;
		}
	}

	return $tags;
}

// Nur einhängen, wenn Easy SVG die Liste auch liest.
if ( defined( 'EASY_SVG_API' ) || function_exists( 'easy_svg_sanitizer' ) ) {
	add_filter( 'esw_svg_allowed_tags', 'myplugin_svg_tags_defensive' );
}

Ohne Bedingung einzuhängen schadet auch nicht: Ohne Easy SVG wendet niemand den Filter an. Die Abfrage dokumentiert nur die Absicht. Kann dein Plugin vor Easy SVG geladen werden, gehört die Abfrage in einen Callback auf plugins_loaded, denn beim Laden deiner Datei hat Easy SVG noch nichts definiert.

Füge niemals script, foreignObject, animate, set oder iframe hinzu. Die Erlaubnisliste entscheidet nur, welche Namen vorkommen dürfen. Was ein Element tut, prüft sie nicht: Ein animate-Element kann über attributeName und values ein href auf javascript: setzen, und foreignObject bettet HTML ein, für das die SVG-Regeln nie gedacht waren. Deine Admins öffnen hochgeladene Dateien in der Mediathek, eine aufgeweichte Liste ist also ein Weg, Code in ihrem Browser auszuführen.

So funktioniert es

Der Filter wird in esw_svg_tags::getTags() angewendet (easy-svg.php, Zeile 74). easy_svg_sanitizer() baut bei jedem Aufruf einen neuen Sanitizer und übergibt new esw_svg_tags() an setAllowedTags(). Das ruft getTags() auf, schreibt jeden Eintrag klein und speichert das Ergebnis. Dein Callback läuft also einmal pro Sanitizer, und jeder Weg, der SVG bereinigt, baut sich seinen eigenen:

Beim Bereinigen läuft die Bibliothek durch das Dokument und entfernt jedes Element, dessen kleingeschriebener Name nicht auf der Liste steht, samt allem, was darin liegt. Danach prüft sie die Attribute gegen esw_svg_allowed_attributes.

Was danach passiert, hängt vom Weg ab:

  • Uploads und neue Anhänge: Nach dem Bereinigen sucht esw_svg_file_checker() nach Animationselementen. Lässt deine Liste animate, set oder animate* durch, entfernt easy_svg_neutralize_href_animation() die, deren attributeName auf href oder einen on*-Handler zielt. Das passiert nur auf den Datei-Wegen, nicht in easy_svg_sanitizer().
  • wp_upload_bits (XML-RPC und Plugins, die Bytes schreiben): Der Filter kann Bytes nicht umschreiben, also wird die Datei abgelehnt, sobald der Sanitizer etwas ändern würde. Streichst du ein Element, das in einer Datei vorkommt, scheitert dieser Upload auf diesem Weg.
  • Icons: Nach dem Bereinigen entfernt easy_svg_harden_icon_markup() die Elemente aus EASY_SVG_ICON_UNSAFE_ELEMENTS (darunter style, script, foreignobject und jedes Animationselement), egal was deine Liste sagt, weil Icons direkt in die Seite eingebettet werden.

Die Upload-Filter sind nur registriert, solange SVG-Uploads in der Mediathek erlauben unter Icons, Einstellungen eingeschaltet ist. Die Prüfung neuer Anhänge läuft immer.

Stolperfallen

  • Ein entferntes Element nimmt seine Kinder mit. Streichst du g oder a, verschwindet jede Form in einer Gruppe oder einem Link, oft die ganze Zeichnung.
  • Gib immer ein Array zurück. Ein Callback, der null oder einen String liefert, führt beim Upload zu einem fatalen Fehler, nicht zu einem stillen Rückfall.
  • Vergleich ohne, Entfernen mit Groß- und Kleinschreibung. Abgeglichen wird kleingeschrieben, dein eigenes array_diff() unterscheidet aber. Vergleiche mit strtolower().
  • Präfixe zählen mit. Schreibt eine Datei svg:rect, muss svg:rect auf der Liste stehen. Eine Datei mit svg:svg als Wurzel kommt ohne Zeichnung heraus.
  • Das Readme-Beispiel bewirkt nichts. view steht schon auf der Standardliste.
  • Alte Dateien werden nicht neu geprüft. Die Liste greift, wenn eine Datei ankommt. Was schon in der Mediathek liegt, behält, was die Liste damals erlaubt hat.
  • Der alte globale Sanitizer ändert die Liste nicht. setAllowedTags() am alten globalen $sanitizer wirkt nicht, weil easy_svg_sanitizer() die Liste an seiner Kopie neu setzt. Nimm diesen Filter.
  • Kein Kontext-Argument. Der Callback bekommt nur die Liste. Uploads per WP-CLI, Cron oder Importer laufen unter Umständen ohne angemeldeten Benutzer. Machst du die Liste von current_user_can() abhängig, sehen diese Wege eine andere Liste.

Siehe auch