Adventskalender Tag 23 – Wie man eigene Felder in einer Multi-Site aktualisiert

Zu den angenehmen Möglichkeiten einer Multi-Site gehört das Erzeugen von Beziehungen zwischen einzelnen Beiträgen über das ganze Netzwerk hinweg. Zum Beispiel kann man eine private Site benutzen, um Redaktionelles zu besprechen und diese Diskussionen mit den öffentlichen Beiträgen verknüpfen.

Oder man baut ein Sprachnetzwerk auf und kennzeichnet einen Beitrag auf de.example.com als Übersetzung von Beiträgen in ru.example.com und en.example.com. Dann möchte man auch einen Editor für die verknüpften Beiträge anbieten, damit alles auf nur einer Seite bearbeitet werden kann.

Dazu braucht man nur eine einfache Tabelle für die Beitragsbeziehungen und eine Routine, um die verknüpften Beiträge zu aktualisieren, wenn sie geändert wurden, also switch_to_blog() und wp_update_post().

Das könnte so ausehen:

add_action( 'save_post', 'update_linked_posts', 10, 2 );

function update_linked_posts( $post_ID, $post ) {

    // avoid recursion
    remove_filter( current_filter(), __FUNCTION__ );

    // get an array of post IDs from the other blogs, this is a custom function
    $linked_posts    = get_linked_post_ids( $post_ID );
    $current_blog_id = get_current_blog_id();

    foreach ( $linked_posts as $blog_id => $linked_post_id ) {

        switch_to_blog( $blog_id );

        $linked_post = get_post( $linked_post_id );

        // post doesn't exist anymore
        if ( ! $linked_post ) {
            // remove it from our table, this is a custom function
            delete_linked_post_relation( $linked_post_id );
        }
        else {
            // assuming you did proper security checks earlier!
            $linked_post->post_content = $_POST[ $blog_id ][ 'post_content' ];

            // YOUR METABOX BREAKS HERE
            wp_update_post( $linked_post );
        }

        restore_current_blog();
    }

    // restore the action callback
    add_action( 'save_post', 'update_linked_posts', 10, 2 );
}

Und dann wird man merken, wie viele Plugins nur für Single-Site-Installationen gemacht wurden und die Beiträge verunstalten, wenn sie im Netzwerk aktiviert werden. Warum?
Weil sie die eigenen Felder für alle Beiträge aktualisieren, ohne zu testen, ob sie noch auf der selben Site sind wie die ursprüngliche Metabox. switch_to_blog() ist ein unbekannter Faktor für die meisten Plugins.

Mit den Resultaten haben die Nutzer schwer zu kämpfen: Russische SEO-Keywords tauchen plötzlich auf der englischen Site auf, und es gibt keinen einfachen Weg, dies zu beheben. Seltsame Untertitel erscheinen auf der falschen Site, oder private Notizen finden ungewollt ihren Weg an die Öffentlichkeit.

Es gibt eine simple Lösung dafür: Man schicke die ID der Ausgangsseite mit den Metaboxdaten mit und kontrolliere vor dem Speichern, ob sie mit der ID der aktuellen Site übereinstimmt. Also ein verstecktes Input-Feld …

<input type="hidden" name="blog_id" value="">

… und in der Validierung, ehe Daten gespeichert werden eine Kontrolle:

        // Network compatibility. Our plugin should not be synchronized.
        if ( empty ( $_POST[ 'blog_id' ] ) )
            return FALSE;

        if ( (int) $_POST[ 'blog_id' ] !== get_current_blog_id() )
            return FALSE;

Das ist alles. Die Nutzer freuen sich, weil sie keine Daten mehr verlieren. Das funktioniert selbst dann, wenn zwei Plugins den selben Namen für das Feld verwenden.

Newsletter abonnieren

Schaue unsere Datenschutzverordnung an

Das könnte dich auch interessieren

Neues Plugin: B2B Market für WooCommerce

B2B Market ist die erste deutschsprachige Lösung für B2B-Shops mit WooCommerce und WordPress. Verkaufe an B2B und an B2C, erfülle die gesetzlichen Anfor ...

Mehr erfahren

WooCommerce Projekte vorgestellt: Die Beer Ambassadors - Bierspezialitäten im Abo

Die Beer Ambassadors haben einen ganz besonderen Onlineshop auf die Beine gestellt - mit WooCommerce und German Market. Wir haben die beiden Gründer Thoma ...

Mehr erfahren

Die Übersicht: 5 DSGVO Plugins für WordPress und WooCommerce

Auch nach dem Inkrafttreten der EU-Datenschutzverordnung suchen viele Portal- und Shopbetreiber nach einer Lösung, um die gesetzlichen Anforderungen zu er ...

Mehr erfahren

Kommentare

4 Kommentare

  1. danke für die sensibilisierung betreffend multisites und speicherung.

    toscho, es wäre für weniger versierte besucher wahrscheinlich hilfreich, wenn du anmerken würdest, dass die funktion

    get_linked_post_ids()

    keine wordpress eigene funktion ist.
    die funktion dient dazu, mit der übergebenen id in der eigens erstellten tabelle nach der post id der anderen multisite zu suchen.

    mfg
    souri

    1. Stimmt, ich habe es nachgetragen.

  2. Thomas, ich danke dir sehr, für diesen Artikel. Ich habe mich bei meinem ersten kleinen Projekt, das mehrere Sprachen beherrschen sollte, für die Umsetzung mithilfe der Multisite Installation entschieden. Von der technischen Sauberkeit dieses Ansatzes hat mich dieser Artikel von Frank überzeugt: http://bueltge.de/wordpress-mehrsprachig-nutzen-ein-loesungsvorschlag/1339/ . Also habe ich das MultilingualPress Pro bei euch geholt. Diese Wahl ist aber bisher eher eine Qual gewesen. Der Grund? Ja eben der den du auch nennst, dass viele Plugins richtig Probleme haben mit einer Multisite Variante von WordPress.

    Deswegen freut es mich sehr, diesen Artikel hier gefunden zu haben. Ein kleiner Funken Hoffnung ist wieder aufgetaucht. Jedoch kann ich momentan nicht viel mit dieser Anleitung anfangen. Könntest du das vielleicht an einem aktuellen Beispiel von mir verdeutlichen?

    Beispiel
    Ich verwende in einer WordPress Multisite Installation den Layer Slider WP (kreaturamedia.com). Wenn ich auf der englischen Seite den Slider aktiviere, dann wird er auf der deutschen Seite nicht mehr gefunden.
    So sieht die Dateienstruktur von dem Layer Slider WP: http://goo.gl/cd4KwE

    Frage:
    Wohin in diese Dateien füge ich den von dir vorgeschlagenen Code?

    1. Wenn du kein PHP kannst, dann fasse das Sliderplugin lieber nicht selbst an, sondern melde den Fehler den Entwicklern, damit die ein Update herausbringen.

      In der Zwischenzeit kannst du ein separates Plugin anlegen mit diesem Inhalt:

      /* Plugin Name: Fix broken Metaboxes */
      add_filter( 'salt', function( $salt, $scheme )
      {
      	return 'nonce' === $scheme ? $salt . get_current_blog_id() : $salt;
      }, 10, 2 );

      Das verhindert das Speichern falscher Werte in anderen Plugins, wenn diese die grundlegenden Sicherheitsprüfungen eingebaut haben. Haben sie das nicht, solltest du ohnehin ein anderes Plugin suchen, denn dann hast du eine Sicherheitslücke.

Schreibe eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Du kannst folgende HTML Tags verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>