APIv4 Pseudoconstants (Option Lists)¶
Some fields in CiviCRM are linked to an option list (aka Pseudoconstant). These fields are typically shown to the user as checkboxes, radios, or a dropdown-select of options from the pseudoconstant list.
The API provides tools for working with such fields; so that downstream developers do not need to translate between database values and option properties.
Option list properties¶
Each option in the list consists of attributes like id
, name
, label
, description
, color
and icon
.
For a complete list and description of each attribute see the framework chapter: Pseudoconstant (Option List) Reference.
Which fields have option lists?¶
To find out which fields have option lists for a particular entity, use the getFields
action from the API or API Explorer, e.g.
civicrm_api4('Contact', 'getFields', [
'where' => [['options', '!=', FALSE]],
])
Retrieving an option list¶
If you need to retrieve the full option list for a field, use the getFields
action and set the loadOptions
parameter
to an array of the above properties you would like to retrieve. Try it in the API explorer, e.g.
civicrm_api4('Contact', 'getFields', [
'where' => [['name', '=', 'contact_type']],
'loadOptions' => ['name', 'label', 'description'],
])->first();
contact_type
field including the list of available options (names will be ['Individual', 'Household', 'Organization'], labels will be localized translations if the site is not in English).
Tip
Unless you are building a form and need to render an option list for the user to select, in most cases
you will not need to query getFields
to e.g. match option ids to labels. The syntax below can automatically
perform such transformations.
Option transformations¶
When reading or writing data from the API, a special suffix tells the API to transform between option ids and other properties. For example:
Writing¶
Activity::create()
->addValue('activity_type_id:name', 'Meeting')
...
Using this syntax saves you from needing to look up the id of an activity type. It also makes your code more portable, as option ids can change from one database to another, but names are consistent.
Reading¶
Get operations use the same syntax to reverse the lookup and transform an option id to another property.
Activity::get()
->addSelect('*', 'activity_type_id:label', 'activity_type_id:icon')
...
This tells the API to return all fields (*
) plus the label and icon of the activity type, giving the data needed for a user-facing display.
Option Lists or Joins
The syntax for option transformations looks very similar to implicit joins (the difference being a colon instead of a dot). Your choice of which to use depends on the field.
For example, the Contact gender_id
field has an option list but not a foreign key, so you must use the option syntax (gender_id:label
).
But the Event campaign_id
field has a foreign key instead of an option list, so you would use a join (campaign_id.title
).