Skip to content

Managed Entities

Introduction

When writing an extension, it's often necessary to insert data when the extension is enabled. For example, menu items, custom fields or option values all might be needed for the extension to function. Extensions may also want to ship with preconfigured SearchKit Displays or Afforms.

You'd want these items to be added when the extension is installed, disabled when the extension is disabled, and deleted when the extension is uninstalled. In some cases you'd also want to allow the end-user to make changes, e.g. adjusting settings for a search display, but allow them to revert it back to the original state defined by your extension. In other cases, e.g. a reserved option value, you want the user to be locked out of editing or deleting it, but you do want changes made in your extension code to update the record in the database, e.g. if you later add a description to the option value record.

Managed Entities provide all of this functionality with minimal coding.

Creating a Managed Record

The recommended way to package and distribute managed records is using the civix export command.

Fine-Tuning

Update Modes

This setting determines whether a managed record will be auto-updated after it is installed. This is important to consider if the values in your mgd.php record might ever change in future updates to your extension.

  • always: Forcibly overwrite record with values from the .mgd.php definition with every cache-flush.
  • never: Once installed, the record will never be updated.
  • unmodified: Updates to the .mgd.php will be propagated only if the record has not been updated by the user.

In general, always is a good choice for records which are not meant to be updated by the user, such as reserved OptionValues. In most other cases, unmodified is the best trade-off between allowing edits to be made by the user, and propagating updates when changes are made to the .mgd.php in new versions of the extension. Changes made by the user can be undone by the revert API action.

Cleanup Modes

This setting determines whether a managed record will be deleted when the extension is uninstalled.

  • always: Unconditionally delete the record when the extension is uninstalled.
  • never: Once installed, the record will never be auto-deleted.
  • unused: Determines whether any references to the record exist (e.g. if the record is an Acitity Type, do any activities exist of that type?), and only delete it if not.

Handling possibly existing records

Normally, if the Managed system tries to add a record which already exists, it causes an error. However, sometimes an extension author isn't sure if the item they want to distribute already exists. For example, the 1.0 release of an extension may have used hook_civicrm_install to add an OptionValue. In the 2.0 release, it's decided to move it into a mgd.php file - what to do about existing sites which have already installed the OptionValue?

The solution is to add match to the params array, declaring which fields should be compared to see if a record exists before creating a new one. The civix export command automatically adds the relevant matches for an entity. For example, an OptionValue will need to match on name, value and option_group_id. A CustomField will need to match on name and custom_group_id. Without adequate parameters, the Managed system can get confused between similar entities across different parent entities, such as OptionValue entities with the same value in different OptionGroup entities.

Technical Details

For more technical details, see the chapter Managed APIv4 Entities.