addressfield_tokens.tokens.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. /**
  3. * @file
  4. * Provides token replacements for address fields.
  5. */
  6. /**
  7. * Implements hook_token_info_alter().
  8. *
  9. * Attaches tokens to all addressfield properties. The default names of each
  10. * addressfield component can be altered by administrators according to the
  11. * site's locale.
  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. // Add extra text to webform submission values help.
  90. if (array_key_exists('submission', $info['tokens'])) {
  91. $info['tokens']['submission']['values']['description'] .= '
  92. <div>
  93. ' . t('For addressfield components you can also choose individual elements of the address using the syntax field_key:element, For example:') . '
  94. <ul>
  95. <li>[submission:values:address:thoroughfare]</li>
  96. <li>[submission:values:address:locality]</li>
  97. <li>[submission:values:address:administrative_area]</li>
  98. <li>[submission:values:address:postal_code]</li>
  99. <li>[submission:values:address:country]</li>
  100. </ul>
  101. </div>';
  102. }
  103. // Attach tokens to all address fields.
  104. $valid_types = entity_token_types();
  105. foreach ($valid_types as $token_type => $type) {
  106. foreach (entity_get_all_property_info($type) as $name => $property) {
  107. $name = str_replace('_', '-', $name);
  108. if (!isset($info['tokens'][$token_type][$name]) && isset($property['type']) && $property['type'] == 'addressfield') {
  109. $info['tokens'][$token_type][$name] = array(
  110. 'name' => $property['label'],
  111. 'type' => 'addressfield',
  112. 'description' => isset($property['description']) ? $property['description'] : t('Address field'),
  113. );
  114. }
  115. }
  116. }
  117. }
  118. /**
  119. * Implements hook_tokens().
  120. */
  121. function addressfield_tokens_tokens($type, $tokens, array $data = array(), array $options = array()) {
  122. $url_options = array();
  123. // @todo: why are we setting $language_code and not using it?
  124. if (isset($options['language'])) {
  125. $url_options['language'] = $options['language'];
  126. $language_code = $options['language']->language;
  127. }
  128. else {
  129. $language_code = LANGUAGE_NONE;
  130. }
  131. $sanitize = !empty($options['sanitize']);
  132. $replacements = array();
  133. $last_original = NULL;
  134. // Process webform submission addressfield tokens.
  135. if ($type == 'submission' && !empty($data['webform-submission'])) {
  136. $submission = $data['webform-submission'];
  137. $node = isset($data['node']) ? $data['node'] : node_load($submission->nid);
  138. $value_tokens = token_find_with_prefix($tokens, 'values');
  139. // Loop through the components of the webform looking for addressfield
  140. // components with the expected form_key.
  141. foreach ($node->webform['components'] as $cid => $component) {
  142. if ($component['type'] == 'addressfield' && isset($submission->data[$cid][0])) {
  143. $address = $submission->data[$cid][0];
  144. if (is_string($address)) {
  145. $address = unserialize($address);
  146. }
  147. $address_tokens = token_find_with_prefix($value_tokens, $component['form_key']);
  148. foreach ($address_tokens as $token => $original) {
  149. if (isset($address[$token])) {
  150. $replacements[$original] = $sanitize ? filter_xss($address[$token]) : $address[$token];
  151. }
  152. }
  153. }
  154. }
  155. }
  156. // Process address field tokens.
  157. elseif ($type == 'addressfield' && !empty($data['addressfield'])) {
  158. foreach ($tokens as $name => $original) {
  159. $last_original = $original;
  160. $name = str_replace('-', '_', $name);
  161. $address = $data['addressfield'];
  162. // If the address field exists, use it.
  163. if (isset($address[$name])) {
  164. $replacements[$original] = $sanitize ? filter_xss($address[$name]) : $address[$name];
  165. }
  166. else {
  167. // Otherwise, it's a special token.
  168. switch ($name) {
  169. case 'full':
  170. $render = addressfield_generate($address, array('address'), array(
  171. 'mode' => 'render',
  172. ));
  173. $replacements[$original] = $sanitize ? filter_xss(drupal_render($render)) : drupal_render($render);
  174. break;
  175. case 'text':
  176. $out = array();
  177. if (!empty($address['thoroughfare'])) {
  178. $out[0] = $address['thoroughfare'];
  179. }
  180. $out[1] = array();
  181. if (!empty($address['locality'])) {
  182. $out[1][] = $address['locality'];
  183. }
  184. if (!empty($address['administrative_area'])) {
  185. $out[1][] = $address['administrative_area'];
  186. }
  187. $out[1] = implode(', ', $out[1]);
  188. if (!empty($address['postal_code'])) {
  189. $out[1] .= ' ' . $address['postal_code'];
  190. }
  191. if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
  192. $out[2] = _addressfield_tokens_country($address['country']);
  193. }
  194. $replacements[$original] = $sanitize ? filter_xss(implode("\n", $out)) : implode("\n", $out);
  195. break;
  196. case 'city_state':
  197. $out = array();
  198. if (!empty($address['locality'])) {
  199. $out[] = $address['locality'];
  200. }
  201. if (!empty($address['administrative_area'])) {
  202. $out[] = $address['administrative_area'];
  203. }
  204. if (!empty($address['country']) && $address['country'] != addressfield_tokens_default_country()) {
  205. $out[] = _addressfield_tokens_country($address['country']);
  206. }
  207. $replacements[$original] = $sanitize ? filter_xss(implode(", ", $out)) : implode(", ", $out);
  208. break;
  209. case 'state_name':
  210. if (!empty($address['administrative_area']) && !empty($address['country'])) {
  211. if ($sanitize) {
  212. $replacements[$original] = filter_xss(addressfield_tokens_state($address['country'], $address['administrative_area']));
  213. }
  214. else {
  215. $replacements[$original] = addressfield_tokens_state($address['country'], $address['administrative_area']);
  216. }
  217. }
  218. break;
  219. case 'country_name':
  220. if (!empty($address['country'])) {
  221. if ($sanitize) {
  222. $replacements[$original] = filter_xss(_addressfield_tokens_country($address['country']));
  223. }
  224. else {
  225. $replacements[$original] = _addressfield_tokens_country($address['country']);
  226. }
  227. }
  228. break;
  229. case 'mc_address':
  230. $address_components = array(
  231. 'thoroughfare',
  232. 'premise',
  233. 'locality',
  234. 'administrative_area',
  235. 'postal_code',
  236. 'country',
  237. );
  238. $mc_address = array();
  239. foreach ($address_components as $component) {
  240. if (!empty($address[$component])) {
  241. $mc_address[] = check_plain($address[$component]);
  242. }
  243. }
  244. // MailChimp requires the address to be a string of double-space
  245. // delimited address fields. (http://kb.mailchimp.com/article/how-do-i-set-up-the-address-field-type-for-import)
  246. $replacements[$original] = !empty($mc_address) ? implode(' ', $mc_address) : '';
  247. break;
  248. }
  249. }
  250. }
  251. if (!isset($replacements[$last_original])) {
  252. $replacements[$last_original] = '';
  253. }
  254. }
  255. else {
  256. $token_types = entity_token_types();
  257. $info = token_info();
  258. if (isset($info['tokens'][$type])) {
  259. // Otherwise, chain address fields attached to other entities.
  260. foreach ($info['tokens'][$type] as $name => $token_info) {
  261. if (isset($token_info['type']) && $token_info['type'] == 'addressfield') {
  262. if ($chained_tokens = token_find_with_prefix($tokens, $name)) {
  263. $wrapper = !isset($wrapper) ? _entity_token_wrap_data($type, $token_types[$type], $data[$type], $options) : $wrapper;
  264. $property_name = str_replace('-', '_', $name);
  265. try {
  266. $address = $wrapper->$property_name->value();
  267. $replacements += token_generate('addressfield', $chained_tokens, array('addressfield' => $address), $options);
  268. }
  269. catch (EntityMetadataWrapperException $e) {
  270. // The property doesn't exist, so skip it.
  271. $replacements[$last_original] = '';
  272. }
  273. }
  274. }
  275. }
  276. }
  277. }
  278. return $replacements;
  279. }