<p>I've had this issue previously before when working on a larger website, when you want to copy an entry type and all its field layouts, or even copy a section all its entry types and all their field layouts.</p>

<p>I've written a plugin that tackles this, check it out here:</p>

<p><a href="https://github.com/kymar/craft_cloner" rel="nofollow noreferrer">Craft Cloner</a></p>

CC BY-SA 3.0
2017-03-21T09:06:50.387Z
2017-03-21T09:06:50.387Z
Kyle Marshall
<p>After hours I managed to fix it. I'm assuming I made an error where I was trying to copy the Fields in the Entry Type I literally just created. So it was copying over 0 fields.</p>

<p>I built the functions from scratch again and finally found the working code. For future reference or to help others, here is the snippet in question.</p>

<pre><code>private function CopyEntryTypes($savedSection, $baseSection)
{
    $baseSectionEntryTypes = $baseSection-&gt;getEntryTypes();

    foreach ($baseSectionEntryTypes as $baseSectionEntryType) {
        $newEntryType = $this-&gt;createNewEntryType($baseSectionEntryType, $savedSection-&gt;id);
        //oke so the New Entry Type is saved, we should get a return statement from the function
        //now loop through the tabs/fields of the baseSection Entry Type.


        $currentLayout = $baseSectionEntryType-&gt;getFieldLayout();
        $currentTabs = $currentLayout-&gt;getTabs();

        // This will the array passed to assembleLayout
        $postedFieldLayout = array();

        // Loop through each tab and build our array
        foreach ($currentTabs as $tab) {
            $fields = $tab-&gt;getFields();
            foreach ($fields as $field) {
                $postedFieldLayout[$tab-&gt;name][] = $field-&gt;fieldId;
            }
        }

        //so now we have a collection of entry types, each of them have a tab-name which we can use to identify
        //the goal is to get 'all' the tabs into the new entry type.
        $requiredFields = array();

        // Assemble the layout
        $fieldLayout = craft()-&gt;fields-&gt;assembleLayout($postedFieldLayout, $requiredFields);
        $fieldLayout-&gt;type = ElementType::Entry;
        $newEntryType-&gt;setFieldLayout($fieldLayout);

        // Save it
        if (craft()-&gt;sections-&gt;saveEntryType($newEntryType))
        {
            Craft::log('Successfully appended fields.');
        }
        else
        {
            Craft::log('Could not append the fields.', LogLevel::Warning);
        }
    }
}

private function createNewEntryType($baseSectionEntryType, $savedSectionId)
{
    $newEntryType = new EntryTypeModel();
    $baseSectionEntryType-&gt;id = null;
    $baseSectionEntryType-&gt;sectionId = $savedSectionId;
    $values = $baseSectionEntryType-&gt;attributes;
    $newEntryType-&gt;setAttributes($values);

    if (craft()-&gt;sections-&gt;saveEntryType($newEntryType))
    {
        var_dump('Successfully saved Entry Type.');
    }
    else
    {
        var_dump('Could not save the Entry Type.');
    }

    return $newEntryType;
}
</code></pre>

<p>I'm also using code that I modified from: <a href="https://craftcms.stackexchange.com/questions/11644/how-can-i-programmatically-add-a-tab-to-entry-type">How can I programmatically add a tab to entry type?</a> so this guy deserves the credit.</p>

CC BY-SA 3.0
2017-02-17T10:17:34.183Z
2017-02-17T10:17:34.183Z
2017-04-13T12:51:00.200Z
Thomas Claessens
<p>For a current project, I am attempting to automate the creation of a section.</p>

<p>I am using a default_section as the base of all the others. This section will contain a couple of entries, and a couple of entry types.</p>

<p>My goal right now is to copy over the Entry Types in its totality. Right now, I'm struggling with the field layout that I have set for the Entry Type</p>

<p>Let's say that the first Entry Type has the following field layout:
<a href="https://i.sstatic.net/IPxX8.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/IPxX8.png" alt="image of the layout i&#39;m trying to replicate"></a></p>

<p>And this is the code that I am using</p>

<pre><code>private function copyEntryTypes($savedSection, $entryTypes)
{
    foreach ($entryTypes as $entryType) {
        $copiedEntryType = $entryType;

        $newEntryType = new EntryTypeModel();
        $copiedEntryType-&gt;id = null;
        $copiedEntryType-&gt;sectionId = $savedSection-&gt;id;
        $values = $copiedEntryType-&gt;attributes;
        $newEntryType-&gt;setAttributes($values);

        $currentLayout = $copiedEntryType-&gt;getFieldLayout();
        $currentTabs = $currentLayout-&gt;getTabs();
        $postedFieldLayout = array();

        foreach ($currentTabs as $tab) {
            $fields = $tab-&gt;getFields();

            foreach ($fields as $field) {
                echo '&lt;pre&gt;' . var_export($field-&gt;attributes) . '&lt;/pre&gt;';
                $postedFieldLayout[$tab-&gt;name][] = $field-&gt;fieldId;
            }
        }

        $requiredFields = array();

        $fieldLayout = craft()-&gt;fields-&gt;assembleLayout($postedFieldLayout, $requiredFields);
        $fieldLayout-&gt;type = ElementType::Entry;
        $newEntryType-&gt;setFieldLayout($fieldLayout);

        //TODO: New Entry Types are succesfully being copied. Now all I need is to move over the fieldset

        if (craft()-&gt;sections-&gt;saveEntryType($entryType))
        {
            var_dump('Successfully appended fields.');
        }
        else
        {
            var_dump('Could not append the fields.');
        }
    }

    return true;
}
</code></pre>

<p>//note: this code is WIP, so it's not super clean, sorry.</p>

<p>The result is that the fields are being looped through correctly, I can var_dump them and find the correct ID's. The problem is that the resulting EntryType I have made does not contain the layout I am trying to copy over. </p>

<p>That's looking like this: 
<a href="https://i.sstatic.net/A9Mxa.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/A9Mxa.png" alt="enter image description here"></a></p>

<plugin-development><entry-type><layout>
Copy the Entry Type along with its field layout
# Copy the Entry Type along with its field layout

(Asked by: username_0 on 2017-02-16)

For a current project, I am attempting to automate the creation of a section.
I am using a default_section as the base of all the others. This section will contain a couple of entries, and a couple of entry types.
My goal right now is to copy over the Entry Types in its totality. Right now, I'm struggling with the field layout that I have set for the Entry Type
Let's say that the first Entry Type has the following field layout:

And this is the code that I am using
private function copyEntryTypes($savedSection, $entryTypes)
{
    foreach ($entryTypes as $entryType) {
        $copiedEntryType = $entryType;

        $newEntryType = new EntryTypeModel();
        $copiedEntryType->id = null;
        $copiedEntryType->sectionId = $savedSection->id;
        $values = $copiedEntryType->attributes;
        $newEntryType->setAttributes($values);

        $currentLayout = $copiedEntryType->getFieldLayout();
        $currentTabs = $currentLayout->getTabs();
        $postedFieldLayout = array();

        foreach ($currentTabs as $tab) {
            $fields = $tab->getFields();

            foreach ($fields as $field) {
                echo '' . var_export($field->attributes) . '';
                $postedFieldLayout[$tab->name][] = $field->fieldId;
            }
        }

        $requiredFields = array();

        $fieldLayout = craft()->fields->assembleLayout($postedFieldLayout, $requiredFields);
        $fieldLayout->type = ElementType::Entry;
        $newEntryType->setFieldLayout($fieldLayout);

        //TODO: New Entry Types are succesfully being copied. Now all I need is to move over the fieldset

        if (craft()->sections->saveEntryType($entryType))
        {
            var_dump('Successfully appended fields.');
        }
        else
        {
            var_dump('Could not append the fields.');
        }
    }

    return true;
}

//note: this code is WIP, so it's not super clean, sorry.
The result is that the fields are being looped through correctly, I can var_dump them and find the correct ID's. The problem is that the resulting EntryType I have made does not contain the layout I am trying to copy over. 
That's looking like this:

**Tags:** plugin-development, entry-type, layout


---

## 2 answers

### Answer by username_1 on 2017-03-21. Score: 1

I've had this issue previously before when working on a larger website, when you want to copy an entry type and all its field layouts, or even copy a section all its entry types and all their field layouts.

I've written a plugin that tackles this, check it out here:

[Craft Cloner](https://github.com/kymar/craft_cloner)


---

### Answer by username_0 on 2017-02-17. Score: 1

After hours I managed to fix it. I'm assuming I made an error where I was trying to copy the Fields in the Entry Type I literally just created. So it was copying over 0 fields.
I built the functions from scratch again and finally found the working code. For future reference or to help others, here is the snippet in question.
private function CopyEntryTypes($savedSection, $baseSection)
{
    $baseSectionEntryTypes = $baseSection->getEntryTypes();

    foreach ($baseSectionEntryTypes as $baseSectionEntryType) {
        $newEntryType = $this->createNewEntryType($baseSectionEntryType, $savedSection->id);
        //oke so the New Entry Type is saved, we should get a return statement from the function
        //now loop through the tabs/fields of the baseSection Entry Type.


        $currentLayout = $baseSectionEntryType->getFieldLayout();
        $currentTabs = $currentLayout->getTabs();

        // This will the array passed to assembleLayout
        $postedFieldLayout = array();

        // Loop through each tab and build our array
        foreach ($currentTabs as $tab) {
            $fields = $tab->getFields();
            foreach ($fields as $field) {
                $postedFieldLayout[$tab->name][] = $field->fieldId;
            }
        }

        //so now we have a collection of entry types, each of them have a tab-name which we can use to identify
        //the goal is to get 'all' the tabs into the new entry type.
        $requiredFields = array();

        // Assemble the layout
        $fieldLayout = craft()->fields->assembleLayout($postedFieldLayout, $requiredFields);
        $fieldLayout->type = ElementType::Entry;
        $newEntryType->setFieldLayout($fieldLayout);

        // Save it
        if (craft()->sections->saveEntryType($newEntryType))
        {
            Craft::log('Successfully appended fields.');
        }
        else
        {
            Craft::log('Could not append the fields.', LogLevel::Warning);
        }
    }
}

private function createNewEntryType($baseSectionEntryType, $savedSectionId)
{
    $newEntryType = new EntryTypeModel();
    $baseSectionEntryType->id = null;
    $baseSectionEntryType->sectionId = $savedSectionId;
    $values = $baseSectionEntryType->attributes;
    $newEntryType->setAttributes($values);

    if (craft()->sections->saveEntryType($newEntryType))
    {
        var_dump('Successfully saved Entry Type.');
    }
    else
    {
        var_dump('Could not save the Entry Type.');
    }

    return $newEntryType;
}

I'm also using code that I modified from: How can I programmatically add a tab to entry type? so this guy deserves the credit.


---

