Answers.Body: <p>It should be like below</p>
  <pre><code>// Not returning anything, the tags are not interpreted at all //
  function mailhooks_civicrm_tokenValues( &amp;$values, &amp;$contactIDs ) {
    foreach($contactIDs as $id){
      $address = \Civi\Api4\Address::get()
        -&gt;addSelect('street_address', 'supplemental_address_1', 'supplemental_address_2', 'supplemental_address_3', 'city', 'postal_code', 'state_province_id:label', 'country_id:label')
        -&gt;addWhere('contact_id', '=', $id)
        -&gt;execute()
        -&gt;itemAt(0);
      $values[$id]['contact.complete_address'] = nl2br(CRM_Utils_Address::format($address));
      $values[$id]['contact.province'] = $address[&quot;state_province_id:label&quot;];
    }
  }
  </code></pre>
  <p>HTH</p>
  <p>Pradeep</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-03T09:30:43.743Z
Answers.Text: 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?
Answers.UserDisplayName: dmgeurts
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-03T09:39:33.930Z
Answers.Text: 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.
Answers.UserDisplayName: dmgeurts
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-03T04:43:38.413Z
Answers.LastActivityDate: 2020-11-03T04:43:38.413Z
Answers.UserDisplayName: Pradeep Nayak
Answers.Body: <p>This doesn't fix the larger issue (see e.g. <a href="https://lab.civicrm.org/dev/core/-/issues/1709" rel="nofollow noreferrer">https://lab.civicrm.org/dev/core/-/issues/1709</a>) but you can update your database to put the full name in the abbreviation field:</p>
  <p><code>alter table civicrm_state_province modify column abbreviation varchar(64) DEFAULT NULL;</code></p>
  <p><code>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';</code></p>
  <p>You might need to re-run if new state/provinces are added to GB.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-17T22:53:10.180Z
Answers.Text: New counties in the UK are VERY rare! Will check the link, thank you.
Answers.UserDisplayName: dmgeurts
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-17T23:05:49.650Z
Answers.Text: That worked a charm thank you!. Pitty that something like {contact.complete_address} isn't available to mailings either.
Answers.UserDisplayName: dmgeurts
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-17T23:13:46.873Z
Answers.Text: It seems like that would be a reasonable thing to have.
Answers.UserDisplayName: Demerit
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-22T23:32:51.410Z
Answers.Text: Darn it, I assigned the bounty to the wrong answer and can't undo this... Sorry!
Answers.UserDisplayName: dmgeurts
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-22T23:49:57.130Z
Answers.Text: No worries! Thanks for the note.
Answers.UserDisplayName: Demerit
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-17T20:21:45.410Z
Answers.LastActivityDate: 2020-11-17T20:21:45.410Z
Answers.UserDisplayName: Demerit
Body: <p>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.</p>
  <p>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.</p>
  <p><a href="https://forum.civicrm.org/index.php%3Ftopic=20687.0.html" rel="nofollow noreferrer">https://forum.civicrm.org/index.php%3Ftopic=20687.0.html</a></p>
  <p>The extension is meant to provide two new tokens to mailings:</p>
  <ul>
  <li>{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</li>
  <li>{contact.complete_address}: prints the full contact's address with the same format set in the label address customization</li>
  </ul>
  <p>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 &quot;Preview as HTML&quot; yet when editing a test mailing.</p>
  <p>My hooks code below:</p>
  <pre><code>// Works, the new hooks show up in the list when editing mailings //
  function mailhooks_civicrm_tokens( &amp;$tokens ) {
      $tokens['contact'] = array(
          'contact.province' =&gt; 'Province',
          'contact.complete_address' =&gt; 'Complete Address',
      );
  }
  // Not returning anything, the tags are not interpreted at all //
  function mailhooks_civicrm_tokenValues( &amp;$values, &amp;$contactIDs ) {
      require_once 'CRM/Utils/Address.php';
      foreach($contactIDs as $id){
          $address = \Civi\Api4\Address::get()
              -&gt;addSelect('street_address', 'supplemental_address_1', 'supplemental_address_2', 'supplemental_address_3', 'city', 'postal_code', 'state_province_id:label', 'country_id:label')
              -&gt;addWhere('contact_id', '=', $id)
              -&gt;execute();
          $values[$id]['contact.complete_address'] = nl2br(CRM_Utils_Address::format($address[$id]));
          $values[$id]['contact.province'] = $address[$id][&quot;state_province_id:label&quot;];
      }
  }
  </code></pre>
  <p>The output from the API Explorer (dummy address):</p>
  <pre><code>(1) [
    {
      &quot;id&quot;: 3,
      &quot;street_address&quot;: &quot;3 Kings Road&quot;,
      &quot;supplemental_address_1&quot;: null,
      &quot;supplemental_address_2&quot;: null,
      &quot;supplemental_address_3&quot;: null,
      &quot;city&quot;: &quot;Hitchin&quot;,
      &quot;postal_code&quot;: &quot;SG5 0AZ&quot;,
      &quot;state_province_id:label&quot;: &quot;Hertfordshire&quot;,
      &quot;country_id:label&quot;: &quot;United Kingdom&quot;
    }
  ]
  </code></pre>
  <p>Partial HTML preview:</p>
  <pre><code>SG5 0AZ, {contact.province}
  United Kingdom
  {contact.complete_address}
  </code></pre>
  <p>Email template:</p>
  <pre><code>{contact.postal_code}, {contact.province}
  {contact.country}
  {contact.complete_address}
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-11-04T22:41:40.863Z
Comments.Text: I must be doing something wrong as when I simplify the return of values, nothing is returned:
  
          $values[$cid]['contact.complete_address'] = 'test';
Comments.UserDisplayName: dmgeurts
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-11-09T21:02:49.277Z
Comments.Text: I'm not following why you want `{contact.province}` when `{contact.state_province_name}` already exists with the full UK County name?
Comments.UserDisplayName: Aidan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-11-10T09:57:25.433Z
Comments.Text: @Aidan Because for some reason '{contact.state_province_name}' isn't available in mailings.
Comments.UserDisplayName: dmgeurts
Tags: <email><hooks><addresses><apiv4>
Title: Use complete address and full county name in mailings
ThreadText: # Use complete address and full county name in mailings
  
  (Asked by: username_0 on 2020-11-03)
  
  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}
  
  ```
  
  **Tags:** email, hooks, addresses, apiv4
  
  > **Comments:**
  > **username_0**: I must be doing something wrong as when I simplify the return of values, nothing is returned:          $values[$cid]['contact.complete_address'] = 'test';  
  > **username_1**: I'm not following why you want `{contact.province}` when `{contact.state_province_name}` already exists with the full UK County name?  
  > **username_0**: @username_1 Because for some reason '{contact.state_province_name}' isn't available in mailings.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2020-11-03. Score: 1
  
  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
  
  username_2
  
  > **Comments:**
  > **username_0**: Thank you, username_2. 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?  
  > **username_0**: 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.  
  
  ---
  
  ### Answer by username_3 on 2020-11-17. Score: 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.
  
  > **Comments:**
  > **username_0**: New counties in the UK are VERY rare! Will check the link, thank you.  
  > **username_0**: That worked a charm thank you!. Pitty that something like {contact.complete_address} isn't available to mailings either.  
  > **username_3**: It seems like that would be a reasonable thing to have.  
  > **username_0**: Darn it, I assigned the bounty to the wrong answer and can't undo this... Sorry!  
  > **username_3**: No worries! Thanks for the note.  
  
  ---
  
  