<?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>Cake Bakery &#187; Code</title>
	<atom:link href="http://cakebakery.de/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebakery.de</link>
	<description>Rezepte für die Entwicklung mit CakePHP</description>
	<lastBuildDate>Wed, 22 Jul 2009 14:59:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Themes in CakePHP</title>
		<link>http://cakebakery.de/2009/07/06/themes-in-cakephp/</link>
		<comments>http://cakebakery.de/2009/07/06/themes-in-cakephp/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 15:21:13 +0000</pubDate>
		<dc:creator>dirk.olbertz</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/?p=58</guid>
		<description><![CDATA[CakePHP bringt von Haus aus eine Unterst&#252;tzung sogenannter &#8220;Themes&#8221;. Man kann sie mit Wordpress-Themes vergleichen, wobei CakePHP hier nat&#252;rlich nur die M&#246;glichkeit anbietet, diese Themes den eigenen Nutzern zur Verf&#252;gung zu stellen.
Wenn man aber, wie bei NoseRub Admins und Usern die M&#246;glichkeit geben m&#246;chte, das Aussehen der gesamten Installation, oder aber der eigenen Profilseite anzupassen, [...]]]></description>
			<content:encoded><![CDATA[<p>CakePHP bringt von Haus aus eine Unterst&#252;tzung sogenannter &#8220;Themes&#8221;. Man kann sie mit Wordpress-Themes vergleichen, wobei CakePHP hier nat&#252;rlich nur die M&#246;glichkeit anbietet, diese Themes den eigenen Nutzern zur Verf&#252;gung zu stellen.</p>
<p>Wenn man aber, wie bei <a href="http://noserub.com/">NoseRub</a> Admins und Usern die M&#246;glichkeit geben m&#246;chte, das Aussehen der gesamten Installation, oder aber der eigenen Profilseite anzupassen, sind die Themes eine prima Sache &#8211; und auch sehr leicht zu implementieren.</p>
<p>Die Templates f&#252;r die Webseiten sind bei Cake in sogenannte <em>Views</em> organisiert und liegen im Normalfall unter <code>/app/views</code>. Zugeh&#246;rige CSS- und JavaScript-Dateien befinden sich unter <code>/app/webroot/</code>.</p>
<p>Um die Unterst&#252;tzung von Themes im eigenen CakePHP Projekt zu aktivieren, muss man erst einmal im entsprechenden Controller auf eine andere View-Klasse wechseln. Der Einfachheit halber kann man das direkt im AppController machen:</p>
<pre name="code" class="php">
class AppController extends Controller {
    public $view = 'Theme';
    ...
}
</pre>
<p>Vor dem Rendern muss CakePHP nun au&#223;erdem mitgeteilt werden, welches Theme benutzt werden soll. F&#252;r NoseRub habe ich das ebenfalls im AppController gemacht um als Standardwert ein vorgegebenes Theme auszuw&#228;hlen:</p>
<pre name="code" class="php">
class AppController extends Controller {
    public $view = 'Theme';
    public $theme = 'default';
    ...
}
</pre>
<p>Man kann das aber nat&#252;rlich auch an anderer Stelle im Controller &#228;ndern. Wenn also z.B. eine Profilseite des Users angezeigt werden soll und dabei ein vom User ausgew&#228;hltes Design genommen werden soll, kann man dies so erreichen:</p>
<pre name="code" class="php">
class UsersController extends AppController {
    public $uses = array('User');

    public function view($username) {
        $user = $this->find('first', array(
            'conditions' => array(
                'User.username' => $username
            )
        ));
        $this->set('user', $user);

        // todo: check that user exists before proceeding!
        // todo: check that value of user theme is valid

        $this->theme = $user['User']['theme'];
    }
}
</pre>
<p>Die Daten f&#252;r dieses View such CakePHP nun an folgenden Orten: <code>/app/views/themed/[theme name]/</code> und <code>/app/webroot/themed/[theme name]/</code>. F&#252;r ein Theme mit dem Namen <em>green</em> w&#252;rde Cake nun also zuerst das Default-Layout (ein anderes ist ja nicht gesetzt) unter <code>/app/views/themed/green/layouts/default.ctp</code> suchen und dann das View, welches hier gerendert werden soll in <code>/app/views/themed/green/users/view.ctp</code>.</p>
<p>Dabei ist das sch&#246;ne, dass Cake immer auf die Version ohne <code>themed</code> im Pfad zur&#252;ckgreift, falls die Variante mit <code>themed</code> gar nicht vorhanden ist. Wenn man seine Applikation also sch&#246;n mit Views und Elementen strukturiert, k&#246;nnen die Themes sehr einfach ausfallen und teilweise nur anderes CSS enthalten. (Man denke nur an <a href="http://www.csszengarden.com/">CSS Zen Garden</a>!)</p>
<p>Das funktioniert nat&#252;rlich auch f&#252;r Javascript Dateien. In NoseRub wird das JavaScript per Element in das Layout hinzugef&#252;gt und zwar &#252;ber folgende zwei Zeilen:<br />
<code name="code" class="php"><br />
echo $javascript->link('theme.js');<br />
echo $javascript->link('noserub.js');<br />
</code></p>
<p>Unter <code>/app/webroot/js/theme.js</code> liegt nun eine leere Implementierung, die automatisch von einer themespezifischen <code>theme.js</code> &#252;berschrieben wird, weil CakePHP diese ja beim Rendern vorziehen wird.</p>
<p>Einziger wirklicher Nachteil der Themes in CakePHP ist, das Views und CSS/JS von einander getrennt sind. Man kann also nicht einfach nur ein einziges Verzeichnis irgendwo hochladen um ein Theme zu &#8220;installieren&#8221;, wie das z.B. bei Wordpress geht. Andererseits ist das aber auch ein riesiger Sicherheitsgewinn, weil der PHP-Code in den Views abseits des &#246;ffentlich zug&#228;nglichen Webroots (vorausgesetzt, der liegt auf <code>/app/webroot/</code>, wie es empfohlen wird).</p>
<p>F&#252;r NoseRub werden wir daf&#252;r aber im Admin-Bereich eine Upload-M&#246;glichkeit geben, wo dann ein Archiv mit zwei Ordnern <em>views</em> und <em>webroot</em> erwartet werden &#8211; sofern uns keine bessere M&#246;glichkeit einf&#228;llt&#8230;</p>
<p><strong>Update: </strong> In den Kommentaren hat Robert noch eine wichtige Anmerkung zum Thema Caching und Themes gemacht.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2009/07/06/themes-in-cakephp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>findCount() und belongsTo</title>
		<link>http://cakebakery.de/2007/02/16/findcount-und-belongsto/</link>
		<comments>http://cakebakery.de/2007/02/16/findcount-und-belongsto/#comments</comments>
		<pubDate>Fri, 16 Feb 2007 11:23:42 +0000</pubDate>
		<dc:creator>dirk.olbertz</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/2007/02/16/findcount-und-belongsto/</guid>
		<description><![CDATA[Die Model-Funktionen findCount() und findCountAll() ber&#252;cksichtigen die Model-Relation belongsTo, was zu ungewollten Effekten f&#252;hrt, da dies zu einigen JOINs in der Datenbankabfrage resultiert und somit mehr oder weniger Resultate liefert, als eigentlich beabsichtigt.
Deshalb sollte man auch vor einem findCount() auf expects() zur&#252;ckgreifen, um nur die Models zu ber&#252;cksichtigen, die auch gewollt sind:

$this->MeinModel->recursive = 0;
$this->MeinModel->expects('MeinModel');
$anzahl = [...]]]></description>
			<content:encoded><![CDATA[<p>Die Model-Funktionen <code>findCount()</code> und <code>findCountAll()</code> ber&#252;cksichtigen die Model-Relation <code>belongsTo</code>, was zu ungewollten Effekten f&#252;hrt, da dies zu einigen JOINs in der Datenbankabfrage resultiert und somit mehr oder weniger Resultate liefert, als eigentlich beabsichtigt.</p>
<p>Deshalb sollte man auch vor einem <code>findCount()</code> auf <a href="http://cakebakery.de/2007/02/16/fallstricke-bei-den-model-relationen/">expects()</a> zur&#252;ckgreifen, um nur die Models zu ber&#252;cksichtigen, die auch gewollt sind:</p>
<pre name="code" class="php">
$this->MeinModel->recursive = 0;
$this->MeinModel->expects('MeinModel');
$anzahl = $this->MeinModel->findCount();
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2007/02/16/findcount-und-belongsto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Der Unterschied zwischen execute() und query()</title>
		<link>http://cakebakery.de/2007/02/15/der-unterschied-zwischen-execute-und-query/</link>
		<comments>http://cakebakery.de/2007/02/15/der-unterschied-zwischen-execute-und-query/#comments</comments>
		<pubDate>Thu, 15 Feb 2007 10:04:26 +0000</pubDate>
		<dc:creator>dirk.olbertz</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/2007/02/15/der-unterschied-zwischen-execute-und-query/</guid>
		<description><![CDATA[Schaut man sich die Beschreibung zu beiden Methoden an, ist eigentlich kein Unterschied auszumachen. In der Praxis k&#246;nnen diese beiden Anfragen aber durchaus unterschiedlich reagieren:

$mein_model->cacheQueries = false;
$mein_model->query('SELECT COUNT(DISTINCT plz) FROM test_table');

$mein_model->cacheQueries = false;
$mein_model->execute('SELECT COUNT(DISTINCT plz) FROM test_table');

query() beachtet n&#228;mlich die Cache-Einstellungen via cacheQueries nicht, w&#228;hrend execute() dies aber tut. Die R&#252;ckgabe beider Methoden ist identisch, [...]]]></description>
			<content:encoded><![CDATA[<p>Schaut man sich die Beschreibung zu beiden Methoden an, ist eigentlich kein Unterschied auszumachen. In der Praxis k&#246;nnen diese beiden Anfragen aber durchaus unterschiedlich reagieren:</p>
<pre name="code" class="php">
$mein_model->cacheQueries = false;
$mein_model->query('SELECT COUNT(DISTINCT plz) FROM test_table');

$mein_model->cacheQueries = false;
$mein_model->execute('SELECT COUNT(DISTINCT plz) FROM test_table');
</pre>
<p><code>query()</code> beachtet n&#228;mlich die Cache-Einstellungen via <code>cacheQueries</code> nicht, w&#228;hrend <code>execute()</code> dies aber tut. Die R&#252;ckgabe beider Methoden ist identisch, man sollte also nach M&#246;glichkeit <code>execute()</code> statt <code>query()</code> benutzen, damit man mittels <code>cacheQueries</code> immer die M&#246;glichkeit hat, auf das Model-Caching von Cake Einflu&#223; nehmen zu k&#246;nnen.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2007/02/15/der-unterschied-zwischen-execute-und-query/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>UTF-8 Model</title>
		<link>http://cakebakery.de/2006/08/24/utf-8-model/</link>
		<comments>http://cakebakery.de/2006/08/24/utf-8-model/#comments</comments>
		<pubDate>Thu, 24 Aug 2006 19:40:58 +0000</pubDate>
		<dc:creator>christian</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/2006/08/24/utf-8-model/</guid>
		<description><![CDATA[Ich m&#246;chte euch schnell einen kleinen Trick zu meinem Lieblingsthema Encoding und I18N zeigen. In CakePHP ist zwar in der n&#228;chsten gr&#246;&#223;eren Version eine I18N Unterst&#252;tzung geplant, ich wei&#223; jedoch nicht in wie weit diese schon implementiert wurde. Nat&#252;rlich haben wir keine Zeit auf diese Version zu warten.
Wenn man die Daten seiner Model UTF-8 kodiert [...]]]></description>
			<content:encoded><![CDATA[<p>Ich m&#246;chte euch schnell einen kleinen Trick zu meinem Lieblingsthema Encoding und I18N zeigen. In CakePHP ist zwar in der n&#228;chsten gr&#246;&#223;eren Version eine I18N Unterst&#252;tzung geplant, ich wei&#223; jedoch nicht in wie weit diese schon implementiert wurde. Nat&#252;rlich haben wir keine Zeit auf diese Version zu warten.<br />
Wenn man die Daten seiner Model UTF-8 kodiert vom Datenbankserver bekommen will, muss man wie bekannt sein sollte, bei jeder neuen Verbindung zuerst das &#8220;set names &#8216;utf8&#8242;&#8221; SQL Statement absetzen um dem Server die Kodierung mitzuteilen. In CakePHP hat man die M&#246;glichkeit bei &#8220;beforeFind&#8221; einzuhacken. Das ist jedoch keine optimale L&#246;sung, da dann vor jedem Query dieses Statement abgesetzt wird. Besser ist folgende Methode, indem der Konstruktor des AppModel erweitert wird:</p>
<pre name="code" class="php">
class AppModel extends Model
{
  function __construct($id=false, $table=null, $ds=null) {
    parent::__construct($id, $table, $ds);
    $this->execute( "SET NAMES 'UTF8'" );
  }
}
</pre>
<p>Auf <a href="http://www.get-the-answer.info">GetTheAnswer</a> gibt es von mir ein etwas ausf&#252;hrlicheres <a href="http://www.get-the-answer.info/comments.php?DiscussionID=5&#038;page=1#Item_1">Tutorial zu Encoding</a> jedoch in Englisch.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2006/08/24/utf-8-model/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Zutaten weglassen beim Backen eines Kuchens</title>
		<link>http://cakebakery.de/2006/08/24/zutaten-weglassen-beim-backen-eines-kuchens/</link>
		<comments>http://cakebakery.de/2006/08/24/zutaten-weglassen-beim-backen-eines-kuchens/#comments</comments>
		<pubDate>Thu, 24 Aug 2006 14:24:32 +0000</pubDate>
		<dc:creator>Daniel Hofstetter</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/2006/08/24/zutaten-weglassen-beim-backen-eines-kuchens/</guid>
		<description><![CDATA[In diesem Artikel besch&#228;ftige ich mich mit zwei Fragen, die praktisch t&#228;glich im IRC-Channel #cakephp gestellt werden: &#8220;Wie kann ich einen Controller erstellen, der kein Model verwendet?&#8221; und &#8220;Wie kann ich ein Model erstellen, welches keine Tabelle verwendet?&#8221;. 
Die L&#246;sungen f&#252;r beide Fragen sind sehr einfach, doch sind sie zugegebenermassen nicht ganz offensichtlich f&#252;r Anf&#228;nger. [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Artikel besch&#228;ftige ich mich mit zwei Fragen, die praktisch t&#228;glich im IRC-Channel #cakephp gestellt werden: &#8220;Wie kann ich einen Controller erstellen, der kein Model verwendet?&#8221; und &#8220;Wie kann ich ein Model erstellen, welches keine Tabelle verwendet?&#8221;. </p>
<p>Die L&#246;sungen f&#252;r beide Fragen sind sehr einfach, doch sind sie zugegebenermassen nicht ganz offensichtlich f&#252;r Anf&#228;nger. Am besten zeige ich die L&#246;sungen gleich anhand von zwei einfachen Beispielen.</p>
<p>Zuerst der Controller, der kein Model verwendet:</p>
<pre name="code" class="php">
class WithoutModelsController extends AppController
{
    var $uses = array();

    // some functions
}
</pre>
<p>Und hier das Model, welches keine Tabelle verwendet:</p>
<pre name="code" class="php">
class ModelWithoutTable extends AppModel
{
    var $useTable = false;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2006/08/24/zutaten-weglassen-beim-backen-eines-kuchens/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Datumsangaben des HTML-Helpers</title>
		<link>http://cakebakery.de/2006/08/15/datumsangaben-des-html-helpers/</link>
		<comments>http://cakebakery.de/2006/08/15/datumsangaben-des-html-helpers/#comments</comments>
		<pubDate>Tue, 15 Aug 2006 15:54:05 +0000</pubDate>
		<dc:creator>dirk.olbertz</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://cakebakery.de/2006/08/15/datumsangaben-des-html-helpers/</guid>
		<description><![CDATA[Wer in seinen Cake-Projekten Datumsangaben verwalten muss, sollte dazu auf den HTML-Helper zur&#252;ckgreifen. Denn f&#252;r die beiden Datentypen DATE und DATETIME gibt es da eine einfache M&#246;glichkeit, diese f&#252;r den Benutzer editierbar zu machen.
Zwischenruf: Eigentlich sollte diese Funktion ja im Form-Helper angesiedelt, meint selbst Nate (dritter Abschnitt).
Im View wird der Helper so verwendet:

echo $html->dateTimeOptionTag('Booking/date_from', 'DMY', [...]]]></description>
			<content:encoded><![CDATA[<p>Wer in seinen Cake-Projekten Datumsangaben verwalten muss, sollte dazu auf den HTML-Helper zur&#252;ckgreifen. Denn f&#252;r die beiden Datentypen DATE und DATETIME gibt es da eine einfache M&#246;glichkeit, diese f&#252;r den Benutzer editierbar zu machen.</p>
<p><i>Zwischenruf: Eigentlich sollte diese Funktion ja im Form-Helper angesiedelt, meint selbst <a href="http://cake.insertdesignhere.com/posts/view/3">Nate</a> (dritter Abschnitt).</i></p>
<p>Im View wird der Helper so verwendet:</p>
<pre name="code" class="php">
echo $html->dateTimeOptionTag('Booking/date_from', 'DMY', 'NONE', null, null, null, false);
</pre>
<p>Bitte nicht durch den Namen <i>dateTimeOptionTag</i> verwirren lassen, denn es lassen sich damit auch reine Datumsangaben realisieren! Dies wird dadurch erreicht, dass der dritte Parameter (<i>$timeFormat</i>) auf <i>NONE</i> gesetzt wird. Andere Optionen f&#252;r diesen Parameter sind <i>12</i> und <i>24</i>, womit dann ausgewÃ¤hlt wird, in welchem Format die Uhrzeit angezeigt wird.</p>
<p>Den letzten Parameter (<i>$showEmpty</i>) habe ich hier auf <i>false</i> gesetzt, damit der Benutzer nicht eine Angabe leer lassen kann, wie z.B. Jahr oder Monat.</p>
<p>Ansonsten ist die Verwendung ganz einfach. Das Feld <i>date_from</i> ist in der MySQL-Datenbank vom Typ <i>DATE</i> und wird bei der Ausgabe &#252;ber den Helper automatisch auf drei Select-Boxen f&#252;r Tag, Monat und Jahr aufgesplittet.</p>
<p>Um die Daten im Controller anschlie&#223;end auch wieder in nur ein Feld von <i>$this->data['Booking']</i> zu haben, muss noch</p>
<pre name="code" class="php">
$this->cleanUpFields();
</pre>
<p>vor der weiteren Verwendung in der entsprechenden Action eingebaut werden. Diese Funktion sammelt n&#228;mlich die einzelnen Variablen, wie sie durch den Helper in den HTML-Code der Seite geschrieben wurden und setzt sie zur urspr&#252;nglichen Variable zusammen (hier <i>date_from</i>).</p>
<p>Aber Vorsicht! Im Moment gibt es noch einen <a href="https://trac.cakephp.org/ticket/1245">Bug in cleanUpFields()</a>. Dazu muss man verstehen, wie <i>cleanUpFields()</i> funktioniert: diese Controller-Funktion geht alle Felder des aktuellen Models durch und &#252;berpr&#252;ft, ob dort eines mit <i>DATE</i> oder <i>DATETIME</i> vorhanden ist. Wenn ja, wird <i>$this->data</i> entsprechend modifiziert. Wenn man in seinem Controller nun aber auf mehrere Models zurÃ¼ckgreift, werden trotzdem immer nur die Felder des Models &#252;berpr&#252;ft, welches zum aktuellen Controller &#8220;geh&#246;rt&#8221;.</p>
<p>Bis der Fehler gefixt wird, kann man sich in seinem Controller so behelfen:</p>
<pre name="code" class="php">
$this->modelClass = 'Bookings';
$this->cleanUpFields();
$this->modelClass = 'User';
</pre>
<p>In diesem Beispiel befinden wir uns im <i>UsersController</i> und wollen <i>cleanUpFields()</i> f&#252;r das Model <i>Bookings</i> benutzen.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebakery.de/2006/08/15/datumsangaben-des-html-helpers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
