Extbase 6.0 Model erweitern [Gelöst]

  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    12. 03. 2013, 13:18

    Hallo,

    TYPO3 6.0.4
    Extbase 6.0.0

    Ich möchte eine (vorerst nur eine Test-) Extension um ein Feld erweitern. Dazu habe ich mit dem Extension Builder eine weitere Extension angelegt. Dort die zu erweiternde Tabelle und das Model angegeben. Die Datenbank wird richtig um die Felder "meinFeld" und "tx_extbase_type" erweitert. Wird im BE der ExtbaseType umgestellt, kann das neue Feld auch korrekt befüllt werden. Nur die Ausgabe im Frontend klappt (noch) nicht. Meine Vermutung, es liegt am Mapping im Typoscript. Der Extension Builder erstellt folgendes Script:

    VendorName: Alpgis,
    Model: Poi,
    zu erweiternde Ext: Test,
    neue Ext: golf

    1. config.tx_extbase {
    2. persistence {
    3. classes {
    4. Alpgis\Test\Domain\Model\Poi {
    5. subclasses {
    6. Tx_Golf_Poi =
    7.  
    8. }
    9. }
    10. {
    11. mapping {
    12. tableName = tx_test_domain_model_poi
    13. recordType = Tx_Golf_Poi
    14. }
    15. }
    16.  
    17. }
    18. }
    19. }

    Dies bringt folgende Fehlermeldung: No class name was given to retrieve the Data Map for.
    Vergebe ich bei "Tx_Golf_Poi =" eine Klasse, kriege ich keine FE-Ausgabe mehr.

    Hat jemand von euch Erfahrungen damit und kann mir den ein oder anderen Tipp geben? Vielen Dank!


  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    12. 03. 2013, 19:13

    Rollen wir das Ganze mal von vorne auf... was braucht man, um mit ext2 die ext1 um ein feld zu erweitern und dies per Fluid ausgeben zu können?

    1. DB-Feld (Feld und tx_extbase_type, zB mit Hilfe von Extension Builder)
    2. Model, welches das Model der ext1 "extended" (auch zB mit Hilfe von Extension Builder)

    ...richtig so weit? wie weiter? (TypoScript? Controller? Repository? ext_tables.php?)

  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    14. 03. 2013, 16:50

    Aktuelle Erkenntnis: Traue nicht dem Extension Builder! Dieser generiert in v2.5.1 ein völlig anderes ext_tables.php als in v2.5.2. Und ich finde einfach die Lösung nicht, für ein - wie ich denke triviales - Problem.

    Kann mir jemand ein funktionierendes Beispiel nennen, indem eine Extbase-Extension eine vorhandene Extbase-Klasse und deren DB-Tabelle erweitert und die Daten im FE ausgegeben werden können? Ich seh momentan gar nicht mehr durch... #angry# ich möchte die "Original"-Klasse, wenn irgendwie möglich, nicht anfassen.

    Danke vielmals!

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 03. 2013, 12:18

    Die Erkenntnis ist schonmal gut :) (Traue nicht dem Extension Builder!)

    Ich nutze noch TYPO3 v4.5 und den ExtensionBuilder 2.4.0
    ... daher weiß ich nicht, ob mein Wissen deinem Problem dient...

    Ich weiß: einbinden externer Klassen geht damit garnicht.
    Relationen innerhalb der eigenen Domäne müssen nach dem Kickstart noch editiert werden.
    Bisher ist allerdings fe_user die einzige externe von mir genutzte Tabelle.
    Extbase hat ja dafür auch schon eine eigene Klasse: Tx_Extbase_Domain_Model_FrontendUser.
    Die nutze ich, wie sie ist. Ich hab die nicht aufgebohrt

    Zuerst würde ich mir die ext_tables.SQL anschauen. Der ExtensionManager erzeugt gern doppelte Einträge.
    Die gewünschten DB-Tabellen und deren Spalten müssen hier drin sein!
    (so wie ich das bei dir lese, tut dieser Teil schon)
    Solange die Eingabe nur über FE erfolgt, ist die TCA-Config (ext_tables.php) auch uninteressant.

    Die Erweiterung des Models um das Attribut, muss logischerweise in deinNeuesModel.php

    Ich hab nicht verstanden, was genau in deinem FE nicht zu sehen ist. Die View muss natürlich wissen, daß es sich um das erweiterte Model handelt, um die richtigen Attribute lesen zu können und es richtig anzuzeigen. Und jeder View muss immer tapfer alles übergeben werden, was sie braucht. Dieser Punkt wird gern bei der Verwendung von Partials vergessen.

    Gruß Harald

  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    15. 03. 2013, 12:48

    Ja, die TCA-Config krieg ich soweit hin. Im Backend habe ich das neue Feld, sowie "tx_extbase_type". Trage ich im neuen Feld Daten ein, werden die auch brav in die DB gespeichert und auch wieder ausgelesen.

    Was noch nicht klapp, ist die Erweiterung des Models. Das Model sieht folgendermassen aus:

    1. class Model2 extends \Vendor\Ext1\Domain\Model\Model {
    2.  
    3. /**
    4. * additional
    5. *
    6. * @var \string
    7. */
    8. protected $additional;
    9.  
    10. /**
    11. * Returns the additional
    12. *
    13. * @return \string $additional
    14. */
    15. public function getAdditional() {
    16. return $this->additional;
    17. }
    18.  
    19. /**
    20. * Sets the additional
    21. *
    22. * @param \string $additional
    23. * @return void
    24. */
    25. public function setAdditional($additional) {
    26. $this->additional = $additional;
    27. }
    28.  
    29. }

    Nur kriege ich das ganze jetzt nicht ins Fluid-Template. Erweitere ich das "original" Model per Hand um obenstehende Code, klappt es problemlos. Also ist mein Verdacht, dass das Model gar nicht wirklich erweitert wird. Denn auch ein Debug im Fluidtemplate gibt das neue Feld noch nicht aus. Mapping im TS falsch?!

    1. config.tx_extbase {
    2. persistence {
    3. classes {
    4. Vendor\Ext1\Domain\Model\Model {
    5. subclasses {
    6. Vendor\Ext2\Domain\Model\Model2 = Vendor\Ext2\Domain\Model\Model2
    7. }
    8. }
    9. Vendor\Ext2\Domain\Model\Model2 {
    10. mapping {
    11. recordType = Vendor\Ext2\Domain\Model\Model2
    12. tableName = tx_ext1_domain_model_model
    13. }
    14. }
    15. }
    16. }
    17. }

    So hab ich das aus blog_example 6.0 abgeschaut. [url=https://github.com/alexanderschnitzler/Blog-Example-6.0]Hier[/url]

    Die View muss natürlich wissen, daß es sich um das erweiterte Model handelt, um die richtigen Attribute lesen zu können und es richtig anzuzeigen

    Klar, nur wie bring ich Ihr das bei? ;-)

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 03. 2013, 13:37

    Nun... das oft zitierte BlogExample hab ich nicht gemacht.

    Ich kenn mich auch nicht so richtig gut aus mit TS-Config.
    Wenn's tut ist gut ;)

    Ich hab bei mir hier sowas:

    1. plugin.tx_myext.persistence.classes {
    2. Tx_Myext_Domain_Model_SubClass.mapping.tableName = tx_myext_domain_model_parentclass
    3. }

    auf dein Model übertragen sollte das dann so aussehen:

    1. plugin.tx_ext2.persistence.classes {
    2. Tx_Ext2_Domain_Model_Model.mapping.tableName = tx_ext1_domain_model_model
    3. }

    Erweitere ich das "original" Model per Hand um obenstehende Code, klappt es problemlos.

    Wo ist dann das Problem?

  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    15. 03. 2013, 14:30

    "Erweitere ich das "original" Model per Hand um obenstehende Code, klappt es problemlos."

    Wo ist dann das Problem?

    Ich will das Model der zu erweiternden Extension nicht "manuel" abändern, sondern nur mit einer zweiten Extension erweitern (Updatesicherheit).

    Habe es nun endlich hin bekommen. Ich glaube ein fehlender Backslash am Anfang der zu erweiternden Klasse im neuen Model hat mich schier in den Wahnsinn getrieben. Desweiteren scheint mir die vom Extension Builder 2.5.2 generierte ext_tables.php nicht brauchbar. Diejenige von v2.5.1 jedoch schon. Bei der setup.txt verhält es sich genau anders rum...

    Ich habe nun noch einmal zwei Extensions erstellt und teile hier die nötigen Files von Extension2, welche Extension1 um ein Feld erweitert. Typo3 läuft momentan in Version 6.0.4.

    Die Files von Extension1 sind wohl uninteressant. Die Extension heisst "Extension1" hat den VendorName "Vendor", den Extension-Key "ext1" und ein Model "Model1" mit einem Feld "field1".

    Nun zur relevanten Extension2:
    Name: Extension2
    VendorName: Vendor
    Key: ext2
    Model: Model2 (erweitert Model1)
    Feld: field2

    Hier die relevanten Files:

    [b]Classes/Domain/Model/Model2.php:[/b]

    1. <?php
    2. namespace Vendor\Ext2\Domain\Model;
    3.  
    4. /***************************************************************
    5.  * Copyright notice
    6.  *
    7.  * (c) 2013
    8.  * All rights reserved
    9.  *
    10.  * This script is part of the TYPO3 project. The TYPO3 project is
    11.  * free software; you can redistribute it and/or modify
    12.  * it under the terms of the GNU General Public License as published by
    13.  * the Free Software Foundation; either version 3 of the License, or
    14.  * (at your option) any later version.
    15.  *
    16.  * The GNU General Public License can be found at
    17.  * http://www.gnu.org/copyleft/gpl.html.
    18.  *
    19.  * This script is distributed in the hope that it will be useful,
    20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22.  * GNU General Public License for more details.
    23.  *
    24.  * This copyright notice MUST APPEAR in all copies of the script!
    25.  ***************************************************************/
    26.  
    27. /**
    28.  *
    29.  *
    30.  * @package ext2
    31.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
    32.  *
    33.  */
    34. class Model2 extends \Vendor\Ext1\Domain\Model\Model1 {
    35.  
    36. /**
    37. * field2
    38. *
    39. * @var \string
    40. */
    41. protected $field2;
    42.  
    43. /**
    44. * Returns the field2
    45. *
    46. * @return \string $field2
    47. */
    48. public function getField2() {
    49. return $this->field2;
    50. }
    51.  
    52. /**
    53. * Sets the field2
    54. *
    55. * @param \string $field2
    56. * @return void
    57. */
    58. public function setField2($field2) {
    59. $this->field2 = $field2;
    60. }
    61.  
    62. }
    63. ?>

    [b]Configuration/TypoScript/setup.txt[/b]

    1. config.tx_extbase{
    2. persistence{
    3. classes{
    4. Vendor\Ext1\Domain\Model\Model1 {
    5. subclasses {
    6. Tx_Ext2_Model2 = Vendor\Ext2\Domain\Model\Model2
    7. }
    8. }
    9. Vendor\Ext2\Domain\Model\Model2 {
    10. mapping {
    11. tableName = tx_ext1_domain_model_model1
    12. recordType = Tx_Ext2_Model2
    13. }
    14. }
    15. }
    16. }
    17. }

    [b]ext_tables.php[/b]

    1. <?php
    2. if (!defined('TYPO3_MODE')) {
    3. die ('Access denied.');
    4. }
    5.  
    6. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'Extension2');
    7. \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA('tx_ext1_domain_model_model1');
    8.  
    9. if (!isset($TCA['tx_ext1_domain_model_model1']['ctrl']['type'])) {
    10. // no type field defined, so we define it here. This will only happen the first time the extension is installed!!
    11. $TCA['tx_ext1_domain_model_model1']['ctrl']['type'] = 'tx_extbase_type';
    12. $tempColumns = array();
    13. $tempColumns[$TCA['tx_ext1_domain_model_model1']['ctrl']['type']] = array(
    14. 'exclude' => 1,
    15. 'label' => 'LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext2_domain_model_model2.tx_extbase_type',
    16. 'config' => array(
    17. 'type' => 'select',
    18. 'items' => array(
    19. array('LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext2_domain_model_model2.tx_extbase_type.0','0'),
    20. ),
    21. 'size' => 1,
    22. 'maxitems' => 1,
    23. 'default' => 'Tx_Ext2_Model2'
    24. )
    25. );
    26. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_ext1_domain_model_model1', $tempColumns, 1);
    27. }
    28.  
    29. $TCA['tx_ext1_domain_model_model1']['types']['Tx_Ext2_Model2']['showitem'] = $TCA['tx_ext1_domain_model_model1']['types']['1']['showitem'];
    30. $TCA['tx_ext1_domain_model_model1']['columns'][$TCA['tx_ext1_domain_model_model1']['ctrl']['type']]['config']['items'][] = array('LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext2_domain_model_model2','Tx_Ext2_Model2');
    31. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tx_ext1_domain_model_model1', $TCA['tx_ext1_domain_model_model1']['ctrl']['type'],'','after:hidden');
    32.  
    33.  
    34. $tmp_ext2_columns = array(
    35.  
    36. 'field2' => array(
    37. 'exclude' => 0,
    38. 'label' => 'LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext2_domain_model_model2.field2',
    39. 'config' => array(
    40. 'type' => 'input',
    41. 'size' => 30,
    42. 'eval' => 'trim'
    43. ),
    44. ),
    45. );
    46.  
    47. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_ext1_domain_model_model1',$tmp_ext2_columns);
    48.  
    49. $TCA['tx_ext1_domain_model_model1']['columns'][$TCA['tx_ext1_domain_model_model1']['ctrl']['type']]['config']['items'][] = array('LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext1_domain_model_model1.tx_extbase_type.Tx_Ext2_Model2','Tx_Ext2_Model2');
    50.  
    51. $TCA['tx_ext1_domain_model_model1']['types']['Tx_Ext2_Model2']['showitem'] = $TCA['tx_ext1_domain_model_model1']['types']['1']['showitem'];
    52. $TCA['tx_ext1_domain_model_model1']['types']['Tx_Ext2_Model2']['showitem'] .= ',--div--;LLL:EXT:ext2/Resources/Private/Language/locallang_db.xlf:tx_ext2_domain_model_model2,';
    53. $TCA['tx_ext1_domain_model_model1']['types']['Tx_Ext2_Model2']['showitem'] .= 'field2';
    54.  
    55. ?>

    [b]ext_tables.sql[/b]

    1. #
    2. # TABLE STRUCTURE FOR TABLE 'tx_ext1_domain_model_model1'
    3. #
    4. CREATE TABLE tx_ext1_domain_model_model1 (
    5.  
    6. field2 VARCHAR(255) DEFAULT '' NOT NULL,
    7.  
    8. tx_extbase_type VARCHAR(255) DEFAULT '' NOT NULL,
    9.  
    10. );

    Ich hab dann einfach die Templates von Extension1 in das Verzeichnis von Extension2 kopiert, um die gewünschten Felder erweitert und in Configuration/TypoScript/constants.txt die Template-Pfade für das Plugin von Extension1 angepasst. Funktioniert nun soweit einwandfrei, ist jedoch noch nicht bis ins Detail getestet. Wüsste jedoch nicht, was noch schief gehen sollte ;)

    Ich hoffe, dass dies dem Ein oder Anderen die Zeit erspart, welche ich dafür gebraucht habe.

    Grüsse
    Kjuuze

  • harald1972 harald197...
    Sternenflotten-Admiral
    0 x
    198 Beiträge
    13 Hilfreiche Beiträge
    15. 03. 2013, 14:50

    Habe es nun endlich hin bekommen. Ich glaube ein fehlender Backslash am Anfang der zu erweiternden Klasse im neuen Model hat mich schier in den Wahnsinn getrieben.

    Schön, freut mich für dich, wenn du es auch ohne meine Hilfe hinkriegst ;)

    Diese Backslash-Notation ist mir nicht so geläufig, verwende ich nicht. Bei mir sieht das (besipielhaft) immer so aus:

    1. class Tx_MyExt_Domain_Model_Foobar extends Tx_Extbase_DomainObject_AbstractEntity

  • kjuuze kjuuze
    Padawan
    0 x
    35 Beiträge
    0 Hilfreiche Beiträge
    15. 03. 2013, 15:05

    Das sind die Namespaces, welche mit Typo3 CMS 6.0.0 eingeführt wurden und die alten Klassennamen ablösen (werden). Wenn du noch auf 4.5 entwickelst, hat dich das wohl bis anhin auch noch nicht kümmern müssen ;) Ausschnitt aus dem Mittwaldblog: ([url=http://blog.mittwald.de/allgemein/typo3-6-0-back-to-the-future/]Link[/url])

    Namespaces

    Der komplette TYPO3-Core wurde auf PHP 5.3 Namespaces umgestellt; es gibt also keine Klassennamen mehr. Dabei mussten circa 1.800 Klassennamen verändert werden. Jede Klasse hat einen neuen Namen und einen anderen Platz innerhalb des Dateisystems erhalten. Es wurde darauf geachtet, dass es eine Rückwärtskompatibilitäts-Schicht für die alten Klassen gibt. Alle Extensions sollten problemlos auch ohne Modifikation weiterhin funktionieren.

    Beispiel für eine neue Klasse von CssStyledContent:

    \TYPO3\CMS\CssStyledContent\Controller (vorher: typo3/sysext/css_styled_content/Classes/Controller)

    Die Einführung von Namespaces war eine große und aufwändige Änderung für den gesamten TYPO3-Core.

  • einpraegsam.net einpraegs...
    MacGyver
    0 x
    9340 Beiträge
    80 Hilfreiche Beiträge
    01. 07. 2013, 10:58

    Trotz der wirklich guten und ausführlichen Beschreibung von kjuuze, bekomme ich das unter TYPO3 6.1.1 nicht zum Laufen - wäre daher für jeden Tipp dankbar.

    Habe eine einfache Extension erstellt - mit einem simplen Model mit einem Titel Feld:

    1. namespace TYPO3\Test\Domain\Model;
    2.  
    3. class Address extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
    4.  
    5. /**
    6. * title
    7. *
    8. * @var \string
    9. */
    10. protected $title;
    11.  
    12. /**
    13. * Returns the title
    14. *
    15. * @return \string $title
    16. */
    17. public function getTitle() {
    18. return $this->title;
    19. }
    20.  
    21. /**
    22. * Sets the title
    23. *
    24. * @param \string $title
    25. * @return void
    26. */
    27. public function setTitle($title) {
    28. $this->title = $title;
    29. }
    30.  
    31. }

    [b]Aufgabe[/b] - Weitere Extension erstellen, die das vorhandene Model um ein weiteres Feld (in meinem Fall subtitle) erweitert.

    [b]Model 2[/b]

    1. namespace TYPO3\Test2\Domain\Model;
    2.  
    3. class Address2 extends \TYPO3\Test\Domain\Model\Address {
    4.  
    5. /**
    6. * subtitle
    7. *
    8. * @var \string
    9. */
    10. protected $subtitle;
    11.  
    12. /**
    13. * Returns the subtitle
    14. *
    15. * @return \string $subtitle
    16. */
    17. public function getSubtitle() {
    18. return $this->subtitle;
    19. }
    20.  
    21. /**
    22. * Sets the subtitle
    23. *
    24. * @param \string $subtitle
    25. * @return void
    26. */
    27. public function setSubtitle($subtitle) {
    28. $this->subtitle = $subtitle;
    29. }
    30.  
    31. }

    [b]Versucht in der ext_typoscript_setup.txt der zweiten Extension bzw. direkt im Backend:[/b]

    1. config.tx_extbase{
    2. persistence{
    3. classes{
    4.  
    5. TYPO3\Test\Domain\Model\Address {
    6. subclasses {
    7. Tx_Test2_Address2 = TYPO3\Test2\Domain\Model\Address2
    8. }
    9. }
    10. TYPO3\Test2\Domain\Model\Address2 {
    11. mapping {
    12. tableName = tx_test_domain_model_address
    13. recordType = Tx_Test2_Address2
    14. }
    15. }
    16. }
    17. }
    18. }

    ext_tables.php und ext_tables.sql in Extension 2 habe ich auch eingebaut - das neue Feld steht im Backend zur Verfügung - dort lassen sich auch Werte speichern.

    1. $tmp_test2_columns = array(
    2.  
    3. 'subtitle' => array(
    4. 'exclude' => 0,
    5. 'label' => 'LLL:EXT:test2/Resources/Private/Language/locallang_db.xlf:tx_test2_domain_model_address2.subtitle',
    6. 'config' => array(
    7. 'type' => 'input',
    8. 'size' => 30,
    9. 'eval' => 'trim'
    10. ),
    11. ),
    12. );
    13.  
    14. t3lib_extMgm::addTCAcolumns('tx_test_domain_model_address',$tmp_test2_columns);
    15.  
    16.  
    17. \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA('tx_test_domain_model_address');
    18. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_test_domain_model_address', $tmp_test2_columns, 1);
    19. \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tx_test_domain_model_address', 'subtitle');

    Wo liegt der Denkfehler?

    in2code.de - Wir leben TYPO3
    - Möchtest du TYPO3 komplett verstehen? Eigene Erweiterungen erstellen? Bei uns gibt es auch Schulungen https://www.in2code.de/produkte/typo3-schulungen/
    - Die Arbeit mit TYPO3 macht dir Spaß? Du stehst auf Berge? Komm zu uns! https://www.in2code.de/agentur/karriere/