So currently i'm working on a TYPO3 extension using a Relation (1:n) to a specific class that provides objects to the main class. Let me explain a bit more in detail: I have a class, that next to normal properties, has a relation to a class that provides objects for some kind of checklist. The idea is that the FE user should be able to add new checklist entries, that's why i use that kind of concept. Initially it would look like this for the edit Action (the [x] represent that it's just a checklist):
- main class
- property of main class of type boolean [x]
- attached object with a string and a boolean property [x]
- attached object with a string and a boolean property [x]
- property of main class of type text (for comments)
The FE user should be able to edit the record, so he should set the checklist entires to true or false, but even though the checklist entries appear, even those of the attached objects, they aren't persisted, only the properties of the main class are persisted when the FE user edits the records in the FE.
Here is my code:
The domain model of the main class (just the lines that specify the relation to the class that "provides" the objects). Keep in mind that few objects of the related class are attached to the main class when a record of the main class is created, the specific code just isn't in the main classe's controller...
/**
* zugewCheckobject
*
* @var TYPO3CMSExtbasePersistenceObjectStorage<...KundentermineDomainModelCheckobject>
* @cascade remove
*/
protected $zugewCheckobject = null;
public function __construct()
{
$this->zugewCheckobject = new TYPO3CMSExtbasePersistenceObjectStorage();
}
/**
* Initializes all ObjectStorage properties
* Do not modify this method!
* It will be rewritten on each save in the extension builder
* You may modify the constructor of this class instead
*
* @return void
*/
protected function initStorageObjects()
{
$this->zugewCheckobject = new TYPO3CMSExtbasePersistenceObjectStorage();
}
/**
* Adds a Checkobject
*
* @param ...KundentermineDomainModelCheckobject $zugewCheckobject
* @return void
*/
public function addZugewCheckobject(...KundentermineDomainModelCheckobject $zugewCheckobject)
{
$this->zugewCheckobject->attach($zugewCheckobject);
}
/**
* Removes a Checkobject
*
* @param ...KundentermineDomainModelCheckobject $zugewCheckobjectToRemove The Checkobject to be removed
* @return void
*/
public function removeZugewCheckobject(...KundentermineDomainModelCheckobject $zugewCheckobjectToRemove)
{
$this->zugewCheckobject->detach($zugewCheckobjectToRemove);
}
/**
* Returns the zugewCheckobject
*
* @return TYPO3CMSExtbasePersistenceObjectStorage<...KundentermineDomainModelCheckobject> $zugewCheckobject
*/
public function getZugewCheckobject()
{
return $this->zugewCheckobject;
}
/**
* Sets the zugewCheckobject
*
* @param TYPO3CMSExtbasePersistenceObjectStorage<UnilabKundentermineDomainModelCheckobject> $zugewCheckobject
* @return void
*/
public function setZugewCheckobject(TYPO3CMSExtbasePersistenceObjectStorage $zugewCheckobject)
{
$this->zugewCheckobject = $zugewCheckobject;
}
The edit and update Actions in the controller of the main class...
public function editAction(...KundentermineDomainModelKaufmnnisch $kaufmnnisch)
{
$this->view->assign('kaufmnnisch', $kaufmnnisch);
}
/**
* action update
*
* @param ...KundentermineDomainModelKaufmnnisch $kaufmnnisch
* @return void
*/
public function updateAction(...KundentermineDomainModelKaufmnnisch $kaufmnnisch)
{
$objectManager = TYPO3CMSCoreUtilityGeneralUtility::makeInstance('TYPO3CMSExtbaseObjectObjectManager');
$checkobjectRepository = $objectManager->get(...KundentermineDomainRepositoryCheckobjectRepository::class);
foreach($kaufmnnisch->getZugewCheckobject() as $chk){
$checkobjectRepository->update($chk);
}
$this->kaufmnnischRepository->update($kaufmnnisch);
$this->redirect('list');
}
Part of the "edit" template. I pass the object "kaufmnnisch" as arguments to a partial of the class Chekobject (as it has objects of that class attached to it) and of course to a partial of the class Kaufmnnisch...
<f:section name="main">
<h1>Edit Kaufmnnisch</h1>
<f:flashMessages />
<f:render partial="FormErrors" arguments="{object:Kaufmnnisch}" />
<f:form action="update" name="kaufmnnisch" object="{kaufmnnisch}" >
<f:render partial="Checkobject/FormFields" arguments="{kaufmnnisch:kaufmnnisch}" />
<f:render partial="Kaufmnnisch/FormFields" arguments="{kaufmnnisch:kaufmnnisch}" />
<f:form.submit value="Save" />
</f:form>
</f:section>
Again: The problem is that only the properties of the main class get edited not those of the related objects. My assumption is that the Edit template or the partials aren't correctly set.
Edit: Here is the code for the partial of the Checkobject class that gets the object Kaufmnnisch as an argument passed.
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:for each="{kaufmnnisch.zugewcheckobject}" as="chk" >
<f:form.checkbox property="checked" value="0" /><br />
</f:for>
</html>
So basically "zugewcheckobject" is my object storage. Each checkbox gets rendered in the Edit template (thanks to the for each viewhelper), but the values for the boolean properties of each Checkobject object aren't persisted if the user clicks on the "save" button.
Edit2: A var_dump within the updateAction (within the foreach loop) reveals that the "Checked" property of each Checkobject object isn't changed, so it's not only not persisted, but the changed values aren't passed from the Edit template to the updateAction.
Edit3: Acessing every Checkobject object (here: $chk) via the objectstorage "zugewcheckobject" of the passed object of the class "Kaufmnnisch" in the Edit template is possible though, i just cant change the specific properties of the Checkobject objects, because JUST the Kaufmnnisch object is passed back to the updateAction of the specific controller, not each Checkobject of the objectstorage ("zugewcheckobject").
As i understand an objectstorage just contains references to its corresponding objects, not the objects themselfs, negating any changes that were made to them in the view.
In short: How can i also pass the corresponding objectstorage objects to the updateAction in one go for them to be persisted?
Edit4: It also doesn't seem to work with that solution...
<f:form action="update" name="kaufmnnisch" object="{kaufmnnisch}" >
<f:for each="{kaufmnnisch.zugewCheckobject}" as="chk" key="chkIndex" >
<f:form.hidden property="zugewCheckobject.{chkIndex}.__identity" value="{chk.uid}" />
<f:form.checkbox property="zugewCheckobject.{chkIndex}.checked" value="{chk.checked}" /><br />
</f:for>
<f:render partial="Kaufmnnisch/FormFields" arguments="{kaufmnnisch:kaufmnnisch}" />
<f:form.submit value="Save" />
</f:form>
The problem was solved here: TYPO3 extension thought experiment: Editing a news entry and the comment entries in one go?
See Question&Answers more detail:
os