<?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>Testbild</title>
	<atom:link href="http://blog.visusnet.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.visusnet.de</link>
	<description></description>
	<lastBuildDate>Tue, 11 May 2010 19:34:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ich bin T-Shirt-geil</title>
		<link>http://blog.visusnet.de/2010/05/11/ich-bin-t-shirt-geil/</link>
		<comments>http://blog.visusnet.de/2010/05/11/ich-bin-t-shirt-geil/#comments</comments>
		<pubDate>Tue, 11 May 2010 19:34:37 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=774</guid>
		<description><![CDATA[Das habe ich ja letztens schon bewiesen, als ich via 3DSupply an ein Shirt gekommen bin. Jetzt gibt es wieder eine aehnliche Aktion, aber diesmal von einer mir zuvor unbekannten Firma: CustomGarment. Die Sache ist die: Die Jungs von CustomGarment schenken mir ein Shirt, wenn ich schreibe, wie cool die sind. Und jeder, der mir [...]]]></description>
			<content:encoded><![CDATA[<p>Das habe ich ja letztens schon bewiesen, als ich via 3DSupply an ein Shirt gekommen bin. Jetzt gibt es wieder eine aehnliche Aktion, aber diesmal von einer mir zuvor unbekannten Firma: <a href="http://www.customgarment.de/" target="_blank">CustomGarment</a>. Die Sache ist die: Die Jungs von CustomGarment schenken mir ein Shirt, wenn ich schreibe, wie cool die sind. Und jeder, der mir ein Shirt schenkt ist sau cool. So einfach ist das. CustomGarment&#8217;s Aktion heisst uebrigens <a href="http://www.customgarment.de/content/Shirt-vs-Link.html">Shirt vs. Link</a>.</p>
<p>Welches T-Shirt ich absahnen moechte? <a href="http://www.customgarment.de/products/Herren-T-Shirts/Geek-and-Nerd/Evolution-T-Shirt.html">Dieses</a>.<a href="http://www.customgarment.de/products/Herren-T-Shirts/Geek-and-Nerd/Evolution-T-Shirt.html"></a></p>
<p>Ein paar Worte zu CustomGarment:</p>
<ul>
<li>Ab 3 Artikeln gibt es keine Versandkosten mehr!</li>
<li>Die Farbauswahl ist groesser als bei der Konkurrenz!</li>
<li>Es gibt Qualitaetsshirts (z.B. Fruit of the Loom)!</li>
<li>Man kann mit PayPal zahlen (ja, das kann man laengst noch nicht ueberall)!</li>
<li>Es gibt sogar Baby-Kleidung (Laetzchen, Shirts, &#8230;)!</li>
</ul>
<p>@CustomGarment: Danke!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/05/11/ich-bin-t-shirt-geil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Jeder hat seinen Preis&#8230;</title>
		<link>http://blog.visusnet.de/2010/04/21/jeder-hat-seinen-preis/</link>
		<comments>http://blog.visusnet.de/2010/04/21/jeder-hat-seinen-preis/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 09:11:43 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=768</guid>
		<description><![CDATA[&#8230; so auch ich! 3Dsupply hat mich bestochen. Ich bekomme ein Shirt, wenn ich euch erzaehle, wie toll die sind.
Und wieso sind die toll? Ehm. 3Dsupply nutzt Twitter? &#8230; Vielleicht deswegen. 3Dsupply schreibt sogar die Konkurrenz ueber Twitter an und unterhaelt sich freundlich? Ja, vielleicht auch deswegen. Aber hauptsaechlich wohl wegen den ganzen Aktionen, von [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; so auch ich! <a href="http://www.3dsupply.de">3Dsupply</a> hat mich bestochen. Ich bekomme ein Shirt, wenn ich euch erzaehle, wie toll die sind.</p>
<p>Und wieso sind die toll? Ehm. 3Dsupply nutzt Twitter? &#8230; Vielleicht deswegen. 3Dsupply schreibt sogar die Konkurrenz ueber Twitter an und unterhaelt sich freundlich? Ja, vielleicht auch deswegen. Aber hauptsaechlich wohl wegen den ganzen Aktionen, von denen ich meist immer erst dann etwas mitbekomme, wenn die Deadline schon abgelaufen ist. Naja, diesmal war ich schnell, denn die Nachricht, dass jetzt wieder eine Aktion stattfindet, habe ich um 10:15:52 Uhr heute bei Twitter empfangen.</p>
<p>Natuerlich will jetzt auch jeder wissen, welches Shirt ich mir ausgesucht habe. Und hier ist es:</p>
<p><a href="http://www.3dsupply.de/products/422-war-for-oil/24-bc-exact-190-schwarz/"><img class="aligncenter size-full wp-image-770" title="Jeder hat seinen Preis..." src="http://blog.visusnet.de/wp-content/uploads/waroil.png" alt="" width="387" height="375" /></a></p>
<p>Und nur um sicherzugehen, dass ihr auch auf Dauer wisst, wie cool 3Dsupply ist, verlinke ich sie sogar in meiner Sidebar.</p>
<p>Zu guter Letzt: Wieso dieses Shirt? Weil ich ein Mensch bin, der sich gerne mit gesellschaftskritischen Shirts schmueckt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/04/21/jeder-hat-seinen-preis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Eclipse / Lines of Code Plugin</title>
		<link>http://blog.visusnet.de/2010/04/02/eclipse-lines-of-code-plugin/</link>
		<comments>http://blog.visusnet.de/2010/04/02/eclipse-lines-of-code-plugin/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 15:35:59 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=762</guid>
		<description><![CDATA[Ich halte mich mal kurz: Es waere cool, wenn man in der Status Line von Eclipse sehen koennte, wieviele Zeilen Code das aktuelle Projekt/Paket/die aktuelle Datei hat. Da mir nicht bekannt ist, dass es ein solches Feature irgendwo gibt, habe ich es mir als Plugin gebaut.
Und hier ist es: de.visusnet.eloc_1.0.0.0.jar und sieht ungefaehr so aus:

Installation

Herunterladen.
In [...]]]></description>
			<content:encoded><![CDATA[<p>Ich halte mich mal kurz: Es waere cool, wenn man in der Status Line von Eclipse sehen koennte, wieviele Zeilen Code das aktuelle Projekt/Paket/die aktuelle Datei hat. Da mir nicht bekannt ist, dass es ein solches Feature irgendwo gibt, habe ich es mir als Plugin gebaut.</p>
<p>Und hier ist es: <a href="http://blog.visusnet.de/wp-content/uploads/de.visusnet.eloc_1.0.0.0.jar">de.visusnet.eloc_1.0.0.0.jar</a> und sieht ungefaehr so aus:</p>
<p><a href="http://blog.visusnet.de/wp-content/uploads/eloc.png" title="Eclipse / Lines of Code Plugin" rel="lightbox[762]"><img class="aligncenter size-full wp-image-764" title="Eclipse / Lines of Code Plugin" src="http://blog.visusnet.de/wp-content/uploads/eloc.png" alt="" width="362" height="61" /></a></p>
<p><strong>Installation</strong></p>
<ol>
<li>Herunterladen.</li>
<li>In path/to/eclipse/plugins schieben.</li>
<li>Eclipse mit dem Argument -clean neustarten, damit der Plugin-Cache neugeladen wird.</li>
</ol>
<p><strong>Hinweise</strong></p>
<ul>
<li>Es funktioniert nur mit Eclipse, nicht mit Eclipse-Derivaten (z.B. Zend Studio), da diese einen eigenen Project-Explorer verwenden, dessen ID, die innerhalb der Equinox Service Registry verwendet wird, nicht publiziert wurde und der Zugriff daher nicht moeglich ist.</li>
<li>-clean sollte nicht in die eclipse.ini (dauerhaft) geschrieben werden, da Eclipse dann jedesmal laenger zum Starten braucht.</li>
<li>Der Quellcode befindet sich im Archiv.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/04/02/eclipse-lines-of-code-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Bit of Awesomeness</title>
		<link>http://blog.visusnet.de/2010/03/18/a-bit-of-awesomeness/</link>
		<comments>http://blog.visusnet.de/2010/03/18/a-bit-of-awesomeness/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 21:34:55 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=758</guid>
		<description><![CDATA[&#8230; habe ich durch Babel gesehen und er hat es wohl von MC Winkels weBlog. Ab geht&#8217;s!
(Bitte den Artikel &#246;ffnen, um die Flashdatei oder den Flashplayer zu sehen.)
]]></description>
			<content:encoded><![CDATA[<p>&#8230; habe ich durch <a href="http://blog.visusnet.de">Babel</a> gesehen und er hat es wohl von <a href="http://www.whudat.de/">MC Winkels weBlog</a>. Ab geht&#8217;s!</p>
<p><object type="application/x-shockwave-flash" data="http://www.youtube.com/v/8i7u3fl-hP8" width="425" height="355" class="embedflash"><param name="wmode" value="opaque" /><param name="movie" value="http://www.youtube.com/v/8i7u3fl-hP8" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><small>(Bitte den Artikel &ouml;ffnen, um die Flashdatei oder den Flashplayer zu sehen.)</small></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/03/18/a-bit-of-awesomeness/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Waffen machen frei</title>
		<link>http://blog.visusnet.de/2010/03/17/waffen-machen-frei/</link>
		<comments>http://blog.visusnet.de/2010/03/17/waffen-machen-frei/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 22:18:07 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=751</guid>
		<description><![CDATA[Das denkt sich wohl zur Zeit unser WaffenVerteidigungsminister zu Guttenberg oder wie erklaert ihr euch die zufaelligen Beschwerden aus den Reihen der Bundeswehr ueber zu wenig Personal und zu wenig Geld?
Das hat doch ganz bestimmt nichts mit einer Ablenkung von der Kunduz-Affaere zu tun? Und das hat doch auch ganz bestimmt nichts damit zu tun, [...]]]></description>
			<content:encoded><![CDATA[<p>Das denkt sich wohl zur Zeit unser <strike>Waffen</strike>Verteidigungsminister zu Guttenberg oder wie erklaert ihr euch die zufaelligen Beschwerden aus den Reihen der Bundeswehr ueber zu wenig Personal und zu wenig Geld?</p>
<p>Das hat doch ganz bestimmt nichts mit einer Ablenkung von der Kunduz-Affaere zu tun? Und das hat doch auch ganz bestimmt nichts damit zu tun, dass wir bald Waffen brauchen, um uns gegen die anderen EU Laender durchsetzen zu koennen, weil <a href="http://www.heise.de/tp/r4/artikel/32/32266/1.html">Deutschland auf Kosten aller anderen lebt</a>?</p>
<p>Das geht nicht mehr lange gut. Und der Hochverraeter Karl-Theodor Maria Nikolaus Johann Jacob Philipp Franz Joseph Sylvester Freiherr von und zu Guttenberg gehoert weggesperrt, nebst Westerwelle und dem Rest der wohl schlechtesten Regierung seit &#8216;49 (verglichen damit war Kohl der reine Segen).</p>
<p>Achja&#8230; Worauf ich noch hinaus wollte: Damit solche Verbrecher enttarnt werden koennen, versucht WikiLeaks seit mehreren Jahren erfolgreich eine Plattform zu bieten, auf der Whistleblower anonym Skandale und Verbrechen publizieren lassen koennen ohne politisch, wirtschaftlich, gesellschaftlich oder auf andere Weise verfolgt zu werden. Dieser Plattform haben wir es u.A. zu verdanken, dass wir Details ueber die Foltermethoden von Guantanamo, Zensursperrlisten einiger Laender und den Kunduz-Feldjaeger-Report zu Gesicht bekommen haben.</p>
<p>Leider kostet der Betrieb von WikiLeaks sehr viel Geld, da nur so die Sicherheit der Whistleblower sichergestellt werden kann. Also wenn ihr ein paar Euronen uebrig habt: <a href="http://wikileaks.org/#Change_you_can_believe_in">Spendet!</a>. Wenn ihr euch bei Spenden denkt, dass ihr davon ja nichts habt, dann kauft euch ein <a href="http://www.getdigital.de/products/Wikileaks_Support">WikiLeaks T-Shirt bei getDigital.de</a>, denn 5 EUR pro Shirt gehen an WikiLeaks.</p>
<div id="attachment_753" class="wp-caption aligncenter" style="width: 250px"><a href="http://www.getdigital.de/products/Wikileaks_Support"><img class="size-full wp-image-753" title="WikiLeaks T-Shirt von getDigital.de" src="http://blog.visusnet.de/wp-content/uploads/t2_wikileaks.jpg" alt="" width="240" height="312" /></a><p class="wp-caption-text">WikiLeaks T-Shirt von getDigital.de</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/03/17/waffen-machen-frei/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Identifikation und Authentifikation in RESTful APIs</title>
		<link>http://blog.visusnet.de/2010/03/10/identifikation-und-authentifikation-in-restful-apis/</link>
		<comments>http://blog.visusnet.de/2010/03/10/identifikation-und-authentifikation-in-restful-apis/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 04:07:06 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=745</guid>
		<description><![CDATA[Ja, viele von euch (srsly?) haben sicher schon einmal ein (semi) RESTful API entwickelt. Ein haeufiges Problem ist herauszufinden, ob ein Aufruf auch durchgefuehrt werden darf. Das Problem besteht darin, dass wir es dabei mit einem zustandslosen Protokoll (RFC 2616) zu tun haben, also fallen die Elgamal- und Diffie-Hellman-Kryptosysteme aus.
Um nun festzustellen, ob die Person [...]]]></description>
			<content:encoded><![CDATA[<p>Ja, viele von euch (srsly?) haben sicher schon einmal ein (semi) RESTful API entwickelt. Ein haeufiges Problem ist herauszufinden, ob ein Aufruf auch durchgefuehrt werden darf. Das Problem besteht darin, dass wir es dabei mit einem zustandslosen Protokoll (<a href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>) zu tun haben, also fallen die <a href="http://de.wikipedia.org/wiki/Elgamal-Kryptosystem">Elgamal</a>- und <a href="http://de.wikipedia.org/wiki/Diffie-Hellman-Schl%C3%BCsselaustausch">Diffie-Hellman-Kryptosysteme</a> aus.</p>
<p>Um nun festzustellen, ob die Person (bzw. eine Applikation, stellvertretend fuer eine Person), die die Anfrage sendet auch wirklich die Person ist, fuer die sie sich ausgibt (Identifikation) und um gleichzeitig festzustellen, ob die Anfrage nicht manipuliert wurde (Authentifikation), gibt es zum einen das freie <a href="http://oauth.net/core/1.0a/">OAuth Protokoll</a>, was aber relativ kompliziert zu implementieren ist, und zum anderen gibt es aehnliche Ansaetze, wie zum Beispiel das <a href="http://www.flickr.com/services/api/auth.spec.html">Flickr Auth Protokoll</a>. Beide Protokolle bieten ausserdem die Moeglichkeit externen Programmen (Clients) den Zugriff auf das System (Service Provider) zu authorisieren.</p>
<p>Sofern letzteres nicht noetig ist, reicht jedoch ein abgespecktes Protokoll, das dem Flickr Protokoll sehr nah kommt. Hierbei faellt der Aufwand der sicheren Schluesseluebertragung weg. Und so einfach kann es gehen:</p>
<ul>
<li>Der Service Provider generiert einen oeffentlichen Schluessel (API Key) und einen privaten Schluessel (Secret). Ich habe fuer den oeffentlichen Schluessel die SHA1 Pruefsumme verschiedener Variablen und fuer den privaten Schluessel die MD5 Pruefsumme von Variablen, Zufallszahlen und Timestamps genutzt.</li>
<li>Der Client wird mit beiden Keys ausgestattet. Wie gesagt: Der unwiretapped Schluesselaustausch muss anders sichergestellt werden. Bei meinem System kann der Benutzer die Keys einsehen, wenn er sich zuvor mit seinen Zugangsdaten eingeloggt hat. Das ist auch gaengige Praxis.</li>
<li>Bei einer Anfragegenerierung werden die Variablen inkl. oeffentlichem Schluessel (die Bezeichner, nicht die Werte!) alphabetisch sortiert und dann mit ihrem Wert konkateniert. Dann werden die Key-Value-Strings konkateniert und der private Schluessel wird vorangestellt. Das Ganze wird jetzt gehasht (e.g. MD5). Nun werden alle Variablen und die zusaetzlich generierte signature-Variable uebertragen.</li>
<li>Der Service Provider empfaengt alle Variablen, nimmt davon den oeffentlichen Schluessel und sucht in seiner Datenbank nach dem dazu passenden privaten Schluessel. Jetzt kann der Service Provider das selbe Spiel spielen, das der Client schon durchgemacht hat: Variablen sortieren, Key-Value-Strings bauen, konkatenieren, den privaten Schluessel voranstellen und hashen. Der Vergleich der uebermittelten Signatur und der generierten Signatur erlaubt die Authentifizierung des Zugriffs.</li>
</ul>
<p><strong>Beispiel</strong></p>
<p>Der API Key ist fd40e3589bbb58ec358122c5cd32fcc6481707bb, das Geheimnis ist 162c9d446beb754b804b904772ff87b6. Die Variablen sind (Bezeichner = Wert):</p>
<ul>
<li>method = deleteEntries</li>
<li>rangeFrom = 99</li>
<li>rangeTo = 101</li>
</ul>
<p>Die Anfrage wird nun wie folgt Client-seitig generiert:<br />
Sortieren:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">apiKey vor method vor rangeFrom vor rangeTo</pre></div></div>

<p>Konkatenieren:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">apiKeyfd40e3589bbb58ec358122c5cd32fcc6481707bbmethoddeleteEntriesrangeFrom99rangeTo101</pre></div></div>

<p>Private Key voranstellen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">162c9d446beb754b804b904772ff87b6apiKeyfd40e3589bbb58ec358122c5cd32fcc6481707bbmethoddeleteEntriesrangeFrom99rangeTo101</pre></div></div>

<p>Hashen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">9ad5100448f0549472b0e70722aa06bb</pre></div></div>

<p>Variablen fuer die Anfrage zusammensetzen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">http://example.com/rest/?apiKey=fd40e3589bbb58ec358122c5cd32fcc6481707bb&amp;method=deleteEntries&amp;rangeFrom=99&amp;rangeTo=101&amp;signature=9ad5100448f0549472b0e70722aa06bb</pre></div></div>

<p>Das wird nun ausgefuehrt und auf der Service Provider Seite geht es dann so weiter:<br />
API Key auslesen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">fd40e3589bbb58ec358122c5cd32fcc6481707bb</pre></div></div>

<p>In der Datenbank nach dem passenden privaten Schluessel suchen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">162c9d446beb754b804b904772ff87b6</pre></div></div>

<p>Sortieren, Konkatenieren, Private Key voranstellen, Hashen (s.o.):</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">9ad5100448f0549472b0e70722aa06bb</pre></div></div>

<p>Ergebnisse vergleichen:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">9ad5100448f0549472b0e70722aa06bb = 9ad5100448f0549472b0e70722aa06bb</pre></div></div>

<p>That&#8217;s it. Ist sehr einfach zu implementieren und ist dafuer extrem sicher.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/03/10/identifikation-und-authentifikation-in-restful-apis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Just Married: Zend Framework &amp; Flickr</title>
		<link>http://blog.visusnet.de/2010/03/09/just-married-zend-framework-flickr/</link>
		<comments>http://blog.visusnet.de/2010/03/09/just-married-zend-framework-flickr/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 20:12:02 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=739</guid>
		<description><![CDATA[Vorweg: Ich glaube dieser Post wird lang&#8230;
Also zur Zeit bastel ich an einem Projekt, das aus einigen Social Networks Daten beziehen und diese auf Public Displays anzeigen soll. Da nur-Text etwas oede ist, habe ich mich also an die Flickr API gesetzt. Eigentlich bietet das Zend Framework dafuer die Klasse Zend_Service_Flickr an, aber leider ist [...]]]></description>
			<content:encoded><![CDATA[<p>Vorweg: Ich glaube dieser Post wird lang&#8230;</p>
<p>Also zur Zeit bastel ich an einem Projekt, das aus einigen Social Networks Daten beziehen und diese auf Public Displays anzeigen soll. Da nur-Text etwas oede ist, habe ich mich also an die Flickr API gesetzt. Eigentlich bietet das Zend Framework dafuer die Klasse Zend_Service_Flickr an, aber leider ist die nicht dafuer ausgelegt Applikationen mit Flickr zu verbinden, sondern lediglich fuer eine direkte Benutzerauthentifizierung via Benutzername/Passwort.</p>
<p>Mein erster Ansatz war also erstmal in die API von Flickr zu schauen, denn die bietet ein OAuth aehnliches Verfahren zur Anwendungsauthentifizierung an. Der Trick war nun Zend_Service_Flickr damit zu verheiraten. Und so geht&#8217;s:</p>
<p>Als erstes registriert man eine Anwendung bei Flickr und richtet eine Callback URL ein. In meinem Fall wird damit die callbackAction meines FlickrControllers getriggert. Ich brauchte also einen FlickrController&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> FlickrController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> authenticateAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> callbackAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Die Authentifizierung laeuft so ab:</p>
<ol>
<li>Der Benutzer oeffnet die index-Seite. Dort ist ein Link zur authenticate-Seite, wenn alles nicht schon gelaufen ist.</li>
<li>Die authenticate-Action prueft zunaechst, ob die Anwendung bereits mit Flickr verknuepft ist. Wenn ja, dann wird zur index-Seite weitergeleitet. Wenn nein, dann wird eine Authentication Request URL gebaut und dorthin wird weitergeleitet.</li>
<li>Auf der Flickr-Seite muss der Benutzer der Anwendung nun den Zugriff erlauben. Ist das geschehen, wird der Benutzer von Flickr direkt zur callback-Seite geleitet. Flickr haengt dabei noch eine Variable mit dem Namen frob an.</li>
<li>Die callback-Action sendet daraufhin eine Anfrage an Flickr, die u.A. auch die frob-Variable enthaelt. Ausserdem wird eine Signatur angehangen.</li>
<li>Flickr antwortet mit einem Token, der dann gespeichert wird und fuer zukuenftige Calls verwendet wird.</li>
</ol>
<p>So, bevor ich alle mit Erklaerungen langweile: Jetzt kommt Code!</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SenScreen_Service_Flickr <span style="color: #000000; font-weight: bold;">extends</span> Zend_Service_Flickr
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_secret</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_perms</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_token</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">const</span> PATH_AUTH <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/services/auth/'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">const</span> PATH_REST <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/services/rest/'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setOptions<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span> <span style="color: #339933;">==</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$validOptions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'api_key'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'secret'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'perms'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_compareOptions<span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #339933;">,</span> <span style="color: #000088;">$validOptions</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'api_key'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiKey</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'api_key'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'secret'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_secret <span style="color: #339933;">=</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'secret'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'perms'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms <span style="color: #339933;">=</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'perms'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms <span style="color: #339933;">=</span> <span style="color: #0000ff;">'read'</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span> instanceof SenScreen_Service_Flickr_AuthToken<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_token <span style="color: #339933;">=</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setApiKey<span style="color: #009900;">&#40;</span><span style="color: #000088;">$apiKey</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiKey</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$apiKey</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getApiKey<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiKey</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setSecret<span style="color: #009900;">&#40;</span><span style="color: #000088;">$secret</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_secret <span style="color: #339933;">=</span> <span style="color: #000088;">$secret</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getSecret<span style="color: #009900;">&#40;</span><span style="color: #000088;">$secret</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_secret<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setPerms<span style="color: #009900;">&#40;</span><span style="color: #000088;">$perms</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms <span style="color: #339933;">=</span> <span style="color: #000088;">$perms</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getPerms<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setToken<span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_token <span style="color: #339933;">=</span> <span style="color: #000088;">$token</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAuthToken<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_token<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getApiSignature<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$plainSignature</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_secret<span style="color: #339933;">;</span>
        <span style="color: #990000;">ksort</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$plainSignature</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$plainSignature</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> _getSignedUrl<span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">URI_BASE</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$path</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'?'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$urlParams</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$urlParams</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$url</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$urlParams</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$url</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&amp;api_sig='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getApiSignature</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$url</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> redirect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'api_key'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiKey</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'perms'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$redirectUrl</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getSignedUrl<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">PATH_AUTH</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Location: '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$redirectUrl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getFrob<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'frob'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> requestToken<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'method'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'flickr.auth.getToken'</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'api_key'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">apiKey</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'frob'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFrob</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'perms'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_perms
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$httpClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Http_Client<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_getSignedUrl<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">PATH_REST</span><span style="color: #339933;">,</span> <span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$httpClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">resetParameters</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$httpClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setParameterGet</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$params</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$httpClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'Accept-encoding'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_parseToken<span style="color: #009900;">&#40;</span><span style="color: #000088;">$httpClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'GET'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> _parseToken<span style="color: #009900;">&#40;</span>Zend_Http_Response <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$xmlElement</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SimpleXMLElement<span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getBody</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> SenScreen_Service_Flickr_AuthToken<span style="color: #009900;">&#40;</span>
            <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$xmlElement</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">auth</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">token</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$xmlElement</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">auth</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">user</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'username'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$xmlElement</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">auth</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">user</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fullname'</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> isRestrictedMethod<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$restrictedMethods</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'flickr.photos.getContactsPhotos'</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$restrictedMethods</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> _execute<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$defaultOptions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_prepareOptions<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span><span style="color: #339933;">,</span> <span style="color: #000088;">$defaultOptions</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$restClient</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRestClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$restClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHttpClient</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">resetParameters</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$restClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">restGet</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/services/rest/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isError</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Zend_Service_Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'An error occurred sending request. Status code: '</span>
                                           <span style="color: #339933;">.</span> <span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadXML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$response</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getBody</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span>_checkErrors<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Service_Flickr_ResultSet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getContactsPhotos<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        static <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'flickr.photos.getContactsPhotos'</span><span style="color: #339933;">;</span>
        static <span style="color: #000088;">$defaultOptions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'count'</span>           <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'just_friends'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'single_photo'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'include_self'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'extras'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update.'</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_execute<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$defaultOptions</span><span style="color: #339933;">,</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getRecent<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        static <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'flickr.photos.getRecent'</span><span style="color: #339933;">;</span>
        static <span style="color: #000088;">$defaultOptions</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'per_page'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'page'</span>     <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
            <span style="color: #0000ff;">'extras'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'license, date_upload, date_taken, owner_name, icon_server, original_format, last_update.'</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_execute<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$defaultOptions</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Diese Klasse erweitert Zend_Service_Flickr, sodass diese auch mit Authentifizierung umgehen kann. Als naechstes muss der Zend_Http_Client ausgetauscht (bzw. erweitert) werden, sodass auch er mit Signaturen und dem Kram umgehen kann:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SenScreen_Service_Flickr_Http_Client <span style="color: #000000; font-weight: bold;">extends</span> Zend_Http_Client
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_flickr</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Accept-Encoding'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setFlickr<span style="color: #009900;">&#40;</span>SenScreen_Service_Flickr <span style="color: #000088;">$flickr</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr <span style="color: #339933;">=</span> <span style="color: #000088;">$flickr</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> request<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">isRestrictedMethod</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">paramsGet</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'method'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">paramsGet</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'auth_token'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAuthToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">paramsGet</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_merge</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">paramsGet</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'api_sig'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getApiSignature</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">paramsGet</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">request</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Als naechstes Brauchen wir noch eine Klasse, die unser Token aufbewahrt und serialisierbar in der DB ablegbar ist:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> SenScreen_Service_Flickr_AuthToken
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_token</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_username</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000088;">$_fullname</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fullname</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_token    <span style="color: #339933;">=</span> <span style="color: #000088;">$token</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_username <span style="color: #339933;">=</span> <span style="color: #000088;">$username</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_fullname <span style="color: #339933;">=</span> <span style="color: #000088;">$fullname</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getToken<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_token<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_username<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getFullname<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_fullname<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Und dann koennen wir endlich den Controller fuellen und jetzt kommen auch mal Kommentare in den Code, damit ich nicht mehr so viel quarken muss:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> FlickrController <span style="color: #000000; font-weight: bold;">extends</span> Zend_Controller_Action
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_config</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'api_key'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'myapplicationkey'</span><span style="color: #339933;">,</span>
        <span style="color: #0000ff;">'secret'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'mysecret'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    protected <span style="color: #000088;">$_flickr</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SenScreen_Service_Flickr<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$httpClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SenScreen_Service_Flickr_Http_Client<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$httpClient</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlickr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Zend_Rest_Client<span style="color: #339933;">::</span><span style="color: #004000;">setHttpClient</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$httpClient</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> indexAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$userId</span> <span style="color: #339933;">=</span> Zend_Auth<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIdentity</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">;</span>
        <span style="color: #009933; font-style: italic;">/**
         * Check whether the current user has an access
         * token for Flickr.
         */</span>
        <span style="color: #000088;">$userSettingModel</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model_UserSetting<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$userSettingModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userId</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'flickr_token'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #009933; font-style: italic;">/**
             * Get the access token.
             */</span>
            <span style="color: #000088;">$access_token</span> <span style="color: #339933;">=</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userSettingModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009933; font-style: italic;">/**
             * Configure the Flickr instance.
             */</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_merge</span><span style="color: #009900;">&#40;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_config<span style="color: #339933;">,</span>
                <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'token'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$access_token</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">contactPhotos</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getContactsPhotos</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'include_self'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'extras'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">showAuthenticationButton</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">view</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">showAuthenticationButton</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> authenticateAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$userId</span> <span style="color: #339933;">=</span> Zend_Auth<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIdentity</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
         * Check whether the current user has an access
         * token for Flickr.
         */</span>
        <span style="color: #000088;">$userSettingModel</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model_UserSetting<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$userSettingModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userId</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'flickr_token'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #009933; font-style: italic;">/**
             * Get the access token.
             */</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirector</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #009933; font-style: italic;">/**
             * The user is not authenticated with Flickr.
             * Request Flickr auth frob and redirect to
             * Flickr's authentication page.
             */</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_config<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> callbackAction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$userId</span> <span style="color: #339933;">=</span> Zend_Auth<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIdentity</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_config<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #009933; font-style: italic;">/**
         * Check whether a frob is present for this user.
         */</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFrob</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #009933; font-style: italic;">/**
             * A frob is present. Request a token and
             * save it in the database.
             */</span>
            <span style="color: #000088;">$token</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_flickr<span style="color: #339933;">-&gt;</span><span style="color: #004000;">requestToken</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$userSettingModel</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model_UserSetting<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$userSettingModel</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setUserId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$userId</span><span style="color: #009900;">&#41;</span>
                             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setKey</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'flickr_token'</span><span style="color: #009900;">&#41;</span>
                             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setValue</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$token</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
            <span style="color: #009933; font-style: italic;">/**
             * Everything is done, redirect to the index
             * page.
             */</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirector</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'flickr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #009933; font-style: italic;">/**
             * The callback has been called without having
             * a request token. Redirect to the index page.
             */</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_helper<span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirector</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'index'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'flickr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Sollte soweit selbsterklaerend sein. Viel Spass damit. <img src='http://blog.visusnet.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>Update:</strong><br />
Wie ihr vielleicht bemerkt habt, nutze ich das <a href="http://blog.visusnet.de/2010/03/05/abstract-data-mapper-pattern/">Abstract Data Mapper Design Pattern</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/03/09/just-married-zend-framework-flickr/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Abstract Data Mapper Pattern</title>
		<link>http://blog.visusnet.de/2010/03/05/abstract-data-mapper-pattern/</link>
		<comments>http://blog.visusnet.de/2010/03/05/abstract-data-mapper-pattern/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 23:22:29 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=725</guid>
		<description><![CDATA[Manchmal ist es frustrierend, wenn man mit dem Zend Framework arbeitet. Es kann zwar so ziemlich alles, aber die Dokumentation ist nicht besonders zu empfehlen. Darin wird zwar jedes leidige Thema angesprochen, jedoch nie in einem globaleren Kontext. Beispiel: PHP kann mit einer speziellen __autoload Funktion Klassen dynamisch aus Dateien laden, sofern sie benoetigt werden. [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal ist es frustrierend, wenn man mit dem <a href="http://framework.zend.com/">Zend Framework</a> arbeitet. Es kann zwar so ziemlich alles, aber die Dokumentation ist nicht besonders zu empfehlen. Darin wird zwar jedes leidige Thema angesprochen, jedoch nie in einem globaleren Kontext. Beispiel: PHP kann mit einer speziellen __autoload Funktion Klassen dynamisch aus Dateien laden, sofern sie benoetigt werden. Darauf basierend arbeiten Autoloader von Zend, die es verschiedene Aufgabenbereiche gibt. Die Dokumentation sagt nun, wie man Autoloader erzeugt. Es fehlen aber einige wichtige Informationen: Wo wird das gemacht, wieso wird das gemacht, welchen Nebeneffekte hat das und wie sieht ein Standard-Use Case aus? Es gibt natuerlich eine Begruendung dafuer, wieso die Dokumentation so anscheinend wichtige Dinge weglaesst: Das Zend Framework ist so konzipiert, dass man es auf beliebige Weise anwenden kann: Ob es als Model-View-Controller Framework oder fuer noch komplexeren Spaghetticode genutzt wird ist so ziemlich egal und diese Flexibilitaet ist durchaus erwuenscht. Best Practice sieht aber anders aus.</p>
<p><strong>Best Practice</strong></p>
<p>Zur Best Practise hat sich mittlerweile die auch von Zend Studio automatisch generierbare Model-View-Controller-Struktur gemausert. Dazu wird zunaechst eine Verzeichnisstruktur in folgender oder aehnlicher Weise mit einigen Standarddateien genutzt:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">application
    configs
        application.ini
    controller
        ErrorController.php
        IndexController.php
    models
    views
        scripts
            error
                error.phtml
            index
                index.phtml
    Bootstrap.php
public
    index.php</pre></div></div>

<p>Hierbei wird der Webserver so konfiguriert, dass die Domain auf das public-Verzeichnis zeigt. Dadurch wird vor allem die Sicherheit der Applikation erhoeht, da der Zugriff auf die einzelnen Dateien nicht mehr moeglich ist. Die Datei application.ini enthaelt die wichtigsten Informationen, die fuer das Deployment benoetigt werden. Das controller-Verzeichnis enthaelt alle Controller und das models-Verzeichnis enthaelt analog die Modellabstraktionen. Jeder Controller besitzt mindestens eine Action in Form einer Methode, mit der Namenskonvention <em>actionname</em>Action. Zu jedem Controller gibt es im views-Unterverzeichnis scripts ein Verzeichnis, in dem fuer jede Action eine Datei mit der Namenskonvention <em>actionname</em>.phtml vorliegt. Diese Dateien definieren die an den Client zurueckzusendenen Darstellungsinformationen.</p>
<p>Soweit so gut. Wenn Projekte wachsen wird man irgendwann anfangen das Gesamtsystem in kleine Haeppchen zu zerhacken. Divide and Conquer &#8211; Teile und herrsche. Wir (angehenden) Software Systems Engineers nennen sowas auch gerne Modularisierung. Das Zend Framework ist fuer diesen Fall natuerlich auch gewappnet und ermoeglicht es Module zu definieren, wobei jedes Modul eine Verzeichnisstruktur aufweist, die identisch zum application-Verzeichnis ist. Es muessen natuerlich nicht alle Verzeichnisse existieren, aber Minimum ist in den meisten Faellen controller, models und views. Fuer jedes Modul gibt es ein Verzeichnis im Verzeichnis modules und das ganze sieht dann in etwa so aus:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">application
    configs
        application.ini
    modules
        default
            controller
                ErrorController.php
                IndexController.php
            models
            views
                scripts
                    error
                        error.phtml
                    index
                        index.phtml
            Bootstrap.php
        foobarmodule
            controller
                ErrorController.php
                IndexController.php
            models
            views
                scripts
                    error
                        error.phtml
                    index
                        index.phtml
            Bootstrap.php
    Bootstrap.php
public
    index.php</pre></div></div>

<p>Hierbei hat default eine spezielle Rolle, denn es wird von Zend als Standard verwendet, sofern kein anderes Modul explizit angegeben wurde.</p>
<p><strong>Models</strong></p>
<p>Wie oben bereits mehrfach erwaehnt kann jedes Modul Models besitzen. Und hierbei gehen die Geister auseinander. Lange Zeit wurde im <a href="http://framework.zend.com/manual/de/learning.quickstart.html">Quick Start Tutorial</a> vom Zend Framework darauf gepocht, dass man die Klasse Zend_Db_Table_Abstract erweitert. Diese abstrakte Klasse ermoeglicht es sehr einfach eine Datenbanktabellenabstraktion zu erstellen, indem man einfach von ihr erbt und lediglich den Tabellennamen angibt, auf der operiert werden soll. Da selbst das einigen Menschen wohl zu viel Schreibarbeit war, wurde in frueheren Versionen des Zend Frameworks Inflection benutzt (<a href="http://framework.zend.com/manual/de/zend.db.table.row.html">hier</a> steht ein bisschen dazu und <a href="http://framework.zend.com/manual/de/zend.db.table.html">hier</a> ganz unten auch). Das funktioniert wie folgt: Man erweitert Zend_Db_Table (nicht die abstrakte Klasse!) und benennt sie nach einem bestimmten Schema (meist Default_Model_<em>DatenbankTabellenName</em>, je nach Autoloader-Konfiguration mit oder ohne <em>Default_</em>-Prefix). Der Name der Klasse wird dann zum Namen der zugehoerigen Tabelle transformiert (hier waere es <em>datenbank_tabellen_name</em>).</p>
<p>Ich sehe in diesem Ansatz jedoch einen Widerspruch zum Begriff Datenbankabstraktion. Man abstrahiert, um vor allem Komplexitaet zu verringern. Zusaetzlich &#8211; und nicht zu vernachlaessigen &#8211; abstrahiert man aber auch, um eine Entkopplung von tieferliegender Implementierung zu hoeheren Komponenten zu erreichen. Stellt man nun eine direkte Abhaengigkeit zwischen dem Klassennamen und den Tabellennamen her, so ist man gezwungen jede Namensaenderung der Datenbanktabelle auf alle Verwendungen des Models anzuwenden. Epic fail!</p>
<p>Ich habe bereits gesagt, dass dies so alles mal in der offiziellen Dokumentation vom Zend Framework stand bzw. noch steht. Dem gewiefte Leser mag nun aufgefallen, dass ich im vorherigen Absatz erwaehnt habe, dass jede Verwendung des Models anzupassen waere, wenn Inflection genutzt wird und sich der Tabellenname in der Datenbank aendert. Wenn es jedoch nur eine einzige Verwendung gibt: Who cares? Aber hier geht es weiter: Die Dokumentation geht an vielen Stellen davon aus, dass man direkt auf Instanzen von Zend_Db_Table oder Instanzen von Unterklassen von Zend_Db_Table_Abstract arbeitet. Das hat natuerlich zur Folge, dass lose Kopplung zum Fremdwort wird.</p>
<p><strong>Is-A vs. Has-A</strong></p>
<p>Plump unterscheidet man haeufig (unter anderem) zwischen einer Ist- (Is-A) und einer Hat-Beziehung (Has-A) zwischen Entitaeten. Was hat das nun mit Models zu tun? Die Weiterfuehrung des Gedankens nicht direkt auf Datenbankabstraktionen zu arbeiten hat zur Folge, dass man Datenbankabstraktionen zu Modelabstraktionen abstrahiert. Beispiel: Es gibt eine Benutzerverwaltungssystem, also gibt es eine Tabelle von Benutzern in der Datenbank (<em>users</em>). Dafuer gibt es nun eine Tabellenabstraktion. Diese Klasse heisse nun <em>Default_Model_Users</em>. Wenn wir nun fuer einzelne Datensaetze, also fuer einzelne Benutzer auch eine Abstraktion verwenden, so gibt es die Wahl zwischen den beiden Beziehungsarten. Fuer eine Ist-Beziehung haetten wir in diesem Beispiel eine Klasse <em>Default_Model_User</em> und wir wuerden Instanzen davon erhalten, wenn wir ueber <em>Default_Model_Users</em> (mit Oberklasse Zend_Db_Table_Row_Abstract) bestimmte Datensaetze auswaehlen. Da man nun die Datenbank wegabstrahieren moechte hat man zunaechst Gateways eingefuehrt.</p>
<p>Gateways besitzen eine Instanz von Zend_Db_Table (bzw. eine Instanz einer Unterklasse von Zend_Db_Table_Abstract), auf der Operationen ausgefuehrt werden, um einzelne Datensaetze zu erhalten. Diese Datensaetze sollen nun nicht in der Form einer Unterklasse von Zend_Db_Table_Row (bzw. Zend_Db_Table_Row_Abstract) vorliegen, da wir ja die Datenbank verschleiern moechten. Haeufige Herangehensweise dabei ist es, fuer jedes Feld einer Tabelle ein Feld in einem Objekt zu generieren. Wir sind endlich bei der Hat-Beziehung angelangt.</p>
<p>Mehr Informationen zu den Beziehungsarten in diesem Kontext (viel besser erklaert, als ich es in aller Kuerze machen koennte) findet ihr bei <a href="http://akrabat.com/">Rob Allen&#8217;s Dev Notes</a>: <a href="http://akrabat.com/js/on-models-in-a-zend-framework-application/">On models in a Zend Framework application</a>.</p>
<p><strong>Service Layer</strong></p>
<p>Hab ich schonmal erwaehnt, dass ich Zwiebeln jeder Art sehr gerne esse? Nicht? Ist auch nicht wichtig. Wichtig ist jedoch, dass wir es in der Software Entwicklung haeufig mit Zwiebeln zu tun haben. Heisst soviel wie: Wir bauen etwas um etwas anderes herum, um u.A. (1) ein gewuenschtes Abstraktionsniveau zu erhalten, (2) lose gekoppelte Systeme schreiben zu koennen und (3) damit wir auf Aenderungen besser reagieren koennen. Es gibt natuerlich auch die Gefahr, dass diese Zwiebelmethode angewendet wird, weil das Wissen ueber die Komponente nicht ausreichend ist oder weil man mit der Komponente nicht zufrieden ist. Dann wird das ganze schnell zu dem Anti-Pattern, das natuerlich auch <a href="http://de.wikipedia.org/wiki/Anti-Pattern#Programmierungs-Anti-Patterns">Onion</a> heisst.</p>
<p>Wenn wir mit Persistenzschichten arbeiten, wollen wir haeufig eine Schnittstelle fuer verschiedene Persistenzsysteme. Wir wollen also zum Beispiel ohne grossen Aufwand ein auf CSV oder XML basiertes Persistenzsystem auf eine Datenbank umaendern. Das ist einfach, wenn wir in unserer Business Logic auf Repraesentationen von den eigentlich betrachteten Objekten arbeiten und nicht direkt auf den Persistenzsystemen. Gateways ermoeglichen das bereits im Ansatz, jedoch besteht noch immer eine direkte Verbindung zwischen den Feldern eine Tabelle in einer Datenbank und den Attributen eines Business Logic Objects.</p>
<p>Und jetzt kommt der Clue: Statt Bottom-Up zunaechst an die Implementierung der Datenbankanbindung zu denken, besinnen wir uns zunaechst daran, dass wir ja auf bestimmten fiktiven oder realen Objekten wie z.B. einem Benutzer arbeiten moechten. Top-Down: Wir definieren uns als erstes die Objekte als Schnittstellen, um zu gewaehrleisen, dass alle Operationen existieren, die wir benoetigen. Da wir Attribute nicht in Schnittstellen definieren koennen, nutzen wir Getter und Setter. Alternativ koennen wir auch mit abstrakten Klassen arbeiten, dann ist es auch moeglich Attribute vorzugeben, es ist jedoch schwieriger sicherzustellen, dass die Attribute auch allen Vorbedingungen, Nachbedingungen und Invarianten des Systems folgen bzw. ueberhaupt genutzt werden. Vorteil von abstrakten Klassen ist jedoch, dass wir Standardimplementierungen vorgeben koennen. </p>
<p>Nachdem wir alle Objekte zumindest strukturell spezifiziert haben, koennen wir nun beginnen sie zu implementieren. Da ich jetzt schon viel zu viel geschrieben habe ohne ein Beispiel zu nennen kommt erstmal eins, bei dem ich mich auf die grundlegenden Dinge beschraenke:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Default_Model_User
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_id</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_name</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setId<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Weiter geht&#8217;s: Jetzt wo wir alle Schnittstellen definiert haben, auf denen wir unabhaengig von der Persistenzschicht arbeiten moechten, faellt auf: Wir haben einen Schicht gebaut, die uns zugleich als Service dienst, daher auch Service Layer genannt.</p>
<div id="attachment_726" class="wp-caption aligncenter" style="width: 248px"><a href="http://blog.visusnet.de/wp-content/uploads/ServiceLayer.png" title="Abstract Data Mapper Pattern" rel="lightbox[725]"><img src="http://blog.visusnet.de/wp-content/uploads/ServiceLayer.png" alt="" title="Abstract Data Mapper Pattern" width="238" height="322" class="size-full wp-image-726" /></a><p class="wp-caption-text">Komponentendiagramm</p></div>
<p><strong>Data Mapper Pattern</strong></p>
<p>Top Down: Vom Model zu den Daten, oder: Von Modelspezifikation zur Anbindung an die Persistenzschicht. Es ist nun moeglich auf Repraesentationen von unseren Business Logic Objects zu arbeiten. Allerdings kommen die Daten bisher anscheinend aus dem Nirvana. Die Idee ist nun, einen Mapper zu konstruieren, der die Daten auf das Model projizieren kann und der das Model auf die Daten projizieren kann. Wenn wir nun unser <em>echtes</em> Objekt, mit der Datenentsprechung und einem Mapper als Strukturmuster definieren, dann erhalten wir das Data Mapper Pattern, das dank Matthew Weier O&#8217;Phinney nun auch im Quick Start Tutorial von Zend verwendet wird (er hat da <a href="http://www.zfforum.de/showthread.php?p=48671">laut dieser</a> Quelle Diskussionen mit dem Autor des Tutorials gefuehrt).</p>
<p>Wenn ihr mehr Informationen zum Data Mapper Pattern haben moechtet, schaut auch mal das Webinar <a href="http://mtadata.s3.amazonaws.com/webcasts/20090724-playdoh.wmv">Play-Doh: Modelling Your Objects</a> von Matthew Weier O&#8217;Phinney an oder lest euch die <a href="http://www.slideshare.net/weierophinney/playdoh-modelling-your-objects-1766001">Slides</a> dazu durch.</p>
<p>Ich bau mal an dem Beispiel weiter und hoffentlich wird dann auch klar, wie der Mapper funktioniert:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Default_Model_DbTable_User <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Table_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'users'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Default_Model_Mapper_User
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_dbTable</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setDbTable<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$dbTable</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$dbTable</span> instanceof Zend_Db_Table_Abstract<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid table data gateway provided'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable <span style="color: #339933;">=</span> <span style="color: #000088;">$dbTable</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getDbTable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Default_Model_DbTable_User'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span>Default_Model_User <span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id = ?'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">==</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$resultSet</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$entries</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$resultSet</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$entry</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Default_Model_User<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$entry</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">&#41;</span>
                  <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span>
                  <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMapper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$entries</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$entry</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$entries</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAdapter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Und am User muessen wir auch noch etwas aendern, sodass es wie folgt aussieht:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Default_Model_User
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_id</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_name</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_mapper</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'set'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mapper'</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid model property'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'get'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mapper'</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid model property'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setOptions<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$methods</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_class_methods</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'set'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$methods</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setMapper<span style="color: #009900;">&#40;</span><span style="color: #000088;">$mapper</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mapper</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$mapper</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$mapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$mapper</span> instanceof Default_Model_Mapper_Abstract<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid data mapper provided'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper <span style="color: #339933;">=</span> <span style="color: #000088;">$mapper</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getMapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMapper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapperClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAdapter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setId<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Endlich! Wir haben das Data Mapper Pattern komplett. Hier mal ein Usage Example:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/* somewhere in your controller */</span>
&nbsp;
<span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Default_Model_User<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$users</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$users</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$u</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$u</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'unknown'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$u</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'unbekannter Nutzername'</span><span style="color: #009900;">&#41;</span>
          <span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Pretty easy, huh? Aber stopp! Im Titel steht doch noch irgendwas von <em>Abstract</em>. Was soll denn der Quark? &#8230;</p>
<p><strong>Reusability: Abstract Data Mapper Pattern</strong></p>
<p>Wenn wir das Data Mapper Pattern jetzt mehrfach verwenden, stellen wir sehr sehr schnell fest, dass wir unglaublich viel Code doppelt und dreifach haben. Jetzt kommt mein Ansatz: Wir packen alles bekannte in abstrakte Oberklassen und erben davon, setzen die benoetigten Meta-Informationen fuer das Pattern und sind fertig. Ohne grosse Umschweife (just kidding, das war ja jetzt wohl genug Umschweife):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Default_Model_DbTable_User <span style="color: #000000; font-weight: bold;">extends</span> Zend_Db_Table_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'users'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
abstract <span style="color: #000000; font-weight: bold;">class</span> Default_Model_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_mapper</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_mapperClass</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOptions</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __set<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'set'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mapper'</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid model property'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'get'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'mapper'</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid model property'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __call<span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">method_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Inaccessible method called'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">call_user_func_array</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #339933;">,</span> <span style="color: #000088;">$method</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setOptions<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$methods</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_class_methods</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$options</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'set'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$method</span><span style="color: #339933;">,</span> <span style="color: #000088;">$methods</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setMapper<span style="color: #009900;">&#40;</span><span style="color: #000088;">$mapper</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mapper</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$mapper</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$mapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$mapper</span> instanceof Default_Model_Mapper_Abstract<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid data mapper provided'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper <span style="color: #339933;">=</span> <span style="color: #000088;">$mapper</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getMapper<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMapper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapperClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_mapper<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAdapter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Default_Model_User <span style="color: #000000; font-weight: bold;">extends</span> Default_Model_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_mapperClass</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Default_Model_Mapper_User'</span><span style="color: #339933;">;</span>
&nbsp;
    protected <span style="color: #000088;">$_id</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_name</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setId<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_id <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_name <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
abstract <span style="color: #000000; font-weight: bold;">class</span> Default_Model_Mapper_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_dbTable</span><span style="color: #339933;">;</span>
    protected <span style="color: #000088;">$_dbTableClass</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> setDbTable<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_string</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$dbTable</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$dbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$dbTable</span> instanceof Zend_Db_Table_Abstract<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            throw <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Invalid table data gateway provided'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable <span style="color: #339933;">=</span> <span style="color: #000088;">$dbTable</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getDbTable<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTableClass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span>_dbTable<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getAdapter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAdapter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    abstract <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #000088;">$entry</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    abstract <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    abstract <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$entry</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    abstract <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Default_Model_Mapper_User <span style="color: #000000; font-weight: bold;">extends</span> Default_Model_Mapper_Abstract
<span style="color: #009900;">&#123;</span>
    protected <span style="color: #000088;">$_dbTableClass</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Default_Model_DbTable_User'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">insert</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">update</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id = ?'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> delete<span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$where</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">function</span> find<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span> <span style="color: #339933;">==</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$result</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">&#41;</span>
             <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
       <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> fetchAll<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$resultSet</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbTable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetchAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$entries</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$resultSet</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$entry</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Default_Model_User<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$entry</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setId</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">id</span><span style="color: #009900;">&#41;</span>
                  <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">name</span><span style="color: #009900;">&#41;</span>
                  <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMapper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$entries</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$entry</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$entries</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Das Pattern nenn ich jetzt einfach mal wie oben genannt und schenke es der Welt.</p>
<p><strong>Update</strong></p>
<p>Ich habe mal ein Demo-Projekt fuer Zend Studio zusammengebaut. In etwa so sollte es aussehen (Modulstruktur und kleine Anpassungen inklusive): <a href='http://blog.visusnet.de/wp-content/uploads/AbstractDataMapperPatternDemo-1.2.zip'>AbstractDataMapperPatternDemo-1.2.zip</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/03/05/abstract-data-mapper-pattern/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
<enclosure url="http://mtadata.s3.amazonaws.com/webcasts/20090724-playdoh.wmv" length="59063715" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Finsternis</title>
		<link>http://blog.visusnet.de/2010/02/27/finsternis/</link>
		<comments>http://blog.visusnet.de/2010/02/27/finsternis/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 15:29:14 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=720</guid>
		<description><![CDATA[Gestern habe ich das Geschenk fuer meine Freundin zum Einjaehrigen eingeloest: Ein Essen im Restaurant Finster in Essen. Dort angekommen hat uns ein Mann mit trockenem Humor empfangen und unsere Essenswuensche und die erste Getraenkebestellung entgegengenommen. Er hat dann eine der Mitarbeiterinnen per Funk geordert, die uns dann Polonaise-artig durch eine Lichtschleuse und dann zum [...]]]></description>
			<content:encoded><![CDATA[<p>Gestern habe ich das Geschenk fuer meine Freundin zum Einjaehrigen eingeloest: Ein Essen im <a href="http://www.finster-essen.de/">Restaurant Finster</a> in Essen. Dort angekommen hat uns ein Mann mit trockenem Humor empfangen und unsere Essenswuensche und die erste Getraenkebestellung entgegengenommen. Er hat dann eine der Mitarbeiterinnen per Funk geordert, die uns dann Polonaise-artig durch eine Lichtschleuse und dann zum Tisch geleitet hat. Dort angekommen musste man sich erst an die absolute Dunkelheit gewoehnen. Eine solche Dunkelheit kann man zuhause kaum erreichen. Es gibt dort keinerlei Restlicht. Man ist quasi blind.</p>
<p>Wir haben also zunaechst den Tisch abgetastet und einen kleinen Teller vorgefunden, neben dem links, rechts und dahinter das Besteck traditionell angeordnet war. Die Kellnerin hat uns dann erklaert, dass in der Mitte des Tisches eine Schuessel mit Dip und Brot liegt. Ich habe natuerlich als erstes in den Dip gelangt. Spaeter hat sich herausgestellt, dass es Ajoli war. Erschmeckt haben wir es nicht. Wir haben auf eine Cocktailsauce oder Tzatziki getippt.</p>
<p>Nachdem wir das Brot vertilgt hatten, kam auch schon unsere Vorspeise: Eine Suppe, die wir schnell als Kartoffelsuppe identifiziert hatten. Dazu brachte man uns direkt die Getraenke, die man uns dann in die Hand gegeben hat. Neben unserem Tisch befand sich eine Saeule, an der wir die Glaeser positioniert haben, damit wir sie jederzeit wiederfinden und die Gefahr senken, die Glaeser umzuwerfen.</p>
<p>Eine Weile nachdem wir nun auch endlich die Vorspeise geloeffelt hatten, wurde der Tisch dann abgeraeumt und die Hauptspeise wurde gereicht. Und das war der Zeitpunkt, ab dem bei mir die Sauerei anfing. Ich wollte als erstes herausfinden, was ueberhaupt auf meinem Teller liegt, denn man bekommt weder gesagt was es ist, noch wo es ist. Auf meiner Seite links auf dem Teller lagen kleine Knoedel, deren Geschmack auf Gnocchi hinwies. Ueber den ganzen Teller verteilt lag Brokkoli mit irgendeiner Sauce und erst spaeter haben wir einen grossen Klumpen entdeckt, der gegenueber von den Gnocchi lag. Den Klumpen konnten wir nicht identifizieren, aber es koennte alles von Reis bis Kuskus in Frikadellenform, paniert und frittiert, gewesen sein. Da der Geschmack nicht so meins war, habe ich den Klumpen dann heimlich auf den Teller meiner Freundin befoerdert.</p>
<p>Meine Finger und die Serviette, die ich mir in den Kragen gestopft hatte, waren bis dahin schon total eingesaut. Das Essen war aber reichlich und wir haben es beide nicht aufgegessen. Eine gefuehlte halbe Stunde spaeter kam die Kellnerin wieder und hat die Teller abgeraeumt und uns neue Getraenke gebracht. Kurze Zeit spaeter kam dann auch der Nachtisch: Panna cotta mit einer alkoholhaltigen Sauce.</p>
<p>Alles in Allem war das Essen sehr lecker. Es ist aber sehr krass ohne etwas zu sehen zu essen. Die Hauptspeise konnte ich nur mit den Fingern essen, da ich sonst nichts aufs Besteck bekommen haette, die Nachspeise musste ich mit dem Dessertloeffel essen, aber das hat auch nicht wirklich geklappt. Meistens war der Loeffel leer, zu voll oder alles fiel schon zuvor auf den Tisch. Was mich gestoert hat war, dass es sehr laut wurde, als eine etwas groessere Gruppe in die Dunkelkammer gebracht wurde.</p>
<p>Irgendwann beim Dessert rief dann ein Kellner dazu auf, einem 8 Jahre alt gewordenem Maedchen ein Staendchen zu singen. Ich hatte da aber den Mund voll, da ich es endlich geschafft hatte ein riesiges Stueck Panna cotta mit dem Loeffel von der schifffoermigen Schuessel zu meinem Mund zu befoerdern.</p>
<p>Der Preis ist sehr hoch, aber es ist die Erfahrung wert.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/02/27/finsternis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Impact</title>
		<link>http://blog.visusnet.de/2010/02/22/impact/</link>
		<comments>http://blog.visusnet.de/2010/02/22/impact/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 00:14:44 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=715</guid>
		<description><![CDATA[Wenn man ueber etwas nachdenkt, dann ist es schwierig solange man sich mittendrin befindet. Wenn man jedoch am Ende steht, scheint es fuer Menschen wesentlich einfacher zu sein Dinge zu reflektieren. Anscheinend laesst sich das auch auf das Leben anwenden. Den Beweis fuer diese These hat Prof. Randy Pausch (* 23. Oktober 1960; ? 25. [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn man ueber etwas nachdenkt, dann ist es schwierig solange man sich mittendrin befindet. Wenn man jedoch am Ende steht, scheint es fuer Menschen wesentlich einfacher zu sein Dinge zu reflektieren. Anscheinend laesst sich das auch auf das Leben anwenden. Den Beweis fuer diese These hat Prof. Randy Pausch (* 23. Oktober 1960; ? 25. Juli 2008) erbracht.</p>
<p>Pausch war Professor an der Carnegie Mellon University in Pittsburgh, Pennsylvania. Sein Forschungsgebiet war die Human-Computer Interaction (HCI), vor allem aber Virtual Reality. Er begruendete u.A. das Alice-Project, bei dem eine offensichtlich funktionierende Idee einfach einmal realisiert wurde: Wenn man Menschen dazu bringt Spass zu haben, dann fokussieren sie ihr Interesse darauf und beginnen dabei Dinge zu lernen, die keine offensichtlichen Beziehungen zum eigentlichen Geschehen haben. Das Alice-Project erleichtert es auf spielerische Weise Programmiersprachen zu lernen und wird (Stand 2008) von 10% der Studierenden von IT-Bereichen in den USA genutzt.</p>
<p>Bei Pausch wurde im September 2006 Bauchspeicheldruesenkrebs diagnostiziert. Er kaempfte mit vielen Behandlungen dagegen an, starb aber im Juli 2008. Zehn Monate vor seinem Tod hielt Randy Pausch seine <em>Last Lecture</em>. Eine letzte Vorlesung zu halten ist Brauch an vielen Universitaeten. Als die CMU allerdings zu seiner letzten Vorlesung lud, war bereits klar, dass der Begriff woertlich zu nehmen ist.</p>
<p>Seine offiziell letzte Vorlesung nutzte Pausch, um auf brilliante Art ueber sein Leben zu sprechen. Er stellte die Vorlesung unter einen Titel (Achieving Your Childhood Dreams), der durchdachter kaum sein koennte. Er nannte seine Kindheitstraeume und wie er sie erreicht hat bzw. wieso es gut ist, dass er auch manche Kindheitstraeume nicht erreicht hat. Er erklaerte, wie er anderen Menschen dabei geholfen hat ihre Kindheitstraeume zu erfuellen und was er aus Allem gelernt hat.</p>
<p>Um die Komplexitaet des Inhalts und der Botschaft seiner Last Lecture zu verstehen reicht es nicht aus darueber zu schreiben. Man muss sie sehen. Es lohnt sich und hat mich sehr beeindruckt.</p>
<p>Das Video der letzten Vorlesung:</p>
<p><object type="application/x-shockwave-flash" data="http://www.youtube.com/v/ji5_MqicxSo" width="425" height="355" class="embedflash"><param name="wmode" value="opaque" /><param name="movie" value="http://www.youtube.com/v/ji5_MqicxSo" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><small>(Bitte den Artikel &ouml;ffnen, um die Flashdatei oder den Flashplayer zu sehen.)</small></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/02/22/impact/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kein Fake! Betrug!</title>
		<link>http://blog.visusnet.de/2010/02/03/kein-fake-betrug/</link>
		<comments>http://blog.visusnet.de/2010/02/03/kein-fake-betrug/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 14:03:11 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=711</guid>
		<description><![CDATA[Hiermit werfe ich der Springer-Presse Betrug vor! Will man gegen Zensursula stimmen und sieht &#8220;sehr gut&#8221; ganz oben, klickt man doch sofort ohne weiter nachzudenken auf &#8220;sehr gut&#8221; ganz unten! Das erklaert wohl auch wieso bei &#8220;sehr gut&#8221; oben 1% sind und unten 12%! Pfui!


]]></description>
			<content:encoded><![CDATA[<p>Hiermit werfe ich der Springer-Presse Betrug vor! Will man gegen Zensursula stimmen und sieht &#8220;sehr gut&#8221; ganz oben, klickt man doch sofort ohne weiter nachzudenken auf &#8220;sehr gut&#8221; ganz unten! Das erklaert wohl auch wieso bei &#8220;sehr gut&#8221; oben 1% sind und unten 12%! Pfui!</p>
<p><a href="http://blog.visusnet.de/wp-content/uploads/2010-02-03-14-44-07-000.png" title="Springer betruegt" rel="lightbox[711]"><img src="http://blog.visusnet.de/wp-content/uploads/2010-02-03-14-44-07-000-300x283.png" alt="" title="Springer betruegt" width="300" height="283" class="aligncenter size-medium wp-image-712" /></a></p>
<p><a href="http://blog.visusnet.de/wp-content/uploads/2010-02-03-14-49-53-000.png" title="Das Ergebnis" rel="lightbox[711]"><img src="http://blog.visusnet.de/wp-content/uploads/2010-02-03-14-49-53-000-300x143.png" alt="" title="Das Ergebnis" width="300" height="143" class="aligncenter size-medium wp-image-713" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/02/03/kein-fake-betrug/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Identitaet und Privatsphaere</title>
		<link>http://blog.visusnet.de/2010/01/29/identitaet-und-privatsphaere/</link>
		<comments>http://blog.visusnet.de/2010/01/29/identitaet-und-privatsphaere/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 20:40:19 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=700</guid>
		<description><![CDATA[Identitaet &#8211; was ist das eigentlich? Irrelevanzia definiert die Identitaet wie folgt:
Beim Menschen bezeichnet Identitaet (v. lat. idem, derselbe, der gleiche) die ihn kennzeichnende und als Individuum von anderen Menschen unterscheidende Eigentuemlichkeit seines Wesens.
Es geht also um Alleinstellungsmerkmale und die kann man zumindest stochastisch evaluieren. Wir ich schon in meinem Paper ueber Reality Mining1 bereits [...]]]></description>
			<content:encoded><![CDATA[<p>Identitaet &#8211; was ist das eigentlich? <a title="Wikipedia" href="http://de.wikipedia.org/wiki/Identit?t">Irrelevanzia</a> definiert die Identitaet wie folgt:</p>
<blockquote><p>Beim Menschen bezeichnet Identitaet (v. lat. <em>idem</em>, derselbe, der gleiche) die ihn kennzeichnende und als Individuum von anderen Menschen unterscheidende Eigentuemlichkeit seines Wesens.</p></blockquote>
<p>Es geht also um Alleinstellungsmerkmale und die kann man zumindest stochastisch evaluieren. Wir ich schon in meinem Paper ueber Reality Mining<sup>1</sup> bereits beschrieben habe, ist Entropie ein dabei besonders interessantes Mass. Es gilt als Einheit fuer Unordnung, aber es ist viel mehr als das. Entropie kann dazu verwendet werden, um Muster zu visualisieren und sie sogar mathematisch vergleichbar zu machen, selbst wenn wir diese Muster nicht in Worte fassen koennen. Eine andere Definition von Entropie nennt es die Generalisierung der Anzahl von moeglichen zufaelligen Unterschieden. Solche Anzahlen werden haeufig auch durch Bits of Entropy dargestellt. Beispiel: Bei einem Zufallsexperiment gibt es zwei moegliche Elementarereignisse. Wir sprechen hierbei dann von einer Entropy von einem Bit, da <img src='http://s.wordpress.com/latex.php?latex=2%5E1%20%3D%202&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2^1 = 2'  class='latex' />. Wenn wir eine Entropy von 3 Bits bei einem Zufallsexperiment annehmen, so gibt es <img src='http://s.wordpress.com/latex.php?latex=2%5E3%20%3D%208&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2^3 = 8'  class='latex' /> Ereignisse, usw.</p>
<p>Nun koennen wir dieses simple mathematische Modell auf die Identitaet anwenden: Es gibt ca. <a href="http://de.wikipedia.org/wiki/Weltbev?lkerung">6,9 Milliarden Menschen</a> (6.900.000.000). Also benoetigt man <img src='http://s.wordpress.com/latex.php?latex=%5Clog_2%20%281%2F6900000000%29%20%3D%2032%2C6839&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\log_2 (1/6900000000) = 32,6839'  class='latex' /> Bits, um eine Person auf der Welt eindeutig zu identifizieren. Da es bei Computern so immer die Sache mit der 8 ist, koennen wir jetzt mal approximieren: <img src='http://s.wordpress.com/latex.php?latex=4%2A8%20%3C%2032%2C6839%20%3C%205%20%2A%208&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4*8 &lt; 32,6839 &lt; 5 * 8'  class='latex' />, also weniger als 5 Byte. Zum Vergleich: Auf x86 Maschinen ist die Assembler Anweisung <em>nop</em> (=<em>no operation</em>, <a href="http://ref.x86asm.net/geek.html#x90">hexadezimal 90 oder auch 10010000</a>) 8 Bit lang. 8 Bits wuerden genuegen, um im optimalen Fall 256 Personen unterscheiden zu koennen. Das ist alles wirklich nicht viel.</p>
<p>Treiben wir das ganze noch weiter und werden politischer: Wenn <em>EVILOFYOURCHOICE</em> Daten von Personen speichert, z.B. Land, Most Viewed Website, durchschnittliche Online-Zeit, Browser, Displaygroesse, zuletzt online gekaufter Artikel, zuletzt offline gekaufter Artikel, etc., ohne zu wissen, wer diese Person ist, so ist das voellig egal, denn man kennt natuerlich auch die Personen, die mit dieser Person kontakt hatten (Telefon, E-Mail, SMS) und deren Daten und das alles aggregiert sich zu einem riesigen Netz (ja, jetzt sind wir beim Reality Mining angelangt). Jetzt nehmen wir mal an, dass wir dieses Netz kennen und eine Person aus diesem Neetz geht in einen Laden und nutzt seine Payback-Karte, die mit dem Namen der Person assoziiert ist&#8230; dann wissen wir auf einmal noch viel mehr und koennen ohne Muehe andere Personen aus diesem Netz identifizieren.</p>
<p>Leute, die unsere Daten speichern, nutzen solche Techniken (die ich bewusst sehr plump erklaert habe) schon seit Jahren! Sie nutzen das auch aus und senden Werbung oder bevorzugen besondere Zentralpersonen solcher Netze bei Hotlines und bei Kulanz. Wisst ihr ueberhaupt, wer was von euch weiss? Glaubt ihr wirklich, dass eure Privatsphaere geschuetzt ist und ihr nichts zu verbergen habt?</p>
<p>Uebrigens: Wenn die Polizei so etwas macht, dann nennt man das Rasterfahndung, deren Vertraeglichkeit mit dem Grundgesetz doch stark zu bezweifeln ist, da sie die Unschuldsvermutung, die wie folgt rechtlich (GG Art. 11 Abs. 1) definiert ist, aufhebt:</p>
<blockquote><p>Jeder Mensch, der einer strafbaren Handlung beschuldigt wird, ist  solange als unschuldig anzusehen, bis seine Schuld in einem oeffentlichen Verfahren, in dem alle fuer seine Verteidigung noetigen Voraussetzungen  gewaehrleistet waren, gemaess dem Gesetz nachgewiesen ist.</p></blockquote>
<p>Auf Europaeischer ebene verletzt es meiner Ansicht nach auch Art. 6 Abs. 2 der Europaeischen Menschenrechtskonvention:</p>
<blockquote><p>Jede Person, die einer Straftat angeklagt ist, gilt bis zum gesetzlichen  Beweis ihrer Schuld als unschuldig.</p></blockquote>
<p>Dennoch wird es gemacht! Wollt ihr wirklich den <em>neuen Personalausweis</em> oder bis vor kurzem <em>ePA</em>?</p>
<p><strong>SRSLY?</strong></p>
<p>Mehr Informationen zu Bits &#038; Privacy? <a href="https://www.eff.org/deeplinks/2010/01/primer-information-theory-and-privacy">Hier</a>.</p>
<ol class="footnotes"><li id="footnote_0_700" class="footnote">Veroeffentlichung steht noch aus.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/01/29/identitaet-und-privatsphaere/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Danke, Frau Merkel!</title>
		<link>http://blog.visusnet.de/2010/01/26/danke-frau-merkel/</link>
		<comments>http://blog.visusnet.de/2010/01/26/danke-frau-merkel/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 08:20:34 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=696</guid>
		<description><![CDATA[Noch peinlicher als das ist wohl nur Frau Merkel selber.
(Bitte den Artikel &#246;ffnen, um die Flashdatei oder den Flashplayer zu sehen.)
]]></description>
			<content:encoded><![CDATA[<p>Noch peinlicher als das ist wohl nur Frau Merkel selber.</p>
<p><object type="application/x-shockwave-flash" data="http://www.youtube.com/v/OXPPu418C78" width="425" height="355" class="embedflash"><param name="wmode" value="opaque" /><param name="movie" value="http://www.youtube.com/v/OXPPu418C78" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><small>(Bitte den Artikel &ouml;ffnen, um die Flashdatei oder den Flashplayer zu sehen.)</small></object></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/01/26/danke-frau-merkel/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Der lange Weg zum NAS</title>
		<link>http://blog.visusnet.de/2010/01/21/der-lange-weg-zum-nas/</link>
		<comments>http://blog.visusnet.de/2010/01/21/der-lange-weg-zum-nas/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 03:15:19 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=687</guid>
		<description><![CDATA[Wie ich waehrend des 26C3 festgestellt habe, mag ich Netzwerk Storages. Ich habe also bei eBay herumgeschaut und musste wiederum feststellen, dass ich mir eine richtige Kiste nicht leisten kann. Also habe ich mich prompt dazu entschieden, mir ein NAS zu improvisieren. Die Zutaten:

ein Thin Client
ein paar USB Sticks
ein paar externe Festplatten
Linux

Ich habe mir also [...]]]></description>
			<content:encoded><![CDATA[<p>Wie ich <a href="http://blog.visusnet.de/2009/12/31/dragons-everywhere-in-essen-tag-4/">waehrend des 26C3 festgestellt habe</a>, mag ich Netzwerk Storages. Ich habe also bei eBay herumgeschaut und musste wiederum feststellen, dass ich mir eine richtige Kiste nicht leisten kann. Also habe ich mich prompt dazu entschieden, mir ein NAS zu improvisieren. Die Zutaten:</p>
<ul>
<li>ein Thin Client</li>
<li>ein paar USB Sticks</li>
<li>ein paar externe Festplatten</li>
<li>Linux</li>
</ul>
<p>Ich habe mir also bei eBay zwei (just in case&#8230;) Thin Clients (FSC Futro S300 und HP Thin Client t5510) fuer insgesamt rund 70 EUR gekauft. Da der HP schoener aussieht und als erstes geliefert wurde, habe ich ihn auserkoren zum NAS zu werden.</p>
<p><strong>Der naive Versuch</strong></p>
<p>Da der HP (und auch der FSC) kein CD Laufwerk hat, bleibt nur USB. Das war mir ja klar, also habe ich auch direkt ein paar (2x 4GB, 10x 2GB, weil die so guenstig waren) USB Sticks gekauft und den Ubuntu Installer auf einen der 4GB Sticks geknallt. Da der Installer aber nach 30 Minuten noch immer nicht komplett geladen war, habe ich das mit dem Ubuntu ad acta gelegt.</p>
<p><strong>Kleine Pueppchen</strong></p>
<p>Nun musste also eine Ersatzdistro her, die am Besten auf Debian basiert (Debian ist sexy). Nach ein paar brutalen Stunden, die ich mit Google verbracht hab, war ich von dem Linux Terminal Server Project etwas enttaeuscht. Dann bin ich endlich auf <a href="http://puppylinux.org">Puppy Linux</a> gestossen. Die knapp 100MB grosse Linux Distribution habe ich dann gepflegt in den Downloadmanager geladen und froehlich 1,5 Stunden(!!!) gewartet. Tolle Mirrors&#8230;.</p>
<p>Aber endlich war es dann soweit. USB Stick mit Puppy Linux beladen und gib ihm&#8230; Haettstewohlgern! Die Fehlermeldung beim Booten haette genauso gut auch EPIC FAIL heissen koennen. Blieb mir nur eins:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">dd</span> <span style="color: #007800;"><span style="color: #000000; font-weight: bold;">if</span></span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #007800;">of</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda</pre></div></div>

<p><strong>Verdammt klein</strong></p>
<p>&#8230; soll ja <a href="http://www.damnsmalllinux.org">Damn Small Linux</a> sein. Da es auch auf Debian basiert, war es meine naechste Wahl. Saugen,? auf den Stick knallen, booten. Endlich! Innerhalb von Sekunden(!!!) startete Fluxbox. Coole Sache. Das hat mich an meine (spaete, da ich anfaenglich nur mit CLI gearbeitet habe) OpenBSD Zeit erinnert. Da gab es tatsaechlich auch die Moeglichkeit ein Pendrive Linux zu installieren. Also steckte ich einen weiteren USB Stick in den Thin Client, der zum Glueck 4 USB Slots hat, und startete sogleich auch den Pendrive Installer. EPIC FAIL. Abgeschmiert. Zu wenig RAM&#8230; Damn Small aber dennoch Damn Memory-leaky. Diesmal habe ich mir dann mit&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">shred</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">10</span> <span style="color: #660033;">-v</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda</pre></div></div>

<p>&#8230;geholfen. *facepalm*<sup>1</sup></p>
<p><strong>Verzweiflung</strong></p>
<p>Zu dem Zeitpunkt war ich doch schon sehr verzweifelt, da ich schon mehrere Tage (da ich ja immer erst spaet von der Uni komme) daran gehockt habe und noch zu keinem Ergebnis gelangt bin. Unter Windows lief mal wieder mein VMware-Ubuntu im Unity-Mode (sexy, wenn auch von Parallels abgeguckt). Da Ubuntu von Debian abstammt, kommt man auch sehr schnell auf die Idee debootstrap anzuschmeissen und sich sein Debian manuell zusammenzubauen. Gesagt, getan: Nach ein paar Stunden Frickelei (USB+ext3 = keine gute Idee, USB+vfat+Linux = noch schlechtere Idee, USB+Grub = beschissene Idee) habe ich es dann auch geschafft mir ein Linux zu bauen, das ich halbwegs booten konnte. Halbwegs. Kernel Panic. Aus die Maus.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">cfdisk <span style="color: #660033;">-z</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda</pre></div></div>

<p>&#8230; und auf Wiedersehen Partitionstabelle.</p>
<p><strong>RTFM</strong></p>
<p>Manchmal ist es doch so einfach: Die Debian Doku enthaelt einen netten Abschnitt ueber <a href="http://www.us.debian.org/releases/stable/amd64/ch04s03.html.de">das Vorbereiten von Dateien fuer das Booten von einem USB Stick</a>. Die boot.img.gz-URL hat mir Google sofort geliefert. wget, zcat, mount und eine sowieso in meinem Dateiarchiv existierende und aktuelle Debian ISO draufgeschoben, brachte mich nun endlich zum Erfolg. Der Debian Installer im Textmodus startete problemlos und hat es zugelassen die Installation auf einen anderen USB Stick vorzunehmen. Nur das mit dem Grub ist da so eine Sache&#8230; Der Installer dachte &#8220;ich USB, ich = sda, sdb = Ziel, (hd2,0) also Bootpartition&#8221; (hd0 ist die interne 32MB Flash Card, die so fest verbaut ist, dass man sie nicht austauschen kann). Dementsprechend pflanzte der Installer eine Grub Config (in (hd1,1), also /dev/sda1, wtf?) und die Flash Card habe ich als MBR-Bettchen erkoren. Beim Rebooten (und gleichzeitigem Entfernen des Installer-Sticks) war es natuerlich klar, dass Grub etwas verwirrt war. Interessanterweise hat er die Config gefunden. Nunja, jetzt zwei Zeichen im Bootmenue zu aendern war nicht das Problem und so bootete endlich(!!!) ein jungfraeuliches Debian.</p>
<p><strong>Fileserver</strong></p>
<p>&#8230; sind auch so eine Sache fuer sich. Samba (jaja, oldschool &#8211; aber soll ja jeder hier im Haus nutzen koennen) hat eine sehr interessante fluide Syntax fuer die Config. Wichtig hierbei war lediglich <em>root preexec</em> zum Mounten der Festplatte (sofern nicht bereits geschehen). Da meine Externe einen netten Stromsparmodus hat und sich selber abschaltet, wenn sie laenger nicht genutzt wurde, konnte ich mir <em>postexec</em> sparen.</p>
<p>Wenn man nun schon einen Fileserver hat, dann kann der ruhig auch hier und da mal dezentrales Filesharing (ohja, man kann auch legale Sachen damit herunterladen!) betreiben. rtorrent hatte ich noch im Hinterkopf, aber das habe ich ganz schnell wieder verworfen. Drecksteil. Das hat mehr Shortcuts als screen und vi zusammen. Oergs. Dann wollte ich noch torrentflux, eine Webschnittstelle zu rtorrent, nutzen&#8230; Ein guter Tipp: MySQL und 128MB RAM vertragen sich gar nicht. Letztendlich war MySQL an, dpkg dachte es sei deinstalliert (sogar purged) und das Init-Script mochte es nicht stoppen, weil es dazu ersteinmal initial-gestartet werden muesste, um die Configs zu generieren. Argh! Uebrigens, folgendes hilft:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">--remove</span> <span style="color: #660033;">--force-remove-reinstreq</span> mysql-server-<span style="color: #000000;">5.0</span></pre></div></div>

<p>Wo war ich? Achja, torrentflux. MySQL + Low Memory = Dreck. Apache ging lustigerweise. Aber ohne torrentflux brauch ich es nicht. Also weg mit dem Mist. Dann blieb ich erstmal bei <a href="http://www.transmissionbt.com/">Transmission</a>. Dank <a href="http://blog.babeltech.de">babels</a> Tipp habe ich mir dann doch (das per Default bereits installierte) BitTornado bzw. btdownloadcurses angeschaut. Nach knapp 1,5 Stunden Spielereien mit screen und btdownloadcurses kam dann ein nettes Bash-Script heraus, das Torrents herunterladen, sie archivieren, sharen und gleichzeitig in eine wunderbare Multiwindow-Screen-Umgebung packen kann. Das moechte ich natuerlich niemanden vorenthalten (ja, inkonsistente Schreibweise, aber ich bin atm zu faul):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">### CONFIG ###</span>
&nbsp;
<span style="color: #007800;">DEVICE</span>=<span style="color: #ff0000;">&quot;/dev/sdb1&quot;</span>
<span style="color: #007800;">MOUNTPOINT</span>=<span style="color: #ff0000;">&quot;/media/storage&quot;</span>
<span style="color: #007800;">TORRENTDIR</span>=<span style="color: #ff0000;">&quot;/root/torrents&quot;</span>
<span style="color: #007800;">DOWNLOADDIR</span>=<span style="color: #ff0000;">&quot;/media/storage/public&quot;</span>
<span style="color: #007800;">PORTFILE</span>=<span style="color: #ff0000;">&quot;/root/torrents/.ports&quot;</span>
<span style="color: #007800;">SCREEN_SESSION_NAME</span>=<span style="color: #ff0000;">&quot;__DEFAULT&quot;</span>
<span style="color: #007800;">SCREEN_DATETIME</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$(date +%Y%m%d_%H%M%S)</span>&quot;</span>
<span style="color: #007800;">MAX_UPLOAD_RATE</span>=<span style="color: #000000;">30</span>
<span style="color: #007800;">MIN_PORT</span>=<span style="color: #000000;">53535</span>
<span style="color: #007800;">MAX_PORT</span>=<span style="color: #000000;">53559</span>
&nbsp;
<span style="color: #666666; font-style: italic;">### CODE ###</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(cat /proc/mounts | grep /media/storage | wc -l)</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Mounting <span style="color: #007800;">$DEVICE</span> on <span style="color: #007800;">$MOUNTPOINT</span>...&quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">mount</span> <span style="color: #660033;">-t</span> ntfs-g3 <span style="color: #007800;">$DEVICE</span> <span style="color: #007800;">$MOUNTPOINT</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$?&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot; done.&quot;</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #007800;">FILE</span>=<span style="color: #ff0000;">&quot;&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Loading $1...&quot;</span>
        <span style="color: #007800;">FILE</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
<span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Downloading torrent...&quot;</span>
        <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> tmp.torrent
        <span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> tmp.torrent $<span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot; done.&quot;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-f</span> <span style="color: #ff0000;">&quot;tmp.torrent&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Name: &quot;</span>
                <span style="color: #c20cb9; font-weight: bold;">read</span> NAME
                <span style="color: #007800;">FILE</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$NAME</span>.torrent&quot;</span>
                <span style="color: #c20cb9; font-weight: bold;">mv</span> tmp.torrent <span style="color: #ff0000;">&quot;<span style="color: #007800;">$FILE</span>&quot;</span>
        <span style="color: #000000; font-weight: bold;">else</span>
                <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Torrent file does not exist&quot;</span>
                <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
        <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$DOWNLOADDIR</span>
&nbsp;
<span style="color: #007800;">SCREEN_EXISTS</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-ls</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #800000;">${SCREEN_SESSION_NAME}</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> -l<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SCREEN_EXISTS</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-S</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${SCREEN_SESSION_NAME}</span>&quot;</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>btdownloadcurses --max_upload_rate <span style="color: #007800;">$MAX_UPLOAD_RATE</span> <span style="color: #660033;">--minport</span> <span style="color: #007800;">$MIN_PORT</span> <span style="color: #660033;">--maxport</span> <span style="color: #007800;">$MAX_PORT</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$TORRENTDIR</span>/<span style="color: #007800;">$FILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #007800;">COMMAND</span>=<span style="color: #ff0000;">&quot;screen /usr/bin/btdownloadcurses --max_upload_rate <span style="color: #007800;">$MAX_UPLOAD_RATE</span> --minport <span style="color: #007800;">$MIN_PORT</span> --maxport <span style="color: #007800;">$MAX_PORT</span> <span style="color: #000099; font-weight: bold;">\&quot;</span><span style="color: #007800;">$TORRENTDIR</span>/<span style="color: #007800;">$FILE</span><span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span>
        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-r</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${SCREEN_SESSION_NAME}</span>&quot;</span> <span style="color: #660033;">-X</span> <span style="color: #7a0874; font-weight: bold;">eval</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$COMMAND</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Last but not least muss ich sagen: Es hat sich (bisher) gelohnt.</p>
<ol class="footnotes"><li id="footnote_0_687" class="footnote">Ich lese definitiv zu viel <a href="http://blog.fefe.de">Fefe</a></li></ol>]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/01/21/der-lange-weg-zum-nas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freedom of Speech</title>
		<link>http://blog.visusnet.de/2010/01/13/freedom-of-speech/</link>
		<comments>http://blog.visusnet.de/2010/01/13/freedom-of-speech/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 00:17:55 +0000</pubDate>
		<dc:creator></dc:creator>
		
		<guid isPermaLink="false">http://blog.visusnet.de/?p=664</guid>
		<description><![CDATA[Normalerweise twitter ich solche Sachen oder ich teile sie auf Facebook. Aber das Folgende ist es einfach wert gebloggt zu werden:
Nachdem Google sich zunaechst der chinesischen Regierung gebeugt und Inhalte zensiert hat, will Google das nicht laenger mitmachen. Ausgeloest haben das vor allem kuerzlich durchgefuehrte Angriffe auf Google und andere Unternehmen aus dem Bereichen Internet, [...]]]></description>
			<content:encoded><![CDATA[<p>Normalerweise twitter ich solche Sachen oder ich teile sie auf Facebook. Aber das Folgende ist es einfach wert gebloggt zu werden:</p>
<p>Nachdem Google sich zunaechst der chinesischen Regierung gebeugt und Inhalte zensiert hat, will Google das nicht laenger mitmachen. Ausgeloest haben das vor allem kuerzlich durchgefuehrte Angriffe auf Google und andere Unternehmen aus dem Bereichen Internet, Finanzen, Technologie, Medien und Chemie. Google hat die U.S. Behoerden und die jeweiligen Firmen ueber die Angriffe informiert und zieht daraus nun Konsequenzen.</p>
<p>Die Angriffe auf Google bezogen sich vor allem auf Diebstahl von Intellectual Property und auf GMail Konten von Menschenrechtsaktivisten. Hier mal ein Auszug aus dem <a href="http://googleblog.blogspot.com/2010/01/new-approach-to-china.html">Blogpost von Google</a>:</p>
<blockquote><p>These attacks and the surveillance they [China] have uncovered&#8211;combined with the attempts over the past year to further limit free speech on the web&#8211;have led us to conclude that we should review the feasibility of our business operations in China. <strong>We have decided we are no longer willing to continue censoring our results on Google.cn</strong>, and so over the next few weeks we will be discussing with the Chinese government the basis on which we could operate an unfiltered search engine within the law, if at all. <strong>We recognize that this may well mean having to shut down Google.cn, and potentially our offices in China.</strong></p></blockquote>
<p>Am Ende des Blogposts nimmt Google noch die Mitarbeiter in China in Schutz und schreibt, dass dieser neue Weg, den Google nun einschlaegt, einzig und allein von den Entscheidungstraegern in den USA bestimmt wurde:</p>
<blockquote><p>We want to make clear that this move was driven by our executives in the United States, without the knowledge or involvement of our employees in China who have worked incredibly hard to make Google.cn the success it is today.</p></blockquote>
<p>Google hat nun also endlich Menschlichkeit bewiesen und erklaert der chinesischen Zensurpolitik den Krieg.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.visusnet.de/2010/01/13/freedom-of-speech/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
