In case you have been living under a rock, the CiviCRM development environment has dramatically changed over the last 5 years. Recently I've had the opportunity to upgrade my 10 year old CiviCRM development chops by learning some of the new tools and I thought I would share my experiences.
The crown jewel of the recent changes is APIv4. Wow. If you haven't tried it out, you should stop what you are doing and take a look at the docs. It makes refactoring old code actually enjoyable. The best part is deleting all those tedious lines of code where you query for the ids of lookup values or create endless
JOIN clauses and replace them with succinct and easily readable phrases like:
->addWhere("status_id:name", "=", "Pending") or
Also, the code just looks prettier.
But wait, there's more! In addition to consuming APIv4 in your code, you can write your own APIv4 code. I've made extensive use of the
\Civi\Api4\Generic\AbstractAction class. For example, I re-wrote all of our Powerbase provisioning code in APIv4. Now, after installing CiviCRM, we simply enable our setup extension and then run:
cv api4 PowerbaseSetup.Initialize.
Managed entities are an awesome way to define entities (custom fields, option values, etc) that your extension needs created in the database when it's enabled (the managed entities system also propagates changes to the entities). But they aren't that new. However, APIv4 managed entities with the
match parameter are new.
match parameter allows you to say, for example, that if an entity with the same name already exists, don't try to create it. This means you can take an extension that already adds entities any old ad-hoc way and move them to managed entities without "duplicate key exists" errors.
And, combined with APIv4's ability to use custom fields by name (rather then id), you can now consistently create and reference custom fields by name throughout your code.
And one more thing… APIv4 has an export function - so you can create your entities by hand using the UI and then easily export them to a format that can
go right into your
Ok, let's be honest. It's a bummer that after committing to AnguarJS, the framework was abandoned upstream, leaving us with two form frameworks that are abandoned. Boo.
However, if you can get over that disappointment, you can create some nice UIs.
First tries are often garbage and this was no exception.
Fortunately, I realized that I didn't need to add anything beyond display code in the angular app - everything else could be neatly placed in my own APIv4 actions (see above, have I mentioned how much I love APIv4?). I re-wrote it, with the angular parts doing nothing but controlling the display and calling APIv4.
And, wow. It is a vast improvement over jQuery. (For example, checkout the May First Dues Calculator.)
One of my extensions sends membership email renewal reminders. We use custom code to send these reminders because we have our own logic for determining which contacts should be notified for a given membership.
The new tokens framework, in addition to solving all kinds of performance problems and general legacy coding messiness, allows you to set your own custom context variables when requesting that the tokens be rendered, and (of course) access that context when providing the filled in tokens.
So, when rendering the email templates I can pass both the contact id and the membership id and be confident that both contexts will be passed on to my functions that provide the tokens.
Much Much More
None of my recent extensions have included any bundled Search Kit searches or make use of Form Builder so I guess you can consider this blog already dated.
Thanks so much to the core developers and everybody else who contributed to these amazing new tools and frameworks!
Thanks Jamie - nice write up. Great to see so much buzz for APIv4 - because I know Coleman spent years convincing us we needed it :-)
Glad you like APIv4 - I agree it's great, and it's also the backbone of SearchKit and Form Builder. Hope you get to try those out too.
Thanks Jamie for sharing for your experiences. Thanks to have you in the community.