<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yoda Condition &#187; Plugin</title>
	<atom:link href="http://yoda.neun12.de/artikel-category/wordpress/plugin/feed" rel="self" type="application/rss+xml" />
	<link>http://yoda.neun12.de</link>
	<description>Debuggen du musst</description>
	<lastBuildDate>Sun, 18 May 2014 13:49:01 +0000</lastBuildDate>
	<language>de-DE</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>TinyMCE zur Bearbeitung von Mediendateien</title>
		<link>http://yoda.neun12.de/artikel-143</link>
		<comments>http://yoda.neun12.de/artikel-143#comments</comments>
		<pubDate>Sun, 18 May 2014 13:40:02 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=143</guid>
		<description><![CDATA[Alle sagen es geht nicht bis einer kommt und es einfach macht. So ging es mir bei diesem G+ Post. Das Problem ist einfach umrissen: In der Medienübersicht wird der Standard-Editor zur Bearbeitung der Medienbeschreibung verwendet. Der Wunsch war jedoch den TinyMCE dafür einzusetzen. Normalerweise reicht es dafür aus einen Filter auf die Editor-Einstellungen zu [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Alle sagen es geht nicht bis einer kommt und es einfach macht. So ging es mir bei <a title="Google+" href="https://plus.google.com/u/0/+ReneWelz/posts/H4RMbXhaVb2">diesem G+ Post</a>. Das Problem ist einfach umrissen: In der Medienübersicht wird der Standard-Editor zur Bearbeitung der Medienbeschreibung verwendet. Der Wunsch war jedoch den TinyMCE dafür einzusetzen. Normalerweise reicht es dafür aus einen Filter auf die Editor-Einstellungen zu verwenden und das Flag für den TinyMCE auf <code>True</code> zu setzen.</p>
<p>Wir haben im Prinzip drei Möglichkeiten um die Editor-Einstellungen zu beeinflussen. Zum einen dann wenn sie definiert werden.</p>
<pre class="brush:php">$editor_args = array(
	'textarea_name' =&gt; 'content',
	'textarea_rows' =&gt; 5,
	'media_buttons' =&gt; false,
	'tinymce' =&gt; false,
	'quicktags' =&gt; $quicktags_settings,
);

$editor_args = apply_filter( 'some_filter', $editor_args );
</pre>
<p>Leider ist dies nicht immer möglich, vor allen Dingen im gegebenen Fall nicht. Leider bietet auch die verwendetet Funktion <code>wp_editor()</code> noch die die Klasse <code>_WP_Editors</code> einen entsprechenden Filter an. Warum das so ist, sei mal dahingestellt. Ebenso das es bereits diverse Tickets im Trac zu den Thema gibt. Wenn man sein Ziel nicht auf direkten Weg erreichen kann, dann muss man manchmal einen kleinen Umweg gehen.</p>
<p>Eine Lösung wäre, wenn die Funktion <code>wp_editor()</code> plugable wäre, man sie also gegen eine eigene Funktion austauschen kann. Ist sie aber nicht, muss man den Hebel also woanders ansetzen.</p>
<p>Im betreffenden Fall wurde angeregt in der <a title="Trac Ticket #28259" href="https://core.trac.wordpress.org/ticket/28259">Klasse einen zusätzlichen Filter</a> einzubauen. Bis dies umgesetzt ist, muss man sich also mit einen kleinen Workaround behelfen.<br />
Wirft man einen Blick in den <a title="Core WordPress Browse Trunk" href="https://core.trac.wordpress.org/browser/trunk/src/wp-includes/general-template.php#L2280">Code</a>, so sieht man das abgefragt wird ob die Klasse <code>_WP_Editors</code> bereits geladen wurde. Nur wenn sie <em>nicht</em> geladen wurde, wird die Klasse aus dem WordPress-Core geladen. Für uns bedeutet dies also, wir können die Original-Klasse durch eine gleichnamige eigene Klasse ersetzen. Wir müssen nur dafür sorgen das unsere Klasse möglichst früh geladen wird. Am einfachsten erreicht man dies indem man einen der sehr früh ausgelösten Hooks benutzt um die eigene Klasse mittels <code>require_once()</code>/<code>include_once()</code> einzubinden.</p>
<p>Wie man sieht, gibt es in WordPress nicht nur eine Möglichkeit um etwas zu beeinflussen. Der einfachste Weg sind Filter und Actions um Variablen direkt zu beeinflussen. Sind diese nicht gegeben, schaut man sich an ob die betreffende Funktion etwas hergibt, also ob diese ggf. einen Filter/Action besitzt oder ob man sie ersetzen kann. Ist dies auch nicht gegeben, so kann man, wie hier im Beispiel, noch eine letzte Chance nutzen und eine Klasse komplett austauschen.</p>
<p>Der erste Schritt zum Plugin besteht also darin die Klasse <code>_WP_Editors</code> komplett in sein Plugin-Ordner zu kopieren. Der nächste Schritt ist das Einbinden der kopierten Klasse:</p>
<pre class="brush:php">/**
 * Including the modified WP class _WP_Editors
 */
add_action(
	'plugins_loaded',
	function() {
		require_once dirname( __FILE__ ) . '/class-wp-editor.php';
	},
	0,
	0
);
</pre>
<p>Um zu überprüfen ob nun die kopierte oder die Original-Klasse geladen wird, kann man am Anfang der Kopie einfach mal ein <code>die( 'Kopierte Klasse' );</code> setzen. Bricht WordPress nach einem Neuladen mit einen weißen Bildschirm ab auf dem nur &#8220;<em>Kopierte Klasse</em>&#8221; steht, so können wir sicher sein das nur unsere kopierte Klasse geladen wird. Nun geht es daran die kopierte Klasse zu modifizieren. Wie im Ticket vorgeschlagen ergänzen wir die Klasse um einen zusätzlichen Filter.</p>
<p>Da wir nun in der kopierten Klasse einen Filter haben den wir nutzen können, reicht es aus diesen zu setzen und in einer passenden Funktion die Werte entsprechend zu ändern.</p>
<pre class="brush:php">/**
 * Add the filter to modify the editor settings
 */

add_filter( 'wp_editor_settings', 'modify_editor_settings', 0, 2 );

/**
 * Modify the editor settings. Currently only set the value for using the TinyMCE to true.
 *
 * @param array $settings Array with editor settings
 * @param array $editor_id The ID of the editor
 * @return array
 */
function modify_editor_settings( $settings, $editor_id ) {

	if ( 'attachment_content' == $editor_id )
		$settings['tinymce'] = true;

	return $settings;

}
</pre>
<p>Ich habe hier bewusst auf umständliche Prüfungen verzichtet um das Beispiel einfach zu halten. Man könnte zusätzlich darauf prüfen ob man sich auch tatsächlich in der Medienübersicht bzw. Medienbearbeitung befindet. Es wird lediglich geprüft ob die Editor-ID <code>attachment_content</code> ist und dann das Flag für den TinyMCE auf <code>true</code> gesetzt.<br />
Durch Anpassung der Funktion <code>modify_editor_settings()</code> lässt sich so der TinyMCE für nahezu alle Eingabefelder aktivieren sofern die Editor-ID bekannt ist und das Eingabefeld über die Funktion <code>wp_editor()</code> erzeugt wird.</p>
<p>Das Plugin ist recht wartungsfreundlich. Sollte eines Tages ein Filter zum Modifizieren der Editor-Einstellungen vorhanden sein, so muss man nicht das komplette Plugin neu konstruieren. Es reicht aus die Einbindung der eigenen Klasse zu entfernen und ggf. den Filter-Namen anzupassen.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-143/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neues Plugin: Password Change Reminder</title>
		<link>http://yoda.neun12.de/artikel-126</link>
		<comments>http://yoda.neun12.de/artikel-126#comments</comments>
		<pubDate>Sun, 24 Nov 2013 11:47:59 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=126</guid>
		<description><![CDATA[Einer der häufigsten Tipps zur Sicherheit ist, sein Passwort regelmäßig zu wechseln. In diesen eigentlich simplen Punkt unterstützt WordPress uns leider in keinster Weise. Zumindest habe ich bei einer schnellen Recherche nichts dazu gefunden. Also habe ich mich hingesetzt und selber ein Plugin geschrieben: Password Change Reminder Zielgruppe des Plugins sind Blogs die mit mehr [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Einer der häufigsten Tipps zur Sicherheit ist, sein Passwort regelmäßig zu wechseln. In diesen eigentlich simplen Punkt unterstützt WordPress uns leider in keinster Weise. Zumindest habe ich bei einer schnellen Recherche nichts dazu gefunden. Also habe ich mich hingesetzt und selber ein Plugin geschrieben: <a title="WordPress › Password Change Reminder « WordPress Plugins" href="http://wordpress.org/plugins/password-change-reminder/">Password Change Reminder</a><br />
Zielgruppe des Plugins sind Blogs die mit mehr oder minder unerfahrenen Benutzern (z.B. mehrere Autoren)  arbeiten. Aber auch Firmen die gewisse Vorgaben machen was das Passwort und die Häufigkeit zur Aktualisierung selbigen angeht. Natürlich ist es genauso für all diejenigen interessant, die sich zwar immer wieder vornehmen das Passwort regelmäßig zu wechseln, dies aber genauso regelmäßig vergessen.</p>
<p>Das Plugin ist sehr einfach gestrickt. Es prüft wie alt das aktuelle Passwort ist und gibt, sofern es veraltet ist, einen Warnhinweis im Adminbereich aus. Dieser Warnhinweis (engl. nag screen; deut. Nörgelbildschirm) erscheint auf allen Seiten im Adminbereich.<br />
Neben den Hinweis im Adminbereich kann das Plugin auch einen unübersehbaren Hinweis auf der Startseite ausgeben. Dies ist nützlich für Benutzer die sich um den Adminbereich drücken.</p>
<p>Natürlich gibt es auch ein paar Einstellungen. Die wichtigste ist wohl die Einstellung wie lange es dauern soll bevor ein Passwort veraltet ist. Es lässt sich aber zusätzlich noch einstellen ob der Hinweis auch auf der Startseite erscheinen soll. Ebenso lässt sich einstellen ob Benutzer den Hinweis eine Zeit lang ignorieren (ausblenden) können und nach welcher Zeitspanne der Hinweis wieder eingeblendet werden soll. Als letzte Einstellung lässt sich noch ein Text festlegen der zusätzlich im Hinweis erscheinen kann. So kann man die Benutzer z.B. auf die Risiken eines veralteten Passwortes aufmerksam machen oder auf verbindliche Nutzerregelungen hinweisen.</p>
<p>Da das Plugin, wie gesagt, sehr einfach gehalten ist, gibt es dazu nun auch nicht mehr viel zu sagen. Experten die das Plugin einsetzen und den Hinweis auf der Startseite optisch ändern möchten, steht ein Stylesheet zur Verfügung das angepasst werden kann.</p>
<p>Für Lob, Kritik, Anregungen und vor allem Fehlerberichte steht der <a title="WordPress › Support » Password Change Reminder" href="http://wordpress.org/support/plugin/password-change-reminder">Support auf WordPress</a> und das <a title="RalfAlbert/PasswordChangeReminder · GitHub" href="https://github.com/RalfAlbert/PasswordChangeReminder">Repo auf GitHub</a> zur Verfügung.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-126/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Das Ende einer langen Pause</title>
		<link>http://yoda.neun12.de/artikel-125</link>
		<comments>http://yoda.neun12.de/artikel-125#comments</comments>
		<pubDate>Wed, 20 Nov 2013 16:27:29 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=125</guid>
		<description><![CDATA[Seit rund 6 Monaten habe ich nun hier nichts mehr rein geschrieben. In etwa genauso lange hat man von mir generell nichts mehr in Sachen WordPress lesen können. Anfangs war es schlichtweg Zeitmangel aufgrund von mehreren Projekten die ich begonnen hatte. Aber dann kam irgendwann der Tag an dem gar nichts mehr ging. Von jetzt [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Seit rund 6 Monaten habe ich nun hier nichts mehr rein geschrieben. In etwa genauso lange hat man von mir generell nichts mehr in Sachen WordPress lesen können. Anfangs war es schlichtweg Zeitmangel aufgrund von mehreren Projekten die ich begonnen hatte. Aber dann kam irgendwann der Tag an dem gar nichts mehr ging. Von jetzt auf Gleich ein Balken im Kopf der die totale Blockade ausgelöst hatte. Nicht eine Zeile Code habe ich mehr hin bekommen. Nicht einen klaren Gedanken fassen können wenn ich ein Problem lösen wollte. Nichts ging mehr.</p>
<p>Zum Glück ist das Programmieren nicht meine Lebensgrundlage, ansonsten wäre ich einige Monate lang berufsunfähig gewesen. So konnte ich mir den Luxus einer langen Auszeit gönnen und habe mich rein gar nicht mehr mit WordPress, PHP oder verwandten Themen befasst.<br />
Andere Dinge rückten in den Mittelpunkt und das war gut so. Ich habe den nötigen Abstand gewonnen um wieder klar denken zu können. Den nötigen Abstand um Projekte, die ich begonnen hatte, wieder mit der nötigen Distanz und Kritikfähigkeit betrachten zu können. Abstand der es mir ermöglichte Wichtiges von Unwichtigen zu trennen.</p>
<p>Bei vielen reicht dafür ein Urlaub. Urlaub bedeutet bei mir jedoch oftmals Zeit zum Coden. Und das war dann wohl auch der Fehler den ich gemacht hatte, weswegen meine Auszeit etwas länger ausfiel.<br />
Dadurch das ich mir Zeit für mich selber und andere Dinge genommen hatte &#8211; eher nehmen musste &#8211; konnte ich den Akku wieder aufladen. Jetzt macht mir das Coden wieder Spaß, die Zeilen flutschen nur so auf den Bildschirm und ich verbeisse mich nicht mehr an unwichtigen Details.<br />
Viele Projekte habe ich auf Eis gelegt oder gleich ganz aufgegeben, ansonsten hätte ich das Coden wahrscheinlich aus lauter Frust komplett an den Nagel gehängt.<br />
Zu den jetzigen Neuanfang gehört auch ein kleines Plugin, welches ich ohne durch Altlasten aufgehalten zu werden, in den letzten vier Tagen umgesetzt habe.</p>
<p>Entstanden ist das Plugin durch die Beschäftigung mit Menschen die es schon als große Leistung ansehen Facebook zu starten. Denn es kann durchaus hinderlich sein wenn man ständig von Menschen umgeben ist die sich auskennen. Man verliert sehr schnell den Blick dafür was diejenigen benötigen (könnten), die sich weniger bis gar nicht auskennen. Raus aus den Elefenbeinturm ist hier die Devise gewesen.<br />
Und so ist in den letzten Tagen <a title="PwCR on GitHub" href="https://github.com/RalfAlbert/PasswordChangeReminder">Password Change Reminder (PwCR)</a> entstanden. Bei einer schnellen Recherche konnte ich kein Plugin finden welches den Benutzer daran erinnert regelmäßig sein Passwort zu ändern. PwCR macht genau das. Nicht mehr und nicht weniger.<br />
Das Plugin ist, wie so häufig bei mir, in einem sehr früher Stadium. Da können noch ein paar Fehler dabei sein, die (englischen) Texte sind alle noch etwas schief, Übersetzungsarbeit ist zu leisten und natürlich Dokumentation. Genaueres zu dem Plugin werde ich in eine  seperaten Artikel schreiben. Bis dahin kann jeder der möchte es schon mal ausprobieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-125/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Linktitel automatisch ausfüllen lassen</title>
		<link>http://yoda.neun12.de/artikel-110</link>
		<comments>http://yoda.neun12.de/artikel-110#comments</comments>
		<pubDate>Sat, 11 May 2013 15:36:28 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=110</guid>
		<description><![CDATA[Bitte beachten! Das Plugin steht nun auch auf WordPress.org zum Download bereit. Bitte alle Supportanfragen und Fehlermeldungen entweder im Support auf WordPress.org oder im Issue Tracker auf GitHub. Bitte keine Support-Anfragen in den Kommentaren! Danke für das Verständnis. Derzeit schreibe ich an ein paar Artikeln und ärgere mich immer das ich, wenn ich einen Link erstelle, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><strong>Bitte beachten!</strong><br />
Das Plugin steht nun auch auf <a title="WordPress - Auto Title To Link &gt; WordPress Plugins" href="http://wordpress.org/plugins/auto-insert-title-to-link/">WordPress.org zum Download</a> bereit. Bitte alle Supportanfragen und Fehlermeldungen entweder im <a title="WordPress - Support &gt; Auto Title To Link" href="http://wordpress.org/support/plugin/auto-insert-title-to-link">Support auf WordPress.org</a> oder im <a title="Issues · RalfAlbert/auto-title-to-link · GitHub" href="https://github.com/RalfAlbert/auto-title-to-link/issues">Issue Tracker auf GitHub</a>. <strong>Bitte keine Support-Anfragen in den Kommentaren!</strong> Danke für das Verständnis.</p>
<hr />
<p>Derzeit schreibe ich an<a class="highslide" onclick="return hs.expand(this)"  href="http://yoda.neun12.de/wp-content/uploads/2013/05/autoinsertlinktitle.jpg"><img class=" wp-image-112 alignright" alt="Autoinsert Linktitle" src="http://yoda.neun12.de/wp-content/uploads/2013/05/autoinsertlinktitle-300x287.jpg" width="210" height="201" /></a> ein paar Artikeln und ärgere mich immer das ich, wenn ich einen Link erstelle, den Titel für den Link manuell ausfüllen muss. Wahrscheinlich bin ich der einzige auf diesen Planeten mit diesen Problem, deswegen habe ich mir schnell mal ein <a title="RalfAlbert/auto-title-to-link · GitHub" href="https://github.com/RalfAlbert/auto-title-to-link">kleines Plugin</a> geschrieben.</p>
<p>Gibt man im URL-Feld eine gültige URL ein und verlässt dieses Feld, dann wird ein Ajax-Request abgesetzt der versucht aus der verlinkten Webseite den <code>title</code>-Tag zu extrahieren. Gelingt dies, wird der Webseitentitel in das Feld für den Linktitel eingefügt. Wenn nicht, passiert nix. Den Titel kann man bei Bedarf dann noch anpassen oder wieder löschen.</p>
<p>Vielleicht nimmt sich ja mal jemand etwas Zeit und gibt ein wenig Feedback, wäre schön und hilfreich.</p>
<h3>Nachtrag</h3>
<p>Ich hatte nicht damit gerechnet das dass Plugin ein so hohes Interesse wecken würde. Github, dort wo der Plugin-Code derzeit liegt, ist nicht jedem bekannt und auch nicht jeder weiß wie man aus dem Repository ein Zip bekommt. Deswegen hier eine kleine Anleitung dazu.</p>
<p><a class="highslide" onclick="return hs.expand(this)"  href="http://yoda.neun12.de/wp-content/uploads/2013/05/github_autoinserttitle1.png"><img class="alignleft size-full wp-image-115" alt="#111" src="http://yoda.neun12.de/wp-content/uploads/2013/05/github_autoinserttitle1.png" width="323" height="239" /></a> Als erstes also mal das <a title="RalfAlbert/auto-title-to-link · GitHub" href="https://github.com/RalfAlbert/auto-title-to-link">Github-Repository</a> öffnen. Sollte euer Bildschirm anders aussehen als im Screenshot links, dann klickt auf <em>Code</em> (zwischen der Pulskurve und <em>Network</em> (die rote Markierung habe allerdings ich eingefügt)). Rechts neben <em> Clone in Windo</em>ws ist ein Button mit einer kleinen Wolke und dem Wort <em>ZIP (siehe Screenshot)</em>. Klickt ihr da drauf, dann sollte eine Aufforderung erscheinen eine Zip-Datei zu speichern.<br />
Diese Zip-Datei speichert ihr auf eurem Computer und kann dann bereits aus dem Backend von WordPress heraus installiert werden.<br />
Dazu im Backend auf die Plugins-Seite gehen, dort oben neben <em>Plugins</em> auf <em>Installieren</em> klicken, im nächsten Bildschirm auf <em> Hochladen</em> (oder in der englischen Version <em>Upload</em>), die zuvor gespeicherte Zip-Datei auswählen und fertig. Nun noch das Plugin aktivieren und das war es.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-110/feed</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>FrankenKey</title>
		<link>http://yoda.neun12.de/artikel-89</link>
		<comments>http://yoda.neun12.de/artikel-89#comments</comments>
		<pubDate>Sat, 22 Dec 2012 22:59:56 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=89</guid>
		<description><![CDATA[Aus einer Frage auf WordPress.Stackexchange.com heraus habe ich ein kleines Plugin geschrieben. Mich hat es auch immer ein wenig genervt das der HTML-Editor von WordPress keine richtigen Tastaturkürzel hat. Es gibt lediglich Access-Keys, was bedeutet das beim Drücken einer bestimmten Tastaturkombination der Fokus vom Textfeld auf einen der Buttons in der Werkzeugleiste verlegt wird. Dadurch [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Aus einer <a title="WPSE" href="http://wordpress.stackexchange.com/questions/74568/create-keyboard-shortcuts-for-html-mode/74600#74600">Frage auf WordPress.Stackexchange.com</a> heraus habe ich ein kleines Plugin geschrieben. Mich hat es auch immer ein wenig genervt das der HTML-Editor von WordPress keine richtigen Tastaturkürzel hat. Es gibt lediglich Access-Keys, was bedeutet das beim Drücken einer bestimmten Tastaturkombination der Fokus vom Textfeld auf einen der Buttons in der Werkzeugleiste verlegt wird. Dadurch muss man noch einmal Enter drücken damit die Aktion ausgeführt wird. Zudem verrenke ich mir immer die Finger beim Drücken von z.B. <code>[shift]+[alt]+[a]</code> um einen Link einzufügen. Mal ganz davon abgesehen das ich es mir nur sehr selten merken kann welche Tastaturkombination welche Aktion ausführt.</p>
<p>Als kleines Weihnachtsgeschenk für diejenigen die es brauchen können habe ich <a title="FrankenKey" href="https://github.com/RalfAlbert/FrankenKey">FrankenKey</a> veröffentlicht. Das Plugin ist eher als &#8220;raft draft&#8221; anzusehen, also ein Entwurf für ein Plugin das noch im Fluss der Entwickelung ist. Wer es dennoch schon mal testen will oder sein eigenes Plugin darauf aufbauen möchte, ist gerne eingeladen daraus seine eigene Lösung zu erstellen.</p>
<p>Technisch gesehen ist das Plugin sehr simple aufgebaut. Die Tastatur wird mit <a title="mousetrap js" href="http://craig.is/killing/mice">mousetrap</a> überwacht. Es gibt zwar noch ein jQuery Plugin namens jQuery Hotkeys welches auch von WordPress bereitgestellt wird, dieses ist aber nicht ganz so leistungsfähig wie mousetrap und ich habe es auch nicht richtig zum Laufen bekommen.<br />
<code>selection.js</code> übernimmt die Arbeit der Modifikationen im Text. Es ist ein jQuery-Plugin welches auf <a title="Stackoverflow" href="http://stackoverflow.com/a/8620938">Code von Stackoverflow</a> basiert. <code>selection.js</code> liefert den ausgewählten Text und kann diesen zum Teil auch modifizieren (z.B. in Tags einschließen).<br />
Die Kernkomponente <code>frankenkey.js</code> arbeitet wie eine Weiche. Hier werden die Bindungen zwischen Textfeld und mousetrap angelegt und letzten Endes auch die Tastatureingaben verarbeitet. Wird eine Tastaturkombination erkannt, wird zuerst entschieden ob es sich um eine Kombination zum Einfügen von Tags oder eines simulierten Klicks auf einen der Buttons handelt. Grundsätzlich hätte man das Script so gestalten können, dass es lediglich Klicks auf die Buttons in der Werkzeugleiste simuliert. Dadurch das eigene Aktionen definiert werden, können auch andere HTML-Tags als die vordefinierten verwendet werden.</p>
<p>Mich würde mal interessieren ob es so was überhaupt braucht oder ob es völlig überflüssig ist. Was denkt ihr darüber?</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-89/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress und FTP</title>
		<link>http://yoda.neun12.de/artikel-66</link>
		<comments>http://yoda.neun12.de/artikel-66#comments</comments>
		<pubDate>Sun, 20 May 2012 12:58:25 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=66</guid>
		<description><![CDATA[Über die Möglichkeiten seine FTP-Zugangsdaten an sein WordPress-Blog zu übermitteln und ein Plugin um dies relativ bequem zu machen.]]></description>
				<content:encoded><![CDATA[<p>Es gibt einige Möglichkeiten wie man seine FTP-Zugangsdaten an WordPress übermitteln kann. Aus einer kleinen <a title="Google+" href="https://plus.google.com/110569673423509816572/posts/dxFmeZa2Uue">Diskussion auf Google+</a> heraus kam die Idee diese mal mit ihren Vor- und Nachteilen zusammen zu fassen. Dies will ich im folgenden mal versuchen und dabei versuchen auch die Gründe aufzuzeigen warum WordPress manchmal FTP-Daten braucht und manchmal nicht. Nebenbei ist noch ein kleines Plugin entstanden welches eine weitere Möglichkeit bietet seine FTP-Daten in seien Blog zu hinterlegen.<span id="more-66"></span></p>
<h3>Ein paar Grundlagen</h3>
<p>Viele kennen es, wenn WordPress versucht Dateiaktionen auf den Server durchzuführen, z.B. ein Plugin oder Theme zu installieren, wird man nach seinen FTP-Zugangsdaten gefragt. Dabei ist es egal ob man eine Archivdatei direkt hochlädt oder von einen entfernten Server ein Update einspielt. Der Grund dafür liegt nicht bei WordPress, sondern bei Unix bzw. einem Unix-ähnlichen Betriebssystem wie Linux. Die Unix-ähnlichen Betriebssysteme kennen nämlich verschiedene Dateiberechtigungen und vor allem Dateibesitzer. Wenn unter einem Unix-System der (FTP-) <em>Benutzer A</em> eine Datei anlegt, so kann auch nur der <em>Benutzer A</em> diese Datei beschreiben bzw. löschen. <em>Benutzer A</em> ist der Dateibesitzer und hat die volle Kontrolle über die von ihm angelegte Datei. Möchte der <em>Benutzer A</em> das die Datei auch von anderen FTP-Benutzern gelesen bzw. beschrieben werden kann, so müssen entsprechende Berechtigungen vergeben werden. Es gibt drei Gruppen denen man den Zugriff auf die Datei erlauben kann: Nur der Eigentümer (also derjenige der die Datei angelegt hat), eine Gruppe von FTP-Benutzern und Alle anderen (<em>others</em> oder <em>public</em>). Zudem kann auch noch die Art des Zugriffs geregelt werden. Möglich sind: Lesen, Schreiben und Ausführen.<br />
<em>Benutzer A</em> könnte z.B. festlegen das die von ihm angelegte Datei nur von ihm beschrieben werden kann, jedoch z.B. alle FTP-Benutzer aus der Gruppe <em>Tastatursklaven</em> die Datei zumindest lesen können. Alle anderen FTP-Benutzer, so z.B. anonyme Gäste, können die Datei weder lesen noch sie beschreiben.</p>
<p>Dies ist ein grundlegender Schutz vor unberechtigten Zugriffen. Es wäre ja schon ein wenig fatal wenn jeder der will z.B. die Datei <em>wp-config.php</em> lesen, geschweige denn sie nach Lust&amp;Laune verändern könnte. Dieser &#8220;Schutz&#8221; wirkt sich nun nicht nur auf Dateien aus, sondern auch auf Verzeichnisse. Dateien die in einem Verzeichnis liegen das nur vom Eigentümer gelesen werden kann, können nicht von anderen FTP-Benutzern gelesen werden, egal welche Dateiberechtigung die einzelnen Dateien haben.<br />
Jetzt stellt sich natürlich die Frage was das alles mit WordPress zu tun hat. Schauen wir uns dazu erst einmal die &#8220;Ausnahme&#8221; an. Das wäre der Fall, wenn WordPress auf einem Server installiert ist auf dem PHP als so genanntes <em>php-cgi</em> läuft. Php-cgi ist eine ausführbare Datei und wird immer unter dem Konto des FTP-Benutzers ausgeführt. Wenn php-cgi also eine Datei auf den Server schreibt, hat die Datei als Eigentümer automatisch den FTP-Benutzer als Dateieigentümer.<br />
Der andere Fall, der weitaus verbreiteter ist, ist der, dass PHP als Apache-Modul (php_mod) ausgeführt wird. In diesen Fall ist nicht der FTP-Benutzer der Dateieigentümer, sondern der Apache-Server, der so gesehen auch ein FTP-Benutzer ist, jedoch mit einen anderen Benutzernamen. Je nachdem wie der Server konfiguriert ist, variiert der FTP-Benutzername des Servers. Häufig ist dies &#8220;nobody&#8221;, aber auch &#8220;wwwrun&#8221;, &#8220;PHP-User&#8221; oder schlicht &#8220;PHP&#8221;. Welcher Benutzername der Apache-Server genau hat, muss also im Einzelfall jeder selber heraus finden, ist aber für das Verständnis gar nicht so wichtig.</p>
<p>Halten wir kurz fest:</p>
<ul>
<li>Unter Unix und Unix-ähnlichen Betriebssystemen haben Dateien und Verzeichnisse einen Besitzer</li>
<li>Nicht jeder FTP-Benutzer kann auf alle Dateien und Verzeichnisse zugreifen</li>
<li>Die Zugriffe auf Dateien und Verzeichnisse werden durch Zugriffsrechte geregelt</li>
<li>Läuft PHP als Apache-Modul, so hat der Server einen eigenen &#8220;Benutzernamen&#8221; und hat dementsprechend auch Besitzrechte an den von ihm angelegten Dateien und Verzeichnisse.</li>
</ul>
<h3>Was passiert beim Upload?</h3>
<p>Wenn wir nun versuchen Dateien oder Verzeichnisse in unser Blog hochzuladen, dann muss WordPress erst einmal feststellen wie es dies bewerkstelligen kann. Die einfachste Methode wäre natürlich WordPress würde die Daten einfach mal so auf dem Server ablegen. Genau genommen versucht WordPress dies auch, lässt es aber meistens aus Sicherheitsgründen sein. Um festzustellen ob WordPress die Daten direkt auf den Server speichern kann, schreibt es eine kleine Testdatei. Danach prüft WordPress ob der FTP-Benutzer mit dem Dateibesitzer der Testdatei übereinstimmt.<br />
Im Fall von php-cgi stimmen die Besitzrechte überein und WordPress kann ohne weitere Nachfrage weiter machen.<br />
Im Fall von PHP als Modul hat die Testdatei jedoch den Server als Besitzer und nicht den FTP-Benutzer. WordPress entscheidet sich in diesen Fall dagegen die Daten direkt auf den Server zu schreiben und sucht nach einer anderen Methode.</p>
<p>Natürlich stellt sich jetzt die Frage warum WordPress nicht doch einfach die Daten auf den Server ablegt. Der Grund liegt in den Zugriffsrechten und und einer Sicherheitslücke die sich (theoretisch) daraus ergibt.<br />
Stellen wir uns mal vor <em>Benutzer A</em> und <em>Benutzer B</em> haben auf dem <em>Webserver C</em> jeweils einen Webspace gemietet. Alle Dateien und Verzeichnisse die von <em>Benutzer A</em> angelegt werden, können auch nur von <em>Benutzer A</em> gelesen und beschrieben werden. Genauso verhält es sich mit den Dateien und Verzeichnissen von <em>Benutzer B</em>. Was ist aber mit den Dateien und Verzeichnissen von &#8220;<em>Benutzer C</em>&#8220;? <em>Benutzer C</em> wäre in diesem Fall der Webserver. Und wenn der Webserver im Webspace von <em>Benutzer A</em> eine Datei anlegt, dann ist der Webserver der Besitzer dieser Datei. Da sich <em>Benutzer A</em> und <em>B</em> einen Webserver teilen, hat <em>Benutzer B</em> theoretisch über den Webserver Zugriff auf die Dateien im Webspace von <em>Benutzer A</em>, die vom Webserver angelegt wurden. Theoretisch könnte <em>Benutzer B</em> also den Webserver anweisen Dateien die er im Webspace von <em>Benutzer A</em> angelegt hat, auszulesen und im Webspace von <em>Benutzer B</em> zu kopieren. Möglich wäre dies, da der Webserver als Dateibesitzer ja die nötigen Rechte dazu hat.<br />
Dies ist eine eher theoretische Sicherheitslücke. Theoretisch deshalb, da auf einen vernünftig konfigurierten Server so etwas nicht möglich sein sollte. Der Server sollte so konfiguriert sein, dass kein Benutzer auf Dateien oder Verzeichnisse außerhalb seines Webspaces zugreifen kann. Andernfalls könnte jeder Benutzer auch problemlos die Konfigurationsdateien des Webservers manipulieren.<br />
Doch grau ist alle Theorie, die Praxis hat schon andere Fälle hervor gebracht. Und genau deswegen geht WordPress auf Nummer sicher und zieht es vor die Daten nicht direkt auf den Server abzulegen sofern es unter PHP als Apache-Modul läuft.</p>
<p>Kurz zusammen gefasst: Stellt WordPress fest das es nicht mit den gleichen Benutzernamen wie der FTP-Benutzer läuft, weigert es sich schlichtweg die Daten direkt auf den Server zu schreiben um nicht eine Sicherheitslücke bei den Zugriffsberechtigungen zu öffnen.</p>
<h3>Und es nervt doch</h3>
<p>Da PHP als Apache-Modul sehr verbreitet ist, werden auch viele WordPress-Nutzer regelmäßig nach ihren FTP-Zugangsdaten gefragt. FTP ist die zweite Variante mit der WordPress die Daten auf den Server bekommt. Dazu tut WordPress einfach so, als sei es der FTP-Benutzer unter dem der Blog angelegt wurde und der rechtmäßig Zugriff auf alle Dateien hat. Somit werden die Daten nicht mit dem FTP-Benutzer &#8220;nobody&#8221; (oder PHP-Run, oder PHP, oder oder oder) geschrieben, sondern mit dem von uns angegebenen Benutzernamen und Passwort.</p>
<p>Wer nur selten Daten auf seinen Server kopiert, den wird es nicht stören ab und an mal seine FTP-Daten anzugeben. Es gibt aber so einige Fälle wo es doch sehr nervig werden kann. Als Entwickler schiebt man ständig zu Testzwecken Daten auf den Server und löscht sie dort wieder. Das man auch beim Löschen von Daten die FTP-Zugangsdaten angeben muss, dürfte mittlerweile klar sein. Denn WordPress kann aufgrund der fehlenden Zugriffsberechtigungen nicht als Benutzer &#8220;PHP-Run&#8221; auf die Daten von FTP-Benutzer &#8220;Horst4711&#8243; zugreifen.<br />
Manchmal ist es aber auch einfach zu unbequem die FTP-Zugangsdaten, die sich natürlich kaum einer merkt weil das Passwort kryptisch³ ist, raus zu suchen. Und manchmal hat ausgerechnet der Mitarbeiter die FTP-Zugangsdaten, der gerade in Kambodscha Urlaub macht und nicht erreichbar ist.</p>
<p>Für solche Fälle gibt es einige Möglichkeiten die FTP-Zugangsdaten direkt in WordPress zu hinterlegen. Alle Möglichkeiten haben ihre Vor- und Nachteile. Einige sind sogar, m.E. nach, ein wenig gefährlich.</p>
<h3>Speichern ist einfacher als raus suchen</h3>
<p>Ab Werk kann man WordPress seine FTP-Daten also nur per Formular übergeben. Wer häufig unterwegs ist und sich dementsprechend genauso häufig in ungesicherte WLAN-Netzwerke einloggt (oder einloggen muss), wird immer ein mulmiges Gefühl haben wenn er die FTP-Zugangsdaten ungesichert quer durch die Bahnhofshalle zum Router schicken muss. Gerade wenn es um Kunden-Server geht ist hier etwas Vorsicht geboten. Falls jetzt jemand die Idee hat SSL wäre ja eine Lösung, der hat im Prinzip Recht. Jedoch denken die meisten Kunden da ganz anders. Wenn SSL extra kostet, dann braucht man das nicht. So denken zumindest die meisten Kunden.<br />
Diese Lösung hat allerdings auch einen Vorteil. Legt man auf dem Server für jeden Admin einen FTP-Konto an, so kann <em>Admin B</em> nicht aus versehen (oder mit voller Absicht) die Dateien und Verzeichnisse von <em>Admin A</em> löschen oder überschreiben.</p>
<h4>wp-config</h4>
<p>Die erste Alternative zur Übertragung via Formular wäre die FTP-Zugangsdaten in der <code>wp-config.php</code> abzulegen. Dazu stellt WordPress drei Konstanten bereit: <code>FTP_HOST</code>, <code>FTP_USER</code> und <code>FTP_PASS</code>. Die Namen sprechen für sich und es dürfte klar sein für was die einzelnen Konstanten stehen. Wer mehr über die Konstanten von WordPress erfahren will, sollte mal einen Blick bei <a title="Google+ Profil von Dominik Schilling" href="https://plus.google.com/101675293278434581718">Dominik Schilling</a> (G+ Profil)  rein werfen. Er hat eine <a title="WP-Grafie, WP-Konstanten" href="http://wpgrafie.de/195/wordpress-konstanten/#dateisystem">umfangreiche Auflistung alle Konstanten</a>.<br />
Beispiel:</p>
<pre class="brush:php">// defining the ftp-account data
if( ! defined( 'FTP_HOST' ) )
  define( 'FTP_HOST', 'meine-dmoain.de' );

if( ! defined( 'FTP_USER' ) )
  define ( 'FTP_USER', 'Horst4711' );

if( ! defined( 'FTP_PASS' ) )
  define( FTP_PASS', '&amp;SchmierMaxe$0815!' );</pre>
<p>Man sieht schon wo hier das Problem liegen könnte. Das Passwort liegt unverschlüsselt in einer PHP-Datei von der so ziemlich jeder Hacker weiß das dort was zu holen ist. Auf der anderen Seite steht in der selben Datei aber auch das Passwort für die Datenbank, ebenfalls unverschlüsselt. Man kann jetzt so oder so argumentieren. Die einen sind der Meinung das eh Hopfen&amp;Malz verloren ist wenn die <code>wp-config.php</code> geknackt ist. Die anderen sagen das man einen Hacker nicht noch freien FTP-Zugang zum Server geben muss wenn er sich schon die Datenbank unter den Nagel gerissen hat.<br />
Diese Methode spart auf alle Fälle die lästige Tipparbeit und man muss, sofern man mit mehren Mitarbeitern an einen Blog arbeitet, die FTP-Zugangsdaten nicht jedem aufs Auge drücken. Irgendwo gibt es immer einen der Zugangsdaten auf einen PostIt schreibt und diesen dann irgendwo vergisst oder verliert.<br />
Hier wird deutlich das WordPress eigentlich ein Single-User-System ist dem man notdürftig eine Benutzerverwaltung aufgepflanzt hat. Denn so kann jeder Benutzer mit Admin-Rechten auf alle Dateien und Verzeichnisse zugreifen. Ob nun gewollt oder ungewollt. Es ist durchaus denkbar das <em>Admin B</em> ein Verzeichnis löscht oder überschreibt das von <em>Admin A</em> angelegt wurde und das auf gar keinen Fall gelöscht oder überschrieben werden durfte.</p>
<h4>FS_METHOD</h4>
<p>Eine andere Alternative zum Formular besteht darin, WordPress dazu zu zwingen die Daten direkt auf den Server zu schreiben. Indem man die Konstante <code>FS_METHOD</code> auf <code>direct</code> setzt, lässt man WordPress erst gar nicht dazu kommen auszuwählen ob es die Daten direkt oder per FTP auf den Server schreibt.<br />
In meinen Augen ein Fauxpas sofern man dies auf einen Shared-Host anwendet. Für die möglichen Gefahren, siehe oben.<br />
Nun ist aber nicht jedes Blog auf einen Shared-Host angelegt. Wer stolzer Besitzer eines eigenen Servers ist, kann diese Methode durchaus dazu nutzen den FTP-Upload zu umgehen. Wenn es auf dem ganzen Server nur einen FTP-Benutzer gibt, gibt es auch keinen zweiten der unberechtigt auf die Dateien zugreifen kann. Wobei man diese Aussage ein wenig relativieren muss. Denn als Apache-Modul ausgeführt, ist der Webserver natürlich auch ein FTP-Benutzer. Durch setzen der Konstante <code>FS_METHOD</code> auf <code>direct</code>, werden alle Dateien und Verzeichnisse mit dem Besitzer &#8220;Webserver&#8221; (oder so ähnlich) erstellt. Das kann in sofern problematisch werden, wenn in einem Plugin oder Theme &#8220;versehentlich&#8221; etwas wie <code>exec( "rm -rf /" );</code> drin steht. Dann werden halt mal alle Dateien und Verzeichnisse die vom aktuellen Benutzer, sprich Webserver, angelegt wurden, gelöscht. Ohne Rückfrage versteht sich. Aber auch ein <code>unlink()</code> kann an der falschen Stelle mit dem falschen Pfad ausreichend Schaden anrichten.<br />
Ein weiteres Problem dürfte zwar nur selten auftreten, ist mir persönlich aber durchaus schon mal passiert. Daten die vom Webserver geschrieben worden sind konnte ich als FTP-Benutzer nicht mehr löschen. Sicherlich auch eine Sache der Server-Konfiguration, man sollte aber vor Einsatz dieser Alternative erst einmal ausprobieren ob man denn die Daten die der Webserver geschrieben hat auch wieder löschen kann. Das Selektive Löschen einzelner Dateien oder Verzeichnisse kann sich dann sehr mühsam gestalten.</p>
<p>Die Konstante <code>FS_METHOD</code> kann jedoch auch sehr nützlich sein. Wir erinnern uns an php-cgi bei dem alle Daten unter dem Benutzernamen geschrieben werden. WordPress muss unter php-cgi nicht nachfragen ob es die Methode &#8220;<em>direct</em>&#8221; oder &#8220;<em>ftp</em>&#8221; benutzen soll, dadurch kann es gleich loslegen. Das ist vielleicht aber gar nicht immer erwünscht. Mit <code>FS_METHOD</code> können wir WordPress auch dazu zwingen FTP als Methode zu verwenden und jedes mal Benutzernamen und Passwort (und Hostname) abzufragen. Für Blogs die unter php-cgi laufen also ein kleiner Workaround wie man ganz einfach eine Authentifizierung vor dem Schreiben/Löschen von Daten erzwingen kann.</p>
<pre class="brush:php">/*
 * force users to use ftp
 *
 * use 'ftpext' for using Apache FTP Extension
 * use 'ftpsockets' for ftp-sockets (Socket-Class or PHP-Extension)
 *
 */

if( ! defined( 'FS_METHOD' ) )
  define( 'FS_METHOD', 'ftpext' );</pre>
<p>Obwohl ich hier nur mehr oder minder die Oberfläche angekratzt habe, sieht man schon wie komplex die gesamte Thematik ist. Gänzlich ausgeklammert habe ich z.B. die ganze Thematik um SSH/SSL, SFTP und das WordPress-Filesystem sowieso. Das ist genug Stoff für weitere drei oder vier Artikel.</p>
<h3>Eine Plugin-Lösung</h3>
<p>Meiner Philosophie zur Folge muss ein Blogartikel nicht komplett und vollständig sein, sondern vielmehr zum Nachdenken, Experimentieren und vor allem Diskutieren anregen. Sicherlich gibt es den einen oder anderen Aspekt den ich übersehen, falsch oder missverständlich dargestellt habe oder der mehr Interesse geweckt hat als der Artikel bedienen kann.<br />
Genauso halte ich es auch mit meinen Plugins. Keine fertige Allroundlösung mit allen erdenklichen Features, sondern ein Lösungsansatz für ein Problem. Das folgende Plugin liegt in der Version <strong>0.1</strong> vor, ist also der erste Entwurf und eher ein PoC (Proof of Concept). Sowohl Artikel als auch Plugin sind beide an einen Tag entstanden, dementsprechend unausgiebig wurde das Plugin von mir getestet. Ich bitte dies beim Ausprobieren zu berücksichtigen.</p>
<h4>FTP-Account to UserMeta</h4>
<p>Dieses Plugin macht in etwa genau das was der (uninspiriert gewählte) Name aussagt. Es speichert die FTP-Zugangsdaten in den Benutzer-Daten des jeweiligen Benutzers. Damit sind zwei Anforderungen die im Laufe des Artikels aufgetaucht sind erledigt. Zum einen, und wichtigsten, muss man die FTP-Zugangsdaten nicht mehr ständig eintippen. Einmal im Benutzerprofil eingegeben stehen sie ab dann immer zur Verfügung wenn WordPress diese anfordert. Zum anderen können mehrere FTP-Benutzer ihre Daten hinterlegen da für jeden Benutzer separate FTP-Zugangsdaten gespeichert werden. Dadurch kann z.B. verhindert werden das <em>Benutzer A</em> die Dateien von <em>Benutzer B</em> versehentlich löscht, das Plugin kommt also aus der Ecke &#8220;Betreutes Bloggen&#8221;.</p>
<p>Das Plugin hinkt noch an der einen oder anderen Stelle. So werden die FTP-Passwörter (noch) im Klartext in der Datenbank gespeichert. Es sollte aber kein Problem darstellen eine entsprechende Ver- und Entschlüsselung nachzurüsten.<br />
Auch fehlt noch die Unterstützung für SFTP/SSL da mir hierfür derzeit die nötige Umgebung fehlt (ja, ich habe weder SSL noch sonst was auf meinen lokalen Server. Nicht mal mod_ftp). Gegen Bereitstellung von etwas Platz auf einen entsprechenden Server mit SSL/SFTP bin ich gerne bereit das zu ändern <img src="http://yoda.neun12.de/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" />  Ansonsten muss man halt warten bis ich das auf meinem lokalen Server nachgerüstet habe.</p>
<p>Die Bedienung des Plugins ist recht simple. Nach der Installation und Aktivierung werden im Benutzerprofil drei Felder für FTP-Hostname, FTP-Benutzername und FTP-Passwort hinzugefügt. Sind die drei Felder ausgefüllt und wird das Profil aktualisiert, verschwindet ab diesen Zeitpunkt für diesen Benutzer die Aufforderung seine FTP-Zugangsdaten einzugeben sofern diese erforderlich sind. Alle anderen Benutzer die FTP benutzen können aber keine Zugangsdaten hinterlegt haben, werden weiterhin aufgefordert ihre Zugangsdaten bei Bedarf einzugeben.<br />
<a class="highslide" onclick="return hs.expand(this)"  href="http://yoda.neun12.de/wp-content/uploads/2012/05/ftp2um.png"><img class="alignleft size-thumbnail wp-image-68" title="FTP2UM im Backend" src="http://yoda.neun12.de/wp-content/uploads/2012/05/ftp2um-150x150.png" alt="" width="150" height="150" /></a>Die Kontrolle darüber welche Benutzer überhaupt die drei Felder zu sehen bekommen, erfolgt hardcodiert im Plugin selber. Voreingestellt sind Administratoren (Role administrator), was wahrscheinlich am meisten Sinn macht. Es können aber auch andere Rollen bzw. Fähigkeiten (Capabilities) angegeben werden, womit eine recht feine Einstellung möglich ist wer seine FTP-Zugangsdaten eingeben kann.<br />
Damit nach der Deinstallation des Plugins keine sensiblen Daten in der Datenbank verbleiben, werden diese bei der Deinstallation (nicht deaktivierung!) gelöscht. Sofern man das Plugin also über das Backend entfernt, kann man es gefahrlos ausprobieren.</p>
<p>Das Plugin findet ihr auf <a title="FTP2UM on GitHub" href="https://github.com/RalfAlbert/WordPress-FTP-Account-to-UserMeta">Github</a>. Für diejenigen die es nicht so mit Git haben, als <a title="FTP 2 UM V0.1.2" href="https://github.com/downloads/RalfAlbert/WordPress-FTP-Account-to-UserMeta/WordPress-FTP-Account-to-UserMeta_0.1.2.zip">Zip-Datei</a>. Die anderen dürfen gerne <a title="Fork FTP2UM" href="https://github.com/RalfAlbert/WordPress-FTP-Account-to-UserMeta/fork">forken</a>, pullen und commiten.</p>
<h4>Update</h4>
<p>Da das Plugin auf  einiges Interesse gestoßen ist, habe ich den Code mal etwas bereinigt und glatt gezogen. Neue Funktionen sind in <a title="Version 0.1.2" href="https://github.com/downloads/RalfAlbert/WordPress-FTP-Account-to-UserMeta/WordPress-FTP-Account-to-UserMeta_0.1.2.zip">dieser Version (v0.1.2)</a> nicht hinzugekommen, dafür aber die eine oder andere Funktion für die nächsten Versionen notiert. Es wird sicherlich noch das eine oder andere umgesetzt werden, da ich hierdurch auch die Möglichkeit bekomme verschiedene Sachen auszuprobieren und ggf. darüber etwas zu schreiben.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-66/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Quick-Tipp: Schnell-Login</title>
		<link>http://yoda.neun12.de/artikel-52</link>
		<comments>http://yoda.neun12.de/artikel-52#comments</comments>
		<pubDate>Sun, 15 Jan 2012 05:34:41 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Code-Snippets]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=52</guid>
		<description><![CDATA[Hin und wieder gibt es das Bedürfnis sich ohne Angabe von Benutzername und Passwort einzuloggen. Das könnte z.B. der Fall sein wenn man automatisierte Tests durchführen möchte die einen Login benötigen. Oder aber man muss zum Testen immer wieder den Benutzer wechseln um verschiedene Szenarien durchzuspielen. Aber auch wenn man sich in einer eher &#8220;unsicheren [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Hin und wieder gibt es das Bedürfnis sich ohne Angabe von Benutzername und Passwort einzuloggen. Das könnte z.B. der Fall sein wenn man automatisierte Tests durchführen möchte die einen Login benötigen. Oder aber man muss zum Testen immer wieder den Benutzer wechseln um verschiedene Szenarien durchzuspielen.<br />
Aber auch wenn man sich in einer eher &#8220;unsicheren Umgebung&#8221; befindet (z.B. schlecht abgesichertes öffentliches Netzwerk) möchte man vielleicht nicht so gerne seine Login-Daten eintippen. Es wäre also ganz praktisch wenn man sich (automatisiert) einloggen kann ohne ständig Login-Daten einzutippen.</p>
<p>WordPress lässt sich relativ einfach dazu bringen Login-Daten automatisiert anzunehmen. In erster Linie ist die Funktion <code>wp_signon()</code> dafür zuständig den Login durchzuführen. Dazu übergibt man ihr Benutzername und Passwort, die Funktion gibt daraufhin <code>true</code> zurück bzw. ein WordPress-Fehler-Objekt. Dies kann man bequem mit <code>is_wp_error()</code> abfragen und so mit nur wenigen Zeilen einen Login durchführen.<div class="gistem"><div id="gist-1529022" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cp">&lt;?php</span></div><div class='line' id='LC2'><span class="k">require</span><span class="p">(</span> <span class="nb">dirname</span><span class="p">(</span><span class="k">__FILE__</span><span class="p">)</span> <span class="o">.</span> <span class="s1">&#39;/wp-load.php&#39;</span> <span class="p">);</span></div><div class='line' id='LC3'><span class="nx">is_wp_error</span><span class="p">(</span></div><div class='line' id='LC4'>	<span class="nx">wp_signon</span><span class="p">(</span></div><div class='line' id='LC5'>		  <span class="k">array</span><span class="p">(</span></div><div class='line' id='LC6'>			<span class="s1">&#39;user_login&#39;</span><span class="o">=&gt;</span><span class="s1">&#39;YourLoginName&#39;</span><span class="p">,</span></div><div class='line' id='LC7'>			<span class="s1">&#39;user_password&#39;</span><span class="o">=&gt;</span><span class="s1">&#39;YoUrAw3s0M3P455W0rD&#39;</span></div><div class='line' id='LC8'>			<span class="p">)</span> </div><div class='line' id='LC9'>		 <span class="p">)</span></div><div class='line' id='LC10'><span class="p">)</span> <span class="o">?</span> <span class="k">die</span><span class="p">(</span><span class="s1">&#39;Mooo... :(&#39;</span><span class="p">)</span> <span class="o">:</span> <span class="nx">wp_safe_redirect</span><span class="p">(</span> <span class="nx">admin_url</span><span class="p">()</span> <span class="p">);</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1529022/41c58a4015161cb71154d1fdb3f0c91a4da5d0e1/quicklogin.php" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1529022#file_quicklogin.php" style="float:right;margin-right:10px;color:#666">quicklogin.php</a>
            <a href="https://gist.github.com/1529022">This Gist</a> is brought to you using <a href="http://en.bainternet.info/2011/simple-gist-embed"><small>Simple Gist Embed</small></a>.
          </div>
        </div>
</div>
</div><style type="text/css">@import "http://gist.github.com/stylesheets/gist/embed.css"; .gistem .highlight {background: inherit; !important;}</style></p>
<p>Speichert man den Code in einer separaten Datei ab, so muss zuerst <code>wp-load.php</code> eingebunden werden um die WordPress-Funktionen verfügbar zu machen. Hier bitte auf den Pfad achten, iom Gist liegt die Datei im gleichen Verzeichnis wie <code>wp-load.php</code>.  Danach wird direkt <code>wp_signon()</code> mit einem Array aus Benutzername und Passwort gefüttert, welches wiederum direkt als Parameter an <code>is_wp_error()</code> übergeben wird.<br />
Durch Aufruf der Datei ist man direkt eingeloggt und wird ins Backend umgeleitet. Möchte man lieber ins Frontend umgeleitet werden, so ersetzt man einfach <code>admin_url()</code> durch <code>site_url()</code>.</p>
<p>Ich habe mir für meine Entwicklungsarbeit ein kleines Plugin geschrieben mit dem ich recht schnell zwischen verschiedenen Benutzern hin- und her wechseln kann. Dazu listet mir das Plugin auf der Login-Seite die Test-User auf, welche ich zuvor angelegt habe. Durch einen Klick auf einen entsprechenden User-Namen kann ich mich dann ohne Eingabe von Benutzername und Passwort anmelden. Auf Optik habe ich verzichtet, da es ein Werkzeug bei der Entwicklung ist. Wer mag, kann dem ganzen ja noch ein bisschen optischen Feinschliff verpassen.<br />
Das Plugin <a title="WP-Quicklogin" href="https://github.com/RalfAlbert/WP-Quicklogin">WP-Quicklogin</a> ist auf Github zu finden.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-52/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance ist nicht gleich Performance</title>
		<link>http://yoda.neun12.de/artikel-54</link>
		<comments>http://yoda.neun12.de/artikel-54#comments</comments>
		<pubDate>Fri, 06 Jan 2012 18:10:44 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=54</guid>
		<description><![CDATA[Ich bin kein großer Fan von Performance-Tests, dass sage ich gleich vorweg. Der Grund ist schlichtweg der, dass man vergleichbare Umgebungen voraussetzen muss um die Ergebnisse übertragbar zu machen. Wenn ich Plugin auf System A teste, rennt es noch wie doof. Teste ich es aber auf System B, hinkt und hakt es wie ein lahmer [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Ich bin kein großer Fan von Performance-Tests, dass sage ich gleich vorweg. Der Grund ist schlichtweg der, dass man vergleichbare Umgebungen voraussetzen muss um die Ergebnisse übertragbar zu machen. Wenn ich Plugin auf System A teste, rennt es noch wie doof. Teste ich es aber auf System B, hinkt und hakt es wie ein lahmer Gaul.<br />
Der Grund dafür liegt in der Optimierung der Systeme, sofern sie optimiert sind. Als Beispiel möchte ich nur die Anbindung an den MySQL-Server nennen. Hier gibt es etliche verschiedene Konfigurationen für die unterschiedlichsten Anwendungsfälle. Werden viele kleine Datensätze abgefragt, optimiert man den MySQL-Server anders als wenn man ihn für wenige große Datensätze benötigt. Somit würde das gleiche Plugin auf beiden Systemen unterschiedlich performant sein, alleine deshalb weil die Anbindung an die Datenbank anders ist.<br />
Nicht viel anders sieht es beim Server selber aus. Auch hier gibt es unzählige Optimierungsvarianten. Hinzu kommt noch unterschiedliche Server-Software, Betriebssysteme auf denen der Server läuft bis hin zu der Hardware die einen sehr wesentlichen Teil der Performance ausmacht. Wie soll man da einen gemeinsamen Nenner finden den man als Grundlage des Vergleichs heranziehen kann?</p>
<p>Viele Tests messen einfach das, was man einfach messen kann. Das wäre dann z.B. der Speicherverbrauch. Dann wird auch gerne die Ausführungszeit gemessen, was aber aufgrund der unterschiedlichen Systeme schon kaum noch Aussagekraft hat. Reicht das alles nicht, kommen gerne noch so obskure Faktoren wie Codezeilen oder Anzahl der verwendeten Hooks und Filter hinzu.<br />
Selten bis gar nicht wird die Code-Qualität bewertet. Dies ist für mich aber ein sehr wichtiges Kriterium. Denn ein schlampig programmiertes Plugin läuft oft auch schlampig, wirft Fehlermeldungen und ist nicht zukunftssicher. Häufig sieht man Plugins die über die Jahre gewachsen sind bis der Autor selber den Überblick verliert. Entweder wird das Plugin dann von Grund auf neu programmiert und weiter gepflegt. Oder aber, was häufiger vorkommt, man lässt das Plugin so wie es ist und kümmert sich nicht mehr darum.<br />
Nun ist Code-Qualität nicht ganz so einfach zu &#8220;messen&#8221;. Man muss den Code bewerten und hierzu eine Reihe von Kriterien heranziehen. das kostet Zeit und Mühe, weshalb es wohl niemand macht. Ein Kriterium wären zum Beispiel die Übersichtlichkeit. Das kann eigentlich jeder bewerten der sich den Code anschaut. Oder aber auch ob der Code ein Wust aus wilden Zeilen darstellt die kaum entzifferbar sind. Ist der Code gut kommentiert damit auch jemand der nicht so viel Ahnung von Programmierung hat versteht was da vor sich geht. Hält der Code sich an gewisse Programmierrichtlinien. Nur um mal einige wenige Kriterien zu nenne die man verwenden kann.<br />
All das kann man mit Noten bewerten, sogar relativ objektiv. Nun werden einige sagen &#8220;<em>Hauptsache es rennt!</em>&#8220;. Das ist natürlich auch ein Argument. Also zieht man noch die Anzahl an Fehlern, Notices usw. heran die das Plugin wirft wenn man es einsetzt. Auch grausam geschriebener Code kann fehlerfrei laufen. So kommt man schon zu einen recht guten und nachvollziehbaren Ergebnis.<br />
Kennt man sich bei der Programmierung ein wenig besser aus, dann kann man auch noch einzelne Code-Abschnitte genauer unter die Lupe nehmen. Ist der Code gemäß den empfohlenen Vorgaben geschrieben? Wenn nicht, macht es Sinn von den Vorgaben abzuweichen? Gibt es &#8220;merkwürdige&#8221; Programmiertechniken im Code oder ist alles auf den ersten Blick verständlich?</p>
<p>Für mich sind dies deutlich wichtigere Faktoren als Millisekunden Laufzeit und Megabyte Speicherverbrauch. Denn dies sind Faktoren die ich erklären kann, so dass auch jemand der weniger Ahnung hat versteht wie ich zu meinen Testergebnis gekommen bin. Und vor allem wird schnell deutlich wo noch Potenzial für Verbesserungen besteht. Code der leicht verständlich ist, wird auch gerne von anderen gepflegt, so dass er sich recht schnell verbreitet und mit der Zeit (hoffentlich) besser wird.</p>
<p>Ein ziemlich merkwürdiger Test macht hingegen gerade auf <a title="G+" href="https://plus.google.com/110569673423509816572/posts/bdbhLMhuaBU">Google+</a> die Runde. Es geht um den <a title="Dev4Press" href="http://www.dev4press.com/2012/blog/benchmark/plugins-performance-testing-2012-january/">Plugin-Test von MillaN</a>. <a title="Sergej Müller" href="http://ebiene.de/">Sergej Müller</a> hat sich wohl zurecht gefragt wie MillaN auf seine Ergebnisse kommt. Getestet wurden 35 Plugins aus den unterschiedlichsten Kategorien und mit einem Wert von 1 (schlecht) bis 5 (sehr gut) bewertet. Nur wie dieser Wert zustande kommt, bleibt vielen vollkommen unergründlich.<br />
Vielleicht ist weniger Speicherverbrauch besser als mehr? Also <a title="FPW Post Instructions" href="http://wordpress.org/extend/plugins/fpw-post-instructions/">FPW Post Instructions</a> bekommt eine 4 bei einem konstanten Speicherverbrauch von 0,1MB. GD Press Tools Pro verbraucht zwar 29 mal so viel Speicher (2,9MB), bekommt aber die Bestnote 5. Es scheint also etwas mit dem Speicherverbrauch im Frontend bzw. Backend zu tun zu haben. Denn GD Press Tools Pro verbraucht im Frontend &#8220;nur&#8221; 2MB Speicher, während FPW Post Instructions sowohl vorne wie hinten den gleichen Speicherverbrauch hat. So wirklich schlüssig ist das Konzept jedoch nicht. Denn <a title="WP Event Manager" href="http://wp-events-plugin.com/">Event Manager</a> bekommt die schlechteste Note 1 bei einem Speicherverbrauch von 5 bzw 3,7MB (Front-/Backend). GD Custom Posts And Taxonomies Tools Lite bekommt für die gleiche Leistung (1,5/1,3MB) eine noch ganz gute 4 verpasst. Event Manager ist also schlechter obwohl es mehr Speicher einspart?<br />
Ich könnte jetzt noch weiter rätseln ob es vielleicht an der Ausführungszeit liegt oder an der Anzahl der verwendeten Hooks. Vielleicht auch am Mondstand beim Test des Plugins. Man weiß es nicht und der Autor trägt auch nicht zur Aufklärung bei.</p>
<blockquote><p>Grade 2 plugins have only some elements of optimization, but they are close to grade 1. Adminimize plugin shouldn’t even load on the front end except for some elements, and that needs to be optimized.</p></blockquote>
<p>Das soll also der Grund sein warum einige Plugins schlechter sind als andere? Adminimize soll z.B. im Frontend nur das laden was es benötigt, was es im Prinzip auch macht, dies sollte aber optimiert werden? Hö? Es scheint also darum zu gehen was ein Plugin im Front- bzw. Backend lädt. Da ist es wohl egal welche Aufgabe es hat, wenn es nicht den geheimen Richtlinien des Autors entspricht, ist es schlecht.</p>
<p>Na dann schauen wir uns doch mal eins dieser supertollen Grade-5 Plugins an. Ich habe mich für GD Unit Converter entschieden und es mal unter die Lupe genommen. Was mir beim ersten Blick auffiel, waren folgende Codezeilen:</p>
<pre class="brush:php">$this-&gt;script = $_SERVER["PHP_SELF"];
$this-&gt;script = end(explode("/", $this-&gt;script));</pre>
<p>Und? Sinn erkannt? Also ich habe erst mal längere Zeit gerätselt was da passiert bis ich den Code kopiert und getestet habe. OK, ich schreibe es mal ein wenig um:</p>
<pre class="brush:php">$this-&gt;script = basename(__FILE__);</pre>
<p>So einfach kann PHP sein. Der nächste Horror folgt sofort:</p>
<pre class="brush:php">    private function plugin_path_url() {
        $this-&gt;plugin_url = plugins_url("/gd-unit-converter/");
        $this-&gt;plugin_path = dirname(dirname(__FILE__))."/";

        define("GDUNITCONVERTER_URL", $this-&gt;plugin_url);
        define("GDUNITCONVERTER_PATH", $this-&gt;plugin_path);
    }</pre>
<p>Da werden also zwei globale Variablen definiert die zwanzig Zeilen später bei einem <code>wp_enqueue_script()</code> wieder verwendet werden. Klar, man hätte auch einfach auf <code>$this-&gt;plugin_url</code> zurück greifen können (OOP, u know!?). Aber warum sparsam mit dem Speicher umgehen wenn man doch so schön sinnlos welchen durch Verwendung globaler Variablen verschwenden kann?<br />
Ach ja. Weil man anderen gerne vorschreibt sie sollen doch bitte schön sparsam mit dem Speicher umgehen:</p>
<blockquote><p>I am sure that many developers will say that these results are not important, but considering that most of the WordPress users are on shared hosting with limited memory and resources available to them, this is most important thing to have plugins they need and still have server running fine.</p></blockquote>
<p>Also Wasser predigen und Wein saufen. Contactform 7 bekommt übrigens nur eine schwache 2, dafür aber eine extra Erwähnung:</p>
<blockquote><p>All tested plugins, but one, used the internal WordPress AJAX handling. Contact Form 7 uses own handler and that is not something I can recommend. Using WP handler is best solution considering that it is already written with security concerns in mind and it is very easy to use, making plugin fit better with WP development concepts.</p></blockquote>
<p>Muss ich extra erwähnen das GD Unit Converter seinen eigenen Caching-Mechanismus mitbringt und mal ganz elegant auf den in WordPress bereits eingebauten Caching-Mechanismus pfeift?<br />
Natürlich darf auch der eigene Logger nicht fehlen, der zwar nicht genutzt wird aber dennoch geladen werden muss (require_once). Über solch lustige Konstrukte wie folgenden wundert man sich dann schon gar nicht mehr.</p>
<pre class="brush:php">$js_url = defined("SCRIPT_DEBUG") &amp;&amp; SCRIPT_DEBUG ? "js/src/unit-converter.js" : "js/unit-converter.js";</pre>
<p>Wenn <code>SCRIPT_DEBUG</code> definiert ist, sollen die JavaScripte aus dem nicht vorhandenen Verzeichnis <code>js/src/</code> geladen werden. Das gibt lustige Fehlermeldungen wenn man sein Blog im Debug-Modus startet. So lustig, das man das Plugin sofort deaktiviert.</p>
<p>Es ist einfach schlau daher zu reden und dann selber solch einen Mist zu veröffentlichen. Gefühlt die Hälfte des Codes die das Plugin umfasst ist sinnlos, wird nicht benötigt, verstößt gegen Coding Guidelines oder ist schlichtweg Speicherverschwendung. Hier sollte der Herr MilanN vielleicht selber noch mal Hand anlegen und das Plugin um fluffige 90% Code reduzieren bevor er ihm die Bestnote 5 verpasst. Ich habe mich vorhin mal eine Stunde lang hingesetzt und versucht das Plugin von Scratch (also ohne Vorlage) nachzubauen. Nach einer Stunde hatte ich bereits brauchbare Ergebnisse und kam mit einem Zehntel an Code aus. Der Speicherverbrauch dürfte noch sparsamer sein, da ich nicht total unnützes Zeug lade, sondern mich darauf beschränke das zu nutzen, was ich benötige.</p>
<p>Solche Tests die nicht klar machen wie eine Bewertung zu Stande kommt und bei denen der Autor sich die Testbedingungen so zurecht biegt das er sich selbst Bestnoten verpassen kann, kann man getrost außer Acht lassen. Hier muss sich jeder selber fragen wie objektiv der Test sein kann wenn die eigenen Plugins den Maßstab vorgeben. Da sollte man sich als Autor nicht wundern wenn andere einen auf den Zahn fühlen und zeigen wo der Mops die Locken hat.</p>
<h3>Fazit</h3>
<p><em>Gute Tests sind objektiv und vergleichen nicht eigene Arbeit mit der von Fremden.</em> Wird die eigene Arbeit dennoch im Test mit einbezogen, dürfen die Testkriterien nicht auf die eigene Optimierung hin zugeschnitten sein.<br />
<em>Die Testkriterien sollten klar und verständlich sein.</em> Was man als Leser nicht nachvollziehen kann, ist nichts wert. Ist es fraglich wie eine Bewertung zu Stande gekommen ist, ist der ganze Test wertlos. <a title="Texto" href="http://www.texto.de/plugin-performance-ich-kapiers-nicht-1323/">Moinka Thon-Soun hat auf Texto</a> in einen Artikel beschrieben wie ein schlecht gemachter Test auf einen Laien wirkt. Nämlich verwirrend, sonst nichts.<br />
<em>Die Tests sollten nachprüfbar sein.</em> Dazu müssen Testscripte zugänglich sein und die Testumgebung erläutert werden.<br />
<em>Test sollten nicht auf einen einzelnen Aspekt fokussiert sein.</em> Jeder Test hat einen Schwerpunkt, dies rechtfertigt jedoch nicht eine schlechte Bewertung weil ein Testkandidat eben nicht genau den Schwerpunkt trifft. Ein guter Tests umfasst mehrere Aspekte und bildet aus den Einzelergebnissen eine Bewertung. Jedes Plugin hat seine Stärken und Schwächen. Ein Plugin das optisch gut gestylt daher kommt, verbraucht eben mehr Speicher (mehr Grafiken, mehr CSS, mehr Code) als ein Plugin welches sehr spartanisch gestaltet ist. Was nützt einem aber ein Plugin das am falschen Ende spart, wenn es durch seinen Purismus nur schwer bedienbar ist?<br />
<em>Tests sollten sich auf das beschränken, was unter anderen Systemen ähnliche (vergleichbare) Ergebnisse liefert.</em> Eine systemunabhängiger Wert sind z.B. Fehlermeldungen (auch Notices und Deprecated Meldungen) . Die werden auf jeden System gleich sein, denn falsch ist hier wie da falsch.<br />
<em>Test sollten realitätsnah sein.</em> Im Labor gelten andere Regeln als in der Wildnis. Selbst wenn ein Plugin im Test wunderbar abschneidet, kann es dadurch versagen das es andere Plugins behindert oder gar komplett ausschaltet. Man kann nicht alle Kombinationen von Plugins prüfen, jedoch gibt es eine Reihe von Regeln für ein friedliches Miteinander die man beachten sollte.</p>
<p>Also bitte nicht jeden Test blauäugig Glauben schenken. Lieber einmal mehr als einmal zu wenig an den Ergebnissen zweifeln. Wir wissen doch alle: Die Statistik die man selber gefälscht hat, ist immer noch die beste <img src="http://yoda.neun12.de/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /> </p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-54/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Login-Name des Autoren verschlüsseln</title>
		<link>http://yoda.neun12.de/artikel-29</link>
		<comments>http://yoda.neun12.de/artikel-29#comments</comments>
		<pubDate>Fri, 11 Mar 2011 14:38:02 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Code-Snippets]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Sicherheit]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=29</guid>
		<description><![CDATA[Klaus stört es das der Login-Name des Autors bei den Post-Metadaten im Link erscheint. Das ist jetzt etwas schwurbelig ausgedrückt, für eine genauere Erklärung einfach beim Klaus nachlesen was er meint. Manchmal bin ich pingelig und mich stört so etwas auch. Logindaten egal welcher Art haben in Links und anderen öffentlich zugänglichen Bereichen einfach nichts [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a title="Login-Name in den Post-Metadaten" href="http://webdesign-passau.com/wordpress/wp-3-sicherheitsluecke-ausgabe-loginname/" target="_blank">Klaus</a> stört es das der Login-Name des Autors bei den Post-Metadaten im Link erscheint. Das ist jetzt etwas schwurbelig ausgedrückt, für eine genauere Erklärung einfach beim Klaus nachlesen was er meint.</p>
<p>Manchmal bin ich pingelig und mich stört so etwas auch. Logindaten egal welcher Art haben in Links und anderen öffentlich zugänglichen Bereichen einfach nichts zu suchen. Das widerspricht auch der Idee das man neben den Login-Namen auch noch zwei andere Namen in seinem Profil angeben kann und auswählen kann welchen Namen man gerne öffentlich verwenden möchte.</p>
<h3>Der Workaround</h3>
<p>Um das Problem zu lösen gibt es einen Workaround und eine Möglichkeit mit Filtern zu arbeiten. Zuerst der Workaround. WordPress bietet nämlich die Möglichkeit für jeden Autoren eine eigene Autoren-Seite anzulegen. Dieses Template wird zuerst gezogen bevor das allgemeine Template für alle anderen Autoren verwendet wird. Anders ausgedrückt: Existiert für den Autor X ein spezielles Template, wird dieses verwendet. Existiert kein solches Template, dann wird das allgemeine Template verwendet.<br />
Dabei sucht WordPress in folgender Reihenfolge nach einem passenden Template:</p>
<ol>
<li><code>author-{autor-name}.php</code></li>
<li><code>author-{autor-ID}.php</code></li>
<li><code>author.php</code></li>
</ol>
<p>Ist der Login-Name des Autoren z.B. &#8220;Klaus&#8221; und existiert ein Template <code>author-klaus.php</code>, wird zuerst dieses Template verwendet. Dies hilft uns in diesem Fall jedoch nicht weiter, da weiterhin der Login-Name verwendet wird.<br />
Jedoch kann man auch die ID des Autoren verwenden. Existiert ein Template author-12.php und hat der Autor &#8220;Klaus&#8221; die ID 12, dann wird dieses Template verwendet. Ändert noch nichts daran das im Link immer noch der Login-Name erscheint.<br />
Um dies zu ändern, greift man in das Template ein in dem die Funktion get_author_posts_url() verwendet wird. Das ist von Theme zu Theme leider immer etwas unterschiedlich, je nach dem wo die Metadaten zum Post ausgegeben werden. Diesen Funktionsaufruf ersetzt man nun mit diesem Monster:</p>
<pre class="brush:php">str_replace(
  get_the_author_meta( 'user_nicename' ),
  get_the_author_meta( 'ID' ),
  get_author_posts_url( get_the_author_meta( 'ID' ) )
)</pre>
<p>Damit ersetzt man den Login-Namen (user_nicename) durch die ID des Autoren. Nun benötigt man noch ein Template <code>author-xy.php</code> wobei <code>xy</code> die jeweilige ID des Autoren ist.</p>
<p>Das ganze ist ein Workaround der nur sehr begrenzt einsatzfähig ist. Man muss jedes mal am Theme rumfummeln, die ganze Sache ist nicht wirklich übersichtlich und am Ende benötigt man auch noch für jeden Autoren ein eigenes Template. Eignet sich also normalerweise nur für Blogs in denen es 1-2 Autoren gibt und die eher selten ihr Theme wechseln.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-29/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress und die Localization</title>
		<link>http://yoda.neun12.de/artikel-6</link>
		<comments>http://yoda.neun12.de/artikel-6#comments</comments>
		<pubDate>Fri, 07 Jan 2011 00:09:56 +0000</pubDate>
		<dc:creator><![CDATA[Ralf]]></dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Tipps&Tricks]]></category>

		<guid isPermaLink="false">http://yoda.neun12.de/?p=6</guid>
		<description><![CDATA[Im Grunde genommen ist es eine feine Sache das man in WordPress Themes und Plugins mit relativ wenig Aufwand in eine andere Sprache übersetzen kann. Man muss lediglich darauf achten beim schreiben des Themes bzw. Plugins die Texte in einem bestimmten Format auszugeben und schon kann man unter zuhilfenahme von Programmen wie z.B. poEdit das [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Im Grunde genommen ist es eine feine Sache das man in WordPress Themes und Plugins mit relativ wenig Aufwand in eine andere Sprache übersetzen kann. Man muss lediglich darauf achten beim schreiben des Themes bzw. Plugins die Texte in einem bestimmten Format auszugeben und schon kann man unter zuhilfenahme von Programmen wie z.B. poEdit das Theme oder Plugin in eine andere Sprache übersetzen ohne es neu zu schreiben.</p>
<p>Im Grunde genommen bedeutet hier aber, dass es nur auf den ersten Blick so einfach zu sein scheint. Wer sich schon mal mit den Thema Übersetzung von Plugins oder Themes beschäftigt hat, der wird früher oder später die vielen kleinen Haken zu spüren bekommen. Einer dieser kleinen Haken ist der, dass WordPress einen grundlegenden Unterschied bei der Einbindung von Übersetzungen macht. <code>load_theme_textdomain()</code> ist, wie der Name vermuten lässt, für Themes zuständig, während <code>load_plugin_textdomain()</code> für Plugins zuständig ist. Es ist schon mal auffällig das es für die gleiche Aufgabe zwei verschiedene Funktionen gibt. Also schauen wir doch mal in die Core-Datei wo der Unterschied bei diesen beiden Funktionen liegt.</p>
<p>Beide Funktionen finden wir in <code>wp-includes/l10n.php</code>. Beide Funktionen erwarten bei ihren Aufruf die Übergabe einer Domain und eines Pfades. Im Falle von <code>load_plugin_textdomain()</code> können sogar zwei verschiedenen Arten von Pfaden angegeben werden, wobei der absolute relative Pfad veraltet ist und nicht mehr verwendet werden sollte.<br />
Bei genauerer Betrachtung fällt aber auf, dass <code>load_theme_textdomain()</code> bei der Pfadangabe deutlich toleranter ist als <code>load_plugin_textdomain()</code>. Ist kein Pafd angegeben, so verwendet <code>load_theme_textdomain()</code> das Verzeichnis des aktuellen Templates als Pfad. Ansonsten könnte man den Pfad auch sonstwohin zeigen lassen, es würde noch funktionieren.<br />
<code>load_plugin_textdomain()</code> ist da etwas strikter. Egal ob man einen Pfad angibt oder nicht, es wird auf jeden Fall <code>WP_PLUGIN_DIR</code>, also der Pfad zum Plugin-Verzeichnis, im Pfad eingefügt.<br />
Mit <code>load_theme_textdomain()</code> könnte man also auch eine Sprachdatei benutzen die in <code>wp-content</code> steht. Mit <code>load_plugin_textdomain()</code> wäre dies unmöglich.</p>
<p>Nun sind Pfadangaben in WordPress eine Sache für sich an die man sich gewöhnen und mit denen man umzugehen lernen kann. Deutlich mehr Kopfschmerzen bereitete mir in der Vergangenheit ein Umstand, den ich irgendwie nicht verstehe. Und zwar das Format nach dem die Sprachdateien benannt werden müssen.<br />
<code>load_theme_textdomain()</code> erwartet das die Sprachdatei lediglich aus der Locale und der Endung .mo besteht. Also z.B. de_DE.mo oder en_EN.mo. <code>load_plugin_textdomain()</code> hingegen erwartet zu der Locale noch zusätzlich die Domaine als Teil des Dateinamens. Die Datei muss also das Format domain-locale.mo haben.<br />
Für mich recht unverständlich und letzten Endes kann dies auch zu Problemen führen. Denn ändert sich im Plugin die Domaine, z.B. nach einem Update, dann können auch die (alten) Sprachdateien nicht mehr geladen werden. Man müsste also entweder alle Domainen im Plugin ändern oder alle Sprachdateien umbennenen.</p>
<p>Aber man sollte auch immer die Vorteile im Auge behalten. Durch die Verwendung der Domaine im Dateinamen der Sprachdatei kann man auf recht einfache Weise z.B. zwischen der Du- und der Sie-Form wechseln. Etwas was für deutsche Übersetzungen ja nicht ganz unerheblich ist.<br />
Dazu legt man einfach z.B. eine Sprachdatei mit den Namen <code>pluginname_du_form-de_DE.mo</code> und eine mit den Dateinamen <code>pluginname_sie_form-de_DE.mo</code> an. Im Plugin selber kann man mittels <code>define('MeinePluginDomain', 'plugin_xx_form');</code> eine Konstante definieren die dann in den Übersetzungsfunktionen verwendet wird (z.B. <code>__('This example text', MeinePluginDomain)</code>). Je nachdem ob xx nun &#8216;du&#8217; oder &#8216;sie&#8217; ist, schaltet man zwischen Du- und Sie-Form um.</p>
<p>Jetzt hat man aber ein Problem mit Sprachen die nicht zwischen Du und Sie unterscheiden. Mit Englisch zum Beispiel. Denn man müsste nun für jede Sprache zwei Sprachdateien anfertigen. Einmal <code>plugin_du_form-en_EN.mo</code> und einmal <code>plugin_sie_form-en_EN.mo</code>.<br />
Das ganze gestaltet sich an diesen Punkt als etwas zu aufwendig um schön zu sein. Es gibt aber auch eine Lösung für das Problem. Wir benötigen ja eigentlich nur eine Funktion die in einem Verzeichnis nachschaut ob es eine Sprachdatei nach dem Format domaine-locale.mo gibt und diese lädt. Gibt es eine solche Sprachdatei nicht, wird halt eine Sprachdatei nach den Format locale.mo geladen. Gibt es diese auch nicht, wird halt nichts übersetzt.<br />
Nebenbei erledigt sich mit solch einer Funktion das leidige Pfad-Problem. Die Sprachdateien können nun quasi an einen beliebigen Ort abgelegt werden. Ob dies Sinn macht, sei an dieser Stelle mal dahin gestellt.</p>
<p>Hier erst einmal die Funktion:</p>
<pre class="brush:php">function flexible_loadtextdomain( $path = false, $domain = 'default' ){

  if( ! $path || ! is_dir( $path ) )

    return false;

  global $l10n;

  $local = get_locale();

  $mofile = $path . $domain . '-' . $local . '.mo';

  // try to find a matching translation

  // first try domain-locale.mo

    if( ! file_exists( $mofile ) ){

    // if not found, try only locale.mo

    $mofile = str_replace( $domain . '-', '', $mofile );

      if( ! file_exists( $mofile ) ){

        // if even this failed, throw an error or do something wired

        return false;

      }

    }

  load_textdomain( $domain, $mofile );

  return isset( $l10n[ $domain ] );

}</pre>
<p>Die Funktion erwartet zwei Parameter. Zum einen eine Pfadangabe und zum anderen den Namen der Domain. Die erste If-Abfrage sorgt dafür das überhaupt ein Pfad übergeben wird und das es auch ein Verzeichnis ist. Anstatt einfach nur false zurück zu geben, kann man hier natürlich noch weitere Spielereien unter bringen indem man z.B. einen Pfad vorgibt (<code>WP_PLUGIN_DIR</code> oder <code>get_template_directory</code>).<br />
Der Rest ist das was ich oben schon beschrieben habe. Erst domain-locale.mo suchen, wenn nicht gefunden locale.mo suchen, wenn das auch nicht gefunden irgendwas verrücktes machen, zum Beispiel false zurück geben.<br />
In der letzten Zeile wird dann noch geprüft ob die Domain erfolgreich geladen wurde. Ab WP 3.0 kann man dies durch <code>return load_textdomain(...)</code> abkürzen. In älteren Versionen muss man diesen kleinen Umweg gehen da <code>load_textdomain</code> keine Erfolgsmeldung zurück gibt.</p>
<p>Der Code der Funktion ist ein wenig abgespeckt. Will man es ganz sauber programmieren, dann würde man noch ein paar Sachen anders machen, z.B. nicht <code>$locale = get_locale();</code> verwenden, sondern <code>$locale = apply_filters( 'xyz', get_locale(), $domain );</code> (xyz = theme_locale oder plugin_locale, je nachdem ob man die Funktion in einem Theme oder Plugin verwendet).</p>
<p>Vielleicht ist dieser Beitrag ja eine kleine Anregung für alle die Themes oder Plugins schreiben.</p>
]]></content:encoded>
			<wfw:commentRss>http://yoda.neun12.de/artikel-6/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
