Cannot add multivalue custom data for contacts with multiple subtypes, in some circumstances
Overview
Pretty obscure, this. If a contact has multiple subtypes, you can't add multiple sets of multivalue data unless the final subtype in the contact's list of subtypes happens to match the subtype the multivalue data is linked to. This only happens when said data is not displayed in a table.
So if a contact has the subtypes 'Staff, Volunteer' (as listed on the Contact Summary, which matches the order in the civicrm_contact table), you can't add more than one set of multivalue data that's linked to the 'Staff' subtype.
In practice what happens is that the 'Another...record' button disappears:
This happens because the button tries to call:
CRM.buildCustomData('Individual','[whatever subtype the data relates to]', '', 1, 8, true )
This call fails because the second parameter needs to match the subtype that the custom data is linked to. But it actually always uses the final subtype in someone's list of subtypes. Thus if someone only has one subtype, or the data happens to be linked to the final subtype, it works fine.
This happens because of this line in CRM_Core_BAO_CustomGroup::getTree(). It calls buildGroupTree() with the $subType parameter. But the $subType parameter only exists because of an earlier foreach where $subType was the iterated value. So $subType always ends up being the last subtype in the array.
I had a go at fixing it, but CustomGroup data and grouptrees are pretty confusing, and far-reaching. I did find that if you run CRM.buildCustomData with a comma separated list of all subtypes then it does actually work ok. However, adapting CRM_Core_BAO_CustomGroup::getTree() to use such a comma-separated list didn't immediately work - it caused problems somewhere else in the grouptree build.
Reproduction steps
- Using one of the sites with demo data, create a new custom data group. Set 'Used For' to 'Individual' -> 'Staff'.
- Tick 'Does this Custom Field Set allow multiple records', and set 'Display Style' to 'Tab'. Then save and add a basic text field.
- Create a new contact with 'Volunteer' and 'Staff' subtypes. Make sure that the 'Staff' subtype comes first in the display on the contact record.
- Go to the multivalue data tab. Click the 'Another...record' button. It disappears.
Environment information
Reproduced on WP demo site on 5.40alpha1. Present on our test site on 5.24 (I know), so not a regression.