<p>Did you consider using Craft 3.1 new Project Config File feature?</p>

<p><a href="https://docs.craftcms.com/v3/project-config.html#enabling-the-project-config-file" rel="nofollow noreferrer">https://docs.craftcms.com/v3/project-config.html#enabling-the-project-config-file</a></p>

<p>Any time a field is added, modified ou removed, every environment will be updated to match the primary one. That could be much more easier than handling it manually with migrations.</p>

CC BY-SA 4.0
2019-07-11T06:23:28.700Z
I totally forgot that this exists. Thanks for the tipp!
Leonardo
CC BY-SA 4.0
2019-06-30T14:02:07.757Z
2019-06-30T14:02:07.757Z
Alban Jubert
<p>Im creating my own migrations to better handle adding/removing fields on all environments.</p>

<p>Is the following <code>safeDown()</code> function the correct way to remove a field from a fieldlayout? It works but im open if their is a better way to archive this.</p>

<pre><code>  public function safeDown()
{
    $tabStructure = [];
    $cartDestinationUrl = Craft::$app-&gt;fields-&gt;getFieldByHandle('cartDestinationUrl');
    $headerGlobalSet = Craft::$app-&gt;globals-&gt;getSetByHandle('header');
    $tabs = $headerGlobalSet-&gt;getFieldLayout()-&gt;getTabs();

    foreach ($tabs as $tab) {
        $fields = $tab-&gt;getFields();
        $fieldIds = [];
        foreach ($fields as $field) {
            $fieldId = $field-&gt;id;
            if ($fieldId !== $cartDestinationUrl-&gt;id) {
                $fieldIds[] = $fieldId;
            }
        }
        $tabStructure[$tab-&gt;name] = $fieldIds;
    }

    //remove empty tabs from layout 
    $tabStructure = array_filter($tabStructure);

    $globalSetLayout = Craft::$app-&gt;fields-&gt;assembleLayout($tabStructure);
    $headerGlobalSet-&gt;setFieldLayout($globalSetLayout);

    return (Craft::$app-&gt;globals-&gt;saveSet($headerGlobalSet));
}
</code></pre>

<craft3><migration>
Migration: Removing field from GlobalSet/Entry
# Migration: Removing field from GlobalSet/Entry

(Asked by: username_0 on 2019-06-27)

Im creating my own migrations to better handle adding/removing fields on all environments.
Is the following safeDown() function the correct way to remove a field from a fieldlayout? It works but im open if their is a better way to archive this.
  public function safeDown()
{
    $tabStructure = [];
    $cartDestinationUrl = Craft::$app->fields->getFieldByHandle('cartDestinationUrl');
    $headerGlobalSet = Craft::$app->globals->getSetByHandle('header');
    $tabs = $headerGlobalSet->getFieldLayout()->getTabs();

    foreach ($tabs as $tab) {
        $fields = $tab->getFields();
        $fieldIds = [];
        foreach ($fields as $field) {
            $fieldId = $field->id;
            if ($fieldId !== $cartDestinationUrl->id) {
                $fieldIds[] = $fieldId;
            }
        }
        $tabStructure[$tab->name] = $fieldIds;
    }

    //remove empty tabs from layout 
    $tabStructure = array_filter($tabStructure);

    $globalSetLayout = Craft::$app->fields->assembleLayout($tabStructure);
    $headerGlobalSet->setFieldLayout($globalSetLayout);

    return (Craft::$app->globals->saveSet($headerGlobalSet));
}

**Tags:** craft3, migration


---

## 1 answers

### Answer by username_1 on 2019-06-30. Score: 2 | Accepted answer

Did you consider using Craft 3.1 new Project Config File feature?

<https://docs.craftcms.com/v3/project-config.html#enabling-the-project-config-file>

Any time a field is added, modified ou removed, every environment will be updated to match the primary one. That could be much more easier than handling it manually with migrations.

> **Comments:**
> **username_0**: I totally forgot that this exists. Thanks for the tipp!  

---

