addressfield_tokens.tokens.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * @file Provides token replacements for address fields.
  4. */
  5. /**
  6. * Implements hook_token_info_alter().
  7. *
  8. * Attaches tokens to all addressfield properties. The default names of each
  9. * addressfield component can be altered by administrators according to the site's locale.
  10. *
  11. * @param array $info The existing token info.
  12. */
  13. function addressfield_tokens_token_info_alter(&$info) {
  14. // Define the address field token types
  15. $info['types']['addressfield'] = array(
  16. 'name' => t('Address field'),
  17. 'description' => t('An address associated with an entity.'),
  18. 'needs-data' => 'addressfield',
  19. );
  20. // Add tokens for each component of the address
  21. $info['tokens'] += array( 'addressfield' => array() );
  22. $props = addressfield_data_property_info();
  23. $names = addressfield_tokens_property_names();
  24. $params = array(
  25. '@default_country' => addressfield_tokens_default_country(),
  26. );
  27. foreach ($props as $field => $data) {
  28. $fieldtoken = str_replace('_', '-', $field);
  29. if (!empty($names[$field])) {
  30. $name = $names[$field];
  31. $descr = $data['label'];
  32. }
  33. else {
  34. $name = $data['label'];
  35. $descr = $name;
  36. $matches = array();
  37. if (preg_match('/^(.*)\s+\(i\.e\.\s+(.*)\)$/', $name, $matches)) {
  38. $name = $matches[1];
  39. $descr = $matches[2];
  40. }
  41. }
  42. $info['tokens']['addressfield'][$fieldtoken] = array(
  43. 'name' => $name,
  44. 'description' => $descr,
  45. 'type' => 'text',
  46. );
  47. $params['@' . $field] = $name;
  48. }
  49. $info['tokens']['addressfield']['administrative-area']['name'] .= ' (abbreviation)';
  50. $info['tokens']['addressfield']['country']['name'] .= ' (abbreviation)';
  51. // Add tokens for the formatted address and text-only version.
  52. $info['tokens']['addressfield'] += array(
  53. 'full' => array(
  54. 'name' => t('Formatted address'),
  55. 'description' => t('The full formatted address.'),
  56. 'type' => 'text',
  57. ),
  58. 'text' => array(
  59. 'name' => t('Text-only address'),
  60. 'description' => t('The full address with line breaks but no formatting.'),
  61. 'type' => 'text',
  62. ),
  63. 'city-state' => array(
  64. 'name' => t('City, State'),
  65. 'description' => t('@locality and @administrative_area separated by commas (and @country if outside @default_country)', $params),
  66. 'type' => 'text',
  67. ),
  68. 'state-name' => array(
  69. 'name' => t('@administrative_area (full name)', $params),
  70. 'description' => t('The full name of the @administrative_area', $params),
  71. 'type' => 'text',
  72. ),
  73. 'country-name' => array(
  74. 'name' => t('@country (full name)', $params),
  75. 'description' => t('The full name of the @country', $params),
  76. 'type' => 'text',
  77. ),
  78. );
  79. // Add user tokens that are useful for MailChimp.
  80. if (module_exists('mailchimp')) {
  81. $info['tokens']['addressfield'] += array(
  82. 'mc-address' => array(
  83. 'name' => t('MailChimp Address'),
  84. 'description' => t('A full address formatted for integration with MailChimp.'),
  85. 'type' => 'text',
  86. ),
  87. );
  88. }
  89. // Attach tokens to all address fields
  90. $valid_types = entity_token_types();
  91. $entity_info = entity_get_info();
  92. foreach ($valid_types as $token_type => $type) {
  93. foreach (entity_get_all_property_info($type) as $name => $property) {
  94. $name = str_replace('_', '-', $name);
  95. if (!isset($info['tokens'][$token_type][$name]) && isset($property['type']) && $property['type'] == 'addressfield') {
  96. $info['tokens'][$token_type][$name] = array(
  97. 'name' => $property['label'],
  98. 'type' => 'addressfield',
  99. 'description' => isset($property['description']) ? $property['description'] : t('Address field'),
  100. );
  101. }
  102. }
  103. }
  104. }
  105. /**
  106. * Implements hook_tokens().
  107. *
  108. * @param string $type The type of tokens to replace. We are looking for 'addressfield', but can also chain
  109. * addressfields onto entities that have addressfields as properties.
  110. * @param array $tokens The tokens to replace.
  111. * @param array $data The data to use as replacements. We are looking for an 'addressfield' property.
  112. * @param array $options Additional options for the tokenizer.
  113. *
  114. * @return array The replaced values.
  115. */
  116. function addressfield_tokens_tokens($type, $tokens, array $data = array(), array $options = array()) {
  117. $url_options = array();
  118. // @todo: why are we setting $language_code and not using it?
  119. if (isset($options['language'])) {
  120. $url_options['language'] = $options['language'];
  121. $language_code = $options['language']->language;
  122. }
  123. else {
  124. $language_code = LANGUAGE_NONE;
  125. }
  126. $sanitize = !empty($options['sanitize']);
  127. $replacements = array();
  128. $last_original = NULL;
  129. // Process address field tokens
  130. if ($type == 'addressfield' && !empty($data['addressfield'])) {
  131. foreach ($tokens as $name => $original) {
  132. $last_original = $original;
  133. $name = str_replace('-', '_', $name);
  134. $address = $data['addressfield'];
  135. // If the address field exists, use it.
  136. if (isset($address[$name])) {
  137. $replacements[$original] = $sanitize ? filter_xss($address[$name]) : $address[$name];
  138. }
  139. else {
  140. // Otherwise, it's a special token
  141. switch ($name) {
  142. case 'full':
  143. $render = addressfield_generate($address, array('address'), array(
  144. 'mode' => 'render',
  145. ));
  146. $replacements[$original] = $sanitize ? filter_xss(drupal_render($render)) : drupal_render($render);
  147. break;
  148. case 'text':
  149. $out = array();
  150. if (!empty($address['thoroughfare'])) {
  151. $out[0] = $address['thoroughfare'];
  152. }
  153. $out[1] = array();
  154. if (!empty($address['locality'])) {
  155. $out[1][] = $address['locality'];
  156. }
  157. if (!empty($address['administrative_area'])) {
  158. $out[1][] = $address['administrative_area'];
  159. }
  160. $out[1] = implode(', ', $out[1]);
  161. if (!empty($address['postal_code'])) {
  162. $out[1] .= ' ' . $address['postal_code'];
  163. }
  164. if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
  165. $out[2] = _addressfield_tokens_country($address['country']);
  166. }
  167. $replacements[$original] = $sanitize ? filter_xss(implode("\n", $out)) : implode("\n", $out);
  168. break;
  169. case 'city_state':
  170. $out = array();
  171. if (!empty($address['locality'])) {
  172. $out[] = $address['locality'];
  173. }
  174. if (!empty($address['administrative_area'])) {
  175. $out[] = $address['administrative_area'];
  176. }
  177. if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
  178. $out[] = _addressfield_tokens_country($address['country']);
  179. }
  180. $replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out);
  181. break;
  182. case 'state_name':
  183. if (!empty($address['administrative_area']) && !empty($address['country'])) {
  184. if ($sanitize) {
  185. $replacements[$original] = filter_xss(_addressfield_tokens_state($address['country'], $address['administrative_area']));
  186. }
  187. else {
  188. $replacements[$original] = _addressfield_tokens_state($address['country'], $address['administrative_area']);
  189. }
  190. }
  191. break;
  192. case 'country_name':
  193. if (!empty($address['country'])) {
  194. if ($sanitize) {
  195. $replacements[$original] = filter_xss(_addressfield_tokens_country($address['country']));
  196. }
  197. else {
  198. $replacements[$original] = _addressfield_tokens_country($address['country']);
  199. }
  200. }
  201. break;
  202. case 'mc_address':
  203. $address_components = array('thoroughfare', 'premise', 'locality', 'administrative_area', 'postal_code', 'country');
  204. $mc_address = array();
  205. foreach ($address_components as $component) {
  206. if (!empty($address[$component])) {
  207. $mc_address[] = check_plain($address[$component]);
  208. }
  209. }
  210. // MailChimp requires the address to be a string of double-space
  211. // delimited address fields. (http://kb.mailchimp.com/article/how-do-i-set-up-the-address-field-type-for-import)
  212. $replacements[$original] = !empty($mc_address) ? implode(' ', $mc_address) : '';
  213. break;
  214. }
  215. }
  216. }
  217. if (!isset($replacements[$last_original])) {
  218. $replacements[$last_original] = '';
  219. }
  220. }
  221. else {
  222. $token_types = entity_token_types();
  223. $info = token_info();
  224. if (isset($info['tokens'][$type])) {
  225. // Otherwise, chain address fields attached to other entities
  226. foreach ($info['tokens'][$type] as $name => $token_info) {
  227. if (isset($token_info['type']) && $token_info['type'] == 'addressfield') {
  228. if ($chained_tokens = token_find_with_prefix($tokens, $name)) {
  229. $wrapper = !isset($wrapper) ? _entity_token_wrap_data($type, $token_types[$type], $data[$type], $options) : $wrapper;
  230. $property_name = str_replace('-', '_', $name);
  231. try {
  232. $address = $wrapper->$property_name->value();
  233. $replacements += token_generate('addressfield', $chained_tokens, array('addressfield' => $address), $options);
  234. }
  235. catch (EntityMetadataWrapperException $e) {
  236. // The property doesn't exist, so skip it.
  237. $replacements[$last_original] = '';
  238. }
  239. }
  240. }
  241. }
  242. }
  243. }
  244. return $replacements;
  245. }