Development

Documentation/de_DE/my_first_project/trunk

You must first sign up to be able to contribute.

Version 4 (modified by gordon, 11 years ago)
actual to "Gültigkeit eines Formulars"

Original Text: http://www.symfony-project.com/tutorial/my_first_project.html

Mein erstes Symfony-Projekt

So, du möchtest es versuchen? Lass uns zusammen eine voll funktionstüchtige Webanwendung in einer Stunde erstellen. Such Dir etwas aus! Einen Buchhandel? Ok, eine andere Idee. Ein Weblog! Das ist eine gute Idee. Lass uns anfangen!

Wir setzen voraus, dass du Apache mit PHP5 auf deinem lokalen Rechner installiert und gestartet hast. Du brauchst außerdem noch die SQLite-Erweiterung, welche bei PHP5 dabei bzw. standardmäßig einkompiliert ist. Seit der Version 5.1.0 von PHP, musst du die Erweiterung allerdings manuell in der php.ini aktivieren (siehe hier).

Installation von Symfony und Initialisierung des Projektes

Um schneller ans Ziel zu kommen, werden wir die Symfony-Sandbox verwenden. Dies ist ein leeres Symfony-Projekt, bei dem alle erforderlichen Bibliotheken eingebunden und die Grundkonfiguration bereits erledigt ist. Der große Vorteil der Sandbox gegenüber anderen Installationsarten ist, dass du sofort damit anfangen kannst mit Symfony zu experimentieren.

Lade dir die Sandbox hier herunter: sf_sandbox.tgz und entpacke sie in deinem root-Webverzeichnis. Für mehr Informationen solltest du einen Blick in die beiliegende Readme-Datei werfen. Die resultierende Dateistruktur sollte folgendermaßen aussehen:

www/
  sf_sandbox/
    apps/
      frontend/
    batch/
    cache/
    config/
    data/
      sql/
    doc/
      api/
    lib/
      model/
    log/
    test/
    web/
      css/
      images/
      js/
      uploads/

Dies zeigt ein sf_sandbox-Projekt, dass eine frontend-Anwendung enthält. Teste die Sandbox indem du folgende Adresse aufrufst:

http://localhost/sf_sandbox/web/index.php/

Du solltest im Erfolgsfalle die folgende Seite sehen:

http://www.symfony-project.com/images/tutorials/first_congrats.gif

Hinweis: Falls du die Seite nicht siehst, solltest du in deiner php.ini überprüfen, ob magic_quotes_gpc auf off gesetzt ist. Weitere Hilfe findest du im Installations-Forum, wo bereits viele spezielle Fälle gelöst wurden.

Du kannst Symfony auch in einem eigenen Ordner installieren und deinen Webserver mit Virtual Hosts und Alias konfigurieren. Das Symfony-Buch enthält detaillierte Kapitel über die Installation, Projekt-Erstellung und Dateistruktur.

Initialisierung des Datenmodells

Der Weblog wird Einträge verwalten und es ermöglichen diese zu kommentieren. Erstelle eine schema.yml Datei im Verzeichnis sf_sandbox/config/ und füge folgende Konfiguration ein:

propel:
  weblog_post:
    _attributes: { phpName: Post }
    id:
    title:       varchar(255)
    excerpt:     longvarchar
    body:        longvarchar
    created_at:
  weblog_comment:
    _attributes: { phpName: Comment }
    id:
    post_id:
    author:      varchar(255)
    email:       varchar(255)
    body:        longvarchar
    created_at:

This configuration file uses the YAML syntax. It's a very simple language that allows XML-like tree structures described by indentation. Furthermore, it is faster to read and write than XML. The only thing is, the indentation has a meaning and tabulations are forbidden, so remember to use spaces for indentation. You will find more about YAML and the symfony configuration in the configuration chapter.

Der Quelltext lässt sich schneller erklären als lesen: Er beschreibt die zwei Tabellen Post und Comment. Speichere die Datei, öffne die Kommandozeile, wechsle in das Verzeichnis sf_sandbox/ und gib folgendes ein:

$ php symfony propel-build-model

Hinweis: Bevor du den symfony-Befehl ausführst, solltest du sicherstellen, dass du dich in dem Hauptverzeichnis deines Symfony-Projektes (sf_sandbox/) befindest.

Einige Klassen werden im sf_sandbox/lib/model/ Verzeichnis erstellt. Dieses sind die Klassen des Objekt-relationalen Mappings, die uns den Zugang zu einer relationalen Datenbank aus Objekt-orientiertem Code heraus erlauben, ohne auch nur ein einziges SQL-Query zu schreiben. Symfony benutzt die Propel-Bibliothek für diesen Zweck. Wir werden diese Objekte weiterführend das Modell (mehr findest Du im Modell-Kapitel) nennen.

Gib nun folgendes in der Kommandozeile ein:

$ php symfony propel-build-sql

Eine Datei lib.model.schema.sql wird in sf_sandbox/data/sql/ angelegt. Dieses SQL-Query kann benutzt werden, um eine Datenbank mit der gleichen Tabellenstruktur anzulegen. Du kannst unter Verwendung der Kommandozeile oder eines Web-Interfaces eine MySQL-Datenbank erstellen (wie im Modell-Kapitel beschrieben). Zum Glück ist die Sandbox so konfiguriert, um out-of-the-box mit einer simplen SQLite-Datei zu arbeiten, so dass keine Datenbankunterstützung benötigt wird. Standardmäßig benutzt das sf_sandbox-Projekt die Datenbank sandbox.db, die sich im Verzeichnis sf_sandbox/data/ befindet. Um die auf der SQL-Datei basierende Tabellenstruktur zu generieren, gib folgendes ein:

$ php symfony propel-insert-sql

Hinweis: Mach dir keine Sorgen, falls an dieser Stelle eine Warnung erscheint, das ist normal. Der insert-sql-Befehl löscht erst alle Tabellen bevor er diejenigen aus der schema.sql einfügt, es gibt zu dem Zeitpunkt jedoch noch keine Tabellen.

Erzeugen des Grundgerüstes für die Anwendung

Die Grundfunktionen eines Weblogs sind das Erstellen, Abfragen, Aktualisieren und Löschen (Create Retrieve Update Delete ~ CRUD) von Einträgen und Kommentaren. Da dir Symfony noch neu ist, bietet es sich an, vorerst keinen Quelltext von Grund auf neu zu schreiben, sondern dir ein Grundgerüst generieren lassen, welches du dann, je nach deinen Bedürfnissen, benutzen oder modifizieren kannst. Symfony kann das Datenmodell interpretieren und somit automatisch eine CRUD-Schnittstelle generieren:

$ php symfony propel-generate-crud frontend post Post
$ php symfony propel-generate-crud frontend comment Comment

Du hast nun die beiden Module post und comment, welche es dir ermöglichen, die Einträge in der Post bzw. Comment Tabelle zu manipulieren (das phpName-Attribut aus der schema.yml-Datei wird dabei zur Namensgebung der jeweiligen Tabelle verwendet). Ein Modul stellt eine oder mehrere Seiten dar, die dem gleichen Zweck dienen. Die neuen Module befinden sich im sf_sandbox/apps/frontend/modules/-Verzeichnis, du kannst sie folgendermaßen aufrufen:

http://localhost/sf_sandbox/web/frontend_dev.php/post
http://localhost/sf_sandbox/web/frontend_dev.php/comment

Um den Weblog nicht so leer aussehen zu lassen, kannst du dir jetzt ein wenig Zeit nehmen um ein paar Einträge zu erstellen.

http://www.symfony-project.com/images/tutorials/first_crud.gif

Mehr über das Grundgerüst sowie eine Erläuterung der Struktur (Projekt, Anwendung, Modul) von Symfony-Projekten.

Hinweis: In den obigen Adressen wurde der Name der Haupt-Skriptes (in Symfony front controller genannt) von index.php auf frontend_dev.php geändert. Beide Skripte greifen auf die selbe Applikation frontend) zu, benutzen jedoch verschiedene Umgebungen. Mit frontend_dev.php, rufst du die Anwendung in der Entwicklungsumgebung auf. Diese stellt nützliche Entwicklungswerkzeuge, wie die Debug-Toolbar oben rechts auf dem Bildschirm und die Live Konfiguration-Engine zur Verfügung. Aus diesem Grund wird die Seite langsamer verarbeitet, als wenn wir die index.php, welche der front controller der Produktionsumgebung und Geschwindigkeitsoptimiert ist, benutzen würden. Wenn du weiterhin die Produktionsumgebung benutzen möchtest, ersetze die frontend_dev.php/ mit index.php/ in den nachfolgenden URLs, aber vergiss nicht den Cache zu leeren, bevor du dir die Änderungen anschaust:

$ php symfony clear-cache

http://localhost/sf_sandbox/web/index.php/

Mehr über Umgebungen.

Modifizieren des Layouts

Um zwischen den Modulen zu navigieren, benötigt unser Weblog noch eine globale Navigation.

Editiere das globale Template sf_sandbox/apps/frontend/templates/layout.php und ändere den Inhalt vom <body>-Tag folgendermaßen:

<div id="container" style="width:600px;margin:0 auto;border:1px solid grey;padding:10px">
  <div id="navigation" style="display:inline;float:right">
    <ul>
      <li><?php echo link_to('List of posts', 'post/list') ?></li>
      <li><?php echo link_to('List of comments', 'comment/list') ?></li>
    </ul>
  </div>
  <div id="title">
    <h1><?php echo link_to('My first symfony project', 'default/index') ?></h1>
  </div>
 
  <div id="content" style="clear:right">
    <?php echo $sf_content ?>
  </div>
</div>

Da eine Stunde wenig Zeit ist, bitten wir das notdürftige Design sowie die Benutzung von inner-tag CSS zu entschuldigen.

http://www.symfony-project.com/images/tutorials/first_crud_layout.gif

Da du schon dabei bist, kannst du auch gleich den Titel deiner Seiten ändern. Editiere dazu die view-Konfigurationsdatei deiner Anwendung sf_sandbox/apps/frontend/config/view.yml), gehe in die Zeile mit dem title-Key und ändere sie folgendermaßen:

default:
  http_metas:
    content-type: text/html; charset=utf-8

  metas:
    title:        The best weblog ever
    robots:       index, follow
    description:  symfony project
    keywords:     symfony, project
    language:     en

Die Hauptseite an sich muss noch geändert werden. Sie benutzt das default-Template aus dem default-Modul, welches in dem Framwork integriert ist und sich nicht in deinem Anwendungs-Verzeichnis befindet. Um dies zu ändern musst du das default-Modul umgehen indem du ein eigenes default-Modul erstellst:

$ cd apps/frontend/modules
$ mkdir default
$ cd default
$ mkdir templates
$ cd templates

Erstelle dort die Datei indexSuccess.php und füge eine nette Begrüßungsnachricht ein:

<h1>Welcome to my swell weblog</h1>
<p>You are the <?php echo rand(1000,5000) ?>th visitor today.</p>

Überprüfe das Ergebnis indem du die Hauptseite erneut aufrufst:

http://localhost/sf_sandbox/web/frontend_dev.php/

http://www.symfony-project.com/images/tutorials/first_welcome.gif

Du kannst nun fortfahren und deine neue Webanwendung benutzen: Erstelle einen neuen Eintrag und gib einen Kommentar dazu ab!

Mehr über Templates und die View-Konfiguration.

Übergebe Daten der Action an das Template

Das ging schnell, oder? Nun ist es jedoch an der Zeit das comment-Modul mit dem post-Modul zu verknüpfen, um somit Kommentare unter den Einträgen anzuzeigen.

Als erstes müssen wir die Kommentare dem post-Template zugänglich machen. Diese Art von Logik wird in Symfony in Actions festgehalten. Öffne die Actions-Datei sf_sandbox/apps/frontend/modules/post/actions/actions.class.php und ändere die executeShow()-Methode indem du die vier mittleren Zeilen einfügst:

public function executeShow ()
{
  $this->post = PostPeer::retrieveByPk($this->getRequestParameter('id'));
 
  $c = new Criteria();
  $c->add(CommentPeer::POST_ID, $this->getRequestParameter('id'));
  $c->addAscendingOrderByColumn(CommentPeer::CREATED_AT);
  $this->comments = CommentPeer::doSelect($c);
 
  $this->forward404Unless($this->post);
}

Die Criteria- und -Peer-Objekte sind Teil des Objekt-relationalen Mappings von Propel. Im Grunde verarbeiten diese vier Zeilen eine SQL-Abfrage an die Comment-Tabelle um alle Kommentare mit Bezug auf den aktuellen Eintrag (welches durch den URL-Parameter id festgelegt wird) abzufragen. Die $this->comments Variable in der Action ermöglicht den Zugriff auf die $comments Variable im entsprechenden Template. Füge nun am Ende des Eintrag-Anzeige-Templates sf_sandbox/apps/frontend/modules/post/templates/showSuccess.php folgendes ein:

...
<?php use_helper('Text', 'Date') ?>
 
<hr />
<?php if ($comments) : ?>
  <p><?php echo count($comments) ?> comment<?php if (count($comments) > 1) : ?>s<?php endif; ?> to this post.</p>
  <?php foreach ($comments as $comment): ?>
    <p><em>posted by <?php echo $comment->getAuthor() ?> on <?php echo format_date($comment->getCreatedAt()) ?></em></p>
    <div class="comment" style="margin-bottom:10px;">
      <?php echo simple_format_text($comment->getBody()) ?>
    </div>    
  <?php endforeach; ?>
<?php endif; ?>

Die Seite nutzt neue, von Symfony bereitgestellte, Funktionen(format_date() und simple_format_text()). Diese werden auch 'Helfer' genannt, da sie dir einige Aufgaben abnehmen wofür du normalerweise mehr Zeit und Quelltext investieren müsstest. Erstelle einen neuen Kommentar für deinen ersten Eintrag und überprüfe diesen erneut, entweder durch Klicken auf seine Nummer in der Liste oder durch direkte Eingabe von:

http://localhost/sf_sandbox/web/frontend_dev.php/post/show?id=1

http://www.symfony-project.com/images/tutorials/first_comments_under_post.gif

Das sieht doch schon ganz gut aus.

Finde mehr über Namens-Konventionen heraus, die eine Action an ein Template bindet, sowie die Text- und Datums-Helfer.

Füge einen Eintrag, welcher mit einer anderen Tabelle verknüpft ist, hinzu

Bei dem hinzufügen eines Kommentars musst du die id eines zugehörigen Eintrags angeben, was nicht gerade Benutzerfreundlich ist. Lass uns dies ändern und zudem noch sicherstellen das der Benutzer, nach dem erstellen eines Kommentars, zum Eintrag zurück geleitet wird.

Füge als erstes folgende Zeile am Ende des neuen modules/post/templates/showSuccess.php-Templates ein:

<?php echo link_to('Add a comment','comment/create?post_id='.$post->getId()) ?>

Der link_to()-Helfer erstellt einen Hyperlink zu der create-Action des Kommentar-Moduls, so dass du einen Kommentar direkt aus der Detail-Seite eines Eintrags erstellen kannst. Öffne als nächstes die Datei modules/comment/templates/editSuccess.php und ersetze die folgenden Zeilen:

<tr>
  <th>Post*:</th>
  <td><?php echo object_select_tag($comment, 'getPostId', array (
  'related_class' => 'Post',
)) ?></td>
</tr>

durch:

<?php if ($sf_request->hasParameter('post_id')): ?>
  <?php echo input_hidden_tag('post_id',$sf_request->getParameter('post_id')) ?> 
<?php else: ?>
  <tr>
    <th>Post*:</th>
    <td><?php echo object_select_tag($comment, 'getPostId', array (
    'related_class' => 'Post',
    )) ?></td>
  </tr>
<?php endif ?>

Das HTML-Formular in der comment/create-Seite zeigt auf die comment/update-Action, welche wiederum zu der comment/show-Action weiterleitet, wenn sie abgesendet wurde (dies ist das Standardverhalten in generierten CRUDs). Für unseren Weblog bedeutet dies, dass nach dem erstellen eines Kommentars, die Details von einem Kommentar angezeigt werden. Jedoch dürfte es hier besser sein den Eintrag samt Kommentaren anzuzeigen. Öffne also modules/comment/actions/actions.class.php und such nach der executeUpdate()-Methode. Beachte hierbei das in der Action das Feld created_at nicht definiert ist: Symfony weiß, dass ein Feld mit dem Namen created_at, bei dem hinzufügen eines Eintrags die aktuelle Systemzeit beinhalten muss. Die finale Weiterleitung der Action muss so modifiziert werden, dass sie auf die korrekte Action zeigt. Ändere sie zu:

public function executeUpdate ()
{
  if (!$this->getRequestParameter('id', 0))
  {
    $comment = new Comment();
  }
  else
  {
    $comment = CommentPeer::retrieveByPk($this->getRequestParameter('id'));
    $this->forward404Unless($comment);
  }    
 
  $comment->setId($this->getRequestParameter('id'));
  $comment->setPostId($this->getRequestParameter('post_id'));
  $comment->setAuthor($this->getRequestParameter('author'));
  $comment->setEmail($this->getRequestParameter('email'));
  $comment->setBody($this->getRequestParameter('body'));
 
  $comment->save();
 
  return $this->redirect('post/show?id='.$comment->getPostId());
}

Die Benutzer können jetzt Kommentare zu einem Eintrag erstellen und werden anschließend wieder zu diesem zurück geleitet. Du wolltest einen Weblog? Nun hast du einen.

Mehr über Actions.

Gültigkeit eines Formulars

Die Besucher können Kommentare schreiben, aber was passiert wenn diese eine leere Form abschicken? Du wird eine unsaubere Datenbank haben. Um dies zu umgeben, erstelle die Datei update.yml in dem Verzeichnis sf_sandbox/apps/frontend/modules/comment/validate/ (Du wirst das Verzeichnis erstellen müssen) und schreibe dort folgendes hinein:

methods:
  post:           [author, email, body]
  get:            [author, email, body]

fillin:
  activate:       on

names:
  author:
    required:     Yes
    required_msg: The name field cannot be left blank

  email:  
    required:     No
    validators:   emailValidator

  body:
    required:     Yes
    required_msg: The text field cannot be left blank

emailValidator:
  class:          sfEmailValidator
  param:
    email_error:  The email address is not valid.

Hinweis:' Du musst aufpassen, dass du nicht die vier zusätzlichen Leerzeichen am Anfang jeder Zeile mit kopierst, da der YAML-Parser in diesem Fall versagen würde. Der erste Buchstabe dieser Datei muss das 'm' von 'methods' sein.

Die Aktivierung von fillin bezweckt, dass das Formular mit den vom Benutzer zuvor eingegebenen Daten wieder angezeigt wird, falls die Überprüfung der Eingabe fehlschlägt. Die names-Deklarationen setzen die Validierungsregeln für jede Eingabe des Formulars.

Der Controller wird im Fehlerfall den Benutzer selbstständig zu einem updateError.php-Template weiterleiten. Es würde besser sein das Formular mit einer Fehlernachricht anzuzeigen. Um dies zu tun, füge der action-Klasse in der modules/comment/actions/actions.class.php Datei eine handleError-Methode hinzu:

public function handleError()
{
  $this->forward('comment', 'create');
}

Um das ganze fertigzustellen, öffne wiederum das modules/comment/templates/editSuccess.php-Template und füge am Anfang folgendes hinzu:

<?php if ($sf_request->hasErrors()): ?>  
  <div id="errors" style="padding:10px;">
    Please correct the following errors and resubmit:
    <ul>
    <?php foreach($sf_request->getErrors() as $error): ?>
      <li><?php echo $error ?></li>
    <?php endforeach ?>
    </ul>
  </div>
<?php endif ?>

Du hast nun ein ausgefeiltes und robustes Formular.

http://www.symfony-project.com/images/tutorials/first_form_validation.gif

Mehr über Formular-Validierung.

Ändere das Aussehen Deiner URLs

Hast du bemerkt, wie die URLs erstellt werden? Du kannst sie Benutzer- und Suchmaschinefreundlicher gestalten. Lass uns den Titel eines Eintrags als URL für Einträge verwenden.

Das Problem ist, dass die Titel der Beiträge besondere Zeichen, wie z.B. Leerzeichen enthalten können. Wenn du nur diese maskierst, wird die URL hässliche Sachen wie %20 anzeigen, von daher ist es besser, wenn du das Modell erweiterst und eine neue Methode zu dem Post-Objekt hinzufügst, um einen sauberen, bereinigten Titel zu bekommen. Um dies zu vollziehen, bearbeite die Datei Post.php im sf_sandbox/lib/model/-Verzeichnis und füge folgende Methode hinzu:

public function getStrippedTitle()
{
  $result = strtolower($this->getTitle());
 
  // strip all non word chars
  $result = preg_replace('/\W/', ' ', $result);
 
  // replace all white space sections with a dash
  $result = preg_replace('/\ +/', '-', $result);
 
  // trim dashes
  $result = preg_replace('/\-$/', '', $result);
  $result = preg_replace('/^\-/', '', $result);
 
  return $result;
}

Nun kannst du eine permalink-Action für die post-Module erstellen. Füge in der modules/post/actions/actions.class.php-Datei die folgende Methode hinzu:

public function executePermalink()
{
  $posts = PostPeer::doSelect(new Criteria());
  $title = $this->getRequestParameter('title');
  foreach ($posts as $post)
  {
    if ($post->getStrippedTitle() == $title)
    {
      break;
    }
  }
  $this->forward404Unless($post);
 
  $this->getRequest()->setParameter('id', $post->getId());
 
  $this->forward('post', 'show');
}

Die Liste der Einträge kann diese permalink-Action statt der show-Action für jeden Eintrag aufrufen. Lösche in der Tabelle der Datei modules/post/templates/listSuccess.php den id-Titel sowie die dazugehörige Zelle und ändere die Title-Zelle:

<td><?php echo $post->getTitle() ?></td>

zu:

<td><?php echo link_to($post->getTitle(), '/'.$sf_last_module.'/permalink?title='.$post->getStrippedTitle()) ?></td>

Nur noch ein weiterer Schritt: Editiere im Verzeichnis sf_sandbox/apps/frontend/config/ die Datei routing.yml und füge am Anfang folgende Regeln hinzu:

list_of_posts:
  url:   /latest_posts
  param: { module: post, action: list }

post:
  url:   /weblog/:title
  param: { module: post, action: permalink }

Navigiere nun erneut in deiner Anwendung und beobachte die URLs.

http://www.symfony-project.com/images/tutorials/first_routing.gif

Mehr über smart URLs.

Bereinigungen im Frontend

Nun, wenn dies ein Weblog ist, dann hat jedermann das Recht etwas zu schreiben. Dies ist nicht wirklich das, woran du gedacht hast, richtig? Nun gut, dann bereinigen wir mal ein bisschen unsere Templates.

Im modules/post/templates/showSuccess.php-Template werden wir den 'edit'-Link los, indem wir folgende Zeile entfernen:

<?php echo link_to('edit', 'post/edit?id='.$post->getId()) ?>

Tue das gleiche für das modules/post/templates/listSuccess.php-Template und lösche:

<?php echo link_to('create', 'post/create') ?>

Du musst auch die folgenden Methoden in der modules/post/actions/actions.class.php entfernen:

* executeCreate
* executeEdit
* executeUpdate
* executeDelete

Alles klar, die Leser können keine Beiträge mehr erstellen.

Generierung vom Backend

Damit du Beiträge schreiben kannst, erstellen wir eine backend-Anwendung indem wir folgendes in die Eingabeaufforderung eintippen (Immer noch vom sf_sandbox-Projekt Verzeichnis aus):

$ php symfony init-app backend
$ php symfony propel-init-admin backend post Post
$ php symfony propel-init-admin backend comment Comment

Dieses Mal benutzen wir den Admin-Generator. Er stellt viel mehr Funktionen und spezielle Modifizierungen, als der doch sehr simple CRUD-Generator, bereit.

Mach es genau so wie bei der frontend-Anwendung und editiere das Layout (apps/backend/template/layout.php) um eine globale Navigation hinzu zu fügen:

<div id="navigation">
  <ul style="list-style:none;">
    <li><?php echo link_to('Manage posts', 'post/list') ?></li>
    <li><?php echo link_to('Manage comments', 'comment/list') ?></li>
  </ul>
</div>      
<div id="content">
  <?php echo $sf_content ?>
</div>

Hinweis: Da du eine Sandbox verwendest, musst du noch das Verzeichnis sf_sandbox/web/sf/images/sf_admin/ in ein sf/images/sf_admin/-Verzeichnis des Wurzelverzeichnisses deines Webservers kopieren (dies liegt an den Bildpfaden in den CSS-Stylesheets).

Du kannst deine neue Administration, in der Entwicklungsumgebung, mit folgender Adresse aufrufen:

http://localhost/sf_sandbox/web/backend_dev.php/post

http://www.symfony-project.com/images/tutorials/first_basic_admin.gif

Der große Vorteil der generierten Administration ist, dass du sie individuell gestalten kannst, indem Du die Konfigurationsdateien bearbeitest.

Ändere die backend/modules/post/config/generator.yml-Datei zu:

generator: 
  class:              sfPropelAdminGenerator
  param:
    theme:            default
    fields:
      title:          { name: Title }
      excerpt:        { name: Exerpt }
      body:           { name: Body }
      nb_comments:    { name: Comments }
      created_at:     { name: Creation date }
    list:
      title:          Post list
      layout:         tabular
      display:        [=title, excerpt, nb_comments, created_at]
      object_actions:
        _edit:        -
        _delete:      -
      max_per_page:   5
      filters:        [title, created_at]
    edit:  
      title:          Post detail        
      fields:
        title:        { type: input_tag, params: size=53 }
        excerpt:      { type: textarea_tag, params: size=50x2 }
        body:         { type: textarea_tag, params: size=50x10 }
        created_at:   { type: input_date_tag, params: rich=on }

Beachte, dass neben den existierenden Spalten der Post-Tabelle, die Administration nach nb_comments schauen wird. Bis jetzt existiert noch keine assoziierte getter-Methode, aber man kann sie einfach in der Datei sf_sandbox/lib/model/Post.php anfügen:

public function getNbComments()
{
  return count($this->getComments()); 
}

Aktualisiere nun die Eintrag-Administration und schaue dir die Veränderungen an:

http://www.symfony-project.com/images/tutorials/first_custom_admin.gif

Zugriff auf das Backend beschränken

Auf das Backend kann jeder zugreifen. Du musst eine Zugriffsbeschränkung hinzufügen.

Erstelle die Datei security.yml in apps/backend/modules/post/config/ und füge folgenden Inhalt ein:

all:
  is_secure: on

Wiederhole die Operation für das comment-Modul. Du kannst jetzt nur noch auf die Module zugreifen wenn du eingeloggt bist.

Jedoch existiert die logging-Action nicht! Ok, dann füge sie einfach hinzu, erstelle erst das Grundgerüst für das security-Modul:

$ php symfony init-module backend security

Das neue Modul wird benutzt um das Login-Formular sowie die Abfrage zu verwalten. Editiere apps/backend/modules/security/templates/indexSuccess.php um ein Login-Formular zu erstellen:

<h2>Authentication</h2>
 
<?php if ($sf_request->hasErrors()): ?>
  Identification failed - please try again
<?php endif ?>
 
<?php echo form_tag('security/login') ?>
  <label for="login">login:</label>
  <?php echo input_tag('login', $sf_params->get('login')) ?>
 
  <label for="password">password:</label>
  <?php echo input_password_tag('password') ?>
 
  <?php echo submit_tag('submit', 'class=default') ?>
</form>

Füge die login-Action, die durch das Formular aufgerufen wird, in das security-Modul (in der Datei apps/backend/modules/security/actions/actions.class.php) ein:

public function executeLogin()
{
  if ($this->getRequestParameter('login') == 'admin' && $this->getRequestParameter('password') == 'password')
  {
    $this->getUser()->setAuthenticated(true);
    return $this->redirect('default/index');
  }
  else
  {
    $this->getRequest()->setError('login', 'incorrect entry');
    return $this->forward('security', 'index');
  }
}

Das Letzte was du tun musst, ist das Eintragen des security-Moduls als Standardmodul für Login-Actions. Um dies zu tun, öffne die Konfigurationsdatei apps/backend/config/settings.yml und füge dort folgendes ein:

all:
  .actions:
    login_module:           security
    login_action:           index

Wenn du nun die Beitrag Verwaltung aufrufen möchtest, muss du die Login-Daten eingeben:

http://www.symfony-project.com/images/tutorials/first_login.gif

Mehr über Sicherheit.

Fazit

Ok, eine Stunde ist vorbei. Du hast es geschafft und kannst nun beide Anwendungen in der Produktionsumgebung benutzen und damit ein wenig rumspielen:

frontend:   http://localhost/sf_sandbox/web/index.php/
backend:    http://localhost/sf_sandbox/web/backend.php/

Wenn nun Fehler auftreten, könnte es daran liegen, dass du das Datenmodell geändert hast, nachdem einige Actions gecached wurden (in der Entwicklungsumgebung ist der Cache deaktiviert). Um den Cache zu leeren, musst du folgendes eingeben:

$ php symfony cc

Siehst du wie schnell und reibungslos die Anwendung läuft? Ziemlich cool, oder? Wenn du Lust hast, kannst du im Code etwas herum schauen, neue Module hinzufügen und das Design der Seiten ändern.

Vergiss nicht deine funktionierenden symfony-Anwendungen im symfony-Wiki zu erwähnen!