Skip to content

Instantly share code, notes, and snippets.

@smichaelsen
Last active August 29, 2015 14:08
Show Gist options
  • Save smichaelsen/68ac037fa4300672d563 to your computer and use it in GitHub Desktop.
Save smichaelsen/68ac037fa4300672d563 to your computer and use it in GitHub Desktop.
Extbase: Modifying properties via request

Extbase: Modifying properties via request

An extbase problem and my solution

Problem

A client contacted me and told me that his extbase extension ceases to work when upgrading from TYPO3 4.5 to 6.2. AJAX requests that aimed to modify a certain model ended in exceptions.

The request looked similar to this:

$_POST = [
  'tx_myextension_myplugin' => [
  	'theModelToUpdate' => [
  		'__identity' => '678',
  		'someOtherProperty' => 'foo',
  	],
  ],
  __referrer => [...],
  __hmac => '...',
];

The Exception he got was:

1249479819: The object of type "Tx_MyExt_Domain_Model_MyModel" given to update must be persisted already, but is new.

Weird, because the object with this ID definetly existed. Looking around in the code with XDebug I stumbled over the following passage in \TYPO3\CMS\Extbase\Property\Mapper (around line 260):

    if (count($propertyValue) === 0) {
        $propertyValue = $existingObject;
    } elseif ($existingObject !== NULL) {
        $newObject = clone $existingObject;
        if ($this->map(array_keys($propertyValue), $propertyValue, $newObject)) {
            $propertyValue = $newObject;
        } else {
            $propertyValue = NULL;
        }
    }

Notice the clone in the 4th line of the snippet. As it clones the model to new object, it changes its spl_object_hash(), which results in the above exception because the persistence manager doesn't know that object with the new hash and can not update it.
Also notice that this clone only happens when there are property updates in the request ('someOtherProperty' => 'foo' in our case).

Solution

As I could not find a solution to this with the old property mapper, I enabled the new property mapper (losing backwards compatiblity to 4.5):

plugin.tx_myextension_myplugin {
  features.rewrittenPropertyMapper = 1
}

With the new property mapper you need to enable property updates on arguments explicitly (for security reasons it seems). You can do that in the initializeAction() of your controller:

/**
 *
 */
public function initializeAction() {
    if ($this->actionMethodName === 'ajaxUpdateAction') {
      $argumentMappingConfiguration = $this->arguments->getArgument('theModelToUpdate')->getPropertyMappingConfiguration();
      $argumentMappingConfiguration->allowProperties('someOtherProperty');
      $argumentMappingConfiguration->setTypeConverterOption('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, TRUE);
    }
}

Puh, quite lengthy and not easy to find out. At least it works now.

Alternative solution

Instead of modifying the model in the argument mapping process, the new property could have been submitted as a separate $_POST parameter and the value could have been assigned in the controller action manually.

/**
 * @param Tx_MyExt_Domain_Model_MyModel $theModelToUpdate 
 * @param string $someOtherProperty
 */
public function ajaxUpdateAction(Tx_MyExt_Domain_Model_MyModel $theModelToUpdate, $someOtherProperty) {
    $theModelToUpdate->setSomeOtherProperty($someOtherProperty);
    //...
}

That's how I usually do it when I build things from ground up. But as I did not have a full overview over this big extension I did not want to start changing fluid, javascript and controller code and went for a less invasive solution.

Upshot

I invested 1.5 hours into this. Maybe this document helps you to be quicker if you find yourself in the same situation.

However if you have a better understanding of Extbase than me and can tell me how this could have worked using the old property mapper or have another simpler solution or any remarks on my solution, I'd love to hear your feedback.

Sebastian Michaelsen [email protected], Oct 23rd 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment