GORM für Einsteiger

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 03.09.2011, 18:19:41

dave hat geschrieben:Du wolltest doch alle Autoren ausgeben? Wie das ganze gestaltet wird, ist natürlich von dir abhängig. Das muss keine Tabelle sein ;).
Das ist klar. Ich hatte es auf die Art und Weise bezogen, wie die Daten erhalten werden.

Wenn ich das folgende Template

Code: Alles auswählen

<html:placeholder name="AuthorsList" />
<html:template name="AuthorsList">
    <select:option value="<template:placeholder name="ID"/>"><template:placeholder name="AuthorName"/></select:option>
</html:template> 
mittels

Code: Alles auswählen

    public function  transformContent() {
    $form = &$this->getForm('AddBook');
    if ($form->isSent() && $form->isValid()){
    }
    else{
        $orm = $this->getMapper();
        $Crit = new GenericCriterionObject();
        $Crit->addPropertyIndicator('Author','%');
        $AuthorsList = $orm->loadObjectListByCriterion('Authors',$Crit);
        $template = &$this->getTemplate('AuthorsList');
        $buffer = '';
        foreach ($AuthorsList as $Author){
        $template->setPlaceHolder('AuthorName', $Author->getProperty('Author'));
        $template->setPlaceHolder('ID', $Author->getProperty('AuthorsID'));
        $buffer .= $template->transformTemplate();
        }
        $this->setPlaceHolder('AuthorsList', $buffer);
        $form->transformOnPlace();
    }
    } 
Dann wird mir alles dargestellt, aber die Select-Box bleibt leer. Im HTML-Quelltext sieht das wie folgt aus:

Code: Alles auswählen

    <select name="Author">
    <option value="0">[Please choose...]</option>
    <6cd9a472df57c54387555e6b6dca477c />
    </select><br/>
 
Da stehe ich derzeit auch auf dem Schlauch.

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

Re: GORM für Einsteiger

Beitrag von dave » 03.09.2011, 18:31:15

Puhh, also ein <form:select> kannst du bequemer mit Daten füllen. Da bin ich mittlerweile recht fit, ich beschäftige mich schon einige Zeit mit meinem Spezial-Select ;).

Template:

Code: Alles auswählen

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

<html:form name="showAutoren" method="post">
  <form:select name="selectAutoren" />
</html:form>
Controller:

Code: Alles auswählen

//Formular holen
$form = &$this->getForm('showAutoren');

//Autoren laden
$AuthorsList = $orm->loadObjectListByCriterion('Authors',$Crit);

//Das form:select aus dem Template holen
$selectOption = &$form->getFormElementByName('selBla');

//Optionen dem form:select hinzufügen
foreach ($AuthorsList as $data) {
  $selectOption->addOption($data->getProperty('AuthorsID'), $data->getProperty('Author'));
}

//Form transformieren
$form->transformOnPlace(); 
Hinweis: Ungetestet!

Zum Nachlesen die Doku: http://adventure-php-framework.org/Seit ... ct-Feldern

Und um einen bestimmten Autor schon vorzuselektieren sei folgende Methode erwähnt:
setOption2Selected()

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 13:14:36

Hervorragend!

Das select-Feld ist nun korrekt vorbefüllt. Jetzt kommt der "knifflige Teil", den ich noch nicht ganz verstehe: Das Speichern eines neuen Buches samt der Beziehung zum Autor.

Stellt der GORM hier automatisch eine Beziehung her oder muss ich auf herkömmliche Art und Weise, schlicht und einfach die ID des Autors in der Büchertabelle speichern? Für was wäre dann die automatisch generierte Tabelle cmp_author2book?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4536
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 04.09.2011, 13:41:49

Hi,

der GORM löst beim Speichern die Baum-Struktur selbst an Hand der Konfigurationen für Objekte und Beziehungen auf. Das bedeutet konkret für dein Buch, dass der Autor und die zugehörige Beziehung ebenfalls mit gespeichert wird. Es gibt nun mehrere Fälle, die jeweils einfach über die saveObject()-Methode abgedeckt werden:
  • Buch neu, Autor neu
  • Bestehendes Buch, neuer Autor
  • Bestehendes Buch, bestehender Autor
Sofern du folgenden Code nutzt, wird die Beziehung beim Speichern jeweils ohne Zutun für dich angelegt:

Code: Alles auswählen

$book->addRelatedObject('Author2Book', $author);
$orm->saveObject($book); 
Welche der oben genannten Fälle du vorliegen hast, kommt nun darauf an, wie $book und $author erstellt werden. Folgender Quellcode zeigt die einzelnen Fälle:

Code: Alles auswählen

// Neues Buch, neuer Autor
$book = new GenericDomainObject('Book');
$book->setProperty('Title', ...);
...

$author = new GenericDomainObject('Author');
$author->setProperty('Name', ...);
...

$book->addRelatedObject('Author2Book', $author);
$orm->saveObject($book);

// Neues Buch, bestehender Autor (z.B. durch Auswahlliste im Erstellen-Dialog)
$book = new GenericDomainObject('Book');
$book->setProperty('Title', ...);
...

$author = new GenericDomainObject('Author');
$author->setObjectId($authorId);
...

$book->addRelatedObject('Author2Book', $author);
$orm->saveObject($book);

// Bestehendes Buch, bestehender Autor (z.B. durch Auswahlliste im Erstellen-Dialog)
$book = new GenericDomainObject('Book');
$book->setObjectId($bookId);
...

$author = new GenericDomainObject('Author');
$author->setObjectId($authorId);
...

$book->addRelatedObject('Author2Book', $author);
$orm->saveObject($book); 
Natürlich kannst du auch mit Hilfe der createAssociation() eine Beziehung zwischen zwei Objekten "manuell" anlegen, in diesem Fall kannst du dir das aber sparen.

Der letzte Fall ist natürlich nur aus Gründen der Vollständigkeit dargestellt. Im täglichen Leben kommt dieser Anwendungsfall wohl nicht vor.

Hoffe, das hilft dir weiter.
Viele Grüße,
Christian

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 13:51:51

Perfekt! Es wird entsprechend gespeichert.

Nur eines passt noch nicht: Mir wird jedes Mal zusätzlich ein neuer, leerer Datensatz in die Tabelle ent_authors eingefügt. Das soll natürlich nicht sein.

Hier mal der Quelltext:

Code: Alles auswählen

    $form = &$this->getForm('AddBook');

    if ($form->isSent() && $form->isValid()){

        $Book = new GenericDomainObject('Books');
        $Book->setProperty('Title', $form->getFormElementByName('Title')->getAttribute('value'));
        $Book->setProperty('Price', $form->getFormElementByName('Price')->getAttribute('value'));

        $Author = new GenericDomainObject('Authors');
        $Author->setObjectId($form->getFormElementByName('Author')->getAttribute('value'));

        $Book->addRelatedObject('Author2Book', $Author);
        
        $orm = $this->getMapper();

        $orm->saveObject($Book);

        // Redirect to the books list
        HeaderManager::forward('?page=booklist');

    } 

Benutzeravatar
dr.e.
Administrator
Beiträge: 4536
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 04.09.2011, 14:38:11

Hi,

hast du mal den Output von

Code: Alles auswählen

$form->getFormElementByName('Author')->getAttribute('value') 
geprüft. Wenn hier keine saubere Id übergeben wird, legt der GORM einen neuen Datensatz für "Author" an (siehe oben).

Noch eine kleinigkeit: sind die Objekte bei dir immer im Plural definiert (z.B. "Authors")? Falls ja, würde ich das auf Singular ändern, denn ein Objekt im Plural assoziiert man mehr mit einer Liste denn mit einem Einzel-Objekt.
Viele Grüße,
Christian

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 14:42:20

dr.e. hat geschrieben:Hi,

hast du mal den Output von

Code: Alles auswählen

$form->getFormElementByName('Author')->getAttribute('value') 
geprüft. Wenn hier keine saubere Id übergeben wird, legt der GORM einen neuen Datensatz für "Author" an (siehe oben).
Ja, da scheint ein Problem zu sein. Der Wert ist NULL.
Wobei ich nicht nachvollziehen kann, wieso.

Der HTML-Teil sieht so aus:

Code: Alles auswählen

<form method="post" action="/apf_114_demo/index_books.php?page=book">
    <label for="Author">Author : </label>
    <select name="Author"><option value="1">Autor 1</option><option value="2">Autor 2</option></select><br/>
    <label for="Title">Title : </label><input type="text" name="Title" id="Title" /><br/>
    <label for="Price">Price : </label><input type="text" name="Price" id="Price" /><br/>
    <input type="reset" name="Reset" value="Clear forms" />
    <input type="submit" name="SubmitBook" value="Add book" />
</form> 
Die IDs sind also vorhanden. Es wird auch eine korrekte Verknüpfung in author2book erstellt.
Korrektur:Es wird die ID des neu erstellten Autors verwendet.

Wie es aussieht, lese ich allerdings den Wert des select-Feldes nicht korrekt aus. Laut Doku soll das mittels getSelectedOption gehen. Ich habe daher mal den Abschnitt gem. der Doku geändert:

Code: Alles auswählen

        $test = &$form->getFormElementByName('Author');
        $option = &$test->getSelectedOption();
        echo "Autor : - " . $option->getAttribute('value') . "-"; 
Nun erhalte ich dafür die Meldung:

Code: Alles auswählen

Fatal error: Call to a member function getAttribute() on a non-object in /var/www/apf_114_demo/apps/books/pres/controller/AddBookController.php on line 23 
Ein var_dump($option) ergibt NULL.
dr.e. hat geschrieben:Noch eine kleinigkeit: sind die Objekte bei dir immer im Plural definiert (z.B. "Authors")? Falls ja, würde ich das auf Singular ändern, denn ein Objekt im Plural assoziiert man mehr mit einer Liste denn mit einem Einzel-Objekt.
Das müsste ich ggf. noch anpassen.

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

Re: GORM für Einsteiger

Beitrag von dave » 04.09.2011, 15:13:46

ma2604121 hat geschrieben:Nun erhalte ich dafür die Meldung:

Code: Alles auswählen

Fatal error: Call to a member function getAttribute() on a non-object in /var/www/apf_114_demo/apps/books/pres/controller/AddBookController.php on line 23 
Hi!

Also zu dem Fehler möchte ich mal auf den von mir erstellten BugReport von gestern Abend verweisen. viewtopic.php?f=8&t=848 Christian scheint da schon was gemacht zu haben, ich kann aber erst heute Abend dardauf reagieren und es selbst bei mir ausprobieren. Aber soviel sei gesagt: An der Stelle bin ich gestern auch hängen geblieben. Feedback gibts dann erst heute Abend, muss noch an einer anderen Baustelle was erledigen :D

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 15:15:22

Das habe ich vorhin schon gelesen und mir die aktuelle APF-Version (Rev. 1467) gezogen, mit der ich derzeit auch arbeite.

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

Re: GORM für Einsteiger

Beitrag von dave » 04.09.2011, 15:20:30

Ist der Fehler damit behoben oder weiterhin vorhanden? Ich bin schon ein wenig nervös, obs nun klappt oder weitere Recherche notwendig ist ;)

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 15:22:47

Nein, ich erhalte obige Fehlermeldung, wenn ich den gewählten Wert mittels

Code: Alles auswählen

echo "Autor : " . $form->getFormElementByName('Author')->getSelectedOption()->getValue(); 
holen will.

Mag aber durchaus sein, dass ich noch irgendwo einen anderen Fehler habe.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4536
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 04.09.2011, 15:34:58

Die Geschichte mit getSelectedOption() muss gefixt sein, ich habe das gerade bei der Implementierung der UMGT-Erweiterungen genutzt und es funktioniert bei mir lokal (Version 1.15, jedoch identisch mit 1.14-stable). Kannst du deinen Code nochmal checken?
Viele Grüße,
Christian

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 04.09.2011, 15:46:08

Bin jetzt nochmal drüber gegangen, mir ist aber nichts ins Auge gefallen. Allerdings brauche ich eh mal eine Pause, da meine Konzentration etwas leidet.

Template

Code: Alles auswählen

<@controller namespace="books::pres::controller" file="AddBookController" class="AddBookController" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<h2>Add a new book</h2>
<html:form name="AddBook">
    <label for="Author">Author : </label>
    <form:select name="Author"/><br/>
    <label for="Title">Title : </label><form:text name="Title" id="Title"/><br/>
    <label for="Price">Price : </label><form:text name="Price" id="Price"/><br/>
    <form:reset name="Reset" value="Clear forms"/>
    <form:button name="SubmitBook" value="Add book"/>
</html:form>

<html:template name="AuthorsList">
    <select:option value="<template:placeholder name="ID"/>"><template:placeholder name="AuthorName"/></select:option>
</html:template> 
Controller

Code: Alles auswählen

<?php
import('tools::link','FrontcontrollerLinkHandler');
import('modules::genericormapper::data','GenericDomainObject');
import('tools::http', 'HeaderManager');

class AddBookController extends base_controller{

    public function  transformContent() {
    $form = &$this->getForm('AddBook');
    if ($form->isSent() && $form->isValid()){
        $Book = new GenericDomainObject('Books');
        $Book->setProperty('Title', $form->getFormElementByName('Title')->getAttribute('value'));
        $Book->setProperty('Price', $form->getFormElementByName('Price')->getAttribute('value'));
        $Author = new GenericDomainObject('Authors');
        $Author->setObjectId($form->getFormElementByName('Author')->getSelectedOption()->getValue());
        $Book->addRelatedObject('Author2Book', $Author);
        $orm = $this->getMapper();
        $orm->saveObject($Book);
        HeaderManager::forward('?page=booklist');
    }
    else{
    }
    }

    private function getMapper(){
    $ormFact = &$this->getServiceObject('modules::genericormapper::data', 'GenericORMapperFactory');
    return $ormFact->getGenericORMapper('modules::gorm', 'books', 'books');
    }
}
?>
Die erzeugte HTML-Datei:

Code: Alles auswählen

<form method="post" action="/apf_114_demo/index_books.php?page=book">
    <label for="Author">Author : </label>
    <select name="Author"><option value="1">Autor 1</option><option value="2">Autor 2</option></select><br/>
    <label for="Title">Title : </label><input type="text" name="Title" id="Title" /><br/>
    <label for="Price">Price : </label><input type="text" name="Price" id="Price" /><br/>
    <input type="reset" name="Reset" value="Clear forms" />
    <input type="submit" name="SubmitBook" value="Add book" />
</form>  

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

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 18:28:06

Die Lösung des Problems ist dank dave gefunden: viewtopic.php?f=8&p=9149

Nun wird alles korrekt gespeichert. Ich werde sehen, dass ich heute das Wiki entsprechend überarbeite.

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

Re: GORM für Einsteiger

Beitrag von dave » 05.09.2011, 18:53:21

Cool 8-)

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast