2016-05-15 25 views
0

Ich habe eine 1: n Beziehung:extbase: Eltern-ID wird nicht aktualisiert, nachdem Objekt Kind Speichern

class Parent { 
    protected $title = ''; 

/** 
    * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\...\Child> 
    * @lazy 
    */ 
protected $allChildren = NULL; 

public function addChild(\...\Child $child) { 
    $this->allChildren->attach($child); 
} 

} 
class Child { 
    /** 
    * reference to the parent object 
    * @var Parent 
    */ 
    protected $parent = NULL; 

    public function getParent() { 
     if ($this->parent instanceof \TYPO3\CMS\Extbase\Persistence\LazyLoadingProxy) { 
     $this->parent->_loadRealInstance(); 
     } 
     return $this->parent; 
    } 
} 

Normalerweise, wenn Kinder Objekte aus der Datenbank (zB durch findByUid) gelesen werden, haben sie bereits verweisen auf das übergeordnete Objekt.

Aber wenn ich ein neues untergeordnetes Objekt erstellen und sofort beibehalten es - uid wird aus der Datenbank abgerufen und übergeordnete Referenz - nicht.
Hier ist die Funktion in der übergeordneten Klasse oben beschrieben vorgehen:

public function appendNewChild() { 
     $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); 
     $child = $objectManager->get(\...\Child::class); 
     $this->addChild($child); 
     $objectManager->get(\...\ParentRepository::class)->update($this); 
     $objectManager->get(\...\PersistenceManager::class)->persistAll(); 
     //at this point is child's 'uid' property updated. 'parent' - is not. 

     return $child; 
    } 

Ich habe auch versucht

$child = $objectManager->get(\...\ChildRepository::class)->findByUid($child->getUid()); 

nach persistAll() Aufruf - ohne Wirkung. Es sieht so aus, als ob dieses Objekt von ExtBase gepuffert und nicht erneut gelesen wird.


EDIT

Hier ist das Kind Modell:

<?php 
namespace MyVendor\MyExt\Domain\Model; 

class Child extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity { 

    /** 
    * ready 
    * 
    * @var boolean 
    */ 
    protected $ready = FALSE; 

    /** 
    * Object latest change timestamp 
    * 
    * @var int 
    */ 
    protected $tstamp = 0; 

    /** 
    * Parent object 
    * 
    * @var \MyVendor\MyExt\Domain\Model\Parent 
    */ 
    protected $parent = NULL; 

    /** 
    * Returns the ready 
    * 
    * @return boolean $ready 
    */ 
    public function getReady() { 
     return $this->ready; 
    } 

    /** 
    * Sets the ready 
    * 
    * @param boolean $ready 
    * @return void 
    */ 
    public function setReady($ready) { 
     $this->ready = $ready; 
    } 

    /** 
    * Returns object's latest change timestamp 
    * 
    * @return int 
    */ 
    public function getEvaluationDate() { 
     return $this->tstamp; 
    } 

    public function getParent() { 
     if ($this->parent instanceof \TYPO3\CMS\Extbase\Persistence\LazyLoadingProxy) { 
      $this->parent->_loadRealInstance(); 
     } 
     return $this->parent; 
    } 

    public function startEvaluation() { 
     //some stuff 
    } 

} 

Hier ist das Muttermodell:

<?php 
namespace MyVendor\MyExt\Domain\Model; 

class Parent extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity { 

    /** 
    * title 
    * 
    * @var string 
    * @validate NotEmpty 
    */ 
    protected $title = ''; 

    /** 
    * children 
    * 
    * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\MyVendor\MyExt\Domain\Model\Child> 
    * @cascade remove 
    * @lazy 
    */ 
    protected $children = NULL; 

    public function __construct() { 
     //Do not remove the next line: It would break the functionality 
     $this->initStorageObjects(); 
    } 

    protected function initStorageObjects() { 
     $this->children = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); 
    } 

    /** 
    * Returns the title 
    * 
    * @return string $title 
    */ 
    public function getTitle() { 
     return $this->title; 
    } 

    /** 
    * Sets the title 
    * 
    * @param string $title 
    * @return void 
    */ 
    public function setTitle($title) { 
     $this->title = $title; 
    } 

    /** 
    * Adds a Child 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Child $child 
    * @return void 
    */ 
    public function addChild(\MyVendor\MyExt\Domain\Model\Child $child) { 
     $this->children->attach($child); 
    } 

    /** 
    * 
    * @return \MyVendor\MyExt\Domain\Model\Child 
    */ 
    public function appendNewChild() { 
     $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); 
     $child = $objectManager->get(\MyVendor\MyExt\Domain\Model\Child::class); 
     $this->addChild($child); 
     $objectManager->get(\MyVendor\MyExt\Domain\Repository\ParentRepository::class)->update($this); 
     $objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class)->persistAll(); 

     //even here, after repeated reading, is parent property =null 
     $t = $objectManager->get(\MyVendor\MyExt\Domain\Repository\ChildRepository::class)->findByUid($child->getUid()); 

     //if I read another child object - it is fetched correctly, with 'parent' filled 
     $t = $objectManager->get(\MyVendor\MyExt\Domain\Repository\ChildRepository::class)->findByUid(42); 

     return $child; 
    } 

    /** 
    * Removes a Child 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Child $childToRemove 
    * @return void 
    */ 
    public function removeChild(\MyVendor\MyExt\Domain\Model\Child $childToRemove) { 
     $this->children->detach($childToRemove); 
    } 

    /** 
    * Returns the children 
    * 
    * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\MyVendor\MyExt\Domain\Model\Child> $children 
    */ 
    public function getChildren() { 
     return $this->children; 
    } 

    /** 
    * Sets the children 
    * 
    * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\MyVendor\MyExt\Domain\Model\Child> $children 
    * @return void 
    */ 
    public function setChildren(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $children) { 
     $this->children = $children; 
    } 
} 

Hier ist die Kontrolle parent:

<?php 
namespace MyVendor\MyExt\Controller; 

class ParentController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController { 

    /** 
    * parentRepository 
    * 
    * @var \MyVendor\MyExt\Domain\Repository\ParentRepository 
    * @inject 
    */ 
    protected $parentRepository = NULL; 

    /** 
    * action list 
    * 
    * @return void 
    */ 
    public function listAction() { 
     $parents = $this->parentRepository->findAll(); 
     $this->view->assign('parents', $parents); 
    } 

    /** 
    * action show 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $parent 
    * @return void 
    */ 
    public function showAction(\MyVendor\MyExt\Domain\Model\Parent $parent) { 
     $this->view->assign('showObject', $parent); 
    } 

    /** 
    * action new 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $newParent 
    * @ignorevalidation $newParent 
    * @return void 
    */ 
    public function newAction(\MyVendor\MyExt\Domain\Model\Parent $newParent = NULL) { 
     $this->view->assign('newParent', $newParent); 
    } 

    /** 
    * action create 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $newParent 
    * @return void 
    */ 
    public function createAction(\MyVendor\MyExt\Domain\Model\Parent $newParent) { 
     $this->parentRepository->add($newParent); 
     $this->redirect('list'); 
    } 

    /** 
    * action edit 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $parent 
    * @ignorevalidation $parent 
    * @return void 
    */ 
    public function editAction(\MyVendor\MyExt\Domain\Model\Parent $parent) { 
     $this->view->assign('parent', $parent); 
    } 

    /** 
    * action update 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $parent 
    * @return void 
    */ 
    public function updateAction(\MyVendor\MyExt\Domain\Model\Parent $parent) { 
     $this->parentRepository->update($parent); 
     $this->redirect('list'); 
    } 

    /** 
    * Confirmation prompt for delete action 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $deleteObject 
    * @return void 
    */ 
    public function deleteConfirmAction(\MyVendor\MyExt\Domain\Model\Parent $deleteObject) { 
     $this->view->assign ('deleteObject', $deleteObject); 
    } 

    /** 
    * Delete classifier 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $parent 
    * @return void 
    */ 
    public function deleteAction(\MyVendor\MyExt\Domain\Model\Parent $deleteObject) { 
     $this->parentRepository->remove($deleteObject); 
     $this->redirect('list'); 
    } 

    /** 
    * action evaluate 
    * 
    * @param \MyVendor\MyExt\Domain\Model\Parent $parent 
    * @return void 
    */ 
    public function evaluateAction(\MyVendor\MyExt\Domain\Model\Parent $parent) { 
     $parent->appendNewChild()->startEvaluation(); 
     $this->redirect('list'); 
    } 

} 

Hier ist TCA Kind:

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

$GLOBALS['TCA']['tx_myext_domain_model_child'] = array(
    'ctrl' => $GLOBALS['TCA']['tx_myext_domain_model_child']['ctrl'], 
    'interface' => array(
     'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, ready, tstamp', 
    ), 
    'types' => array(
     '1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, ready, '), 
    ), 
    '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_myext_domain_model_child', 
       'foreign_table_where' => 'AND tx_myext_domain_model_child.pid=###CURRENT_PID### AND tx_myext_domain_model_child.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, 
      ) 
     ), 

     'ready' => array(
      'exclude' => 0, 
      'label' => 'LLL:\...\<SomeReadyLabel>', 
      'config' => array(
       'type' => 'check', 
       'default' => 0 
      ) 
     ), 

     'parent' => array(
       'exclude' => 1, 
       'label' => 'LLL:\...\<SomeParentLabel>', 
       'config' => array(
         'type' => 'select', 
         'minitems' => 1, 
         'maxitems' => 1, 
         'foreign_table' => 'tx_myext_domain_model_parent', 
       ) 
     ), 

     'tstamp' => array(
       'exclude' => 1, 
       'label' => 'TimeStamp', 
       'config' => Array (
         'type' => 'none', 
         'format' => 'date', 
         'eval' => 'date', 
         ), 
     ), 

    ), 
); 

Hier ist TCA-Mutter:

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

$GLOBALS['TCA']['tx_myext_domain_model_parent'] = array(
    'ctrl' => $GLOBALS['TCA']['tx_myext_domain_model_parent']['ctrl'], 
    'interface' => array(
     'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, title, children', 
    ), 
    'types' => array(
     '1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, title, children, '), 
    ), 
    '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_myext_domain_model_parent', 
       'foreign_table_where' => 'AND tx_myext_domain_model_parent.pid=###CURRENT_PID### AND tx_myext_domain_model_parent.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, 
      ) 
     ), 

     'title' => array(
      'exclude' => 0, 
      'label' => 'LLL:EXT:myext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_parent.title', 
      'config' => array(
       'type' => 'input', 
       'size' => 30, 
       'eval' => 'trim,required' 
      ), 
     ), 
     'children' => array(
      'exclude' => 0, 
      'label' => 'LLL:\...\<SomeChildrenLabel>', 
      'config' => array(
       'type' => 'inline', 
       'foreign_table' => 'tx_myext_domain_model_child', 
       'foreign_field' => 'parent', 
       'maxitems'  => 9999, 
       'appearance' => array(
        'collapseAll' => 0, 
        'levelLinksPosition' => 'top', 
        'showSynchronizationLink' => 1, 
        'showPossibleLocalizationRecords' => 1, 
        'showAllLocalizationLink' => 1 
       ), 
      ), 

     ), 
    ), 
); 

Antwort

0

von TCA Tabellenkonfigurationen Achten Sie darauf. Dies sollte funktionieren.

class Parent { 

    /** 
    * @var string 
    */ 
    protected $title = ''; 

    /** 
    * Init object storage 
    */ 
    public function __construct() 
    { 
     $this->initStorageObjects(); 
    } 


/** 
    * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\...\Child> 
    * @lazy 
    */ 
    protected $allChildren = NULL; 

    /** 
    * Attach child 
    * 
    * @param \..\Child $child 
    * @return void 
    */ 
    public function addChild(\...\Child $child) { 
     $this->allChildren->attach($child); 
    } 

    /** 
    * returns allChildren 
    * 
    * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\..\Child> allChildren 
    */ 
    public function getAllChildren() { 
     return $this->allChildren; 
    } 

    /** 
    * sets allChildren 
    * 
    * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\..\Child> allChildren 
    * @return void 
    */ 
    public function setAllChildren(\TYPO3\CMS\Extbase\Persistence\ObjectStorage $allChildren) { 
     $this->allChildren = $allChildren 
    } 


    /** 
    * @return void 
    */ 
    protected function initStorageObjects() 
    { 
     $this->allChildren = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); 
    } 

    } 
    class Child { 
    /** 
     * reference to the parent object 
     * @var \..\Parent 
     */ 
     protected $parent = NULL; 

     /** 
     * returns parent 
     * @return \...\Parent 
     */ 
     public function getParent() { 
     return $this->parent; 
     } 
    } 
+0

OK. Ich habe die Funktionen, die Sie in der Klasse beachten. Leider ohne Änderungen. Welche TCA-Konfigurationen meinen Sie? Ich habe dem Beitrag TCA-Teile hinzugefügt. Warum haben Sie 'LazyLoadingProxy'-Überprüfung entfernt? – firelex

+0

Es kann Eltern mit Hilfe der TCA-Konfiguration erhalten. Kannst du die tca-Konfiguration für diese Tabellen posten? –

+0

Die Annotationen sind so wichtig, dass Sie bei jeder Änderung der Annotation den Cache vom Installationstool löschen müssen. Können Sie all dies posten: Controller, wo Sie diese Ergebnisse, Modell, Tca-Konfiguration und SQL-Tabellen zeigen müssen –