Anfängerfragen Extbase

  • Philipp88 Philipp88
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    14. 03. 2013, 19:33

    Hi:)

    Ich bin gerade dabei mir Extbase anzueignen.
    Dazu habe ich 4 Fragen:

    1. Wie kann ich, wenn ich in meinem Controller per finAll() alle Datensätze hole mit den SQL- Befehlen "WHERE", "GROUP BY", "ORDER BY", "LIMIT" die Ausgabe ändern? Oder muss ich da ein eigenes Statement schreiben?

    2. SQL wird ja erst ausgeführt, wenn ich die Daten für den Viewhelper benötige. Was ist aber, wenn ich die Daten erst noch per PHP bearbeiten möchte und die dann erst ausgeben möchte? Früher habe ich per $GLOBALS["TYPO3_DB"]->SQL_fetch_assoc($res) jede Zeile einzeln geholt, Daten abgeändert und in Marker geschrieben. Wie geht sowas?

    3. Ich habe folgende Funktion in Repostory:

    1. public function all_name() {
    2. $res = array(
    3. "vorname" => "wwe",
    4. "name" => "wwebhj",
    5. );
    6.  
    7. return $res;
    8. }

    Wie bekomme ich ein Array - so wie ein SQL- Query - Zeile für Zeile ins Template? Wie muss das Array aufgebaut sein?

    4. Wenn ich per Extension Builder eine Extension erstelle, ist ja als Default eingestellt, dass die list- Action als erstes aufgerufen wird. Wie kann man das ändern?

    Ich weiß das sind viele Anfängerfragen zum Thema Extbase, hoffe aber trotzdem das jemand die mir antworten kann, würde mich sehr freuen :)
    Philipp


  • karf karf
    T3PO
    0 x
    25 Beiträge
    0 Hilfreiche Beiträge
    15. 03. 2013, 16:35

    [quote="Philipp88"]
    1. Wie kann ich, wenn ich in meinem Controller per finAll() alle Datensätze hole mit den SQL- Befehlen "WHERE", "GROUP BY", "ORDER BY", "LIMIT" die Ausgabe ändern? Oder muss ich da ein eigenes Statement schreiben?
    [/quote]
    Group By gibt es in extbase nicht, wenn du um die nutzung davon nicht rum kommst musst du ein eigenes SQL-Query schreiben. (es gibt aber ein GroupFor Viewhelper, den du eventuell vorher mal ausprobieren solltest)

    Für andere Querys musst du das entsprechende Repository erweitern

    Dort kannst du mit $this->createQuery() ein neues Query Objekt erstellen und dem Conditions und Sortierung mitgeben. Ich hab leider grad kein Simples Beispiel zur Hand, Schau dir am besten die Klasse \TYPO3\CMS\Extbase\Persistence\Generic\Query an. (wichtige methoden zum beispiel: matching(), execute() und setOrderings())

    Für einfache Abfragen wo du nur anhand einer Property filtern musst gibt es die findBy* Methoden.
    Also zum Beispiel findByUid() oder findByName() oder wie auch immer deine Properties heißen.

    [quote="Philipp88"]
    2. SQL wird ja erst ausgeführt, wenn ich die Daten für den Viewhelper benötige. Was ist aber, wenn ich die Daten erst noch per PHP bearbeiten möchte und die dann erst ausgeben möchte? Früher habe ich per $GLOBALS["TYPO3_DB"]->SQL_fetch_assoc($res) jede Zeile einzeln geholt, Daten abgeändert und in Marker geschrieben. Wie geht sowas?
    [/quote]

    Du kannst die Results aus den Repositories auch schon im PHP per foreach Schleife durchgehen. Und deine bearbeiten Dateien dann in ein Array oder ein ObjectStorage stecken und an den View weitergeben.
    also zum Beispiel so in der Art.

    1. $array = array();
    2.  
    3. foreach($this->repository->findAll() as $object)
    4. {
    5. $object->SetWhatEver(42);
    6. $array[] = $object;
    7. }
    8.  
    9. $this->view->assign('list', $array);

    [quote="Philipp88"]
    3. Ich habe folgende Funktion in Repostory:

    1. public function all_name() {
    2. $res = array(
    3. "vorname" => "wwe",
    4. "name" => "wwebhj",
    5. );
    6.  
    7. return $res;
    8. }

    Wie bekomme ich ein Array - so wie ein SQL- Query - Zeile für Zeile ins Template? Wie muss das Array aufgebaut sein?
    [/quote]

    Ich verstehe dein Beispiel grad glaube ich nicht ganz ;)
    Aber auf ein Array kannst du auf zwei Wege zugreifen.

    Wenn du ein Numerisches Array hast, also mit Index von 0 bis n
    kannst du mittels des for-ViewHelpers durch iterieren.

    und auf keys direkt kannst du mit "." zugreifen, also zum Beispiel "array.key"

    Hier ein kurzes Beispiel.

    1. $list = array(array('a' => 1, 'b' => 2),
    2. array('a' => 3, 'b' => 4),
    3. array('a' => 5, 'b' => 6),
    4. array('a' => 7, 'b' => 8-),
    5. );
    6.  
    7. $this->view->assign('list', $list);

    1. <f:for earch="{list}" as="value">
    2. <f:comment>{value} ist jetzt immer einer der inneren Arrays aus {list]</f:comment>
    3. <div>
    4. {value.a} <!-- 1, 3, 5 oder 7. je nach dem in welcher iteration wir sind -->
    5. {value.b} <!-- 2, 4, 6, 8 -->
    6. </div>
    7.  
    8. </f:for>
    9.  
    10. {list.0.a} würde natürlich ebenfalls 1 ausgeben. Das Funktioniert natürlich nicht mehr
    11. wenn du ein QueryResult (aus dem Repository) oder ein ObjectStorage (aus dem Model) hast.
    12.  
    13. Zu beachten ist eventuell noch, dass du auf die Property eines Models mit {model.property} zugreifst. (dabei wird dann $model->getProperty() ausgeführt)

    [quote="Philipp88"]
    4. Wenn ich per Extension Builder eine Extension erstelle, ist ja als Default eingestellt, dass die list- Action als erstes aufgerufen wird. Wie kann man das ändern?
    [/quote]

    Dort wo du im Builder dein Plugin definierst, kannst du auch die gültigen Actions angeben.
    immer in der Form "Controller => Action1, Action2, Action3" und je eine Zeile pro Controller.

    Die erste Action die du hier angibst wird Standardmäßig aufgerufen. (Hier Action1)

    [i]Alle Beispiele sind frei runtergetippt, also keine Garantie das sie direkt laufen![/i]

  • Philipp88 Philipp88
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    18. 03. 2013, 18:16

    danke für deine ausführliche Antwort :) Leider verstehe ich das bearbeiten der Daten noch nicht ganz:( SetWhatEver(42); - Was bedeutet die 42?
    Wie bekomme ich die gesamte Anzahl der Datensätze in PHP - ohne sie mit den Viewhelper item auszugeben? Für Berechnung der Seiten in einer Navigation etc.?
    Also die Querys mit LIMIT und komplexeren where- Bedingungen kann ich ohne Probleme selbst schreiben oder gibt's da sowas wie findAll() mit Parameter?

  • karf karf
    T3PO
    0 x
    25 Beiträge
    0 Hilfreiche Beiträge
    18. 03. 2013, 18:36

    SetWhatEver(42); ist nur ein Beispiel, weil du ja in PHP noch irgendwas an den Models verändern wolltest bevor du sie dem View übergibst.

    Die Anzahl der Datensätze bekommst du mit der Methode QueryResult::count() (QueryResults sind die Objekte die die Repositories zurück geben)

    also zum Beispiel, $this->repository->findAll()->count()

    [i]Vorsicht, das "count()" funktioniert nicht mehr, wenn du per statement() ein eigenes SQL Query schreibst! Dann wird dir count() immer die Anzahl aller Datensätze zurück geben![/i]

    Selber SQL zu schreiben ist in Extbase immer eine schlechte Idee (auch wenn es sich nicht immer vermeiden lässt)

    generell gibt es für jede Property deines Models die Methoden FindByProperty() und FindOneByProperty() im Repository. Wobei "Property" der Property name ist, also zum Beispiel findByTitle('test') oder findOneByName('foo'). Ersteres gibt ein QueryResult zurück, das alle Models mit dem Titel "test" beinhalten, das zweite Beispiel gibt dir direkt ein Model mit dem Namen 'foo' zurück. (wenn es mehrere mit dem Namen gibt, dann das erste davon)

    Brauchst du mehr als ein Kriterium (oder was anderes wie eine "ist gleich" Beziehung) musst du eine eigene Methode im Repository schreiben.

    hier mal ein kleines Beispiel:

    1. public function findNonPublicByTest(\TYPO3\MyExt\Domain\Model\Test $test) {
    2.  
    3. $query = $this->createQuery();
    4.  
    5. $condition1 = $query->equals('public', false);
    6. $condition2 = $query->equals('test', $test);
    7. $condition = $query->logicalAnd($condition1, $condition2);
    8.  
    9. $query->matching($condition);
    10. $query->setOrderings(array('titel' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
    11.  
    12. return $query->execute();
    13. }

    Hier kriege ich eine Liste aller Datensätze zurück die nicht public sind und in der Property "Test" mit dem übergebenen Objekt übereinstimmen.

    Ist etwas umständlich gemacht, aber wenn man sich dran gewöhnt hat funktioniert es eigentlich ganz gut ;)

    Wenn es immer noch nicht klar ist, Zeig mir einfach mal wie deine aktuellen Models aussehen, dann tippe ich dir schnell Beispiele anhand deiner eigenen Models zusammen.

  • tobla tobla
    R2-D2
    0 x
    100 Beiträge
    1 Hilfreiche Beiträge
    19. 03. 2013, 13:39

    Hallo Philipp88

    Hinter Extbase steckt ein komplett anderes Konzept als bei der alten pi-Base. Bitte programmiere auf KEINEN Fall in Extbase so, wie du mit pi-Base Extensions geschrieben hast, das kommt nicht gut *schauder*. #angry#

    Extbase setzt auf Objektorientierte Programmierung, während pi-Base irgendetwas zwischen strukturierter und undefinierter Programmierung als Konzept voraussetzte. http://de.wikipedia.org/wiki/Objektorientierte_Programmierung

    Die Leute von Mittwald haben ein sehr gutes Manual geschrieben, das dich Schritt für Schritt an Extbase heranführt und als Beispiel gleich eine kleine Extension anlegt. https://www.mittwald.de/fileadmin/downloads/pdf/dokus/Extbase_Fluid_Dokumentation.pdf

    Das Manual hast du relativ schnell durch. Anschliessend bist du mit den Konzepten vertraut und meines Erachtens lösen sich dann auch alle von dir gestellten Fragen.

  • Philipp88 Philipp88
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    10. 04. 2013, 17:22

    Hi ich nochmal :)

    ich bin richtig am verzweifeln mit Extbase:(
    Also ich arbeite gerade das Tutorial durch was oben verlinkt wurden ist.

    Wenn ich wie beschrieben auf Seite 82 den Code schreibe in ProjektController.php

    1. $this->projektRepository = t3lib_div::makeInstance (
    2. "Tx_timetrack_Domain_Repository_ProjektRepository" );

    Kommt folgender Fehler:
    "Fatal error: Class '\TYPO3\Timetrack\Controller\ProjektController' not found"

    Könnt ihr mir helfen?

  • karf karf
    T3PO
    0 x
    25 Beiträge
    0 Hilfreiche Beiträge
    10. 04. 2013, 18:11

    [quote="Philipp88"]
    Hi ich nochmal :)

    ich bin richtig am verzweifeln mit Extbase:(
    Also ich arbeite gerade das Tutorial durch was oben verlinkt wurden ist.

    Wenn ich wie beschrieben auf Seite 82 den Code schreibe in ProjektController.php

    1. $this->projektRepository = t3lib_div::makeInstance (
    2. "Tx_timetrack_Domain_Repository_ProjektRepository" );

    Kommt folgender Fehler:
    "Fatal error: Class '\TYPO3\Timetrack\Controller\ProjektController' not found"

    Könnt ihr mir helfen?
    [/quote]

    Irgendwie passt dein Code und deine Fehlermeldung nicht zusammen (einmal Repository und einmal Controller?)

    Nutzt du Typo3 4.x oder Typo3 6.x?

    und generell würde ich empfehlen Objekte über den Objekt Manager zu erstellen. Also per "$this->objectManager->get($className);"

  • Philipp88 Philipp88
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    10. 04. 2013, 18:19

    ich nutze 6.0.
    Php kennt die t3lib_div Klasse nicht, gibs die in 6 nicht?

  • karf karf
    T3PO
    0 x
    25 Beiträge
    0 Hilfreiche Beiträge
    10. 04. 2013, 18:31

    doch die gibt es natürlich. Aber du befindest dich in einem namespace, dann heißt die klasse nicht mehr t3lib_div sondern \t3lib_div

    Aber wie gesagt ich würde dir wirklich empfehlen den objectManager zu verwenden. Ansonsten kannst du komische Fehler mit deinen Objekten bekommen.

    Also in deinem Fall

    1. $this->projektRepository = $this->objectManager('TYPO3\Timetrack\Domain\Repository\ProjektRepository');

    (oder bist du dir sicher das deine Klasse Tx_timetrack_Domain_Repository_ProjektRepository heißt? In Typo3 6 solltest du am besten die namespaces benutzen!)

    Noch besser ist es aber natürlich sich die Repositorys direct injecten zu lassen. dazu einfach die @inject Annotation an deine Klasse-Variable schreiben.

    also

    1. /**
    2.  * ProjektRepository
    3.  * @var \TYPO3\Timetrack\Domain\Repository\ProjektRepository
    4.  * @inject
    5.  **/
    6. protected $projektRepository;

    Danach hast du in $this->projectRepository automatisch deine Repository Klasse drin. (nicht vergessen vorher den Cache zu löschen ;))

  • Philipp88 Philipp88
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    10. 04. 2013, 19:13

    Sorry nochmal :(

    erstmal Danke, hat geklappt :)

    jetzt ein anderes Problem:
    Wie kann ich im Controller eine neue Funktion anmelden?

    1. The action "cform" (controller "Personen") is not allowed by this plugin

    Funktion heißt "cform"

    1. /**
    2. * action cform
    3. *
    4. * @return void
    5. */
    6. protected function cformAction($person) {
    7. \t3lib_utility_Debug::debug($person, 'auto');
    8.  
    9. }

    Ich finde die alte Programmierung war verständlicher bzw. einfacher als Extbase oder ändert sich das noch?