CakePHP/mod_rewrite: Bestimmten Ordner von RewriteRules ausschließen

Die RewriteRules bei CakePHP sind so eingestellt, dass man an Ordner im root-Verzeichnis nicht dran kommt. Möchte man bspw. einen bestimmten Ordern von der RewriteRule ausschließen, muss folgende Regel in die .htaccess dazugeschrieben werden (im root-Verzeichnis von CakePHP):

RewriteRule ^Ordnername – [L,NC]

wobei – ausdrückt, dass nichts passieren soll
L steht für Last Rule
und NC für no-case, so dass Groß-/Kleinschreibung ignoriert wird (ordnername wird also auch erreicht)

Alles was nun mit “Ordnername” beginnt, betrifft diese Regel.

CakePHP: Input Validierung mit mehreren Regeln

Fast einen Monat ist es her seit dem letzten Post. Nur ein kleiner Tipp und auch kein besonders aufwändiger für multiple Validierungsfeldern pro Eingabefeld. Die Überprüfung eines Eingabefeld für eine deutsche Bankleitzahl könnte beispielsweise so im Model implementiert werden:

var $validate = array(
'blz' => array(
									'minLength' => array(
										'rule' => array('minLength', 8),
										'message' => 'Bitte geben Sie eine gültige Bankleitzahl eines deutschen Bankinstituts ein.'),
									'maxLength' => array(
										'rule' => array('maxLength', 8),
										'message' => 'Bitte geben Sie eine gültige Bankleitzahl eines deutschen Bankinstituts ein.'),
									'numeric' => array(
									'rule' => 'numeric',
									'required' => true,
									'message' => 'Bitte geben Sie nur Zahlen als Bankleitzahl ein.'))
)

CakePHP: This email was sent using the CAKEPHP framework

Um diesen schönen Satz einmal nicht in einer mit der Email-Component versendeten Email zu erhalten, genügt es, das default-layout für die Emails in der App zu überschreiben. Also einfach eine “default.ctp” Datei innerhalb “app/views/layouts/email/html” bzw. “app/views/layouts/email/text” erzeugen mit dem Inhalt:

echo $content_for_layout

Das war’s auch schon.

CakePHP: Validierung ohne zu Speichern

Es kann vorkommen, da möchte man die Nutzereingaben in einem Formular zunächst nur validieren, bevor sie in der Datenbank gespeichert werden. Dies kann zum Beispiel bei einem Bestellvorgang sein, bei dem die eingegebenen Nutzerangaben noch einmal zur Übersicht dem Nutzer angezeigt werden soll und erst nach dieser Prüfung gesichert werden sollen.
Dafür stellt CakePHP die Methode ‘validates()‘ des Models bereit.

In der CakePHP-Dokumentation steht genau dieser Anwendungsfall beschrieben, jedoch überliest man auf die schnelle ggf. eine wichtige Stelle: Vor der Validierung müssen die Daten auf jeden Fall dem Model übergeben werden.

$this->Modelname->set($this->data);
if($this->Modelname->validates()) { #Alles ok, Überprüfungsseite anzeigen
#....
} else { #Daten validieren nicht
#...
}

CakePHP: dateFormat und timeFormat

Mit Hilfe des Form-Helpers lassen sich bequem Eingabefelder für Datums- oder Zeitangaben erstellen. Der Form-Helper erkennt aus der Datenbank heraus, was für ein Input-Feld er generieren muss. Um die Anordnung der entstehenden Select-Felder an das deutsche Format anzupassen, kann dem ‘options’-Array einmal der Schlüssel “dateFormat” für Datumsangaben und der Schlüssel “timeFormat” für Zeitangaben übergeben werden.

Um ein Datum in das deutsche Format zu bringen genügt als Wert die Angabe “DMY”. Bei “timeFormat” gibt man “24″ für die deutsche 24-Stunden Darstellung an.

		echo $form->input('tag', array('label' => 'Tag:', 'dateFormat' => 'DMY'));
		echo $form->input('von', array('label' => 'von:', 'timeFormat' => 24));

CakePHP: Fat Models innerhalb von Plugins…

… oder auch: Wieso wirft CakePHP ständig den SQL Error: 1064 und nimmt als SQL Query meinen Methodennamen?

Folgender Hintergrund: Wir befinden uns innerhalb eines Plugins (‘app/plugins/pluginname/’). Innerhalb des Plugins exisiteren die Controller, die Models und die Views. Die Models erben vom PluginnameAppModel, dieses wiederrum erbt vom AppModel.

Macht man das Model zu einem “Fat Model”, also ergänzt eigene Methoden und ruft diese Methoden innerhalb des dazugehörigen Controllers auf, so erscheint der SQL Error Code 1064.

Die Lösung zum Problem ist recht simpel und einleuchtend, man kommt nur nicht so schnell drauf ;-) . Innerhalb des Controllers muss man mit dem $uses-Attribut das zu nutzende Model bestimmen. Nur reicht es nicht aus, den Modelnamen in das Array zu schreiben, sondern das dazugehörige Plugin eben auch, getrennt durch einen Punkt.

var $uses = array('Pluginname.Model1', 'Pluginname.Model2');

CakePHP 1.3.4: Datenvalidierung und eine Warnung

Eventuell kommt die folgende Warnung bei einer Datenvalidierung im Model:

Warning (2): preg_match() [function.preg-match]: Empty regular expression [CORE/cake/libs/model/model.php, line 2596]

Die Warnung trat auf, als zwar der ‘rule’-Schlüssel im Validierungsarray angegeben wurde, er jedoch nur auf ‘false’ stand. Sobald eine Regel angegeben wird, tritt diese Warnung nicht mehr auf.
Es muss also immer eine Regel angegeben werden!

var $validate = array(
						'name' => array(
									'rule' => 'notEmpty',
									'required' => true,
									'message' => 'Bitte gib Deinen Nachnamen ein.'),
						'vorname' => array(
									'rule' => 'notEmpty',
									'required' => true,
									'message' => 'Bitte gib Deinen Vornamen ein.'),
						'email' => array(
									'rule' => array('email', true),
									'message' => 'Bitte gib Deine eMail-Adresse ein.'));

CakePHP: $displayField funktioniert nicht innerhalb von Plugins?!

Es existiert eine $belongsTo-Beziehung, angenommen zwischen einem Impressum und einem Buch. Das Impressum-Model wurde also entsprechend mit dem $belongsTo-Attribut beschrieben. Nun soll ein neues Impressum eines Buches angelegt werden und dafür soll bpsw. nicht der Buchname aus dem Buch-Model, sondern die ISBN-Nummer als Referenz herangezogen werden. Also bekommt das Buch-Model das Model-Attribut $displayField = ‘isbn’. Das scheint aber nicht zu funktionieren. Wenn jemand weiß warum nicht, dann bitte kommentieren! Ich freue mich auf antworten! Bis dahin kann man das natürlich umgehen, indem man das $displayField-Atribut unmittelbar vor dem Aufruf im Controller zur Laufzeit setzen lässt:

#innerhalb des impressum controller
$this->Impressum->Buch->displayField = 'isbn';
$this->set('buch',$this->Impressum->Buch->find('list');

Das Ganze findet innerhalb eines Plugins statt. Nennen wir das Plugin “Bibliothek”…Muss man hier etwas beachten?

Das erdachte Szenario möge man mir verzeihen. Es geht hier nur ums Prinzip ;-)

 

Die Lösung ist gefunden!

Näheres dazu und ergänzt um virtuelle Felder im Blog “CakePHPDoku”

CakePHP: Ajax Layout

Werden Links oder Formulare mittels des AJAX-Helpers erstellt, um die Daten ansynchron zu laden und in einem DIV-Bereich anzuzeigen, wird in diesem DIV ggf. das Default-Layout genutzt. So kommt es dann zum Effekt der “Seite in der Seite”. Um das zu vermeiden, muss das Layout bspw. in der Methode (Action) entsprechend gesetzt werden. Möglich ist ein eigenes AJAX-Layout zu entwerfen oder aber gar kein Layout zu nutzen:

function TuDingeUndZeigeSieDannImDivAn () {
   $this->layout = '';
   $ergebnis = $this->tuWas();
   $this->set('view',$ergebnis);
}

CakePHP: Monatsnamen auf Deutsch (Teil 2)

In Ergänzung zu meinem Blogpost “CakePHP: Monatsnamen auf Deutsch” kann man die erstelle ‘locale’ Datei natürlich auch nutzen, um die Monatsnamen in Views auf Deutsch anzeigen zu lassen.

Dazu muss die ‘__()’ – Funktion, wie bei der Internationalisierung üblich, genutzt werden. Letzendlich sieht das Ganze dann so aus:


__(date('F',strtotime($controllerKlasse['Klasse']['datum'])),true)

wobei date(‘F’) den ausgeschriebenen Monatsnamen ausgibt. (siehe dazu auch die date() Dokumentation auf php.net)

CakePHP: Fatal error: Class ‘ConnectionManager’ not found in … sanitize on line 72

Falls mir jemand den Fehler erklären möchte, ich freue mich über jede Antwort!
Die Lösung zumindest liefert das einbinden des ‘ConnectionsManagers‘ in den Controller, in dem auch eine sanitize-Methode zum Einsatz kommt.

App::Import('ConnectionManager'); 

Diese Zeile muss vor Beginn der Deklaration der Klasse stehen, ganz genauso wie auch der Import der Sanitize-Klasse.
Ich habe keine Ahnung, wieso CakePHP (1.2.6) den ConnectionManager nicht direkt im Core ordentlich mit eingebunden hat.

Also Feuer frei für Kommentare!!!

CakePHP: Fatal error: Call to undefined method stdClass::send()

Wer in das Verlangen kommt, die Email-Component von CakePHP nutzen zu wollen, sollte sich stets eines Schusselfehlers bewußt sein. Die Email-Component bindet man wie gewöhnlich über

$components = array('Email');

in den jeweiligen Controller ein. Wer jedoch bei ‘$components’ das ‘s’ vergisst (Schusselfehler) erhält die im Titel dargestellte Fehlermeldung.

CakePHP: Redirect auf statische Seite

Vermutlich kommt das Problem seltener vor, aber nichts destotrotz verdeutlicht es ganz anschaulich die Funktionsweise der ‘redirect‘-Methode.
Angenommen man befindet sich innerhalb eines Controllers in einem Plugin und möchte nach der Ausführung einer Methode auf eine statische Seite umleiten (redirecten), dann übergibt man dieser Methode mehrere Parameter in der folgenden Form:

$this->redirect(array('controller' => 'pages', 'action'=>'display','ueberuns/kontakt', 'plugin' => null));

Der ‘action‘-Schlüssel muss ‘display‘ als Wert haben, da nur diese Methode im pages_controller existiert. Damit der pages_controller weiß, welche statische Seite aufgerufen werden soll, wird als weiterer Parameter die View übergeben (in diesem Fall die View ‘kontakt‘ im Ordner ‘ueberuns‘. Damit das Ganze nicht innerhalb des momentanen Plugins stattfindet, setzen wir den ‘plugin‘-Schlüssel noch null und schon funktioniert der Redirect.

CakePHP: Breadcrumb-Helper

Einen funktionierenden Breadcrumb-Helper gibt es in der CakePHP bakery. Kann diesen Helper nur empfehlen. Er funktioniert wunderbar. Eine Ausnahme: Die Auto-Analyse (dritter Parameter = ‘auto’) scheint in statischen Seiten (pages_controller) ab der dritten Ebene nicht zu funktionieren. Ist aber nicht weiter schlimm, denn man kann den Parameter ja manuell setzen.

Hier ist der Link!

CakePHP: lastlogin eines Nutzers speichern

Um den letzten erfolgreichen Login eines Nutzers in einem Feld ‘lastlogin‘ zu speichern, muss in der login()-Methode des UsersController folgender Code eingefügt werden:

if ($this->Auth->user()) { 
 $this->User->id = $this->Auth->user('id'); 
 $this->User->saveField('lastlogin', date("Y-m-d H:i:s")); 
 $this->redirect('/controller/action'); 
}

Damit das ganze auch aufgerufen wird, muss im app_controller noch das autoRedirect ausgestellt werden. Dies erklärt auch die redirect()-Methode in der oben dargestellten login()-Methode.

Im app_controller muss also noch folgendes stehen (oder im beforeFilter() des UsersController)

$this->Auth->autoRedirect = false;