Zum Inhalt springen

Anfängerfragen Extbase

Erstellt am 14. März 2013 · 18 Antworten · letzte Antwort am 2. Mai 2013

Tags: Frage

karf ·

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()

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!

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:

	public function findNonPublicByTest(\TYPO3\MyExt\Domain\Model\Test $test) {
		    
		        $query = $this->createQuery();
		        
		        $condition1 = $query->equals('public', false);
		        $condition2 = $query->equals('test', $test);
		        $condition  = $query->logicalAnd($condition1, $condition2);
		        
		        $query->matching($condition);
			     $query->setOrderings(array('titel' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
		        
		        return $query->execute();
	}

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 ·

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 ·

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

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

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

Könnt ihr mir helfen?

karf ·
Philipp88 schrieb

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

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

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

Könnt ihr mir helfen?

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);"

karf ·

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

$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

/**
 * ProjektRepository
 * @var \TYPO3\Timetrack\Domain\Repository\ProjektRepository
 * @inject
 **/
protected $projektRepository;

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

Philipp88 ·

Sorry nochmal 🙁

erstmal Danke, hat geklappt 🙂

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

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

Funktion heißt "cform"

 /**
	 * action cform
	 *
	 * @return void
	 */
	protected function cformAction($person) {
          \t3lib_utility_Debug::debug($person, 'auto');
          
	}

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

karf ·
Philipp88 schrieb

Sorry nochmal 🙁

erstmal Danke, hat geklappt 🙂

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

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

Funktion heißt "cform"

 /**
	 * action cform
	 *
	 * @return void
	 */
	protected function cformAction($person) {
          \t3lib_utility_Debug::debug($person, 'auto');
          
	}

Im Extension Builder, auf der Linken Seite wo du deine Plugins einrichtest gibt es eine Textbox in die du alle validen Actions für dieses Plugin schreiben kannst. Da dürftest du auch schon etwas reingeschrieben haben, da soweit ich weiß bei keiner Angabe alle Actions erlaubt sind.

Wenn du den Extension Builder nicht nutzt (was ein Fehler ist! der nimmt dir sehr viel Arbeit ab!) kannst du das in der localconf.php konfigurieren.

Philipp88 schrieb

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

Extbase ist in seinen Grundzügen sehr logisch aufgebaut, wenn du mal verstanden hast warum es was macht und vorallem was es alles automatisch macht wirst du es einfacher haben 😉
Allerdings kam ich mit piBase auch nie zurecht *g* (Ok, musste es glücklicherweiße auch nicht allzulange nutzen)

Philipp88 ·

ok, ich habe es jetzt mit den Extension Builder aktualisiert jetzt geht es🙂

Jetzt habe ich ein Formular was in etwa so aussieht:

<f:form action="cform" name="person">
  <table>
    <tr>
      <td>Name</td>
      <td><f:form.textfield property="name" /></td>
    </tr>
    <tr>
      <td>Vorname</td>
      <td><f:form.textfield property="vorname" /></td>
    </tr>
    <tr>
      <td>Kurze Beschreibung</td>
      <td><textarea name="tx_people_people[desc]" cols="10" rows="5"></textarea></td>
    </tr>
    <tr>
      <td colspan="2"><input type="submit" name="tx_people_people[send]" value="Benutzer anlegen" /></td>
    </tr>
  </table>
  </f:form>

Ich versuche jetzt mittels Extbase an die variablen (post) heranzukommen:

public function cformAction($person) {
          \t3lib_utility_Debug::debug($person, 'person');
	}

leider ohne erfolg🙁

Kannst du bitte nochmal helfen?

karf ·

Damit extbase dir ein Objekt erstellt musst du das im <f:form> angeben.

In deinem Fall würde das jetzt so aussehen

<f:form action="cform" name="person" object="{person}">

ich bin mir nicht sicher ob du vorher {person} selbst erzeugen musst. Schaden tut es sicherlich nicht 😉

Es gibt übrigens auch einen <f:form.textarea /> ViewHelper.

(Basic Viewhelper sind alle hier aufgelistet: http://wiki.typo3.org/Fluid)

Philipp88 ·

Hi,

ich habe jetzt den Formular object="{Person}" mitgegeben, leider ist die Variable immer noch leer🙁

Was meinst du mit object selber anlegen?

karf ·

In der dazugehörigen Action eine neue Instanz von Person erstellen

$person = $this->objectManager->create('\Dein\Model\Person');

und an den View übergeben.

$this->view->assign('person', $person);

Ich bin mir aber nicht sicher, ob das nötig ist oder dein Problem löst. Aber so mache ich das meistens (Im Normalfall um default Parameter zu setzen)

Morgen oder Montag werde ich aber wahrscheinlich ein neues Formular machen müssen, da schau ich mal nach welche Schritte mindestens nötig sind.

Philipp88 ·

Das wäre nett von dir ich bekomme das einfach nicht zum laufen 🙁

Jetzt kommt folgende Fehlermeldung:

1253175643: The argument type for parameter $person of method TYPO3\People\Controller\PersonenController->cformAction() could not be detected.

Bei diesen PHP- Code:

/**
	 * action cform
	 *
	 * @return void
	 */
	public function cformAction($person) {
          $person = $this->objectManager->create('\TYPO3\People\Domain\Model\Personen');
          
          $this->view->assign('person', $person);
	}

Wenn ich bei der Funktion den Parameter weglasse kommt zwar nicht mehr die Fehlermeldung von oben, stattdessen aber ne andere:

Fatal error: Class '\TYPO3\People\Domain\Model\Personen' not found

Das Model gibt es aber ...🙁

Bitte helf mir

Philipp

karf ·
Philipp88 schrieb

Das wäre nett von dir ich bekomme das einfach nicht zum laufen 🙁

Jetzt kommt folgende Fehlermeldung:

1253175643: The argument type for parameter $person of method TYPO3\People\Controller\PersonenController->cformAction() could not be detected.

Bei diesen PHP- Code:

/**
	 * action cform
	 *
	 * @return void
	 */
	public function cformAction($person) {
          $person = $this->objectManager->create('\TYPO3\People\Domain\Model\Personen');
          
          $this->view->assign('person', $person);
	}

Du musst den Parameter noch als Annotation in den Header eintragen.
also
@param \TYPO3\People\Domain\Model\Personen $person
in die Zeile vor dem @return

Philipp88 schrieb

Wenn ich bei der Funktion den Parameter weglasse kommt zwar nicht mehr die Fehlermeldung von oben, stattdessen aber ne andere:

Fatal error: Class '\TYPO3\People\Domain\Model\Personen' not found

Das Model gibt es aber ...🙁

Bitte helf mir

Philipp

Sorry das war ein Fehler in meinem Beispiel. Wenn du Klassennamen an eine Typo3 Funktion übergibst, immer ohne den ersten / vom Namespace. Also nur 'TYPO3\People\Domain\Model\Personen'

Du solltest aber vorher noch überprüfen ob nicht ein Objekt übergeben wurde, ansonsten macht der Parameter ja keinen Sinn und du würdest immer mit einem frischen Objekt beginnen. (oder ist das gewollt?)

if ($person == null)
{
    $person = $this->objectManager->create('TYPO3\People\Domain\Model\Personen');
}
Philipp88 ·

hast du schon etwas herrausfinden können? Bei mir funzt es einfach nicht 🙁

Mal was anderes:

Ich sitze jetzt an einer anderen Extension, wo mehrere Bilder ein Datensatz zugeordnet sind und diese in der Singleansicht ausgegeben werden sollen.

Erstmal der Code:

Controller:

...
public function showAction(\TYPO3\Project\Domain\Model\Project $project) {
    $project_id = $this->request->getArgument('project');
    $this->view->assign('project', $project);
    $this->view->assign("path", "uploads/tx_project");

    $images = $this->projectRepository->get_images($project_id);    
    #print_r($images);
    
    $this->view->assign("images", $images);
    
  }

Repository:

public function showAction(\TYPO3\Project\Domain\Model\Project $project) {
    $project_id = $this->request->getArgument('project');
    $this->view->assign('project', $project);
    $this->view->assign("path", "uploads/tx_project");

    $images = $this->projectRepository->get_images($project_id);    
    #print_r($images);
    
    $this->view->assign("images", $images);
    
  }

Ergebnis soll in Template erscheinen:

<f:for each="{images}" as="image">
          {image.image}
        </f:for>

Leider kommt dann folgende Fehlermeldung 🙁

Cannot cast object of type "TYPO3\CMS\Extbase\Persistence\ObjectStorage" to string.

Was ist den da falsch?

Kannst Du oder jemand anderes mir helfen?
Philipp