Published
Friday, February 19, 2016 - 08:09
Written by

CiviCooP is working with Emphanos on a nice CiviCRM project (of which I am sure Young-Jin will blog at some point in the near future). As part of this project I developed a specific extension that creates or updates Activity Types, Contact Types, Custom Groups with Custom Fields, Event Types, Groups, Membership Types, Option Groups with Option Values, Relationship Types and Tags from JSON files.

So for example there is a JSON file for activity types which looks like this:

{
  "cont_education_info":{
    "name": "cont_education_info",
    "label": "Continuing Education Info",
    "is_active": 1
  },
  "award_win":{
    "name": "award_win",
    "label": "Award Win",
    "is_active": 1
  },
  "advocate":{
    "name": "advocate",
    "label": "Advocate",
    "is_active": 1
  }
}

When the scheduled job Update is executed it will either create or update all the activity types in the JSON file with the values in the JSON file. So rather than manually creating and changing the activity types in your test environment and your production environment you just run the scheduled job in this extension. The added benefit is that the names of the activity types will be the same in all your project environments, so you can use the name in other customizations. In this JSON file there is an activity type award winner, so in any modification I create I can get the activity type for Award Winner with this name, knowing it will be as consistent as the 'Meeting' name for the activity type Meeting.

So for staging, you would start with a development environment, include all your settings once they are agreed on to the JSON files, and then run the scheduled job with the new JSON files on your accept environment so the agreed settings are created and/or updated.

Here is also an example of the option group with option values, which will also be created or updated when the scheduled job has run.

"employment_status":{
  "name":"employment_status",
  "title":"Ik ben werkende",
  "is_active":"1",
  "is_reserved":"0",
  "option_values":{
    "labourer":{
      "name":"labourer",
      "value":"Arbeider",
      "label":"Arbeider",
      "is_active":1
    },
    "services":{
      "name":"services",
      "value":"Bediende",
      "label":"Bediende",
      "is_active":1
    },
    "self_employed":{
      "name":"self_employed",
      "value":"Zelfstandige",
      "label":"Zelfstandige",
      "is_active":1
    },
    "other":{
      "name":"other",
      "value":"Ander",
      "label":"Ander",
      "is_active":1
    }
  }

Altought it was specifically created for this project it is obviously easy to copy and change to your specific situation. I know I do it for other projects :-) So I thought it would be nice to share even though there is no point in publishing the extension. You can find it here: https://github.com/CiviCooP/org.iida.civiconfig.

Hans Idink from Orgis and Trinfinity has added Profiles to the same extension (although be careful, he might not have my latest fixes yet....), you can find this here: https://github.com/catorghans/net.trinfinity.orgis.mi.dataquality/tree/master/resources

Filed under

Comments

It does not only work via the scheduled job. It also works via the enable method in the Upgrader class, https://github.com/catorghans/net.trinfinity.orgis.mi.dataquality/blob/m...

and should also work in an upgrade methode, so when you change a json file, you can activate it via an upgrade method.

Thanks for the remark Hans, and for the co-production!

Thanks for sharing!

There are several nice aspects here, like:

  • It's an extension, so you can use it without waiting for any core updates.
  • It has pretty broad scope -- supporting many different configuration elements.
  • You have enough room to handle dependencies in a reasonable order (e.g. importing CustomGroups and OptionGroups *before* importing CustomFields).

Do you have any thoughts or lessons from comparing this with other configuration-management techniques (eg Drupal Features, CRM_Utils_Migrate_{Import,Export}, and *.mgd.php) -- problems you were able to avoid/resolve in this approach, or features you'd like to embrace/incorporate (when someone has time/money/energy)?

Hi Tim,

thanks for your comments. And obviously (shame on me :-)) I did not compare this with CRM_Utils_Migrate as I was not aware of this and being me, I just started :-) Drupal Features was not an option as I wanted it to be CiviCRM native so I can use the same setup for a Wordpress project we are doing. I think if you use *.mgd.php the downside would be that you can not fix the small little inconsistencies in some of the API functions (like option_group with custom field still generates a new one even if I add the parameter, group name always gets the group_id at the end even if there is a name in the param, I want to be able to remove custom fields it they are in a controlled custom group but not in the JSON).

One difference I think I see with this method compared to the *.mdg.php: the managed records makes sense where you know you need to force a specific set of values for that record, but this one seems like a better approach for an initial setup that may be customized later (and for which you don't want a managed record automatically clobbering your changes).

One difference I think I see with this method compared to the *.mdg.php: the managed records makes sense where you know you need to force a specific set of values for that record, but this one seems like a better approach for an initial setup that may be customized later (and for which you don't want a managed record automatically clobbering your changes).

Something else to consider in the functionality would be a method to export the existing entities in your CiviCRM extension so that like Drupal's views import and similar workflows, that you could export into the appropriate JSON format, then import on other environments as an alternative to hand-coding the JSON.

I can see the point. However, this extension was developed for the situation where I also have crap configuration items in my sandbox. So I would not copy to test as it would also load unwanted stuff.... But I think it is a good idea and can easily be done.