3

I'm working on an Element Action that will duplicate some fields from the primary locale, to whatever locale the user is currently in, if those fields are already empty.

Asset fields seem to work fine, but I can't find a way to duplicate Matrix fields with all their content, including their own relation fields.

So far I've got:

foreach ($criteria->find() as $element) { $locale = $criteria->locale; $content = $element->getContent(); $gbr = craft()->entries->getEntryById($element->id, 'en_gb'); foreach ($element->getFieldLayout()->getFields() as $fieldLayoutField) { $field = $fieldLayoutField->getField(); $fieldHandle = $field->handle; if (in_array((string) $field->type, array('Assets', 'Entries', 'Categories', 'Tags'))) { // only copy the relation's IDs if there's nothing there already if ($element->$fieldHandle->total() == 0) { $content->$fieldHandle = $gbr->$fieldHandle->ids(); } } elseif ((string) $field->type == 'Matrix') { if ($element->$fieldHandle->total() == 0) { foreach($gbr->$fieldHandle->find() as $gbrBlock) { // not sure what to do here to duplicate $gbrBlock, // and save it to $locale with the same contents. } } } } } $element->setContent($content); 

I've tried using craft()->matrix->getBlockById($gbrBlock->id, $locale) like you do when duplicating whole entries (they're both elements right?) but that always comes back null, so... I need to create a new MatrixBlockModel in that locale?

1 Answer 1

4

For Matrix fields, you would basically need to duplicate all of this logic (or move it to a separate function), to recreate each Matrix block.

$newBlocks = array(); foreach ($gbr->$fieldHandle->find() as $gbrBlock) { $newBlock = new MatrixBlockModel(); $newBlock->fieldId = $field->id; $newBlock->typeId = $gbrBlock->getType()->id; $newBlock->ownerId = $element->id; $newBlock->locale = $newLocale; $newBlockContent = $newBlock->getContent(); foreach ($gbrBlock->getFieldLayout()->getFields() as $gbrBlockFieldLayoutField) { // same field value duplication logic... } $newBlocks[] = $newBlock; } $content->$fieldHandle = $newBlocks; 

Unfortunately there’s just no easy way to duplicate element content at the moment. Field types each store things differently, and the way they expect their values to be formatted when saving an element may be different from how they are formatted when fetching an existing element from the DB. (This is something we’ve made much easier in Craft 3 though.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.