Answers.Body: <p>If you mean which api functions to call to create/update/delete the type, as a general rule you look in api explorer (available via the admin menu in civicrm under Support -> Developer) to see if there's something there (which shows there is ContactType -> create), and if had turned out there wasn't anything you could look in the core code to see how civi does it when you do it from the UI.</p>
  
  <p>If you're asking which hooks to use it would be hook_civicrm_install / uninstall / enable / disable. In install/uninstall you create/delete the type, in enable/disable you set <code>is_active</code> to 1 or 0. In uninstall you might not want to delete the type if there are existing contacts with that type.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T16:56:33.867Z
Answers.LastActivityDate: 2019-12-10T20:28:10.213Z
Answers.LastEditDate: 2019-12-10T20:28:10.213Z
Answers.UserDisplayName: Demerit
Answers.Body: <p>A contact subtype is an "entity" - it exists as a record in the civicrm_contact_type table. So that means you can use the "managed entity" approach described here:</p>
  
  <p><a href="https://civicrm.org/blog/totten/api-and-art-installation" rel="nofollow noreferrer">https://civicrm.org/blog/totten/api-and-art-installation</a></p>
  
  <p>and documented here:</p>
  
  <p><a href="https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed/" rel="nofollow noreferrer">https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed/</a></p>
  
  <p>You could instead implement the install hook (<a href="https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install/" rel="nofollow noreferrer">https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install/</a>) and manually test for the existence of the contact type and create it if not (more details in Demerit's answer below).</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T17:29:17.917Z
Answers.Text: Thank you!  I think I'd like to use the managed entity approach and I believe I somewhat understand it.  I'm just wondering if there's a civix command to create the .mgd.php file and the code that goes in it, or do I just manually do that?
Answers.UserDisplayName: Jason Brown
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T18:05:20.557Z
Answers.Text: I believe it's only a manual thing. It's deceptively easy, here's an example: https://github.com/iATSPayments/com.iatspayments.civicrm/blob/master/CRM/Core/Payment/Iats.mgd.php
  You just have to look at the table and see what CiviCRM expects  in terms of fields/types/values.
Answers.UserDisplayName: Alan Dixon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T19:11:31.553Z
Answers.Text: It looks like everything in the managed hook is referencing "version 3".  I'm assuming that's api version 3?  If so, is it safe to change it to 4 manually?
Answers.UserDisplayName: Jason Brown
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T20:08:08.947Z
Answers.Text: Good question. Yes, I think you're correct about 3 being the api version. I haven't tried api v4 with the managed hook. I assume it should work similarly.
Answers.UserDisplayName: Alan Dixon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T20:57:52.300Z
Answers.Text: Thanks for all your help!  Got it working, but it does not appear that it's possible to use version 4 at this time (at least I can't get it to work.
Answers.UserDisplayName: Jason Brown
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T22:35:30.560Z
Answers.Text: Well, it worked for the ContactType, but when I tried to add a RelationshipType it only does one or the other.  I've tried 1 array with both of them, 2 seperate arrays, 2 seperate files, and even 2 seperate files in 2 different directories.  Each of them work fine if I remove the other, but when they are both present...only the RelationshipType is created.  Any idea what's going on there?
Answers.UserDisplayName: Jason Brown
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-11T17:22:16.283Z
Answers.Text: Each entity type should have  it's own file in the right directory, for sanity if not code correctness. The entity management only happens erratically in my experience, the best way to trigger it is to uninstall and reinstall an extension. Sounds like you might have a name space collision of some kind?
Answers.UserDisplayName: Alan Dixon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-11T17:29:05.983Z
Answers.Text: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/102081/discussion-between-jason-brown-and-alan-dixon).
Answers.UserDisplayName: Jason Brown
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-04-13T16:18:02.083Z
Answers.Text: I have to say, I struggled with this today but it now works.  Creating a module from scratch using civix generate:module did not add the scaffolding for the hook_civicrm_managed.  I had to add it in to both the extension_name.civix.php and the accompanying extension_name.php.  Has something changed with all this?
Answers.UserDisplayName: ChumKui
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-04-19T14:06:46.943Z
Answers.Text: I suspect you're experiencing the new "mixin" structure to civix that provides hidden magic.
Answers.UserDisplayName: Alan Dixon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-10T16:51:21.210Z
Answers.LastActivityDate: 2019-12-10T18:08:06.450Z
Answers.LastEditDate: 2019-12-10T18:08:06.450Z
Answers.UserDisplayName: Alan Dixon
Body: <p>I'm building a new extension using civix and buildkit.  I need to create a new ContactType (sub-type of individual) on install (if it doesn't already exist).  I know how I would do it, but I'd prefer to do it in accordance with CiviCRM's standards.  What's the correct way to do this?</p>
  
Tags: <developer><civix>
Title: Create new contact sub-type when extension is installed
ThreadText: # Create new contact sub-type when extension is installed
  
  (Asked by: username_0 on 2019-12-10)
  
  I'm building a new extension using civix and buildkit. I need to create a new ContactType (sub-type of individual) on install (if it doesn't already exist). I know how I would do it, but I'd prefer to do it in accordance with CiviCRM's standards. What's the correct way to do this?
  
  **Tags:** developer, civix
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2019-12-10. Score: 5 | Accepted answer
  
  A contact subtype is an "entity" - it exists as a record in the civicrm\_contact\_type table. So that means you can use the "managed entity" approach described here:
  
  <https://civicrm.org/blog/totten/api-and-art-installation>
  
  and documented here:
  
  <https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_managed/>
  
  You could instead implement the install hook (<https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install/>) and manually test for the existence of the contact type and create it if not (more details in username_1's answer below).
  
  > **Comments:**
  > **username_0**: Thank you!  I think I'd like to use the managed entity approach and I believe I somewhat understand it.  I'm just wondering if there's a civix command to create the .mgd.php file and the code that goes in it, or do I just manually do that?  
  > **username_2**: I believe it's only a manual thing. It's deceptively easy, here's an example: https://github.com/iATSPayments/com.iatspayments.civicrm/blob/master/CRM/Core/Payment/Iats.mgd.php You just have to look at the table and see what CiviCRM expects  in terms of fields/types/values.  
  > **username_0**: It looks like everything in the managed hook is referencing "version 3".  I'm assuming that's api version 3?  If so, is it safe to change it to 4 manually?  
  > **username_2**: Good question. Yes, I think you're correct about 3 being the api version. I haven't tried api v4 with the managed hook. I assume it should work similarly.  
  > **username_0**: Thanks for all your help!  Got it working, but it does not appear that it's possible to use version 4 at this time (at least I can't get it to work.  
  > **username_0**: Well, it worked for the ContactType, but when I tried to add a RelationshipType it only does one or the other.  I've tried 1 array with both of them, 2 seperate arrays, 2 seperate files, and even 2 seperate files in 2 different directories.  Each of them work fine if I remove the other, but when they are both present...only the RelationshipType is created.  Any idea what's going on there?  
  > **username_2**: Each entity type should have  it's own file in the right directory, for sanity if not code correctness. The entity management only happens erratically in my experience, the best way to trigger it is to uninstall and reinstall an extension. Sounds like you might have a name space collision of some kind?  
  > **username_0**: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/102081/discussion-between-jason-brown-and-alan-dixon).  
  > **username_3**: I have to say, I struggled with this today but it now works.  Creating a module from scratch using civix generate:module did not add the scaffolding for the hook_civicrm_managed.  I had to add it in to both the extension_name.civix.php and the accompanying extension_name.php.  Has something changed with all this?  
  > **username_2**: I suspect you're experiencing the new "mixin" structure to civix that provides hidden magic.  
  
  ---
  
  ### Answer by username_1 on 2019-12-10. Score: 1
  
  If you mean which api functions to call to create/update/delete the type, as a general rule you look in api explorer (available via the admin menu in civicrm under Support -> Developer) to see if there's something there (which shows there is ContactType -> create), and if had turned out there wasn't anything you could look in the core code to see how civi does it when you do it from the UI.
  
  If you're asking which hooks to use it would be hook\_civicrm\_install / uninstall / enable / disable. In install/uninstall you create/delete the type, in enable/disable you set `is_active` to 1 or 0. In uninstall you might not want to delete the type if there are existing contacts with that type.
  
  
  ---
  
  