3

i wanna ad a relation from one model to a nother.

enter image description here

/**
 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
 * @inject
 */
protected $objectManager;



/**
 * action create
 *
 * @param \ReRe\Rere\Domain\Model\Modul $newModul
 * @return void
 */
public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul) {
    $this->addFlashMessage('The object was created. Please be aware that this action is publicly accessible unless you implement an access check. See <a href="http://wiki.typo3.org/T3Doc/Extension_Builder/Using_the_Extension_Builder#1._Model_the_domain" target="_blank">Wiki</a>', '', \TYPO3\CMS\Core\Messaging\AbstractMessage::ERROR);
    $this->modulRepository->add($newModul);
    // Erzeugt ein Leeres Fach
    $fachHelper = new \ReRe\Rere\Domain\Model\Fach();


    $fach = $this->objectManager->create('\ReRe\Rere\Domain\Model\Fach');


    // Fach Werte setzen
    $fach->setFachname($this->request->getArgument('fachname'));
    $fach->setFachnr($this->request->getArgument('fachnummer'));
    $fach->setPruefer($this->request->getArgument('pruefer'));
    $fach->setNotenschema($this->request->getArgument('notenschema'));
    // Fach einem Modul zuordnen

    $fach->setModulnr($newModul->getModulnr());
    //$request = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance("\ReRe\Rere\Domain\Model\Fach");
    //\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($newModul);
    // Fach speichern
    $this->fachRepository->add($fach);

    $newModul->addFach($fach);
    $this->redirect('list');
}

in database in modul the relationcounter will increased ...

DB looks like this: enter image description here enter image description here

but if I want to render the view like this:

<f:for each="{moduls}" as="modul">

{modul.modulname}

<f:for each="{modul.fach}" as="fach">
{fach.fachname} 

no fach objects were printed ..

if I do <f:debug> of modul i got this:

Here The TCA-Configs:

Modul:

if (!defined('TYPO3_MODE')) {
   die('Access denied.');
}

$GLOBALS['TCA']['tx_rere_domain_model_modul'] = array(
   'ctrl' => $GLOBALS['TCA']['tx_rere_domain_model_modul']['ctrl'],
   'interface' => array(
       'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, modulnr, modulname, gueltigkeitszeitraum, fach',
),
'types' => array(
    '1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource,    hidden;;1, modulnr, modulname, gueltigkeitszeitraum, fach, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'),
),
'palettes' => array(
    '1' => array('showitem' => ''),
),
'columns' => array(
    'sys_language_uid' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
        'config' => array(
            'type' => 'select',
            'foreign_table' => 'sys_language',
            'foreign_table_where' => 'ORDER BY sys_language.title',
            'items' => array(
                array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
                array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
            ),
        ),
    ),
    'l10n_parent' => array(
        'displayCond' => 'FIELD:sys_language_uid:>:0',
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
        'config' => array(
            'type' => 'select',
            'items' => array(
                array('', 0),
            ),
            'foreign_table' => 'tx_rere_domain_model_modul',
            'foreign_table_where' => 'AND tx_rere_domain_model_modul.pid=###CURRENT_PID### AND tx_rere_domain_model_modul.sys_language_uid IN (-1,0)',
        ),
    ),
    'l10n_diffsource' => array(
        'config' => array(
            'type' => 'passthrough',
        ),
    ),
    't3ver_label' => array(
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'max' => 255,
        )
    ),
    'hidden' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
        'config' => array(
            'type' => 'check',
        ),
    ),
    'starttime' => array(
        'exclude' => 1,
        'l10n_mode' => 'mergeIfNotBlank',
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
        'config' => array(
            'type' => 'input',
            'size' => 13,
            'max' => 20,
            'eval' => 'datetime',
            'checkbox' => 0,
            'default' => 0,
            'range' => array(
                'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
            ),
        ),
    ),
    'endtime' => array(
        'exclude' => 1,
        'l10n_mode' => 'mergeIfNotBlank',
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
        'config' => array(
            'type' => 'input',
            'size' => 13,
            'max' => 20,
            'eval' => 'datetime',
            'checkbox' => 0,
            'default' => 0,
            'range' => array(
                'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
            ),
        ),
    ),
    'modulnr' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.modulnr',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim'
        ),
    ),
    'modulname' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.modulname',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim,required'
        ),
    ),
    'gueltigkeitszeitraum' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.gueltigkeitszeitraum',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim'
        ),
    ),
    'fach' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_modul.fach',
        'config' => array(
            'type' => 'inline',
            'foreign_table' => 'tx_rere_domain_model_fach',
            'foreign_field' => 'modulnr',
            'maxitems' => 9999,
            'appearance' => array(
                'collapseAll' => 0,
                'levelLinksPosition' => 'top',
                'showSynchronizationLink' => 1,
                'showPossibleLocalizationRecords' => 1,
                'showAllLocalizationLink' => 1
            ),
        ),
    ),
),
);

And TCA Fach

<?php
if (!defined ('TYPO3_MODE')) {
    die ('Access denied.');
}

$GLOBALS['TCA']['tx_rere_domain_model_fach'] = array(
'ctrl' => $GLOBALS['TCA']['tx_rere_domain_model_fach']['ctrl'],
'interface' => array(
    'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, fachnr, fachname, pruefer, notenschema, modulnr, matrikelnr',
),
'types' => array(
    '1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, fachnr, fachname, pruefer, notenschema, modulnr, matrikelnr, --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access, starttime, endtime'),
),
'palettes' => array(
    '1' => array('showitem' => ''),
),
'columns' => array(

    'sys_language_uid' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
        'config' => array(
            'type' => 'select',
            'foreign_table' => 'sys_language',
            'foreign_table_where' => 'ORDER BY sys_language.title',
            'items' => array(
                array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
                array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
            ),
        ),
    ),
    'l10n_parent' => array(
        'displayCond' => 'FIELD:sys_language_uid:>:0',
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
        'config' => array(
            'type' => 'select',
            'items' => array(
                array('', 0),
            ),
            'foreign_table' => 'tx_rere_domain_model_fach',
            'foreign_table_where' => 'AND tx_rere_domain_model_fach.pid=###CURRENT_PID### AND tx_rere_domain_model_fach.sys_language_uid IN (-1,0)',
        ),
    ),
    'l10n_diffsource' => array(
        'config' => array(
            'type' => 'passthrough',
        ),
    ),

    't3ver_label' => array(
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'max' => 255,
        )
    ),

    'hidden' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.hidden',
        'config' => array(
            'type' => 'check',
        ),
    ),
    'starttime' => array(
        'exclude' => 1,
        'l10n_mode' => 'mergeIfNotBlank',
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.starttime',
        'config' => array(
            'type' => 'input',
            'size' => 13,
            'max' => 20,
            'eval' => 'datetime',
            'checkbox' => 0,
            'default' => 0,
            'range' => array(
                'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
            ),
        ),
    ),
    'endtime' => array(
        'exclude' => 1,
        'l10n_mode' => 'mergeIfNotBlank',
        'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.endtime',
        'config' => array(
            'type' => 'input',
            'size' => 13,
            'max' => 20,
            'eval' => 'datetime',
            'checkbox' => 0,
            'default' => 0,
            'range' => array(
                'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
            ),
        ),
    ),

    'fachnr' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.fachnr',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim'
        ),
    ),
    'fachname' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.fachname',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim,required'
        ),
    ),
    'pruefer' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.pruefer',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim'
        ),
    ),
    'notenschema' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.notenschema',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim,required'
        ),
    ),
    'modulnr' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.modulnr',
        'config' => array(
            'type' => 'input',
            'size' => 30,
            'eval' => 'trim,required'
        ),
    ),
    'matrikelnr' => array(
        'exclude' => 1,
        'label' => 'LLL:EXT:rere/Resources/Private/Language/locallang_db.xlf:tx_rere_domain_model_fach.matrikelnr',
        'config' => array(
            'type' => 'select',
            'foreign_table' => 'tx_rere_domain_model_pruefling',
            'MM' => 'tx_rere_fach_pruefling_mm',
            'size' => 10,
            'autoSizeMax' => 30,
            'maxitems' => 9999,
            'multiple' => 0,
            'wizards' => array(
                '_PADDING' => 1,
                '_VERTICAL' => 1,
                'edit' => array(
                    'type' => 'popup',
                    'title' => 'Edit',
                    'script' => 'wizard_edit.php',
                    'icon' => 'edit2.gif',
                    'popup_onlyOpenIfSelected' => 1,
                    'JSopenParams' => 'height=350,width=580,status=0,menubar=0,scrollbars=1',
                    ),
                'add' => Array(
                    'type' => 'script',
                    'title' => 'Create new',
                    'icon' => 'add.gif',
                    'params' => array(
                        'table' => 'tx_rere_domain_model_pruefling',
                        'pid' => '###CURRENT_PID###',
                        'setValue' => 'prepend'
                        ),
                    'script' => 'wizard_add.php',
                ),
            ),
        ),
    ),

    'modul' => array(
        'config' => array(
            'type' => 'passthrough',
        ),
    ),
    'note' => array(
        'config' => array(
            'type' => 'passthrough',
        ),
    ),
),
);

enter image description here

Felix
  • 5,452
  • 12
  • 68
  • 163

2 Answers2

1

The model class looks ok and all annotations seem to be correct.

Could you please post your TCA configuration for both Modul and Fach (the relation entry for both should be enough).

Quick question, are you able to see the relations between the two objects in the backend and if so, can you see it from both sides? Go to the BE and check with the list tool if you can see related "Fach" objects in a "Modul" object and vise versa.

Maybe the TCA relation is no set up correctly and you can only access the relation from one side.

From which side have you created the relations (Modul->Fach or Fach->Modul)? Of course it should be working either way.

UPDATE 1

Does the column "modulnr" in your table "tx_rere_domain_model_fach" contain the correct Modul-UIDs?

-> To speed the process up, could you send me a download link to your extension? I would then install it on a test system and we will quickly find out what is wrong.

UPDATE 2

I found what is going wrong in your extension. After creating a new Modul and Fach the class \ReRe\Rere\Controller\ModulController handles the form data. In line 116

$fach->setModulnr($newModul->getModulnr());

the value for the reference, which should be the UID of the Modul is set to the Modulnr. As the reference to the foreign table is configured to be the UID, the UID of the Modul needs to be set here. Change the line to the following and it works:

$fach->setModulnr($newModul->getUid());

You will have to change this in every controller action that creates a new Fach-Modul relation. So this is only an example of what you need to do.

Sidenote

As an additional tip, you might want to take a look into the best practises on how to handle form data in Extbase.

Calls like this

$fach->setFachnr($this->request->getArgument('fachnummer'));

will work but open up a world of pain when it comes to injections, as there is no validation etc.

A very easy and quick way to set up basic validation and also make your code much more readable is to use annotations and parameters in your controller action. So instead of getting the arguments yourself, let the framework to the work for you:

/**
 * action create
 *
 * @param \ReRe\Rere\Domain\Model\Modul $newModul
 * @param string                        $fachname
 * @param int                           $fachnummer
 */
public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul, $fachname, $fachnummer) {
...

If you want to make a parameter optional, just give it a value in the method call:

public function createAction(\ReRe\Rere\Domain\Model\Modul $newModul, $fachname = "foo", $fachnummer="bar") {
...

As I said, this is just a tip, you might want to consider :)

lc_ik
  • 124
  • 5
  • Hi Thanks for your help. I've added the Domain/Modul.php and both TCA-Configs. the action create in my first Posting is in the ModulController.php The whole thing is a backend Modul. Where can I check the relations in Backend? – Felix Dec 27 '14 at 07:36
  • To check the relations you just need to log in to the backend, go to the "list" tool on the left side and select your storage sysfolder containing your entities from the page tree. If you are not sure where your entities are storged, just check your database table, the column "pid" gives you the UID of the storage folder. You can then just type the UID in the search field in the TYPO3 backend and you should find the folder containing your entities. To check the relations, just edit a Modul object and see if the Fach objects are there, same from the other side. – lc_ik Dec 27 '14 at 07:48
  • don't have a list modul (or do you mean the one under web) have you taken a look at the tca configs? – Felix Dec 27 '14 at 07:51
  • The list module should be the third module in the category "web". By default you have "Page, View, List, Functions...". I will have a look at the TCA right now – lc_ik Dec 27 '14 at 07:57
  • I think i don't save a uid, i save a whole object? .. heres the link, https://dl.dropboxusercontent.com/u/3756778/rere.zip pls tell me when you downloaded it – Felix Dec 27 '14 at 09:44
  • Thx, I downloaded it. Might take me till evening to check it out though. Will come back to you asp – lc_ik Dec 27 '14 at 14:05
  • I have to say thanks ... Then i will delete the download link. – Felix Dec 27 '14 at 14:07
  • Really Thanks for your answer, but if I try `$fach->setModulnr($newModul->getUid());` I got this error: `Argument 1 passed to ReRe\Rere\Domain\Model\Modul::setFach() must be an instance of TYPO3\CMS\Extbase\Persistence\ObjectStorage, instance of ReRe\Rere\Domain\Model\Fach given, called in C:\xampp\htdocs\typo3\typo3conf\ext\rere\Classes\Controller\ModulController.php ` Thanks for the hint with the anotations like it really – Felix Dec 27 '14 at 21:48
  • I can't reproduce the error in the test system. My test workflow is to create a new Modul and Fach via ModulController->new fill out the form fields and the creation is done in ModulController->create. While debugging the new Modul given in the create action you can see that the property Fach is already of type ObjectStorage. So there should be no need to "set" is again, you could just use the "add" method on the object storage to add a new relation. Are you using the same workflow? In which line is the error thrown? – lc_ik Dec 28 '14 at 09:06
  • Really Really mysterius ... It works ... It Works ... IT WORKS ... oh my godness! Really Really Really Really Thanks!!!! – Felix Dec 28 '14 at 09:13
  • Maybe it was just a caching problem then :) Well then keep up the good work and thanks for accepting this as answere – lc_ik Dec 28 '14 at 12:30
0

Please check if the ObjectStorage is related to the correct class in your model. Sometimes the extensionbuilder does set up the ObjectStorage but messes up the annotation.

Check if the annotation for "fach" in your ReRe\Rere\Domain\Model\Modul class contains the referenced class. It should look like this:

@var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ReRe\Rere\Domain\Model\Fach>

If assume your looks just like this, which is wrong and leads to an empty ObjectStorage in the FE: @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<>

See how the class the ObjectStorage contains is missing.

lc_ik
  • 124
  • 5
  • thanks for your answer. my model loocs like this: `/** * fach * * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\ReRe\Rere\Domain\Model\Fach> * @cascade remove */ protected $fach = NULL;` looks ok or? do you have some other ideas? why I have this problem? – Felix Dec 26 '14 at 20:20
  • Yes, that looks ok. Could you please post the entire class \ReRe\Rere\Domain\Model\Modul maybe there is something wrong with the initialization of the object storage or another annotation (the getter annotation for example) – lc_ik Dec 26 '14 at 22:22