We've been having quite a few requests for the ability to modify and extend the types of contact records which we can be stored in CiviCRM (currently limited to Individuals, Households and Organizations). Thanx to the nice folks at Alpha International
, we will be adding the ability to rename or "hide" the existing Contact Types AND define Contact Sub-types as part of CiviCRM v3.1. Here is a first draft of what we plan to implement. Your comments and feedback are appreciated.
In v3.1 we will introduce the notion of a Contact Sub-type. This will allow users to create specific types of Contacts for their use cases. For example, a school could introduce three new sub-types: Student, Parent and Staff. Sub-Types will inherit from one of the three contact types (Individuals in this case). Sub-types will have all the properties and features of the main contact types. Thus an admin will be able to:
- Create a custom group that extends a specific sub-type. Thus all Student data can be extended with a set of student-specific custom fields. Custom fields defined for a specific sub-type can be viewed/edited for contacts of that sub-type (and conversely these fields are NOT included when viewing or editing other contacts).
- Create a profile tailored for a specific sub-type. Thus a student directory will show properties of contacts who are students. A profile "create contact" form for a specific subtype will set the contact subtype appropriately.
- Allow relationships to be created between specific contact sub-types. Thus a teacher <-> student relationship can be created where one contact is required to be of sub-type teacher while the other contact is required to be of sub-type student.
- Allow the import/export mappings to reflect fields that belong to a specific sub-type.
- Allow import of a file related to one contact sub-type only. Thus you can import only contacts of sub-type Student. Also allow import of the contact_type and contact_sub_type fields in a generic import (so you can included contacts of various types and sub-types in a single import file).
- Allow overriding of the edit / view screens by contact subtype (similar to how we do template overrides for profile pages).
- Add "create new..." menu entries for all sub-types, under the main contact type.
Contact Sub-types need to be extensible. We will use the civicrm_option_group and civicrm_option_value tables to store the Contact Type and Contact Sub-type information. Contact types will be stored in the option group 'contact_type'. The name will be the internal name used within the code (individual, household, organization etc). The label will be the value displayed to the user. Renaming is trivial and can be accomplished by changing the label of the option group. Hiding can be accomplished by setting the option group to be hidden.
The contact sub-types will be stored in the option group: 'contact_subtype_typeName'. Each option group will have an entry for the default case (i.e. no contact subtype specified). Adding more contact sub-types for a specific contact type will simply mean adding a new option value entry.
Adding a completely new contact type seems pretty feasible in this scheme. We will also need to store additional data as to what columns in civicrm_contact are applicable to this contact type, and which ones are required (for e.g. individual uses the first_name, last_name, gender_id etc). The required rules for individual are a bit more complex. Seems like this might be a good case to allow for extension via "hooks".
In the table civicrm_contact the column contact_type is an enum. We need to change this to make it either a varchar or a integer (pointing to the option value for the contact type). For ease of implementation, i suspect we'll change it to a varchar and use the 'name' from the option_group_table. we also have a column in civicrm_contact for contact_sub_type (varchar). We could potentially store the name of the contact_sub_type or the option_value id. I suspect to keep things in sync with contact_type we will keep it as a string. If we do allow multiple sub types, we could store a comma separated string. I suspect a join table here might be a bit of a overkill
- During this development, we will also attempt to allow folks to hide or rename the main Contact Types. Thus an install can decide to hide the Household contact type and rename the Organization contact type to Team.
- We currently are not planning to allow a contact to have multiple sub-types. We think that this will increase the complexity of the implementation significantly. However if it turns out to be not too hard, we might go down this route. If this is of interest to you, please consider sponsoring the functionality. We expect this feature to take an additional 50-100 hours at least
- We currently do not plan on allowing new top level Contact types. However this might be a relatively easy feature when we restructure the code base to handle contact sub-types.