easy_svg_pro_set_write_context
Entscheide, ob ein Request vor dem Lesen eines Sets die Set-Sperre nimmt, damit dein Cron-Job oder Formular keinen anderen Schreibvorgang überschreibt.
Filter · Easy SVG Pro · Status: Stabil
Ein Set speichert alle Icons als einen einzigen Wert. Jede Änderung liest diesen Wert, ändert ihre Kopie und schreibt alles zurück. Machen das zwei Requests gleichzeitig, schreibt der zweite eine Kopie zurück, in der die Änderung des ersten fehlt. Easy SVG Pro verhindert das mit einer Sperre, aber nur in Requests, von denen es weiß, dass sie schreiben. Mit diesem Filter sagst du ihm, dass dein Request auch schreibt.
Verwendung
apply_filters( 'easy_svg_pro_set_write_context', bool $writes )
Angewendet in includes/editor/sets.php, in der internen Funktion set_write_context(). Der Filter wird bei jedem Lesen und Schreiben eines Sets gefragt, bis die Sperre in diesem Request einmal genommen wurde.
Wann du es brauchst
- Ein Cron-Job von dir ändert Sets, zum Beispiel ein nächtlicher Abgleich mit einem Designsystem.
- Ein Formular-Handler über
admin-post.php, eine AJAX-Action oder ein Webhook-Endpunkt, der keine REST-Route ist, ändert Sets. - Du führst die Abilities aus PHP aus (
wp_get_ability( ... )->execute()), außerhalb eines REST-Requests, etwa aus deinem eigenen Queue-Worker.
Nicht dafür gedacht:
- Dein Code liest Sets nur. Lesen braucht keine Sperre, und eine Sperre lässt jeden anderen Schreiber warten.
- Dein Code läuft als REST-Request mit POST, PUT, PATCH oder DELETE oder unter WP-CLI. Das ist schon ein Schreibkontext.
Parameter
true, wenn der Request ein REST-Request ist (REST_REQUEST ist definiert und true) und die Methode nicht GET ist, oder wenn er unter WP-CLI läuft. Sonst false, auch bei Cron, admin-ajax.php, admin-post.php und normalen Seitenaufrufen.
Rückgabewert
true, damit vor dem ersten Lesen eines Sets in diesem Request die Sperre genommen wird. Der Wert wird in einen Boolean umgewandelt.
Standardwert
true bei REST-Requests, die kein GET sind, und bei WP-CLI, sonst false.
Beispiele
Ein Cron-Job, der Sets ändert
/**
* Der nächtliche Icon-Abgleich schreibt Sets und braucht deshalb die Sperre.
*/
function acme_lock_sets_in_cron( $writes ) {
return $writes || wp_doing_cron();
}
add_filter( 'easy_svg_pro_set_write_context', 'acme_lock_sets_in_cron' );
Nur für deinen eigenen admin-post-Handler
Beschränk es auf die eine Action, die schreibt, damit andere Admin-Requests nicht langsamer werden.
/**
* Unser Button "Marken-Icons abgleichen" schickt an admin-post.php?action=acme_sync_icons.
*/
function acme_lock_sets_for_sync( $writes ) {
if ( $writes ) {
return true;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nur fürs Routing, der Handler prüft die Nonce.
$action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( $_REQUEST['action'] ) ) : '';
return is_admin() && 'acme_sync_icons' === $action;
}
add_filter( 'easy_svg_pro_set_write_context', 'acme_lock_sets_for_sync' );
Die Abilities aus einem Queue-Worker ausführen
/**
* Unser Worker läuft als einfacher PHP-Request und ruft die Set-Abilities direkt auf.
*/
function acme_lock_sets_in_worker( $writes ) {
return $writes || ( defined( 'ACME_ICON_WORKER' ) && ACME_ICON_WORKER );
}
add_filter( 'easy_svg_pro_set_write_context', 'acme_lock_sets_in_worker' );
function acme_worker_add_icons( $set_id, array $icons ) {
if ( ! function_exists( 'wp_get_ability' ) ) {
return new WP_Error( 'acme_no_abilities', 'Die Abilities API ist nicht verfügbar.' );
}
$ability = wp_get_ability( 'easy-svg-pro/add-icons-to-set' );
if ( null === $ability ) {
return new WP_Error( 'acme_no_ability', 'Schalte Abilities für KI-Agenten und den Icon-Set-Editor ein.' );
}
return $ability->execute(
array(
'set_id' => (int) $set_id,
'icons' => $icons,
)
);
}
Die Ability prüft Berechtigungen. Der Worker muss also als Benutzer mit manage_options laufen (wp_set_current_user()).
Defensiv: die Sperre nie versehentlich abschalten
/**
* Unseren Kontext ergänzen, nie den wegnehmen, den Easy SVG Pro entschieden hat.
*/
function acme_safe_write_context( $writes ) {
return (bool) $writes || apply_filters( 'acme_is_icon_job', false );
}
add_filter( 'easy_svg_pro_set_write_context', 'acme_safe_write_context', 20 );
Gibst du false zurück, während $writes true ist, nimmst du den eigenen REST-Routen des Plugins und WP-CLI den Schutz. Verknüpf immer mit ||.
So funktioniert es
- Jedes Lesen und Schreiben eines Sets fragt den Filter (über
set_write_context()). - Ist die Antwort in einem Request zum ersten Mal
true, führt Easy SVG ProSELECT GET_LOCK('easy_svg_pro_sets', 10)aus. Es wartet bis zu zehn Sekunden, bis ein anderer Request fertig ist. - Es registriert
RELEASE_LOCKaufshutdown. MySQL gibt die Sperre außerdem frei, wenn die Verbindung endet. - Für jedes Set löscht es danach einmal das Meta dieses Posts aus dem Objekt-Cache, damit es liest, was wirklich gespeichert ist, und nicht, was ein anderer Request gerade gecacht hat.
Es gibt eine Sperre für alle Sets, nicht eine pro Set: Ein Verschieben schreibt zwei Sets, und zwei Sperren pro Set könnten ewig aufeinander warten. Die Sperre gilt bis zum Ende des Requests, nicht nur während des Schreibens.
Stolperfallen
- Früh entscheiden. Wurde das erste Set ohne Sperre gelesen, ist dieses Lesen schon passiert. Häng den Filter ein, bevor irgendetwas ein Set liest, am besten beim Laden deines Plugins.
- Zehn Sekunden, dann geht es trotzdem weiter. Das Ergebnis von
GET_LOCKwird nicht geprüft. Hält ein anderer Request die Sperre länger als zehn Sekunden, läuft dein Request ohne weiter. Halte Schreibvorgänge an Sets kurz. - Nur MySQL und MariaDB. Auf einer Datenbank ohne
GET_LOCK(etwa mit der SQLite-Integration) wirkt die Sperre nicht, übrig bleibt nur das Leeren des Objekt-Caches. - Sie bremst jeden Schreiber. Solange dein Request die Sperre hält, wartet jeder andere Schreibvorgang auf irgendein Set. Gib für Seitenaufrufe oder lange Berichte nicht
truezurück. - Direkte Meta-Schreibzugriffe sind nie gesperrt. Der Filter wirkt nur auf Lese- und Schreibvorgänge über Easy SVG Pro.
update_post_meta()auf_easy_svg_set_iconsumgeht die Sperre, den Sanitizer und die Actioneasy_svg_pro_set_icons_written. - Cron und AJAX sind standardmäßig nicht abgedeckt. Schreibst du dort Sets ohne diesen Filter, können zwei gleichzeitige Läufe still Icons verlieren.