address.inc 12 KB

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