Now that Code for Change is done, this document describes the status of the things we worked on in CiviCRM. The three big pieces we implemented are:
- Standalone UF (no CMS required)
- Nestable groups (parent and child groups)
- Multi-organization support (groups and organization contacts joined together and other goodies)
Standalone UF
The Standalone UF was implemented first and thus is the most thoroughly tested. It is implemented as just another user framework (UF) like Drupal and Joomla, with the addition of an OpenID-based login system. Little attention has been paid to making it look correct or nice, just to making it work. There should probably be some more attention paid to the layout of the system. The actual UF code was borrowed heavily from the Joomla UF since that is more loosely-coupled than the Drupal one. Installation instructions are sprinkled throughout the civicrm.settings.php.sample.tmpl file in the comments (just like for the other UFs), but there is also a standalone installer that fires up when it detects that you haven't configured CiviCRM yet. That system's interaction with the Drupal and Joomla UF's has not been tested.
As part of the new OpenID-based login system, the unique identifier has been changed from an email address to an OpenID (or OpenID-like construction consisting of username.domain_name_of_site.tld). This needs more thorough testing and actual implementation code for the Drupal and Joomla UFs (i.e. someone who knows how to get the username and domain name from those CMSs should code that in there).
Nestable groups
Nestable groups were implemented second, and thus have been reasonably well tested. More stress testing and corner-case testing is definitely in order, however.
Nestable groups are implemented with an additional database table called civicrm_group_nesting. This is a very simple table with three columns:
- id
- child_group_id
- parent_group_id
This allows the table to map arbitrary parent-child relationships among the groups in the system. Multi-parent relationships are allowed, so it's not a strict hierarchy, but a graph. Steps are taken to ensure infinite loops cannot easily be created in the interface, and when possible without killing performance, not followed even if they are created. This needs more testing.
This table has a schema xml file and a DAO class file in the places you'd expect (CRM/Contact). There is also a CRM/Contact/BAO/GroupNesting.php class which implements several handy class methods for determining group relationships. The existing group classes and database schema were not modified. The BAO also implements the Iterator interface (when you implement an instance of it rather than calling its class methods) that lets you iterate over the groups in a manner that's logical for displaying them in the interface. It treats them as though they were a hierarchy and repeats the same group more than once for every time it's a sub-group of something else. The iterator can send an indentation level hint so that the displaying widget can indent sub-groups to make the relationships apparent. This seems to be the best way to display them for now, though this would benefit from a more advanced widget in the future (perhaps a dojo tree widget).
Defining new parent-child relationships is done in the group settings page. There is a new option to add and remove child groups from any group in the system. The list of available child groups is limited to those groups that won't define a cyclical relationship. Contacting searching has been updated to understand nested groups. CiviMail also now has a basic awareness of them. Other areas of the system need to be updated to deal with them properly (they're not broken right now, they are just missing obvious features that users of nested groups will want). This includes Importing, CiviContribute, CiviEvent, and CiviMember.
Multi-org
The multi-org implementation is the least mature of the three as we did that last. There is a new table called civicrm_group_organization that links groups and organization contacts. In this way, organization contacts that are internal your organization (i.e. sub organizations of your parent organization) can have groups affiliated with them and thus contacts in the system can be grouped under which organization they belong to. Combining this with the nested groups abilities above, quite complex organizational structures can be modeled.
You can define new organization<->group links in the group settings page. (To be continued...)
