我有一个1:n的关系:
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;
}
}
通常,当从数据库中读取子对象时(例如,通过findByUid
),它们已经引用了父对象。
但是如果我创建一个新的子对象并立即保留它 - 从数据库和父引用中获取uid
- 不是。
这是上面描述的父类中的函数:
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;
}
我也试过
$child = $objectManager->get(\...\ChildRepository::class)->findByUid($child->getUid());
调用persistAll()
后- 没有效果。看起来这个对象是由ExtBase缓冲的,而不是再次读取。
修改
这是儿童模特:
<?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
}
}
这是父模型:
<?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;
}
}
这是父控制:
<?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');
}
}
这是孩子的TCA:
<?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',
),
),
),
);
这是父母的TCA:
<?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
),
),
),
),
);
答案 0 :(得分:0)
注意TCA表配置。 这应该工作。
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;
}
}