address.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <?php
  2. /**
  3. * @file
  4. * The default format for adresses.
  5. */
  6. $plugin = array(
  7. 'title' => t('Address form (country-specific)'),
  8. 'format callback' => 'addressfield_format_address_generate',
  9. 'type' => 'address',
  10. 'weight' => -100,
  11. );
  12. /**
  13. * Format callback.
  14. *
  15. * @see CALLBACK_addressfield_format_callback()
  16. */
  17. function addressfield_format_address_generate(&$format, $address, $context = array()) {
  18. // Load the predefined address format for the selected country.
  19. module_load_include('inc', 'addressfield', 'addressfield.address_formats');
  20. $address_format = addressfield_get_address_format($address['country']);
  21. // Used to move certain fields to their own row.
  22. $clearfix = '<div class="clearfix"></div>';
  23. // The street block.
  24. $format['street_block'] = array(
  25. '#type' => 'addressfield_container',
  26. '#attributes' => array(
  27. 'class' => array('street-block'),
  28. ),
  29. '#weight' => 0,
  30. );
  31. $format['street_block']['thoroughfare'] = array(
  32. '#title' => t('Address 1'),
  33. '#tag' => 'div',
  34. '#attributes' => array(
  35. 'class' => array('thoroughfare'),
  36. 'x-autocompletetype' => 'address-line1',
  37. 'autocomplete' => 'address-line1',
  38. ),
  39. '#size' => 30,
  40. '#required' => TRUE,
  41. );
  42. $format['street_block']['premise'] = array(
  43. '#title' => t('Address 2'),
  44. '#tag' => 'div',
  45. '#attributes' => array(
  46. 'class' => array('premise'),
  47. 'x-autocompletetype' => 'address-line2',
  48. 'autocomplete' => 'address-line2',
  49. ),
  50. '#size' => 30,
  51. );
  52. $format['locality_block'] = array(
  53. '#type' => 'addressfield_container',
  54. '#attributes' => array(
  55. 'class' => array('addressfield-container-inline', 'locality-block', 'country-' . $address['country']),
  56. ),
  57. '#weight' => 50,
  58. );
  59. $format['locality_block']['#attached']['css'][] = drupal_get_path('module', 'addressfield') . '/addressfield.css';
  60. $format['locality_block']['postal_code'] = array(
  61. '#title' => $address_format['postal_code_label'],
  62. '#required' => in_array('postal_code', $address_format['required_fields']),
  63. '#access' => in_array('postal_code', $address_format['used_fields']),
  64. '#size' => 10,
  65. '#attributes' => array(
  66. 'class' => array('postal-code'),
  67. 'x-autocompletetype' => 'postal-code',
  68. 'autocomplete' => 'postal-code',
  69. ),
  70. );
  71. $format['locality_block']['dependent_locality'] = array(
  72. '#title' => $address_format['dependent_locality_label'],
  73. '#required' => in_array('dependent_locality', $address_format['required_fields']),
  74. '#access' => in_array('dependent_locality', $address_format['used_fields']),
  75. '#size' => 25,
  76. '#tag' => 'div',
  77. '#attributes' => array(
  78. 'class' => array('dependent-locality')
  79. ),
  80. // Most formats place this field in its own row.
  81. '#suffix' => $clearfix,
  82. );
  83. $format['locality_block']['locality'] = array(
  84. '#title' => $address_format['locality_label'],
  85. '#required' => in_array('locality', $address_format['required_fields']),
  86. '#access' => in_array('locality', $address_format['used_fields']),
  87. '#size' => 30,
  88. '#prefix' => ' ',
  89. '#attributes' => array(
  90. 'class' => array('locality'),
  91. 'x-autocompletetype' => 'locality',
  92. 'autocomplete' => 'locality',
  93. ),
  94. );
  95. $format['locality_block']['administrative_area'] = array(
  96. '#title' => $address_format['administrative_area_label'],
  97. '#required' => in_array('administrative_area', $address_format['required_fields']),
  98. '#access' => in_array('administrative_area', $address_format['used_fields']),
  99. '#empty_value' => '',
  100. '#size' => 10,
  101. '#prefix' => ' ',
  102. '#render_option_value' => $address_format['render_administrative_area_value'],
  103. '#attributes' => array(
  104. 'class' => array('state'),
  105. 'x-autocompletetype' => 'region',
  106. 'autocomplete' => 'region',
  107. ),
  108. );
  109. $format['country'] = array(
  110. '#title' => t('Country'),
  111. '#options' => _addressfield_country_options_list(),
  112. '#render_option_value' => TRUE,
  113. '#required' => TRUE,
  114. '#attributes' => array(
  115. 'class' => array('country'),
  116. 'x-autocompletetype' => 'country',
  117. 'autocomplete' => 'country',
  118. ),
  119. '#weight' => 100,
  120. );
  121. if (empty($format['locality_block']['postal_code']['#access'])) {
  122. // Remove the prefix from the first widget of the block.
  123. $element_children = element_children($format['locality_block']);
  124. $first_child = reset($element_children);
  125. unset($format['locality_block'][$first_child]['#prefix']);
  126. }
  127. if (!empty($format['locality_block']['administrative_area']['#access'])) {
  128. // Set the predefined administrative areas, if found.
  129. module_load_include('inc', 'addressfield', 'addressfield.administrative_areas');
  130. $administrative_areas = addressfield_get_administrative_areas($address['country']);
  131. $format['locality_block']['administrative_area']['#options'] = $administrative_areas;
  132. }
  133. // Country-specific customizations.
  134. if (in_array($address['country'], array('AU', 'EE', 'LT', 'LV', 'NZ', 'RU'))) {
  135. // These countries don't use the "Address 2" line.
  136. // Leave it as a precaution, but hide the label to avoid confusing users.
  137. $format['street_block']['thoroughfare']['#title'] = t('Address');
  138. $format['street_block']['premise']['#title_display'] = 'invisible';
  139. }
  140. elseif ($address['country'] == 'US') {
  141. if ($context['mode'] == 'render') {
  142. $format['locality_block']['locality']['#suffix'] = ',';
  143. }
  144. }
  145. elseif ($address['country'] == 'BR') {
  146. $format['locality_block']['dependent_locality']['#suffix'] = $clearfix;
  147. $format['locality_block']['dependent_locality']['#tag'] = 'div';
  148. $format['locality_block']['administrative_area']['#suffix'] = $clearfix;
  149. $format['locality_block']['postal_code']['#tag'] = 'div';
  150. // Change some titles to make translation easier.
  151. $format['street_block']['#attributes'] = array(
  152. 'class' => array('addressfield-container-inline'),
  153. );
  154. $format['street_block']['thoroughfare']['#title'] = t('Thoroughfare');
  155. $format['street_block']['thoroughfare']['#tag'] = NULL;
  156. $format['street_block']['premise'] = array(
  157. '#title' => t('Complement'),
  158. '#tag' => NULL,
  159. '#attributes' => array('class' => array('premise')),
  160. '#size' => 20,
  161. '#prefix' => ', ',
  162. );
  163. $format['locality_block']['locality']['#suffix'] = ' - ';
  164. // Hide suffixes and prefixes while in form.
  165. if ($context['mode'] == 'form') {
  166. $format['street_block']['premise']['#prefix'] = NULL;
  167. $format['street_block']['premise']['#suffix'] = NULL;
  168. $format['locality_block']['locality']['#suffix'] = NULL;
  169. }
  170. }
  171. elseif ($address['country'] == 'CN') {
  172. $format['locality_block']['locality']['#suffix'] = $clearfix;
  173. }
  174. elseif ($address['country'] == 'CA') {
  175. if ($context['mode'] == 'render') {
  176. $format['locality_block']['locality']['#suffix'] = ',';
  177. }
  178. }
  179. elseif ($address['country'] == 'GB') {
  180. $format['locality_block']['administrative_area']['#size'] = '30';
  181. }
  182. elseif ($address['country'] == 'ID') {
  183. $format['locality_block']['administrative_area']['#weight'] = 1;
  184. }
  185. elseif ($address['country'] == 'JP') {
  186. $format['locality_block']['#weight'] = 10;
  187. $format['locality_block']['postal_code']['#weight'] = 10;
  188. $format['locality_block']['postal_code']['#tag'] = 'div';
  189. $format['locality_block']['postal_code']['#size'] = 30;
  190. $format['locality_block']['administrative_area']['#weight'] = 20;
  191. $format['locality_block']['administrative_area']['#size'] = 30;
  192. $format['locality_block']['locality']['#weight'] = 30;
  193. $format['street_block']['#weight'] = 20;
  194. }
  195. elseif ($address['country'] == 'PE') {
  196. $format['locality_block']['administrative_area']['#weight'] = 1;
  197. $format['locality_block']['locality']['#weight'] = 2;
  198. }
  199. elseif ($address['country'] == 'PH' || $address['country'] == 'TH') {
  200. $format['locality_block']['dependent_locality']['#suffix'] = '';
  201. $format['locality_block']['locality']['#suffix'] = $clearfix;
  202. }
  203. // These countries show every field in its own row.
  204. $countries_field_per_row = array(
  205. 'AM', 'EG', 'FK', 'GB', 'GG', 'GS', 'HK', 'HU', 'IE', 'IM', 'IO', 'JE', 'JM',
  206. 'JP', 'KE', 'KR', 'KZ', 'LK', 'PA', 'PN', 'RU', 'SC', 'SH', 'SZ', 'TC', 'UA',
  207. 'VG', 'ZA',
  208. );
  209. if (in_array($address['country'], $countries_field_per_row)) {
  210. $format['locality_block']['#attributes']['class'][0] = 'addressfield-container';
  211. $format['locality_block']['postal_code']['#prefix'] = '';
  212. $format['locality_block']['postal_code']['#tag'] = 'div';
  213. $format['locality_block']['locality']['#prefix'] = '';
  214. $format['locality_block']['locality']['#tag'] = 'div';
  215. $format['locality_block']['administrative_area']['#prefix'] = '';
  216. $format['locality_block']['administrative_area']['#tag'] = 'div';
  217. }
  218. // These countries tend to put the postal code after the locality.
  219. $countries_postal_code_after_locality = array(
  220. 'AS', 'AU', 'BD', 'BF', 'BH', 'BM', 'BN', 'BR', 'BT', 'CA', 'CC', 'CN', 'CX',
  221. 'EG', 'FK', 'FM', 'GB', 'GG', 'GS', 'GU', 'HN', 'HU', 'ID', 'IL', 'IM', 'IN',
  222. 'IO', 'IQ', 'IR', 'JE', 'JO', 'JP', 'KE', 'KH', 'KR', 'LB', 'LK', 'LS', 'LV',
  223. 'MH', 'MM', 'MN', 'MP', 'MT', 'MV', 'MX', 'MY', 'NF', 'NG', 'NP', 'NZ', 'PG',
  224. 'PH', 'PK', 'PN', 'PR', 'PW', 'RU', 'SA', 'SH', 'SO', 'SZ', 'TC', 'TH', 'TW',
  225. 'UA', 'UM', 'US', 'VE', 'VI', 'VG', 'VN', 'ZA',
  226. );
  227. if (in_array($address['country'], $countries_postal_code_after_locality)) {
  228. // Take the widget out of the array.
  229. $postal_code_widget = $format['locality_block']['postal_code'];
  230. $postal_code_widget['#prefix'] = ' ';
  231. unset($format['locality_block']['postal_code']);
  232. // Add it back.
  233. $format['locality_block']['postal_code'] = $postal_code_widget;
  234. // Remove the prefix from the first widget of the block.
  235. $element_children = element_children($format['locality_block']);
  236. $first_child = reset($element_children);
  237. unset($format['locality_block'][$first_child]['#prefix']);
  238. }
  239. if ($context['mode'] == 'form') {
  240. // Provide a wrapper ID for AJAX replacement based on country selection.
  241. if (!isset($format['#wrapper_id'])) {
  242. $format['#wrapper_id'] = drupal_html_id('addressfield-wrapper');
  243. $format['#prefix'] = '<div id="' . $format['#wrapper_id'] . '">';
  244. $format['#suffix'] = '</div>';
  245. }
  246. // AJAX enable it.
  247. $format['country']['#ajax'] = array(
  248. 'callback' => 'addressfield_standard_widget_refresh',
  249. 'wrapper' => $format['#wrapper_id'],
  250. );
  251. $format['country']['#element_validate'] = array('addressfield_standard_country_validate');
  252. // Don't validate any element when the country is changed.
  253. $format['country']['#limit_validation_errors'] = array();
  254. // Move the country selector to the top of the form.
  255. $format['country']['#weight'] = -500;
  256. // Limit it to the countries supported by the widget.
  257. if (isset($context['field'])) {
  258. $format['country']['#options'] = _addressfield_country_options_list($context['field'], $context['instance']);
  259. }
  260. // The whole field is considered empty if the country column is empty.
  261. // Therefore, if the field is optional, allow the country to be optional.
  262. // The same logic applies if the field allows multiple values, in which case
  263. // only the first delta needs to have a value.
  264. if (empty($context['instance']['required']) || (isset($context['delta']) && $context['delta'] > 0)) {
  265. $format['country']['#required'] = FALSE;
  266. $format['country']['#empty_value'] = '';
  267. // Hide all other fields until the country is selected.
  268. if (empty($address['country'])) {
  269. $format['street_block']['#access'] = FALSE;
  270. $format['locality_block']['#access'] = FALSE;
  271. }
  272. }
  273. }
  274. }