<p>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.</p>



<pre class="lang-php prettyprint-override"><code>$newBlocks = array();

foreach ($gbr-&gt;$fieldHandle-&gt;find() as $gbrBlock)
{
    $newBlock = new MatrixBlockModel();
    $newBlock-&gt;fieldId = $field-&gt;id;
    $newBlock-&gt;typeId  = $gbrBlock-&gt;getType()-&gt;id;
    $newBlock-&gt;ownerId = $element-&gt;id;
    $newBlock-&gt;locale  = $newLocale;

    $newBlockContent = $newBlock-&gt;getContent();

    foreach ($gbrBlock-&gt;getFieldLayout()-&gt;getFields() as $gbrBlockFieldLayoutField)
    {
        // same field value duplication logic...
    }

    $newBlocks[] = $newBlock;
}

$content-&gt;$fieldHandle = $newBlocks;
</code></pre>

<p>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.)</p>

CC BY-SA 3.0
2015-10-06T20:08:58.773Z
2015-10-06T20:08:58.773Z
Brandon Kelly
<p>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.</p>

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

<p>So far I've got:</p>



<pre class="lang-php prettyprint-override"><code>foreach ($criteria-&gt;find() as $element)
{
    $locale  = $criteria-&gt;locale;
    $content = $element-&gt;getContent();
    $gbr     = craft()-&gt;entries-&gt;getEntryById($element-&gt;id, 'en_gb');

    foreach ($element-&gt;getFieldLayout()-&gt;getFields() as $fieldLayoutField)
    {
        $field       = $fieldLayoutField-&gt;getField();
        $fieldHandle = $field-&gt;handle;

        if (in_array((string) $field-&gt;type, array('Assets', 'Entries', 'Categories', 'Tags')))
        {
            // only copy the relation's IDs if there's nothing there already
            if ($element-&gt;$fieldHandle-&gt;total() == 0)
            {
                $content-&gt;$fieldHandle = $gbr-&gt;$fieldHandle-&gt;ids();
            }
        }
        elseif ((string) $field-&gt;type == 'Matrix')
        {
            if ($element-&gt;$fieldHandle-&gt;total() == 0)
            {
                foreach($gbr-&gt;$fieldHandle-&gt;find() as $gbrBlock)
                {
                    // not sure what to do here to duplicate $gbrBlock,
                    // and save it to $locale with the same contents.
                }
            }
        }
    }
}

$element-&gt;setContent($content);
</code></pre>

<p>I've tried using <code>craft()-&gt;matrix-&gt;getBlockById($gbrBlock-&gt;id, $locale)</code> 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?</p>

<plugin-development><matrix><localization>
Duplicating Matrix fields with content from another locale
# Duplicating Matrix fields with content from another locale

(Asked by: username_0 on 2015-03-05)

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?

**Tags:** plugin-development, matrix, localization


---

## 1 answers

### Answer by username_1 on 2015-10-06. Score: 4 | Accepted answer

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.)


---

