Entwickler-AnleitungenAuf Set-Änderungen reagieren

Auf Set-Änderungen reagieren

Häng dich mit easy_svg_pro_set_icons_written an jedes Speichern eines Icon-Sets: Caches leeren, JSON exportieren, Team informieren, alte Versionen lesen.

Icon-Sets ändern sich an vielen Stellen: im Set-Editor, in der Mehrfachbearbeitung, bei Importen, Presets, über WP-CLI, im Kundenmodus und durch die KI-Abilities. Baut dein Theme oder Plugin etwas aus einem Set, musst du wissen, wann es sich geändert hat. Dieses Tutorial zeigt dir den einen Hook, der jede Änderung mitbekommt, wie dein Code sicher bleibt, wenn zwei Speichervorgänge gleichzeitig laufen, und wie du frühere Versionen aus den WordPress-Revisionen liest.

Die eine Stelle, an der jede Änderung vorbeikommt

Jeder Weg, der die Icons eines Sets ändert, endet in derselben internen Funktion. Sie speichert die Icons und löst dann easy_svg_pro_set_icons_written aus. Du musst dich also nie getrennt an Editor, Importe und WP-CLI hängen.

Was du bekommst: die Post-ID des Sets und die vollständige Liste der Icons nach dem Speichern, jeweils mit label und bereinigtem markup. Was du nicht bekommst: den vorherigen Stand oder eine Liste der Änderungen.

Was hier nicht vorbeikommt: ein leeres Set anlegen, ein Set umbenennen, in den Papierkorb legen, wiederherstellen und löschen. Das ändert den Post, nicht seine Icons.

Schritt für Schritt: ein JSON-Export pro Set

Ein typischer Agentur-Fall: Ein Headless-Frontend oder ein Designsystem will die Icons eines Sets als JSON-Datei. Wir schreiben pro Set eine Datei in den Uploads-Ordner und halten sie aktuell.

Die Action einhängen

Registrier den Callback, wenn dein Plugin lädt, und nur, wenn Easy SVG Pro da ist.

add_action(
	'plugins_loaded',
	function () {
		if ( ! defined( 'EASY_SVG_PRO_FILE' ) ) {
			return;
		}
		add_action( 'easy_svg_pro_set_icons_written', 'acme_export_set_json', 10, 2 );
	}
);

Den Slug der Sammlung finden

Templates und Frontends sprechen Icons als collection/slug an. Die Post-ID ist nicht dieser Slug. Easy SVG Pro speichert den Slug pro Set in einer Option, mit der Post-ID als Schlüssel.

function acme_set_collection_slug( $post_id ) {
	$slugs = get_option( 'easy_svg_pro_set_collection_slugs', array() );
	if ( is_array( $slugs ) && ! empty( $slugs[ (string) $post_id ] ) ) {
		return (string) $slugs[ (string) $post_id ];
	}

	// Ein Set, das in diesem Request angelegt wurde, wird beim nächsten Seitenaufruf eingetragen.
	return (string) get_post_field( 'post_name', $post_id );
}

Die Datei schreiben

function acme_export_set_json( $post_id, $icons ) {
	if ( 'publish' !== get_post_status( $post_id ) ) {
		return;
	}

	$uploads = wp_upload_dir();
	$dir     = trailingslashit( $uploads['basedir'] ) . 'icon-sets';
	if ( ! wp_mkdir_p( $dir ) ) {
		return;
	}

	$slug = sanitize_file_name( acme_set_collection_slug( $post_id ) );
	$data = array(
		'collection' => $slug,
		'label'      => get_the_title( $post_id ),
		'updated'    => gmdate( 'c' ),
		'icons'      => array(),
	);
	foreach ( $icons as $icon_slug => $icon ) {
		$data['icons'][ $icon_slug ] = array(
			'label'  => (string) ( $icon['label'] ?? $icon_slug ),
			'markup' => (string) ( $icon['markup'] ?? '' ),
		);
	}

	file_put_contents( $dir . '/' . $slug . '.json', wp_json_encode( $data ) );
}

Das Markup ist schon bereinigt und gehärtet, du kannst es also so weitergeben.

Aufräumen, wenn ein Set geht

Beim Papierkorb und beim Löschen feuert die Action nicht. Häng dich selbst ein.

function acme_remove_set_json( $post_id ) {
	if ( 'easy_svg_set' !== get_post_type( $post_id ) ) {
		return;
	}
	$uploads = wp_upload_dir();
	$file    = trailingslashit( $uploads['basedir'] ) . 'icon-sets/' . sanitize_file_name( acme_set_collection_slug( $post_id ) ) . '.json';
	if ( file_exists( $file ) ) {
		wp_delete_file( $file );
	}
}
add_action( 'wp_trash_post', 'acme_remove_set_json' );
add_action( 'before_delete_post', 'acme_remove_set_json' );

Langsames aus dem Speichern heraushalten

Dein Callback läuft in dem Request, der das Set speichert. Eine Person im Editor, ein Kunde im Kundenmodus oder ein CI-Job wartet darauf. Alles Langsame (ein HTTP-Aufruf, Bildgenerierung, ein CDN-Upload) gehört in einen Hintergrund-Job:

function acme_queue_set_sync( $post_id, $icons ) {
	if ( ! wp_next_scheduled( 'acme_sync_icon_set', array( (int) $post_id ) ) ) {
		wp_schedule_single_event( time() + 60, 'acme_sync_icon_set', array( (int) $post_id ) );
	}
}
add_action( 'easy_svg_pro_set_icons_written', 'acme_queue_set_sync', 10, 2 );

Die Prüfung mit wp_next_scheduled() fasst zehn schnelle Speichervorgänge zu einem Abgleich zusammen. Wenn der Job läuft, lies das Set frisch, statt die $icons vom Zeitpunkt des Einplanens zu nehmen.

Sets aus eigenem Code schreiben

Ändert dein Cron-Job, dein admin-post.php-Handler oder dein Webhook Sets, sag Easy SVG Pro, dass der Request schreibt, damit es vorher die Set-Sperre nimmt. Ohne sie können zwei überlappende Speichervorgänge Icons verlieren.

add_filter(
	'easy_svg_pro_set_write_context',
	function ( $writes ) {
		return $writes || wp_doing_cron();
	}
);

REST-Requests, die kein GET sind, und WP-CLI sind schon abgedeckt. Was die Sperre macht und wo sie nicht hinreicht, steht bei easy_svg_pro_set_write_context.

Um Sets aus Code zu ändern, nimm die REST-Routen oder die Abilities, die über den Sanitizer und die Sperre laufen. Schreib das Post-Meta _easy_svg_set_icons nie selbst: Du umgehst damit Bereinigung, Sperre und diese Action.

Frühere Versionen mit dem Icon-Verlauf

Schaltest du Icon-Verlauf unter Icons → Funktionen ein, hängt sich Easy SVG Pro an dieselbe Action und bittet WordPress nach jedem Speichern um eine Revision. Die Revisionen tragen das Meta _easy_svg_set_icons, du kannst also lesen, wie ein Set vorher aussah. Pro Set bleiben die letzten zehn Revisionen, und WordPress legt keine neue an, wenn sich nichts geändert hat.

/**
 * Die Icons, die ein Set ein Speichern vorher hatte, oder ein leeres Array.
 */
function acme_previous_set_icons( $post_id ) {
	$revisions = wp_get_post_revisions( $post_id, array( 'order' => 'DESC' ) );
	$revisions = array_values( $revisions );

	// [0] ist das Speichern, das gerade passiert ist, [1] das davor.
	if ( ! isset( $revisions[1] ) ) {
		return array();
	}

	$raw  = get_post_meta( $revisions[1]->ID, '_easy_svg_set_icons', true );
	$data = is_string( $raw ) ? json_decode( $raw, true ) : null;

	return is_array( $data ) ? $data : array();
}

Ruf sie aus einem Callback mit Priorität 20 auf, damit der Callback des Verlaufs (Priorität 10) die neue Revision schon gespeichert hat. Hat das Speichern nichts geändert, hat WordPress keine neue Revision angelegt, und [0] ist schon der Stand davor. Vergleich [0] zuerst mit den aktuellen Icons, wenn dir dieser Fall wichtig ist.

Revisions-Meta ist der rohe gespeicherte Wert und wird beim Lesen auf diesem Weg nicht erneut gehärtet. Der Verlauf von Easy SVG Pro schickt ihn durch den Härter, bevor er etwas zeichnet. Mach es genauso, oder vergleich ihn nur und gib ihn nie aus.

Der Verlauf beginnt, wenn die Funktion eingeschaltet wird. Speichervorgänge davor haben keine Revision hinterlassen.

Checkliste

  • Nimm zwei Argumente an: add_action( ..., 10, 2 ).
  • Behandle $icons als kompletten neuen Stand, nicht als Differenz.
  • Rechne mit der Action auch, wenn sich nichts geändert hat, und mit zwei Sets bei einem Verschieben.
  • Häng dich selbst an Papierkorb, Wiederherstellen und Löschen, wenn du Caches baust.
  • Mach aus der Post-ID den Sammlungs-Slug über easy_svg_pro_set_collection_slugs.
  • Verlag Langsames in Cron.
  • Ergänze easy_svg_pro_set_write_context, wenn dein eigener Code außerhalb von REST und WP-CLI Sets schreibt.

Siehe auch