Daten in Model erweitern [Gelöst]

  • Freshmeat Freshmeat
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    26. 07. 2011, 18:00

    Ich befasse mich neu mit der Erstellung einer Extension auf Extbase/Fluid Basis. Jetzt haben sich einige Fragen aufgetan, die ich bis jetzt nicht lösen konnte. Hoffentlich kann mir jemand hier helfen.

    [b]Model um eigene Daten erweitern[/b]
    Ich habe verschiedene Datensätze die einen generischen Link zu einem Portal beinhalten. Diesen Link würde ich gern im Model verfügbar haben, aber er muss nicht in der Datenbank gespeichert werden. Wie kann ich diesen bei der Instanzierung des Objekts im Model "abspeichern"?
    Aktuell habe ich das in einem Viewhelper ausgelagert. Was für mich auch okey ist... nur habe ich eine ähnliche Situtation die sich nicht mit einem Viewhelper lösen lässt.

    Etwa das gleiche Problem habe ich mit einem anderen "Feld". Ich habe verschiedene Datensätze die auf einer Google-Map dargestellt werden. Ich möchte nun die umliegenden Datensätze finden und deren individuelle Distanz zum aktuellen Karten-Mittelpunkt ausgeben. Die Berechnung der Distanz findet auf einem eigenen SQL-Statement statt. Von dort wird die berechnete Distanz aber nicht an das Model weitergegeben. Kann ich diese im Repository irgendwie ins Model speichern pro einzelner Datensatz?

    PS: Ich weiss, dass ich die Distanz per Javascript errechnen könnte, nur muss ich sortieren können und wenn die Berechnung schon in der SQL stattfindet, bietet es sich an diese gleich zu verwenden.

    Hört sich kompliziert an, falls jemand Code-Stücke benötigt, dann kann ich diese nachliefern, aber ich glaube es sind eher grundsätzliche Fragen die sich auch in anderen Fällen bieten.


  • 1
  • Eydamos Eydamos
    Padawan
    0 x
    54 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 10:03

    Ich habe folgende Idee nicht getestet, sollte aber eigentlich funktionieren:

    Erweiter dein Model einfach um die entsprechenden Eigenschaften wie z.B. distanz. Mach dazu deine setter und getter Methoden.
    Trage die Eigenschaften die nicht in die Datenbank sollen auch NICHT ins TCA ein. Das sollte verhindern, dass TYPO3 versucht die Daten in die Datenbank zu schreiben bzw Sie auszulesen.
    Im Controller kannst du dann die Eigenschaften beliebig mit Daten füllen.

  • BlackPixel BlackPixe...
    Sternenflotten-Admiral
    0 x
    230 Beiträge
    3 Hilfreiche Beiträge
    27. 07. 2011, 10:10

    [quote="Eydamos"]
    Ich habe folgende Idee nicht getestet, sollte aber eigentlich funktionieren:

    Erweiter dein Model einfach um die entsprechenden Eigenschaften wie z.B. distanz. Mach dazu deine setter und getter Methoden.
    Trage die Eigenschaften die nicht in die Datenbank sollen auch NICHT ins TCA ein. Das sollte verhindern, dass TYPO3 versucht die Daten in die Datenbank zu schreiben bzw Sie auszulesen.
    Im Controller kannst du dann die Eigenschaften beliebig mit Daten füllen.
    [/quote]

    Genauso gehts. Einfach Dein Model um die Properties erweitern die du benötigst. Die Felder die nicht in der DB vorhanden sind werden auch nicht geschrieben.

    Gruß Manfred

    TYPO3 Slider Revolution: https://www.rutschmann.biz/extensions/typo3-slider-revolution/
    TYPO3 Layerslider Extension: http://www.rutschmann.biz/extensions/typo3-layerslider/
    TYPO3 Responsive Flipbook Extension: http://www.rutschmann.biz/extensions/typo3-responsive-flipbook/
    TYPO3 PayPal Download Checkout: http://www.rutschmann.biz/extensions/typo3-paypal-download/

    http://www.rutschmann.biz/
    ----------------------------------------------------
    Extbase, Fluid, HTML & CSS Development

  • Freshmeat Freshmeat
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 10:19

    Das habe ich bereits mit dem generischen Link probiert. Jedoch wird dieser im Objekt nicht mitgegeben, wenn ich z.B. über das Repository das Objekt anfrage.

    Habe dann versucht die Funktion im Konstruktor (oder auch im initStorageObjects) aufzurufen, aber dadurch wurde der Link nicht gesetzt. Und ich möchte nicht jedesmal einen Schleife machen für alle Objekte um den Link zu setzen.

    Was mache ich falsch?

  • Eydamos Eydamos
    Padawan
    0 x
    54 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 10:48

    Du musst den Wert wenn er nicht aus der Datenbank kommt irgendwo setzen.

    Entweder du schreibst ihn statisch ins Model rein, wenn es eh immer der selbe Wert ist kannst du ihn ja so als default nutzen, oder du setzt ihn im Controller. Wenn es mehrere Objekte sind musst du die halt in ner Schleife durchlaufen lassen.
    Der Konstruktor ist natürlich auch eine Möglichkeit, nur wird es dann glaub ich schwer einen Wert zu übergeben.

  • Freshmeat Freshmeat
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 10:56

    Konkret geht es um folgenden Link:

    1. http://maps.google.ch/maps?f=d&hl=de&geocode=&saddr=&daddr= ADDRESSE &sll= LATITUDE , LONGITUDE &sspn=&ie=isoz=15

    Die grossgeschriebenen Variablen des Links sind im Model (Datenbank) hinterlegt. Dieser Link möchte ich nun z.B. als Property "googleMapsUri" im Model verfügbar haben. Beim "build" des Models soll dieser erzeugt werden.

  • Eydamos Eydamos
    Padawan
    0 x
    54 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 12:07

    Du kannst ihn ja auch beim abfragen generieren.

    Fluid:

    1. {object.googleMapsUri}

    Model:
    1. public function getGoogleMapsUri() {
    2. return "http://maps.google.ch/maps?f=d&hl=de&geocode=&saddr=&daddr=".$this->addresse."&sll=".$this->latitude.",".$this->longitude."&sspn=&ie=isoz=15";
    3. }

  • Freshmeat Freshmeat
    Sternenflotten-Admiral
    0 x
    194 Beiträge
    0 Hilfreiche Beiträge
    27. 07. 2011, 14:22

    Okey ... jetzt konnte ich es lösen. Auf meine Art zufriedenstellend. Vielleicht sogar korrekt. Hatte etwas kompliziert gedacht.

    Im [b]Model[/b] habe ich die Distanz erweitert (ohne Datenbankfeld)
    Im [b]Repository[/b] eine Funktion geschrieben mit einem eigenen SQL-Statement das die umliegenden Standorte sucht. Liefert aber Objects zürck
    Im [b]Controller[/b] durchlaufe ich dann (trotzdem) nochmals alle Standorte und berechne mit der Suchanfrage die Distanz zum gewählten Standort. (PHP)

    [b]Model[/b]

    1. /**
    2.  * Description of property: distance
    3.  *
    4.  * @var string
    5.  */
    6. protected $distance;
    7.  
    8. /**
    9.  * Returns the distance between the own point and the target location
    10.  *
    11.  * @param string $lat
    12.  * @param string $lng
    13.  * @return string $distance
    14.  */
    15. public function calculateDistance($lat, $lng) {
    16.  
    17. $lat = $lat * 3.141 / 180; // calculate radian
    18. $lng = $lng * 3.141 / 180; // calculate radian
    19.  
    20. $placeLat = $this->getPlace()->getLatitude() * 3.141 / 180; // calculate radian
    21. $placeLng = $this->getPlace()->getLongitude() * 3.141 / 180; // calculate radian
    22.  
    23. $distance = round( 6371 * acos(sin($placeLat) * sin($lat) + cos($placeLat) * cos($lat) * cos($placeLng - $lng) ), 2);
    24.  
    25. return $distance;
    26. }

    [b]Repository[/b]

    1. public function findDemanded(Tx_KiAffiliates_Domain_Model_Demand $demand = NULL, $storagePid = NULL) {
    2.  
    3. $affiliatesQuery = $this->createQuery();
    4.  
    5. if ($demand !== NULL) {
    6.  
    7. $affiliatesQuery->statement('
    8. SELECT places.*, affiliates.*, ( ROUND( 6371 * ACOS( SIN( '.$demand->getSearchLocationLat().' * PI() / 180 ) * SIN( latitude * PI() / 180 ) + COS( '.$demand->getSearchLocationLat().' * PI() / 180 ) * COS( latitude * PI() / 180 ) * COS( ( longitude * PI() / 180) - ('.$demand->getSearchLocationLng().' * PI() / 180) ) ), 1 ) ) AS distance
    9. FROM tx_kiaffiliates_domain_model_places AS places
    10. INNER JOIN tx_kiaffiliates_domain_model_affiliates AS affiliates
    11. ON affiliates.place = places.uid
    12. WHERE affiliates.pid = '.$storagePid.'
    13. AND NOT affiliates.deleted
    14. AND NOT affiliates.hidden
    15. AND (
    16. ( affiliates.starttime = 0 AND affiliates.endtime = 0)
    17. OR ( affiliates.starttime < UNIX_TIMESTAMP() AND affiliates.endtime > UNIX_TIMESTAMP() )
    18. OR ( affiliates.starttime = 0 AND affiliates.endtime > UNIX_TIMESTAMP() )
    19. OR ( affiliates.starttime < UNIX_TIMESTAMP() AND affiliates.endtime = 0 )
    20. )
    21. AND affiliates.sys_language_uid IN (0, -1)
    22. HAVING distance < '.$demand->getSearchLocationRad().'
    23. ORDER BY distance
    24. ');
    25.  
    26. }
    27.  
    28. $affiliates = $affiliatesQuery->execute();
    29.  
    30. return $affiliates;
    31.  
    32. }

    [b]Controller[/b]

    1. $affiliates = $this->affiliatesRepository->findDemanded($demand, intval($configuration['persistence']['storagePid']));
    2.  
    3. foreach ($affiliates as $affiliate) {
    4.  
    5. $distance = $affiliate->calculateDistance($demand->getSearchLocationLat(), $demand->getSearchLocationLng());
    6. $affiliate->setDistance($distance);
    7.  
    8. }

    Kann/darf/sollte man das so machen?

  • Eydamos Eydamos
    Padawan
    0 x
    54 Beiträge
    0 Hilfreiche Beiträge
    28. 07. 2011, 09:06

    Ja ich denke ich hätte es auf jeden Fall ähnlich wenn nicht genauso gemacht.

    Noch eine kleine Anmerkung zum Controller:
    Du berechnest die Distanz und speicherst sie anschließend mit einer extra Methode ab. Es ist doch das selbe Objekt, also speicher die Distanz direkt im Objekt anstatt es zurückzugeben und danach mit einer setter zu speichern.

  • 1