 Hallo, mein Name ist Christoph Daum. Ich arbeite bei der Ruhr 24 GmbH als Web-Entwickler und in den letzten Monaten habe ich ein Pluckin für uns geschrieben, was uns erlauben soll, mit einer einzigen WordPress-Instanz in mehrere andere WordPress-Instanzen den Inhalt zu replizieren. Hintergrund war an der Stelle, dass wir, also wir betreiben mehrere lokale News Portale und die Anforderung, die mir gestellt war, war, dass wir ein Launch von mehreren neuen Städten planen und die Redaktion nur ein einziges Backend haben sollten, ohne dass das jetzt zwingende Multi-Site oder ähnliches gewesen ist. Die Anforderung hat sich ein kleines bisschen geändert. Die Schnittstelle werden wir trotzdem in den Einsatz bringen, denn den einen Vorteil, den die immer noch für uns bringt, ist, wir haben eine komplette Abkoppelung von dem Redaktionsbackend, von dem Frontend, wo die Benutzer drauf kommen. Was im Zweifel soll heißt, wenn aus irgendwelchen Gründen das Frontend super viel Traffic bekommt und die Seite sperrt, kann die Redaktion trotzdem weiterarbeiten, da wir eine mehrere Vollzeit-Redakteure haben, ist das im Zweifel soll tatsächlich auch für uns ein wirtschaftlicher Faktor, wenn die Redakteure nicht arbeiten können. Ich habe, stelle gerade fest, dass ich noch nicht im Präsentationsmodus bin, weiß einer die fantastischen Kombinationen aus dem Kopf, sonst muss ich nachgucken. Also ich habe keine Folien vorbereitet, wir machen das hier tatsächlich so Merlevinian Karaoke-mäßig und ich werde euch zeigen, ich werde euch die Probleme zeigen, auf die ich gestoßen bin, ich werde ein paar Bucks aufzeigen, die ich auf dem Weg gefunden habe. Vorab eine Frage, die sich mit Sicherheit früher oder später stellen würde, das Plug-in ist stand jetzt nicht veröffentlicht, es kann sein, dass ich es irgendwann veröffentlichen werde, aber stand jetzt ist das Plug-in, was nicht veröffentlicht ist und wann und ob ich es veröffentlichen kann und darf, kann ich leider noch nicht sagen. So, fangen wir an, ich habe hier, ich habe hier ein schwarzes WordPress, weiß nicht ob man es oben sehen kann, das heißt Central, das ist meine Hauptinstanz. Und ich habe hier, das brauche ich glaube ich nicht, ich habe hier ein zweites und ein drittes WordPress, die heißen Sat1 und Sat2. Sat1 ist rot und Sat2 ist wenn ich im Backend bin, dieses blau-grün. So, ich schreibe jetzt einen Beitrag, ich habe Gutenberg aktiviert, das Plug-in funktioniert mit beiden und ich schreibe jetzt hier mal Hallo, Liebes, WordCamp, Köln. Ich schreibe einen Xbeliebigen Blindtext und sage jetzt, dass ich diesen Beitrag auf Satellite 1 veröffentlichen möchte. Ich drücke jetzt hier auf Veröffentlichen. Jetzt passiert im Hintergrund ein kleines bisschen Magie, ich warte jetzt einen Moment, lasse Sicherheitshalbe einmal neu, damit meine Magie passiert. Und jetzt springen wir mal hier rüber in Satellite 1, gucken auf Beiträge und oh Wunder, hier ist ein Beitrag Hallo, Liebes, WordCamp, Köln. Gewählt mir jetzt glauben, dass es tatsächlich zwei getrennte Datenbanken sind, das ist zwar alles lokal bei mir auf der Maschine, aber es sind komplett voneinander getrennte Systeme, die könnten auch auf komplett physikal getrennten Maschinen liegen. Hier im Übrigen ist kein Beitrag, gar mehr Noten im einen veröffentlicht. Jetzt sage ich, ich möchte das Teil jetzt vielleicht nicht auf Satellite 1, sondern auf Satellite 2 haben, drücke auf Aktualisieren und warte bis er gespeichert hat und laden wir mal Sicherheitshalbe neu. Jetzt aktualisiere ich die beiden mal und oh Wunder, hier ist er verschwunden, da ist er. Was passiert jetzt da im Hintergrund? Beim Abspeichern des Beitrages schreibe ich mir in eine Warteschleife rein, dass ich den ganzen aktualisieren möchte. Sobald der WP Cron im Hintergrund läuft, läuft die Aktualisierung im Hintergrund. Was man jetzt auch noch mal sich angucken kann, ich öffne den hier mal im Frontend. Ich habe jetzt hier meinen tollen Text und ich stelle jetzt fest, der Text ist noch ein bisschen sehr lang. Ich möchte da dann doch nur den kurzen Blindtext drin haben und möchte noch irgendwie ein bisschen. Es ist scheiß egal, wir veröffentlicht auch nochmal ein Bild, hängen wir nochmal mit dran. Ach komm, ich arbeite nicht viel im Redaktionsbereich. Ja, ich habe gerade Enter gedrückt. So, Bild, Bild, Bild. Wir laden mal sinnvollerweise ein neues Bild hoch und aus meinem tollen, wo habe ich meinen Bildordner? Downloads, nee Scheiße, ich habe einen Desktop. Bilder. So, ein x-beliebiges Bild, aktualisieren und jetzt warte mal wieder ein Moment. Das wäre jetzt ein Dorfes Bild, das habe ich nämlich, das ist immer das, was ich zuerst benutze. Ich lad noch ein zweites hoch. Wir nehmen mal hier Piano, das habe ich lange nicht mehr hochgeladen. So, das laden wir jetzt hoch und jetzt gucken wir hier schon mal hier drüben. Hier sollte tatsächlich nämlich schon das komplett angekommen sein mit beiden Bildern. Und, damit ihr mir auch gleich glaubt, Bild in neuem Tab öffnen. Das Bild liegt tatsächlich auf Satellite 2. Das liegt nicht auf der Central, sondern das ist tatsächlich auf Satellite 2. Das ist jetzt nicht irgendwie die, die gelingt oder sowas, es liegt tatsächlich auch logisch und physikalisch. Wie viel man bei Nordatai physikalisch sagen kann, auf Satellite 2. Es kostet einen Kölsch heute Abend, genau. So, ich will jetzt auch nicht zu langweilig werden und sagen, das funktioniert für Kategorien, das funktioniert für Schlagwörter, das funktioniert für alles. Das, was jetzt aber tatsächlich ein bisschen spannend ist, dieser Beitrag hat die Post ID 464. Wenn wir jetzt nochmal hierhin zurückgehen, dieser Beitrag hat die Post ID 238 und der hier hatte noch eine ganz andere. Das heißt, da passiert tatsächlich, warum lädst du so lange, die haben tatsächlich alle eigene IDs. Da ist irgendwas kaputt, das gucken wir uns nicht weiter an. Was passiert jetzt im Hintergrund? Dann springen wir jetzt in den Quelltext drüber, da wird es nämlich etwas spannend. Oder wir machen noch einen Zwischenschritt, das sieht nämlich tatsächlich relativ spannend aus. Ich gehe jetzt hier mal und veröffentliche in den beiden Satelliten, drücke auf Aktualisieren, gehe schnell in meine Datenbank und bin zu langsam. Und habe hier unten, doch, ich war schnell genug, habe hier unten, kann ich hier zoomen? Nein, kann ich leider nicht zoomen, muss ich so zoomen. Ich habe hier unten in den letzten zwei Zeilen, ich weiß nicht, ob man es, man kann es nicht sehen. Hier in der Spalte könnt ihr sehen, dass hier ein etwas breiterer Text steht, da steht Success. Hier steht Open. Das heißt, hier in dieser Datenbank steht alles drin, was ich in der Zwischenzeit gespeichert habe, was übermittelt wird. Wenn ihr jetzt hier guckt, hier sehen wir tatsächlich, was ich heute gemacht habe. Das, was wir heute gemacht haben, fängt hier an. Hier haben wir ein paar Posts hin und her geschoben. Hier steht nämlich auch einmal Delete mit einer Post ID. Und hier sind die beiden Bilder, die ich neu hochgeladen habe. Das heißt hier in dieser Tabelle, das ist meine Warteschleife. Da speichere ich mir ab, was im Hintergrund passiert. Und wenn ich das jetzt neu lade, ist noch nichts passiert, weil ich das Backend nicht neu geladen habe hier. Wenn ich das jetzt neu lade, steht jetzt hier kurz Processing. Dahinten steht, steht Informationen, dass das Teil nicht doppelt verarbeitet wird. Und wenn es jetzt wieder neu lade, steht dort Success. Und wir könnten im Frontend sehen, was dort tatsächlich angekommen ist. So, ich fange jetzt erstmal an mit den Problemen, in die ich reingelaufen bin. Oh ja, das ist eine gute Idee. Bisschen größer und nicht schwarz. Aber wie kann ich... Wieso zoomt er denn hier mit Pinch nicht? Da gab es da irgendwie ein Präsentationsmodus, oder wäre ich mich da jetzt... View, Switch Colors geben. Colors geben. Defaults. Ja. Aus irgendwelchen Gründen ist nur diese eine Zeile dann dunkel. Aber das ist nichts, was wir zwingend brauchen. So. Was mache ich an der Stelle? Ich fange erstmal mit dem Problem an. Welche Probleme bin ich reingesteuert? Damit ich die Information habe, welcher Beitrag auf den Remote System zu dem Beitrag auf dem Master System dazugehört, gibt es hier ein Postmeter, den ich Remote Items genannt habe. Da speichere ich mir tatsächlich die ID auf dem Remote System ab. Darüber kann ich updaten. Funktioniert, alles schön. Ich habe dann aber auch noch den Remote System nochmal die ID auf dem Parent System mit übergeben. Da habt Sören mich dann zwischendurch mal ertragen müssen und mir so ein paar Stubser gegeben mit der Validierung vom Übertragen bei Postmeter. Ich weiß auch, was das gewesen ist. Und da bin ich in drei Probleme reingetappt. Und zwar, wenn man versucht, eine neue Kategorie, eine neue User, generell eine Taxonomie, User oder ein Bild anzulegen und dabei gleichzeitig ein Postmeter übertragen will. Bekommt man eine Fehlermeldung? Weil dort ein Back ist. Und das gleichzeitige Anliegen von Bildern, beim Übertragen von Daten war eh sehr, sehr anstrengend. Zeige ich euch gleich mal so ein bisschen den Unterschied, was da im Endeffekt passiert. An paar Stellen bin ich wirklich in Sackkassen reingelaufen, wo ich Bugs gemeldet habe, wo ich dann auch ein bisschen um die Ecke fahren musste. Und eine Sache, die tatsächlich nicht funktioniert, ist das Zuschneiden von Bildern. Da habe ich auch noch keine Lösung. Beim WordPress hinterlegt beim Zuschneiden von Bildern. In den Postmeter die Information, dass das Bild zugeschnitten ist, speichert ein neues Bild ab. Das ist aber weiterhin der Original Post. Die REST API kann das nicht. Gar nicht. Das heißt, wenn man sowas mit zuschneiden von Bildern machen wollte, müsste man irgendwie tricksen. Und ich habe zwischendurch überlegt, die Bilder gar nicht erst zu übertragen, sondern nur quasi über die ganzen Filter reinzuhängen und nur die ID zu übertragen und die IDs auf einen CDN rüberzuschieben. Ich habe dann nur festgestellt, wie viele Filter ich da durchgehen müsste und habe dann gesagt, nee, das möchte ich zu diesem aktuellen Zeitpunkt nicht machen. Ich habe mich dann dafür entschieden, ich übertrag die Bilder erstmal und bin dann halt auf das Problem gestoßen, dass zuschneiden von Bildern nicht funktioniert. Ich habe dann mit auf dem Worldcamp Europe auch ein paar Gespräche geführt. Daraufhin ein Ticket eröffnet. Ich hoffe, dass das irgendwann gelöst wird. Also das Mediatheam sagt, ja, das brauchen wir unbedingt, sagt dem API-Team Bescheid. Ticket eingestellt. Auf meine letzte Rückfrage, was in der Stand zu dem Ticket ist, kam die Aussage nicht vor 5.1. Ja, gut, es ist immer eine Aussage, ich muss mindestens ein halbes Jahr auf meine Lösung warten. So, das waren so die größten Probleme. Ach so, das allergrößte Problem, weswegen überhaupt diese Warteschleife existiert, ist, ich habe das Teil, also erstmal seht ihr, wenn ihr seht, das Teil heißt Bifrost V2. V2 impliziert, es gab eine V1. Die V1 hatte ich geschrieben und habe festgestellt, dass ich mit meinem Code zwar viele funktionierende Sachen geschrieben habe, aber auch viele Sackkassen erwischt habe. Das heißt, ich habe gesagt, bevor ich jetzt anfange, das aufzuräumen, archiviere ich das, fange von vorne an und kopiere nur das, was ich wieder verwenden will und den Rest schreibe ich neu. Und strukturier es sauber. Eines der Probleme, in das ich nämlich reingelaufen bin, ursprünglich sollten es mal, was sieht man hier aus, es sollten mal 19 Satelliten sein, es sind nur noch 2. Und ursprünglich habe ich die Dinger symmetrisch und prozedual übertragen. Das funktioniert bei 2 Satelliten und einem Beitrag, der in Millisekunden übertragen wird, gut. Bei einem Bild, was 3 Sekunden braucht, nicht. In meinem Test hat dann das Hochladen eines einzelnen Bildes 90 Sekunden gedauert, weil er halt erstmal das Bild auf das Master System hochgeladen hat, 3 Sekunden. Auf System 1, 2, 3, 19 macht er dann am Ende knapp 90 Sekunden und dann habe ich festgestellt, ne, da springt mir jeder meiner Redakteure mit dem Arsch ins Gesicht, das machen die nicht mit. Und das nächste Problem, was ich je schon auf dem Schirm hatte, was passiert denn, wenn gerade das Remote-System einen Schluck aufhat, ich muss das Teil ja noch ein zweites Mal raus schicken, falls das System nicht antwortet. Also habe ich dann den direkten Übertrag beim Abspeichern, verworfen, das Ganze in diese Warteschleife geschrieben und angefangen, die Informationen danach über den WP Cron zu übertragen. Da habe ich auch mal experimentiert. Es gibt auch in WordPress integriert eine Funktion, ich glaube, irgendwie Request-Size, womit man tatsächlich auch parallel die Sachen abfrühstücken kann. Habe ich ausprobiert, hat funktioniert, hatte aber Probleme, weil er teilweise die Ausführung beendet hat, bevor die Antwort gekommen ist. Das heißt, ich habe den Beitrag übertragen, hatte aber noch nicht die Antwort mit der ID und konnte dementsprechend nicht zurückschreiben, dass das Übertragen funktioniert hat. Das heißt, das habe ich am Ende wieder zurückgeschrieben und habe tatsächlich, im Hintergrund läuft es prozedural ab, aber es läuft halt im Hintergrund ab, so dass der Redakteur im Idealfall nicht beeinträchtigt wird. Dann zeige ich euch mal so ein kleines bisschen an einem einfacheren Beispiel, was da denn tatsächlich passiert. Und zwar habe ich hier in meinem Code mehrere Module und wenn er neben uns mal das einfache, was schön einfach zu erklären ist, das hier ein Post-Tag. Und zwar brauche ich jetzt die Klass-Post-Tag. Wo ist denn meine Klass-Post-Tag? Bin ich blind? Ne, in der Request gehen wir gleich zum Ende rein. Ah, das heißt Klass-Term. So, die Datei ist tatsächlich wunderschön einfach und das wirklich Tolle war dann tatsächlich, als ich das so fertig hatte, das Einfügen, sobald ein Eins funktioniert hat, das Einfügen von weiteren Analog dazu, war tatsächlich größtenteils Copy and Paste anfassen und wirklich eine neue Übertragungsweg ist teilweise in eine halben Stunde fertig. Bei V1 war das nicht so. So, was mache ich? Ich hänge mich in die beiden Hooks created, edited rein zum erstellen und in pre-delete-Term zum löschen. Pre-delete-Term brauche ich aus einem Grund. Ich habe es im ersten Versuch mit delete-Term gemacht, aber bei delete-Term existiert die Postmeter schon nicht mehr. Das heißt, ich weiß nicht mehr, was ich dem Remote-System sagen muss, was er löschen muss. So, in die beiden ersten Hooks hänge ich mich rein und das kann man jetzt, ich hoffe, man kann es halbwegs lesen, das Orange ist wahrscheinlich ein bisschen weg. Die eine Funktion ist eigentlich nur Rapper, weil die übergebende Parameter ein bisschen anders sind. Am Ende rufe ich eigentlich nur dieses hier unten auf und überprüfe hier oben, ob ich das dann auch wirklich synchronisieren möchte und das, was nachher eigentlich tatsächlich wichtig ist, ist das. Das steht am Ende, das, was wichtig ist, Q at taxonomy term ID. Das wird ausgeführt und damit schmeiße ich dann meine Informationen hier in die Datenbank rein, dass ich zu den entsprechenden Knoten die Taxonomie hinzufügen will. Wir machen das mal eben schnell, damit wir was da drinstehen haben. Neue Kategorie erstellen, Word Camp, Camp. Neue Kategorie hinzufügen. So, einmal neu laden, ja, ja, das interessiert mich. Die Vertragung passiert jetzt. So, die ist nämlich auch schon durch. Hier habe ich jetzt drin stehen. Kategorie, schon mit Success und die ID der Kategorie auf meinem lokalen System, oder auf dem Master System. Das passiert an dieser Stelle. Damit schreibe ich es in die Q rein. Löschen passiert sehr analog. Das heißt dann nicht add, sondern delete ist ansonsten vollkommen analog. Und über den, über den WP Cron, oder in dem Fall auf dem Entwicklungssystem durch neu laden, wird die Q Verarbeitung aufgerufen. Oh, schön. Die Zahlen, die ihr nicht lesen soll, sie sind unlesbar. Ich greife mich hier direkt auf die Datenbank zu. Deswegen sagt mir mein Code Sniffer auch, du, du, du. So, hier ist die add Funktionen und so weiter. Das sind unheimlich viele technische Details. Wer sich dafür interessiert, kommt gerne im Laufe des Camps oder morgen auf mich zu. Ich rede gerne darüber und ich zeige euch gerne, was da für Ideen drinstehen. Aber ich glaube, das sind für so einen kurzen Talk jetzt dann doch zu viele technische Details. Deswegen springen wir in den interessanten Teil und zwar Handle Q. In Handle Q bin ich nämlich in noch ein Problem oder ich dachte zumindest in einem Problem reingelaufen und zwar in das Problem von Race Conditions. Wer weiß nicht, was Race Conditions sind. Okay. Race Conditions ist, wenn zwei Prozesse parallel laufen und quasi das Gleiche machen würden. Das heißt, deswegen habt ihr in der Datenbank, habe ich euch vorhin ganz kurz gezeigt, hier in dieser Spalte, in der eine Spalte stand irgendein Wert drin, ein kryptischer Wert. Das ist für mich eine Semmerfore. Damit beim Laden der Einträge schreibe ich dort rein, dass diese Einträge gerade verarbeitet werden. Denn das dauert tatsächlich einige Sekunden vom Anfang bis zum Ende bis die verarbeitet werden. Das heißt, wenn zwei Prozesse innerhalb von einer Sekunde anfangen und beide sehen, guck mal, der ist noch nicht verarbeitet, den nehme ich mir mal jetzt. Dann kann es passieren, dass zweimal das Gleiche gemacht wird. Und das möchte ich ja nicht. Ich möchte ja keine Duplikate auf den anderen Systemen erstellen. Beim Update wäre es noch egal, dann mache ich zweimal das Update. Aber beim Erstellen produziere ich mir bei Posts Duplikaten und bei Kategorien bekomme ich Fehlermeldung. Denn Kategorien sagen praktischerweise, wenn ich einen Beitrag zweimal über die REST API erstelle, habe ich zwei Duplikate. Das Gleiche müsste für Bilder funktionieren. Bei Kategorien, Usern etc. bekomme ich eine Fehlermeldung zurück. Existiert bereits. Was mit dem einen Bug, den ich gemeldet habe, sehr spaßig war, weil ich dann eine Fehlermeldung bekommen habe, aber die Erstellung funktioniert hat. Und wenn ich es nochmal übertragen habe, habe ich die Fehlermeldung bekommen, existiert schon. Also gehen wir hier rein. Hier an dieser Stelle lade ich mir meine Informationen rein. Was an der Stelle übrigens sehr wichtig war, was ihr hier seht, hier ist eine Lock Funktion. Die Lock Funktion, ich habe den Lock zu, aber ich hoffe, ich habe ihn gestern leer gemacht. Den Lock, der sieht so aus. Das sieht erstmal total unspannend aus. Der interessante Teil kommt tatsächlich hier unten. Wenn wir jetzt mal ganz da unten gehen, sehe ich hier Markt Entries for Handling, Rose Effecteds 2, Fetched Results, Edit Request und hier steht dann, dass ich an Satz 1 Kategories, irgendwas übermittelt habe, heransatz 2 Kategories, denn an der Stelle, ich bin sonst jemand, der viel zu viel mit Badam debackt, aber an der Stelle wäre es einfach nicht möglich gewesen, alles mit Badam zu debacken. Hier habe ich mir einen eigenen Rapper für die Composer Bibliothek Monologue geschrieben und schreibe mir da tatsächlich meinen Lock, worüber ich dann wieder sehen kann, was passiert und insbesondere halt auch die ganzen Fehlermeldung, die von der anderen Seite bekommen, sehen kann. Jetzt springen wir nochmal wieder in Code zurück, das machen wir zu. Also hier ziehe ich mir, wo bin ich denn jetzt? Ich bin in der falschen Datei. Also ich ziehe mir meine ganzen Dateien, hier stand das mit Fetched Results, hier gab es irgendwelche Fehlermeldung und hier habe ich eine große Schleife. Mit der Schleife gehe ich jetzt durch die einzelnen Elemente, die ich mir aus der Datenbank gezogen habe, durch und verarbeite sie. Dabei gibt es noch die möglichen Elemente, die ich mir aus der Datenbank gezogen habe und verarbeite sie. Dabei gibt es noch die Möglichkeit, ich habe Abhängigkeiten im System. Ich kann zum Beispiel eine Kategorie, kann eine Parent-Kategorie haben, ein Beitrag kann eine Kategorie haben und alle IDs, die ich übertrage, muss ich auf das entsprechende System matchen. Gerade kam schon die Frage wegen Request. Hier unten steht mir jetzt hier gleich irgendwo, wenn ich nicht schon daran vorbeigescrollt habe. Wenn ich jetzt eine Request suche, finden wir alles nur nicht das, was ich eigentlich haben möchte. Moment, da, da, da, da, da. Hier oben müsste ich es irgendwo haben. Edit Request. Ich finde es jetzt gerade nicht, wo es im Code drin steht, ich lade für jeden einzelnen Eintrag, den ich in der, in der Queue habe, lade ich mir in Request. Und das sind dann hier diese Request, die ihr gerade gesehen habt. Und jetzt springen wir nämlich in den Request-Post-Tag rein. Und dann kommen wir jetzt in den tatsächlich ein bisschen interessanteren Teil, aber da ist auch noch viel Magie ein bisschen versteckt. Und zwar schreibe ich mir jetzt den Request raus. Da ziehe ich mir jetzt erstmal alle Informationen hier oben raus, die ich übertragen möchte. Name Slug Description. Dann füge ich in der eigenen Funktion nochmal die Meta-Information hinzu. Das ist nicht der letzte Stand, wie ich es eigentlich haben möchte. Eigentlich ziehe ich mir die Meta-Information noch aus einer anderen Stelle. Und dann gibt es hier meine ganzen Filter. Und die Filter sind natürlich bei Post-Tag sehr langweilig, weil die Post-Tags eigentlich keine Abhängigkeiten haben. Deswegen gucken wir uns jetzt mal die Kategorie an. Bei Kategorie haben wir nämlich eine Abhängigkeit, eine Kategorie keine Parent haben. Es gibt also hier die Kategorie den Filter-Parent. Die Funktion für Filter-Parent, die in Filter-Parent drin ist, die sieht erstmal sehr unspektakulär aus. Das ist die Kategorie der Post-Parent-Kategorie. Will ich euch zeigen, was da drin passiert? Kann eh keiner verstehen. Also das, was diese Funktion prinzipiell macht, ist, sie guckt in den eigenen, in den eigenen, in den lokal gespeicherten Meta-Informationen ab, existiert für diese Kategorie, existiert der Post-Parent auf dem Remote-System, gibt mir die ID zurück. Wenn nicht, wirft es eine Exception und dann kann ich das Teil entweder zum späteren Zeitpunkt während dieser Schleife nochmal neu ausversuchen oder das sieht man jetzt hier in der Datenbank. Es gibt eine Spalte, die heißt Attempts und hier sieht man auch bei manchen dann eine Zahl. Wenn es nicht funktioniert, dann gibt es auch Fehler und dann wird das Teil in fünf Minuten, zehn Minuten etc. nochmal versucht. Darüber iteriere ich dann durch das System durch und wenn gewiss eine Anzahl von Fehlern erreicht wird, brecht das System auch ab. Und dann, wird das ganz übermittelt, darüber baue ich mir den, die Lok habe ich gerade wieder zugemacht. Darüber baue ich mir im Endeffekt den kompletten API-Request zusammen, übermittel ihn und das landet dann wieder zurück in der großen Schleife, die ihr gerade gesehen habt und darüber wird dann alles abgefrühstückt. Das, was ich gemacht habe, ist, ich habe ein Request für die Gutenberg-Blocke. Für Kommentare, Bilder, alles. Ich habe sogar für Settings einen Endpoint geschrieben, der einzelne Einträge aus der Settings an das Remote-System übertragen kann. Aus dem Grund, Yoast speichert aktuell die Taxonomy-Meter noch in der WP-Options ab. Das heißt, das musste ich dann auch übertragen und mapen. Weil es definitiv noch nicht perfekt. Ich hoffe, dass ich es in den nächsten Wochen oder Monaten einmal produktiv bei uns testen kann und würde mit Sicherheit dann auch nochmal darüber bei uns irgendwie schreiben berichten. Mir wird hier schön gezeigt, dass ich noch fünf Minuten habe. Ich habe glaube ich erst mal genug erzählt. Ich würde jetzt erst mal fragen an der Stelle zu lassen. Fangen wir hier vorne an. Ja. Die Frage war, ich habe hier Basic Authentification, ob ich zu einem späteren Zeitpunkt andere Authentifikation benutzen möchte und wenn ja welche. Die Antwort ist an der Stelle einfach. Es ist zwar Basic Authentification, aber die komplette Übermittlung des Passwortes passiert über eine Verschlüsselung. Ich möchte mit Sicherheit irgendwann noch auf eine andere Authentifizierung gehen, aber erst mal ist es in Ordnung, weil es mit eine verschlüsselte Übermittlung des Passwortes ist. Ja, ich weiß, das ist nicht ideal und ich habe auch an einer Stelle schon das Problem gemerkt. Wenn du PRP über FPM glaube ich eingebunden hast, wird die Basic Authentification gar nicht durchgereicht. Hat mich eine Stunde gekostet, ob rauszufinden, dass das so ist. Ja. Nächste Frage. Also, die Frage war bezüglich Yoast oder allgemein bezüglich Plugins, sage ich es jetzt mal, was wird übertragen, Metadaten, ein Title etc. für Bilder. Es wird alles übertragen, was ich dem System beibringe. Ich möchte definitiv alles übertragen. Das heißt, ich habe hier, deswegen habe ich die Datei gerade aufgemacht, ich habe hier eine Datei, die meine Postmeter registriert und ich habe hier extra eine Funktion, die alle Yoast Postmeter überträgt. Alles, was WordPress Core Standard ist, wird sowieso übertragen. Das heißt, alles, was in der Posttabelle drin steht, wird übertragen. Postmeter muss sich dem System einmal beibringen. Danach wird es auch übertragen, aber die Zielsetzung ist tatsächlich, alles komplett zu übertragen und eine Anforderung ursprünglich, die werde ich jetzt erstmal nicht zwingend brauchen, war sogar, dass ich partiell Inhalte ausfilterte. Dass ich zum Beispiel sagen kann, in einem Post, Absatz 1 ist nur für Satellit 1, Absatz 2 ist nur für Satellit 2, Absatz 3, 4 und 5 sind für beide. Das war ursprünglich eine Anforderung. Das funktioniert, wenn auch ohne hübsche UI funktioniert das bereits. Zweite Frage, es ist, also die Frage war, ob das eine Duplicierung der Datenbankinhalte ist oder ob sie umgezogen werden, streng genommen weder noch. Das Central ist das für ein System und die Inhalte bleiben auch dort komplett. Es ist aber keine Replikation auf Datenbank-Ebene, sondern tatsächlich wird der Inhalt über die API auf das andere System kopiert. Deswegen sind ja auch die IDs unterschiedlich. Wenn ich mit einer Datenbank Replikation arbeiten würde, was natürlich auch mal eine Idee gewesen ist, würde ich immer die Datenbank 1 zu 1 kopieren. Das hätte auch viele Probleme wahrscheinlich sogar erstmal verworfen. Auf der anderen Seite hätte ich dann alle URLs regelmäßig umschreiben müssen. Also es ist kopieren via API. Die Frage war, was passiert mit den Beiträgen auf den Satelliten? Die Antwort ist einfach, die kann ich dir quasi durch das Öffnen der Request-User beantworten. Standardmäßig übertrage ich nämlich, dass die Rollen der User auf den Satelliten komplett negiert werden. Auf den Satelliten hat der Redakteur nichts zu suchen. Die Satelliten sollen reine Read-Only-Systeme sein. Also das, was tatsächlich relevant ist, die Satelliten sind eigentlich bis auf die Installation des Plugins, damit die Postmeter gelesen werden können über die API, komplett unbehandelte WordPress-Instanzen. Das heißt, wenn das System aus irgendwelchen Gründen nicht mehr funktioniert, schaltet man die Schnittstelle ab und arbeitet auf den Satelliten weiter. Dann hat man ein Problem, dass die Inhalte nicht mehr synchron sind. Die Idee ist tatsächlich, es wird nur auf dem Central gearbeitet und die Satelliten, wie viele es auch immer sind, sind reine Read-Only-Systeme. Die Frage war, ob ich die Back-ID habe. Ja, die Back-ID von dem Central habe ich. Die Idee davon, dass ich es übertrage, ist halt unter anderem, dass ich verhindern möchte, dass, wenn eine Anfrage kommt, dass dann falsche Synchronisation passiert. Ich habe eine Back-ID von dem Central-System auf den Satelliten. Das war eines der Probleme, weswegen ich dann bei den Usern und Kategorien in diesen Back reingelaufen bin. Der Nutzen ist aber im Moment noch nicht existent. Die Planung davon ist, dass ich verhindern will, dass ein fremder Artikel den falschen Artikel überschreibt. Die Frage war mit Double-Cade-Content-Problematik, wie das an der Stelle gelöst ist. Das Central-System ist theoretisch so abgeriegelt, dass es nur für Redakteure im Zugriff ist. Das heißt, Google soll das System gar nicht sehen und inwieweit dann Dritte das System lesen können, lässt sich darüber diskutieren, aber soll definitiv nicht in Google erscheinen. Und Double-Cade-Content ist darüber gelöst, dass ich zumindest tendenziell automatisch die Canonical URL über Yoast SEO setze. Darüber, dass es einen primären Note gibt, soll das System dann automatisch die Canonical URL übertragen. Das ist an der Stelle, wie ich verhindere, dass Double-Cade-Content ausgelesen wird. Oder du setzt die Canonical von Hand. Dahinten war zuerst. Die Frage war, ob es nur mit normalen Blogbeiträgen oder mit Custom-Post-Types funktioniert. Ich habe es schon soweit, dass es die reusable Blogs von Gutenberg überträgt, was ein Custom-Post-Type ist. Und jeden weiteren Custom-Post-Type, wenn ich jetzt hier einmal den Custom-Post-Type-Block aufmache, das ist, was ich für den Custom-Post-Type übertragen muss. Oder einfügen musste, damit er läuft. Und noch an zwei, drei anderen Stellen, d.h. ein Custom-Post-Type dem System beizubringen, ist eine Sache von einer halben Stunde bis Stunde. Letzte Frage. Komm, die beiden Fragen machen wir noch. Das ist eine Custom-Taxonomy. Ich habe eine Custom-Taxonomy gemacht, die Note heißt, wo ich meine ganzen Einstellungen drin habe. Name, URL, Username, Password, eine Default-User-ID. Und darüber, dass es eine Custom-Taxonomy ist, erscheint das automatisch in den Beiträgen hier drin. Das Einzige, was ich hier, das passiert alles automatisch. Das Einzige, was ich jetzt gemacht habe, ist, weil das eine Custom-Taxonomy ist, aber nicht so ganz, habe ich die im Backend von hier nach hier verschoben. Letzte Frage. Kannst du nochmal den Namen wiederholen? Also, das Pluckin? Also nur für die Aufnahme eben schnell. Es kam die Anmerkung aus dem Publikum. Es gibt ein Pluckin von Broadcasts, von PlaneView Pluckins, was eine ähnliche Funktionalität hat, allerdings an der Stelle nur auf Multisite-Installation. Ich habe es tatsächlich vorher nicht angeguckt, um dazu ganz kurz noch eine Sache zu sagen. Ich habe mich an dem Punkt bewusst dagegen entschieden, eine Multisite zu machen, weil Multisite halt diese eine Anforderung, Trennung von Redaktionssystemen und Produktivsystemen nicht gewährleisten würde, weil ich halt immer noch das Problem hätte, wenn ich Last auf dem System habe und die Redakteure nicht mehr arbeiten können, das habe ich bei einer Multisite immer noch. Und Multisite produziert ein bisschen mehr Last als eine normale WordPress-Instanz. So, ich stehe gerne für Fragen noch außerhalb der Session bereit. Sucht mich, ich bin nicht so unauffällig, und auch nicht so klein.