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

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

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


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.

  • I totally forgot that this exists. Thanks for the tipp! – Leonardo Jul 11 '19 at 6:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.