5

Currently i use this to programmatically add user fields:

function openid_connect_entity_base_field_info(EntityTypeInterface $entity_type) {
    if ($entity_type->id() === 'user') {
        $fields['field_family_name'] = BaseFieldDefinition::create('string')
          ->setLabel(t('Family Name'))
          ->setDescription(t('Add a description'))
          ->setRevisionable(TRUE)
          ->setTranslatable(TRUE)
          ->setDisplayOptions('form', array(
            'type' => 'string_text_field',
            'weight' => 30,
            'default_value' => 0,
          ))
          ->setDisplayConfigurable('form', TRUE);
      }
return $fields;
}

but it results in the admin of the site unable to uninstall my module as shown: enter image description here

Are there any alternative ways to programmatically add user fields without causing the admin of the website to be unable to uninstall the module that programmatically added the user fields?

3 Answers 3

8

I found a solution using .yml files in your modules config/install directory.

1. Create the user field

go to Configuration -> People -> Account Settings -> Manage fields and press "+ Add field". I'd recommend giving the field a unique machine-readable name to prevent conflicting user fields.

enter image description here

Enable the user field in Manage Form Display and Manage Display if you want it to appear in the users edit profile and registration page.

2.Exporting the user field configuration

go to Configuration -> Development -> Configuration Synchronization -> Export -> Single Item

Once you get to a screen similar to the one below, set configuration type to "Field" then set the configuration name to the field you have created.

In your modules Config/install folder(create one if needed) create a new file named after filename highlighted in red below.

Finally Copy the yml text into the file you just created.

enter image description here

then set configuration type to "Field Storage" then set the configuration name to the user field you have created.

In your modules Config/install folder(create one if needed) create a new file named after filename highlighted in red below (don't copy the one in the example your user field will have a different name).

Finally Copy the yml text into the file you just created.

enter image description here

YOU NEED BOTH YML FILES TO PROGRAMMATICALLY CREATE A USER FIELD

I recommend doing this for each user field you want to programmatically add rather than copying the configuration and changing a few properties.

With this method you can uninstall the module that created these user fields.

4
  • 1
    Note: The user field will be disabled on manage form display and manage display even if you enabled them before the configuration.
    – Callum
    Commented Jan 5, 2017 at 15:18
  • 1
    UUID has to be deleted before enabling the module.
    – JurgenR
    Commented Mar 27, 2017 at 8:12
  • With only these 2 YML files, when I install the module the custom user field is added in the list "Manage fields" (/admin/config/people/accounts/fields). But the new field is not displayed in the user edit form, so I can't change its value.
    – Eria
    Commented Sep 11, 2017 at 13:26
  • If you need to update or override existing fields, take a look at drupal.org/project/config_rewrite
    – Nicolaj
    Commented Jan 17, 2018 at 12:50
0

Updated answer:

You can include the field as default configuration upon installing the module. By adding the field configuration to exportable files (yaml-files) these can then be installed and added. When uninstalling the module the field and data will remain.

In your module create the folders config/install and place the configuration files there: For example, if I add a field field_test_email I would place the field storage and then the instance on the User entity.

field.storage.user.field_test_email.yml field.field.user.user.field_test_email.yml

https://www.drupal.org/docs/8/creating-custom-modules/include-default-configuration-in-your-drupal-8-module

Old answer:

If you want to keep the fields and its data the short answer is No, you cannot and shouldn't. Field definitions, configuration are coupled to its creator "the module", and when uninstalling everything it did goes away with it.

Drupal used to support disabling a module, but that was removed. See explanation here: https://www.drupal.org/node/2225029

A huge debate and amount of thought went into this, with strong talk on both sides. Reasons for this include : * Because upgrades of some contrib module don't actually work (and can't > be made to work) if upgrading when they are disabled. * Because data left behind by a disabled module that is later re-enabled > causes integrity issues and cruft. * Some upgrades left behind data loss due to things like unexpected > dependencies, plugins or hooks being unavailable at key times - when things were disabled. .. that issue is several hundred arguments long, so It's unfair to over-summarize.

During an uninstall there are different validators called to ensure the system does not break or keep data that cannot be handled later. For your case it is the FieldModuleUninstallValidator validator that gives you those error messages.

So to uninstall the module all data has to be deleted; You can try using the Field API bulk deletion for that: https://api.drupal.org/api/drupal/core!modules!field!field.purge.inc/group/field_purge/8.2.x

3
  • I found the same solution as you have, i've made a step by step tutorial how to do it below.
    – Callum
    Commented Jan 5, 2017 at 15:04
  • > You cannot programmatically create the fields to the User entity. Not strictly true. No reason you can't create the config entities from code, without using the config import folder. FieldStorageConfig::create() and FieldConfig::create() will do it.
    – Sam Becker
    Commented Jan 6, 2017 at 20:41
  • @Sam152 Thanks for the correction. Removed that part of my answer.
    – johndevman
    Commented Jan 7, 2017 at 11:28
0

You can use this module to programmatically create fields and attach them to the User entity:

https://drupal.org/project/field_create

As you can read in the documentation, this module is meant for development purpose only. Enable it, create your fields and then uninstall it. This way, there is no "custom module" to install in order to have your custom fields.

Your website admin does not have to worry about uninstalling anything :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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