[Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Hier finden sich Fragen und Ergänzung zur Dokumentation. // All questions and discussions about the documentation.
Antworten
Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

[Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 02.04.2011, 21:57:06

So, ich muss nochmal die Forengemeinde um Hilfe bitten. Ich hänge an der konkreten Umsetzung des MVC innerhalb von APF sowie dem Zusammenspiel einiger Komponenten. Für die meisten dürfte das eher ein Heimspiel sein, aber ich habe mich irgendwie „verrannt“ und wäre froh, man könnte mir etwas zur Hand gehen.

Vielleicht ist es möglich, dass man mir das anhand eines einfachen Beispiels erklärt. Ich habe zwar in den verschiedenen (zumeist sehr komplexen) Tutorials bzw. auch der Sandbox in den entsprechenden Quelltexten (wobei der dortige SQL-Code innerhalb des Controllers eher gegen MVC spricht) nachgeschaut, aber ich trete auf der Stelle. Vielleicht liegt das auch daran, dass ich a) im Umgang mit Frameworks auf absolutem Anfängerniveau spiele und b) von OOP eher rudimentäre Kenntnisse habe.

Um es konkret zu machen hätte ich das folgende, einfache Beispiel:

Eine Seite, auf der ein Formular zur Eingabe eines Wertes ist sowie ein Submit-Button. Wird der Button gedrückt, soll der eingegebene Wert validiert und in eine Datenbank eingetragen werden. Danach sollen alle bereits vorhandenen Werte ausgelesen und auf der oben genannten Seite unterhalb des Eingabeformulars aufgelistet werden.

Ich denke, dass dieses Beispiel recht einfach gehalten ist und daher ggf. auch andere Nichtwissende hier nachschauen können und die Schritte nachvollziehen können. Vielleicht kann es dann letzendlich sogar anderen Nutzern als Einstieghilfe dienen.

Wie fange ich nun an?

Ich nenne das Projekt einfach mal „messenger“ (da man einfache Textnachrichten hinterlassen kann).

Verzeichnisstruktur

Die Verzeichnisstruktur dürfte demnach wie folgt sein:

Code: Alles auswählen

apf/apps/messenger
Im Verzeichnis messenger wiederum würden folgende Verzeichnisse angelegt (soweit ich alles richtig verstanden habe):

Code: Alles auswählen

biz
data
pres, pres/documentcontroller, pres/templates
Benötigte Dateien
Model / Mapper, der die Datenbankeinträge ergänzt bzw. die vorhandenen ausliest

View / Templatedatei, die das Eingabeformular darstellt und zugleich die bereits vorhandenen Datenbankeinträge ausgibt.

Controller, der die Anfragen behandelt


Wie fange ich nun an?
Meine Bootstrapdatei (index.php) würde wie folgt aussehen:

Code: Alles auswählen

<?php
// Fehlermeldungen einschalten
ini_set('html_errors', 'on');

// Pagecontroller starten
require_once './apps/core/pagecontroller/pagecontroller.php';

// Frontcontroller starten
import('core::frontcontroller', 'Frontcontroller');

$fC = &Singleton::getInstance('Frontcontroller');
$fC->setContext('messenger');

// Startseite anzeigen
echo $fC->start('messenger::pres::templates', 'main');
?>
Weiterhin würde folgende Templatedatei „main.html“ zur Verfügung stehen:

Code: Alles auswählen

<@controller namespace="messenger::biz" file="messengerController" class="messengerController" @> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>messenger</title>
</head>
<body>

<h1><a href="index.php">Nachrichten</a></h1>

<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />

<html:form name="msg">

<form:error><p>Du musst eine neue Nachricht eingeben, die mind. 6 Zeichen umfasst!</p></form:error>

Neue Nachricht :
<form:text name="newHeadline" minlength="6"/>

<form:addvalidator
 class="TextLengthValidator"
 control="newHeadline"
 button="send"
/>

<form:button name="send" value="Eintragen"/>

</html:form>
<hr/>
<h2>Nachrichtenübersicht</h2>
</body>
</html> 
Sowie die messengerController.php in /apps/messenger/biz:

Code: Alles auswählen

<?php
class messengerController extends base_controller{

public function  transformContent() {

$form = &$this->__getForm('msg');

if ($form->isSent() && $form->isValid()){
    /** 
     * Gesendet und valide
     * neuen Eintrag in DB einfügen
     * alle vorhandenen Einträge auslesen und ausgeben
     */

}
else{
    /**
     * Gesendet und nicht valide
     * also Fehlermeldung ausgeben
     */

    $this->__getForm('msg')->transformOnPlace();
}
}
}
?>
Was ebenfalls bereits klar ist, ist die (einfach strukturierte) MySQL-Datenbank-Tabelle:

Code: Alles auswählen

 CREATE TABLE `apf_messenger`.`messages` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`message` VARCHAR( 100 ) NOT NULL ,
`mod` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = MYISAM 
Dort soll also nur die neu eingetragene Nachricht hinterlegt werden. Die Datenbank weist eine ID zu und speichert zudem, wann der Eintrag erfolgt ist.

Bin ich bis dahin mit meinen Überlegungen auf dem richtigen Weg? Oder befinde ich mich bereits auf dem Holzweg?
Zuletzt geändert von ma2604121 am 03.04.2011, 23:26:04, insgesamt 4-mal geändert.

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [Beispiel ]Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Screeze » 02.04.2011, 22:23:09

ich bin zwar kein experte was mvc und co angeht, aber soweit sieht das schon sinnvoll aus.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel ]Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 02.04.2011, 22:27:57

Dann wäre da für das weitere Vorgehen natürlich die INI-Datei für die Datenbankverbindung interessant. Diese würde ich unter

Code: Alles auswählen

/apps/config/core/database/messenger
als DEFAULT_connections.ini mit folgendem Inhalt ablegen:

Code: Alles auswählen

[MySQL]
DB.Host = "localhost"
DB.User = "benutzer"
DB.Pass = "passwort"
DB.Name = "apf_messenger"
DB.Type = "MySQLx"
DB.Charset = "utf-8"
Der Mapper im Grundzug:

Code: Alles auswählen

<?php
import('core::database', 'ConnectionManager');

class messengerMapper extends APFObject{

    private function &__getConnection(){
    $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
    $conn = &$cM->getConnection('MySQL');
    return $conn;
    }
}
?>
Wobei ich hier schon nicht mehr ganz sicher bin, ob die Anweisungen in &__getConnection() richtig sind.

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [Beispiel ]Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Screeze » 02.04.2011, 23:23:26

Passt auch, wenn ich allerdings ein paar kosmetische Vorschläge machen darf, würde ich folgendes Vorschlagen:

Code: Alles auswählen

    <?php
    import('core::database', 'ConnectionManager');

    class MessengerMapper extends APFObject{

        protected function &getConnection(){
            $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
            return $cM->getConnection('MySQL');
        }
    }
    ?>
Zum einen in getConnection die __ Notation weglassen, da diese veraltet ist, und wir das APF auch nach und nach davon umstellen. Zum anderen braucht es keine Zuweisung in eine Variable, du kannst das direkt zurückgeben. Desweiteren würde ich "protected" vorziehen anstatt "private", weil du sonst wenn du den Mapper erweiterst in der abgeleiteten Klasse nichtmehr auf deine DB-Verbindung zugreifen kannst. Und zu guter letzt würde ich die Klasse Groß schreiben, ist allerdings Geschmackssache ;)

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel ]Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 02.04.2011, 23:31:05

Kritik ist natürlich willkommen.

Die __ Notation lasse ich dann selbstverständlich weg. Ich habe mir das wenige "Wissen" um das APF aus den Tutorials usw. geholt und da findet man teilweise noch diese Vorgehensweise. Wenn das veraltet ist, werde ich natürlich darauf verzichten.

Zum Rest bzw. was die weitere Umsetzung angeht muss ich mir morgen Gedanken machen.

Bzw. nur noch kurz der "Rumpf" des Mappers. Ich denke, dass hier zwei Methoden reichen (soll schließlich ein einfaches Beispiel bleiben): Eine schreibende, die die neue Nachricht in die Datenbank überträgt und eine lesende, die alle vorhandenen Nachrichten ausliest und als Array ausliefert.

Code: Alles auswählen

<?php
import('core::database', 'ConnectionManager');

class MessengerMapper extends APFObject{

    /**
     * Liest alle vorhandenen Nachrichten der Datenbank aus
     *
     * @return <array> $headlines - Alle vorhandenen Nachrichten werden als Array ausgeliefert
     */
    public function readHeadlines(){

    }

    /**
     * Schreibt eine neue Nachricht in die Datenbank
     *
     * @param <string> $headline - Enthält die neue Nachricht, die in die DB geschrieben werden soll
     */
    public function writeHeadline($headline){

    }

    /**
     * Datenbankverbindung herstelen
     */
    protected function &getConnection(){
    $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
    return $cM->getConncetion('MySQL');
    }
}
?>

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 03.04.2011, 15:24:35

So, der Mapper in seinen Grundzügen:

Code: Alles auswählen

<?php
import('core::database', 'ConnectionManager');

class MessengerMapper extends APFObject{

    /**
     * Liest alle vorhandenen Nachrichten der Datenbank aus
     *
     * @return <array> $content - Alle vorhandenen Nachrichten werden als Array ausgeliefert
     */
    public function readHeadlines(){

    // Datenbankverbindung
    $SQL = &$this->getConnection();

    // Query formulieren, neueste Nachricht als Erstes (DESC)
    $select = 'SELECT * FROM `messages` ORDER BY `messages`.`mod` DESC';

    // Nachrichten holen
    $result = $SQL->executeTextStatement($select);

    // Ausgelesene Nachrichten aufbereiten
    while ($data = $SQL->fetchData($result)){
        $content[] = array('id' => $data['id'], 'message' => $data['message'], 'mod' => $data['mod']);
    }

    // Ergebnisse ausliefern
    return $content;

    }

    /**
     * Schreibt eine neue Nachricht in die Datenbank
     *
     * @param <string> $headline - Enthält die neue Nachricht, die in die DB geschrieben werden soll
     */
    public function writeHeadline($headline){

    // Datenbankverbindung
    $SQL = &$this->getConnection();

    // Query formulieren
    $insert = 'INSERT INTO messages (`message`) VALUES (\'' . $SQL->escapeValue($headline) . '\')';

    // Daten schreiben
    $result = $SQL->executeTextStatement($insert);

    // ID holen
    $lastId = $SQL->getLastID();

    // ID ausliefern, keine vorhanden => Eintrag nicht erfolgreich
    return $lastId;

    }

    /**
     * Datenbankverbindung herstellen
     */
    protected function &getConnection(){
    $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
    return $cM->getConnection('MySQL');
    }
}
?>

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Screeze » 03.04.2011, 15:35:13

Das lässt sich etwas vereinfachen, aber vorher noch ein Tipp zur Formatierung: Normalerweis rückt man Code innerhalb { } ein, auch in Funktionen, dann ist es besser lesbar.
Das Aufbereiten der Daten geht kürzer, du kannst einfach das ganze array nehmen wie es ist, da du ja eh alle Felder nur kopierst.

Meine Version sähe wie folgt aus:

Code: Alles auswählen

    <?php
    import('core::database', 'ConnectionManager');

    class MessengerMapper extends APFObject{

        /**
         * Liest alle vorhandenen Nachrichten der Datenbank aus
         *
         * @return <array> $content - Alle vorhandenen Nachrichten werden als Array ausgeliefert
         */
        public function readHeadlines(){

            // Datenbankverbindung
            $SQL = &$this->getConnection();

            // Query formulieren, neueste Nachricht als Erstes (DESC)
            $select = 'SELECT * FROM `messages` ORDER BY `messages`.`mod` DESC';

            // Nachrichten holen
            $result = $SQL->executeTextStatement($select);

            // Ausgelesene Nachrichten aufbereiten
            while ($data = $SQL->fetchData($result)){
                $content[] = $data;
            }

            // Ergebnisse ausliefern
            return $content;

        }

        /**
         * Schreibt eine neue Nachricht in die Datenbank
         *
         * @param <string> $headline - Enthält die neue Nachricht, die in die DB geschrieben werden soll
         */
        public function writeHeadline($headline){

            // Datenbankverbindung
            $SQL = &$this->getConnection();

            // Query formulieren
            $insert = 'INSERT INTO messages (`message`) VALUES (\'' . $SQL->escapeValue($headline) . '\')';

            // Daten schreiben
            $result = $SQL->executeTextStatement($insert);

            // ID holen
            $lastId = $SQL->getLastID();

            // ID ausliefern, keine vorhanden => Eintrag nicht erfolgreich
            return $lastId;

        }

        /**
         * Datenbankverbindung herstellen
         */
        protected function &getConnection(){
            $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
            return $cM->getConnection('MySQL');
        }
    }
    ?>

Benutzeravatar
dave
Beiträge: 903
Registriert: 04.02.2011, 19:03:57
Wohnort: Berlin
Kontaktdaten:

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von dave » 03.04.2011, 19:20:34

Sauber! Man sollte auf jeden Fall einen Link von der Tutorials-Seite hierher setzen!

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 03.04.2011, 20:56:21

Screeze hat geschrieben:Das lässt sich etwas vereinfachen, aber vorher noch ein Tipp zur Formatierung: Normalerweis rückt man Code innerhalb { } ein, auch in Funktionen, dann ist es besser lesbar.
Da kann ich nichts für. Das passiert offenbar durch das Kopieren der Quelltexte ins Forum. In der IDE ist alles korrekt eingerückt. Ansonsten würde ich beim Lesen verzweifeln. ;)
Screeze hat geschrieben:Das Aufbereiten der Daten geht kürzer, du kannst einfach das ganze array nehmen wie es ist, da du ja eh alle Felder nur kopierst.

Meine Version sähe wie folgt aus:
Sieht gut aus und wird natürlich auch so übernommen.
dave hat geschrieben:Sauber! Man sollte auf jeden Fall einen Link von der Tutorials-Seite hierher setzen!
Freut mich, dass meine ersten Schritte im APF sogar ein Lob bekommen... :oops:

Mal schauen, ob ich heute abend noch ein wenig am Controller voran komme.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 03.04.2011, 23:24:20

So, ich präsentiere die fertigen Dateien:

Model / Mapper

Code: Alles auswählen

<?php
import('core::database', 'ConnectionManager');

class MessengerMapper extends APFObject{

    /**
     * Liest alle vorhandenen Nachrichten der Datenbank aus
     *
     * @return <array> $content - Alle vorhandenen Nachrichten werden als Array ausgeliefert
     */
    public function readHeadlines(){

    // Datenbankverbindung
    $SQL = &$this->getConnection();

    // Query formulieren, neueste Nachricht als Erstes (DESC)
    $select = 'SELECT * FROM `messages` ORDER BY `messages`.`mod` DESC';

    // Nachrichten holen
    $result = $SQL->executeTextStatement($select);

    // Ausgelesene Nachrichten aufbereiten
    while ($data = $SQL->fetchData($result)){
        $content[] = $data;
    }

    // Ergebnisse ausliefern
    return $content;

    }

    /**
     * Schreibt eine neue Nachricht in die Datenbank
     *
     * @param <string> $headline - Enthält die neue Nachricht, die in die DB geschrieben werden soll
     */
    public function writeHeadline($headline){

    // Datenbankverbindung
    $SQL = &$this->getConnection();

    // Query formulieren
    $insert = 'INSERT INTO messages (`message`) VALUES (\'' . $SQL->escapeValue($headline) . '\')';

    // Daten schreiben
    $result = $SQL->executeTextStatement($insert);

    // ID holen
    $lastId = $SQL->getLastID();

    // ID ausliefern, keine vorhanden => Eintrag nicht erfolgreich
    return $lastId;

    }

    /**
     * Datenbankverbindung herstellen
     */
    protected function &getConnection(){
    $cM = &$this->__getServiceObject('core::database', 'ConnectionManager');
    return $cM->getConnection('MySQL');
    }
}
?>
View / Template

Code: Alles auswählen

<@controller namespace="messenger::biz" file="messengerController" class="messengerController" @> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>messenger</title>
</head>
<body>

<h1><a href="index2.php">Nachrichten</a></h1>

<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />

<html:form name="msg">

<form:error><p>Du musst eine neue Nachricht eingeben, die mind. 6 Zeichen bzw. max. 100 Zeichen umfasst!</p></form:error>

Neue Nachricht :
<form:text name="newHeadline" minlength="6" maxlength="100"/>

<form:addvalidator
 class="TextLengthValidator"
 control="newHeadline"
 button="send"
/>

<form:button name="send" value="Eintragen"/>

</html:form>

<hr/>

<h2>Nachrichtenübersicht</h2>

<table>
    <tr>
    <th>#</th>
    <th>Nachricht</th>
    <th>Erzeugt</th>
    </tr>
    <html:placeholder name="list"/>
</<table>

<html:template name="messages">
    <tr>
    <td><template:placeholder name="id"/></td>
    <td><template:placeholder name="message"/></td>
    <td><template:placeholder name="mod"/></td>
    </tr>
</html:template>

</body>
</html> 
Controller

Code: Alles auswählen

<?php
import('messenger::data', 'messengerMapper');

class messengerController extends base_controller{

    public function  transformContent() {

    // Platzhalter im View mit vorhandenen Nachrichten füllen
    $this->setPlaceHolder('list', $this->createMessages());

    // View holen
    $form = &$this->__getForm('msg');

    // Vorhandene Nachrichten auslesen
    $mM = &$this->getMapper();
    $headlines = $mM->readHeadlines();

    if ($form->isSent() && $form->isValid()){
        // Neue Nachricht wurde geschickt und ist valide

        // Nachricht holen
            $headlineControl = $form->getFormElementByName('newHeadline');
        $headline = $headlineControl->getAttribute('value');

        // Nachricht an Mapper schicken und in DB speichern
        $mM = &$this->getMapper();
        $mM->writeHeadline($headline);

        // Vorhandene Nachrichten auslesen
        $headlines = $mM->readHeadlines();

        // Liste mit den vorhandenen Nachrichten erstellen und den Platzhalter im View ersetzen
        $this->setPlaceHolder('list', $this->createMessages());

        // View ausgeben
        $this->__getForm('msg')->transformOnPlace();

    }
    else{
        // Gesendete Nachricht wurde nicht geschickt bzw. ist nicht valide

        // Vorhandene Nachrichten ausgeben
        $this->setPlaceHolder('list', $this->createMessages());

        // View ausgeben
        $this->__getForm('msg')->transformOnPlace();

    }
    }


    /**
     * Ersetzt im View die Platzhalter mit den vorhandenen Nachrichten
     * hierzu wird zum Erzeugen der einzelnen Listenpunkte der Abschnitt
     * <html:template name="messages"> als Vorlage verwendet
     */
    public function createMessages(){

    // HTML-Puffer initialisieren
    $buffer = (string)'';

    // Vorhandene Nachrichten auslesen
    $mM = &$this->getMapper();
    $headlines = $mM->readHeadlines();

    // Vorhandene Nachrichten an Template übergeben
    foreach ($headlines as $value){

        // Abschnittsvorlage zum Erzeugen der Ausgabe aus dem View holen
        $tpl = &$this->__getTemplate('messages');

        // Die einzelnen Platzhalter ersetzen
        $tpl->setPlaceHolder('id', $value['id']);
        $tpl->setPlaceHolder('message', $value['message']);
        $tpl->setPlaceHolder('mod', $value['mod']);

        // Alles zusammenfügen
        $buffer .= $tpl->transformTemplate();
    }

    // Fertige Liste ausliefern
    return $buffer;
    
    }


    /**
     * Stellt die Datenbankverbindung her
     */
    private function &getMapper(){
    return $this->__getServiceObject('messenger::data', 'messengerMapper');
    }

}
?>
Die Zeile

Code: Alles auswählen

// HTML-Puffer initialisieren
    $buffer = (string)''; 
ist mir allerdings etwas suspekt geblieben. Ich habe sie so in einem Tutorial gesehen, bin mir aber nicht ganz sicher, was die genau macht. Ist das etwas APF-spezifisches?

Insgesamt funktioniert nun alles, wie es soll. Aber entspricht mein Vorgehen auch dem MVC-Konzept bzw. der Idee, wie es mit dem APF umgesetzt werden soll?

Ach ein kleiner Schönheitsfehler ist noch:
Nach dem Absenden der neuen Nachricht ist das Eingabefeld weiterhin mit dieser befüllt. Da dürfte noch ein Fehler im Controller sein oder? Denn eigentlich sollte das Eingabefeld nach dem Absenden doch wieder leer sein?

Well
Beiträge: 263
Registriert: 25.10.2009, 11:00:19
Wohnort: Beuren
Kontaktdaten:

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Well » 04.04.2011, 00:04:17

Hey,

Code: Alles auswählen

// HTML-Puffer initialisieren
    $buffer = (string)'';  
Nein, das hat nichts mit dem APF zu tun. Damit wird die Variable eben initialisiert, also bekannt gemacht. Ohne diese Zeile würde PHP eine Notiz ala
PHP Notice: Undefined variable: buffer in php shell code on line 1
werfen. Denn

Code: Alles auswählen

$buffer .= $xyz; 
entspricht

Code: Alles auswählen

$buffer = $buffer . $xyz; 
Da zuerst der rechte Teil der Zuweisung "abgearbeitet" wird, ist die Variable ja zu diesem Zeitpunkt noch nicht bekannt, also noch undefiniert. (Zumindest beim ersten Durchgang der Schleife)
Ach ein kleiner Schönheitsfehler ist noch:
Nach dem Absenden der neuen Nachricht ist das Eingabefeld weiterhin mit dieser befüllt. Da dürfte noch ein Fehler im Controller sein oder? Denn eigentlich sollte das Eingabefeld nach dem Absenden doch wieder leer sein?
Das liegt nun am APF, denn das Form-Tool füllt die Formularfelder immer mit den zuvor abgesendeten Werten vor. Wenn du das nicht willst, musst du das Attribut »value« im Controller leeren:

Code: Alles auswählen

$formElement->setAttribute('value', ''); 

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Screeze » 04.04.2011, 06:21:19

Ich denke eher er ist über die explizite type declaration (string) gestolpert, die ich auch noch nicht so gesehen habe beim initialisieren.
Soweit ich das mit dem Handy beurteilen kann sieht das schon ganz gut aus, aber ich schau mir das heute Nachmittag nochmal genauer an. 2 dinge sind mir aber aufgefallen:
1. Ich würde den iterator nehmen um die nachrichten auszugeben.
2. Die Anwendung ist anfällig gegen XSS, beim ausgeben der headlines sollten die erst durch htmlentities() gejagt werden. Und ein striptags filter im formular wär auch nicht schlecht.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 04.04.2011, 08:42:29

Well hat geschrieben:Nein, das hat nichts mit dem APF zu tun. Damit wird die Variable eben initialisiert, also bekannt gemacht.
Dass man eine Variable so initialisieren kann, war mir nicht bekannt. Aber man lernt nicht aus. ;)
Well hat geschrieben:Das liegt nun am APF, denn das Form-Tool füllt die Formularfelder immer mit den zuvor abgesendeten Werten vor. Wenn du das nicht willst, musst du das Attribut »value« im Controller leeren:

Code: Alles auswählen

$formElement->setAttribute('value', ''); 
Dann werde ich das entsprechend anpassen.
Screeze hat geschrieben:2 dinge sind mir aber aufgefallen:
1. Ich würde den iterator nehmen um die nachrichten auszugeben.
2. Die Anwendung ist anfällig gegen XSS, beim ausgeben der headlines sollten die erst durch htmlentities() gejagt werden. Und ein striptags filter im formular wär auch nicht schlecht.
Zu 1. bräuchte ich noch ein paar Infos. Den Begriff "Iterator" habe ich zwar schon gehört im Zusammenhang mit OOP, aber so richtig anfangen kann ich damit nichts.

Zu 2. könnte ich sagen, dass die Frage hinsichtlich der korrekten Umsetzung des MVC-Konzepts innerhalb des APF gestellt war und nicht hinsichtlich der Sicherheit. ;) Aber ich nehme das natürlich gerne an und werde es einbauen, da ich Dir Recht geben muss: Wenn, dann macht man es richtig und da gehören entsprechende Schutzmechanismen einfach dazu. Daher: Guter Hinweis! Ich muss zugeben, dass ich das gestern abend auch im Hinterkopf hatte, aber irgendwie ging es dann doch unter.

Dank dem Feedback und den kleinen Hinweisen ist mir doch schon einiges klarer geworden; auch was Abläufe innerhalb der APF-Komponenten angeht. Ich überlege das Beispiel noch ein wenig zu ergänzen und eine Möglichkeit einzubauen, dass man die angezeigten Nachrichten durch das Anklicken der ID löschen kann. Es wäre schön, wenn ich auch weiterhin entsprechende Hilfestellungen bekommen könnte.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von ma2604121 » 04.04.2011, 08:58:34

Zu den Filtern:

Ich habe jetzt testweise den OnlyHTMLEntitiesFilter eingebaut.

Code: Alles auswählen

<html:form name="msg">

<form:error><p>Du musst eine neue Nachricht eingeben, die mind. 6 Zeichen bzw. max. 100 Zeichen umfasst!</p></form:error>

Neue Nachricht <form:text name="newHeadline" minlength="6" maxlength="100"/>

<form:button name="send" value="Eintragen"/>

<form:addvalidator
    class="TextLengthValidator"
    control="newHeadline"
    button="send"
/>

<form:addfilter
    class="OnlyHTMLEntitiesFilter"
    button="send"
    control="newHeadline"
/>

</html:form> 
Das Problem: Der Filter zerhaut mir meinen Zeichensatz!

Ich liefere meine Seite grundsätzlich in UTF-8 aus. Jetzt gebe ich aber z.B. als Nachricht

Code: Alles auswählen

Heut' ist ein schöner Tag!
ein. Dann erhalte ich als ausgeliefertes Resultat:

Code: Alles auswählen

Heut' ist ein schöner Tag!
Als HTML:

Code: Alles auswählen

Heut' ist ein sch&Atilde;&para;ner Tag!
Das ist natürlich nicht in meinem Sinne.

Benutzeravatar
Screeze
Beiträge: 1920
Registriert: 05.08.2009, 09:49:04
Kontaktdaten:

Re: [Beispiel] Verständnis Umsetzung MVC innerhalb des APF

Beitrag von Screeze » 04.04.2011, 09:53:35

Zur sicherheit: dachte ich mir schon, aber gerade was tutorials angeht sag ich das lieber dazu, sonst kopiert das jemand einfach evtl.
Zum rest meld ich mich nachher nochmal, unterricht geht weiter ;)

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste