From: Eileen McNaughton Date: Fri, 8 Dec 2023 03:43:26 +0000 (+1300) Subject: Split CRM_Utils_Address::vcard into 2 functions X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=564998b5dbd79ff8e3bdfaee683bde796562f87d;p=civicrm-core.git Split CRM_Utils_Address::vcard into 2 functions --- diff --git a/CRM/Core/BAO/Address.php b/CRM/Core/BAO/Address.php index 1489b5ca67..cb0d95e66c 100644 --- a/CRM/Core/BAO/Address.php +++ b/CRM/Core/BAO/Address.php @@ -471,9 +471,13 @@ class CRM_Core_BAO_Address extends CRM_Core_DAO_Address implements Civi\Core\Hoo else { $fields['county'] = NULL; } - - $this->display = CRM_Utils_Address::format($fields, NULL, $microformat); - $this->display_text = CRM_Utils_Address::format($fields); + if ($microformat) { + $this->display = CRM_Utils_Address::formatVCard($fields); + $this->display_text = CRM_Utils_Address::format($fields); + } + else { + $this->display = $this->display_text = CRM_Utils_Address::format($fields); + } } /** diff --git a/CRM/Utils/Address.php b/CRM/Utils/Address.php index 2b79d40a59..91f89f0822 100644 --- a/CRM/Utils/Address.php +++ b/CRM/Utils/Address.php @@ -47,7 +47,10 @@ class CRM_Utils_Address { $unused = FALSE, $tokenFields = NULL ) { - + if ($microformat) { + CRM_Core_Error::deprecatedFunctionWarning('CRM_Utils_Address::formatVCard (not recommended outside core - figure out a token way)'); + self::formatVCard($fields); + } if (!$format) { $format = Civi::settings()->get('address_format'); } @@ -58,6 +61,123 @@ class CRM_Utils_Address { $fullPostalCode .= '-' . $fields['postal_code_suffix']; } + $replacements = [ + 'contact.display_name' => $fields['display_name'] ?? NULL, + 'contact.formal_title' => $fields['formal_title'] ?? NULL, + 'contact.first_name' => $fields['first_name'] ?? NULL, + 'contact.middle_name' => $fields['middle_name'] ?? NULL, + 'contact.last_name' => $fields['last_name'] ?? NULL, + 'contact.individual_prefix' => $fields['prefix_id:label'] ?? ($fields['individual_prefix'] ?? NULL), + 'contact.prefix_id:label' => $fields['prefix_id:label'] ?? ($fields['individual_prefix'] ?? NULL), + 'contact.individual_suffix' => $fields['suffix_id:label'] ?? ($fields['individual_suffix'] ?? NULL), + 'contact.suffix_id:label' => $fields['suffix_id:label'] ?? ($fields['individual_suffix'] ?? NULL), + 'contact.address_name' => $fields['address_name'] ?? NULL, + 'contact.street_address' => $fields['street_address'] ?? NULL, + 'contact.supplemental_address_1' => $fields['supplemental_address_1'] ?? NULL, + 'contact.supplemental_address_2' => $fields['supplemental_address_2'] ?? NULL, + 'contact.supplemental_address_3' => $fields['supplemental_address_3'] ?? NULL, + 'contact.city' => $fields['city'] ?? NULL, + 'contact.state_province_name' => $fields['state_province_id:label'] ?? ($fields['state_province_name'] ?? NULL), + 'contact.county' => $fields['county_id:label'] ?? ($fields['county'] ?? NULL), + 'contact.state_province' => $fields['state_province_id:label'] ?? ($fields['state_province'] ?? NULL), + 'contact.postal_code' => $fullPostalCode, + 'contact.country' => $fields['country_id:label'] ?? ($fields['country'] ?? NULL), + 'contact.world_region' => $fields['world_region'] ?? NULL, + 'contact.geo_code_1' => $fields['geo_code_1'] ?? NULL, + 'contact.geo_code_2' => $fields['geo_code_2'] ?? NULL, + 'contact.current_employer' => $fields['current_employer'] ?? NULL, + 'contact.nick_name' => $fields['nick_name'] ?? NULL, + 'contact.email' => $fields['email'] ?? NULL, + 'contact.im' => $fields['im'] ?? NULL, + 'contact.do_not_email' => $fields['do_not_email'] ?? NULL, + 'contact.do_not_phone' => $fields['do_not_phone'] ?? NULL, + 'contact.do_not_mail' => $fields['do_not_mail'] ?? NULL, + 'contact.do_not_sms' => $fields['do_not_sms'] ?? NULL, + 'contact.do_not_trade' => $fields['do_not_trade'] ?? NULL, + 'contact.job_title' => $fields['job_title'] ?? NULL, + 'contact.birth_date' => $fields['birth_date'] ?? NULL, + 'contact.gender' => $fields['gender'] ?? NULL, + 'contact.is_opt_out' => $fields['is_opt_out'] ?? NULL, + 'contact.phone' => $fields['phone'] ?? NULL, + 'contact.home_URL' => $fields['home_URL'] ?? NULL, + 'contact.contact_source' => $fields['contact_source'] ?? NULL, + 'contact.external_identifier' => $fields['external_identifier'] ?? NULL, + 'contact.contact_id' => $fields['id'] ?? NULL, + 'contact.household_name' => $fields['household_name'] ?? NULL, + 'contact.organization_name' => $fields['organization_name'] ?? NULL, + 'contact.legal_name' => $fields['legal_name'] ?? NULL, + 'contact.preferred_communication_method' => $fields['preferred_communication_method'] ?? NULL, + 'contact.communication_style' => $fields['communication_style'] ?? NULL, + 'contact.addressee' => $fields['addressee_display'] ?? NULL, + 'contact.email_greeting' => $fields['email_greeting_display'] ?? NULL, + 'contact.postal_greeting' => $fields['postal_greeting_display'] ?? NULL, + ]; + + // replacements in case of Custom Token + if (stristr(($formatted ?? ''), 'custom_')) { + $customToken = array_keys($fields); + foreach ($customToken as $value) { + if (substr($value, 0, 7) == 'custom_') { + $replacements["contact.{$value}"] = $fields["{$value}"]; + } + } + } + + // also sub all token fields + if ($tokenFields) { + foreach ($tokenFields as $token) { + $replacements["{$token}"] = $fields["{$token}"] ?? NULL; + } + } + + // for every token, replace {fooTOKENbar} with fooVALUEbar if + // the value is not empty, otherwise drop the whole {fooTOKENbar} + foreach ($replacements as $token => $value) { + if ($value && is_string($value) || is_numeric($value)) { + $formatted = preg_replace("/{([^{}]*)\b{$token}\b([^{}]*)}/u", "\${1}{$value}\${2}", ($formatted ?? '')); + } + else { + $formatted = preg_replace("/{[^{}]*\b{$token}\b[^{}]*}/u", '', ($formatted ?? '')); + } + } + + $formatted = "\n$formatted\n"; + + $formatted = preg_replace('/\n{[^{}]*}/u', "\n", $formatted); + $formatted = preg_replace('/{[^{}]*}\n/u', "\n", $formatted); + + // if there are any 'sibling' {...} constructs, replace them with the + // contents of the first one; for example, when there's no state_province: + // 1. {city}{, }{state_province}{ }{postal_code} + // 2. San Francisco{, }{ }12345 + // 3. San Francisco, 12345 + $formatted = preg_replace('/{([^{}]*)}({[^{}]*})+/u', '\1', $formatted); + + // drop any remaining curly braces leaving their contents + $formatted = str_replace(['{', '}'], '', $formatted); + + // drop any empty lines left after the replacements + $formatted = preg_replace('/^[ \t]*[\r\n]+/m', '', $formatted); + return $formatted; + } + + /** + * Format an address in the vcard format. + * + * @param array $fields + * The address fields. + * + * @return string + * formatted address string + */ + public static function formatVCard($fields) { + $formatted = Civi::settings()->get('address_format'); + + $fullPostalCode = $fields['postal_code'] ?? NULL; + if (!empty($fields['postal_code_suffix'])) { + $fullPostalCode .= '-' . $fields['postal_code_suffix']; + } + // make sure that some of the fields do have values $emptyFields = [ 'supplemental_address_1', @@ -72,87 +192,31 @@ class CRM_Utils_Address { } } - if (!$microformat) { - // replacements in case of Individual Name Format - $replacements = [ - 'contact.display_name' => $fields['display_name'] ?? NULL, - 'contact.formal_title' => $fields['formal_title'] ?? NULL, - 'contact.first_name' => $fields['first_name'] ?? NULL, - 'contact.middle_name' => $fields['middle_name'] ?? NULL, - 'contact.last_name' => $fields['last_name'] ?? NULL, - 'contact.individual_prefix' => $fields['prefix_id:label'] ?? ($fields['individual_prefix'] ?? NULL), - 'contact.prefix_id:label' => $fields['prefix_id:label'] ?? ($fields['individual_prefix'] ?? NULL), - 'contact.individual_suffix' => $fields['suffix_id:label'] ?? ($fields['individual_suffix'] ?? NULL), - 'contact.suffix_id:label' => $fields['suffix_id:label'] ?? ($fields['individual_suffix'] ?? NULL), - 'contact.address_name' => $fields['address_name'] ?? NULL, - 'contact.street_address' => $fields['street_address'] ?? NULL, - 'contact.supplemental_address_1' => $fields['supplemental_address_1'] ?? NULL, - 'contact.supplemental_address_2' => $fields['supplemental_address_2'] ?? NULL, - 'contact.supplemental_address_3' => $fields['supplemental_address_3'] ?? NULL, - 'contact.city' => $fields['city'] ?? NULL, - 'contact.state_province_name' => $fields['state_province_id:label'] ?? ($fields['state_province_name'] ?? NULL), - 'contact.county' => $fields['county_id:label'] ?? ($fields['county'] ?? NULL), - 'contact.state_province' => $fields['state_province_id:label'] ?? ($fields['state_province'] ?? NULL), - 'contact.postal_code' => $fullPostalCode, - 'contact.country' => $fields['country_id:label'] ?? ($fields['country'] ?? NULL), - 'contact.world_region' => $fields['world_region'] ?? NULL, - 'contact.geo_code_1' => $fields['geo_code_1'] ?? NULL, - 'contact.geo_code_2' => $fields['geo_code_2'] ?? NULL, - 'contact.current_employer' => $fields['current_employer'] ?? NULL, - 'contact.nick_name' => $fields['nick_name'] ?? NULL, - 'contact.email' => $fields['email'] ?? NULL, - 'contact.im' => $fields['im'] ?? NULL, - 'contact.do_not_email' => $fields['do_not_email'] ?? NULL, - 'contact.do_not_phone' => $fields['do_not_phone'] ?? NULL, - 'contact.do_not_mail' => $fields['do_not_mail'] ?? NULL, - 'contact.do_not_sms' => $fields['do_not_sms'] ?? NULL, - 'contact.do_not_trade' => $fields['do_not_trade'] ?? NULL, - 'contact.job_title' => $fields['job_title'] ?? NULL, - 'contact.birth_date' => $fields['birth_date'] ?? NULL, - 'contact.gender' => $fields['gender'] ?? NULL, - 'contact.is_opt_out' => $fields['is_opt_out'] ?? NULL, - 'contact.phone' => $fields['phone'] ?? NULL, - 'contact.home_URL' => $fields['home_URL'] ?? NULL, - 'contact.contact_source' => $fields['contact_source'] ?? NULL, - 'contact.external_identifier' => $fields['external_identifier'] ?? NULL, - 'contact.contact_id' => $fields['id'] ?? NULL, - 'contact.household_name' => $fields['household_name'] ?? NULL, - 'contact.organization_name' => $fields['organization_name'] ?? NULL, - 'contact.legal_name' => $fields['legal_name'] ?? NULL, - 'contact.preferred_communication_method' => $fields['preferred_communication_method'] ?? NULL, - 'contact.communication_style' => $fields['communication_style'] ?? NULL, - 'contact.addressee' => $fields['addressee_display'] ?? NULL, - 'contact.email_greeting' => $fields['email_greeting_display'] ?? NULL, - 'contact.postal_greeting' => $fields['postal_greeting_display'] ?? NULL, - ]; - } - else { - $replacements = [ - 'contact.address_name' => "" . $fields['address_name'] . "", - 'contact.street_address' => "" . $fields['street_address'] . "", - 'contact.supplemental_address_1' => "" . $fields['supplemental_address_1'] . "", - 'contact.supplemental_address_2' => $fields['supplemental_address_2'], - 'contact.supplemental_address_3' => $fields['supplemental_address_3'], - 'contact.city' => "" . $fields['city'] . "", - 'contact.state_province_name' => "" . $fields['state_province_name'] . "", - 'contact.county' => "" . $fields['county'], - 'contact.state_province' => "" . $fields['state_province'] . "", - 'contact.postal_code' => "" . $fullPostalCode . "", - 'contact.country' => "" . $fields['country'] . "", - 'contact.world_region' => "" . $fields['world_region'] . "", - ]; - - // Erase all empty ones, so we don't get blank lines - foreach (array_keys($replacements) as $key) { - $exactKey = substr($key, 0, 8) == 'contact.' ? substr($key, 8) : $key; - if ($key !== 'contact.postal_code' && empty($fields[$exactKey])) { - $replacements[$key] = ''; - } - } - if (empty($fullPostalCode)) { - $replacements['contact.postal_code'] = ''; + $replacements = [ + 'contact.address_name' => "" . $fields['address_name'] . "", + 'contact.street_address' => "" . $fields['street_address'] . "", + 'contact.supplemental_address_1' => "" . $fields['supplemental_address_1'] . "", + 'contact.supplemental_address_2' => $fields['supplemental_address_2'], + 'contact.supplemental_address_3' => $fields['supplemental_address_3'], + 'contact.city' => "" . $fields['city'] . "", + 'contact.state_province_name' => "" . $fields['state_province_name'] . "", + 'contact.county' => "" . $fields['county'], + 'contact.state_province' => "" . $fields['state_province'] . "", + 'contact.postal_code' => "" . $fullPostalCode . "", + 'contact.country' => "" . $fields['country'] . "", + 'contact.world_region' => "" . $fields['world_region'] . "", + ]; + + // Erase all empty ones, so we don't get blank lines + foreach (array_keys($replacements) as $key) { + $exactKey = substr($key, 0, 8) == 'contact.' ? substr($key, 8) : $key; + if ($key !== 'contact.postal_code' && empty($fields[$exactKey])) { + $replacements[$key] = ''; } } + if (empty($fullPostalCode)) { + $replacements['contact.postal_code'] = ''; + } // replacements in case of Custom Token if (stristr(($formatted ?? ''), 'custom_')) { @@ -164,13 +228,6 @@ class CRM_Utils_Address { } } - // also sub all token fields - if ($tokenFields) { - foreach ($tokenFields as $token) { - $replacements["{$token}"] = $fields["{$token}"] ?? NULL; - } - } - // for every token, replace {fooTOKENbar} with fooVALUEbar if // the value is not empty, otherwise drop the whole {fooTOKENbar} foreach ($replacements as $token => $value) { @@ -182,18 +239,7 @@ class CRM_Utils_Address { } } - // drop any {...} constructs from lines' ends - if (!$microformat) { - $formatted = "\n$formatted\n"; - } - else { - if ($microformat == 1) { - $formatted = "\n
\n$formatted
\n"; - } - else { - $formatted = "\n
$formatted
\n"; - } - } + $formatted = "\n
\n$formatted
\n"; $formatted = preg_replace('/\n{[^{}]*}/u', "\n", $formatted); $formatted = preg_replace('/{[^{}]*}\n/u', "\n", $formatted); @@ -210,27 +256,21 @@ class CRM_Utils_Address { // drop any empty lines left after the replacements $formatted = preg_replace('/^[ \t]*[\r\n]+/m', '', $formatted); - - if (!$microformat) { - $finalFormatted = $formatted; - } - else { - // remove \n from each line and only add at the end - // this hack solves formatting issue, when we convert nl2br - $count = 1; - $finalFormatted = NULL; - $formattedArray = explode("\n", $formatted); - $formattedArray = array_filter($formattedArray); - - foreach ($formattedArray as $line) { - $line = trim($line); - if ($line) { - if ($count > 1 && $count < count($formattedArray)) { - $line = "$line\n"; - } - $finalFormatted .= $line; - $count++; + // remove \n from each line and only add at the end + // this hack solves formatting issue, when we convert nl2br + $count = 1; + $finalFormatted = NULL; + $formattedArray = explode("\n", $formatted); + $formattedArray = array_filter($formattedArray); + + foreach ($formattedArray as $line) { + $line = trim($line); + if ($line) { + if ($count > 1 && $count < count($formattedArray)) { + $line = "$line\n"; } + $finalFormatted .= $line; + $count++; } } return $finalFormatted;