Eine simple API für WordPress, Teil 1

Ich benötig(t)e eine Methode, um von ferne (remote) meine verschiedenen WordPress-Blogs betreiben zu können. Artikel, Posts etc. sollen von einer Datenbank gefüttert werden.

Dazu hat es früher einmal im Kern von WordPress eine REST-API gegeben, die aber abgeschaltet wurde. Demnächst (ab WP 4.7) soll sie wieder implementiert werden. Ich habe mir die Dokumentation des Beta-Plugins durchgelesen und finde sie wie immer viel zu lang. Es dauert ewig, bis jemand auf den Punkt kommt. Typisch doppelter Overhead der OOP-verliebten Informatiker was Code und Dokumentation betrifft.

Auch wollte ich mich nicht auf eine Beta-API verlassen, deren Schnittstellen offen vorlegen. Da kann ich die Zeit stoppen, bis die ersten Hacker sich drauf einstellen. Dann eine Lücke und zack! ist mein Blog gekapert.

Also muss eine eigene Lösung her. WordPress liefert intern alle möglichen, bequemen Methoden, um Artikel anzulegen, zu bearbeiten oder zu löschen. Mehr brauchen wir erstmal nicht. Die Kunst besteht nur darin, diese Methoden anzusprechen.

Also bauen wir uns unsere eigene API. Wir benötigen:

  1. einen Server im WordPress-Blog, der auf Kommandos wartet, diese verarbeitet und Ergebnisse zurückmeldet.
  2. einen Client, der Befehle sendet, wartet und die Antworten des Servers auswertet.
  3. und natürlich sollte der Server geschützt sein, damit er nicht gehackt wird.

Der Server

Zunächst legen wir im Hauptverzeichnis des WordPress-Webservers einen Unterverzeichnis an. Ich nenne diese Verzeichnis „maschine“ – aber ihr könnt auch jeden anderen eindeutigen Namen nehmen.

(Natürlich kann man das Verzeichnis auch per FTP anlegen, wenn ihr keine Kommandozeile öffnen könnt.)

Nun heißt es erst einmal, das Verzeichnis gegen Unbefugte abzusichern. Das geht am einfachsten mit einer .htpasswd-Datei. Diese kann man online generieren. Dann einfach nur ins Verzeichnis „maschine“ kopieren.

Mit der User/Passwort-Kombination mueller/geheim sieht die Datei folgendermaßen aus:

Aufpassen: vor dem htpasswd steht ein Punkt, das macht die Datei normalerweise unsichtbar, daher muss man das Anzeigen von versteckten Dateien im FTP-Programm aktivieren.

Nun braucht es noch eine .htaccess-Datei mit folgenden Einträgen:

Der Eintrag in AuthUserFile kann bei euch natürlich ein anderer sein. Wichtig ist, dass er den absoluten Pfad (vom root des Servers aus) zur eben angelegten .htasswd-Datei beinhaltet. Diesen Pfad könnt ihr bei eurem Provider erfragen oder in den FAQ nachlesen. Meist liefern die Provider auch bequeme Funktionen (Stichwort: Verzeichnisschutz) gleich mit, um alles online zu generieren.

Nun ein kleiner Test. Wir rufen im Browser auf:

Ab jetzt steht „domain.tld“ natürlich für eure eigene Domain. Jetzt müsste sofort die Abfrage nach User und Passwort erfolgen. Wenn nicht, habt ihr etwas falsch gemacht. Dann nochmal von vorn, denn Sicherheit, besonders im produktiven Bereich ist wichtig.

In Zukunft erfolgt der Aufruf natürlich automatisiert, da ist eine Passwort-Eingabe nicht möglich. Zu diesem Punkt kommen wir gleich.

Jetzt programmieren wir den einfachsten Server. Dazu legen wir eine Datei „index.php“ im Verzeichnis „maschine“ an, die demnächst unsere Befehle verarbeitet.

Wir nutzen die multibyte-fähigen Funktionen, die man am Präfix „mb_“ erkennt, damit wir später keine Probleme mit Umlauten haben. Unseren kleinen Server kann man schon per Get-Parameter in der URL oder per Post (bspw. bei Formulareingaben) bedienen. Zurückgegeben wir ein einfacher utf8-kodierter Text. Das ist für unsere Belange absolut ausreichend und bietet bessere Debug-Möglichkeiten.

Was macht der Server? Er nimmt einen Parameter (Hier „befehl“) auf und wandelt den String in Großbuchstaben um. Das ist natürlich ein wenig sinnfrei, aber wir wollen ja erstmal testen.

Wir rufen also im Browser auf:

Mit den Angaben vor dem „@“ kann man User und Passwort gleich in der URL übergeben und muss diese nicht immer extra eingeben. Und wenn alles geklappt hat, müsste im Browser der Text „HALLO“ erscheinen.

Der Client

Jetzt geht es an einen kleinen, ersten Client. Wir legen eine Datei an, der Name ist egal, ich nenne sie „client.php“. Diese Datei kann irgendwo angelegt sein, sinnvollerweise nicht auf dem selben Server, auf dem unser API-Server läuft, denn sonst wäre die Arbeit ja sinnlos.

Das sieht schon etwas komplizierter aus. Im Grunde simulieren wir das, was wir vorhin im Browser händisch gemacht haben: Wir packen Daten zusammen (hier nur $befehl), authentifizieren uns am Server und geben die Rückgabe wieder aus.

Zeile 2+3 sind selbsterklärend. WICHTIG: Ohne das abschließende Slash in Zeile 4 wird es nicht funktionieren – also nicht vergessen.

Zeile 5 beinhaltet den „Befehl“, den wir absenden, wieder erstmal nichts besonderes.

Der Rest der Zeilen dient dazu, einen Stream zu generieren und damit das PHP-Skript zu einem kleinen Browser zu machen.

Zeile 21 legt einen Timeout in Millisekunden fest. Da die meisten Hoster nur 30 Sekunden an Ausführungszeit für ihre Skripte zulassen, lohnen sich Werte über 30 Sekunden gar nicht erst, denn der Server wird bereits vorher abbrechen.

Wir machen den Test und rufen den Client im Browser auf:

Etwas smarter, bitte!

Nun ist es auf Dauer etwas unbefriedigend, immer nur $befehl=blabla an den Server zu senden, daher machen wir jetzt die Datenübermittlung etwas smarter. Und zwar so, dass im Prinzip alles gesendet und empfangen werden kann, solang wir es in Variablen verpacken können.

Dazu passen wir zunächst den Client an:

Zeile 5 wird zu:

und Zeile 9 zu:

Und der Server wird auch angepasst.

Die Zeilen 3, 4 und 5 werden zu:

Welchen Sinn hat das? Wir packen alle Variablen, die wir übertragen wissen wollen, in ein Array, serialisieren es mit serialize und packen es auf der anderen Seite wir mit unserialize wieder aus. Der Name des zu transportierenden Arrays spielt dabei keine Rolle; array_shift ermittel automatisch das richtige Array.

Später werden wir serialize auch nutzen, um mehr als nur ein simples „Hallo Welt“ an den Client zurückzuliefern. Aber fürs erste sollte das genügen.

Wir fassen zusammen

Server

Client

Wenn wir jetzt den Client wieder aufrufen:

erhalten wir:

Und mehr benötigen wir für heute nicht. Der Server hat also das Array richtig empfangen.

Im nächsten Teil werden wir dann unseren kleinen Server dazu nutzen, um einen WordPress-Artikel anzulegen.

Microsoft Word 2016 schluckt die letzte Zeile – mal wieder

Ich ärgere mich gerade maßlos, dass Microsoft es 2016 immer noch schafft, auf dem eigenen Betriebssystem und mit der eigenen Software hundertprozentig zuverlässig Textkopien zu erstellen.

Word 2016 schneidet den letzten Satz ab.

Sebastian Brück, ein befreundeter Journalist, mit dem ich zusammen das Projekt Krimischätze  ins Leben gerufen habe, hat mir einen längeren Text, genauer gesagt eine Abschrift eines Roman von 1926 geschickt. Meine Aufgabe ist, daraus ein E-Book zu gestalten.

Der letzte Satz im Text müsste lauten:

Selig sind die Heimatlosen. Denn ich glaube, sie werden nach Hause kommen.

Zufällig bemerke ich, dass die allerletzte Zeile, bzw. der allerletzte Satz im Dokument abgeschnitten ist. Offensichtlich kann „mein“ Word 2016, das ich im Zuge des Office 2016 Pakets für 10 Euro Monatsgebühr abonniert habe nicht das Word-Dokument meines Freundes öffnen.

fehler

Speichern als RTF und alles ist wieder gut.

Wenn ich die selbe Datei nun als RTF speichere und mit bzw. Libre Office Writer öffne, ist die Zeile auf einmal wieder da.

alles_ok

Woher das letzte kleine „s“ auf einmal herkommt, kann ich auch nicht sagen – wieso auch? – ich weiß ja nicht einmal, wieso Word nach Gusto einfach was abschneidet.

Warum kann Word nicht fehlerfrei Word-Dokumente öffnen und anzeigen?

Jetzt wird es noch bunter und es fehlt immer noch die Conclusio: Wenn ich den Text komplett mit STRG+A markiere und mit STRG+C kopiere, dann in einem reinen Texteditor meiner Wahl (hier natürlich Notepadd++) einfüge, ist der Satz wieder da… zumindest die Hälfte davon

immer_noch_nichts

Was fehlt noch?

Was fehlt noch? Was ist mir in den letzten Monaten und Jahren noch durch die Finger geschlüpft? Ich weiß, dass ich dieses Problem vor einigen Monaten schon einmal hatte, damals mit einem mit Open Office erzeugten Word-Dokument; dasselbe Problem: der letzte Satz war abgeschnitten. Damals habe ich das dem exotischen Format „.doc“ zugerechnet und einer fehlerhaften Exportfunktion von Open Office Writer. Aber nun, was ist nun der Grund?

Ich werde diesen Text mitsamt der Datei an den Microsoft-Support schicken, mal schauen, was denen so dazu einfällt.

Und es gibt Ingenieure, die wollen tatsächlich selbstfahrende Autos zu Millionen auf die Menschheit loslassen!

ssdeep Funktionen für PHP installieren

Wer folgende ssdeep-PHP-Funktionen

  • ssdeep_fuzzy_compare
  • ssdeep_fuzzy_hash_filename
  • ssdeep_fuzzy_hash

nutzen möchte, der muss sie zunächst für PHP installieren. Dazu werden verschiedene Pakete und Bibliotheken benötigt. Ich skizziere hier einmal den Schnelldurchgang.

Die Funktionen selbst sind hier beschrieben: http://php.net/manual/en/ref.ssdeep.php

Search and replace inside zip with PHP

Ever wanted to search and replace inside a zip container with PHP?

Linux: Skript ausführen beim Ausschalten

Ich bin ein fauler Hund und noch dazu vergesslich. Also, was passiert, sobald ich meine virtuelle Linux-Maschine ausschalte? Ich denke, verdammt, schon wieder das Backup vergessen!

Also habe ich nach einer Methode gesucht, ein (oder mehrere) Backup-Skripte auszuführen, sobald ich den Rechner ausschalte. Bei einer virtuellen Maschine wird das natürlich durch einen ACPI-Event simuliert. Aber Linux bemerkt da keinen Unterschied.

Hier also meine schnelle: „Klicken-und-vergessen“-Methode für

  • Oracle VM VirtualBox Manager
  • Host: Windows 7 64 Bit
  • Gast: Ubuntu Linux 14.04.1 – 64 Bit
  • Netzwerk: AVM FRITZ!Box 7390, Host über WLAN verbunden

Wir installieren (falls noch nicht geschehen) ACPI, das Advanced Configuration and Power Interface.

Alles wichtige findet sich unter etc/acpi/:

Werfen wir einen Blick in die auszuführende Datei powerbtn-acpi-support.sh:

Zum Glück ist die Datei nicht sehr lang und erklärt sich sogar einem Laien wie mir einigermaßen. Wir suchen die Zeile weiter unten mit dem Kommentar: # Normal handling.

Und direkt vor dem /sbin/shutdown -h -P now platzieren wir den Aufruf zu unserem Skript. Das könnte dann etwa so aussehen:

In backup_files.sh rufe ich meine verschiedenen Backup-Befehle auf, die sonst auch bei reboot oder shutdown aufgerufen werden. Wie das funktioniert, habe ich schon hier: Und es geht doch: Linux, Skript ausführen beim Herunterfahren beschrieben.

Das war’s. Beim nächsten Ausschalten gibt es vorher erst einmal – wie es sich gehört – ein Backup.

Und es geht doch: Linux, Skript ausführen beim Herunterfahren

Geradezu abenteuerlich sind die Aussagen einiger selbsternannter Experten beim Thema „Skripte ausführen beim Herunterfahren“. Von „Linux fährt man nicht herunter“ bis zu „ist überhaupt nicht möglich“ habe ich alles schon lesen dürfen.

Dabei ist es ganz einfach. Ich benutze diese Methode auf meiner virtuellen Entwicklungsmaschine, um Dateien und Datenbanken nach einem Arbeitstag auf dem Host zu sichern.

Hier also meine schnelle: „Klicken-und-vergessen“-Methode für

  • Oracle VM VirtualBox Manager
  • Host: Windows 7 64 Bit
  • Gast: Ubuntu Linux 14.04.1 – 64 Bit (Hostname: minlux)
  • Netzwerk: AVM FRITZ!Box 7390, Host über WLAN verbunden

Die auszuführenden Dateien befinden sich in /etc/init.d/.

Wir legen ein Skript an, das nichts anderes macht, als eine leere Datei namens goodbye.txt ins Home-Verzeichnis des Users zu schreiben. Das Skript, das das erledigen soll, erhält den Namen custom-shutdown.sh.

Wir machen die Datei ausführbar:

Prüfen, ob alles geklappt hat:

Nun legen wir in /etc/rc0.d/ einen Link zum Skript. Beachte: das Präfix K04 vor dem Dateinamen, ohne das geht es nicht.

Fertig. Nun starten wir die Maschine neu

Test, ob goodbye.txt auch wirklich angelegt wurde:

Man beachte, dass die Datei für den Nutzer root angelegt worden ist, falls man noch irgendetwas damit plant.

Skript beim Hochfahren ausführen

Wer möchte, kann Skripte auch ausführen lassen beim Hochfahren des Rechners. Dann muss der Link aber nicht in rc0.d sondern in rc6.d platziert werden.

WICHTIG: Server neu starten

Wenn man Datenbanksicherungen beim Herunterfahren anlegen möchte, so muss man natürlich beachten, dass die Datenbank schon längst selbst heruntergefahren ist. Also muss man diese kurz wieder starten:

Mein Dank geht an http://ubuntu.flowconsult.at/linux/ubuntu-14-10-shutdown-script-with-rc0-d-rc6-rcd/ und https://unix.stackexchange.com/questions/34963/running-script-before-shutdown-seemingly-not-working. Mehr Informationen zum Runlevel: https://en.wikipedia.org/wiki/Runlevel#Ubuntu

Oracle VM VirtualBox Manager – Zugriff auf gemeinsame Ordner und Dateien über Gasterweiterungen

Ein Thema, zu dem ich auch keine simple Lösung finden konnte: wie tauschen Host und Gast Dateien aus? Normalerweise funktioniert das über die sogenannten Gasterweiterungen. Aber diese zu installieren, ist so umständlich und schlecht erklärt, dass es schon an Körperverletzung grenzt.

Hier also meine schnelle: „Klicken-und-vergessen“-Methode für

  • Oracle VM VirtualBox Manager
  • Host: Windows 7 64 Bit
  • Gast: Ubuntu Linux 14.04.1 – 64 Bit (Hostname: minlux)
  • Netzwerk: AVM FRITZ!Box 7390, Host über WLAN verbunden

Ohne dem geht es nicht. Warum? Keine Ahnung. Oracle versucht es hier zu erklären.

Die richtige ISO-Datei mit den Gasterweiterungen herunterladen und über den VirtualBox Manager einlegen:  Geräte->CD/DVD-Laufwerke->Datei für virtuelles CD/DVD-Medium auswählen…

Die ISO-Datei auswählen
Die ISO-Datei auswählen

Im Manager den gemeinsamen Order (hier: C:\Users\juergen\share) angeben. Dazu noch die Optionen: „automatisch einbinden“ und „permanent erzeugen“ aktivieren. Fragen Sie mich nicht, worin der Unterschied zwischen beiden besteht.

Gemeinsamen Ordner auswählen
Gemeinsamen Ordner auswählen

Es genügt nicht, die ISO-Datei wie oben einfach nur auszuwählen; man muss sie auch mit mount einbinden. Keine Angst wegen der Read-Only-Nachricht, denn schließlich ist die ISO-Datei ja als CD-Abbild schreibgeschützt.

Jetzt werden die Gasterweiterungen installiert. Schon diese zweite Befehlszeile lässt sich nirgends bei Oracle finden. Wie soll da jemand von selbst darauf kommen? Die Fehlermeldungen können ignoriert werden, da sie sich meist nur auf nicht installierte Desktop-Erweiterungen beziehen.

Ein kleiner Test. Jetzt sollte ein Gerät „vboxsf“ zu sehen sein.

Kann man schon das Verzeichnis sehen? Es sollte automatisch das Prefix „sf_“ erhalten haben; hier also „sf_share“.

Auch wichtig, sonst gibt es als kastrierter Nutzer, der man ist, wieder Probleme.

Erst jetzt werden die Änderungen wirksam.

Wir wechseln in das Verzeichnis und legen ein erstes Testfile ein, das auf beiden Maschinen zu sehen sein sollte.

Der gemeinsame Ordner auf dem Gastsystem.
Der gemeinsame Ordner auf dem Gastsystem.

Noch ein letzter Test: Jetzt sollte auch in der Windows-Maschine die Datei zu sehen sein.

Der gemeinsame Ordner auf dem Hostsystem
Der gemeinsame Ordner auf dem Hostsystem

 

 

Oracle VM VirtualBox Manager: Zugriff von Host auf Gast über Hostname statt IP

Wer eine virtuelle Maschine aufsetzt, möchte sich

a) die IP des Gastsystems nicht merken und

b) nicht ständig in irgendwelchen /etc/hosts Einträge pflegen müssen.

Daher schien es mir kein großes Unterfangen, das zu erledigen, wie falsch lag ich doch. Einen ganzen Tag habe ich damit vergeudet die Posts von Linux-Trollen zu lesen, die immer nur das gleiche aussagten: „Ach, irgendwie weiß ich auch nicht, wie das geht, aber ich schicke dich auf eine lange sudo-apt-get-install-Reise mit ein wenig Du-musst-dich-erstmal-einarbeiten-Kauderwelsch und Linux-ist-nur-für-Profis-Gebetsmühlenwiederkäuerei.

Also, hier ein 1-Minuten-Tutorial für:

  • Oracle VM VirtualBox Manager
  • Host: Windows 7 64 Bit
  • Gast: Ubuntu Linux 64 Bit (Hostname: minlux)
  • Netzwerk: AVM FRITZ!Box 7390, Host über WLAN verbunden

Ausgangssituation

Versucht man per

über die Windows-Konsole zuzugreifen, klappt es nicht.

Kennt man, sonst wären Sie nicht auf dieser Seite. Kein Zugriff auf die Gastmaschine über den Namen. Scheiße, oder?
Kennt man, sonst wären Sie nicht auf dieser Seite. Kein Zugriff auf die Gastmaschine über den Namen. Scheiße, oder?

 

Lösung

Wir öffnen Oracle VM VirtualBox Manager und passen die Netzwerkeinstellungen an. Man muss als Anschlusspunkt „Netzwerkbrücke“ auswählen und das Gerät mit dem der Host (also die Windows-Maschine) ins Internet geht . Zu den anderen Einstellung und deren Bedeutung kann ich nichts sagen.

Einfach die richtigen Haken setzen. Kein "NAT" sondern "Netzwerkbrücke" - das ist der Kniff
Einfach die richtigen Haken setzen. Kein „NAT“ sondern „Netzwerkbrücke“ – das ist der Kniff

Ergebnis

ping ok
ping ok
Einstellungen für PuTTY
Einstellungen für PuTTY
SSH ok
SSH ok
Browser ok
Browser ok

Na, war doch gar nicht so schwer. Und wieder einmal geht ein Stück exklusives Herrschaftswissen von den Linux-Jüngern verloren. Man muss nicht das Kernel neu kompilieren, nicht mit vi und grep irgendwelche Zeilen filtern und auskommentieren und auch nicht bei Vollmond nackt im Garten auf einem Bein stehen.

Ein Haken im schmutzigen Windows setzen, fertig!

Wordpress, PHP, MySQL, Plugins, Android, Amazon Kindle, eBooks