1

Working on a mailing that includes contacts full address details. And I'm encountering an issue for UK addresses where the county is abbreviated in the same way US states are. I've never seen such 3-char abbreviations used in the UK and it will cause confusion. Omitting the county is not an option either. Sadly the standard address hooks for mailings are limited.

Googling yielded the following page which has code I'm trying to use in a custom Civicrm extension. So far my attempts are failing miserably. I'm not very familiar with PHP, so please excuse and gently correct whatever atrocities I might be committing in the code below.

https://forum.civicrm.org/index.php%3Ftopic=20687.0.html

The extension is meant to provide two new tokens to mailings:

  • {contact.province}: prints the State / Province full name (as in {contact.state_province_name}). Not the same name in case this brings any conflict with the existing one
  • {contact.complete_address}: prints the full contact's address with the same format set in the label address customization

The article is quite old and uses APIv2, so I've resorted to adapt it to APIv4. In doing so my PHP errors have disappeared but I'm not seeing any results in "Preview as HTML" yet when editing a test mailing.

My hooks code below:

// Works, the new hooks show up in the list when editing mailings //
function mailhooks_civicrm_tokens( &$tokens ) {
    $tokens['contact'] = array(
        'contact.province' => 'Province',
        'contact.complete_address' => 'Complete Address',
    );
}
// Not returning anything, the tags are not interpreted at all //
function mailhooks_civicrm_tokenValues( &$values, &$contactIDs ) {
    require_once 'CRM/Utils/Address.php';
    foreach($contactIDs as $id){
        $address = \Civi\Api4\Address::get()
            ->addSelect('street_address', 'supplemental_address_1', 'supplemental_address_2', 'supplemental_address_3', 'city', 'postal_code', 'state_province_id:label', 'country_id:label')
            ->addWhere('contact_id', '=', $id)
            ->execute();
        $values[$id]['contact.complete_address'] = nl2br(CRM_Utils_Address::format($address[$id]));
        $values[$id]['contact.province'] = $address[$id]["state_province_id:label"];
    }
}

The output from the API Explorer (dummy address):

(1) [
  {
    "id": 3,
    "street_address": "3 Kings Road",
    "supplemental_address_1": null,
    "supplemental_address_2": null,
    "supplemental_address_3": null,
    "city": "Hitchin",
    "postal_code": "SG5 0AZ",
    "state_province_id:label": "Hertfordshire",
    "country_id:label": "United Kingdom"
  }
]

Partial HTML preview:

SG5 0AZ, {contact.province}
United Kingdom
{contact.complete_address}

Email template:

{contact.postal_code}, {contact.province}
{contact.country}
{contact.complete_address}
  • I must be doing something wrong as when I simplify the return of values, nothing is returned: $values[$cid]['contact.complete_address'] = 'test'; – dmgeurts Nov 4 '20 at 22:41
  • I'm not following why you want {contact.province} when {contact.state_province_name} already exists with the full UK County name? – Aidan Nov 9 '20 at 21:02
  • @Aidan Because for some reason '{contact.state_province_name}' isn't available in mailings. – dmgeurts Nov 10 '20 at 9:57
1
+50

It should be like below

// Not returning anything, the tags are not interpreted at all //
function mailhooks_civicrm_tokenValues( &$values, &$contactIDs ) {
  foreach($contactIDs as $id){
    $address = \Civi\Api4\Address::get()
      ->addSelect('street_address', 'supplemental_address_1', 'supplemental_address_2', 'supplemental_address_3', 'city', 'postal_code', 'state_province_id:label', 'country_id:label')
      ->addWhere('contact_id', '=', $id)
      ->execute()
      ->itemAt(0);
    $values[$id]['contact.complete_address'] = nl2br(CRM_Utils_Address::format($address));
    $values[$id]['contact.province'] = $address["state_province_id:label"];
  }
}

HTH

Pradeep

  • Thank you, Pradeep. Sadly the HTML Preview is still not converting the tokens. Is it an issue that on the preview HTML the contactIDs value is likely a single entry and not an array or is this always parsed as an array to tokenValues? – dmgeurts Nov 3 '20 at 9:30
  • Hmmm, array vs single entry is unlikely the issue. adding "$contactIDs = (is_array($contactIDs)) ? $contactIDs : [$contactIDs];" to ensure the parsed values are an array doesn't make any difference. – dmgeurts Nov 3 '20 at 9:39
1

This doesn't fix the larger issue (see e.g. https://lab.civicrm.org/dev/core/-/issues/1709) but you can update your database to put the full name in the abbreviation field:

alter table civicrm_state_province modify column abbreviation varchar(64) DEFAULT NULL;

update civicrm_state_province s inner join civicrm_country c ON s.country_id = c.id SET s.abbreviation = s.name WHERE c.iso_code='GB';

You might need to re-run if new state/provinces are added to GB.

  • New counties in the UK are VERY rare! Will check the link, thank you. – dmgeurts Nov 17 '20 at 22:53
  • That worked a charm thank you!. Pitty that something like {contact.complete_address} isn't available to mailings either. – dmgeurts Nov 17 '20 at 23:05
  • It seems like that would be a reasonable thing to have. – Demerit Nov 17 '20 at 23:13
  • Darn it, I assigned the bounty to the wrong answer and can't undo this... Sorry! – dmgeurts Nov 22 '20 at 23:32
  • No worries! Thanks for the note. – Demerit Nov 22 '20 at 23:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.